[C#] RtlRandomEx Function P/Invoke Example (ntdll.dll)

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
There are other methods other than using the Random class to generate random values. Not to mention it only supports int, and double for numbers.

Here's a fast function that generates nice random numbers from ntdll.dll:

Code:
sealed internal class NativeMethods
{
	[DllImport("ntdll.dll")]
	internal static extern ulong RtlRandomEx(ref ulong Seed);
}

There is a non-"ex" version of this, but this extended function is much better, and is the one you will want to be using if you choose to call to this function.

Here are my overloaded methods as a wrapper for returning usable random unsigned long values:

Code:
public static ulong RandGen()
{
	return RandGen(1);
}

public static ulong RandGen(ulong seed)
{
	return RandGen(seed, 0, ulong.MaxValue);
}

public static ulong RandGen(ulong seed, ulong lowerBound, ulong upperBound)
{
	if (lowerBound >= upperBound)
	{
		throw new ArgumentException("The lowerbound argument cannot be equal to or greater than the exclusive upperbound.");
	}
	ulong r = NativeMethods.RtlRandomEx(ref seed);
	return (r %= upperBound - lowerBound) + lowerBound;
}

Here are some return values just from a bit of fun and play:

Code:
1586179657
510558172
1605617193
1424793008
1152951110
528928978
107522126
724979721
2106295624
458868389

Code:
for (int i = 0; i < 10; i++)
{
	ulong x = (ulong)(int.MaxValue ^ i << i);
	Console.WriteLine(RandGen(x, 0, ulong.MaxValue));
}

:beerchug2:
 
Here's an example of this function's usage in C++. In order to call this function, you'll need to use runtime dynamic linking.

Code:
[plain]typedef ULONG (__stdcall *_RtlRandomEx) ( PULONG Seed );

ULONG get_random(ULONG seed, ULONG lowerBound, ULONG upperBound)
{
	assert(lowerBound <= upperBound);
	_RtlRandomEx RtlRandomEx = (_RtlRandomEx) GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlRandomEx");
	ULONG r = RtlRandomEx(&seed);
	return (r % upperBound - lowerBound) + lowerBound;
}

ULONG get_random(ULONG seed)
{
	return get_random(seed, 0, 0xffffffffUL);
}

ULONG get_random()
{
	return get_random(1);
}

int main(void)
{
	for (int i = 0; i < 100; i++)
		std::cout << get_random(i, 0, 1000) << std::endl;
	return 0;
}[/plain]
 
Last edited:

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top