逆向分析kernel32.dll!__local_unwind2函数

引言:__local_unwind2函数是结构化异常处理的局部展开函数.

7C80DF7F int __cdecl _local_unwind2(int argEstablisherFrame, int argTryLevel); CODE XREF: sub_7C80DF44+22p 7C80DF7F ; BasepGetTempPathW(x,x,x)+11Ep ... 7C80DF7F 7C80DF7F varPrevTryLevel = dword ptr -18h 7C80DF7F argEstablisherFrame= dword ptr 4 7C80DF7F argTryLevel = dword ptr 8 7C80DF7F 7C80DF7F ; FUNCTION CHUNK AT .text:7C80DFE1 SIZE 0000000E BYTES 7C80DF7F 7C80DF7F push ebx 7C80DF80 push esi 7C80DF81 push edi 7C80DF82 mov eax, [esp+0Ch+argEstablisherFrame] 7C80DF86 push ebp ; [ebp-00]:ebp 7C80DF87 push eax ; [ebp-04]:trylevel 7C80DF88 push 0FFFFFFFEh ; [ebp-08]:scopetable 7C80DF8A push offset sub_7C80DF44 ; [ebp-0C]:NestedExceptionHandler 7C80DF8F push large dword ptr fs:0 ; [ebp-10]:prev 7C80DF96 mov large fs:0, esp ; 安装新的SEH结构 7C80DF9D 7C80DF9D loc_7C80DF9D: ; CODE XREF: __local_unwind2+4Cj 7C80DF9D ; __NLG_Return2j 7C80DF9D mov eax, [esp+20h+argEstablisherFrame] 7C80DFA1 mov ebx, [eax+8] ; ebx=argEstablisherFrame->scopetable 7C80DFA4 mov esi, [eax+0Ch] ; esi=argEstablisherFrame->trylevel 7C80DFA7 cmp esi, 0FFFFFFFFh ; if(argEstablisherFrame->trylevel==0xFFFFFFFF) goto loc_7C80DFE1 7C80DFAA jz short loc_7C80DFE1 7C80DFAC cmp [esp+20h+argTryLevel], 0FFFFFFFFh 7C80DFAC ; argTryLevel属于最外层被标识为EXCEPTION_EXECUTE_HANDLER的__try/__except的位置 7C80DFAC ; if(argTryLevel == 0xFFFFFFFF) goto loc_7C80DFB9 7C80DFB1 jz short loc_7C80DFB9 ; 也就是说,不存在被标识为EXCEPTION_EXECUTE_HANDLER的最外层__try/__except! 7C80DFB1 ; 那么系统将直接遍历所有的__try/__except(__finally)结构并执行__finally块 7C80DFB3 cmp esi, [esp+20h+argTryLevel] 7C80DFB3 ; if(argEstablisherFrame->trylevel <= argTryLevel) goto loc_7C80DFE1 7C80DFB3 ; 也就是从触发异常的__try/__except位置到含有EXCEPTION_EXECUTE_HANDLER的__try/__except所在位置均遍历完毕! 7C80DFB7 jbe short loc_7C80DFE1 7C80DFB9 7C80DFB9 loc_7C80DFB9: ; CODE XREF: __local_unwind2+32j 7C80DFB9 lea esi, [esi+esi*2] 7C80DFBC mov ecx, [ebx+esi*4]; ecx=argEstablisherFrame->scopetable[argEstablisherFrame->trylevel].prevtrylevel 7C80DFBF mov [esp+20h+varPrevTryLevel], ecx 7C80DFC3 mov [eax+0Ch], ecx ; argEstablisherFrame->trylevel=ecx 7C80DFC3 ; 移除当前__try/__except(__finally)信息 7C80DFC6 cmp dword ptr [ebx+esi*4+4], 0 7C80DFC6 ; if(argEstablisherFrame->scopetable[argEstablisherFrame->trylevel].lpfnFilter) goto loc_7C80DF9D 7C80DFCB jnz short loc_7C80DF9D ; 如果lpfnFilter存在(也就是__finally块不存在),向上一个__try/__except(或__finally)遍历 7C80DFCD push 101h 7C80DFD2 mov eax, [ebx+esi*4+8] ; eax=argEstablisherFrame->scopetable[argEstablisherFrame->trylevel].lpfnHandler 7C80DFD6 call __NLG_Notify 7C80DFDB call dword ptr [ebx+esi*4+8] ; 调用argEstablisherFrame->scopetable[argEstablisherFrame->trylevel].lpfnHandler 7C80DFDB __local_unwind2 endp ; ; 也就是进入__finally块处理 7C80DFDB 7C80DFDF 7C80DFDF ; =============== S U B R O U T I N E ======================================= 7C80DFDF 7C80DFDF 7C80DFDF __NLG_Return2 proc near 7C80DFDF jmp short loc_7C80DF9D ; 处理上一个__try/__except(或__finally)结构 7C80DFDF __NLG_Return2 endp 7C80DFDF 7C80DFE1 ; --------------------------------------------------------------------------- 7C80DFE1 ; START OF FUNCTION CHUNK FOR __local_unwind2 7C80DFE1 7C80DFE1 loc_7C80DFE1: ; CODE XREF: __local_unwind2+2Bj 7C80DFE1 ; __local_unwind2+38j 7C80DFE1 pop large dword ptr fs:0 ; 恢复初始SEH结构 7C80DFE8 add esp, 10h 7C80DFEB pop edi 7C80DFEC pop esi 7C80DFED pop ebx 7C80DFEE retn 7C80DFEE ; END OF FUNCTION CHUNK FOR __local_unwind2 7C80DFEF 7C80DFEF ; =============== S U B R O U T I N E ======================================= 7C80DFEF

