如何验证加载的是正确DLL以抵御侧载攻击?
抵御DLL侧载的哈希验证方案
一、构建阶段生成哈希值
- 借助构建脚本(PowerShell、Python或CI/CD流程步骤)遍历所有依赖DLL,计算SHA-256哈希(MD5、SHA1已被破解,绝对不能用),将哈希值与对应DLL文件名存入带数字签名的配置文件(XML/JSON均可)——配置文件必须签名,否则攻击者篡改哈希列表就能绕过验证。
- 示例PowerShell脚本片段:
$targetDir = "C:\YourApp\Dependencies" $hashOutput = "C:\YourApp\dll_hashes.json" $dlls = Get-ChildItem -Path $targetDir -Filter *.dll -Recurse $hashList = @() foreach ($dll in $dlls) { $hash = (Get-FileHash -Path $dll.FullName -Algorithm SHA256).Hash $hashList += [PSCustomObject]@{ RelativePath = $dll.FullName.Substring($targetDir.Length + 1) SHA256Hash = $hash } } $hashList | ConvertTo-Json -Depth 10 | Out-File $hashOutput -Encoding UTF8 # 用signtool给哈希文件签名(需提前准备代码签名证书) signtool sign /f "YourCert.pfx" /p "CertPassword" $hashOutput
二、加载时验证的核心流程
- 绝对不能用默认
LoadLibrary,必须自定义加载逻辑:- 强制指定DLL的完整可信路径(比如应用安装目录下的
Dependencies子文件夹),避免系统默认搜索顺序导致的路径劫持。 - 读取DLL文件内容,计算SHA-256哈希(不要加载后再计算,否则恶意代码可能已执行)。
- 先验证哈希配置文件的数字签名有效性,再从中取出对应DLL的预期哈希值。
- 只有哈希完全匹配、配置文件签名有效,才调用
LoadLibraryExW加载DLL,同时指定LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS参数限制搜索范围。
- 强制指定DLL的完整可信路径(比如应用安装目录下的
- 哈希不匹配或签名无效时,直接终止加载流程,绝不能跳过验证继续执行。
三、可直接集成的工具/方案
- Windows Authenticode:官方的代码签名方案,比单纯哈希更可靠。构建时用
signtool给所有DLL签名,加载时调用WinVerifyTrustAPI验证签名——既验证文件未篡改,又验证发布者身份,不需要自行维护哈希列表。 - OpenSSL:跨平台场景下,可用OpenSSL的libcrypto模块完成哈希计算和配置文件的签名/验证,无需依赖Windows特定API。
- CI/CD集成:GitHub Actions、GitLab CI等流程中,可直接添加步骤自动计算哈希并签名,确保构建产物的完整性。
四、自行开发的关键注意事项
- 哈希算法必须选SHA-256、SHA-3等强哈希,禁止使用弱算法。
- 哈希配置文件的签名是核心,必须用可信的代码签名证书(不要用自签名证书,用户端无法验证)。
- 不要加载未验证的DLL,哪怕是“临时应急”,一旦加载恶意DLL,防御就失效了。
- 处理文件读取、哈希计算时的异常,比如文件损坏、权限不足,直接终止加载,避免攻击者利用异常绕过验证。
内容的提问来源于stack exchange,提问作者Squazz
相关产品推荐
相关产品推荐

