Lukesmith
Lukesmith

Reputation: 170

Replacing a function in a decompiled DLL

I have decompiled a dll and I want to replace a call to a function in the DLL with call a custom function created by me (with the same signature) instead.

I have managed to find where the function is called in assembly. Could anybody explain what I need to do now?

Can my custom function be located in a separate dll or does it need to be included in the same dll?

How can I call replace the function call with my new one?

Thanks

Upvotes: 1

Views: 2255

Answers (1)

Captain Obvlious
Captain Obvlious

Reputation: 20063

Might be easier to just patch the executable module. Add your new code to the end of the text segment and place a jump to your added code at the beginning to the old function. This way you don't have to deal with problems the decompiled version of the DLL may cause.

For example here is the beginning of the existing function you want to replace:

000D0880  push        ebp  
000D0881  mov         ebp,esp  
000D0883  sub         esp,0E0h  
000D0889  push        ebx  
000D088A  push        esi  
000D088B  push        edi  
000D088C  lea         edi,[ebp-0E0h]  
000D0892  mov         ecx,38h  
000D0897  mov         eax,0CCCCCCCCh

To redirect the call just add a JMP instruction at D0880. We add NOP instructions after the jump just to make the disassembled output cleaner during debug sessions. It's not necessary but it does come in handy.

000D0880  jmp         NewFunction
000D0885  nop
000D0886  nop
000D0887  nop
000D0888  nop
000D0889  push        ebx  
000D088A  push        esi  
000D088B  push        edi  

Now you append your new code to the end of the text segment and calculate the address based on the offset where the segment is loaded. This makes it much easier to debug and manage since you know beforehand exactly where in the text segment your function actually resides.

To call either function from another in-process executable module can also be done. Since you already know the offsets of both the original function and the next function you can calculate their exact location based on the load address of the module.

typedef void (*EXTPROC)(int a, int b);

// Windows loads the dll at 0xC0000
HMODULE hMod = LoadLibrary("some.dll"); 
// The function is at offset 0x10880 (from start of text segment)
EXTPROC proc = CalculateAddress(hMod, 0x00010880);
// Call proc at 0xd0880
proc(0, 1);

The function CalculateAddress retrieves the base address of the DLL and calculates the actual address of the function and returns pointer to it. The result is the same as in the earlier example - 0xD0880. Now that you have the address you can call it through the function pointer. You can apply the same technique to call the new function you are adding as you know the offset of that function as well.

If you wanted to go the extra mile you could even update the export table with new entries pointing to those offsets and use GetProcAddress to retrieve the address without having to calculate it yourself. This adds a bit more complexity to the patching process since you have to update an additional section in the DLL.

To call a function that exists in a different DLL is a bit more complex as you would need to do a runtime patch of the original function to make it call the address of the external one. For this I recommend looking into the suggestion made by Rich and create a proxy DLL as described in this article.

Upvotes: 5

Related Questions