I am using dliNotePreLoadLibrary
in my own delay loading hook to verify the code signature of a DLL to be loaded before actually loading it. In order to avoid it to execute any code whatsoever, I load it by means of LoadLibraryExA(...,...,LOAD_LIBRARY_AS_DATAFILE)
(the hook only provides the ANSI name, so that's okay) and unload it after verification so that it can be loaded as a DLL with code.
Stepping through the code in the debugger I can see that I receive a handle and that handle is <baseaddress>+1
as expected for a "data module". However, once I attempt to pass this handle to GetModuleFileName
inside a library function (that is also the reason why I can't pass the name, only the module handle), the function returns 0
and GetLastError gives me ERROR_MOD_NOT_FOUND
. However, the module got loaded, so it was definitely found. Also, this is in the current process, so access to the "target process" is no issue here.
So I thought why not use VirtualQuery
to retrieve the actual base address (MEMORY_BASIC_INFORMATION::BaseAddress
) of the DLL I just loaded (in case the <baseaddress>+1
is an issue), but the result remains the same: ERROR_MOD_NOT_FOUND
.
I'm out of ideas. Does anyone have any ideas what is going on here?
Platform of the tests: Windows 7 SP1, x64 (latest patches)
Here's the code of the:
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;
The function VerifyModuleSignature
calls first of all GetModuleFileName
to retrieve the file name and it fails at that step. I verified that with the .exe
that creates the process, the code signature verification works fine.
Side-note: I have verified that the ERROR_MOD_NOT_FOUND
error comes from GetModuleFileName
and not, for example, from the earlier call to LoadLibraryExA
. In order to make sure I don't get a "polluted" last error code I called SetLastError(ERROR_SUCCESS)
right before the call to GetModuleFileName
.