软件调试学习笔记(四)—— 异常的处理流程
軟件調(diào)試學習筆記(四)—— 異常的處理流程
- 要點回顧
- 異常的處理流程
- 實驗1:理解調(diào)試器與異常的關系
- 未處理異常:最后一道防線
- 實驗2:理解UnhandledExceptionFilter執(zhí)行流程
- 實驗3:利用UnhandledExceptionFilter實現(xiàn)反調(diào)試
要點回顧
調(diào)試事件有多重類型、例如DLL加載、進程創(chuàng)建、線程創(chuàng)建等等。
其中最關鍵的調(diào)試事件是”異常“。
在調(diào)試過程中,不論是軟件斷點、硬件斷點還是INT 3斷點,都是通過異常來實現(xiàn)的。
異常的處理流程
流程圖:
實驗1:理解調(diào)試器與異常的關系
1)編譯并運行以下代碼:
#include <stdio.h> #include <windows.h>int main () {int x = 100;int y = 0;int z;_try{z = x / y; //除0異常printf("無法執(zhí)行的代碼 \n");}_except(1){printf("SEH異常處理代碼 \n");}return 0; }執(zhí)行結果:
2)設置調(diào)試器選項
3)使用調(diào)試器運行程序
程序停在40104E處,由于調(diào)試器沒有除0異常處理代碼,因此無法繼續(xù)向下執(zhí)行。
4)手動模擬異常處理,將[ebp-0x20]的值改為1,繼續(xù)運行
程序成功向下運行。
思考:會不會存在某種異常沒人處理的情況
答案:不存在,因為有UnhandledExceptionFilter(未處理異常)
未處理異常:最后一道防線
描述:在前面異常相關章節(jié)已經(jīng)學習,任何一個線程,在啟動時都會先布置最后一道防線。
__try {} __except(UnhandledExceptionFilter(GetExceptionInformation()) {//終止線程//終止進程 }UnhandledExceptionFilter執(zhí)行流程:
1)通過NtQueryInformationProcess查詢當前進程是否正在被調(diào)試,如果是,返回EXCEPTION_CONTINUE_SEARCH,此時會進入第二輪分發(fā)。
2)如果沒有被調(diào)試:
實驗2:理解UnhandledExceptionFilter執(zhí)行流程
1)編譯以下代碼
#include <stdio.h> #include <windows.h>int main () {int x = 100;int y = 0;int z;_try{z = x / y; //除0異常printf("無法執(zhí)行的代碼 \n");}_except(0){printf("SEH異常處理代碼 \n");}getchar();return 0; }2)雙擊運行程序
結論:
1)由于當前進程并未處于調(diào)試狀態(tài),因此不會調(diào)用UnhandledExceptionFilter。
2)由于當前程序并未使用SetUnhandledExceptionFilter注冊處理函數(shù),因此會讓用戶選擇是否啟動調(diào)試器。
通過UnhandledExceptionFilter的這個性質,可以借此實現(xiàn)反調(diào)試。
實驗3:利用UnhandledExceptionFilter實現(xiàn)反調(diào)試
1)編譯并運行以下代碼:
#include <stdio.h> #include <windows.h>DWORD g_Test = 0;LONG NTAPI TopLevelExcepFilter(PEXCEPTION_POINTERS pExcepInfo) {printf("頂級異常處理器修復異常 \n");g_Test = 1;return EXCEPTION_CONTINUE_EXECUTION; }int main () {int r = 0;int x = 100;SetUnhandledExceptionFilter(&TopLevelExcepFilter);r = x / g_Test; //除0異常printf("正常邏輯開始執(zhí)行 \n");for(int i=0; i<10; i++){Sleep(1000);printf("%d \n", i);}getchar();return 0; }編譯器運行結果:
雙擊運行結果:
由于調(diào)試器不會觸發(fā)SetUnhandledExceptionFilter設置的頂層異常,因此程序處于被調(diào)試狀態(tài)時無法回歸到正常邏輯;且調(diào)試器在處理異常時,若處理結果與程序所需不符,程序也將無法得以正常執(zhí)行。
總結
以上是生活随笔為你收集整理的软件调试学习笔记(四)—— 异常的处理流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件调试学习笔记(三)—— 调试事件的处
- 下一篇: 软件调试学习笔记(五)—— 软件断点内存