|
标 题:
【原创】加密与解密二版菜鸟学习笔记(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 |
相关推荐
中断和异常
最近在看内存方面的知识,打算写一系列的博客分享记录一下。 本文介绍任务管理器里各个内存项的含义以及用一个例子也解释独占性。 目录 内存项含义 1.工作集Working Set(内存)=内存(专用工作集)+ 内存(共享工作集) 2.提交大小 Comitted Memory 内存的独占性 内存项含义 打开任务管理--详细信息---右键选择列,选择下面这4个。 1....
Windows的结构化异常处理
我们知道,异常就像中断,不管是什么原因(“软异常”除外)所引起,一旦发生首先进入的是内核中的异常响应/ 处理程序的入口,这就是类似于KiTrap0()那样的底层内核函数,只是因为引起异常的原因不同而进入不同的入口,就像对于不同的中断向量有不同的入口 一样。在内核中,仍以页面异常为例,正如读者已经看到,CPU会从KiTrap14()进入函数KiPageFaultHandler()。在那儿,如果 所发
易语言SEH异常捕获模块.e
支持易语言程序代码自设SEH捕获异常
【加密与解密(第四版)】第八章笔记
SEH(结构化异常处理)是 Windows 操作系统用于自身除错的一种机制,也是开发人员处理程序错误或异常的强有力的武器。从程序设计的角度来说,就是系统在终结程序之前给程序提供的一个执行其预先设定的回调函数的机会。IDT(中断描述符表)是硬件和操作系统交接中断和异常的关口,IDT是一张位于物理内存中的线性表,共有256项。IDTR寄存器共有48位,其中高32位是表的基址,低 16 位是表的长度。IDT的每一项都是一个门结构,它是发生中断或异常时 CPU转移控制权的必经之路,包括如下3 种门描述符。
易语言SEH异常处理源码.rar
易语言SEH异常处理源码.rar
易语言SEH异常处理源码
易语言SEH异常处理源码。@易语言资源网站。
易语言关于SEH异常处理
敏感肌能用吗
阿里巴巴-AI Agent工程师面试题精选:10道高频考题+答案解析(附PDF)
阿里巴巴AIAgent技术面试要点摘要(149字) 阿里巴巴在AIAgent领域布局完整,面试重点考察系统架构、幻觉治理、成本优化等核心能力。候选人需掌握分层架构设计、多Agent协作死锁处理、Token成本优化策略等关键技术。面试强调工程落地能力,包括工具调用容错、记忆系统设计、安全防护等实践要点。评估体系需覆盖效果、效率、成本多维度指标。未来趋势关注垂直领域专业化、多模态融合等方向。建议准备实际项目案例,突出技术深度与业务价值的结合,展现系统思维和工程能力。
WINDOWS+PE权威指南读书笔记(16)
加载配置信息 何谓加载配置信息: Windows 结构化异常处理: 什么是SEH: Windows 异常分类: 内核模式下的异常处理: 用户模式下的异常处理: Windows SEH 机制解析: SEH 编程实例: PE 中的加载配置信息: 加载配置信息定位: 加载配置目录 IMAGE_LOAD_CONFIG_DIRECTORY: 加载配置信息实例分析: 加载配置编程: 程序源代码分析: 为 PE 添加加载配置信息: 运行测试: 注册多个异常处理函数示例: 小
论文超详细精读|万字:2s-AGCN
1. 提出了一种新的双流自适应图卷积网络(2S-AGCN)用于基于骨架的动作识别。**模型中的图的拓扑既可以统一地学习,也可以通过BP算法以端到端的方式单独学习。** 2. 提出了一种同时对**一阶和二阶信息(骨架的长度与方向)建模的双流框架**,在识别精度上有了显著的提高。 它将骨架数据的图结构参数化,并嵌入到网络中,与模型共同学习和更新。 3. 文章主要创新点有两个,一个是双流网络,另外一个是自适应。
博途 V15.1安装步骤
温馨提醒:安装此软件电脑配置至少应满足以下要求 处理器 CoreTM i5-3320M 3.3 GHz 或相当 内存 至少8G 硬盘 300 GB SSD 显示器 15.6' 宽屏显示 (1920 x 1080) 1.双击打开【Siemens v15.1】文件夹。 2.鼠标右击【STEP 7 BasicProfess...
脱壳基础知识入门和提高-----第二课 SEH技术
结构化异常处理(Structured Exception Handling,SEH)是Windows操作系统处理程序错误或异常的技术。SEH是Windows操作系统的一种系统机制,与特定的程序设计语言无关。 外壳程序里大量地使用了SEH,如果不了解SEH,将会使你跟踪十分困难。 SEH in ASM 研究(一)by hume SEH in ASM 研究(二)by hume S
ABAQUS二次开发中创建SET
在ABAQUS中创建加载、边界条件时,需要使用set,创建set时需要使用对象集合对象中的Set函数,这个函数需要提供加入对象集合的列表,但这个对象列表好像并不能自行创建,只能通过ABAQUS各类对象集合中的findAt、getSequenceFromMask、getByBoundingSphere、getByBoundingCylinder或getByBoundingSphere函数得到,但这几个函数在直接使用PYTHON编程时都不太好用。这个函数返回一个字典,如下所示。
自修改代码(SMC)技术学习
<<加密与解密>>第14章的SMC(Self-Modifying Code)技术实现很有意思,这节的练习例子将SMC技术与其它一些反跟踪技术结合起来,有一种海陆空联合作战的赶脚:单步跟踪,软断点,硬件断点都要中作者的陷阱,从而不是跑飞就是掉进系统DLL领空迷失,无法正确跟踪到后面的源代码,更别说分析了. 作者太高估咱们(异或是唯独自己太蠢?)的水平,书上和例子代...
「Unity3D」Addressable版本冲突解析:SBP与Addressables兼容性问题实战指南
本文深入解析Unity3D中Addressable与SBP(Scriptable Build Pipeline)版本冲突问题,提供实战解决方案。当遇到「Build Task CreateBuiltInShadersBundle failed」错误时,可通过版本匹配、临时资源引用或构建参数调整解决。文章详细分析兼容性原理,并给出版本组合指南与最佳实践,帮助开发者高效处理资源构建问题。
Pytorch CIFAR10图像分类 EfficientNet v1篇
EfficientNet源自Google Brain的论文EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks. 从标题也可以看出,这篇论文最主要的创新点是. 论文提出了,混合缩放,把网络缩放的三种方式:深度、宽度、分辨率,组合起来按照一定规则缩放,从而提高网络的效果。EfficientNet在网络变大时效果提升明显,把精度上限进一步提升,成为了当前最强网络。
脱壳基础知识入门
现在加解密发展己形成2个分支了,一个就是传统的算法,另一个就是加密壳。越来越多的软件采用了密码学相关算法,现在要做出一个软件注册机己不象前几年那么容易,这就要求解密者必须要有一定的数学功底和密码学知识,而这些在短时间内是不容易掌握的。除了密码学的应用,越来越多的软件加壳了,因此要求解密者必须掌握一些脱壳技术,这就使得壳成了解密必须迈过的一个门槛。壳发展到今天,强度越来越高了,将许多人挡在门外,使得
【ArcGIS Pro微课1000例】0073:ArcGIS Pro3.5.2学习版下载及安装教程
ArcGIS Pro 3.5.2安装教程摘要:系统需Windows10及以上,8GB内存(推荐32GB)。安装步骤:1)安装.NET 8.0运行环境;2)执行主程序安装包,按向导完成基础安装;3)安装升级补丁;4)替换AfCore.dll文件并导入注册表。注意安装后删除临时文件节省空间。软件下载地址包含在百度网盘链接。安装过程需依次完成环境配置、主程序安装、补丁更新及破解步骤。
逆向工程入门:从黑盒到白盒的系统分析方法与实践指南
逆向工程是一套系统性的分析方法,其核心目标是通过拆解已完成的软件或硬件,理解其工作原理与设计逻辑。从技术原理上看,它主要涉及对二进制可执行文件的分析,将机器码转换为可读的汇编语言或高级语言伪代码,从而洞察程序内部的数据结构与算法实现。这项技术的核心价值在于深刻理解系统底层机制,是学习优秀代码实践、分析算法实现和排查复杂系统问题的有效途径。在应用场景上,逆向工程广泛应用于软件安全分析、漏洞挖掘、恶意代码分析、兼容性研究以及关键技术学习等领域。本文聚焦于逆向工程的基础方法论,详细阐述了静态分析与动态分析两大核心
WPF数据绑定Binding对数据的转换与效验(四)
Binding的作用就是架在Source与Target之间的桥梁,数据可以在这座桥梁的帮助下来流通。就像现实世界中的桥梁会设置一些关卡进行安检一样,Binding这座桥上也可以设置关卡对数据的有效性进行检验,不仅如此,当Binding的两端要求使用不同的数据类型时,我们还可以为数据设置转换器。Binding用于数据有效性检验的关卡是它的ValidationRules属性,用于数据类型转换的关卡是它的Converter属性。
Probability and Statistics - 4th edition
Probability and Statistics - 4th edition
漫谈兼容内核之二十六:Windows的结构化异常处理(三)
用户空间的异常机制是对于系统空间的异常机制的模拟。在内核中,并非所有的异常都是一来就进入“基于SEH框架(Frame-Based)”的异常处理, 而是先进入_KiTrap14()等等类似于向量中断的入口,在那里可以被拦截进行一些优先的处理,例如页面换入和对Copy-On-Write页面的处 理等等。这些处理是全局性质的,而不属于某个SEH域。这相当于是一层全局性的过滤。只有不属于这个层次的异常
Statistics and Machine Learning Toolbox
Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具
逆向破解学习二之<TraceMe>
这次在破解TraceMe的时候,我有看过别人的视频。但是我并没有按照别人思路走,而是完全安全自己的思路试了一次。结果破解成功。新手学破解,如果有不对的地方,还请指出来。 004013A0 crackmes.<ModuleEntryPoint> /$ 55 push ebp ; E...
LinePhone3.2.7(android端最新版本) sip客户端
SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/
STM32F407中文手册
STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。
3531



被折叠的 条评论
为什么被折叠?



