无法在 ollydbg 中(正确)调用函数

逆向工程 ollydbg
2021-07-06 01:16:31

我需要一些有关 Ollydbg 汇编调用的帮助。我正在搞一个简单的应用程序。到目前为止,太好了,我为自己创建了一个 codecave 来添加一些代码。

但是,每当我尝试创建对调试的可执行模块之外的函数的调用时,例如 a kernel32ormsvcrt函数,它都会把一切搞砸。

让我们看看应用程序中的一些随机调用:

0041D654     FF15 DC714200  CALL DWORD PTR DS:[<&KERNEL32.GetCommandLineA>]

当我双击它时,它向我显示CALL DWORD PTR DS:[4271DC] 所以,4271DC似乎指向76FB496D,这确实是:

76FB496D >-FF25 60070177    JMP DWORD PTR DS:[<&api-ms-win-core-processenvironment-l1-2-0.Get> ;KERNELBA.GetCommandLineA

好吧,我只是从应用程序本身中窃取了它。现在我想给kernel32自己打电话我组装一条线并输入CALL DWORD PTR DS:[Kernel32.GetCommandLineA] 现在它说:

0041D654     FF15 6D49FB76  CALL DWORD PTR DS:[KERNEL32.GetCommandLineA]

看起来不错!

组装线CALL DWORD PTR DS:[76FB496D]运行它当然很好,但是每当我在另一台电脑上像这样运行它时,一切都会崩溃。

我的问题是:如何制作这样的指针CALL DWORD PTR DS:[4271DC],以便代码在所有电脑上运行?

我当然可以CALL DWORD PTR DS:[4271DC]在应用程序中随时使用来调用该函数getcomandlineA,但我不知道(动态?)指针,比方说,kernel32.lstrcpy

3个回答

004271DC 处的地址在应用程序启动时通过可执行导入解析。这些地址对于每个可执行文件都是不同的。加载模块和函数的地址(此处为 76FB496D)也不能保证始终保持不变,因此您不应对其进行硬编码。

在任何可执行文件中调用函数的通用方法是使用 LoadLibrary 和 GetProcAddress 动态导入它,如下所述:https : //stackoverflow.com/questions/8696653/dynamically-load-a-function-from-a-dll

如果您只想使用单个CALL,则需要确保您的目标 API 函数是静态导入的。您可以使用IIDKing 之类的工具将目标 API 函数添加到 PE 文件的静态导入中。

调用硬编码地址会因为不同的原因而不起作用,最明显的是ASLR,它随机化每个DLL的基地址,这意味着每次启动时函数地址都会不同。

解决这个问题远没有使用LoadLibraryand 那么简单GetProcAddress,开发者经典使用的动态导入 DLL 也会有动态地址,所以你不能用它们来确定你想要的函数的地址。

要解决这个问题,你必须使用 shellcode 技术;换句话说,您必须包含解析PEB结构的汇编代码,以确定 Kernel32 地址的基地址,在导出表中搜索您的函数并最终使用它。

另一种用于更复杂使用的更高级技术是使用反射 DLL 注入,但它与您所寻找的相差甚远。