C++ 如何解决转发的WinAPI的循环依赖关系?

C++ 如何解决转发的WinAPI的循环依赖关系?,c++,winapi,dll,portable-executable,C++,Winapi,Dll,Portable Executable,我试图找到一种方法来解析映射到进程中的特定API的内存地址和DLL文件名。大多数问题可以通过DLL中的导入/导出表以及分析映射模块的导入地址表来解决。这是大多数函数的情况 但问题发生在一些人身上。在我的Windows 10系统上,这种函数的一个例子就是DeleteProcThreadAttributeList。例如,如果我用这样的函数构建一个测试32位进程,或者更好,让我们使用c:\windows\syswow64\cmd.exeimage中的cmd.exe的32位版本,然后尝试分析它的导入表。

我试图找到一种方法来解析映射到进程中的特定API的内存地址和DLL文件名。大多数问题可以通过DLL中的导入/导出表以及分析映射模块的导入地址表来解决。这是大多数函数的情况

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

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

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
模块的导出表:

这表明
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”


您可以阅读此概念的Microsoft专利。

这是众所周知的事情,但您实际尝试得到的是什么?如果您想在函数实际实现的位置获得dll,只需调用
GetProcAddress
。然后可以将返回的地址与
GetMappedFileName
一起使用。如果想要确切的dll base-
RtlPcToFileHeader
@RbMm:那么,我也在尝试理解加载程序在内部做什么。查找-ParentName参数。相同的名称
api-ms-win-core-processthreads-l1-1-0
可以转换为
kernel32
kernelbase
依赖于ParentNameparameter@RbMm:是的,我看到
ApiseResolvetoHost
似乎就是那个未记录的API,它的输入自7年以来在每个Windows版本中都会发生变化。不过我很好奇,是否有一个记录在案的解决方法?还有,为什么
LoadLibraryEx
/
GetModuleFileNameEx
不这样做呢?这是您提出的一个非常优雅的解决方案。