Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1

reference manuals [Intel2, Intel3] we learn that RDTSCperforms a Read Time-
Stamp Counter operation. The time-stamp counter is a very high-speed 64-bit
counter, which is incremented by one on each clock cycle. This means that on
a 3.4-GHz system this counter is incremented roughly 3.4 billion times per sec-
ond. RDTSCloads the counter into EDX:EAX, where EDXreceives the high-
order 32 bits, and EAXreceives the lower 32 bits. Defender takes the lower 32
bits from EAXand does a bitwise ANDwith 7FFF0000. It then takes the result
and passes that (it actually passes a pointer to that value) as the second param-
eter in the NtAllocateVirtualMemorycall.
Why would defender pass a part of the time-stamp counter as a parameter
to NtAllocateVirtualMemory? Let’s take a look at the prototype for
NtAllocateVirtualMemoryto determine what the system expects in the
second parameter. This prototype was taken from http://undocumented.
ntinternals.net, which is a good resource for undocumented Windows
APIs. Of course, theauthoritative source of information regarding the Native
API is Gary Nebbett’s book Windows NT/2000 Native API Reference[Nebbett].


NTSYSAPI
NTSTATUS
NTAPI
NtAllocateVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG RegionSize,
IN ULONG AllocationType,
IN ULONG Protect );

It looks like the second parameter is a pointer to the base address. IN OUT
specifies that the function reads the value stored in BaseAddrand then writes
to it. The way this works is that the function attempts to allocate memory at the
specified address and writes the actual address of the allocated block back into
BaseAddress. So, Defender is passing the time-stamp counter as the pro-
posed allocation address.... This may seem strange, but it really isn’t—all the
program is doing is trying to allocate memory at a random address in memory.
The time-stamp counter is a good way to achieve a certain level of random-
ness.
Another interesting aspect of this call is the fourth parameter, which is the
requested block size. Defender is taking a value from [EBP-4]and using that
as the block size. Going back in the code, you can find the following sequence,
which appears to take part in producing the block size:


004035FE MOV EAX,DWORD PTR [EBP+8]
00403601 MOV DWORD PTR [EBP-70],EAX

Breaking Protections 389
Free download pdf