手动填写DLL导入表:IMAGE_IMPORT_DESCRIPTOR的“名称”字段存储0x0000FFFF [英] Fill in DLL import table manually: IMAGE_IMPORT_DESCRIPTOR's Name field stores 0x0000FFFF
问题描述
我的目标是手动填写Dll的导入表,以挂接内部LoadLibrary调用(加载库时,它可能会在DllMain中加载另一个库)。
这是我的代码,为依赖关系层次结构中的每个dll递归地填充了导入表,并且除了一些dll( api-ms-win-crt-locale-l1-1-0.dll 情况)。 ; void(HMODULE&)>回调)
{
std :: stack< HMODULE>模块;
modules.push(loadedModule);
而(modules.size())
{
auto module = modules.top();
modules.pop();
auto imageBase =(DWORD_PTR)模块;
自动标头= ImageNtHeader(module);
auto importTable =(PIMAGE_IMPORT_DESCRIPTOR)(DWORD_PTR)(header-> OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_IMPORT] .VirtualAddress + imageBase);
而(importTable-> OriginalFirstThunk)
{
// !!!
//这里出现错误:importTable->名称存储0x0000FFFF而不是dll名称
//!
自动的importModuleName =(char *)(DWORD_PTR)(importTable->名称+ imageBase);
自动的importModule = GetModuleHandleA(importedModuleName);
if(!importedModule)
{
importedModule = LoadLibraryExA(importedModuleName,0,DONT_RESOLVE_DLL_REFERENCES);
if(标志== FillImportFlag :: Recursive)
modules.push(importedModule);
}
auto nameAddressPtr =(PIMAGE_THUNK_DATA)(DWORD_PTR)(importTable-> OriginalFirstThunk + imageBase); //导入查找表地址(函数名称)
auto functionAddressPtr =(PIMAGE_THUNK_DATA)(DWORD_PTR)(importTable-> FirstThunk + imageBase); //导入地址表(IAT)地址(函数地址)
而(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);
importantFunctionPtr = GetProcAddress(importedModule,(char *)impotByNameImage-> Name);
}
如果(importedFunctionPtr)
{
auto oldProt = 0ul;
VirtualProtect(functionAddressPtr,sizeof(IMAGE_THUNK_DATA),PAGE_EXECUTE_READWRITE,& oldProt);
functionAddressPtr-> u1.Function =(DWORD_PTR)importedFunctionPtr;
}
nameAddressPtr ++;
functionAddressPtr ++;
}
importTable ++;
}
//在回调中,我钩上LoadLibrary& RegQueryVAlue调用模块是否具有此类依赖性
callback(module);
}
}
问题在于
字段存储 IMAGE_IMPORT_DESCRIPTOR
结构的Name 0x0000FFFF
而不是Dll名称。
所以我的问题是如何解决? 0x0000FFFF
是什么意思?也许这是一些特殊模块(请参见屏幕快照中的 api-ms-win-crt-locale-l1-1-0.dll )?
这是我的调试会话的屏幕截图。
UPDATE:
可能是0x0000FFFF
我看过 api-ms-win-crt-locale-l1-1-0.dll > Dependency Walker中的 strong>依赖项,似乎此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]
为零。需要检查-导入是否在处理之前存在
My goal is to fill in Dll's import table manually in order to hook internal LoadLibrary calls (when you load library it may load another library inside its DllMain).
Here is my code which fill in Import table recursively for each dll in dependecies hierarchy and it works fine except some dlls (api-ms-win-crt-locale-l1-1-0.dll in this case).
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);
}
}
The problem is that the Name
field of IMAGE_IMPORT_DESCRIPTOR
structure stores 0x0000FFFF
instead of Dll name.
So my question is how can I fix that? What does 0x0000FFFF
mean? Maybe this is some "special" module (see api-ms-win-crt-locale-l1-1-0.dll below on screenshot)?
Here is screenshot from my debug session.
UPDATE:
Maybe 0x0000FFFF means that dll doesn't have dependencies?
I've looked api-ms-win-crt-locale-l1-1-0.dll dependencies in Dependency Walker and seems this dll has nothing to import.
from your screenshot clear view that importTable
point to imageBase
(i.e. IMAGE_DOS_HEADER
). this happens when header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0
- you not check for this condition, as result and error
api-ms-win-crt-locale-l1-1-0.dll
simply have no import - DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
is zero. need check - are import exist before process it
这篇关于手动填写DLL导入表:IMAGE_IMPORT_DESCRIPTOR的“名称”字段存储0x0000FFFF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!