日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SEH链和展开操作

發布時間:2023/12/1 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SEH链和展开操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


每次我們定義了一個新的SEH異常處理回調函數,EXCEPTION_REGISTRATION結構的prev字段都被要求填寫上一個EXCEPTION_REGISTRATION結構的地址,隨著應用程序對模塊的調用一層層深入下去的時候,那么最后回調函數會形成一個SEH鏈

?

當程序中有多個線程在運行的時候,每個線程中都會存在各自的SEH鏈,這些SEH鏈中指定了多個回調函數,除他們以外,系統中可能還會存在一個全局性的篩選器,再者如果進程被調試,調試器進程也相當于一個異常處理的程序存在.那么當一個異常發生的時候,系統究竟該聽誰的呢?

?

在這種情況下,系統按一定的步驟選擇一個回調函數并執行他,如果這個回調函數可以執行這個異常,那么其他的回調函數都不會執行,否則系統執行下一個回調函數

(1).系統查看產生異常的進程是否正在被調試,如果正在被調試的話,那么向調試器發送EXCEPTION_DEBUG_EVENT事件

(2).如果進程沒有被調試或者調試器不去處理這個異常,那么系統 檢查異常所處的線程,并在這個線程環境中查看fs:[0]來確定是否安裝有SEH異常處理回調函數,如果有則調用它.

(3).回調函數嘗試處理這個異常,如果可以正確處理的話,則修正錯誤并將返回值設置為ExceptionContinueExecution,這時系統將結束整個查找過程

(4).如果回調函數返回ExceptionContinueSearch,告知系統他無法處理這個異常,那么系統將根據SEH鏈中的prev字段得到上一個回調函數地址,并重復步驟(3)過程,直到鏈中某個回調函數返回ExceptionContinueExecution為止,查找結束?

(5).如果到了SEH鏈的尾部,卻沒有一個回調函數愿意處理這個異常,那么系統將再次檢測進程是否正在被調試,如果被調試的話,則再次通知調試器

(6).如果調試器還是不去處理這個異常或者進程沒有被調試 ,那么系統檢查有沒有安裝篩選器回調函數,如果有,則去調用他,篩選器回調函數返回的時候,系統默認的異常處理程序根據這個返回值將做出相應的動作

(7).如果沒有安裝篩選器回調函數,系統直接 調用默認的異常處理程序終止進程

一個 比較形象的比喻就是:

Windows拿著一份異常處理的活挨個問每個回調函數
"你干不干" ,"不干","你呢","我也不干"... ... 當問到某一個的時候,
他說:"那我來干好了!"那么Windows就不會在去問其他人了,于是相安無事

有時,問完一圈后,誰都不愿意干(當然是干不了)Windows大怒:"誰都不干,看我炒了你們!"于是就把整個進程終止掉,所有的異常處理回調函數全部完蛋啦
(篩選器-全局的-進程的? SEH-線程的)

?完整的異常處理回調函數

<span style="font-family:Microsoft YaHei;font-size:13px;">_Handler1 proc C _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext;C調用方式-調用者自己平衡堆棧.if (異常代碼 == 0c0000027h) || (異常標志 & EXCEPTION_UNWINDING) || (異常標志 & EXCEPTION_UNWINDING_FOR_EXIT);進行資源釋放等掃尾工作mov eax,ExceptionContinueSearch.elseif 異常代碼 == 可以處理的異常代碼;處理異常,對CONTEXT進行修正;進行展開操作mov eax,ExceptionContinueExecution.else;其他無法處理的異常代碼mov eax,ExceptionContinueSearch.endifret_Handler1 endp</span>


?

二.展開操作(Unwinding)

如果把第一個SEH處理的函數的返回值改成ExceptionContinueSearch這個時候函數將會進行循環查找

這個時候回調函數應該進行一些掃尾工作,因為其將被卸載

注冊 Unwinding操作可以使用RtlUnwinding函數

invoke RtlUnwinding,lpLastStackFrame,lpCodeLabel,lpExceptionRecord,dwRet

