如何在Visual Studio中为延迟加载DLL设置断点或异常?
延迟加载DLL的异常与断点设置全指南
我来帮你搞定延迟加载DLL时的断点/异常设置问题,顺便解释下你之前断点没触发的原因~
一、最靠谱的加载异常触发法(就是你用的sxe ld)
你提到的sxe ld <binary name>其实是延迟加载场景下最稳的方案。因为延迟加载DLL的加载时机是进程第一次调用它里面的函数时,这个命令会在DLL刚被映射到进程地址空间时立刻触发中断,不管它是正常加载还是延迟加载。
这里给你补两个小细节:
<binary name>可以写完整文件名(比如myDelayDll.dll),也可以只写不带扩展名的名字(比如myDelayDll),WinDbg会自动匹配- 要是后续想取消这个异常,直接用
sxd ld <binary name>就行
二、为啥你设的入口函数断点没触发?
你尝试的{,,<binary name>.dll} EntryFunctions断点失效,大概率是这几个坑:
- DLL还没加载就设断点:延迟加载的DLL在进程启动时不会被加载,只有第一次调用其函数时才会加载。你提前设断点时,WinDbg找不到这个DLL的地址空间,相当于断点根本没真正注册上
- 符号没拉对:如果WinDbg找不到对应DLL的PDB符号,根本解析不了
EntryFunctions这个函数名,断点自然无效。可以用!sym noisy开启符号调试日志,看看是不是符号路径有问题 - 函数名写错了:多数DLL的入口函数是
DllMain,如果是C++编译的DLL,函数还会有名字粉碎(比如myDll!MyDll::DllMain@12),直接写EntryFunctions肯定匹配不到
三、正确设置入口函数断点的步骤
如果一定要在DLL的入口函数(比如DllMain)断下来,按这个流程走绝对没问题:
- 先设置加载异常:
sxe ld myDelayDll.dll,让WinDbg在DLL加载瞬间中断 - 中断后,立刻设置入口函数断点:
- 纯C写的DLL:直接敲
bp myDelayDll!DllMain - C++写的DLL:先执行
x myDelayDll!*DllMain*找到正确的修饰函数名,再用这个名字设断点(比如bp myDelayDll!MyDllClass::DllMain@12)
- 纯C写的DLL:直接敲
- 输入
g继续执行程序,等DLL入口函数被调用时就会触发断点了
四、针对延迟加载具体函数的断点技巧
如果你的目标是断在某个特定的延迟加载函数(不是DLL入口),还有两个实用方法:
- 方法一:开启延迟加载调试标志
敲!gflag +dl开启延迟加载的全局调试标志,这样每次进程调用延迟加载的函数时都会触发中断。缺点是会拦截所有延迟加载操作,比较“吵”,用完记得用!gflag -dl关掉 - 方法二:加载后手动设断点
等DLL加载(通过sxe ld中断)后,用x myDelayDll!TargetFunc找到目标函数的地址,然后用bp <函数地址>设置断点,后续调用这个函数时就会精准断下来
内容的提问来源于stack exchange,提问作者Kedar Grr




