我试图从汇编代码中调用 USER32.DLL 函数。我在 Ollydbg 2.01 中启动了一个应用程序(calc.exe)。我选择 calc.exe 只是因为我知道它会加载 USER32.DLL。
我看到的格式为:
MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, uType);
hWnd=0 usually "If this parameter is NULL, the message box has no owner window"
uType = MB_OK =0 for OK button only
我将 4 个值压入堆栈,然后尝试将以下内容输入 Olly:
CALL DWORD PTR DS:[<&USER32.MessageBoxA>]
但是 Olly 不会组装它并给我错误“请指定模块”(如链接中所示)
编辑:看来我不能使用 Olly 反汇编的确切语法。例如,calc.exe 调用 USER32.MessageBeep,但它通过使用存储在 00121420 = &USER32.MessageBeep 的地址来间接调用。
00145C19 |. FF15 20141200 CALL DWORD PTR DS:[<&USER32.MessageBeep> ; \USER32.MessageBeep
为了让 Olly 创建相同的指令,我会双击并组合:
CALL DWORD PTR DS:[00121420]
接着
00145C19 |. FF15 20141200 CALL DWORD PTR DS:[<&USER32.MessageBeep> ; \USER32.MessageBeep
会出现。如果我能弄清楚如何输入标签 USER32.MessageBeep 而不是寻找它并复制/粘贴地址,那就太好了。
在人们可以简单地调用加载的 DLL 中的函数之前,似乎还有更多的知识需要了解。当我看到人们在 Olly 中编辑补丁来调用来自其他模块的过程时,他们似乎只调用了原始程序已经调用的过程,而对于带有 MessageBoxA 的 USER32.DLL,我面临着它不在内存中的额外挑战。当我尝试调用消息框时,我得到了奇怪的结果(它出现在背景中但不会让鼠标靠近它并返回到一个奇怪的地址 90909090 - 可能是由于我的下一个指令操作码)。也许这种奇怪的行为是因为它需要对程序没有完成的消息框进行一些设置。
所以也许我的问题的答案取决于该过程是否已经以某种方式被原始程序加载。在 Blabbb 的回答中,他/她使用的是 notepad.exe 而不是 calc.exe。
我的问题可能越来越不集中,但也许对我的问题的一个很好的回答可以解释其他模块是如何加载的,以及如何在 Ollydbg 中实现这一点。我仍在学习如何将 PE 应用程序加载到内存中,但我想知道答案是否是在模块之间我们不应该期望看到相对的 CALL 操作码 E8(参见下面 blabbb 的评论),因为程序员不知道什么地址在内存中,DLL 过程将被加载到,而在原始程序中,它们必须通过带有操作码 FF15 的间接 CALL 间接调用。我认为这可能与“可能注册 DLL 函数?”的行为有关。在 calc.exe 中,看起来 MessageBoxA 不能被间接调用(除非我用它的地址在某处编辑内存)。
在我使用 calc.exe 的情况下,我在内存的 calc .text 部分看到了一些(但不是全部)USER32.DLL 过程。程序似乎通过此列表间接调用它们。例如这里有一些 USER32
使用 calc.exe 我在这里找不到 MessageBoxA,但是如果我在 USER32.DLL 模块中查找它的地址,并选择名称(见下文)
我可以按名称排序,然后开始输入名称,以便它为我找到它
然后组装调用 7634FD1E
00148C40 6A 00 PUSH 0
00148C42 68 598C1400 PUSH 00148C59 ; ASCII "cap"
00148C47 68 5D8C1400 PUSH 00148C5D ; ASCII "text"
00148C4C 6A 00 PUSH 0
00148C4E E8 CB702076 CALL MessageBoxA