diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 803ed5310aa..b3e3540c5af 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -501,7 +501,7 @@ @ stub RtlDeactivateActivationContext @ stub RtlDeactivateActivationContextUnsafeFast @ stub RtlDebugPrintTimes -# @ stub RtlDecodePointer +@ stdcall RtlDecodePointer(ptr) # @ stub RtlDecodeSystemPointer @ stub RtlDecompressBuffer @ stub RtlDecompressFragment @@ -543,7 +543,7 @@ @ stdcall RtlDuplicateUnicodeString(long ptr ptr) @ stdcall RtlEmptyAtomTable(ptr long) # @ stub RtlEnableEarlyCriticalSectionEventCreation -# @ stub RtlEncodePointer +@ stdcall RtlEncodePointer(ptr) # @ stub RtlEncodeSystemPointer @ stdcall -ret64 RtlEnlargedIntegerMultiply(long long) @ stdcall RtlEnlargedUnsignedDivide(double long ptr) diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 8ddab6a3497..449e91a89e7 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -886,3 +886,39 @@ NTSTATUS WINAPI RtlIpv4AddressToStringExW (PULONG IP, PULONG Port, return STATUS_SUCCESS; } + +static DWORD_PTR get_pointer_obfuscator( void ) +{ + static DWORD_PTR pointer_obfuscator; + + if (!pointer_obfuscator) + { + ULONG seed = NtGetTickCount(); + ULONG_PTR rand; + + /* generate a random value for the obfuscator */ + rand = RtlUniform( &seed ); + + /* handle 64bit pointers */ + rand ^= RtlUniform( &seed ) << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8); + + /* set the high bits so dereferencing obfuscated pointers will (usually) crash */ + rand |= 0xc0000000 << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8); + + interlocked_cmpxchg_ptr( (void**) &pointer_obfuscator, (void*) rand, NULL ); + } + + return pointer_obfuscator; +} + +PVOID WINAPI RtlEncodePointer( PVOID ptr ) +{ + DWORD_PTR ptrval = (DWORD_PTR) ptr; + return (PVOID)(ptrval ^ get_pointer_obfuscator()); +} + +PVOID WINAPI RtlDecodePointer( PVOID ptr ) +{ + DWORD_PTR ptrval = (DWORD_PTR) ptr; + return (PVOID)(ptrval ^ get_pointer_obfuscator()); +}