命令說明
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的區別如下:
從是否處理來說,e|d|i|n分為兩類:
另外還有比較關鍵的是 [-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出堆疊,檢視解除安裝原因。
在dll載入失敗的情況下,一般是LdrLoadDll失敗,從而呼叫到LdrUnloadDll。我們只要在執行序列中持續 shift+f11 就能獲取到 LdrLoadDll 返回值,也就能獲取到dll載入失敗的原因了。