; ; pker's Random Number Generator (PKRNG) ; ====================================== ; ; ; Description ; ----------- ; ; PKRNG is a random number generator. It can be used for MASM, TASM, FASM, etc. It ; containz four procedurez: __randomize, __random and __m_seq_gen and ; __random_rdtsc. __randomize procedure is for generating initial seed in the seed ; field, which specified as parameter. The __m_seq_gen procedure is used to ; generate m-sequence, which used by __random, which generate random numberz ; finally. __random_rdtsc is the simplest one, it just get the RDTSC and divide it ; by the range given as parameter. ; ; ; How to use PKRNG ; ---------------- ; ; When using MASM or TASM to initialize seed field: ; ; mov edi,offset dwSeed ; call __randomize ; ; The get a random number in eax: ; ; mov eax,offset dwSeed ; mov ecx,32 ; get a random number between 0~31 ; call __random ; ; ; Same thing happened with FASM: ; ; mov edi,dwSeed ; call __randomize ; ; mov eax,dwSeed ; mov ecx,32 ; get a random number between 0~31 ; call __random ; ; ; Copyright ; --------- ; ; (c) 2004. No rightz reserved. Use without permission :P. ; ; ; __randomize procedure ; ===================== ; ; ; Description ; ----------- ; ; This function use RDTSC instruction to generator a random number in order to ; initialize the seed field. ; ; ; Parameterz and Return Values ; ---------------------------- ; ; input: ; edi --- points to the seed field ; output: ; nothing ; __randomize: pushad db 0fh,31h ; RDTSC add eax,edx ; ... stosd ; fill in the seed buffer popad ret ; ; __random procedure ; ================== ; ; ; Description ; ----------- ; ; This function generates a random number and rewrite the seed field. The function ; first get a 32 bit m-sequence, which then multiply with the previous seed, with ; __m_seq_gen procedure. And then, it calls __m_seq_gen again to generate another ; m-sequence to make noise by adding on the DWORD calculated before. Also, this ; result is the new seed, and will be write to the seed field which pointed by EAX ; as argument. Finally, the seed is divided by ECX, and return the modulus, which ; is the expected random number. ; ; ; Parameterz and Return Values ; ---------------------------- ; ; input: ; eax --- pointz to the random seed field ; edx --- the range of the random number to be generated ; output: ; eax --- random number as result ; __random: pushad xchg ecx,edx mov edi,eax mov esi,eax lodsd ; get the previous seed value mov ebx,eax mov ebp,ebx call __m_seq_gen ; generate a m-sequence imul ebp ; multiply with the previous seed xchg ebx,eax call __m_seq_gen ; generate anothe m-sequence add eax,ebx ; to make noise... add eax,92151fech ; and some noisez... stosd ; write new seed value xor edx,edx div ecx ; calculate the random number mov [esp+28],edx ; according to a specified range popad ret ; ; __m_seq_gen procedure ; ===================== ; ; ; Description ; ----------- ; ; This function use a PN (Pseudo Noise) generator to generate m-sequencez. The ; configuration of the generator shows below (figure 1): ; ; (module 2 addition) ; ___ ; / \ ; +---------- | + | <------------------------------+ ; | \___/ | ; | A | ; | +-----+ | +-----+ +-----+ | ; +--> | D31 | -+-> | D30 | ---> ... ---> | D01 | -+-> output ; +-----+ +-----+ +-----+ ; A A A ; | | | ; CLK ---------------+------------+---------------------+ ; ; figure 1. m-Sequence Generator ; ; ; Parameterz and Return Values ; ---------------------------- ; ; input: ; eax --- a non-zero random number, which could be generated by RDTSC or ; GetTickCount or such functionz ; output: ; eax --- the result of the function ; __m_seq_gen: pushad xor esi,esi ; use to save the 32bit m-sequence push 32 ; loop 32 times (but it's not a pop ecx ; cycle in the m-sequence generator) msg_next_bit: mov ebx,eax mov ebp,ebx xor edx,edx inc edx and ebp,edx ; get the lowest bit dec cl shl ebp,cl or esi,ebp ; output... inc cl and ebx,80000001h ; \ ror bx,1 ; \ mov edx,ebx ; \ ror ebx,16 ; module 2 addition xor bx,dx ; / rcl ebx,17 ; / rcr eax,1 ; / loop msg_next_bit mov [esp+28],esi popad ret ; ; __random_rdtsc procedure ; ======================== ; ; ; Description ; ----------- ; ; This is the simplest RNG in the packet. Well, nothing to explain :P ; ; ; Parameterz and Return Value ; --------------------------- ; ; input: ; ecx --- the range of the random number to be generated ; ; output: ; eax --- random number as result ; __random_rdtsc: pushad db 0fh,31h add eax,edx xor edx,edx or ecx,ecx jz rnd_rdt_no_range div ecx xchg eax,edx rnd_rdt_no_range: mov [esp+28],eax popad ret