標 題: 【原創】加密與解密二版菜鳥學習筆記(2) - SEH 結構化異常處理
作 者: ytcswb 時 間: 2005-02-01,16:40:24 鏈 接: http://bbs.pediy.com/showthread.php?t=10651 看學加密與解密二版學習筆記(2) - SEH 結構化異常處理 [ 工 具 ] flyod1.10 [ 目 的 ] 學習SEH的手法,另書中是用SoftICE調試的,看起來不習慣.根據原文內容重新整理一下,便於和我一樣的菜鳥們一起學習. 今天下決心,好好學習,這是就算是個開始吧!感覺學明白的確很不容易! [ 注 釋 ] ?--爲不能理解的地方,請大俠們指點一下.學習過程中,有理解錯誤的地方,肯請大俠們多多指教. [練習對象] 加密與加密二版第10章,光盤配套的練習軟件:seh.exe seh2.exe [ writer ] ytcswb 2005.2.1 感謝看學及論壇的大俠們爲我們提供這麼好的學習資料。 1.例子seh.exe學習: 00401000 > $ 8D4424 F8 lea eax,dword ptr ss:[esp-8] //程序入口!根據下面的代碼分析,這裏顯然可以 //理解爲開闢8字節的空間,並把棧頂指針保存到eax //相當於sub esp,8 ; lea eax,dword ptr ss:[esp] 00401004 . 64:8705 00000>xchg dword ptr fs:[0],eax //記住fs[0]永遠是指向當前err結構的指針, //執行完成後,fs[0]指向棧頂,準備在堆棧中構造1個err結構 //eax等於原fs[0],即指向原來的err結構的指針,即那個err結構的地址 0040100B . BB 2E104000 mov ebx,Seh.0040102E //地址40102e-->ebx,建議在此地址上設斷點,才能正常跟蹤入seh代碼中 00401010 . 53 push ebx //壓入堆棧,即當前err結構的handler成員,當前異常處理代碼的入口地址 00401011 . 50 push eax //壓入原fs[0],即當前err結構的prev成員,即下一個err結構的地址 此時堆棧: 0012FFBC 0012FFE0 指針到下一個 SEH 記錄 //0012FFE0是個指針,看看就知道指向下一個err結構,數值上等於下一個err結構的地址 0012FFC0 0040102E SE 句柄 //建立了1個當前的err結構 0012FFE0 FFFFFFFF SEH 鏈尾部 0012FFE4 77E74809 SE 句柄 err結構的定義[在Essup.INC源文件中定義的---VC++ CRT(CRT含義:C++RunTime library)]: _EXCEPTION _REGISTERATION stru prev dd ? //指向下一個err結構的指針,數值上等於下一個err結構的首地址(在堆棧中) handler dd ? //指向異常處理代碼的指針,數值上等於異常處理代碼的入口地址即首地址 _EXCEPTION _REGISTERATION ends 00401012 . BE 00000000 mov esi,0 //簡單的賦值語句 00401017 . 8B06 mov eax,dword ptr ds:[esi] //讀取線性地址0,產生異常 //執行後,windows檢查到異常,執行線程馬上被中段,從用戶模式轉到內核模式 //控制權交到操作系統的異常調試程序(exception dispatcher),由它負責找到 //處理這個異常的方法,即所有應用程序的異常最終都是由windwos來處理的, //同一個版本的windows有固定的異常處理代碼. //如果你把這句nop掉了,也就等於去除了異常.會接着執行到下面的代碼,並顯示"SEH Fail"! 00401019 . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 0040101B . 68 00304000 push Seh.00403000 ; |Title = "OK" 00401020 . 68 10304000 push Seh.00403010 ; |Text = "SEH Fail" 00401025 . 6A 00 push 0 ; |hOwner = NULL 00401027 . E8 1C000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 0040102C . EB 13 jmp short Seh.00401041 0040102E . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 00401030 . 68 00304000 push Seh.00403000 ; |Title = "OK" 00401035 . 68 03304000 push Seh.00403003 ; |Text = "SEH Succeed " 0040103A . 6A 00 push 0 ; |hOwner = NULL 0040103C . E8 07000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 00401041 > 6A 00 push 0 ; /ExitCode = 0 00401043 . E8 06000000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess 00401048 $- FF25 08204000 jmp dword ptr ds:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA 0040104E .- FF25 00204000 jmp dword ptr ds:[<&KERNEL32.ExitProcess>; kernel32.ExitProcess 00401054 00 db 00 00401055 00 db 00 --------------------------------------------------------------------------------------------------- 00401017 . 8B06 mov eax,dword ptr ds:[esi] //讀取線性地址0,產生異常 //執行完這1條指令,od的狀態行可以看到,產生了什麼異常.狀態行的內容如下: //訪問違反:讀取[00000000],使用shift+F7/F8/F9鍵跳過異常以繼續執行程序. //windows檢測到了這個異常,就會向堆棧壓入3個結構.壓入順序爲 EXCEPTION_RECORD,EXCEPTION_CONTEXT,EXCEPTION_POINTERS //EXCEPTION_POINTERS結構就在棧頂,其定義如下: typedef strut_EXCEPTION_POINTERS{ +0 pEXCEPTION_RECORD ExceptionRecord DWORD ? //指針,指向EXCEPTION_RECORD結構,即EXCEPTION_RECORD的首地址 +4 pCONTEXT ContextRecord DWORD ? //指針,指向EXCEPTION_CONTEXT結構,即EXCEPTION_CONTEXT的首地址 }_EXCEPTION_POINTERS ends 在看看EXCEPTION_RECORD結構: EXCEPTION_RECORD struct{ //共6個成員 +0 DWORD ExceptionCode //異常代碼,定義了產生異常的原因 +4 DWORD ExceptionFlags //異常標誌 ? +8 struct EXCEPTION_RECORD //指針,指向另一個EXCEPTION_RECORD結構 +C DVOID ExceptionAddress //異常發生的地址 +10 DWORD NumberParameters //與異常聯繫的參數個數(0~15)一般=0 ? +14 ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS] //異常信息 ? }EXCEPTION_RECORD ends //執行完401017指令後,我們在od的代碼窗口的看到代碼如下: 77FB4DAF > 8B4C24 04 mov ecx,dword ptr ss:[esp+4] 77FB4DB3 8B1C24 mov ebx,dword ptr ss:[esp] //來到了ntdll領空,即系統領空 { //馬上看看堆棧: 0012FCCC 0012FCD4 -| //指針,指向EXCEPTION_RECORD結構,即EXCEPTION_RECORD的首地址-----\這就是EXCEPTION_POINTERS 0012FCD0 0012FCF0 -| //指針,指向EXCEPTION_CONTEXT結構,即EXCEPTION_CONTEXT的首地址---\ 0012FCD4 C0000005---------------\1--異常代碼.這裏開始就是EXCEPTION_RECORD結構 0012FCD8 00000000 \2--異常標誌=0 0012FCDC 00000000 \3--指針,指向另一個EXCEPTION_RECORD結構,這裏=0 沒有另一個EXCEPTION_RECORD結構,爲NULL指針. 0012FCE0 00401017 Seh.00401017 \4--異常發生的地址,這就是發生異常的那條指令的地址. 0012FCE4 00000002 \5--與異常聯繫的參數個數=2 ? 0012FCE8 00000000 \6--異常信息 ? 0012FCEC 00000000---------------\ 0012FCF0 0001003F---------------\這裏開始就是EXCEPTION_CONTEXT結構,ContextFlags 0012FCF4 00000000 \Dr0 0012FCF8 00000000 \Dr1 0012FCFC 00000000 \Dr2 0012FD00 00000000 \Dr3 0012FD04 0000A000 \Dr6 0012FD08 00000000 \Dr7 我們重點看看0012FCF0 +B8=12FDA8 0012FDA4 0012FFF0 0012FDA8 00401017 Seh.00401017 \異常發生的地址,這就是發生異常的那條指令的地址. 0012FDAC 0000001B } 繼續跟蹤: 77FB4DB6 51 push ecx //指針,指向EXCEPTION_CONTEXT結構 77FB4DB7 53 push ebx //指針,指向EXCEPTION_RECORD結構 77FB4DB8 E8 ACBDFAFF call ntdll.77F60B69 //如果f8過,會出現SEH succeed 提示窗口,即執行了程序自己的異常代碼, //爲了看系統是如何處理的,我們f7進入 77FB4DBD 0AC0 or al,al 77FB4DBF 74 0C je short ntdll.77FB4DCD 77FB4DC1 5B pop ebx 77FB4DC2 59 pop ecx 77FB4DC3 6A 00 push 0 77FB4DC5 51 push ecx 77FB4DC6 E8 480BFCFF call ntdll.ZwContinue 77FB4DCB EB 0B jmp short ntdll.77FB4DD8 77FB4DCD 5B pop ebx 77FB4DCE 59 pop ecx 77FB4DCF 6A 00 push 0 77FB4DD1 51 push ecx 77FB4DD2 53 push ebx 77FB4DD3 E8 F213FCFF call ntdll.ZwRaiseException 77FB4DD8 83C4 EC add esp,-14 77FB4DDB 890424 mov dword ptr ss:[esp],eax 77FB4DDE C74424 04 01000>mov dword ptr ss:[esp+4],1 77FB4DE6 895C24 08 mov dword ptr ss:[esp+8],ebx 77FB4DEA C74424 10 00000>mov dword ptr ss:[esp+10],0 77FB4DF2 54 push esp 77FB4DF3 E8 AFC2F9FF call ntdll.RtlRaiseException 77FB4DF8 C2 0800 retn 8 繼續跟到這段代碼裏: 77F79B7E 55 push ebp 77F79B7F 8BEC mov ebp,esp 77F79B81 FF75 0C push dword ptr ss:[ebp+C] 77F79B84 52 push edx 77F79B85 64:FF35 0000000>push dword ptr fs:[0] 77F79B8C 64:8925 0000000>mov dword ptr fs:[0],esp { //堆棧建立了1個err結構 0012FC04 0012FFBC 指針到下一個 SEH 記錄 //enter鍵看看 0012FC08 77F79BB8 SE 句柄 0012FFBC 0012FFE0 指針到下一個 SEH 記錄 0012FFC0 0040102E SE 句柄 // 熟悉這個地址吧 0012FFE0 FFFFFFFF SEH 鏈尾部 0012FFE4 77E74809 SE 句柄 } 77F79B93 FF75 14 push dword ptr ss:[ebp+14] 77F79B96 FF75 10 push dword ptr ss:[ebp+10] 77F79B99 FF75 0C push dword ptr ss:[ebp+C] 77F79B9C FF75 08 push dword ptr ss:[ebp+8] 77F79B9F 8B4D 18 mov ecx,dword ptr ss:[ebp+18] { //此時我們馬上看看堆棧: 0012FBF4 0012FCD4 //指針,指向EXCEPTION_RECORD結構,即EXCEPTION_RECORD的首地址 -----回調函數的參數1 0012FBF8 0012FFBC //指向err結構.可以看看上面我們截取的SEH鏈表 -----回調函數的參數2 0012FBFC 0012FCF0 //指針,指向EXCEPTION_CONTEXT結構,即EXCEPTION_CONTEXT的首地址-----回調函數的參數3 0012FC00 0012FCAC //參數4 _lpDispatchrContext ? 最先被壓入堆棧. 0012FC04 0012FFBC 指針到下一個 SEH 記錄 0012FC08 77F79BB8 SE 句柄 0012FC0C 0012FFBC } 77F79BA2 FFD1 call ecx //Seh.0040102E到這裏執行,就是程序的自己的異常處理代碼,f7 //這就是異常處理回調函數,其參數含義請往下看. { 0040102C . /EB 13 jmp short Seh.00401041 0040102E . |6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 00401030 . |68 00304000 push Seh.00403000 ; |Title = "OK" 00401035 . |68 03304000 push Seh.00403003 ; |Text = "SEH Succeed " 0040103A . |6A 00 push 0 ; |hOwner = NULL 0040103C . |E8 07000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 00401041 > \6A 00 push 0 ; /ExitCode = 0 00401043 . E8 06000000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess 00401048 $- FF25 08204000 jmp dword ptr ds:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA 0040104E .- FF25 00204000 jmp dword ptr ds:[<&KERNEL32.ExitProcess>; kernel32.ExitProcess } 77F79BA4 64:8B25 0000000>mov esp,dword ptr fs:[0] 77F79BAB 64:8F05 0000000>pop dword ptr fs:[0] 77F79BB2 8BE5 mov esp,ebp 77F79BB4 5D pop ebp 77F79BB5 C2 1400 retn 14 [總結] //讀取線性地址0,產生異常 //執行後,windows檢查到異常,執行線程馬上被中段,從用戶模式轉到內核模式 //控制權交到操作系統的異常調試程序(exception dispatcher),由它負責找到 //處理這個異常的方法,即所有應用程序的異常最終都是由windwos來處理的, //那麼同一個版本的windows就有固定的異常處理代碼.跟蹤seh保護的程序時,以此爲切入點,可以輕而一舉地找到關鍵! 2.例子seh2.exe學習: 00401000 >/$ 68 51104000 push seh2.00401051 ; SE handler installation發生異常後到這裏執行 //看學強調:提前在這個handler設個斷點,否則程序容易跑飛! //只有這樣才能正常跟進seh處理代碼! 00401005 |. 64:FF35 00000>push dword ptr fs:[0] 0040100C |. 64:8925 00000>mov dword ptr fs:[0],esp //構造1個err結構 0012FFBC 0012FFE0 指針到下一個 SEH 記錄 //fs:[0]=esp=0x0012FFBC 0012FFC0 00401051 SE 句柄 0012FFE0 FFFFFFFF SEH 鏈尾部 0012FFE4 77E74809 SE 句柄 00401013 |. BE 00000000 mov esi,0 00401018 |. 8B06 mov eax,dword ptr ds:[esi] //產生異常 //這裏實際是故意引發一個異常,爲的就是通過修改CONTEXT,來實現反跟蹤及改變程序流程(設置暗樁嗎?) 0040101A |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 0040101C |. 68 00304000 push seh2.00403000 ; |Title = "SEH" 00401021 |. 68 0F304000 push seh2.0040300F ; |Text = "SEH程序沒有運行" 00401026 |. 6A 00 push 0 ; |hOwner = NULL 00401028 |. E8 57000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 0040102D |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 0040102F |. 68 00304000 push seh2.00403000 ; |Title = "SEH" 00401034 |. 68 04304000 push seh2.00403004 ; |Text = "Hello,SEH!" 00401039 |. 6A 00 push 0 ; |hOwner = NULL 0040103B |. E8 44000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 00401040 |. 64:8F05 00000>pop dword ptr fs:[0] 00401047 |. 83C4 04 add esp,4 0040104A |. 6A 00 push 0 ; /ExitCode = 0 0040104C \. E8 39000000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess 00401051 /$ 55 push ebp ; Structured exception handler 00401052 |. 8BEC mov ebp,esp 00401054 |. 53 push ebx 00401055 |. 8B45 10 mov eax,dword ptr ss:[ebp+10] 00401058 |. 8D1D 2D104000 lea ebx,dword ptr ds:[40102D] 0040105E |. 8998 B8000000 mov dword ptr ds:[eax+B8],ebx 00401064 |. 33DB xor ebx,ebx 00401066 |. 8958 04 mov dword ptr ds:[eax+4],ebx 00401069 |. 8958 08 mov dword ptr ds:[eax+8],ebx 0040106C |. 8958 0C mov dword ptr ds:[eax+C],ebx 0040106F |. 8958 10 mov dword ptr ds:[eax+10],ebx 00401072 |. C740 18 55010>mov dword ptr ds:[eax+18],155 00401079 |. B8 00000000 mov eax,0 0040107E |. 5B pop ebx 0040107F |. C9 leave 00401080 \. C2 1000 retn 10 00401083 CC int3 發生異常,就來到這裏: 看堆棧: 0012FCCC 0012FCD4 //指針,指向EXCEPTION_RECORD結構,即EXCEPTION_RECORD的首地址-----\這就是EXCEPTION_POINTERS 0012FCD0 0012FCF0 //指針,指向EXCEPTION_CONTEXT結構,即EXCEPTION_CONTEXT的首地址---\ 0012FCD4 C0000005 ---------------\1--異常代碼.這裏開始就是EXCEPTION_RECORD結構 0012FCD8 00000000 0012FCDC 00000000 0012FCE0 00401018 seh2.00401018 \4--異常發生的地址,這就是發生異常的那條指令的地址. 0012FCE4 00000002 0012FCE8 00000000 0012FCEC 00000000 0012FCF0 0001003F ---------------\這裏開始就是EXCEPTION_CONTEXT結構,ContextFlags 0012FCF4 00000000 //dr0 0012FCF8 00000000 //dr1 0012FCFC 00000000 //dr2 0012FD00 00000000 //dr3 0012FD04 0000A000 //dr6 0012FD08 00000000 //dr7 0012FD0C FFFF027F 77FB4DB3 8B1C24 mov ebx,dword ptr ss:[esp] 77FB4DB6 51 push ecx 77FB4DB7 53 push ebx 77FB4DB8 E8 ACBDFAFF call ntdll.77F60B69 //f7 77FB4DBD 0AC0 or al,al 77FB4DBF 74 0C je short ntdll.77FB4DCD 77FB4DC1 5B pop ebx 77FB4DC2 59 pop ecx 77FB4DC3 6A 00 push 0 77FB4DC5 51 push ecx 77FB4DC6 E8 480BFCFF call ntdll.ZwContinue 77FB4DCB EB 0B jmp short ntdll.77FB4DD8 77FB4DCD 5B pop ebx 77FB4DCE 59 pop ecx 77FB4DCF 6A 00 push 0 77FB4DD1 51 push ecx 77FB4DD2 53 push ebx 77FB4DD3 E8 F213FCFF call ntdll.ZwRaiseException 77FB4DD8 83C4 EC add esp,-14 77FB4DDB 890424 mov dword ptr ss:[esp],eax 77FB4DDE C74424 04 01000>mov dword ptr ss:[esp+4],1 77FB4DE6 895C24 08 mov dword ptr ss:[esp+8],ebx 77FB4DEA C74424 10 00000>mov dword ptr ss:[esp+10],0 77FB4DF2 54 push esp 77FB4DF3 E8 AFC2F9FF call ntdll.RtlRaiseException 77FB4DF8 C2 0800 retn 8 77FB4DFB >^ E9 7DBCFAFF jmp ntdll.77F60A7D 77F79B7E 55 push ebp 77F79B7F 8BEC mov ebp,esp 77F79B81 FF75 0C push dword ptr ss:[ebp+C] 77F79B84 52 push edx 77F79B85 64:FF35 0000000>push dword ptr fs:[0] 77F79B8C 64:8925 0000000>mov dword ptr fs:[0],esp 77F79B93 FF75 14 push dword ptr ss:[ebp+14] //參數4 _lpDispatchrContext ? 77F79B96 FF75 10 push dword ptr ss:[ebp+10] //參數3 _lpDContext,指向Context結構 77F79B99 FF75 0C push dword ptr ss:[ebp+C] //參數2 _lpSEH ,指向ERR結構 77F79B9C FF75 08 push dword ptr ss:[ebp+8] //參數1 _lpExceptionRecord ,指向ExceptionRecord結構 77F79B9F 8B4D 18 mov ecx,dword ptr ss:[ebp+18] 77F79BA2 FFD1 call ecx ; seh2.00401051 轉到這裏了 f7 //這就是異常處理回調函數,執行當前異常處理代碼即401051處 //注:回調函數都是由windows調用的! //看學強調: 在此回調函數上設斷點,可以輕易地對付一些加殼的反跟蹤代碼!!!!! 77F79BA4 64:8B25 0000000>mov esp,dword ptr fs:[0] //恢復原來的SEH鏈表 77F79BAB 64:8F05 0000000>pop dword ptr fs:[0] 77F79BB2 8BE5 mov esp,ebp 77F79BB4 5D pop ebp 77F79BB5 C2 1400 retn 14 00401051 /$ 55 push ebp ; Structured exception handler 00401052 |. 8BEC mov ebp,esp 00401054 |. 53 push ebx 00401055 |. 8B45 10 mov eax,dword ptr ss:[ebp+10] // eax是CONTEXT結構的指針 00401058 |. 8D1D 2D104000 lea ebx,dword ptr ds:[40102D] //通過修改CONTEXT.EIP,希望到這裏執行! 0040105E |. 8998 B8000000 mov dword ptr ds:[eax+B8],ebx //修改CONTEXT.EIP,改變程序執行線路,這大概就是利用seh的常用手法! //沒改時,是401018即發生異常的指令地址,經過1輪處理又會到這裏執行 //又產生異常 00401064 |. 33DB xor ebx,ebx 00401066 |. 8958 04 mov dword ptr ds:[eax+4],ebx //DR0 清零,使斷點失效,這大概也是利用seh的常用手法,實現反跟蹤! 00401069 |. 8958 08 mov dword ptr ds:[eax+8],ebx //DR1 0040106C |. 8958 0C mov dword ptr ds:[eax+C],ebx //DR2 0040106F |. 8958 10 mov dword ptr ds:[eax+10],ebx//DR3 00401072 |. C740 18 55010>mov dword ptr ds:[eax+18],155 //DR7 00401079 |. B8 00000000 mov eax,0 //回調處理函數的返回值ExceptionContinueExcetion-->eax //ExceptionContinueExcetion=0 回調函數返回後,系統將線程環境恢復到_lpContext參數指定的CONTEXT結構並繼續執行. 即,表示已經修復,從異常處繼續執行,如果前面沒有修改CONTEXT.EIP的值,就會到401018即異常發生處 繼續執行,由於前面修改了CONTEXT.EIP=40102D,所以就轉到40102D處繼續執行了. //ExceptionContinueExcetion=1 回調函數拒絕處理這個異常,系統將通過err結構的prev指針得到前一個回掉函數的地址並繼續執行它 也就是轉到前一個err結構的異常處理代碼處繼續執行. //ExceptionContinueExcetion=2 回調函數在執行中又發生了異常,即嵌套異常 //ExceptionContinueExcetion=3 發生嵌套的展開操作 ? 0040107E |. 5B pop ebx 0040107F |. C9 leave 00401080 \. C2 1000 retn 10 [總結] //看學強調: 在此回調函數上設斷點,可以輕易地對付一些加殼的反跟蹤代碼!!!!! //看學強調: 要提前在err結構的handler地址上設斷點,否則代碼就可能跑飛跟蹤seh的關鍵斷點!!!! //看學提示: 可修改CONTEXT結構成員,來實現反跟蹤及改變程序流程(設置暗樁嗎?) ************************************************************************************************************** [附錄] 跟蹤到異常處理回調函數的過程: 注: windows xp-sp1平臺.只要是同樣平臺,就可以按下面步驟,來到系統的異常處理回調函數. 熟悉一下這段代碼,應該有好處,當發生異常時,可以快速找到那個call ecx異常處理回調函數,從而找到程序自己的異常處理代碼。 00401000 >/$ 68 51104000 push seh2.00401051 // SE handler installation //只有在這個401051上設斷點,才能跟到異常處理代碼(SEH代碼)處. //即要提前在err結構的handler地址上設斷點,否則代碼就可能跑飛! //跟蹤seh的關鍵斷點!!!! 00401005 |. 64:FF35 00000>push dword ptr fs:[0] 0040100C |. 64:8925 00000>mov dword ptr fs:[0],esp 00401013 |. BE 00000000 mov esi,0 00401018 |. 8B06 mov eax,dword ptr ds:[esi] //產生異常,來到 代碼[1] 0040101A |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 0040101C |. 68 00304000 push seh2.00403000 ; |Title = "SEH" 00401021 |. 68 0F304000 push seh2.0040300F ; |Text = "SEH程序沒有運行" 00401026 |. 6A 00 push 0 ; |hOwner = NULL 00401028 |. E8 57000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 0040102D |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 0040102F |. 68 00304000 push seh2.00403000 ; |Title = "SEH" 00401034 |. 68 04304000 push seh2.00403004 ; |Text = "Hello,SEH!" 00401039 |. 6A 00 push 0 ; |hOwner = NULL 0040103B |. E8 44000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 00401040 |. 64:8F05 00000>pop dword ptr fs:[0] 00401047 |. 83C4 04 add esp,4 0040104A |. 6A 00 push 0 ; /ExitCode = 0 0040104C \. E8 39000000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess 00401051 /$ 55 push ebp ; Structured exception handler 00401052 |. 8BEC mov ebp,esp 00401054 |. 53 push ebx 00401055 |. 8B45 10 mov eax,dword ptr ss:[ebp+10] 00401058 |. 8D1D 2D104000 lea ebx,dword ptr ds:[40102D] 0040105E 8998 B8000000 mov dword ptr ds:[eax+B8],ebx 00401064 |. 33DB xor ebx,ebx 00401066 |. 8958 04 mov dword ptr ds:[eax+4],ebx 00401069 |. 8958 08 mov dword ptr ds:[eax+8],ebx 0040106C |. 8958 0C mov dword ptr ds:[eax+C],ebx 0040106F |. 8958 10 mov dword ptr ds:[eax+10],ebx 00401072 |. C740 18 55010>mov dword ptr ds:[eax+18],155 00401079 |. B8 00000000 mov eax,0 0040107E |. 5B pop ebx 0040107F |. C9 leave 00401080 \. C2 1000 retn 10 代碼[1] 77FB4DB3 8B1C24 mov ebx,dword ptr ss:[esp] 77FB4DB6 51 push ecx 77FB4DB7 53 push ebx 77FB4DB8 E8 ACBDFAFF call ntdll.77F60B69 //F7 進入,來到代碼 [2] 77FB4DBD 0AC0 or al,al 77FB4DBF 74 0C je short ntdll.77FB4DCD 77FB4DC1 5B pop ebx 77FB4DC2 59 pop ecx 77FB4DC3 6A 00 push 0 77FB4DC5 51 push ecx 77FB4DC6 E8 480BFCFF call ntdll.ZwContinue //代碼[5],F7進入,回到代碼[6] 77FB4DCB EB 0B jmp short ntdll.77FB4DD8 77FB4DCD 5B pop ebx 77FB4DCE 59 pop ecx 77FB4DCF 6A 00 push 0 77FB4DD1 51 push ecx 77FB4DD2 53 push ebx 77FB4DD3 E8 F213FCFF call ntdll.ZwRaiseException 77FB4DD8 83C4 EC add esp,-14 77FB4DDB 890424 mov dword ptr ss:[esp],eax 77FB4DDE C74424 04 01000>mov dword ptr ss:[esp+4],1 77FB4DE6 895C24 08 mov dword ptr ss:[esp+8],ebx 77FB4DEA C74424 10 00000>mov dword ptr ss:[esp+10],0 77FB4DF2 54 push esp 77FB4DF3 E8 AFC2F9FF call ntdll.RtlRaiseException 77FB4DF8 C2 0800 retn 8 77FB4DFB >^ E9 7DBCFAFF jmp ntdll.77F60A7D 代碼 [2] 77F60B69 55 push ebp 77F60B6A 8BEC mov ebp,esp 77F60B6C 83EC 60 sub esp,60 77F60B6F 56 push esi 77F60B70 FF75 0C push dword ptr ss:[ebp+C] 77F60B73 8B75 08 mov esi,dword ptr ss:[ebp+8] 77F60B76 56 push esi 77F60B77 E8 AA000000 call ntdll.77F60C26 77F60B7C 84C0 test al,al 77F60B7E 0F85 EB6F0200 jnz ntdll.77F87B6F 77F60B84 53 push ebx 77F60B85 57 push edi 77F60B86 8D45 F8 lea eax,dword ptr ss:[ebp-8] 77F60B89 50 push eax 77F60B8A 8D45 FC lea eax,dword ptr ss:[ebp-4] 77F60B8D 50 push eax 77F60B8E E8 3C910100 call ntdll.77F79CCF 77F60B93 E8 52910100 call ntdll.77F79CEA 77F60B98 8365 08 00 and dword ptr ss:[ebp+8],0 77F60B9C 8BD8 mov ebx,eax 77F60B9E 83FB FF cmp ebx,-1 77F60BA1 0F84 4A1C0100 je ntdll.77F727F1 77F60BA7 3B5D FC cmp ebx,dword ptr ss:[ebp-4] 77F60BAA 0F82 481C0100 jb ntdll.77F727F8 77F60BB0 8D43 08 lea eax,dword ptr ds:[ebx+8] 77F60BB3 3B45 F8 cmp eax,dword ptr ss:[ebp-8] 77F60BB6 0F87 3C1C0100 ja ntdll.77F727F8 77F60BBC F6C3 03 test bl,3 77F60BBF 0F85 331C0100 jnz ntdll.77F727F8 77F60BC5 8B43 04 mov eax,dword ptr ds:[ebx+4] 77F60BC8 3B45 FC cmp eax,dword ptr ss:[ebp-4] 77F60BCB 72 09 jb short ntdll.77F60BD6 77F60BCD 3B45 F8 cmp eax,dword ptr ss:[ebp-8] 77F60BD0 0F82 221C0100 jb ntdll.77F727F8 77F60BD6 F605 4A32FC77 8>test byte ptr ds:[77FC324A],80 77F60BDD 0F85 936F0200 jnz ntdll.77F87B76 77F60BE3 FF73 04 push dword ptr ds:[ebx+4] 77F60BE6 8D45 F0 lea eax,dword ptr ss:[ebp-10] 77F60BE9 50 push eax 77F60BEA FF75 0C push dword ptr ss:[ebp+C] 77F60BED 53 push ebx 77F60BEE 56 push esi 77F60BEF E8 528F0100 call ntdll.77F79B46 // F4下,F7進入,來到代碼[3] 77F60BF4 F605 4A32FC77 8>test byte ptr ds:[77FC324A],80 77F60BFB 8BF8 mov edi,eax 77F60BFD 0F85 896F0200 jnz ntdll.77F87B8C 77F60C03 395D 08 cmp dword ptr ss:[ebp+8],ebx 77F60C06 0F84 8E6F0200 je ntdll.77F87B9A 77F60C0C 8BC7 mov eax,edi 77F60C0E 33C9 xor ecx,ecx 77F60C10 2BC1 sub eax,ecx 77F60C12 0F84 3E340100 je ntdll.77F74056 77F60C18 48 dec eax 77F60C19 0F85 886F0200 jnz ntdll.77F87BA7 77F60C1F 8B1B mov ebx,dword ptr ds:[ebx] 77F60C21 ^ E9 78FFFFFF jmp ntdll.77F60B9E 77F60C26 55 push ebp 77F60C27 8BEC mov ebp,esp 77F60C29 51 push ecx 77F60C2A 51 push ecx 77F60C2B 57 push edi 77F60C2C BF 1032FC77 mov edi,ntdll.77FC3210 77F60C31 393D 1032FC77 cmp dword ptr ds:[77FC3210],edi 77F60C37 0F85 48E80100 jnz ntdll.77F7F485 77F60C3D 32C0 xor al,al 77F60C3F 5F pop edi 77F60C40 C9 leave 77F60C41 C2 0800 retn 8 77F60C44 > 55 push ebp 代碼[3] 77F79B46 BA B89BF777 mov edx,ntdll.77F79BB8 77F79B4B EB 07 jmp short ntdll.77F79B54 77F79B4D BA DF9BF777 mov edx,ntdll.77F79BDF 77F79B52 8D09 lea ecx,dword ptr ds:[ecx] 77F79B54 53 push ebx 77F79B55 56 push esi 77F79B56 57 push edi 77F79B57 33C0 xor eax,eax 77F79B59 33DB xor ebx,ebx 77F79B5B 33F6 xor esi,esi 77F79B5D 33FF xor edi,edi 77F79B5F FF7424 20 push dword ptr ss:[esp+20] 77F79B63 FF7424 20 push dword ptr ss:[esp+20] 77F79B67 FF7424 20 push dword ptr ss:[esp+20] 77F79B6B FF7424 20 push dword ptr ss:[esp+20] 77F79B6F FF7424 20 push dword ptr ss:[esp+20] 77F79B73 E8 06000000 call ntdll.77F79B7E //// F4下,F7進入,來到代碼[4] 77F79B78 5F pop edi 77F79B79 5E pop esi 77F79B7A 5B pop ebx 77F79B7B C2 1400 retn 14 代碼[4] 77F79B7E 55 push ebp 77F79B7F 8BEC mov ebp,esp 77F79B81 FF75 0C push dword ptr ss:[ebp+C] 77F79B84 52 push edx 77F79B85 64:FF35 0000000>push dword ptr fs:[0] 77F79B8C 64:8925 0000000>mov dword ptr fs:[0],esp 77F79B93 FF75 14 push dword ptr ss:[ebp+14] 77F79B96 FF75 10 push dword ptr ss:[ebp+10] 77F79B99 FF75 0C push dword ptr ss:[ebp+C] 77F79B9C FF75 08 push dword ptr ss:[ebp+8] 77F79B9F 8B4D 18 mov ecx,dword ptr ss:[ebp+18] 77F79BA2 FFD1 call ecx //這就是異常處理回調函數! 77F79BA4 64:8B25 0000000>mov esp,dword ptr fs:[0] 77F79BAB 64:8F05 0000000>pop dword ptr fs:[0] 77F79BB2 8BE5 mov esp,ebp 77F79BB4 5D pop ebp 77F79BB5 C2 1400 retn 14 //返回後繼續跟,回到代碼[5]處 代碼[6] 77F75913 > B8 20000000 mov eax,20 77F75918 BA 0003FE7F mov edx,7FFE0300 77F7591D FFD2 call edx //f7,到代碼[8] 77F7591F C2 0800 retn 8 代碼[8] 7FFE0300 8BD4 mov edx,esp 7FFE0302 0F34 sysenter 7FFE0304 C3 retn //返回到 代碼[9] 代碼[9] 0040102F |. 68 00304000 push seh2.00403000 ; |Title = "SEH" 00401034 |. 68 04304000 push seh2.00403004 ; |Text = "Hello,SEH!" 00401039 |. 6A 00 push 0 ; |hOwner = NULL 0040103B |. E8 44000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 00401040 |. 64:8F05 00000>pop dword ptr fs:[0] 00401047 |. 83C4 04 add esp,4 0040104A |. 6A 00 push 0 ; /ExitCode = 0 0040104C \. E8 39000000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess //f7,進入,到代碼[10] 代碼[10]-----這段代碼,任何程序只要執行了exitprocess都會看到!留個印象吧! 77E598FD > 55 push ebp 77E598FE 8BEC mov ebp,esp 77E59900 6A FF push -1 77E59902 68 B0F3E877 push kernel32.77E8F3B0 77E59907 FF75 08 push dword ptr ss:[ebp+8] 77E5990A E8 86FFFFFF call kernel32.77E59895 // 結束了應用程序的生命! 77E5990F ^ E9 A47DFEFF jmp kernel32.TerminateProcess 77E59914 - FF25 F413E477 jmp dword ptr ds:[<&ntdll.LdrShutdownProcess>] ; ntdll.LdrShutdownProcess 77E5991A 391D A470EB77 cmp dword ptr ds:[77EB70A4],ebx 77E59920 0F84 99150000 je kernel32.77E5AEBF 77E59926 53 push ebx 77E59927 53 push ebx 77E59928 53 push ebx 77E59929 E8 D2F4FEFF call kernel32.WriteProfileStringW 77E5992E E9 8C150000 jmp kernel32.77E5AEBF 77E59933 > 837C24 04 00 cmp dword ptr ss:[esp+4],0 77E59938 0F84 C4730200 je kernel32.77E80D02 77E5993E FF7424 08 push dword ptr ss:[esp+8] 77E59942 FF7424 08 push dword ptr ss:[esp+8] 77E59946 FF15 6814E477 call dword ptr ds:[<&ntdll.NtTerminateThread>] ; ntdll.ZwTerminateThread 77E5994C 85C0 test eax,eax 77E5994E 0F8C B7730200 jl kernel32.77E80D0B 77E59954 33C0 xor eax,eax 77E59956 40 inc eax 77E59957 C2 0800 retn 8 **************************************************************************************************************附件:SEH.rar |
加密與解密二版菜鳥學習筆記(2) - SEH 結構化異常處理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.