flat assembler
Message board for the users of flat assembler.

Index > Windows > How to generate random numbers?

Goto page 1, 2, 3  Next
Author
Thread Post new topic Reply to topic
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 24 May 2022, 09:49
I think this is a well answered question, but when I want to do it, I do not know where to look for solution.

I use srand and rand function from C Runtime:

Code:
        ccall  [srand]
        ccall  [rand]           


Or if I use seed number:
Code:
        ccall  [srand],1234
        ccall  [rand]           


Questions:
1. Am I correct to use ccall in 32-bit PE GUI? Not invoke nor cinvoke nor call nor fastcall?

2. The random number generated by the above function is the same each time I start the program. How to have different random number every time I run the program and call the function (for once)?

The functions are referenced as below:
Code:
section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL',\
          msvcrt,'msvcrt.dll'

  import msvcrt,\
         rand,'rand',\
         srand,'srand'       


Thank you for any help.
Post 24 May 2022, 09:49
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 24 May 2022, 10:02
If you want a good cryptographic quality PRNG then the C runtime is not going to do it for you.

Instead you can try this:
Code:
PROV_RSA_FULL           = 1
CRYPT_VERIFYCONTEXT     = 0f0000000h

proc rand uses ebx,store,length
        local   context:DWORD
        invoke  CryptAcquireContext,addr context,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT
        test    eax,eax
        jz      .done
        invoke  CryptGenRandom,[context],[length],[store]
        test    eax,eax
        setz    bl
        invoke  CryptReleaseContext,[context],0
        test    eax,eax
        setz    al
        or      al,bl
        movzx   eax,al
        dec     eax     
    .done:
        ret
endp    
Otherwise if you roll your own then proper seeding is probably the hardest and most important aspect of it, then the mixing algorithm must be strong.

cinvoke func is the same as ccall [func]. Either works for calling MSVCRT.
Post 24 May 2022, 10:02
View user's profile Send private message Visit poster's website Reply with quote
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 24 May 2022, 11:03
I have issue with local context:DWORD (I am not sure how to handle "proc" macro) because FASMW complained : "Error: Invalid value" by pointing to "pushd addr ..var?TQ" . To workaround that, I declare "context" in data section as "dw".

Now everything compile and run, but it exits silently after call rand and did not execute the next instruction in my code to display a message box.

This is how I reference to the APIs:
Code:
  import advapi,\
          CryptAcquireContext, 'CryptAcquireContextA',\
          CryptGenRandom, 'CryptGenRandom',\
          CryptReleaseContext, 'CryptReleaseContext'      


Microsoft Docs states:
Quote:
Important This API is deprecated. New and existing software should start using Cryptography Next Generation APIs. Microsoft may remove this API in future releases.


And I am using Windows 11, is this the reason it quits silently on my PC?

I include the full source below:
Code:
format PE GUI 4.0
entry start

include 'win32a.inc'

section '.text' code readable executable

proc rand uses ebx,store,length
        invoke  CryptAcquireContext,context,0,0,1,0xF0000000
        test    eax,eax
        jz      .done
        invoke  CryptGenRandom,dword [context],[length],[store]
        test    eax,eax
        setz    bl
        invoke  CryptReleaseContext,dword [context],0
        test    eax,eax
        setz    al
        or      al,bl
        movzx   eax,al
        dec     eax     
    .done:
        ret
endp

  start:
        ;ccall  [srand]
        ;ccall  [rand]
        call    rand
        cinvoke wsprintf,msg,fmt,eax
        invoke  MessageBox,0,msg,title,0x40
        invoke  ExitProcess,0

section '.data' data readable writeable

  msg     rb 32
  fmt     db '%d',0
  title   db 'rand',0
  context dw ?

section '.idata' import readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL',\
          advapi,'ADVAPI32.DLL',\
          msvcrt,'msvcrt.dll'

  import kernel,\
         ExitProcess,'ExitProcess'

  import user,\
         wsprintf,'wsprintfA',\
         MessageBox,'MessageBoxA'

  import advapi,\
          CryptAcquireContext, 'CryptAcquireContextA',\
          CryptGenRandom, 'CryptGenRandom',\
          CryptReleaseContext, 'CryptReleaseContext'

;  import msvcrt,\
;         rand,'rand',\
;         srand,'srand'      
    
Post 24 May 2022, 11:03
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 24 May 2022, 11:10
If you use win32ax.inc then the other stuff you had trouble with should be okay.

And it is a stdcall function, not a normal call. So call it like this:
Code:
stdcall rand, buffer, length    
Post 24 May 2022, 11:10
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 24 May 2022, 11:13
context is not the random numbers, it is a private pointer for the API. The generated numbers are stored in the buffer you declare in the call.
Post 24 May 2022, 11:13
View user's profile Send private message Visit poster's website Reply with quote
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 24 May 2022, 11:25
revolution wrote:
If you use win32ax.inc then the other stuff you had trouble with should be okay.

And it is a stdcall function, not a normal call. So call it like this:
Code:
stdcall rand, buffer, length    


Thank you for bearing with me, I am still poor in many things related to FASM.

Now it works:

Code:
stdcall rand, buffer, 32       


Code:
  buffer  rb 32
          db 0      


EDIT: The "eax" returned by "rand" is -1.

But it is still the same number I get each time I run the program, i.e. 4202536.

