反調試——Windows異常-SEH

反調試——Windows異常-SEH

概念:

SEH:Structured Exception Handling

SEH是Windows默認的異常處理機制

如何使用

在程式碼中使用

__try


__except()//結構類型的語句

__except()小括弧裡面填寫表達式,表達式為真的時候執行裡面的內容

__try裡面包含的是可能觸發異常的語句,except裡面包含的是出現了異常後執行的操作。

例子:

int main()
{
__try
{
cout<<"hello,world"<<endl;
}
__except(1)
{
cout<<"異常"<<endl;
}
return 0;
}

異常的作業

1 便於查找錯誤

2 可以用在反調試裡面

異常處理機制

當我們在非調試狀態下運行一個程式,程式如果觸發了異常,會先判斷是否有異常處理器,如果存在則跳轉到異常處理函數去執行,如果不存在則退出程式

如果程式處於被調試狀態,觸發異常時,作業系統會先把異常拋給調試進程,也就是讓調試器來處理異常。可以看到的現象就是觸發了異常後,程式會暫停下來,也就是斷下來,也就是斷點的原理。當異常拋給調試器後,調試器可以選擇:

1 修改觸發異常的程式碼繼續執行(程式會停在觸發異常的程式碼處,導致異常的程式碼無法執行)

2 忽略異常交給SEH執行

也就是說Windows發生異常後的處理順序為:1、調試器處理。2、SEH處理 3、崩潰

剖析SEH

SEH結構:

typedef struct _EXCEPTION_REGISTRATION_RECORD {
  struct _EXCEPTION_REGISTRATION_RECORD *Next;
  PEXCEPTION_ROUTINE Handler;//異常處理器,異常處理函數
} EXCEPTION_REGISTRATION_RECORD;

SEH在程式中實際上是以鏈表形式存在,每一個next都指向下一個SEH,這個鏈表也叫SEH鏈(如圖):

 

 

每次添加一個異常就會添加該異常到異常鏈的頭結點的位置

觀察SEH是如何生成和使用的

生成兩個程式觀察,兩個程式的區別就是一個有異常SEH,一個沒有

//有異常的程式程式碼
#include<Windows.h>
#include<iostream>
int main()
{
__try
{
char* str = NULL;
str[0] = 'a';
}
__except(1)
{
printf("觸發異常了\n");
}
printf("Sna1lGo\n");
return 0;
}

 

//沒有異常的程式程式碼
#include<Windows.h>
#include<iostream>
int main()
{
char* str = NULL;
str[0] = 'a';
printf("Sna1lGo\n");
return 0;
}

分別生成後,都用od打開調試比對

 

 

然後都進入main函數

 

 

重點查看SEH的程式碼:

 

 

這四條指令就是SEH的關鍵程式碼,這一系列操作相當於創建了一個異常的結構體,然後添加到異常鏈的表頭裡面。

分析為什麼是這樣:

首先,大概畫一個堆棧圖:

 

 

先存進來了一個0x01293609,然後調用了fs:[0]這個東西,這個東西有點眼熟之前的TEP-PEB查找核心模組的時候有用過,但是這裡,可以將fs:[0]直接理解為SEH鏈的表頭。

這裡取出來fs:[0]給eax後又把eax入棧,然後將fs:[0]賦值為esp

 

 

可以理解為在棧中創建了一個SEH變數,然後第一個欄位存放了函數地址也就是0x01293690,next欄位指向了fs:[0]也就是SEH鏈的第一個節點,然後再把fs:[0]的值修改為該節點的首地址,也就是讓fs:[0]指向新的節點。(可能你的程式碼有點不一樣,但是稍微分析下,對於異常處理這裡也是一樣的)

下面進入異常處理函數的地址查看(這裡是0x01293690)

 

 

然後再運行會暫停下來,因為出現了異常,異常優先給調試器處理,但是調試器也是可以選擇處理異常的:

在od的選項中選擇調試選項,再選擇異常:

 

 

就可以設置要捕獲的異常類型了,選擇忽略掉一些異常後再遇到就不會中斷下來了。

也可以選擇插件的StrongOD:

 

 

在取消掉Skip Some Exceptions之後,OD就會捕獲所有異常了

SEH鏈存放的位置

 

經過上面的分析可以知道了,SEH存放的位置在fs:[0]這裡

作業系統如何使用SEH

創建異常後,作業系統會自動把異常添加到頭結點,然後把頭指針指向新的異常節點

Tags: