SEH中的prolog和epilog
来源:互联网 发布:android开源项目源码 编辑:程序博客网 时间:2024/05/29 12:15
使用SEH的代码都需要构建栈桢,支持exception处理的栈桢,而重复的代码就应当提炼成函数,微软自然不会例外。为此系统提供了prolog和epilog系列,类似的函数有不少版本,但大同小异。这次不用调试器,分析下__SEH_prolog4_GS和__SEH_epilog4_GS 2个函数,看看它们如何工作支持异常的栈桢结构。
先看看prolog,这是内核函数KiDispatchException调用__SEH_prolog4_GS的代码,
000 push 0F8h
004 push offset off_8488DCE0
008 call __SEH_prolog4_GS
调用函数前传递2个参数,一个是需要保留的栈的大小,一个是指针。
再看看函数代码本身,详细的注释在代码后面,
; two instrucitons before call it.
;
; take KiDispatchException as example,
;
; 000 push 0F8h ; it's used as a stack size
; 004 push offset off_8488DCE0 ; it's pointer to scope table entry.
__SEH_prolog4_GS proc near
arg_4= dword ptr 8
000 push offset __except_handler4
004 push large dword ptr fs:0
008 mov eax, [esp+8+arg_4] ; so now there are 5 values in stack.
;
; f8
; 8488dce0
; return address of call
; _except_handler4
; old fs:0
; ; follwing is additional information
; to be pointer to EXCEPTION_POINTERS
; to be esp value
; to be cookie value
008 mov [esp+8+arg_4], ebp ; push current ebp value into place
; where 0f8 is here.
008 lea ebp, [esp+8+arg_4] ; update ebp to current frame pointer
008 sub esp, eax ; reserve stack
008 push ebx
00C push esi
010 push edi
014 mov eax, ___security_cookie
014 xor [ebp-4], eax ; encrypt pointer to scope table entry
014 xor eax, ebp
014 mov [ebp-1Ch], eax ; store cookie value
014 push eax
018 mov [ebp-18h], esp ; store current esp
; middle part
018 push dword ptr [ebp-8] ; push "return address" of current call
; for next ret instruction
01C mov eax, [ebp-4] ; mov [ebp-4] to [ebp-8]
01C mov dword ptr [ebp-4], 0FFFFFFFEh ; initialize try level
01C mov [ebp-8], eax ; so far, the stack is following:
;
; ebp
; -2
; 8488DCE0 xor ___security_cookie
; _except_handler4
; old fs:[0]
; to be pointer to EXCEPTION_POINTERS
; current esp value
; cookie value (___security_cookie xor ebp)
; ...
; ebx
; esi
; edi
; cookie value
; return address to parent function
01C lea eax, [ebp-10h]
01C mov large fs:0, eax ; update fs:[0] to current frame
01C retn ; return to parent function.
由于注释比较详细,就不多说什么了,补充几张图。
函数开始执行2条push指令后的栈,
执行到中间处的栈如下,注意数字顺序。
执行到最后retn之前的栈,此时(ebp-10)处已经构建好了异常栈桢结构,(ebp-18)(ebp-1c)处也赋了相应的值。
接下来分析epilog,先看看KiDispatchException如何调用它的,
; why is there 118?
11C lea esp, [ebp-118h] ; sizeof exception_frame + F8(includes additional information) + sizeof( ebx + esi + edi + cookie )
; ebp - (10+F8+10)
000 call __SEH_epilog4_GS
000 retn 14h
将栈指针修正到合适的位置,实际上就是__SEH_prolog4_GS函数返回后的栈的位置。然后调用函数__SEH_epilog4_GS,注意call指令会将返回地址压栈。
再看看函数的实现部分,
__SEH_epilog4_GS proc near
000 mov ecx, [ebp-1Ch] ; cookie value (___security_cookie xor ebp)
000 xor ecx, ebp
000 call @__security_check_cookie@4 ;
; cmp ecx, ___security_cookie
; jnz ___report_gsfailure
; retn
000 jmp __SEH_epilog4
__SEH_epilog4_GS endp
检查cookie有没有被破坏,如果没有问题就跳转到__SEH_epilog4。
__SEH_epilog4 proc near
000 mov ecx, [ebp-10h] ; restore old fs:[0]
000 mov large fs:0, ecx
000 pop ecx ; return address of parent function
-04 pop edi ; another cookie value besides [ebp-1c]
-08 pop edi
-0C pop esi
-10 pop ebx
-14 mov esp, ebp ; restore esp and ebp
000 pop ebp
-04 push ecx
000 retn
__SEH_epilog4 endp
这个函数比prolog简单的多了,恢复fs:[0],恢复寄存器,返回到调用__SEH_epilog4_GS的地方。
对这2个函数的分析最终演变成了对栈中数据结构的理解,这也让我想起了<人月神话>中的一句话。"给我看你的流程图,而藏起你的表,我仍然莫名其妙,给我看你的表藏起流程图,它们是如此的明显。 "这里的“表”指的就是数据结构,它最终决定了代码的实现。
- SEH中的prolog和epilog
- SEH中的prolog和epilog
- prolog中的树操作
- SEH 中的 __except
- MiniDump 和SEH
- 浅谈SEH和UEF
- Prolog中的表处理谓词
- prolog
- Prolog
- prolog
- Prolog
- SEH在驱动中的应用
- 用Prolog和Turbo Prolog语言开发专家系统
- SEH
- SEH
- seh
- seh
- SEH链和展开操作
- 动态实例变量:解决脆弱的基类问题
- 关于Uboot的USB下载功能
- Java的MD5加密和解密类
- MFC 拷贝ListBox单行的数据到剪切板
- PDU编码规则
- SEH中的prolog和epilog
- 数据结构之线性表——倒数第k个结点
- 30分钟理解关键链--《突破项目的瓶颈--关键链 》读书笔记
- 一个经典的iptables的shell脚本
- 关于JAVA字符串对象数组的循环次数问题
- 自己总结的sql基本操作
- Windows线程简单封装
- KNOW: Sort & Search
- Lucas 定理 模板