17

I have a small problem. I have loaded DLL into the process (it's not mine) and I have to use function inside it. I have got offset to this function so only what I have to do is to get DLLs address and add to it the offset to get to the function. GetModuleHandle() returns HMODULE variable but actually I don't know what HMODULE is. Is it address of loaded DLL or some kind of other mark?

And if it's not address of place where DLL is loaded, how can I get this address? I hope I make myself clear.

Chan Kim
  • 5,177
  • 12
  • 57
  • 112
Blood
  • 4,126
  • 3
  • 27
  • 37

3 Answers3

13

The method that you propose will work fine.

It seems that you have injected a dll into a target process and wish to obtain the address of a function in that dll in the target process from the process that injected the dll.

I assume that you also have the dll loaded in the process that injected the dll into the target process and that you want to create a remote thread in the target process and get it to execute the target function in the target process.

Since the dll that you have injected may not be loaded at the same address in the target process as it is in the injecting process you cannot simply use the address that you would obtain from calling GetProcAddress on the function in the injecting process.

An HMODULE is just the DLL's base address (see this answer for details). So you can take the HMODULE of the dll in your injecting process and subtract it from the address returned by GetProcAddress on your function. You can then add the HMODULE of the injected dll in the target process to this offset to get the address of the target function in the injected dll in the target process. Assuming this function has the correct signature, pass it as the thread function to your call to create the remote thread and you are now running the target function in the target process.

I explain this in more detail in this answer.

Community
  • 1
  • 1
Len Holgate
  • 21,282
  • 4
  • 45
  • 92
  • Thanks. I've got another problem. When i'm doing like this -> http://wklej.org/id/700802/ i'm getting wrong sum. Should i do it like that -> http://wklej.org/id/700803/ ?? – Blood Mar 03 '12 at 14:08
  • @Blood: Neither of those things make any sense. You've added the offset (to go from the base to the function) but forgot to subtract it (to get the base in the first place). See my answer. Since you have to do both, and they cancel out, you might as well just not bother. – David Schwartz Mar 04 '12 at 00:31
  • 1
    David, the only time it cancels out is if the dll is loaded at the same base address in both processes. Otherwise my answer works and yours doesnt :). – Len Holgate Mar 04 '12 at 10:17
  • Blood, your problem is that you need to add the HMODULE of the dll in the target process; the easiest way to get this is simply to capture the return value of the remote thread that you started which called LoadLibrary to inject the dll into the target process. – Len Holgate Mar 04 '12 at 13:00
  • @LenHolgate: Where did a second process come from? His question doesn't involve two processes as far as I can tell. – David Schwartz Mar 06 '12 at 01:04
  • 1
    "I have loaded DLL into the process (it's not mine)". I thought the question could be phrased better, which is why I explained my understanding of his question in my answer. Though reading that phrase again it could equally be that the DLL isn't his - but I would have expected him to correct me rather than mark the answer as correct - who knows... – Len Holgate Mar 06 '12 at 09:04
  • Can you double check this? On 64 bit I remember casting a HMODULE to a pointer and found that the DLL wasn't there. – Joshua Oct 30 '21 at 21:01
  • Joshua, do you have code that shows the failure? This method has worked for me for years; though you may need to read this answer too: https://stackoverflow.com/a/1163681/7925 – Len Holgate Nov 01 '21 at 08:46
4

Call GetProcAddress. The offset cancels out, as you'd have to both add it (to get to the function) and subtract it (to get the base address), so you might as well not bother.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

It is similar to the void* returned by the POSIX dlopen() function (it might even be a typedef - but I don't know that for sure). You pass it to GetProcAddress as an argument. When you are done you also pass it to FreeLibrary to unload the DLL.

user7610
  • 25,267
  • 15
  • 124
  • 150
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636