C++ 链接器/delayload未完全使用winhttp.dll

C++ 链接器/delayload未完全使用winhttp.dll,c++,winapi,visual-c++,portable-executable,C++,Winapi,Visual C++,Portable Executable,我正试图防止我的可执行文件中存在dll劫持漏洞,该漏洞只有一个明确的动态依赖项--winhttp.dll 我的尝试是使用链接器/delayload:winhttp.dll选项,并在程序开始时调用SetDefaultDllDirectories。似乎它对某些模块和winhttp本身都有效,但对它的依赖项无效-binary仍在加载mpr.dll和main之前的一些其他模块(它首先尝试从我的可执行文件夹加载它) 将mpr.dll添加到/delayload列表没有帮助-我得到链接:警告LNK4199:/

我正试图防止我的可执行文件中存在dll劫持漏洞,该漏洞只有一个明确的动态依赖项--
winhttp.dll

我的尝试是使用链接器
/delayload:winhttp.dll
选项,并在程序开始时调用
SetDefaultDllDirectories
。似乎它对某些模块和
winhttp
本身都有效,但对它的依赖项无效-binary仍在加载
mpr.dll
main
之前的一些其他模块(它首先尝试从我的可执行文件夹加载它)

mpr.dll
添加到
/delayload
列表没有帮助-我得到
链接:警告LNK4199:/delayload:mpr.dll被忽略;未找到来自mpr.dll的导入

Dependency Walker向我展示了这个依赖链:
winhttp->oleaut32->combase->ole32->mpr

为什么在使用任何
winhttp
函数之前加载此模块

另外,我确实希望避免手动使用
LoadLibrary
+
GetProcAddress

Win 8.1,MSVS 2013更新5

Procmon:

副沃克:


这很疯狂,但这种行为的真正原因似乎是我的可执行文件名。它确实包含一个单词“launcher”,似乎就是触发Windows AppCompat层的那个。
重命名为“test1.exe”的同一个可执行文件运行良好。

如果您包含一个使用winhttp的小示例程序,该程序足以重现问题,则会有所帮助。另外,附加一个为进程启用加载程序快照的调试器,而不是使用过时的依赖项Walker工具。在Windows 10中,我尝试了一个延迟加载的
WinHttpOpen
调用,该调用按预期工作。加载winhttp加载了sechost,sechost又加载了rpcrt4。winhttp还依赖于kernel32、kernelbase和ucrtbase,但它们已经加载。所有这些DLL都受KnownDLS列表的保护。函数调用本身加载了其他依赖项,包括combase,但不是oleaut32或ole32(它在mpr上有延迟加载依赖项)。实际上,您最好让它加载它想要的任何内容,然后使用
WinVerifyTrust
检查系统DLL上的签名。尽管这也不会阻止有人使用调试器修补您的检查。如果有人设法在您的应用程序二进制文件旁边放置DLL,他们有比攻击您的应用程序更好的方法来危害系统。除非安装到不安全的位置,否则需要管理员权限才能写入应用程序目录。如果您试图保护用户不被意外加载(和执行)恶意可执行映像,则检查数字签名是可行的选择。您可以将其与实现结合起来,在模块实际加载之前先查看一下。@eryksun,我的应用程序清单确实包含
trustInfo
元素,其中已包含
requestedExecutionLevel
元素。我还尝试将
compatibility
元素添加到所有5个
supportedOS
guid中,但是
AcLayers.dll
仍在加载中(这导致
mpr
被不安全地加载)。