我dliNotePreLoadLibrary
在我自己的延迟加载钩子中使用它来验证要在实际加载之前加载的 DLL 的代码签名。为了避免它执行任何代码,我通过LoadLibraryExA(...,...,LOAD_LIBRARY_AS_DATAFILE)
(钩子只提供ANSI名称,所以没关系)加载它并在验证后卸载它,以便它可以作为带有代码的DLL加载。
单步调试调试器中的代码,我可以看到我收到了一个句柄,并且该句柄<baseaddress>+1
与“数据模块”的预期一致。但是,一旦我尝试将此句柄传递到GetModuleFileName
库函数内部(这也是我不能传递名称的原因,只能传递模块句柄),函数返回0
并且 GetLastError 给了我ERROR_MOD_NOT_FOUND
. 但是,该模块已加载,因此肯定找到了。此外,这是在当前进程中,因此访问“目标进程”在这里没有问题。
所以我想为什么不使用VirtualQuery
检索MEMORY_BASIC_INFORMATION::BaseAddress
我刚刚加载的 DLL 的实际基地址 ( )(以防万一<baseaddress>+1
出现问题),但结果保持不变ERROR_MOD_NOT_FOUND
:
我没主意了。有谁知道这里发生了什么?
测试平台:Windows 7 SP1,x64(最新补丁)
这是以下代码:
FARPROC WINAPI MyDliHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
switch(dliNotify)
{
case dliNotePreLoadLibrary:
if(0 == lstrcmpiA(pdli->szDll, "DLLNAME.dll"))
{
HMODULE hVerifiedDll = LoadLibraryExA(pdli->szDll, NULL, LOAD_LIBRARY_AS_DATAFILE);
if(hVerifiedDll)
{
MEMORY_BASIC_INFORMATION mbi;
if(0 != VirtualQuery(hVerifiedDll, &mbi, sizeof(mbi)));
{
VerifyModuleSignature((HMODULE)mbi.BaseAddress, pdli->szDll);
}
FreeLibrary(hVerifiedDll);
}
}
break;
default:
break;
}
return NULL;
}
PfnDliHook __pfnDliNotifyHook2 = MyDliHook;
该函数VerifyModuleSignature
首先调用GetModuleFileName
以检索文件名,但在该步骤失败。我验证了.exe
创建过程的代码签名验证工作正常。
旁注:我已经验证了ERROR_MOD_NOT_FOUND
错误来自GetModuleFileName
而不是,例如,来自之前对LoadLibraryExA
. 为了确保SetLastError(ERROR_SUCCESS)
在调用GetModuleFileName
.