C++ Function Hook (memory address only)
Asked Answered
S

2

7

I have a memory address, its the memory address of a function in another program (one of its dlls). I am already loaded into the program via DLL injection. I already have the bass address, and the actual location of the function each time the program loads. So, this is not an issue.

I want to just simply hook that location, and grab the variables. I know the function's pseudocode. So this is not an issue. OR another approach that would be great is doing a break point at that memory location and grab the debug registers.

I can not find any clear-cut examples of this. I also do not have the "name" of the function, I just have the memory address. Is there any way to work with just a memory address? Most, if not all the examples have you use the name of the function, which I do not have.

If anyone could point me into the right direction so I can accomplish this task, I would greatly appreciate it. It also might help a lot of other people who may have the same question.

Edit: I should also mention that Id rather not overload my program with someone else code, I really just want the barebones, much like a basic car with roll-up windows. No luxury packages for me please.

Scrawl answered 23/10, 2012 at 8:22 Comment(1)
you probably have to cast the address to the function prototype. If it's a class member function you would need to use .* or ->* to invoke it.Questor
C
7

You missed the most important part, is this for 32 or 64 bit code? In any case, the code project has a good run-down and lib here that covers both.

If you want to do this "old-school", then it can be done quite simply:

firstly, you need to find the virtual address of the function you want to hook (due to ASLR, you should never rely on it being in the same place), this is generally done with RVA + module base load address for function that are not exported, for exported functions, you can use GetProcAddress.

From there, the type hook depends on what you want to accomplish, in your case, there are two methods:

  1. patch a jump/call out to your function in the target function' prologue
  2. patch all call sites to the function you want to hook, redirecting to your function

the first is simpler, but messy as it generally involves some inline assembly (unless you are hooking a /HOTPATCH binary or you just want to stub it), the second is much cleaner, but requires a bit of work with a debugger.

The function you'll jump out to should have the same parameters and calling convention (ABI) as the function you are hooking, this function is where you can capture the passed parameters, manipulate them, filter calls or whatever you are after.

for both, you need a way to write some assembly to do the patching, under windows, WriteProcessMemory is your first port of call (note: you require RWX permissions to do this, hence the calls to VirtualProtect), this is a little utility function that creates a 32bit relative call or jump (depending on the opcode passed as eType)

#pragma pack(1)
struct patch_t
{
    BYTE nPatchType;
    DWORD dwAddress;
};
#pragma pack()

BOOL ApplyPatch(BYTE eType, DWORD dwAddress, const void* pTarget)
{
    DWORD dwOldValue, dwTemp;
    patch_t pWrite =
    {
        eType,
        (DWORD)pTarget - (dwAddress + sizeof(DWORD) + sizeof(BYTE))
    };

    VirtualProtect((LPVOID)dwAddress,sizeof(DWORD),PAGE_EXECUTE_READWRITE,&dwOldValue);
    BOOL bSuccess = WriteProcessMemory(GetCurrentProcess(),(LPVOID)dwAddress,&pWrite,sizeof(pWrite),NULL);
    VirtualProtect((LPVOID)dwAddress,sizeof(DWORD),dwOldValue,&dwTemp);
    return bSuccess;
}

This function works great for method 2, but for method 1, you'll need to jump to an intermediary assembly trampoline to restore any code that the patch overwrote before returning to the original function, this gets very tedious, which is why its better to just use an existing and tested library.

From the sounds of it, using method 1 and patching a jump over the prologue of your target function will do what you need, as it seems you don't care about executing the function you patched.

(there is a third method using HW breakpoints, but this is very brittle, and can become problematic, as you are limited to 4 HW breakpoints).

Contredanse answered 23/10, 2012 at 8:27 Comment(5)
This should be a comment, not an answer.Eng
@thecoshman: the first part yes, but the second part answers the question.Contredanse
Are you absolutely sure this works with just memory locations? In the examples I see them using names of the functions to search for in the DLL, which I do not have.Scrawl
@Ohmages: yes, instead of using GetProcAddress, you'd just cast the VA of the function to hook to a void*/ULONG_PTRContredanse
Thanks for such an in-depth overview of what needs to happen. I really do appreciate this, and I am sure other people do to.Scrawl
Q
0

Your "sample" is here:

http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces#section_1

Normally when you "hook" into the DLL, you actually put your function in front of the one in the DLL that gets called, so your function gets called instead. You then capture whatever you want, call the other function, capture its return values and whatever else, then return to the original caller.

Questor answered 23/10, 2012 at 8:35 Comment(1)
I do not want to call the function, only to hook it to grab whatever was pushed to it.Scrawl

© 2022 - 2024 — McMap. All rights reserved.