c++ - 如何解决转发的 WinAPI 的循环依赖?

标签 c++ winapi dll portable-executable

我正在尝试找到一种方法来解析映射到进程中的特定 API 的内存地址和 DLL 文件名。大多数问题可以通过 DLL 中的导入/导出表以及分析映射模块的导入地址表来解决。这适用于大多数功能。

但问题发生在某些 forwarded functions 上.这种功能的一个例子恰好是 DeleteProcThreadAttributeList在我的 Windows 10 系统上。因此,例如,如果我用这样的函数构建一个测试 32 位进程,或者更好,让我们使用 cmd.exe 的 32 位版本。来自 c:\windows\syswow64\cmd.exe图像,然后尝试分析其导入表。事实证明,这个函数是从 API Set 导入的,虚拟名称为 API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL :

enter image description here

要找到它重定向到的实际文件,我执行以下操作:

HMODULE hMM = ::LoadLibraryEx(L"API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL", 
    NULL, DONT_RESOLVE_DLL_REFERENCES);
WCHAR buffModPath[MAX_PATH];
::GetModuleFileNameEx(::GetCurrentProcess(), hMM, buffModPath, _countof(buffModPath));
::FreeLibrary(hMM);

这给了我 buffModPath作为C:\Windows\System32\KERNEL32.DLL .

因为我是从 32 位进程调用它,所以我现在检查 c:\windows\syswow64\KERNEL32.DLL 的导出表模块:

enter image description here

这表明DeleteProcThreadAttributeList转发给api-ms-win-core-processthreads-l1-1-0.DeleteProcThreadAttributeList .

好的,然后我再次使用我的方法来解决虚拟 api-ms-win-core-processthreads-l1-1-0.dll 的重定向API 集:

HMODULE hMM = ::LoadLibraryEx(L"api-ms-win-core-processthreads-l1-1-0.dll", 
    NULL, DONT_RESOLVE_DLL_REFERENCES);
WCHAR buffModPath[MAX_PATH];
::GetModuleFileNameEx(::GetCurrentProcess(), hMM, buffModPath, _countof(buffModPath));
::FreeLibrary(hMM);

这给了我 C:\Windows\System32\KERNEL32.DLL ,这让我回到了起点。

那么我该如何解决这种对实际 DLL 地址/入口点的循环依赖,就像操作系统模块加载器那样?

最佳答案

我认为如果您 GetProcAddress 这些导出之一应该是一个黑盒子,那么无论发生什么情况。

PEB 在 Windows 7+ 中有一个 ApiSetMap 成员,其中包含加载程序使用的设置信息。此数据的格式至少更改了 3 次,但映射不仅仅是从“API-*.dll”到“*32.dll”。

你可以阅读这个概念的微软专利here .

关于c++ - 如何解决转发的 WinAPI 的循环依赖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48184822/

相关文章:

c++ - 将 'override' 用于已使用 'typedef' 声明的函数

c - NULL_PEN 和 PS_NULL 有区别吗?

dll - ERROR_INVALID_ORDINAL 究竟是什么意思?

c# - 如何替换dll中的类?

c++ - 在构建过程中是否可以在没有可执行文件的情况下对 dll 的方法执行单元测试?

python - Cython:将字符值转换为字符串的最快方法

c++ - 将转换应用到 PolyData

python - EnumDisplayDevices 提供两个显示器,即使我有一个

c++ - "cdecl"代表什么?

c++ - 如何在 C++ 中从 dll(dll 中的构造函数)创建一些类?