相应的伪代码:

/** * VC++扩展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; * }; * * scopetable_entry定义: * struct scopetable_entry{ * DWORD prevtrylevel; * PVOID lpfnFilter; * PVOID lpfnHandler; * } * * 参数说明: * argEstablisherFrame - 当前的SEH异常栈帧 * argTryLevel - 被标识为EXCEPTION_EXECUTE_HANDLER的__try/__except所在位置 **/ void __local_unwind2( struct _EXCEPTION_REGISTRATION* argEstablisherFrame, int argTryLevel) { DWORD dwTryLevel , dwPrevTryLevel; __try { //__try/__except(__finally)当前所在位置由argEstablisherFrame->trylevel表示. //在嵌套的__try/__except(__finally)结构中,越里层的__try/__except(__finally)其trylevel值越大. //向上遍历__try/__finally while(argEstablisherFrame->trylevel != 0xFFFFFFFF) { dwTryLevel = argEstablisherFrame->trylevel; //从触发异常的__try/__except(__finally)到被标识为 //EXCEPTION_EXECUTE_HANDLER的__try/__except的向上遍历过程已完成 if(argTryLevel!=0xFFFFFFF && dwTryLevel <= argTryLevel) return; //若不存在被标识为EXCEPTION_EXECUTE_HANDLER的最外层__try/__except(即:argTryLevel==0xFFFFFFF). //或 还未遍历到argTryLevel,则继续遍历__try/__except(__finally)结构并执行__finally块. //移除当前__try/__except(__finally)信息 dwPrevTryLevel = argEstablisherFrame->scopetable[dwTryLevel].prevtrylevel argEstablisherFrame->trylevel = dwPrevTryLevel; //如果lpfnFilter存在(也就是__finally块不存在),遍历上一个__try/__except(或__finally) if(argEstablisherFrame->scopetable[dwTryLevel].lpfnFilter) continue; //作用未知 __NLG_Notify(0x101); //进入__finally块处理 argEstablisherFrame->scopetable[dwTryLevel].lpfnHandler(); } } //局部展开过程中若出现异常,采用NestedExceptionHandler进行处理,即:sub_7C80DF44. __except(NestedExceptionHandler()){} }

示意图:

你可能感兴趣的:(c,exception,function,struct,扩展,Pointers)