以10.0.15063.468版windbg为例。
windbg帮助手册里指出.load用于加载扩展DLL,但有天bluerust用!load成功加载扩展DLL,而且他是照着某篇微软文档中的示例做的。这引起我的好奇,帮助手册里从来没有说!load有这个效果,甚至没有!load这个命令。
于是我跟bluerust讨论了一下,.load和!load有什么区别,二者对应的处理函数是什么?针对第2个问题,现在我们当然知道很多办法去定位,但最初提出这个问题时,尚无此积累。bluerust想到一个歪招:
他假设!load对应的处理流程会引用字符串"The call to LoadLibrary",在所有模块中搜索它,然后用交叉引用或数据断点定位到:
dbgeng!ExtensionInfo::Load+0x56e:
上面是当时bluerust的一些尝试,最近我又琢磨了一下原始问题,见下。
bp dbgeng!ProcessCommands
断下来时,对比".load jsprovider.dll"、"!load jsprovider.dll"在其中的执行过程,发现ProcessCommands()有两处对DotCommand()的调用:
case '.':
case '!':
这样比较累,干脆拦截jsprovider.dll的加载,对比调用栈回溯,但是没有区别:
ntdll!NtMapViewOfSection+0x14
...
KERNELBASE!LoadLibraryExW+0x14a
dbgeng!ExtensionInfo::Load+0x3b2
dbgeng!ExtensionInfo::CheckAdd+0x6e
dbgeng!ParseBangCmd+0x248
dbgeng!ProcessCommands+0xdbb
dbgeng!ProcessCommandsAndCatch+0xa5
dbgeng!Execute+0x2bb
dbgeng!DebugClient::ExecuteWide+0x83
cdb!MainLoop+0x516
cdb!wmain+0x46e
尽管我知道很多.命令与!命令不相同,但.load和!load给我带了一丝幻想:
> .echo scz
scz
> !echo scz
No export echo found
为什么load被特殊处理,echo就没有?
看得出来,windbg的命令分发流程有很多历史痕迹,未必是当下最优逻辑,估计也不会对之优化重构了。
BTW,原文链接指向GB2312的*nix格式TXT,看不懂这句话的就自动忽略吧。