(1).lpLastStackFrame:這個參數設置為NULL,那么他將對所有的SEH鏈進行展開操作,這時所有的回調函數參數中的異常標志在帶有EXCEPTION_UNWINDING的同時也帶有EXCEPTION_UNWINDING_FOR_EXIT標志位,這種方式稱為展開退出

指定為當前回調函數的EXCEPTION_REGISTRATION結構的地址的話,表示對當前回調函數之后的所有其他回調函數進行展開操作,這樣RtlUnwinding函數調用的每一個回調函數時,異常標記位都會帶有EXCEPTION_UNWINDING標記位

(2).lpCodeLabel參數指明函數將要返回的位置,如果位NULL,那么RtlUnwinding函數將返回到其后面的一條指令,否則函數直接返回到lpCodeLabel指定的位置

(3).lpExceptionRecord指定一個EXCEPTION_RECORD結構,這個結構將在調用的時候傳給每一個回調函數

(4).dwRet參數一般不被使用,它可以指明為NULL

?

使用RtlUnwinding函數時要注意的是:這個函數并不像其他API函數一樣保存esi,edi和ebx寄存器的值,在函數返回時候這些寄存器的值可能會改變,所以如果程序用到這些寄存器的話,必須手動去保存和恢復他們

?

?

<span style="font-family:Microsoft YaHei;font-size:13px;"> .386.model flat,stdcalloption casemap:none ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Include 文件定義 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.libL macro var:VARARGLOCAL @lbl.const@lbl db var,0.codeexitm <offset @lbl> endm ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 數據段 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.data szMsg1 db '這是外層異常處理程序(將處理異常)',0dh,0ahdb '異常發生位置:%08X,異常代碼:%08X,標志:%08X',0 szMsg2 db '這是內層異常處理程序(對異常不進行處理)',0dh,0ahdb '異常發生位置:%08X,異常代碼:%08X,標志:%08X',0 szCaption db '提示信息',0 szBeforeUnwind db '現在將開始 Unwind,當前的 FS:[0] = %08X',0 szAfterUnwind db 'Unwind 返回,當前的 FS:[0] = %08X',0 szSafe1 db '回到了外層子程序的安全位置!',0 szSafe2 db '回到了內層子程序的安全位置!',0 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 代碼段 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.code ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 外層錯誤 Handler,將處理異常 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _Handler1 proc C _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContextlocal @szBuffer[256]:bytepushadmov esi,_lpExceptionRecordmov edi,_lpContextassume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT,fs:nothinginvoke wsprintf,addr @szBuffer,addr szMsg1,\[edi].regEip,[esi].ExceptionCode,[esi].ExceptionFlagsinvoke MessageBox,NULL,addr @szBuffer,NULL,MB_OK ;******************************************************************** ; 將 EIP 指向安全的位置并恢復堆棧 ;********************************************************************mov eax,_lpSEHpush [eax + 8]pop [edi].regEippush _lpSEHpop [edi].regEsp ;******************************************************************** ; 對前面的 Handler 進行 Unwind 操作 ;********************************************************************invoke wsprintf,addr @szBuffer,addr szBeforeUnwind,dword ptr fs:[0]invoke MessageBox,NULL,addr @szBuffer,addr szCaption,MB_OKinvoke RtlUnwind,_lpSEH,NULL,NULL,NULLinvoke wsprintf,addr @szBuffer,addr szAfterUnwind,dword ptr fs:[0]invoke MessageBox,NULL,addr @szBuffer,addr szCaption,MB_OK ;********************************************************************assume esi:nothing,edi:nothingpopadmov eax,ExceptionContinueExecutionret_Handler1 endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 內層錯誤 Handler,不處理異常 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _Handler2 proc C _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContextlocal @szBuffer[256]:bytepushadmov esi,_lpExceptionRecordmov edi,_lpContextassume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXTinvoke wsprintf,addr @szBuffer,addr szMsg2,\[edi].regEip,[esi].ExceptionCode,[esi].ExceptionFlagsinvoke MessageBox,NULL,addr @szBuffer,NULL,MB_OKassume esi:nothing,edi:nothingpopadmov eax,ExceptionContinueSearchret_Handler2 endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _Test2 procassume fs:nothingpush offset _SafePlacepush offset _Handler2push fs:[0]mov fs:[0],esp ;******************************************************************** ; 會引發異常的指令 ;********************************************************************pushadxor eax,eaxmov dword ptr [eax],0popad ;這一句將無法被執行 _SafePlace:invoke MessageBox,NULL,L("回到了內層子程序的安全位置!"),L("提示信息"),MB_OKpop fs:[0]add esp,8ret_Test2 endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _Test1 procassume fs:nothingpush offset _SafePlacepush offset _Handler1push fs:[0]mov fs:[0],espinvoke _Test2 _SafePlace:invoke MessageBox,NULL,L("回到了外層子程序的安全位置!"),L("提示信息"),MB_OKpop fs:[0]add esp,8ret_Test1 endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> start:invoke _Test1invoke ExitProcess,NULL ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>end start </span>

