c ++ - 按地址调用函数失败

时间:2013-01-10 23:29:22

标签: c++ memory-address

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

所以我做的是创建了一个注入器和一个DLL,并抓取了示例可执行文件。当你按F11时它基本上输出这个: http://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);

4 个答案:

答案 0 :(得分:1)

  

所以,如果我找到一种方法来获取“主”的地址,我可以添加一个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();

答案 1 :(得分:1)

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

要了解有关您的exe的更多信息,请将以下两行添加到您的exe:

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

答案 2 :(得分:0)

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

如果您编译了DLL,则可以选择为您的DLL禁用ASLR。

答案 3 :(得分:0)

我无法编辑我的帖子,也无法添加任何评论,因此我必须将此作为新答案发布。

你的结果:

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中执行相同的数学计算,无论os如何加载exe,都可以正确跟踪目标函数地址。