-
-
SEH简单笔记
-
发表于:
2011-12-21 17:09
6878
-
回头看了下,大致做了下笔记,正好出了一个新手版块,就发这里了,看的时候尚需抱怀疑态度
■结构化异常处理SEH
TIB线程信息块 TEB线程环境块 ╭─-→ PEB进程环境块
+00h[ ExceptionList ]←╮ +00h[ NtTib ]{TIB} │ +00h[ InheritedAddressSpace ]
+04h[ StackBase ] │ +1Ch[ EnvironmentPointer ] │ +01h[ReadImageFileExecOpions]
+08h[ StackLimit ] │ +20h[ ClienId ] │ +02h[ BeingDebugged ]
+0ch[ SubSystemTib ] │ [ ... ] │ [ ... ]
+10h[ u.FiberData ] │ [ ... ] │ [ ... ]
[ u.Version ] │ +30h[ProcessEnvironmentBlock*]────╯ +68h[ NtGlobalFlag ]
+14h[ArbitraryUserPointer] │ [ ... ] +70h[CriticalSectionTimeOut ]
+18h[ Self ]─╯ +fb5h[ BooleanSpare ] +78h[ HeapSegmentReserve ]
EXCEPTION_REGISTRATION ╭→EXCEPTION_REGISTRATION ╭→... ╭→EXCEPTION_REGISTRATION
FS:[0]→[ prev ]────╯ [ prev ]────╯ ────╯ [FFFFFFFh]
[handler1] [handler2] [handler3]
╭─→ EXCEPTION_RECORD
│ [ ExceptionCode ] //switch
│ [ ExceptionFlags ]
│ [ EXCEPTION_RECORD* ]
│ [ ExceptionAddress ]
│ [ NumberParameters ]
EXCEPTION_POINTERS │ [ExceptionInformation[]] //[0]为0则读,为1则写 [1]触发地址
[pEXCEPTION_RECORD]──╯
[ pCONTEXT ]────→ CONTEXT
+00h[ ContextFlags ]══════╣CONTEXT_i386
+04h[ Dr0 ]① ║CONTEXT_i486
+08h[ Dr1 ]│ ║CONTEXT_DEBUG_REGISTERS①
+0Ch[ Dr2 ]│ ║CONTEXT_FLOATING_POINT②
+10h[ Dr3 ]│ ║CONTEXT_SEGMENTS③
+14h[ Dr6 ]│ ║CONTEXT_INTEGER④
+18h[ Dr7 ]① ║CONTEXT_CONTROL⑤
+1C~+88h[ FloatSave ]② ║CONTEXT_EXTENDED_REGISTERS⑥
+8Ch[ SegGs ]③ ║CONTEXT_FULL③~⑤
+90h[ SegFs ]│ ║CONTEXT_ALL①~⑥
+94h[ SegEs ]│
+98h[ SegDs ]③
+9Ch[ Edi ]④
+A0h[ Esi ]│
+A4h[ Ebx ]│
+A8h[ Edx ]│
+ACh[ Ecx ]│
+B0h[ Eax ]④
+B4h[ Ebp ]⑤
+B8h[ Eip ]│
+BCh[ SegCs ]│
+C0h[ EFlags ]│
+C4h[ Esp ]│
+C8h[ SegSs ]⑤
+CCh[ExtendedRegisters[]]⑥
1个线程对应1个TEB结构;FS:[0]指向当前线程的TEB结构(即TIB.ExceptionList)
程序构造ERR(常用原FS[0]的prev)并使FS:[0]指向;FS:[4]即handler(常异常前现于栈)尽早设断
异常后步入系统(F7或Shift+F7),栈顶为EXCEPTION_POINTERS,故D [esp+4]+0b8为CONTEXT.Eip
㈠若被调试则系统填写EXCEPTION_DEBUG_INFO(其dwFirstChance=1)并通知调试器
㈡若未处理则经过线程ERR或ERR链;回调ERR.handler内常修改CONTEXT.Eip且清零CONTEXT.DrX;返回后将进系统再至新eip
㈢若被调试则系统填写EXCEPTION_DEBUG_INFO(其dwFirstChance=0)并通知调试器
㈣若未处理且程序SetUnhandledExceptionFilter且未被调试则转至进程filter
㈤若未处理则系统弹框让选直接终止或附加调试器
㈥直接终止或附加失败或未处理都将再过线程ERR链并终止
■调试器
DEBUG_EVENT
[ dwDebugEventCode ]-╮
[ dwProcessId ] ↓
[ dwThreadId ]
EXCEPTION_DEBUG_INFO [u.Exception ]//执行首指令前(EXCEPTION_DEBUG_EVENT): switch(.ExceptionRecord.ExceptionCode)
CREATE_THREAD_DEBUG_INFO [u.CreateThread ]//创建支线程或被捆绑(CREATE_THREAD_DEBUG_EVENT)时用此
CREATE_PROCESS_DEBUG_INFO [u.CreateProcessInfo]//进程刚被创建或捆绑(CREATE_PROCESS_DEBUG_EVENT)时用此
EXIT_THREAD_DEBUG_INFO [u.ExitThread ]//支线程退出(EXIT_THREAD_DEBUG_EVENT)时用此
EXIT_PROCESS_DEBUG_INFO [u.ExitProcess ]//进程退出(EXIT_PROCESS_DEBUG_EVENT)时用此
LOAD_DLL_DEBUG_INFO [u.LoadDll ]//加载动态链接库(LOAD_DLL_DEBUG_EVENT)时用此
UNLOAD_DLL_DEBUG_INFO [u.UnloadDll ]//卸载动态链接库(UNLOAD_DLL_DEBUG_EVENT)时用此
OUTPUT_DEBUG_STRING_INFO [u.DebugString ]//向调试器发消息字符串(OUTPUT_DEBUG_STRING_EVENT)时用此
RIP_INFO [u.RipInfo ]//系统调试出错(RIP_EVENT)时用此
EXCEPTION_DEBUG_INFO CREATE_PROCESS_DEBUG_INFO LOAD_DLL_DEBUG_INFO UNLOAD_DLL_DEBUG_INFO
[ExceptionRecord] [ hFile ]o [ hFile ]o [lpBaseOfDll]
[ dwFirstChance ] [ hProcess ] [ lpBaseOfDll ]
[ hThread ] [dwDebugInfoFileOffset]
[ lpBaseOfImage ] [ nDebugInfoSize ]
[dwDebugInfoFileOffset] [ lpImageName ]x
[ nDebugInfoSize ] [ fUnicode ]
[ lpThreadLocalBase ]
[ lpStartAddress ]
[ lpImageName ]x
[ fUnicode ]
CREATE_THREAD_DEBUG_INFO EXIT_THREAD_DEBUG_INFO OUTPUT_DEBUG_STRING_INFO EXIT_PROCESS_DEBUG_INFO
[ hThread ] [dwExitCode] [lpDebugStringData ] [dwExitCode]
[lpThreadLocalBase] [ fUnicode ]
[ lpStartAddress ] [nDebugStringLength]
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!