Как разрешить циклическую зависимость перенаправленного WinAPI?
Я пытаюсь найти способ разрешения адреса памяти и имени файла DLL для конкретного API, когда он отображается в процесс. Большая часть этого может быть решена с помощью таблиц импорта / экспорта в DLL и путем анализа таблицы адресов импорта сопоставленного модуля. Это для большинства функций.
Но проблема возникает с некоторыми перенаправленными функциями. Примером такой функции является DeleteProcThreadAttributeList
в моей системе Windows 10. Так, например, если я создаю тестовый 32-битный процесс с такой функцией, или еще лучше, давайте использовать 32-битную версию cmd.exe
от c:\windows\syswow64\cmd.exe
изображение, а затем попробуйте проанализировать его таблицу импорта. Оказывается, эта функция импортирована из набора 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, как это делает загрузчик модуля ОС?
1 ответ
Я думаю, что бы ни случилось, если ты GetProcAddress
один из этих экспортных товаров должен быть черным ящиком.
У PEB есть член ApiSetMap в Windows 7+, который содержит информацию о наборе, которую использует загрузчик. Формат этих данных изменялся как минимум 3 раза, но сопоставление не только от "API-*. Dll" до "*32.dll".
Вы можете прочитать патент Microsoft на эту концепцию здесь.