• Welcome to Valhalla Legends Archive.
 

Hooking an API with VirtualProtect?

Started by MyndFyre, September 17, 2006, 07:12 AM

Previous topic - Next topic

MyndFyre

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?
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

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.

MyndFyre

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?
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

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.