Michael,
Very interesting...!
Your code crashes on my Win XP SP3 machine. It happens here:
RtlRandomEx 8BFF mov edi, edi ; ntdll.7C920228
0047E789 /. 55 push ebp
0047E78A |. 8BEC mov ebp, esp
0047E78C |. A1 30495C00 mov eax, [5C4930]
0047E791 |. 83E0 7F and eax, 7F
0047E794 |. 53 push ebx
0047E795 |. 8D0C85 38495C00 lea ecx, [eax*4+5C4938]
0047E79C |. 8B01 mov eax, [ecx]
0047E79E |. 56 push esi
0047E79F |. 8B75 08 mov esi, [arg.1]
0047E7A2 |. A3 30495C00 mov [5C4930], eax
0047E7A7 |. 57 push ediObviously, I wondered why mine didn't crash:
RtlRandomEx /$ 8BFF mov edi, edi
7C947B82 |. 55 push ebp
7C947B83 |. 8BEC mov ebp, esp
7C947B85 |. A1 8009997C mov eax, [7C990980]
7C947B8A |. 83E0 7F and eax, 7F
7C947B8D |. 53 push ebx
7C947B8E |. 8D0C85 8809997C lea ecx, [eax*4+7C990988]
7C947B95 |. 8B01 mov eax, [ecx]
7C947B97 |. 56 push esi
7C947B98 |. 8B75 08 mov esi, [arg.1]
7C947B9B |. A3 8009997C mov [7C990980], eax
7C947BA0 |. 57 push ediWe are using two different DLLs, ntoskrnl.exe vs NtDll.dll
Running your code with "my" DLL yields this:
mean : 4035C436h
98675333
100855976
99656502
97367024
101346380
97367072
99983825
103363306
103799432
97585150 How did you get yours (i.e. the native API) running without that exception?
When I use your code with ntdll for generating the ENT data file, the same bad results pop up, in particular the mean of 111.x as compared to 127.5 (=255/2).
There is actually a problem with the documentation. According to MSDN,
RtlRandomEx returns a random number in the range [0..MAXLONG-1]. -> WinNT.h: #define MAXLONG 0x7fffffff, i.e. a 32-bit number.
However, using this C++ snippet:
#include <iostream>
#include <Windows.h>
typedef ULONGLONG(__stdcall *_RtlRandomEx)(PULONG seed);
int main()
{
_RtlRandomEx RtlRandomEx = (_RtlRandomEx)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlRandomEx");
ULONG seed = 123;
ULONGLONG result;
for (int i = 0; i < 10; ++i)
__asm int 3;
result=RtlRandomEx(&seed);
__asm int 3;
std::cout << result << std::endl;
}
... you find this:
00411412 ³. FF55 F8 call near [local.2] <<<<<<< RtlRandomEx
00411415 ³. 3BF4 cmp esi, esp
00411417 ³. E8 24FDFFFF call 00411140 ; [_RTC_CheckEsp
0041141C ³. 8945 DC mov [local.9], eax <<<<<<< QWORD, not
0041141F ³. 8955 E0 mov [local.8], edx <<<<<<< DWORD!!!
RtlRandomEx Ú$ 8BFF mov edi, edi ; ntdll.RtlRandomEx(guessed Arg1)
7C947B82 ³. 55 push ebp
7C947B83 ³. 8BEC mov ebp, esp
7C947B85 ³. A1 8009997C mov eax, [7C990980]
7C947B8A ³. 83E0 7F and eax, 0000007F
7C947B8D ³. 53 push ebx
7C947B8E ³. 8D0C85 8809997C lea ecx, [eax*4+7C990988]
7C947B95 ³. 8B01 mov eax, [ecx]
7C947B97 ³. 56 push esi
7C947B98 ³. 8B75 08 mov esi, [ebp+8]
7C947B9B ³. A3 8009997C mov [7C990980], eax
7C947BA0 ³. 57 push edi
7C947BA1 ³. 8BF8 mov edi, eax
7C947BA3 ³. 8B06 mov eax, [esi]
7C947BA5 ³. 69C0 EDFFFF7F imul eax, eax, 7FFFFFED
7C947BAB ³. 05 C3FFFF7F add eax, 7FFFFFC3
7C947BB0 ³. BB FFFFFF7F mov ebx, 7FFFFFFF
7C947BB5 ³. 33D2 xor edx, edx
7C947BB7 ³. F7F3 div ebx
7C947BB9 ³. 8BC7 mov eax, edi
7C947BBB ³. 5F pop edi
7C947BBC ³. 8916 mov [esi], edx
7C947BBE ³. 5E pop esi
7C947BBF ³. 8911 mov [ecx], edx
7C947BC1 ³. 5B pop ebx
7C947BC2 ³. 5D pop ebp
7C947BC3 À. C2 0400 retn 4
... it is evident that RtlRandomEx returns a QWORD, not a DWORD. Which, by the way, has exactly the same ENT characteristics, i.e. the 111 mean and the 7.95 bits.