手动填写DLL import table:IMAGE_IMPORT_DESCRIPTOR's Name field stores 0x0000FFFF
Fill in DLL import table manually: IMAGE_IMPORT_DESCRIPTOR's Name field stores 0x0000FFFF
我的目标是手动填写 Dll 的导入 table 以挂钩内部 LoadLibrary 调用(当您加载库时,它可能会在其 DllMain 中加载另一个库)。
这是我的代码,它为依赖层次结构中的每个 dll 递归地填充 Import table,它工作正常,除了一些 dll (api-ms-win-crt- locale-l1-1-0.dll 在这种情况下)。
void PEUtility::fillImportTable(HMODULE loadedModule, FillImportFlag flag, std::function<void(HMODULE&)> callback)
{
std::stack<HMODULE> modules;
modules.push(loadedModule);
while (modules.size())
{
auto module = modules.top();
modules.pop();
auto imageBase = (DWORD_PTR)module;
auto header = ImageNtHeader(module);
auto importTable = (PIMAGE_IMPORT_DESCRIPTOR)(DWORD_PTR)(header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + imageBase);
while (importTable->OriginalFirstThunk)
{
// !!!
// HERE I've got an error: importTable->Name stores 0x0000FFFF instead dll name
// !!!
auto importedModuleName = (char*)(DWORD_PTR)(importTable->Name + imageBase);
auto importedModule = GetModuleHandleA(importedModuleName);
if (!importedModule)
{
importedModule = LoadLibraryExA(importedModuleName, 0, DONT_RESOLVE_DLL_REFERENCES);
if (flag == FillImportFlag::Recursive)
modules.push(importedModule);
}
auto nameAddressPtr = (PIMAGE_THUNK_DATA)(DWORD_PTR)(importTable->OriginalFirstThunk + imageBase); //Import Lookup Table address (functions names)
auto functionAddressPtr = (PIMAGE_THUNK_DATA)(DWORD_PTR)(importTable->FirstThunk + imageBase); //Import Address Table (IAT) address (functions addresses)
while (nameAddressPtr->u1.Function)
{
FARPROC importedFunctionPtr = NULL;
if (nameAddressPtr->u1.Ordinal & IMAGE_ORDINAL_FLAG)
{
importedFunctionPtr = GetProcAddress(importedModule, MAKEINTRESOURCEA(nameAddressPtr->u1.Ordinal));
}
else
{
auto impotByNameImage = (PIMAGE_IMPORT_BY_NAME)(DWORD_PTR)(nameAddressPtr->u1.AddressOfData + imageBase);
importedFunctionPtr = GetProcAddress(importedModule, (char*)impotByNameImage->Name);
}
if (importedFunctionPtr)
{
auto oldProt = 0ul;
VirtualProtect(functionAddressPtr, sizeof(IMAGE_THUNK_DATA), PAGE_EXECUTE_READWRITE, &oldProt);
functionAddressPtr->u1.Function = (DWORD_PTR)importedFunctionPtr;
}
nameAddressPtr++;
functionAddressPtr++;
}
importTable++;
}
// HERE in callback I hook LoadLibrary & RegQueryVAlue calls if 'module' has such dependencies
callback(module);
}
}
问题是 IMAGE_IMPORT_DESCRIPTOR
结构的 Name
字段存储 0x0000FFFF
而不是 Dll 名称。
所以我的问题是我该如何解决这个问题? 0x0000FFFF
是什么意思?也许这是一些 "special" 模块(参见下面的 api-ms-win-crt-locale-l1-1-0.dll 屏幕截图)?
这是我的调试会话的屏幕截图。
更新:
也许 0x0000FFFF 意味着 dll 没有依赖关系?
我在 Dependency Walker 中查看了 api-ms-win-crt-locale-l1-1-0.dll 依赖项,似乎是这个 dll没有什么可导入的。
从您的屏幕截图中可以清楚地看到 importTable
指向 imageBase
(即 IMAGE_DOS_HEADER
)。当 header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0
时会发生这种情况 - 您没有检查此条件,结果和错误
api-ms-win-crt-locale-l1-1-0.dll
根本没有导入 - DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
是零。需要检查 - 在处理它之前是否存在导入
我的目标是手动填写 Dll 的导入 table 以挂钩内部 LoadLibrary 调用(当您加载库时,它可能会在其 DllMain 中加载另一个库)。
这是我的代码,它为依赖层次结构中的每个 dll 递归地填充 Import table,它工作正常,除了一些 dll (api-ms-win-crt- locale-l1-1-0.dll 在这种情况下)。
void PEUtility::fillImportTable(HMODULE loadedModule, FillImportFlag flag, std::function<void(HMODULE&)> callback)
{
std::stack<HMODULE> modules;
modules.push(loadedModule);
while (modules.size())
{
auto module = modules.top();
modules.pop();
auto imageBase = (DWORD_PTR)module;
auto header = ImageNtHeader(module);
auto importTable = (PIMAGE_IMPORT_DESCRIPTOR)(DWORD_PTR)(header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + imageBase);
while (importTable->OriginalFirstThunk)
{
// !!!
// HERE I've got an error: importTable->Name stores 0x0000FFFF instead dll name
// !!!
auto importedModuleName = (char*)(DWORD_PTR)(importTable->Name + imageBase);
auto importedModule = GetModuleHandleA(importedModuleName);
if (!importedModule)
{
importedModule = LoadLibraryExA(importedModuleName, 0, DONT_RESOLVE_DLL_REFERENCES);
if (flag == FillImportFlag::Recursive)
modules.push(importedModule);
}
auto nameAddressPtr = (PIMAGE_THUNK_DATA)(DWORD_PTR)(importTable->OriginalFirstThunk + imageBase); //Import Lookup Table address (functions names)
auto functionAddressPtr = (PIMAGE_THUNK_DATA)(DWORD_PTR)(importTable->FirstThunk + imageBase); //Import Address Table (IAT) address (functions addresses)
while (nameAddressPtr->u1.Function)
{
FARPROC importedFunctionPtr = NULL;
if (nameAddressPtr->u1.Ordinal & IMAGE_ORDINAL_FLAG)
{
importedFunctionPtr = GetProcAddress(importedModule, MAKEINTRESOURCEA(nameAddressPtr->u1.Ordinal));
}
else
{
auto impotByNameImage = (PIMAGE_IMPORT_BY_NAME)(DWORD_PTR)(nameAddressPtr->u1.AddressOfData + imageBase);
importedFunctionPtr = GetProcAddress(importedModule, (char*)impotByNameImage->Name);
}
if (importedFunctionPtr)
{
auto oldProt = 0ul;
VirtualProtect(functionAddressPtr, sizeof(IMAGE_THUNK_DATA), PAGE_EXECUTE_READWRITE, &oldProt);
functionAddressPtr->u1.Function = (DWORD_PTR)importedFunctionPtr;
}
nameAddressPtr++;
functionAddressPtr++;
}
importTable++;
}
// HERE in callback I hook LoadLibrary & RegQueryVAlue calls if 'module' has such dependencies
callback(module);
}
}
问题是 IMAGE_IMPORT_DESCRIPTOR
结构的 Name
字段存储 0x0000FFFF
而不是 Dll 名称。
所以我的问题是我该如何解决这个问题? 0x0000FFFF
是什么意思?也许这是一些 "special" 模块(参见下面的 api-ms-win-crt-locale-l1-1-0.dll 屏幕截图)?
这是我的调试会话的屏幕截图。
更新:
也许 0x0000FFFF 意味着 dll 没有依赖关系?
我在 Dependency Walker 中查看了 api-ms-win-crt-locale-l1-1-0.dll 依赖项,似乎是这个 dll没有什么可导入的。
从您的屏幕截图中可以清楚地看到 importTable
指向 imageBase
(即 IMAGE_DOS_HEADER
)。当 header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0
时会发生这种情况 - 您没有检查此条件,结果和错误
api-ms-win-crt-locale-l1-1-0.dll
根本没有导入 - DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
是零。需要检查 - 在处理它之前是否存在导入