SEH相关数据结构

TEB结构

          TEB(Thread Environment Block,线程环境块)在Windows9X系列中称为TIB(Thread Information Block,线程信息块),它记录着线程的重要信息。每一个线程对应一个TEB结构,在Windows2000 DDK中定义为:

typedef struct _NT_TIB {
    struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
    PVOID StackBase;
    PVOID StackLimit;
    PVOID SubSystemTib;
    union {
        PVOID FiberData;
        DWORD Version;
    };
    PVOID ArbitraryUserPointer;
    struct _NT_TIB *Self;
} NT_TIB;

         与异常处理相关的项是指向_EXCEPTION_REGISTRATION_RECORD 结构的指针*ExceptionList,正好位于TEB的偏移0处。Windows在创建线程时,操作系统均会为每个线程分配TEB,而且都将FS段选择器指向当前线程的TEB数据,即TEB总是由[FS:0]指向的。

        下面所说的_EXCEPTION_REGISTRATION_RECORD 结构就是前面的异常处理的基本过程中链起来的异常处理线程基础。

EXCEPTION_REGISTRATION结构

     我能找到正式定义 EXCEPTION_REGISTRATION 结构的唯一地方是 EXSUP.INC 文件,该文件来自 Visual C++ 运行库的源:

_EXCEPTION_REGISTRATION struc
	prev dd ?		;指向前一个EXCEPTION_REGISTRATION结构的指针
	handler dd ?		;当前异常处理回调函数的地址
_EXCEPTION_REGISTRATION ends

  你还将看到该结构在 WINNT.H 文件中定义的 NT_TIB 结构中被引用为 _EXCEPTION_REGISTRATION_RECORD。唉,除此之外,没有什么地方能找到 _EXCEPTION_REGISTRATION_RECORD 的定义,所以我只能使用 EXSUP.INC 文件中定义的汇编语言结构。

         其中,prev是指向前一个EXCEPTION_REGISTRATION(简称ERR)的指针,形成一个链状结构;handler指向异常处理代码,当系统遇到一个它不知道如何处理的异常时,它就查找异常处理链表。每个线程都有它自己的异常处理链表。

00401000 >  8D4424 F8       lea eax,dword ptr ss:[esp-0x8]    ;分配8个字节来存放ERR结构,并把地址存放到eax中
00401004    64:8705 0000000>xchg dword ptr fs:[0],eax         ;eax和fs:[0]交换位置,现在的eax指向一开始fs:[0]的ERR结构;fs:[0]指向现在构造的ERR结构
0040100B    BB 2E104000     mov ebx,Seh.0040102E
00401010    53              push ebx                          ;handler
00401011    50              push eax                          ;prev
00401012    BE 00000000     mov esi,0x0
00401017    8B06            mov eax,dword ptr ds:[esi]        ;当这里读取异常的时候,将交给系统异常处理,处理完毕后,调回到handler执行
00401019    6A 00           push 0x0
0040101B    68 00304000     push Seh.00403000                        ; ASCII "OK"
00401020    68 10304000     push Seh.00403010                        ; ASCII "SEH Fail"
00401025    6A 00           push 0x0
00401027    E8 1C000000     call <jmp.&USER32.MessageBoxA>
0040102C    EB 13           jmp short Seh.00401041
0040102E    6A 00           push 0x0
00401030    68 00304000     push Seh.00403000                        ; ASCII "OK"
00401035    68 03304000     push Seh.00403003                        ; ASCII "SEH Succeed "
0040103A    6A 00           push 0x0
0040103C    E8 07000000     call <jmp.&USER32.MessageBoxA>
00401041    6A 00           push 0x0
00401043    E8 06000000     call <jmp.&KERNEL32.ExitProcess>
00401048  - FF25 08204000   jmp dword ptr ds:[<&USER32.MessageBoxA>] ; user32.MessageBoxA
0040104E  - FF25 00204000   jmp dword ptr ds:[<&KERNEL32.ExitProcess>; kernel32.ExitProcess


            当堆栈刚出现这个的时候,就要注意handler的地址,因为程序即将跳到handler的地址执行。分析的时候需提前下断。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值