結構化異常(SEH)簡述,結構化seh簡述
/*********************************************************************
* Author : Samson
* Date : 08/04/2014
* Test platform:
* Linux ubuntu 3.2.0-58-generic-pae
* GNU bash, version 4.2.39
* *******************************************************************/
結構化例外處理常式?
SEH:structured Exception Handling,結構化異常處理。
結構化異常處理,是Windows作業系統上,Microsoft對C/C++程式語言做的文法擴充,用於處理例外狀況事件的程式控制結構。
例外狀況事件是打斷程式正常執行流程的不在期望之中的硬體、軟體事件。硬體異常是CPU拋出的如“除0”、數值溢出等;軟體異常是作業系統與程式通過RaiseException語句拋出的異常。
Microsoft擴充了C語言的文法,用 try-except與try-finally語句來處理異常。例外處理常式可以釋放已經擷取的資源、顯示出錯資訊與程式內部狀態供調試、從錯誤中恢複、嘗試重新執行出錯的代碼或者關閉程式等等。
一個__try語句不能既有__except,又有__finally。但try-except與try-finally語句可以嵌套使用。
允許在發生緊急情況時(如:記憶體訪問錯誤,被0除,或無效操作),由應用程式擷取控制權並自主處理,無需作業系統幹預。未被處理的異常通常會導致應用程式異常終止,隨之而來的是程式執行無效操作即將關閉的訊息。
__try { // 受保護執行的代碼}__except ( 過濾運算式 ){ // 異常處理代碼}
首先,__try複合陳述式中的受保護的代碼被執行。如果沒有異常發生,則繼續執行__except複合陳述式之後的代碼。如果__try複合陳述式中的受保護執行的代碼發生了異常,或受保護執行的代碼調用的函數內部發生了異常並要求調用者來處理該異常,__except語句的過濾運算式(filter expression)被求值,根據其結果來決定如何處理異常:
- EXCEPTION_CONTINUE_EXECUTION (–1) : 導致異常的問題已經解決,在異常出現的現場重新執行操作。
- EXCEPTION_CONTINUE_SEARCH (0) :當前__except語句不能處理該異常,通知作業系統繼續搜尋該線程其他的例外處理常式。
- EXCEPTION_EXECUTE_HANDLER (1):當前__except語句識別該異常,通過執行__except的複合陳述式來處理該異常。然後執行__except複合陳述式之後的代碼。
內在函數
GetExceptionCode返回一個32位整型值,表示異常的類型。
陷阱與攻擊:
在大部分情況下,指向結構化例外處理常式的指標都儲存在棧的SEH幀中,溢出緩衝區可以改寫它們。改寫SEH幀主要有兩個目的:通過替換結構化例外處理常式擷取控制權;萬一產生異常時,抵製程序異常終止。
windows 2003中內建的反緩衝區溢位及大部分類似的保護機制,都以SEH為基礎。駭客通過捕獲結構化例外處理常式,並用定製的處理常式替換它,就可以使這類保護機制失效。
REF:
http://zh.wikipedia.org/wiki/%E7%BB%93%E6%9E%84%E5%8C%96%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86
SEH體系是什東東阿
SEH:結構化異常處理
結構化異常處理是一種作業系統提供的機制,用來最佳化程式的結構,提供更加健壯的程式執行環境.試想想你寫程式不用考慮哪裡有個記憶體訪問錯誤,哪裡有個null 指標等等一類的錯誤,一直按照程式的邏輯結構向下寫,而不用去檢查函數是否成功,這會是多麼愉悅的事情(這個乃是seh的宣傳詞,不代表我的觀點,這裡完全是無責任應景之語).
結構化異常處理---seh,是一個作業系統級的概念,作業系統為每個線程(windows平台線程是系統調度的基本單元)維護一個異常處理鏈表,當有異常發生的時候,控制權轉移到作業系統手上,作業系統按照一定的方式遍曆這個鏈表,尋找合適的處理函數,執行處理工作,並且進行堆棧的unwind.
在usermode的線程啟動並執行時候,作業系統讓fs寄存器指向線程的環境塊(teb),這個teb是一個usermode可訪問的資料結構,在他的開頭嵌入一個叫NT_TIB結構的tib(線程資訊塊),這個tib裡面儲存著seh要用到的鏈表.
struct_TEB
{
NT_TIBNtTib;
......
};
structNT_TIB
{
EXCEPTION_REGISTRATION_RECORD*ExceptionList;
.....
};
structEXCEPTION_REGISTRATION_RECORD
{
EXCEPTION_REGISTRATION_RECORD*Next;
enum_EXCEPTION_DISPOSITION(*Handler)(_EXCEPTION_RECORD*ExceptionRecord,void*EstablisherFrame,_CONTEXT *ContextRecord,void*DispatcherContext);
};
線上程啟動並執行時候fs段就指向的是TEB結構.這個能在下面的彙編代碼裡面看到.
先具體的說說究竟異常發生的時候作業系統都作了什麼吧.
首先要明白什麼是異常,顧名思意,異常就是不尋常的地方(-.-b),cpu在遇到異常的時候,會引發一個中斷,作業系統會擷取到控制權(具體的情況,我就不能在這裡詳細的描述了),在經過必要的儲存現成等一系列動作以後,作業系統通過fs索引到TEB,也就是TIB,然後訪問到ExceptionList,調用他裡面的handler函數指標指向的函數,如果函數返回了,就檢查函數的傳回值,如果傳回值表示他不能處理這個異常,那麼就通過Next指標索引到下一個record,重複,到了鏈表的盡頭了,還是沒有人能處理,就自動的kill掉這個線程.
那那個handler是從哪裡來的呢?是應用程式在執行的時候給安裝的,也許你已經知道了,那個handler一般都指向了一個叫_except_handler3的函數,從上面已經看出來了,這個函數是整個seh的關鍵,下面會詳細的介紹這個函數.
在c語言裡面,seh的文法是__try....__except....__finally這樣構成的(具體的文法,這裡也不詳細說了),大家都知道,c語言是會轉編譯成機器語言,然後由cpu指向的,那這樣的一個__try結構都會被轉換成什麼樣子的機器語言呢?和他對等的組合語言是什麼樣子的呢?因為seh涉及到太多的底層,特別是記憶體布局是非常重要的,所以這裡必須要講講這個轉換的過程.
編譯器遇到了一個__try結構,他就知道應該要進行seh代碼產生了,也就是要完成上面的那個EXCEPTION_REGISTRATION_RECORD的連結,
push_except_handler3 ;這個r......餘下全文>>
C語言異常處理
bad_alloc:new分配失敗
bad_cast:dynamic_cast失敗
bad_typeid:typeif參數為空白
logic_error:邏輯錯誤
ios_base::failure:IO錯誤
runtime_error:執行階段錯誤
bad_exception:未知錯誤
賦值不成功可以用runtime_error,你也可以自己繼承一個異常類過來,自訂異常資訊