TIB(线程信息块)
代码语言:javascript复制0:000> dt ntdll!_TEB
0x000 NtTib : _NT_TIB
代码语言:javascript复制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;
typedef NT_TIB *PNT_TIB;
ExceptionList,正好位于TEB的偏移0处,总是由[FS:0]指向的,这个结构是用来注册我们的_except_handler()即:异常处理程序
代码语言:javascript复制EXCEPTION_DISPOSITION __cdecl _except_handler (
_In_ struct _EXCEPTION_RECORD *_ExceptionRecord,
_In_ void * _EstablisherFrame,
_Inout_ struct _CONTEXT *_ContextRecord,
_Inout_ void * _DispatcherContext
);
_EXCEPTION_REGISTRATION_RECORD的结构如下:
代码语言:javascript复制typedef
EXCEPTION_DISPOSITION
(*PEXCEPTION_ROUTINE) (
IN struct _EXCEPTION_RECORD *ExceptionRecord,
IN PVOID EstablisherFrame,
IN OUT struct _CONTEXT *ContextRecord,
IN OUT PVOID DispatcherContext
);
typedef struct _EXCEPTION_REGISTRATION_RECORD {
struct _EXCEPTION_REGISTRATION_RECORD *Next;// 下一个,从而形成链
PEXCEPTION_ROUTINE Handler;
} EXCEPTION_REGISTRATION_RECORD;
PEXCEPTION_ROUTINE指向的就是一个_except_handler.
构建及调用SEH链的代码如下:
代码语言:javascript复制EXCEPTION_DISPOSITION HGYSEH(
IN struct _EXCEPTION_RECORD *ExceptionRecord,
IN PVOID EstablisherFrame,
IN OUT struct _CONTEXT *ContextRecord,
IN OUT PVOID DispatcherContext
)
{
return ExceptionContinueSearch;
}
int _tmain(int argc, _TCHAR* argv[])
{
__asm
{
push HGYSEH // 设置当前的_except_handler
push DWORD PTR fs:[0] // 设置_EXCEPTION_REGISTRATION_RECORD.next
mov fs:[0],esp // 设置到fs:[0]位
mov eax, DWORD PTR fs:[0]
call DWORD PTR[eax 4] // 调用HGYSEH
}
构建SEH
示例1:
代码语言:javascript复制void SEHTest()
{
__try
{
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
反汇编如下:
代码语言:javascript复制 8 012213c0 55 push ebp
8 012213c1 8bec mov ebp,esp
8 012213c3 6afe push 0FFFFFFFEh
8 012213c5 68686a2201 push offset test!__rtc_tzz 0x104 (01226a68)
8 012213ca 687d102201 push offset test!ILT 120(__except_handler4) (0122107d)//1. 压入 __except_handler4,它是缺省的异常处理程序
8 012213cf 64a100000000 mov eax,dword ptr fs:[00000000h]//TEB取值到eax
8 012213d5 50 push eax//2.压入前一个TEB 值
8 012213d6 81c438ffffff add esp,0FFFFFF38h
8 012213dc 53 push ebx
8 012213dd 56 push esi
8 012213de 57 push edi
8 012213df 8dbd28ffffff lea edi,[ebp-0D8h]
8 012213e5 b930000000 mov ecx,30h
8 012213ea b8cccccccc mov eax,0CCCCCCCCh
8 012213ef f3ab rep stos dword ptr es:[edi]
8 012213f1 a100702201 mov eax,dword ptr [test!__security_cookie (01227000)]
8 012213f6 3145f8 xor dword ptr [ebp-8],eax
8 012213f9 33c5 xor eax,ebp
8 012213fb 50 push eax
8 012213fc 8d45f0 lea eax,[ebp-10h]
8 012213ff 64a300000000 mov dword ptr fs:[00000000h],eax// 设置 FS:[0] 值
8 01221405 8965e8 mov dword ptr [ebp-18h],esp
9 01221408 c745fc00000000 mov dword ptr [ebp-4],0
11 0122140f c745fcfeffffff mov dword ptr [ebp-4],0FFFFFFFEh
11 01221416 eb10 jmp test!SEHTest 0x68 (01221428) Branch
15 01221428 8b4df0 mov ecx,dword ptr [ebp-10h]
15 0122142b 64890d00000000 mov dword ptr fs:[0],ecx//恢复 SEH 链处理
15 01221432 59 pop ecx
15 01221433 5f pop edi
15 01221434 5e pop esi
15 01221435 5b pop ebx
15 01221436 8be5 mov esp,ebp
15 01221438 5d pop ebp
15 01221439 c3 ret
实际上VC 扩展了_EXCEPTION_REGISTRATION_RECORD,它的结构如下:
代码语言:javascript复制; exception registration record structure.
__EXCEPTIONREGISTRATIONRECORD struc
prev_structure dd ?
ExceptionHandler dd ?
ExceptionFilter dd ?//scopetable
FilterFrame dd ?
PExceptionInfoPtrs dd ?
__EXCEPTIONREGISTRATIONRECORD ends
ExceptionFilter对应scopetable
用C描述为:(https://www.microsoft.com/msj/0197/exception/exception.aspx)
代码语言:javascript复制struct _EXCEPTION_REGISTRATION{
struct _EXCEPTION_REGISTRATION *prev;
void (*handler)(PEXCEPTION_RECORD,
PEXCEPTION_REGISTRATION,
PCONTEXT,
PEXCEPTION_RECORD);
struct scopetable_entry *scopetable;
int trylevel;
int _ebp;
PEXCEPTION_POINTERS xpointers;
};
因为_except_handler4是缺省SEH,所以分析从它开始
代码语言:javascript复制012ec630 QQDemo!_except_handler4 (struct _EXCEPTION_RECORD *, struct _EXCEPTION_REGISTRATION_RECORD *, struct _CONTEXT *, void *)
-->
012ec783 e868000000 call QQDemo!ValidateLocalCookies (012ec7f0)
-->
012ec7f0 QQDemo!ValidateLocalCookies (struct _EH4_SCOPETABLE *, char *)
-->
0:000> dt _EH4_SCOPETABLE
QQDemo!_EH4_SCOPETABLE
0x000 GSCookieOffset : Uint4B
0x004 GSCookieXOROffset : Uint4B
0x008 EHCookieOffset : Uint4B
0x00c EHCookieXOROffset : Uint4B
0x010 ScopeRecord : [1] _EH4_SCOPETABLE_RECORD
用C描述为:
代码语言:javascript复制struct _EH4_SCOPETABLE {
UINT GSCookieOffset;
UINT GSCookieXOROffset;
UINT EHCookieOffset;
UINT EHCookieXOROffset;
_EH4_SCOPETABLE_RECORD ScopeRecord[1];
};