Is this how it should work?
Post 24 May 2022, 11:25
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 24 May 2022, 11:31
eax is the indicator of success or failure. It can only be zero or negative one. Zero mean failure, negative one means success.

The buffer is filled with the result. In your case 32 bytes of data. Print the contents of the buffer, not the address. 4202536 looks like the address.
Post 24 May 2022, 11:31
View user's profile Send private message Visit poster's website Reply with quote
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 24 May 2022, 11:40
Excellent! You're right.

It really is random data, i.e. different set of data each time I run the program.

Now I need to turn the random data to random number.
Thanks @revolution for your zeal in helping me and others.


Description: Random data #2..... etc
Filesize: 9.84 KB
Viewed: 8313 Time(s)

Screenshot 2022-05-24 193731.png


Description: Random data #1
Filesize: 9.92 KB
Viewed: 8313 Time(s)

Screenshot 2022-05-24 193747.png


Post 24 May 2022, 11:40
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 24 May 2022, 12:22
FlierMate wrote:
It really is random data, i.e. different set of data each time I run the program.
It's really only a PRNG. The magic is all in the seeding.
Post 24 May 2022, 12:22
View user's profile Send private message Visit poster's website Reply with quote
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 24 May 2022, 13:29
I don't know about the term PRNG, I think bitRAKE posted some random data generator recently.

I use your method to show quote of the day. Smile


Description: Random quote generator (ANSI, english)
Download
Filename: rand_en.asm
Filesize: 3.54 KB
Downloaded: 224 Time(s)

Description: Random quote generator (UTF-8, chinese)
Download
Filename: rand_zh.asm
Filesize: 3.45 KB
Downloaded: 250 Time(s)



Last edited by FlierMate on 28 May 2022, 10:36; edited 2 times in total
Post 24 May 2022, 13:29
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1618
Location: Toronto, Canada
AsmGuru62 24 May 2022, 13:33
I use this generator (WELL512) -- it passes all the tests.
Just ignore some of the functions in the file -- it is for a game I was coding.


Description:
Download
Filename: well512.Asm
Filesize: 5.75 KB
Downloaded: 247 Time(s)

Description:
Download
Filename: well512.Inc
Filesize: 283 Bytes
Downloaded: 232 Time(s)

Post 24 May 2022, 13:33
View user's profile Send private message Send e-mail Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 926
Location: Russia
macomics 24 May 2022, 15:29
Code:
// calculate a 't' value that will linearly interpolate from 0 to 1 and back every 20 seconds
DWORD currentTime = GetTickCount();
if ( m_startTime == 0 )
{
    m_startTime = currentTime;
}
float t = 2 * (( currentTime - m_startTime) % 20000) / 20000.0f;
if (t > 1.0f)
{
    t = 2 - t;
}    
The simplest random number generator is given as an example in the description of the GetTickCount function
Post 24 May 2022, 15:29
View user's profile Send private message Reply with quote
pabloreda



Joined: 24 Jan 2007
Posts: 116
Location: Argentina
pabloreda 25 May 2022, 00:35
I use this code (in forth/r3)

Code:
##seed $a3b195354a39b70d

::rand | -- rand
  seed $da942042e4dd58b5 * 1 + dup 'seed ! ;

    


in ASM is like

Code:
seed dq $a3b195354a39b70d

rand:   ;    call rand ; rax a rand number
    mov rax,[seed]
    imul rax,$da942042e4dd58b5
    add rax,1
    mov [seed],rax
    ret

    
Post 25 May 2022, 00:35
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 25 May 2022, 01:16
Those LCG class generators were one of the first types to be used. Simple and easy.

WP has an article on some other types of simple generators.
https://en.wikipedia.org/wiki/Xorshift

Check out this page for some stats on them
https://prng.di.unimi.it/

None of those are cryptographic though, so the potential applications are limited by that.

And the seeding is the hardest bit. So all generators, no matter how fantastic, are terrible if the seeding is bad.
Post 25 May 2022, 01:16
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 28 May 2022, 14:08
One more example, with no call to anything.
Code:
   rdtsc    
al -- pseudorandom up to 256
Code:
   rdtsc
   mov bl,10
   mul bl
   mov bl,0xFF
   div bl    
al -- pseudorandom up to 10
Post 28 May 2022, 14:08
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2493
Furs 28 May 2022, 14:55
Code:
rdrand    
Post 28 May 2022, 14:55
View user's profile Send private message Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 28 May 2022, 15:08
Quote:

rdrand

Nice one begins from IvyBridge and Ryzen
Post 28 May 2022, 15:08
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 28 May 2022, 16:05
fixed example to show 0-10:
Code:
   rdtsc
   mov bl,11
   mul bl
   xor dx,dx
   mov bx,0x0100
   div bx 
    
Post 28 May 2022, 16:05
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 28 May 2022, 16:33
Nobody trusts rdrand anyway. Razz It is a blackbox function with no way to verify it has no backdoors.

rdtsc can be good for simple apps, but I would prefer to use it as part of the generator seeding, rather than directly as the generator itself.
Post 28 May 2022, 16:33
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 28 May 2022, 17:01
Image
Quote:
Nobody trusts rdrand anyway. It is a blackbox function with no way to verify it has no backdoors.

Don't you trust CPU instructions? How can you trust to rest of them? Very Happy
Post 28 May 2022, 17:01
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.