SEH

说明

结构化异常处理(SEH)是Windows操作系统提供的强大异常处理功能。而Visual C++中的__try{}/\_finally{}和__try{}/__except{}结构本质上是对Windows提供的SEH的封装。

结构

线程信息块TIB

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;

Fs:[0]总是指向当前线程的TIB,其中0偏移的指向线程的异常链表,即ExceptionList是指向异常处理链表(EXCEPTION_REGISTRATION结构)的一个指针。

EXCEPTION_REGISTRATION结构

typedef struct _EXCEPTION_REGISTRATION_RECORD {
struct _EXCEPTION_REGISTRATION_RECORD *Prev; //指向前一个EXCEPTION_REGISTRATION的指针
PEXCEPTION_ROUTINE Handler; //当前异常处理回调函数的地址
} EXCEPTION_REGISTRATION_RECORD;

流程

代码

加入SEH的代码(没加SEH代码去掉try和except结构即可)

int main()
{
__try
{
char* str = NULL;
str[0] = 'a';
}

__except(1){
printf("!!!\n");
}

printf("HELLO SEH!\n");
getchar();
return 0;
}

没有SEH的反汇编

查看加入SEH代码后的反汇编

真正的代码在xref后面

可以通过od改eip的值绕过异常代码

反调试

可用于反调试,代码如下

#include <iostream>
#include <Windows.h>

EXCEPTION_DISPOSITION myExceptHandler( // enum type
struct _EXCEPTION_RECORD* ExceptionRecord, // 记录了一些异常信息
PVOID EstablisherFrame,
PCONTEXT pcontext, // 寄存器环境
PVOID DisspatcherContext
)
{
DWORD isDebugger = 0;
_asm{
mov eax,fs:[0x18] // teb
mov eax,[eax+0x30] // peb
movzx eax,byte ptr[eax+2] // 如果为1表示被调试
mov isDebugger,eax
}
if(isDebugger)
{
MessageBoxA(0,"Go out HACKERS!","WARNING",MB_OK);
exit(0);
}

MessageBoxA(0,"Exception Code Running","TIPS",MB_OK);
pcontext -> Eip += 1;
return ExceptionContinueExecution;
}

int main()
{

DWORD exceptionFunAddr = (DWORD)myExceptHandler;

_asm{
push exceptionFunAddr
mov eax,fs:[0]
push eax
mov fs:[0],esp
}

char* str = NULL;
str[0] = 'a';

printf("HELLO SEH!\n");
getchar();
return 0;
}

References

https://blog.csdn.net/xiaocaiju/article/details/25995495

https://www.cnblogs.com/Sna1lGo/p/14732048.html

https://www.cnblogs.com/yilang/p/11233935.html

http://www.cppblog.com/weiym/archive/2015/02/27/209884.html

文章作者: Alex
文章链接: http://example.com/2021/05/10/SEH/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Alex's blog~