逆向分析MSVCR90D.dll!_EH4_LocalUnwind函数

引言:_EH4_LocalUnwind是except_handler4_common的局部展开函数。

102D9C0C int __fastcall _EH4_LocalUnwind(_EXCEPTION_REGISTRATION_RECORD *EstablisherFrame, 102D9C0C int TryLevel, 102D9C0C int FrameEBP, 102D9C0C int *CookiePointer 102D9C0C ) 102D9C0C @_EH4_LocalUnwind@16 proc near ; CODE XREF: __except_handler4_common+13Fp 102D9C0C ; __except_handler4_common+192p 102D9C0C 102D9C0C FrameEBP = dword ptr 4 102D9C0C CookiePointer = dword ptr 8 102D9C0C 102D9C0C push ebp 102D9C0D mov ebp, [esp+4+FrameEBP] ; 切换ebp,准备局部展开 102D9C11 push edx ; TryLevel 102D9C12 push ecx ; EstablisherFrame 102D9C13 push [esp+0Ch+CookiePointer]; CookiePointer 102D9C17 call __local_unwind4 102D9C1C add esp, 0Ch 102D9C1F pop ebp 102D9C20 retn 8 102D9C20 @_EH4_LocalUnwind@16 endp /** * * 操作系统原始的SEH异常帧结构 * struct _EXCEPTION_REGISTRATION_RECORD{ * struct _EXCEPTION_REGISTRATION_RECORD *Next; * _except_handler Handler; * } * * C/C++编译器扩展SEH的异常帧结构: * [ebp-18] ESP * [ebp-14] PEXCEPTION_POINTERS xpointers; * struct _EXCEPTION_REGISTRATION{ * [ebp-10] struct _EXCEPTION_REGISTRATION *prev; * [ebp-0C] _except_handler handler; * [ebp-08] struct scopetable_entry *scopetable; * [ebp-04] int trylevel; * [ebp-00] int _ebp; * }; * * 参数说明: * EstablisherFrame - 当前异常帧结构 * TryLevel - __try/__except(EXCEPTION_EXECUTE_HANDLER)所在的__try * FrameEBP - 引发异常函数的EBP,在执行__finally之前回复其上下文 * CookiePointer - 安全码所在地址,用于解密异常帧的ScopeTable. * **/ int __fastcall _EH4_LocalUnwind(_EXCEPTION_REGISTRATION_RECORD *EstablisherFrame, int TryLevel, int FrameEBP, int *CookiePointer ) { //切换ebp __asm mov ebp,FrameEBP return __local_unwind4(CookiePointer,EstablisherFrame,TryLevel); }

继续__local_unwind4的分析:

102D9AD0 int __cdecl _local_unwind4(int *CookiePointer, 102D9AD0 _EXCEPTION_REGISTRATION_RECORD *EstablisherFrame, 102D9AD0 int TryLevel 102D9AD0 ) 102D9AD0 102D9AD0 __local_unwind4 proc near ; CODE XREF: __fsopen+1B3p 102D9AD0 ; __gets_helper+4C6p ... 102D9AD0 102D9AD0 var_20 = dword ptr -20h 102D9AD0 CookiePointer = dword ptr 4 102D9AD0 EstablisherFrame= dword ptr 8 102D9AD0 TryLevel = dword ptr 0Ch 102D9AD0 102D9AD0 push ebx 102D9AD1 push esi 102D9AD2 push edi 102D9AD3 mov edx, [esp+0Ch+CookiePointer] 102D9AD7 mov eax, [esp+0Ch+EstablisherFrame] 102D9ADB mov ecx, [esp+0Ch+TryLevel] 102D9ADF push ebp 102D9AE0 push edx 102D9AE1 push eax 102D9AE2 push ecx 102D9AE3 push ecx 102D9AE4 push offset _unwind_handler4 ; Handler,局部展开发生异常时调用 102D9AE9 push large dword ptr fs:0 ; Prev 102D9AF0 mov eax, ___security_cookie 102D9AF5 xor eax, esp 102D9AF7 mov [esp+28h+var_20], eax 102D9AFB mov large fs:0, esp ;安装新的SEH 102D9B02 102D9B02 _lu_top: ; CODE XREF: __local_unwind4+64j 102D9B02 ; __local_unwind4+80j 102D9B02 mov eax, [esp+28h+EstablisherFrame] 102D9B06 mov ebx, [eax+8] ; 获取异常帧ScopeTable:EstablisherFrame->ScopeTable; 102D9B09 mov ecx, [esp+28h+CookiePointer] ; 获取安全码所在地址 102D9B0D xor ebx, [ecx] ; 解密异常帧ScopeTable 102D9B0F mov esi, [eax+0Ch] ; 获取异常TryLevel:EstablisherFrame->TryLevel 102D9B12 cmp esi, 0FFFFFFFEh ; 判断异常帧中的__try是否已经遍历完毕 102D9B15 jz short _lu_done ; 若不存在__try语句,退出! 102D9B17 mov edx, [esp+28h+TryLevel] 102D9B1B cmp edx, 0FFFFFFFEh 102D9B1E jz short loc_102D9B24 102D9B20 cmp esi, edx ; 判断当前__try是否在EXCEPTION_EXECUTE_HANDLER的__try语句里层 102D9B22 jbe short _lu_done ; 当前__try在EXCEPTION_EXECUTE_HANDLER的__try的外层,退出! 102D9B24 102D9B24 loc_102D9B24: ; CODE XREF: __local_unwind4+4Ej 102D9B24 lea esi, [esi+esi*2] 102D9B27 lea ebx, [ebx+esi*4+10h] ; 102D9B27 ; struct _EH4_SCOPETABLE_RECORD { 102D9B27 ; DWORD EnclosingLevel; //上一层__try块 102D9B27 ; PVOID FilterFunc; //过滤表达式 102D9B27 ; union 102D9B27 ; { 102D9B27 ; PVOID HandlerAddress; //__except块代码 102D9B27 ; PVOID FinallyFunc; //__finally块代码 102D9B27 ; }; 102D9B27 ; } 102D9B27 ; struct _EH4_SCOPETABLE { 102D9B27 ; DWORD GSCookieOffset; 102D9B27 ; DWORD GSCookieXOROffset; 102D9B27 ; DWORD EHCookieOffset; 102D9B27 ; DWORD EHCookieXOROffset; 102D9B27 ; struct _EH4_SCOPETABLE_RECORD ScopeRecord; 102D9B27 ; } 102D9B27 ; 102D9B27 ; 获取&(EstablisherFrame->ScopeTable)->ScopeRecord 102D9B2B mov ecx, [ebx] 102D9B2D mov [eax+0Ch], ecx ; 使当前异常帧指向上一个__try语句,也就是移除当前异常帧指向的__try. 102D9B2D ; EstablisherFrame->TryLevel=ScopeRecord->EnclosingLevel 102D9B30 cmp dword ptr [ebx+4], 0 ; 判断__try过滤表达式是否存在 102D9B34 jnz short _lu_top ; 不存在__finally语句,向上一层__try搜索! 102D9B36 push 101h 102D9B3B mov eax, [ebx+8] 102D9B3E call __NLG_Notify ; 作用未知! 102D9B43 mov ecx, 1 102D9B48 mov eax, [ebx+8] 102D9B4B call __NLG_Call ; 进入__finally块处理 102D9B50 jmp short _lu_top ; 遍历上一个__try/__except(或__finally) 102D9B52 ; --------------------------------------------------------------------------- 102D9B52 102D9B52 _lu_done: ; CODE XREF: __local_unwind4+45j 102D9B52 ; __local_unwind4+52j 102D9B52 pop large dword ptr fs:0 102D9B59 add esp, 18h 102D9B5C pop edi 102D9B5D pop esi 102D9B5E pop ebx 102D9B5F retn 102D9B5F __local_unwind4 endp /** * * 操作系统原始的SEH异常帧结构 * struct _EXCEPTION_REGISTRATION_RECORD{ * struct _EXCEPTION_REGISTRATION_RECORD *Next; * _except_handler Handler; * } * * SEH异常处理函数原型 * EXCEPTION_DISPOSITION (__cdecl *PEXCEPTION_ROUTINE)( * struct _EXCEPTION_RECORD *_ExceptionRecord, * void * _EstablisherFrame, * struct _CONTEXT *_ContextRecord, * void * _DispatcherContext * ); * * C/C++编译器扩展SEH的异常帧结构: * [ebp-18] ESP * [ebp-14] PEXCEPTION_POINTERS xpointers; * struct _EXCEPTION_REGISTRATION{ * [ebp-10] struct _EXCEPTION_REGISTRATION *Prev; * [ebp-0C] PEXCEPTION_ROUTINE Handler; * [ebp-08] struct _EH4_SCOPETABLE *ScopeTable; * [ebp-04] int TryLevel; * [ebp-00] int _Ebp; * }; * * C/C++运行库使用的SCOPE TABLE结构 * struct _EH4_SCOPETABLE { * DWORD GSCookieOffset; * DWORD GSCookieXOROffset; * DWORD EHCookieOffset; * DWORD EHCookieXOROffset; * struct _EH4_SCOPETABLE_RECORD ScopeRecord; * }; * * C/C++运行库使用的SCOPE TABLE RECORD结构 * struct _EH4_SCOPETABLE_RECORD { * DWORD EnclosingLevel; //上一层__try块 * PVOID FilterFunc; //过滤表达式 * union * { * PVOID HandlerAddress; //__except块代码 * PVOID FinallyFunc; //__finally块代码 * }; * }; * * 参数说明: * CookiePointer - 安全码所在地址,用于解密异常帧的ScopeTable. * EstablisherFrame - 当前异常帧结构 * TryLevel - __try/__except(EXCEPTION_EXECUTE_HANDLER)所在的__try * **/ int __cdecl _local_unwind4(int *CookiePointer, _EXCEPTION_REGISTRATION_RECORD *EstablisherFrame, int TryLevel ) { //安装SEH,_local_unwind4局部展开发生异常时调用 __asm push _unwind_handler4 __asm push dword ptr fs:[0] __asm mov fs:[0],esp //解密ScopeTable struct _EH4_SCOPETABLE * pScopeTable = EstablisherFrame->ScopeTable ^ (*CookiePointer); struct _EH4_SCOPETABLE_RECORD * pScopeRecord = &pScopeTable->ScopeRecord; //当前异常帧不存在__try块,退出! while(EstablisherFrame->TryLevel != 0xFFFFFFFE) { //越里层的__try其TryLevel值越高,捕获异常的__try通常在引发异常__try的外层 //这里判断当前异常帧指向的__try的TryLevel值是否正常. if(EstablisherFrame->TryLevel!=0xFFFFFFFE && EstablisherFrame->TryLevel <= TryLevel) break; //移除当前__try/__except(__finally)信息,使其指向上一层__try块 EstablisherFrame->TryLevel = pScopeRecord->EnclosingLevel; //__except过滤表达式存在,也就是__finally块不存在,向上一层__try/__except(__finally)遍历 if(pScopeRecord->FilterFunc) continue; //作用未知! __NLG_Notify(101); //进入__finally块处理 pScopeRecord->FinallyFunc(); } //恢复SEH __asm pop dword ptr fs:[0] }

 

你可能感兴趣的:(c,exception,struct,解密,编译器,Pointers)