问题
I'm trying to find a way to resolve a memory address and a DLL file name for a particular API when it's mapped into a process. Most of this can be resolved with the import/export tables in a DLL and by analyzing the Import Address Table of a mapped module. That is for most functions.
But the issue happens with some forwarded functions. An example of such function happens to be DeleteProcThreadAttributeList
on my Windows 10 system. So for instance, if I build a test 32-bit process with such function, or better yet, let's use a 32-bit version of cmd.exe
from c:\windows\syswow64\cmd.exe
image, and then try to analyze its import table. It turns out that this function is imported from the API Set with a virtual name API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL
:
To find an actual file that it redirects to I do the following:
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);
Which gives me buffModPath
as C:\Windows\System32\KERNEL32.DLL
.
Since I'm calling it from a 32-bit process, I now inspect the export table of c:\windows\syswow64\KERNEL32.DLL
module:
that shows that DeleteProcThreadAttributeList
is forwarded to api-ms-win-core-processthreads-l1-1-0.DeleteProcThreadAttributeList
.
OK, I then use my method again to resolve redirection of the virtual api-ms-win-core-processthreads-l1-1-0.dll
API set:
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);
Which gives me C:\Windows\System32\KERNEL32.DLL
, that brings me back to where I started.
So how do I resolve this circular dependency to actual DLL address/entry point the way OS module loader does it?
回答1:
I think whatever happens if you GetProcAddress
one of these exports is supposed to be a black box.
The PEB has a ApiSetMap member in Windows 7+ that contains set information that the loader uses. The format of this data has changed at least 3 times but the mapping is not just from "API-*.dll" to "*32.dll".
You can read the Microsoft patent of this concept here.
来源:https://stackoverflow.com/questions/48184822/how-to-resolve-circular-dependency-of-a-forwarded-winapi