?

?

?

?

?

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的SEH链和展开操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 五十路妻| 中文字幕综合网 | 欧美三区在线观看 | 韩日激情视频 | 国产免费黄网站 | av午夜精品 | 成人av国产 | 成人黄色片在线观看 | 蜜乳av网站 | 中国超碰 | 一级黄色性生活视频 | 午夜影院在线 | 97在线观看视频 | 97国产在线| 精品久久久久久久中文字幕 | 长腿校花无力呻吟娇喘的视频 | 久久无码人妻精品一区二区三区 | 蜜桃久久久久久久 | 在线成人播放 | 国产乱国产 | 成人网页 | 影音先锋欧美在线 | a亚洲天堂 | 中国精品一区二区 | 中文字幕一区二区人妻在线不卡 | 亚洲麻豆一区二区三区 | 中文字幕不卡在线观看 | 欧美在线视频网 | 亚洲精品乱 | 欧美三级在线观看视频 | 久久久久久1 | 国产视频在线观看免费 | 欧美一级片免费观看 | 久久综合99 | 久久911| 91久久久久久久久久久久久 | 黑人玩弄人妻一区二区三区影院 | 午夜精品久久久久久久久久久久久蜜桃 | 国产欧美精品区一区二区三区 | 国产成人av电影 | 九色免费视频 | www青青草| 国产一区二区免费 | 午夜试看120秒 | 国产香蕉在线观看 | 翔田千里一区二区三区av | 丰满人妻熟妇乱偷人无码 | 裸体视频软件 | 色一情一区二区三区四区 | 国产香蕉一区二区三区 | 另类老妇性bbwbbw图片 | 在线免费看mv的网站入口 | 精品乱子伦一区二区三区 | 色臀av | 自拍偷拍视频在线 | 亚洲h动漫| 亚洲区中文字幕 | 亚洲一区电影在线观看 | 福利所导航 | 双性尿奴穿贞c带憋尿 | 国产制服在线 | 中文字幕1区2区3区 www.com黄色片 | 2021狠狠操 | 久久机热这里只有精品 | 亚洲影院中文字幕 | 夜夜嗨av色一区二区不卡 | 日韩电影中文字幕在线观看 | 成人在线免费观看视频 | 亚洲一区欧美一区 | 日韩熟女一区二区 | 一级片在线 | 在线一区观看 | 性色影院 | 97视频在线看 | 成人在线精品 | 天天舔天天干天天操 | 理论黄色片 | 在线观看sm | 青娱乐导航| 欧美日韩精品在线 | 国产三级三级三级三级三级 | 日韩激情第一页 | 激情六月天婷婷 | av在线不卡观看 | 亚洲av成人一区二区 | av夜夜| 新天堂网| 国产人妻一区二区三区四区五区六 | 成人免费黄| 91麻豆蜜桃一区二区三区 | 色妞av| jizz性欧美2| 国产午夜大片 | 国产青青操 | 精品欧美一区二区久久久久 | 激情亚洲视频 | 蜜桃av噜噜一区二区三区网址 | 亚洲色图一区二区三区 | 亚洲av无码专区国产乱码不卡 |