sx命令与简单应用

命令说明 sx 命令用于控制当异常或者事件发生时调试器的行为。
Sx命令对应 windbg.exe(gui)的”debug”菜单项中的”Event Filters”子菜单项。
基本语法如下:

sx
sx{e|d|i|n} [-c "Cmd1"] [-c2 "Cmd2"] [-h] {Exception|Event|*}
sx- [-c "Cmd1"] [-c2 "Cmd2"] {Exception|Event|*}
sxr
用法如下:
Sx:列出所有支持的event与exception。
Sxr:恢复事件与异常处理到默认配置。
sx{e|d|i|n} [-c "Cmd1"] [-c2 "Cmd2"] [-h] {Exception|Event|*}
e|d|i|n的区别如下:
sx命令与简单应用
文章图片
从是否处理来说,e|d|i|n分为两类:


sx命令与简单应用
文章图片
另外还有比较关键的是 [-c "Cmd1"] [-c2 "Cmd2"]。
从help文件看,-c与-c2的区别主要在异常发生时,调试器终端的时机。 当进程抛出一个异常后,内核会检查当前进程的调试端口是否为空(是否有调试器附加在进程上),如果调试端口存在,则会将异常抛到调试端口中,由调试器决定是否处理这个异常,这就是所谓的first chance。
如果调试器不处理这个异常(调试器很有可能会把处理的机会留给异常处理块),则内核会继续将异常发送到进程的异常端口,由异常处理块来处理这个异常。
应用层的异常处理以链表的形式链在一起(有兴趣可以研究下SEH的汇编实现,很有意思),其尾部为默认的异常处理器 UnhandledExceptionFilter,当异常第一次路由到UnhandledExceptionFilter并且进程被调试器附加的情况下,UnhandledExceptionFilter会将异常再次发给调试器处理,这就是所谓的second chance。此时调试器必须谨慎对待这个异常了,这说明这个异常是程序员没有意料到的异常。如果调试器依然没有处理,那么程序被终止。
First chance与second chance的分发流程挺有意思,部分程序会利用这个特性就行反调试。
简单应用 Sx在我的日常调试中,主要用于两个方面,都与模块加载事件有关(ld:加载事件;ud:卸载事件):
1.实现bu功能:
当需要对某个未加载模块下断点,一般会用到bu命令。不过在调试中,如果符号没有正确加载,则bu可能会失效。在这种情况下,sxe命令可以完成相同功能。
假设要对 mod!fun + 0x12下断点,则在程序初始断点中执行 sxe ld:mod 命令,当mod被加载时,调试器会断下。x mod!* 列出所有符号,然后 bp mod!fun + 0x12就能完成断点的设置。
2.dll加载失败原因:
实践中经常会跑到dll加载失败或者被提前卸载的问题,原因很多。包括dll依赖的库找不到;dll的导出接口不足等。
假设mod.dll加载失败,在进程的初始断点中执行 sxe ld:mod。当mod加载被断下后执行 sxe ud:mod命令。当调试器被重现断下时,k出堆栈,查看卸载原因。
【sx命令与简单应用】在dll加载失败的情况下,一般是LdrLoadDll失败,从而调用到LdrUnloadDll。我们只要在执行序列中持续 shift+f11 就能获取到 LdrLoadDll 返回值,也就能获取到dll加载失败的原因了。

    推荐阅读