C++ 手动填写DLL导入表:IMAGE#u import#u DESCRIPTOR';s名称字段存储0x0000FFFF

C++ 手动填写DLL导入表:IMAGE#u import#u DESCRIPTOR';s名称字段存储0x0000FFFF,c++,dll,hook,dllimport,portable-executable,C++,Dll,Hook,Dllimport,Portable Executable,我的目标是手动填充Dll的导入表,以便钩住内部LoadLibrary调用(当您加载库时,它可能会在其DllMain中加载另一个库) 下面是我的代码,它递归地为dependecies层次结构中的每个dll填充导入表,除了一些dll(api-ms-win-crt-locale-l1-1-0.dll,在本例中为 void-PEUtility::fillImportTable(HMODULE-loadedModule,FillImportFlag标志,std::函数回调) { std::堆栈模块; 模块

我的目标是手动填充Dll的导入表,以便钩住内部LoadLibrary调用(当您加载库时,它可能会在其DllMain中加载另一个库)

下面是我的代码,它递归地为dependecies层次结构中的每个dll填充导入表,除了一些dll(api-ms-win-crt-locale-l1-1-0.dll,在本例中为

void-PEUtility::fillImportTable(HMODULE-loadedModule,FillImportFlag标志,std::函数回调)
{
std::堆栈模块;
模块。推送(加载模块);
while(modules.size())
{
自动模块=modules.top();
modules.pop();
auto imageBase=(DWORD_PTR)模块;
自动标头=图像标头(模块);
自动可导入=(PIMAGE\u IMPORT\u描述符)(DWORD\u PTR)(标题->可选标题.DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u IMPORT].VirtualAddress+imageBase);
while(可导入->原始初始链接)
{
// !!!
//这里有一个错误:importable->Name存储0x0000FFFF,而不是dll名称
// !!!
自动导入模块名=(字符*)(DWORD_PTR)(可导入->名称+图像库);
自动导入模块=GetModuleHandleA(导入模块名);
如果(!importedModule)
{
importedModule=LoadLibraryExA(importedModuleName,0,不解析DLL引用);
if(flag==FillImportFlag::Recursive)
模块。推送(导入模块);
}
自动名称地址PTR=(PIMAGE_THUNK_DATA)(DWORD_PTR)(importable->OriginalFirstThunk+imageBase);//导入查找表地址(函数名称)
auto functionAddressPtr=(PIMAGE_THUNK_DATA)(DWORD_PTR)(可导入->FirstThunk+imageBase);//导入地址表(IAT)地址(函数地址)
while(nameAddressPtr->u1.Function)
{
FARPROC importedFunctionPtr=NULL;
if(nameAddressPtr->u1.Ordinal和IMAGE_Ordinal_标志)
{
importedFunctionPtr=GetProcAddress(importedModule,MAKEINTRESOURCEA(nameAddressPtr->u1.Ordinal));
}
其他的
{
自动导入dynameimage=(PIMAGE\u IMPORT\u BY\u NAME)(DWORD\u PTR)(nameAddressPtr->u1.AddressOfData+imageBase);
importedFunctionPtr=GetProcAddress(importedModule,(char*)ImportByNameImage->Name);
}
if(导入功能PTR)
{
自动oldProt=0ul;
VirtualProtect(functionAddressPtr、sizeof(IMAGE\u THUNK\u DATA)、PAGE\u EXECUTE\u READWRITE和OldProtet);
functionAddressPtr->u1.Function=(DWORD_PTR)导入的functionPtr;
}
nameAddressPtr++;
functionAddressPtr++;
}
可导入++;
}
//在callback中,如果'module'具有此类依赖项,我将钩住LoadLibrary&RegQueryVAlue调用
回调(模块);
}
}
问题是
IMAGE\u IMPORT\u DESCRIPTOR
结构的
Name
字段存储
0x0000FFFF
,而不是Dll名称

所以我的问题是我该如何解决这个问题?
0x0000FFFF
是什么意思?也许这是一些“特殊”模块(请参见下面屏幕截图上的api-ms-win-crt-LOCE-l1-1-0.dll)

这是我调试会话的屏幕截图。

更新: 也许0x0000FFFF意味着dll没有依赖项


我在Dependency Walker中查看了api-ms-win-crt-locale-l1-1-0.dll
依赖项,似乎这个dll没有什么可导入的

从您的屏幕截图中可以清楚地看到,
可导入的
指向
图像库
(即
图像标题
)。当
header->OptionalHeader.DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u IMPORT].VirtualAddress==0
时会发生这种情况-您没有检查这种情况,结果是错误的


api-ms-win-crt-locale-l1-1-0.dll
没有导入-
DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u import]
为零。需要检查-在处理之前导入是否存在从您的屏幕截图中清楚地看到,
可导入
指向
imageBase
(即
图像DOS\u标题
)。当
header->OptionalHeader.DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u IMPORT].VirtualAddress==0
时会发生这种情况-您没有检查这种情况,结果是错误的


api-ms-win-crt-locale-l1-1-0.dll
没有导入-
DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u import]
为零。需要检查-在处理之前是否存在导入

这是否意味着当且仅当
DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u import]
为零时,DLL才没有导入?如何最好地检查没有导入的模块?@DmitryKatkevich-是的,您确实需要检查
DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u import]
-VirtualAddress必须是=0和大小==
sizeof(图像\u导入\u描述符)*n
其中n>0这是否意味着当且仅当
DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u IMPORT]
为零时,DLL才没有导入?如何最好地检查没有导入的模块?@DmitryKatkevich-是的,您确实需要检查
DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u import]
-VirtualAddress必须是=0和大小==
sizeof(图像\u导入\u描述符)*n其中n>0