按地址调用函数失败

calling function by address fails

本文关键字:失败 函数 调用 地址      更新时间:2023-10-16

我正在阅读CodeProject上的各种东西,我发现了这篇文章:http://www.codeproject.com/Articles/29527/Reverse-Engineering-and-Function-Calling-by-Addres

所以我所做的就是创建一个注入器和一个DLL,并获取示例可执行文件。当你按下F11时,它基本上输出如下:https://i.stack.imgur.com/YIygV.jpg

所以我遵循了整个教程,但问题是DLL中使用的地址总是在变化。具体来说:

pFunctionAddress pMySecretFunction = (pFunctionAddress)(0x004113C0);

在他的教程中,函数的地址是0x004113C0。在我心中,它是另一种东西,我拿起我所拥有的,并使用它。它工作得很好,但是当我关闭可执行文件并打开它时,它不再工作了,OllyDbg显示地址是一个全新的地址。

所以我研究了一下,我开始用OllyDbg添加断点。我发现地址总是会是:

main + 4C

我猜"main"是这些可执行文件的主模块。我怎么才能找到函数的地址呢?因为它一直在变,而我现在一点头绪都没有。在这篇文章中,我读到它没有经历当可执行文件被重新打开时会发生什么,我花了5个小时试图找到一个解决方案。

提前感谢!

编辑:

非常感谢大家。特别感谢mfc,我终于弄清楚了!我最后做的是,每当我点击DLL_PROCESS_ATTACH时,我将一个全局HMODULE设置为可执行文件的地址,如下所示:

HMODULE g_hExeModule;
g_hExeModule = GetModuleHandle(L"TutExample.exe");

经过几次测试后,似乎函数地址总是可执行文件的地址+ 0x11014,所以在调用中我只做:

pFunctionAddress pMySecretFunction = (pFunctionAddress)((DWORD)g_hExeModule + 0x11014);

所以如果我找到一种方法来获得"main"的地址,我可以添加一个4C偏移量,函数将始终在那里,我认为

同样,函数有一个地址:
void *(funcPtr)() = (void (*)())((char *)&main +  0x4C);
// If you were right, and you also substituted the appropriate
// function signature above, then this should work:
funcPtr();

您试图调用的函数在exe文件内部,因此引用偏移量应该相对于exe加载的内存地址。目标函数的偏移量应该是一个常量,只有在每次编译源代码后才会改变。

要查找有关exe的更多信息,请在exe中添加以下两行:

printf(_T("Exe loaded at: %08X"), GetModuleHandle(_T("TutExample.exe")));
printf(_T("Target function at: %08X"), mySecretFunction);

我不能编辑我的帖子,也不能添加任何评论,所以我不得不把这个作为一个新的答案发布。

你结果:

Exe loaded at: 00000000 (wrong, probably: 00BE0000 and offset is: 00001005)
Target function at: 00BE1005
Exe loaded at: 00000000 (wrong, probably: 01230000 and offset is: 00001005)
Target function at: 01231005
Exe loaded at: 00000000 (wrong, probably: 012A0000 and offset is: 00001005)
Target function at: 012A1005

请检查您编译的exe的名称,它是"TutExample.exe"吗?如果不是,则在调用GetModuleHandle时将其更改为确切的名称。

"00000000"表示GetModuleHandle失败,因为在当前内存空间中找不到名称"TutExample.exe"。

目标函数的地址似乎没有问题。只要用加载的exe的地址减去这个地址,你就会得到exe内存布局中的偏移量。

您可以在注入的dll中执行相同的数学运算,以始终正确地跟踪目标函数地址,无论操作系统如何加载exe

较新的操作系统有一个称为ASLR(地址空间布局随机化)的功能。犯罪分子使用了你正在使用的一些技巧。因此,为了让坏人的日子更不好过,每次运行程序时,EXE和DLL都会被分配一个不同的地址。

如果你编译了DLL,有一个选项来禁用你的DLL的ASLR