SEH Code Execute
SEH简介
SEH(Structured Exception Handling)结构化异常处理,是windows操作系统默认的错误处理机制,它允许我们在程序产所错误时使用特定的异常处理函数处理这个异常,尽管提供的功能预取为处理异常,但由于其功能的特点,也往往大量用于反调试。
讲原理的话还挺复杂的,用户层异常涉及到多次换栈cpu层级切换,这里不做简介,有兴趣的可以参考段钢老师的《加密与解密》。
SEH默认存储在栈中,以链表的形式保存其结构如下。
typedef struct _Exception_SEH_List{
PException_SEH *next; //*next指针指向下一个节点,
PException_DISPOSITION handle; //handle指向一个异常处理函数。
}_Exception_SEH_List,*_Exception_SEH_List;
当异常产生时操作系统会接管并会按照(A)->(B)->(C)的顺序依次传递,直到异常处理完毕。
异常处理函数通常也遵循约定的编写格式,由于异常处理函数是一个回调函数,所以第一参数是由操作系统传递的一个指向EXCEPTION_RECORD结构体的指针。
CONTEXT保存CPU处理异常前的状态,用于处理后的恢复。

常见的异常:
异常发生的时候,执行异常代码的线程就会发生中断,转而运行SEH,此时操作系统会把线程 CONTEXT结构体的指针传递给异常处理函数的相应参数。由于这个处理函数可以由我们自定义,所以我们可以利用操作系统来帮我执行shellcode,同时由于seh的特殊性,调试器默认会接管异常而不使用seh,所以我们通常会利用seh进行一些反调试。
结构化异常基于线程,每个单独的线程都有自己的seh链,我们可以在TEB.NtTib.ExceptionList找到seh的链表头,而TEB可以在FS:[00]寄存器位置找到,NTTIB和ExceptionList分别处于各自结构体第一个成员,所以FS:[00]=TEB.NtTib.ExceptionList。


SEH实现
原始实现:
编译器封装:
SEH利用
如果有调试器并接管异常,那么程序会在发生除零异常的位置停滞,而没有调试器程序则会处理这个异常并执行shellcode。

或:

LINKS
最后更新于
这有帮助吗?