最有效的dll劫持防护手段包括:启用safedllsearchmode(注册表值为1)、利用knowndlls白名单强制从system32加载关键dll、调用setdefaultdlldirectories限定可信路径,以及通过清单文件绑定dll签名与版本。

直接锁定系统库文件的加载路径,是阻断 DLL 劫持最有效的手段之一。关键不在于“禁止加载”,而在于让系统跳过不可信路径(尤其是当前目录和应用目录),只从可信位置(如 %SystemRoot%\System32)加载特定系统 DLL。
启用 SafeDllSearchMode 并确认其生效
该机制自 Windows XP SP2 起默认开启,它把“系统目录”提前到搜索顺序第 2 位(紧随程序所在目录之后),大幅降低当前目录被优先命中风险。无需手动修改注册表,但需验证状态:
- 检查注册表项
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SafeDllSearchMode,值为 1 表示启用 - 若为 0,说明已关闭——攻击者可将恶意 DLL 放入当前目录并被优先加载,应立即设回 1
- 注意:此设置影响全局,重启后生效,对所有进程起作用
利用 KnownDLLs 注册表强制系统级白名单
Windows 7 及以上版本内置了 KnownDLLs 机制,将高频、高危系统 DLL(如 kernel32.dll、user32.dll、ntdll.dll 等)列入白名单,强制它们只能从 System32 加载,完全绕过应用目录和当前目录。
- 注册表路径:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs - 该键下每个字符串值代表一个受保护 DLL 名称(不含扩展名),例如
kernel32 - 只要 DLL 名在此列表中,即使你在程序目录放同名恶意 DLL,系统也拒绝加载——这是内核级硬防护
- 不建议手动增删此项,除非明确知道某 DLL 已被微软官方加入 KnownDLLs 清单
调用 SetDefaultDllDirectories 限定可信路径
这是开发者可在代码中主动控制的 API,比旧版 SetDllDirectory 更安全、更明确:
- 调用
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32),表示后续所有LoadLibrary都只在 System32 中查找 - 还可组合使用:
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR(程序目录)、LOAD_LIBRARY_SEARCH_APPLICATION_DIR(应用目录),但避免包含 LOAD_LIBRARY_SEARCH_USER_DIRS 或当前目录 - 该设置作用于当前进程,且一旦设定无法撤销,适合启动早期调用
配合清单文件(Manifest)绑定系统 DLL 版本与签名
清单文件不是“路径锁”,但它能从语义层面锁定 DLL 来源,使系统拒绝加载未签名或版本不符的同名 DLL:
- 为可执行文件嵌入 manifest,声明依赖的系统 DLL(如
Microsoft.VC90.CRT)及其公钥令牌、语言、版本号 - Windows 加载器会校验 DLL 的数字签名是否匹配 manifest 中指定的发布者(通常是 Microsoft)
- 即使恶意 DLL 文件名、导出函数完全一致,签名不匹配即被拒绝加载
- 适用于 VC++ 运行时、COM 组件等常见劫持目标,需配合正确签名的系统 DLL 使用











