Valhalla Legends Forums Archive | Advanced Programming | Hooking an API with VirtualProtect?

AuthorMessageTime
Myndfyr
Since shared DLLs are paged in and the pages are shared as long as the pages are read-only, and then a copy is made when the page is written to, is it possible to hook an API by patching its call location with a redirect to a function I write? 

UserLoser said something about hooking GetModuleFileName to implement CheckRevision via one of the version check DLLs downloaded from the Bnet FTP service.  I'm just wondering if this is the right way to do it - set the memory to be writeable, GetProcAddress the API, overwrite the API to call my function.

Since the paged-in API would be private to my process, I wouldn't need to worry about other processes getting screwed up.  Just mine, and it could be very fast, and then restore the API.

Am I way off?
September 17, 2006, 12:12 PM
Skywing
Yes, that is one way to do it.  Congratulations on looking to do some original work instead of just using stolen code like some people in the community.

Images are mapped copy on write, so when one process writes to them, that process tranparently receives its own copy of the modified areas.  This is used for loader relocations quite frequently.  It is possible to mark certain pages as shared between all processes within a session even if modified, but this is rarely used (and has security flaws that make it undesirable).

Be sure to address threading issues with the particular part of code or data you are modifying.

As a note specific to directly calling ix86ver, there are a number of input validation errors (crashes on certain formula variations, and a reliance on the caller to properly validate the length of a formula string to avoid a buffer overflow) and memory leaks in that particular module that make it less than ideal to use directly, especially if you connect to untrusted (third party) Battle.net-compatible servers or have a long-running program that will make many calls to the version check module.
September 17, 2006, 4:57 PM
Myndfyr
If I wrote a call instruction over the first few bytes of GetModuleFileName, it would corrupt the stack, right?  Because it would push the return address onto the stack, and I wouldn't have the parameters I expected?

Would a jmp instruction be better?
September 17, 2006, 9:07 PM
Skywing
It would not corrupt the stack.  You would have a frame that would be like, assuming x86 and you patched the start of GetModuleFileNameA

[esp+0] GetModuleFileNameA+5
[esp+4] callsite return address of GetModuleFileNameA call, which may be a pointer into ix86ver, or perhaps a pointer to some other module
[esp+8] hModule
[esp+c] lpFilename
[esp+10] nSize

So, you could still access those if you needed to.

Be sure to restore the stack and parameter values on the stack appropriately when you return, either to the caller or into GetModuleFileNameA.  Also, make sure that you run whichever instruction(s) were ruined by writing 5 bytes over the start of GetModuleFileNameA, which may be more than 5 bytes worth of instructions - need to make sure that you keep track of instruction level boundaries.  Libraries such as Detours (or other disassembly libraries) are useful for this sort of patching.
September 18, 2006, 4:35 AM

Search