说明
结构化异常处理(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; 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( struct _EXCEPTION_RECORD* ExceptionRecord, PVOID EstablisherFrame, PCONTEXT pcontext, PVOID DisspatcherContext ) { DWORD isDebugger = 0; _asm{ mov eax,fs:[0x18] mov eax,[eax+0x30] movzx eax,byte ptr[eax+2] 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