我正在弄一个简单的应用程序。
到目前为止,到目前为止,我已经为自己创建了一个代码凹坑,以添加一些代码。
但是每当我尝试在调试的可执行模块之外创建对某个函数的调用时,例如对
kernel32
或msvcrt
函数的调用,都会使一切混乱。在应用程序中:0041D654 FF15 DC714200 CALL DWORD PTR DS:[<&KERNEL32.GetCommandLineA>]
当我双击它时,它显示我
CALL DWORD PTR DS:[4271DC]
,所以,
4271DC
似乎指向76FB496D
,实际上是: br /> 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]
。允许运行该程序当然是可以的,但是每当我在另一台PC上这样运行时,一切都会崩溃。当然,我可以在应用程序中使用CALL DWORD PTR DS:[4271DC]
来调用函数CALL DWORD PTR DS:[4271DC]
,但是我不知道指向getcomandlineA
的(动态指针)。 /> #1 楼
004271DC的地址是在应用程序启动时通过可执行的Imports解析的。对于每个可执行文件,这些地址都不同。也不保证模块和功能的加载地址(此处为76FB496D)始终保持不变,因此您不应该对其进行硬编码。在任何可执行文件中调用函数的通用方法是使用LoadLibrary和GetProcAddress动态导入它,如下所述:https://stackoverflow.com/questions/8696653/dynamically-load-a-function -from-a-dll
#2 楼
如果只想使用一个CALL
,则需要确保目标API函数是静态导入的。您可以使用IIDKing之类的工具将目标API函数添加到PE文件的静态导入中。#3 楼
出于各种原因,对硬编码地址的调用将不起作用,最明显的是ASLR,它使每个DLL的基地址随机化,这意味着函数地址在每次启动时都会不同。这个问题绝非易事,因为开发人员通常用于动态导入DLL的
LoadLibrary
和GetProcAddress
的使用也将具有动态地址,因此您不能使用它们来确定所需函数的地址。要解决此问题,您必须使用shellcode技术;换句话说,您将必须包含用于解析
PEB
结构的汇编代码,以确定Kernel32地址的基地址,在导出表中搜索您的函数并最终使用它。更复杂的用法是使用反射性DLL注入,但与您要查找的内容有点不同。
评论
您可以通过在PE编辑器(例如CFF Explorer)中进行编辑来禁用ASLR。然后它将在所有计算机上运行。启用ASLR后,您可以执行以下操作找到LoadLibrary函数:code.google.com/p/w32-dl-loadlib-shellcode/source/browse/trunk / ...