首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GetModuleInformation在使用LoadLibraryExA(.,.,LOAD_LIBRARY_AS_DATAFILE)时失败?

GetModuleInformation在使用LoadLibraryExA(.,.,LOAD_LIBRARY_AS_DATAFILE)时失败?
EN

Stack Overflow用户
提问于 2012-08-20 20:32:04
回答 1查看 1.9K关注 0票数 1

在实际加载DLL之前,我在自己的延迟加载钩子中使用dliNotePreLoadLibrary来验证要加载的DLL的代码签名。为了避免它执行任何代码,我使用LoadLibraryExA(...,...,LOAD_LIBRARY_AS_DATAFILE)加载它(钩子只提供ANSI名称,所以没关系),并在验证后卸载它,这样它就可以作为一个带有代码的DLL加载。

通过调试器中的代码,我可以看到我收到了一个句柄,并且这个句柄是<baseaddress>+1,正如“数据模块”所期望的那样。但是,一旦我试图在库函数中将这个句柄传递给GetModuleFileName (这也是为什么我不能传递名称,只传递模块句柄的原因),该函数将返回0,GetLastError给我ERROR_MOD_NOT_FOUND。但是,模块被加载了,所以肯定被找到了。而且,这是在当前的过程中,所以访问“目标进程”在这里没有问题。

因此,我想为什么不使用VirtualQuery来检索我刚刚加载的DLL的实际基址(MEMORY_BASIC_INFORMATION::BaseAddress) (以防<baseaddress>+1出现问题),但结果仍然是一样的:ERROR_MOD_NOT_FOUND

我没有主意了。有人知道这是怎么回事吗?

测试平台: Windows 7 SP1,x64 (最新补丁)

下面是代码:

代码语言:javascript
运行
复制
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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-21 06:56:37

正如在MSDN中所解释的,当使用GetModuleHandle时,不能使用LOAD_LIBRARY_AS_DATAFILE检索模块:

如果使用此值,则系统将该文件映射到调用进程的虚拟地址空间,就好像它是数据文件一样。对执行或准备执行映射的文件不做任何操作。因此,不能用这个DLL调用像GetModuleFileName、GetModuleHandle或GetProcAddress这样的函数。

编辑:实际上比这个答案更接近原因。虽然这个答案重申了MS的观点,但它并没有给出理由。但是,原因是GetModuleFileName基本上遍历了PEBLDR_MODULE列表,并且只有在“加载代码”时才会填充详细信息。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12044691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档