我已经反编译了一个dll,我想用我创建的自定义函数(具有相同的签名)替换对DLL中某个函数的调用。替换反编译DLL中的函数
我已经设法找到在汇编中调用函数的位置。任何人都可以解释我现在需要做什么吗?
我的自定义函数可以位于单独的dll中,还是需要包含在同一个dll中?
如何调用我的新函数来调用函数调用?
谢谢
我已经反编译了一个dll,我想用我创建的自定义函数(具有相同的签名)替换对DLL中某个函数的调用。替换反编译DLL中的函数
我已经设法找到在汇编中调用函数的位置。任何人都可以解释我现在需要做什么吗?
我的自定义函数可以位于单独的dll中,还是需要包含在同一个dll中?
如何调用我的新函数来调用函数调用?
谢谢
可能更容易只修补可执行模块。将新代码添加到文本段的末尾,并在开始时将旧代码添加到旧函数中。这样你就不必处理反编译的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文章中所述。
可能更容易修补DLL。将新代码添加到文本段的末尾,并在开始时将旧代码添加到旧函数中。 – 2013-04-26 23:05:38
其实我只是意识到这不是一个选项。它需要跳转到或从另一个dll调用一个函数。那可能吗? – Lukesmith 2013-04-26 23:28:29
如果你可以用更多的_details_来更新你的问题,你想从外部DLL调用函数,我会更新我的答案以反映这些变化。 – 2013-04-26 23:30:53