2013-04-26 122 views
0

我已经反编译了一个dll,我想用我创建的自定义函数(具有相同的签名)替换对DLL中某个函数的调用。替换反编译DLL中的函数

我已经设法找到在汇编中调用函数的位置。任何人都可以解释我现在需要做什么吗?

我的自定义函数可以位于单独的dll中,还是需要包含在同一个dll中?

如何调用我的新函数来调用函数调用?

谢谢

+1

可能更容易修补DLL。将新代码添加到文本段的末尾,并在开始时将旧代码添加到旧函数中。 – 2013-04-26 23:05:38

+0

其实我只是意识到这不是一个选项。它需要跳转到或从另一个dll调用一个函数。那可能吗? – Lukesmith 2013-04-26 23:28:29

+0

如果你可以用更多的_details_来更新你的问题,你想从外部DLL调用函数,我会更新我的答案以反映这些变化。 – 2013-04-26 23:30:53

回答

3

可能更容易只修补可执行模块。将新代码添加到文本段的末尾,并在开始时将旧代码添加到旧函数中。这样你就不必处理反编译的DLL版本可能导致的问题。

例如这里是要替换现有的函数的开头:

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 

要重新定向呼叫只是在D0880添加JMP指令。在跳转后添加NOP指令只是为了在调试会话期间使反汇编输出更清晰。这不是必要的,但确实派上用场。

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

现在,您将新代码附加到文本段的末尾,并根据段加载的偏移量计算地址。这使得调试和管理变得更加容易,因为您事先知道函数实际驻留在文本段中的哪个位置。

也可以调用另一个进程内可执行模块中的任意一个函数。由于您已经知道原始函数和下一个函数的偏移量,因此可以根据模块的加载地址计算其确切位置。

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); 

功能CalculateAddress检索DLL的基地址并计算功能的实际地址,并返回指向它的指针。结果与前面的例子相同 - 0xD0880。既然你有地址,你可以通过函数指针调用它。您也可以应用相同的技巧来调用您添加的新函数,因为您也知道该函数的偏移量。

如果你想多走一步,你甚至可以使用指向这些偏移量的新条目更新导出表,并使用GetProcAddress来检索地址,而无需自己计算。这会增加修补过程的复杂性,因为您必须更新DLL中的附加部分。

调用存在于另一个DLL中的函数会稍微复杂一些,因为您需要对原始函数的运行时补丁进行调用以使其调用外部函数的地址。为此,我建议查看Rich所提出的建议,并创建一个代理DLL,如this文章中所述。

+0

好的答案,但我只是意识到我确实需要其他功能在一个不同的DLL。有没有什么办法可以在不同的dll中调用函数? – Lukesmith 2013-04-26 23:40:32

+0

我已经扩展了从外部DLL的函数调用的答案,以及使用代理DLL调用外部模块中的函数的答案(谢谢Rich建议!) – 2013-04-27 00:00:02

+0

Dude真棒答案。你能解释我如何编辑导出表?看起来这可能是一个很简单的方法,因为我可以将我感兴趣的函数添加到导出表中,然后在外部访问它。 – Lukesmith 2013-04-27 12:15:01