SEH 结构化异常处理(2)
2007-01-14 16:44:41 来源:WEB开发网核心提示:看堆栈:0012FCCC0012FCD4//指针,指向EXCEPTION_RECORD结构,即EXCEPTION_RECORD的首地址-这就是EXCEPTION_POINTERS0012FCD00012FCF0//指针,指向EXCEPTION_CONTEXT结构,即EXCEPTION_CONTEXT的首地址---001
看堆栈:
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 movebx,dwordptrss:[esp]
77FB4DB6 51 pushecx
77FB4DB7 53 pushebx
77FB4DB8 E8ACBDFAFF callntdll.77F60B69//f7
77FB4DBD 0AC0 oral,al
77FB4DBF 740C jeshortntdll.77FB4DCD
77FB4DC1 5B popebx
77FB4DC2 59 popecx
77FB4DC3 6A00 push0
77FB4DC5 51 pushecx
77FB4DC6 E8480BFCFF callntdll.ZwContinue
77FB4DCB EB0B jmpshortntdll.77FB4DD8
77FB4DCD 5B popebx
77FB4DCE 59 popecx
77FB4DCF 6A00 push0
77FB4DD1 51 pushecx
77FB4DD2 53 pushebx
77FB4DD3 E8F213FCFF callntdll.ZwRaiseException
77FB4DD8 83C4EC addesp,-14
77FB4DDB 890424 movdwordptrss:[esp],eax
77FB4DDE C744240401000>movdwordptrss:[esp+4],1
77FB4DE6 895C2408 movdwordptrss:[esp+8],ebx
77FB4DEA C744241000000>movdwordptrss:[esp+10],0
77FB4DF2 54 pushesp
77FB4DF3 E8AFC2F9FF callntdll.RtlRaiseException
77FB4DF8 C20800 retn8
77FB4DFB>^E97DBCFAFF jmpntdll.77F60A7D
77F79B7E 55 pushebp
77F79B7F 8BEC movebp,esp
77F79B81 FF750C pushdwordptrss:[ebp+C]
77F79B84 52 pushedx
77F79B85 64:FF350000000>pushdwordptrfs:[0]
77F79B8C 64:89250000000>movdwordptrfs:[0],esp
77F79B93 FF7514 pushdwordptrss:[ebp+14]//参数4 _lpDispatchrContext?
77F79B96 FF7510 pushdwordptrss:[ebp+10]//参数3 _lpDContext,指向Context结构
77F79B99 FF750C pushdwordptrss:[ebp+C] //参数2 _lpSEH,指向ERR结构
77F79B9C FF7508 pushdwordptrss:[ebp+8] //参数1 _lpExceptionRecord,指向ExceptionRecord结构
77F79B9F 8B4D18 movecx,dwordptrss:[ebp+18]
77F79BA2 FFD1 callecx ;seh2.00401051转到这里了f7
//这就是异常处理回调函数,执行当前异常处理代码即401051处
//注:回调函数都是由windows调用的!
//看学强调:在此回调函数上设断点,可以轻易地对付一些加壳的反跟踪代码!!!!!
77F79BA4 64:8B250000000>movesp,dwordptrfs:[0]//恢复原来的SEH链表
77F79BAB 64:8F050000000>popdwordptrfs:[0]
77F79BB2 8BE5 movesp,ebp
77F79BB4 5D popebp
77F79BB5 C21400 retn14
00401051 /$ 55 pushebp ; Structuredexceptionhandler
00401052 |. 8BEC movebp,esp
00401054 |. 53 pushebx
00401055 |. 8B4510 moveax,dwordptrss:[ebp+10]//eax是CONTEXT结构的指针
00401058 |. 8D1D2D104000leaebx,dwordptrds:[40102D]//通过修改CONTEXT.EIP,希望到这里执行!
0040105E |. 8998B8000000movdwordptrds:[eax+B8],ebx//修改CONTEXT.EIP,改变程序执行线路,这大概就是利用seh的常用手法!
//没改时,是401018即发生异常的指令地址,经过1轮处理又会到这里执行
//又产生异常
00401064 |. 33DB xorebx,ebx
00401066 |. 895804 movdwordptrds:[eax+4],ebx//DR0清零,使断点失效,这大概也是利用seh的常用手法,实现反跟踪!
00401069 |. 895808 movdwordptrds:[eax+8],ebx//DR1
0040106C |. 89580C movdwordptrds:[eax+C],ebx//DR2
0040106F |. 895810 movdwordptrds:[eax+10],ebx//DR3
00401072 |. C7401855010>movdwordptrds:[eax+18],155//DR7
00401079 |. B800000000 moveax,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 popebx
0040107F |. C9 leave
00401080 . C21000 retn10
[总结]
//看学强调:在此回调函数上设断点,可以轻易地对付一些加壳的反跟踪代码!!!!!
//看学强调:要提前在err结构的handler地址上设断点,否则代码就可能跑飞跟踪seh的关键断点!!!!
//看学提示:可修改CONTEXT结构成员,来实现反跟踪及改变程序流程(设置暗桩吗?)
**************************************************************************
[附录]跟踪到异常处理回调函数的过程:
更多精彩
赞助商链接