为什么要获取导出函数的指针直接返回同一模块中的地址?

时间:2019-01-21 11:32:25

标签: c++ dll direct3d dll-injection

我正在使用经典的设置来挂接d3d9函数:注入DLL,然后获取目标函数地址,并使用JMP指令对其进行修补。

但是我遇到了我不太了解的事情。考虑以下我将注入到目标进程中的DLL中的片段:

HMODULE ModuleBasedOnGetAPI = NULL;
HMODULE ModuleBasedOnAddress = NULL;

ModuleBasedOnGetAPI = GetModuleHandleA("d3d9.dll");
D3D9Create_Original = (t_D3D9Create)GetProcAddress(ModuleBasedOnGetAPI,
                      "Direct3DCreate9");

D3D9Create_Original2 = &Direct3DCreate9;
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
                   GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                   (LPCSTR)D3D9Create_Original2, &ModuleBasedOnAddress);

char ModuleBasedOnGetAPI_path[_MAX_PATH];
GetModuleFileNameA(ModuleBasedOnGetAPI, ModuleBasedOnGetAPI_path, _MAX_PATH);

char ModuleBasedOnAddress_path[_MAX_PATH];
GetModuleFileNameA(ModuleBasedOnAddress, ModuleBasedOnAddress_path,
                  _MAX_PATH);

其中D3D9Create_Original和D3D9Create_Original2是类型的函数指针:

IDirect3D9*(__stdcall *)(UINT)

基本上,我执行了通常的GetModuleHandle调用,并获得了该文件的名称。然后我得到了函数指针,并使用GetModuleHandleExGET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS来基本确定该地址来自哪个DLL。

因此ModuleBasedOnGetAPI_path是d3d9.dll文件的实际路径。 尽管ModuleBasedOnAddress_path似乎是我提取此摘录的DLL的路径。

那为什么呢?为什么Direct3DCreate9函数既驻留在我的DLL中又驻留在d3d9.dll中?构建DLL时我链接了d3d9.lib是否与事实有关?

1 个答案:

答案 0 :(得分:0)

您的构建配置是什么(即调试或发布)?看起来编译器的优化在这里也很重要。

对于发布版本,我无法重现该问题-这两个地址相同。

对于Debug版本,您的假设是正确的。这是因为当您直接在代码中引用Direct3DCreate9时,您是在自己的模块中调用存根代码,这将进一步从Import Address Table获取真实的Direct3DCreate9地址。

为了更好地说明这一概念,

enter image description here

请注意,Visual Studio已经告诉您这两个地址来自不同的模块。

让我们看看地址0x008f1249

enter image description here

不超过jmp。进一步查看0x08FCFAD

enter image description here

另一跳。最后0x0913220

enter image description here

请记住D3D9Create_Original的值-这是与D3D9Create_Original相同的真实地址。