SEH查看相关

简单的写(搬运)一下SEH相关。

结构化异常处理,按照我的理解,是一连串由单链表串起来在栈中分配的,这就有了利用SEH完成溢出的可能。

异常处理链的头指针保存在TEB(线程环境块)的起始位置,所以想添加一个新的异常处理程序的话,新的结点应该添加到异常处理链的头部,同时TEB中保存的指针也应该指向这个新的结点.

异常处理链中结点的类型都是_EXCEPTION_REGISTRATION_RECORD,结点中保存了异常处理函数的地址和指向下一个结点的指针.奇怪的是,最后一个结点的指向下一个结点的指针并不为空,而是0xffffffff.该结构定义如下:

使用WinDgb查看_EXCEPTION_REGISTRATION_RECORD

发现一个由Header 和Next构成 其中Header占用4个字节。

X86汇编语言如下

1
2
3
4
5
6
7
8
9
10
11
mov eax,dword ptr fs:[00000000h] ;获取异常处理链的头结点指针
push eax ;保存异常处理链旧的头结点指针
lea eax,[ebp-10h]
mov dword ptr fs:[00000000h],eax ;设置新的头结点指针
mov ecx,dword ptr [ebp-10h] ;获取旧的头结点指针(当前头结点的NEXT域)
mov dword ptr fs:[00000000h],ecx ;恢复旧的头结点指针

编译器通常会注册一个全局的句柄,通过这个全局句柄可以得知程序的那些区域被执行了,并且可以相应的处理.

每一个线程的TEB都不相同,操作系统会确保段选择子fs一直都指向TEB的.可以通过fs:[18h]来获取TEB的地址,这里面保存着TEB的自指针(PS:指向自己的指针).

一定要记得fs是一直指向的,可以通过查看fs来验证。

除此之外,还可以通过?poi(fs:[18h])

来验证

查看整个_EXCEPTION_REGISTRATION_RECORD结构,可以再用

!slist命令来看

文章目录