Reverse Engineering RET Homepage RET Members Reverse Engineering Projects Reverse Engineering Papers Reversing Challenges Reverser Tools RET Re-Search Engine Reverse Engineering Forum Reverse Engineering Links

Reverse Engineering Team Blog

03.09.05

RE: Debug thunks on Windows 95/98/ME

Posted in General Posts at 10:53 am by sna

I’ve written a C++ class based on the idea I presented last time. There’s not a whole lot to say about the code except that I hope it works. I haven’t had the opportunity to test it on Windows 98 or Millennium Edition but I don’t see why it wouldn’t work there (more on this later).

The class is called ‘RealAddress’ and since a picture says more than a thousand words, here’s what a test application using the class shows when you run it: Testing RealAddress on Windows 95.

The tiny test application gets the address of MessageBoxA by using GetProcAddress. It also imports MessageBoxA so it then fetches the address from out of its own IAT. Those are the top two addresses shown in the message boxes in the picture above. Note that these two addresses could be faked and point to debug thunks. To get the real addresses the test application turns to RealAddress.

RealAddress has a function, GetProcAddress, which works just like the real GetProcAddress, except it tries to bypass any debug thunks Windows throws at it. RealAddress also has a second function, GetThunkAddress, which you can use when iterating through an import address table. It too tries to bypass debug thunks.

The header file for RealAddress is here and the source code is here. Set tab width at 4 cols for pretty code.

Oh, I’ve commented out the check that tests if addresses are above 2GB. I figured it doesn’t really add anything and it locks the code down a lot. What if some weird Windows version decides that it wants to build the debug thunks on the process heap instead? BOOM! The class wouldn’t work any more. But with the check disabled it should work just as good anywhere else as it does on Windows 95.

There’s a super rare case where disabling the check is un-good. It happens when you’re using GetThunkAddress and the application is importing a variable. Imagine that the variable’s least-significant-byte is 0×68 and five bytes further away you find a pattern that matches the debug thunks’ jump pattern. It’s incredibly super unlikely that this will ever happen – but it could happen. The long jump really makes it all so much harder for it to happen, but beware.

Leave a Comment