展望未來:->windows XP下的向量化異常處理 (3千字)

看雪資料發表於2002-03-25

windows XP下的向量化異常處理(Vectored Exception Handling)
                                  原作:    Matt Pietrek
                                  翻譯改寫:  hume/冷雨飄心

首先回顧一下(SEH)結構化異常處理,結構化異常處理用EXCEPTION_RETGISTRATION結構鏈起來的異常處理系統,那麼當異常發生時,系統會遍歷這個鏈,首先是鏈最前面的,系統會問:這個異常你處理嗎?如果回答YES(透過返回EXCEPTION_CONTINUE_EXECUTION)的話,那系統就把控制權交給他,然後由其處理這個異常,返回到異常處理程式想返回的任何地方.如果透過返回EXCEPTION_CONTINUE_SEARCH回答:NO,let others do that! 系統就繼續查詢這個鏈,不厭其煩地問同樣的問題和採取相同的處理原則.這個鏈最前面的EXCEPTION_RETGISTRATION是由fs:[0]處的一個dword指標指向的.具體細節還請參閱相關資料或我以前的<<seh In Asm研究>>.

讓我們來看一下seh的缺點,就是最後安裝的seh處理例程總是優先得到控制權,這有時並不是最好的解決方案,但確實是seh的工作機制,當然Final型的或稱top型的(還記得嗎,也就是透過SetUnHandledExceptionFilter安裝的)例外,因為他是不允許巢狀的.我們提到的是執行緒相關的也就是per_Thread型別的.為什麼不是好的解決方案呢,讓我們設想一下,假如你用兩週寫了一個異常完美的seh處理例程,能夠完美處理所有異常,並希望異常全部由你來處理,但很不幸,比如你呼叫了一個外部模組,而這個模組自己安裝了一個ugly的seh處理例程,他的動作是隻要有異常發生就簡單地終止程式...hmmm...!!!這意味著什麼?你的兩週工作全部付諸東流!又比如你想在你的加殼程式裡面加密目標程式程式碼段,然後發生無效指令異常的時候用你自己安裝的處理控制程式碼來解密程式碼段繼續執行,聽起來這的確是一個好主意,但遺憾的是大多數C/C++程式碼都用_try{}_except{}塊來保證其正確執行,而這些異常處理例程是在你殼註冊的例程之後安裝的,因而也就在鏈的前面,無效指令一執行,首先是C/C++編譯器本身提供的處理例程或者程式其他的異常處理例程來處理,可能簡單結束程式或者....天知道!
    在Xp下,Microsoft又提供了又一種異常處理,那就是VEH(Vectored Exception Handling),我譯作向量異常處理,這個東東用如下api註冊,類似於SEH,也是一個鏈狀結構,讓我們來看看他的不同之處,噫,好像差不多啊:
    WINBASEAPI PVOID WINAPI AddVectoredExceptionHandler(
    ULONG FirstHandler,
    PVECTORED_EXCEPTION_HANDLER VectoredHandler );

    FirstHandler:是一個標誌,可以指定是否將你的VEH處理例程放在VEH鏈的最前面!
    VectoredHandler:這個東東是異常處理例程入口
    LONG NTAPI VectoredExceptionHandler(PEXCEPTION_POINTERS);
    PEXCEPTION_POINTERS是指向EXCEPTION_POINTERS的指標,具體EXCEPTION_POINTERS的結構是否和SEH的一致?估計是一致的,我裝了Xp,沒有下DDk呢,現在正在找!
    正像你看到的,好像和Final型SEH處理差不多?不一樣!區別如下:
    1)首先是AddVectoredExceptionHandler新增的異常處理控制程式碼可以巢狀,而不是隻能指定一個
    2)其次是AddVectoredExceptionHandler可以指定你的異常處理控制程式碼是否在鏈的最前面,hoho,這可是我們期望的!當然如果在你後面有人呼叫AddVectoredExceptionHandler也作同樣指定,那對不起,你只得在他後面了.

    相同之處在於他們都是程式而不是執行緒相關的.

    XP仍然支援SEH,那麼問題來了SEH和VEH是什麼關係,答案很簡單,VEH優先權高於SEH,只有所有VEH全不處理某個異常的時候,異常處理權才會到達SEH.只要目標程式中沒有利用VEH,你的VEH就是第一個得到控制者.哈哈,現在的採用SEH作為異常處理的普通C/C++程式對你不會再有干擾了!你可以用VEH來hook api了,god!

    另外一個問題,如果有debugger怎麼辦?控制權轉向又如何呢?不幸的訊息來了,異常發生後首先通知的還是debugger,debugger不處理才返回控制權給VEH,[VEH不處理,返回給SEH,seh不處理,又給debugger一個機會,如果還不處理,才由系統處理,這是我猜測的,Matt沒說這個問題,嘿嘿]

    RemoveVectoredExceptionHandler 用來移除VEH處理控制程式碼.是否需要看你的了,由於沒有下XP DDK,所以沒有實際程式碼,大家湊合著看,等我找到並下了DDK再說,由於要參加專業考試,所以玩耍要暫緩了,以後再寫東西翻譯東西的機會不多了,要等我9月考完再說,本來是好好學習的(剛剛發了誓),這不在網上遛Q看了Matt老哥吹的我又坐不住,當一個好訊息和大家共享,原文去MSDN查查,是 <<New Vectored Exception Handling in Windows XP>>.
   
    BB,我要開始聊天了:D...)!@#$%

相關文章