Как разрешить циклическую зависимость перенаправленного 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 на эту концепцию здесь.

Другие вопросы по тегам