|
[原创]SEH分析笔记(X86篇)
附录2 《nt!__local_unwind2 的反汇编代码》 [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf __local_unwind2 nt!__local_unwind2 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]205[/color][color=#0A246A]]: [/color][color=#800080]8087257b [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#800080]8087257c [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#800080]8087257d [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#800080]8087257e [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration [/color][color=#800080]80872582 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#800080]80872583 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#800080]80872584 [/color][color=#0A246A]push [/color][color=#800080]0FFFFFFFEh 80872586 [/color][color=#0A246A]push offset [/color][color=#000000]nt!__unwind_handler [/color][color=#0A246A]([/color][color=#800080]80872540[/color][color=#0A246A]) [/color][color=#800080]8087258b [/color][color=#0A246A]push dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#800080]80872592 [/color][color=#0A246A]mov dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]],[/color][color=#FF8000]esp [/color][color=#008000]; __local_unwind2 自身也会构建 _EXCEPTION_REGISTRATION [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x1e [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]222[/color][color=#0A246A]]: > [/color][color=#800080]80872599 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]24h[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration [/color][color=#0A246A]: [/color][color=#800080]8087259d [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ebx = pExceptionRegistration->scopetable [/color][color=#0A246A]: [/color][color=#800080]808725a0 [/color][color=#0A246A]mov [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRegistration->trylevel [/color][color=#0A246A]: [/color][color=#800080]808725a3 [/color][color=#0A246A]cmp [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFFh [/color][color=#008000]; cmp pExceptionRegistration->trylevel, TRYLEVEL_NONE [/color][color=#0A246A]:< [/color][color=#800080]808725a6 [/color][color=#0A246A]je [/color][color=#000000]nt!_NLG_Return2[/color][color=#0A246A]+[/color][color=#800080]0x2 [/color][color=#0A246A]([/color][color=#800080]808725dd[/color][color=#0A246A]) :: :: [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x2d [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]228[/color][color=#0A246A]]: :: [/color][color=#800080]808725a8 [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]28h[/color][color=#0A246A]],[/color][color=#800080]0FFFFFFFFh [/color][color=#0A246A]::< [/color][color=#800080]808725ad [/color][color=#0A246A]je [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x3a [/color][color=#0A246A]([/color][color=#800080]808725b5[/color][color=#0A246A]) ::: ::: [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x34 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]230[/color][color=#0A246A]]: ::: [/color][color=#800080]808725af [/color][color=#0A246A]cmp [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]28h[/color][color=#0A246A]] :::< [/color][color=#800080]808725b3 [/color][color=#0A246A]jbe [/color][color=#000000]nt!_NLG_Return2[/color][color=#0A246A]+[/color][color=#800080]0x2 [/color][color=#0A246A]([/color][color=#800080]808725dd[/color][color=#0A246A]) :::: :::: [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x3a [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]234[/color][color=#0A246A]]: ::>: [/color][color=#800080]808725b5 [/color][color=#0A246A]lea [/color][color=#FF8000]esi[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]] :: : [/color][color=#800080]808725b8 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; move ecx, [pExceptionRegistration->scopetable[i].previousTryLevel] [/color][color=#0A246A]:: : [/color][color=#800080]808725bb [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; 这个 esp+8 只写没读,什么情况? [/color][color=#0A246A]:: : [/color][color=#800080]808725bf [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistration->trylevel = ecx [/color][color=#0A246A]:: : [/color][color=#800080]808725c2 [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; cmp pExceptionRegistration->scopetable->lpfnFilter, NULL [/color][color=#0A246A]:: :< [/color][color=#800080]808725c7 [/color][color=#0A246A]jne [/color][color=#000000]nt!_NLG_Return2 [/color][color=#0A246A]([/color][color=#800080]808725db[/color][color=#0A246A]) :: :: :: :: [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x4e [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]243[/color][color=#0A246A]]: :: :: [/color][color=#008000]; RegistrationPointer->scopetable->lpfnFilter 等于 NULL,即这里是 __try & __finally 的组合 [/color][color=#0A246A]:: :: [/color][color=#800080]808725c9 [/color][color=#0A246A]push [/color][color=#800080]101h [/color][color=#0A246A]:: :: [/color][color=#800080]808725ce [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] :: :: [/color][color=#800080]808725d2 [/color][color=#0A246A]call [/color][color=#000000]nt!_NLG_Notify [/color][color=#0A246A]([/color][color=#800080]80872617[/color][color=#0A246A]) [/color][color=#008000]; 这个函数对理解 SEH 不重要,可以暂时忽略 [/color][color=#0A246A]:: :: [/color][color=#800080]808725d7 [/color][color=#0A246A]call dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration->scopetable->lpfnHandler() [/color][color=#0A246A]:: :: :: :: [/color][color=#000000]nt!_NLG_Return2 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]251[/color][color=#0A246A]]: <: :> [/color][color=#800080]808725db [/color][color=#0A246A]jmp [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x1e [/color][color=#0A246A]([/color][color=#800080]80872599[/color][color=#0A246A]) [/color][color=#008000]; 循环 [/color][color=#0A246A]: : : : [/color][color=#000000]nt!_NLG_Return2[/color][color=#0A246A]+[/color][color=#800080]0x2 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]253[/color][color=#0A246A]]: > > [/color][color=#800080]808725dd [/color][color=#0A246A]pop dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#800080]808725e4 [/color][color=#0A246A]add [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]10h 808725e7 [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#800080]808725e8 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#800080]808725e9 [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#800080]808725ea [/color][color=#0A246A]ret [/color][/font] |
|
[原创]SEH分析笔记(X86篇)
附录1 《Ntfs!_except_handler3 的反汇编代码》 [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf Ntfs!_except_handler3 [/color][color=#008000];nt!_except_handler3 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 172]: [/color][color=#800080]80872c00 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#800080]80872c01 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp [/color][color=#800080]80872c03 [/color][color=#0A246A]sub [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]8 80872c06 [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#800080]80872c07 [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#800080]80872c08 [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#800080]80872c09 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#800080]80872c0a [/color][color=#0A246A]cld [/color][color=#800080]80872c0b [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration [/color][color=#800080]80872c0e [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRecord [/color][color=#800080]80872c11 [/color][color=#0A246A]test dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6 [/color][color=#008000]; test pExceptionRecord->ExceptionFlags, (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND) [/color][color=#0A246A]< [/color][color=#800080]80872c18 [/color][color=#0A246A]jne [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xc9 [/color][color=#0A246A]([/color][color=#800080]80872cc9[/color][color=#0A246A]) : : [/color][color=#008000];nt!_except_handler3+0x1e [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 202]: [/color][color=#0A246A]: [/color][color=#008000]; ebp-8 和 ebp-4 是一个类型为 PEXCEPTION_POINTERS 的结构体,称之为 l_ExceptionPointers [/color][color=#0A246A]: [/color][color=#800080]80872c1e [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; l_ExceptionPointers->ExceptionRecord = pExceptionRecord [/color][color=#0A246A]: [/color][color=#800080]80872c21 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; eax = pContext [/color][color=#0A246A]: [/color][color=#800080]80872c24 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; l_ExceptionPointers->ContextRecord = pContext [/color][color=#0A246A]: [/color][color=#800080]80872c27 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = lException [/color][color=#0A246A]: [/color][color=#800080]80872c2a [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; ebx-4 指向 pExceptionRegistration 所在栈上类型为 PEXCEPTION_POINTERS 的变量 [/color][color=#0A246A]: [/color][color=#008000]; 具体栈的构造形式请参考当时建立 pExceptionRegistration 的代码 [/color][color=#0A246A]: [/color][color=#008000]; 这里是赋值给该 PEXCEPTION_POINTERS 变量,以提供给 GetExceptionInformation 和 GetExceptionCode 使用 [/color][color=#0A246A]: [/color][color=#800080]80872c2d [/color][color=#0A246A]mov [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRegistration->trylevel [/color][color=#0A246A]: [/color][color=#800080]80872c30 [/color][color=#0A246A]mov [/color][color=#FF8000]edi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; edi = pExceptionRegistration->scopetable [/color][color=#0A246A]: [/color][color=#800080]80872c33 [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#0A246A]: [/color][color=#800080]80872c34 [/color][color=#0A246A]call [/color][color=#000000]nt!_ValidateEH3RN [/color][color=#0A246A]([/color][color=#800080]8087cde8[/color][color=#0A246A]) : [/color][color=#800080]80872c39 [/color][color=#0A246A]add [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]4 [/color][color=#0A246A]: [/color][color=#800080]80872c3c [/color][color=#0A246A]or [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#0A246A]:< [/color][color=#800080]80872c3e [/color][color=#0A246A]je [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xbb [/color][color=#0A246A]([/color][color=#800080]80872cbb[/color][color=#0A246A]) :: :: [/color][color=#008000];nt!_except_handler3+0x40 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 218]: [/color][color=#0A246A]:: > [/color][color=#800080]80872c40 [/color][color=#0A246A]cmp [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFFh [/color][color=#008000]; cmp pExceptionRegistration->trylevel, TRYLEVEL_NONE [/color][color=#0A246A]::< : [/color][color=#800080]80872c43 [/color][color=#0A246A]je [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xc2 [/color][color=#0A246A]([/color][color=#800080]80872cc2[/color][color=#0A246A]) ::: : ::: : [/color][color=#008000];nt!_except_handler3+0x45 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 220]: [/color][color=#0A246A]::: : [/color][color=#800080]80872c45 [/color][color=#0A246A]lea [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]] [/color][color=#008000]; esi *= 3; 下面要将 eis*4,总共 esi*12,这是因为 scopetable_entry 大小是12 [/color][color=#0A246A]::: : [/color][color=#800080]80872c48 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration->scopetable[i].lpfnFilter [/color][color=#0A246A]::: : [/color][color=#800080]80872c4c [/color][color=#0A246A]or [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#0A246A]:::< : [/color][color=#800080]80872c4e [/color][color=#0A246A]je [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xa9 [/color][color=#0A246A]([/color][color=#800080]80872ca9[/color][color=#0A246A]) [/color][color=#008000]; lpfnFilter 为 NULL 则跳转 [/color][color=#0A246A]:::: : :::: : [/color][color=#008000];nt!_except_handler3+0x50 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 226]: [/color][color=#0A246A]:::: : [/color][color=#800080]80872c50 [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#0A246A]:::: : [/color][color=#800080]80872c51 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#0A246A]:::: : [/color][color=#800080]80872c52 [/color][color=#0A246A]lea [/color][color=#FF8000]ebp[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; ebp = pExceptionRegistration->_ebp [/color][color=#0A246A]:::: : [/color][color=#800080]80872c55 [/color][color=#0A246A]xor [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#0A246A]:::: : [/color][color=#800080]80872c57 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#0A246A]:::: : [/color][color=#800080]80872c59 [/color][color=#0A246A]xor [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edx [/color][color=#0A246A]:::: : [/color][color=#800080]80872c5b [/color][color=#0A246A]xor [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi [/color][color=#0A246A]:::: : [/color][color=#800080]80872c5d [/color][color=#0A246A]xor [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#0A246A]:::: : [/color][color=#800080]80872c5f [/color][color=#0A246A]call [/color][color=#FF8000]eax [/color][color=#008000]; pExceptionRegistration->scopetable[i].lpfnFilter() [/color][color=#0A246A]:::: : [/color][color=#800080]80872c61 [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#0A246A]:::: : [/color][color=#800080]80872c62 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#0A246A]:::: : [/color][color=#800080]80872c63 [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; ebx = pExceptionRegistration [/color][color=#0A246A]:::: : [/color][color=#800080]80872c66 [/color][color=#0A246A]or [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#0A246A]::::< : [/color][color=#800080]80872c68 [/color][color=#0A246A]je [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xa9 [/color][color=#0A246A]([/color][color=#800080]80872ca9[/color][color=#0A246A]) [/color][color=#008000]; EXCEPTION_CONTINUE_SEARCH [/color][color=#0A246A]::::: : ::::: : [/color][color=#008000];nt!_except_handler3+0x6a [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 245]: [/color][color=#0A246A]::::: : [/color][color=#008000]; 如果 lpfnFilter 返回 EXCEPTION_CONTINUE_EXECUTION,跳过下面的展开操作 [/color][color=#0A246A]:::::<: [/color][color=#800080]80872c6a [/color][color=#0A246A]js [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xb4 [/color][color=#0A246A]([/color][color=#800080]80872cb4[/color][color=#0A246A]) [/color][color=#008000]; EXCEPTION_CONTINUE_EXECUTION [/color][color=#0A246A]::::::: ::::::: [/color][color=#008000];nt!_except_handler3+0x6c [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 249]: [/color][color=#0A246A]::::::: [/color][color=#008000]; lpfnFilter 返回 EXCEPTION_EXECUTE_HANDLER,开始展开 [/color][color=#0A246A]::::::: [/color][color=#800080]80872c6c [/color][color=#0A246A]mov [/color][color=#FF8000]edi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; edi = pExceptionRegistration->scopetable [/color][color=#0A246A]::::::: [/color][color=#800080]80872c6f [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#0A246A]::::::: [/color][color=#800080]80872c70 [/color][color=#0A246A]call [/color][color=#000000]nt!__global_unwind2 [/color][color=#0A246A]([/color][color=#800080]80872520[/color][color=#0A246A]) ::::::: [/color][color=#800080]80872c75 [/color][color=#0A246A]add [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]4 [/color][color=#0A246A]::::::: ::::::: [/color][color=#800080]80872c78 [/color][color=#0A246A]lea [/color][color=#FF8000]ebp[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; ebp = pExceptionRegistration->_ebp [/color][color=#0A246A]::::::: [/color][color=#800080]80872c7b [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#008000]; 展开到当前 trylevel 为止(不包含本 scopetable_entry) [/color][color=#0A246A]::::::: [/color][color=#800080]80872c7c [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#0A246A]::::::: [/color][color=#800080]80872c7d [/color][color=#0A246A]call [/color][color=#000000]nt!__local_unwind2 [/color][color=#0A246A]([/color][color=#800080]8087257b[/color][color=#0A246A]) ::::::: [/color][color=#800080]80872c82 [/color][color=#0A246A]add [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]8 [/color][color=#0A246A]::::::: ::::::: [/color][color=#800080]80872c85 [/color][color=#0A246A]lea [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]] ::::::: [/color][color=#800080]80872c88 [/color][color=#0A246A]push [/color][color=#800080]1 [/color][color=#0A246A]::::::: [/color][color=#800080]80872c8a [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration->scopetable[i].lpfnHandler [/color][color=#0A246A]::::::: [/color][color=#800080]80872c8e [/color][color=#0A246A]call [/color][color=#000000]nt!_NLG_Notify [/color][color=#0A246A]([/color][color=#800080]80872617[/color][color=#0A246A]) ::::::: [/color][color=#800080]80872c93 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; [/color][color=#0A246A]::::::: [/color][color=#800080]80872c96 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; pExceptionRegistration->trylevel = RegistrationPointer->scopetable[i].previousTryLevel [/color][color=#0A246A]::::::: [/color][color=#800080]80872c99 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration->scopetable[i].lpfnHandler [/color][color=#0A246A]::::::: [/color][color=#800080]80872c9d [/color][color=#0A246A]xor [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#0A246A]::::::: [/color][color=#800080]80872c9f [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#0A246A]::::::: [/color][color=#800080]80872ca1 [/color][color=#0A246A]xor [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edx [/color][color=#0A246A]::::::: [/color][color=#800080]80872ca3 [/color][color=#0A246A]xor [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi [/color][color=#0A246A]::::::: [/color][color=#800080]80872ca5 [/color][color=#0A246A]xor [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#0A246A]::::::: [/color][color=#800080]80872ca7 [/color][color=#0A246A]call [/color][color=#FF8000]eax [/color][color=#008000]; pExceptionRegistration->scopetable[i].lpfnHandler(); 这里不会返回的!! [/color][color=#0A246A]::::::: ::::::: [/color][color=#008000];nt!_except_handler3+0xa9 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 285]: [/color][color=#0A246A]::::::: [/color][color=#008000]; 找到 scopetable 中的下一个 scopetable_entry,继续循环 [/color][color=#0A246A]:::>>:: [/color][color=#800080]80872ca9 [/color][color=#0A246A]mov [/color][color=#FF8000]edi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] ::: :: [/color][color=#800080]80872cac [/color][color=#0A246A]lea [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]] ::: :: [/color][color=#800080]80872caf [/color][color=#0A246A]mov [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]] ::: :< [/color][color=#800080]80872cb2 [/color][color=#0A246A]jmp [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0x40 [/color][color=#0A246A]([/color][color=#800080]80872c40[/color][color=#0A246A]) ::: : ::: : [/color][color=#008000];nt!_except_handler3+0xb4 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 291]: [/color][color=#0A246A]::: > [/color][color=#800080]80872cb4 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0 [/color][color=#008000]; eax = ExceptionContinueExecution (0) [/color][color=#0A246A]::: < [/color][color=#800080]80872cb9 [/color][color=#0A246A]jmp [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xde [/color][color=#0A246A]([/color][color=#800080]80872cde[/color][color=#0A246A]) ::: : ::: : [/color][color=#008000];nt!_except_handler3+0xbb [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 295]: [/color][color=#0A246A]:>: : [/color][color=#800080]80872cbb [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] : : : [/color][color=#800080]80872cbe [/color][color=#0A246A]or dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]8 [/color][color=#0A246A]: : : : : : [/color][color=#008000];nt!_except_handler3+0xc2 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 298]: [/color][color=#0A246A]: > : [/color][color=#800080]80872cc2 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#008000]; eax = ExceptionContinueSearch (1) [/color][color=#0A246A]: :< [/color][color=#800080]80872cc7 [/color][color=#0A246A]jmp [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xde [/color][color=#0A246A]([/color][color=#800080]80872cde[/color][color=#0A246A]) : :: > :: [/color][color=#008000];nt!_except_handler3+0xc9 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 302]: [/color][color=#0A246A]:: [/color][color=#008000]; 设置了(EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND),开始展开 [/color][color=#0A246A]:: [/color][color=#800080]80872cc9 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#0A246A]:: [/color][color=#800080]80872cca [/color][color=#0A246A]lea [/color][color=#FF8000]ebp[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000];ebp = pExceptionRegistration->_ebp [/color][color=#0A246A]:: [/color][color=#800080]80872ccd [/color][color=#0A246A]push [/color][color=#800080]0FFFFFFFFh [/color][color=#0A246A]:: [/color][color=#800080]80872ccf [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#0A246A]:: [/color][color=#800080]80872cd0 [/color][color=#0A246A]call [/color][color=#000000]nt!__local_unwind2 [/color][color=#0A246A]([/color][color=#800080]8087257b[/color][color=#0A246A]) :: [/color][color=#800080]80872cd5 [/color][color=#0A246A]add [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]8 [/color][color=#0A246A]:: [/color][color=#800080]80872cd8 [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#0A246A]:: [/color][color=#800080]80872cd9 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#FF8000]eax [/color][color=#0A246A]= [/color][color=#000000]ExceptionContinueSearch [/color][color=#0A246A]([/color][color=#800080]1[/color][color=#0A246A]) :: :: [/color][color=#008000];nt!_except_handler3+0xde [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 313]: [/color][color=#0A246A]>> [/color][color=#800080]80872cde [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#800080]80872cdf [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#800080]80872ce0 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#800080]80872ce1 [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#800080]80872ce2 [/color][color=#0A246A]mov [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#FF8000]ebp [/color][color=#800080]80872ce4 [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#800080]80872ce5 [/color][color=#0A246A]ret[/color][/font] |
|
[原创]SEH分析笔记(X86篇)
三、展开 (unwind) 为了说明这个概念,需要先回顾下异常发生后的处理流程。 我们假设一系列使用 SEH 的函数调用流程: func1 -> func2 -> func3。在 func3 执行的过程中触发了异常。 看看分发异常流程 RtlRaiseException -> RtlDispatchException -> RtlpExecuteHandlerForException RtlDispatchException 会遍历异常链表,对每个 EXCEPTION_REGISTRATION 都调用 RtlpExecuteHandlerForException。 RtlpExecuteHandlerForException 会调用 EXCEPTION_REGISTRATION::handler,也就是 PassThrough!_except_handler4。如咱们上面分析,该函数内部遍历 EXCEPTION_REGISTRATION::scopetable,如果遇到有 scopetable_entry::lpfnFilter 返回 EXCEPTION_EXECUTE_HANDLER,那么 scopetable_entry::lpfnHandler 就会被调用,来处理该异常。 因为 lpfnHandler 不会返回到 PassThrough!_except_handler4,于是执行完 lpfnHandler 后,就会从 lpfnHandler 之后的代码继续执行下去。也就是说,假设 func3 中触发了一个异常,该异常被 func1 中的 __except 处理块处理了,那 __except 处理块执行完毕后,就从其后的指令继续执行下去,即异常处理完毕后,接着执行的就是 func1 的代码。不会再回到 func2 或者 func3,这样就有个问题,func2 和 func3 中占用的资源怎么办?这些资源比如申请的内存是不会自动释放的,岂不是会有资源泄漏问题? 这就需要用到“展开”了。 说白了,所谓“展开”就是进行清理。(注:这里的清理主要包含动态分配的资源的清理,栈空间是由 func1 的“mov esp,ebp” 这类操作顺手清理的。当时我被“谁来清理栈空间”这个问题困扰了很久……) 那这个展开工作由谁来完成呢?由 func1 来完成肯定不合适,毕竟 func2 和 func3 有没有申请资源、申请了哪些资源,func1 无从得知。于是这个展开工作还得要交给 func2 和 func3 自己来完成。 展开分为两种:“全局展开”和“局部展开”。 全局展开是指针对异常链表中的某一段,局部展开针对指定 EXCEPTION_REGISTRATION。用上面的例子来讲,局部展开就是针对 func3 或 func2 (某一个函数)内部进行清理,全局展开就是 func2 和 func3 的局部清理的总和。再归纳一下,局部展开是指具体某一函数内部的清理,而全局展开是指,从异常触发点(func3)到异常处理点(func1)之间所有函数(包含异常触发点 func3)的局部清理的总和。 来看反汇编代码: [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_EH4_GlobalUnwind PassThrough!_EH4_GlobalUnwind [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]485[/color][color=#0A246A]]: [/color][color=#000000]f87205fa [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#000000]f87205fb [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp [/color][color=#000000]f87205fd [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#000000]f87205fe [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#000000]f87205ff [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#000000]f8720600 [/color][color=#0A246A]push [/color][color=#800080]0 [/color][color=#008000]; pReturnValue [/color][color=#000000]f8720602 [/color][color=#0A246A]push [/color][color=#800080]0 [/color][color=#008000]; pExceptionRecord [/color][color=#000000]f8720604 [/color][color=#0A246A]push offset [/color][color=#000000]PassThrough!_EH4_GlobalUnwind[/color][color=#0A246A]+[/color][color=#800080]0x15 [/color][color=#0A246A]([/color][color=#000000]f872060f[/color][color=#0A246A]) [/color][color=#008000]; pReturnEip [/color][color=#000000]f8720609 [/color][color=#0A246A]push [/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistration [/color][color=#000000]f872060a [/color][color=#0A246A]call [/color][color=#000000]PassThrough!RtlUnwind [/color][color=#0A246A]([/color][color=#000000]f8720678[/color][color=#0A246A]) [/color][color=#000000]f872060f [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#000000]f8720610 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#000000]f8720611 [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#000000]f8720612 [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#000000]f8720613 [/color][color=#0A246A]ret [/color][/font] RtlUnwind 的原型: VOID RtlUnwind( PEXCEPTION_REGISTRATION pExceptionRegistration PVOID pReturnEip PEXCEPTION_RECORD pExceptionRecord, PVOID pReturnValue ); [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!RtlUnwind [/color][color=#008000]; 提示:此函数 wrk 提供了实现源码 [/color][color=#000000]nt!RtlUnwind [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]423[/color][color=#0A246A]]: [/color][color=#800080]80867358 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#800080]80867359 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp [/color][color=#800080]8086735b [/color][color=#0A246A]sub [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]37Ch 80867361 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#000000]nt!__security_cookie [/color][color=#0A246A]([/color][color=#800080]80895388[/color][color=#0A246A])] [/color][color=#800080]80867366 [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#800080]80867367 [/color][color=#0A246A]mov [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRecord [/color][color=#800080]8086736a [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#800080]8086736d [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#800080]8086736e [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D8h[/color][color=#0A246A]] [/color][color=#008000]; [ebp-2D8h] = l_pHighLimit [/color][color=#800080]80867374 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#800080]80867375 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D4h[/color][color=#0A246A]] [/color][color=#008000]; [ebp-2D4h] = l_pLowLimit [/color][color=#800080]8086737b [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#800080]8086737c [/color][color=#0A246A]call [/color][color=#000000]nt!RtlpGetStackLimits [/color][color=#0A246A]([/color][color=#800080]80887cdc[/color][color=#0A246A]) [/color][color=#800080]80867381 [/color][color=#0A246A]xor [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#800080]80867383 [/color][color=#0A246A]cmp [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#008000]; pExceptionRecord 是否为 NULL [/color][color=#0A246A]< [/color][color=#800080]80867385 [/color][color=#0A246A]jne [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x5a [/color][color=#0A246A]([/color][color=#800080]808673b2[/color][color=#0A246A]) : : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x2f [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]452[/color][color=#0A246A]]: : [/color][color=#800080]80867387 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] : [/color][color=#800080]8086738a [/color][color=#0A246A]lea [/color][color=#FF8000]esi[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]37Ch[/color][color=#0A246A]] [/color][color=#008000]; ebp-37Ch 是局部变量 l_ExceptionRecord [/color][color=#0A246A]: [/color][color=#800080]80867390 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]37Ch[/color][color=#0A246A]],[/color][color=#800080]0C0000027h [/color][color=#008000]; l_ExceptionRecord.ExceptionCode = STATUS_UNWIND [/color][color=#0A246A]: [/color][color=#800080]8086739a [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]378h[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags = 0 [/color][color=#0A246A]: [/color][color=#800080]808673a0 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]374h[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; l_ExceptionRecord.ExceptionRecord = NULL [/color][color=#0A246A]: [/color][color=#800080]808673a6 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]370h[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; l_ExceptionRecord.ExceptionAddress = ret_addr (PassThrough!RtlUnwind 执行完毕后的返回地址) [/color][color=#0A246A]: [/color][color=#800080]808673ac [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]36Ch[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; l_ExceptionRecord.ExceptionInformation[0] = 0; [/color][color=#0A246A]: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x5a [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]462[/color][color=#0A246A]]: > [/color][color=#800080]808673b2 [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; pExceptionRegistration 是否为 NULL [/color][color=#0A246A]< [/color][color=#800080]808673b5 [/color][color=#0A246A]je [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x65 [/color][color=#0A246A]([/color][color=#800080]808673bd[/color][color=#0A246A]) : : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x5f [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]463[/color][color=#0A246A]]: : [/color][color=#800080]808673b7 [/color][color=#0A246A]or dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]2 [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags |= EXCEPTION_UNWINDING (0x2) [/color][color=#0A246A]:< [/color][color=#800080]808673bb [/color][color=#0A246A]jmp [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x69 [/color][color=#0A246A]([/color][color=#800080]808673c1[/color][color=#0A246A]) :: :: [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x65 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]466[/color][color=#0A246A]]: >: [/color][color=#800080]808673bd [/color][color=#0A246A]or dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6 [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags |= EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND (0x2 | 0x4) [/color][color=#0A246A]: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x69 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]466[/color][color=#0A246A]]: > [/color][color=#800080]808673c1 [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#800080]808673c2 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]] [/color][color=#008000]; ebp-2D0 是局部变量 l_Context [/color][color=#800080]808673c8 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#800080]808673c9 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]],[/color][color=#800080]10007h [/color][color=#008000]; lContext.ContextFlags = CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS (0x10000 | 0x1 | 0x2 | 0x3) [/color][color=#800080]808673d3 [/color][color=#0A246A]call [/color][color=#000000]nt!RtlpCaptureContext [/color][color=#0A246A]([/color][color=#800080]80887c50[/color][color=#0A246A]) [/color][color=#800080]808673d8 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; eax = ReturnValue [/color][color=#800080]808673db [/color][color=#0A246A]add dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]20Ch[/color][color=#0A246A]],[/color][color=#800080]10h [/color][color=#008000]; -20C = -2D0+C4, lContext.Esp += 0x10 [/color][color=#800080]808673e2 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]220h[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; -220 = -2D0+B0, lContext.Eax = ReturnValue [/color][color=#800080]808673e8 [/color][color=#0A246A]call [/color][color=#000000]nt!RtlpGetRegistrationHead [/color][color=#0A246A]([/color][color=#800080]80887d04[/color][color=#0A246A]) [/color][color=#800080]808673ed [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#008000]; ebx = 异常链表头,这里暂命名为 l_pExceptionRegistration [/color][color=#0A246A]< [/color][color=#800080]808673ef [/color][color=#0A246A]jmp [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1d1 [/color][color=#0A246A]([/color][color=#800080]80867529[/color][color=#0A246A]) : : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x9c [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]500[/color][color=#0A246A]]: : > [/color][color=#800080]808673f4 [/color][color=#0A246A]cmp [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; cmp l_pExceptionRegistration,pExceptionRegistration [/color][color=#0A246A]:< : [/color][color=#800080]808673f7 [/color][color=#0A246A]jne [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xb0 [/color][color=#0A246A]([/color][color=#800080]80867408[/color][color=#0A246A]) :: : :: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xa1 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]501[/color][color=#0A246A]]: :: : [/color][color=#008000]; pExceptionRegistration 等于 l_pExceptionRegistration,说明展开完毕 [/color][color=#0A246A]:: : [/color][color=#800080]808673f9 [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#008000]; TestAlert = FALSE [/color][color=#0A246A]:: : [/color][color=#800080]808673fa [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_Context [/color][color=#0A246A]:: : [/color][color=#800080]80867400 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#0A246A]:: : [/color][color=#800080]80867401 [/color][color=#0A246A]call [/color][color=#000000]nt!ZwContinue [/color][color=#0A246A]([/color][color=#800080]8082c0b8[/color][color=#0A246A]) [/color][color=#008000]; 这里不会返回 [/color][color=#0A246A]::< : [/color][color=#800080]80867406 [/color][color=#0A246A]jmp [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xe6 [/color][color=#0A246A]([/color][color=#800080]8086743e[/color][color=#0A246A]) ::: : ::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xb0 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]509[/color][color=#0A246A]]: :>: : [/color][color=#800080]80867408 [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; cmp pExceptionRegistration, NULL [/color][color=#0A246A]: :< : [/color][color=#800080]8086740b [/color][color=#0A246A]je [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xe6 [/color][color=#0A246A]([/color][color=#800080]8086743e[/color][color=#0A246A]) : :: : : :: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xb5 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]509[/color][color=#0A246A]]: : :: : [/color][color=#800080]8086740d [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]ebx [/color][color=#008000]; cmp pExceptionRegistration,l_pExceptionRegistration [/color][color=#0A246A]: ::< : [/color][color=#800080]80867410 [/color][color=#0A246A]jae [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xe6 [/color][color=#0A246A]([/color][color=#800080]8086743e[/color][color=#0A246A]) : ::: : : ::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xba [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]514[/color][color=#0A246A]]: : ::: : [/color][color=#008000]; pExceptionRegistration 在 l_pExceptionRegistration 之下,即 pExceptionRegistration 超出了异常链表的栈范围 [/color][color=#0A246A]: ::: : [/color][color=#800080]80867412 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]] [/color][color=#008000]; ebp-32Ch 是局部变量 l_ExceptionRecord [/color][color=#0A246A]: ::: : [/color][color=#800080]80867418 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#0A246A]: ::: : [/color][color=#800080]80867419 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]],[/color][color=#800080]0C0000029h [/color][color=#008000]; l_ExceptionRecord.ExceptionCode = STATUS_INVALID_UNWIND_TARGET [/color][color=#0A246A]: ::: : [/color][color=#800080]80867423 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]328h[/color][color=#0A246A]],[/color][color=#800080]1 [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE (1) [/color][color=#0A246A]: ::: : [/color][color=#800080]8086742d [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]324h[/color][color=#0A246A]],[/color][color=#FF8000]esi [/color][color=#008000]; l_ExceptionRecord.ExceptionRecord = &l_ExceptionRecord [/color][color=#0A246A]: ::: : [/color][color=#800080]80867433 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]31Ch[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; l_ExceptionRecord.NumberParameters = 0 [/color][color=#0A246A]: ::: : [/color][color=#800080]80867439 [/color][color=#0A246A]call [/color][color=#000000]nt!RtlRaiseException [/color][color=#0A246A]([/color][color=#800080]80887a94[/color][color=#0A246A]) : ::: : : ::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xe6 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]530[/color][color=#0A246A]]: : >>> : [/color][color=#800080]8086743e [/color][color=#0A246A]cmp [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D4h[/color][color=#0A246A]] [/color][color=#008000]; cmp l_pExceptionRegistration, l_pLowLimit [/color][color=#0A246A]: : [/color][color=#800080]80867444 [/color][color=#0A246A]lea [/color][color=#FF8000]edi[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; edi = l_pExceptionRegistration->scopetable_entry [/color][color=#0A246A]: < : [/color][color=#800080]80867447 [/color][color=#0A246A]jb [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x162 [/color][color=#0A246A]([/color][color=#800080]808674ba[/color][color=#0A246A]) [/color][color=#008000]; l_pExceptionRegistration 低于线程栈底,跳到错误处理 [/color][color=#0A246A]: : : : : : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xf1 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]530[/color][color=#0A246A]]: : : : [/color][color=#800080]80867449 [/color][color=#0A246A]cmp [/color][color=#FF8000]edi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D8h[/color][color=#0A246A]] [/color][color=#008000]; cmp l_pExceptionRegistration->scopetable_entry,l_pHighLimit [/color][color=#0A246A]: :< : [/color][color=#800080]8086744f [/color][color=#0A246A]ja [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x162 [/color][color=#0A246A]([/color][color=#800080]808674ba[/color][color=#0A246A]) [/color][color=#008000]; l_pExceptionRegistration 高于线程栈顶,跳到错误处理 [/color][color=#0A246A]: :: : : :: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xf9 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]530[/color][color=#0A246A]]: : :: : [/color][color=#008000]; l_pExceptionRegistration 处于合法栈中,检查它是否正确对齐 [/color][color=#0A246A]: :: : [/color][color=#800080]80867451 [/color][color=#0A246A]test [/color][color=#FF8000]bl[/color][color=#0A246A],[/color][color=#800080]3 [/color][color=#008000]; 检查 l_pExceptionRegistration 是否4字节对齐 [/color][color=#0A246A]: ::< : [/color][color=#800080]80867454 [/color][color=#0A246A]jne [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 没对齐,跳到错误处理 [/color][color=#0A246A]: ::: : : ::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x102 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]580[/color][color=#0A246A]]: : ::: : [/color][color=#008000]; 进行局部展开 [/color][color=#0A246A]: ::: : [/color][color=#800080]8086745a [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; l_pExceptionRegistration->Handler [/color][color=#0A246A]: ::: : [/color][color=#800080]8086745d [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2DCh[/color][color=#0A246A]] [/color][color=#008000]; 这里是局部变量 l_DispatchContext [/color][color=#0A246A]: ::: : [/color][color=#800080]80867463 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#008000]; [/color][color=#0A246A]: ::: : [/color][color=#800080]80867464 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_Context [/color][color=#0A246A]: ::: : [/color][color=#800080]8086746a [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#008000]; l_Context [/color][color=#0A246A]: ::: : [/color][color=#800080]8086746b [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#008000]; l_pExceptionRegistration [/color][color=#0A246A]: ::: : [/color][color=#800080]8086746c [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#008000]; &l_ExceptionRecord [/color][color=#0A246A]: ::: : [/color][color=#800080]8086746d [/color][color=#0A246A]call [/color][color=#000000]nt!RtlpExecuteHandlerForUnwind [/color][color=#0A246A]([/color][color=#800080]80887b54[/color][color=#0A246A]) [/color][color=#008000]; 内部调用 l_pExceptionRegistration->Handler [/color][color=#0A246A]: ::: : [/color][color=#800080]80867472 [/color][color=#0A246A]dec [/color][color=#FF8000]eax [/color][color=#0A246A]: :::< : [/color][color=#800080]80867473 [/color][color=#0A246A]je [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x156 [/color][color=#0A246A]([/color][color=#800080]808674ae[/color][color=#0A246A]) [/color][color=#008000]; 如果返回 ExceptionContinueSearch 则跳转 [/color][color=#0A246A]: :::: : : :::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x11d [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]586[/color][color=#0A246A]]: : :::: : [/color][color=#800080]80867475 [/color][color=#0A246A]dec [/color][color=#FF8000]eax [/color][color=#0A246A]: :::: : [/color][color=#800080]80867476 [/color][color=#0A246A]dec [/color][color=#FF8000]eax [/color][color=#0A246A]: :::: < : [/color][color=#800080]80867477 [/color][color=#0A246A]je [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x150 [/color][color=#0A246A]([/color][color=#800080]808674a8[/color][color=#0A246A]) [/color][color=#008000]; 如果返回 ExceptionCollidedUnwind 则跳转 [/color][color=#0A246A]: :::: : : : :::: : : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x121 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]621[/color][color=#0A246A]]: : :::: : : [/color][color=#008000]; 返回 ExceptionContinueSearch 和 ExceptionCollidedUnwind 之外的非法值 [/color][color=#0A246A]: :::: : : [/color][color=#800080]80867479 [/color][color=#0A246A]and dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]31Ch[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; l_ExceptionRecord.NumberParameters = 0 [/color][color=#0A246A]: :::: : : [/color][color=#800080]80867480 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_ExceptionRecord [/color][color=#0A246A]: :::: : : [/color][color=#800080]80867486 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#0A246A]: :::: : : [/color][color=#800080]80867487 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]],[/color][color=#800080]0C0000026h [/color][color=#008000]; l_ExceptionRecord.ExceptionCode = STATUS_INVALID_DISPOSITION [/color][color=#0A246A]: :::: : : [/color][color=#800080]80867491 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]328h[/color][color=#0A246A]],[/color][color=#800080]1 [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE (1) [/color][color=#0A246A]: :::: : : [/color][color=#800080]8086749b [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]324h[/color][color=#0A246A]],[/color][color=#FF8000]esi [/color][color=#008000]; l_ExceptionRecord.ExceptionRecord = &l_ExceptionRecord [/color][color=#0A246A]: :::: : : [/color][color=#800080]808674a1 [/color][color=#0A246A]call [/color][color=#000000]nt!RtlRaiseException [/color][color=#0A246A]([/color][color=#800080]80887a94[/color][color=#0A246A]) : ::::<: : [/color][color=#800080]808674a6 [/color][color=#0A246A]jmp [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x156 [/color][color=#0A246A]([/color][color=#800080]808674ae[/color][color=#0A246A]) : :::::: : : :::::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x150 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]608[/color][color=#0A246A]]: : :::::: : [/color][color=#008000]; RtlpExecuteHandlerForUnwind 返回 ExceptionCollidedUnwind,从 l_DispatchContext.RegistrationPointer 继续处理 [/color][color=#0A246A]: :::::> : [/color][color=#800080]808674a8 [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2DCh[/color][color=#0A246A]] [/color][color=#008000]; l_pExceptionRegistration = l_DispatchContext.RegistrationPointer [/color][color=#0A246A]: ::::: : : ::::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x156 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]630[/color][color=#0A246A]]: : ::::: : [/color][color=#008000]; 局部展开完毕,从异常链表中摘除 l_pExceptionRegistration [/color][color=#0A246A]: :::>> : [/color][color=#800080]808674ae [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#008000]; eax = l_pExceptionRegistration [/color][color=#0A246A]: ::: : [/color][color=#800080]808674b0 [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]] [/color][color=#008000]; l_pExceptionRegistration = l_pExceptionRegistration.prev [/color][color=#0A246A]: ::: : [/color][color=#800080]808674b2 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#0A246A]: ::: : [/color][color=#800080]808674b3 [/color][color=#0A246A]call [/color][color=#000000]nt!RtlpUnlinkHandler [/color][color=#0A246A]([/color][color=#800080]80887c10[/color][color=#0A246A]) [/color][color=#008000]; 摘除 [/color][color=#0A246A]: :::< : [/color][color=#800080]808674b8 [/color][color=#0A246A]jmp [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1cf [/color][color=#0A246A]([/color][color=#800080]80867527[/color][color=#0A246A]) : :::: : : :::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x162 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]540[/color][color=#0A246A]]: : :::: : [/color][color=#008000]; l_pExceptionRegistration 并不处在当前线程栈中,这种情况不一定是出错,有可能当前正在执行 DPC。 [/color][color=#0A246A]: :::: : [/color][color=#008000]; 当时还需要检查是否对齐,不对齐就一定是出错 [/color][color=#0A246A]: >>:: : [/color][color=#800080]808674ba [/color][color=#0A246A]test [/color][color=#FF8000]bl[/color][color=#0A246A],[/color][color=#800080]3 [/color][color=#008000]; 检查 l_pExceptionRegistration 是否4字节对齐 [/color][color=#0A246A]: ::< : [/color][color=#800080]808674bd [/color][color=#0A246A]jne [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) : ::: : : ::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x167 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]540[/color][color=#0A246A]]: : ::: : [/color][color=#008000]; 如果当前正在执行 DPC,那 IRQL 一定不得低于 DISPATCH_LEVEL(难道不是应该一定等于 DISPATCH_LEVEL ?) [/color][color=#0A246A]: ::: : [/color][color=#800080]808674bf [/color][color=#0A246A]call dword ptr [[/color][color=#000000]nt!_imp__KeGetCurrentIrql [/color][color=#0A246A]([/color][color=#800080]8080102c[/color][color=#0A246A])] : ::: : [/color][color=#800080]808674c5 [/color][color=#0A246A]cmp [/color][color=#FF8000]al[/color][color=#0A246A],[/color][color=#800080]2 [/color][color=#008000]; DISPATCH_LEVEL (2) [/color][color=#0A246A]: :::< : [/color][color=#800080]808674c7 [/color][color=#0A246A]jb [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 低于 DISPATCH_LEVEL,跳到错误处理点 [/color][color=#0A246A]: :::: : : :::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x171 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]542[/color][color=#0A246A]]: : :::: : [/color][color=#800080]808674c9 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]00000020h[/color][color=#0A246A]] [/color][color=#008000]; eax = 当前 CPU 的 KPCR::Prcb [/color][color=#0A246A]: :::: : [/color][color=#800080]808674cf [/color][color=#0A246A]cmp byte ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]95Ah[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; KPCR::Prcb->DpcRoutineActive (BOOLEAN 类型) [/color][color=#0A246A]: :::: : [/color][color=#800080]808674d6 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]948h[/color][color=#0A246A]] [/color][color=#008000]; ecx = KPCR::Prcb->DpcStack [/color][color=#0A246A]: ::::< : [/color][color=#800080]808674dc [/color][color=#0A246A]je [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 当前不是在执行 DPC,跳到错误处理点 [/color][color=#0A246A]: ::::: : : ::::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x186 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]547[/color][color=#0A246A]]: : ::::: : [/color][color=#008000]; KPCR::Prcb->DpcRoutineActive 为 TRUE,当前异常是由 DpcRoutine 触发 [/color][color=#0A246A]: ::::: : [/color][color=#800080]808674de [/color][color=#0A246A]cmp [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#008000]; 比较 l_pExceptionRegistration->scopetable_entry 和 DPC 栈顶 [/color][color=#0A246A]: :::::< : [/color][color=#800080]808674e0 [/color][color=#0A246A]ja [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 高出 DPC 栈顶,跳到错误处理点 [/color][color=#0A246A]: :::::: : : :::::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x18a [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]547[/color][color=#0A246A]]: : :::::: : [/color][color=#800080]808674e2 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ecx[/color][color=#0A246A]-[/color][color=#800080]3000h[/color][color=#0A246A]] [/color][color=#008000]; eax = KPCR::Prcb->DpcStack - KERNEL_STACK_SIZE, 即 DPC 栈底 [/color][color=#0A246A]: :::::: : [/color][color=#800080]808674e8 [/color][color=#0A246A]cmp [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#008000]; 比较 l_pExceptionRegistration 和 DPC 栈底 [/color][color=#0A246A]: ::::::< : [/color][color=#800080]808674ea [/color][color=#0A246A]jb [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 低于 DPC 栈底,跳到错误处理点 [/color][color=#0A246A]: ::::::: : : ::::::: : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x194 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]555[/color][color=#0A246A]]: : ::::::: : [/color][color=#800080]808674ec [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D8h[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; l_pHighLimit = DPC 栈顶 [/color][color=#0A246A]: ::::::: : [/color][color=#800080]808674f2 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D4h[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; l_pLowLimit = DPC 栈底 [/color][color=#0A246A]: :::::::<: [/color][color=#800080]808674f8 [/color][color=#0A246A]jmp [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1cf [/color][color=#0A246A]([/color][color=#800080]80867527[/color][color=#0A246A]) : ::::::::: : ::::::::: [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]564[/color][color=#0A246A]]: : ::::::::: [/color][color=#008000]; 栈错误 [/color][color=#0A246A]: >:>>>>>:: [/color][color=#800080]808674fa [/color][color=#0A246A]and dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]31Ch[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#0A246A]: : :: [/color][color=#800080]80867501 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_ExceptionRecord [/color][color=#0A246A]: : :: [/color][color=#800080]80867507 [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#0A246A]: : :: [/color][color=#800080]80867508 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]],[/color][color=#800080]0C0000028h [/color][color=#008000]; l_ExceptionRecord.ExceptionCode = STATUS_BAD_STACK [/color][color=#0A246A]: : :: [/color][color=#800080]80867512 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]328h[/color][color=#0A246A]],[/color][color=#800080]1 [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE (1) [/color][color=#0A246A]: : :: [/color][color=#800080]8086751c [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]324h[/color][color=#0A246A]],[/color][color=#FF8000]esi [/color][color=#008000]; l_ExceptionRecord.ExceptionRecord = &l_ExceptionRecord [/color][color=#0A246A]: : :: [/color][color=#800080]80867522 [/color][color=#0A246A]call [/color][color=#000000]nt!RtlRaiseException [/color][color=#0A246A]([/color][color=#800080]80887a94[/color][color=#0A246A]) : : :: : : :: [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1cf [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]493[/color][color=#0A246A]]: : > >: [/color][color=#800080]80867527 [/color][color=#0A246A]xor [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#0A246A]: : : : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1d1 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]493[/color][color=#0A246A]]: > : [/color][color=#800080]80867529 [/color][color=#0A246A]cmp [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFFh [/color][color=#008000]; cmp l_pExceptionRegistration, EXCEPTION_CHAIN_END [/color][color=#0A246A]< [/color][color=#800080]8086752c [/color][color=#0A246A]jne [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x9c [/color][color=#0A246A]([/color][color=#800080]808673f4[/color][color=#0A246A]) [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1da [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]647[/color][color=#0A246A]]: [/color][color=#800080]80867532 [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#800080]0FFFFFFFFh [/color][color=#008000]; cmp pExceptionRegistration, EXCEPTION_CHAIN_END [/color][color=#800080]80867536 [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#800080]80867537 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_Context [/color][color=#800080]8086753d [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#008000]; bTestAlert = FALSE 或 bFirstChance = FALSE [/color][color=#800080]8086753e [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#0A246A]< [/color][color=#800080]8086753f [/color][color=#0A246A]jne [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1f0 [/color][color=#0A246A]([/color][color=#800080]80867548[/color][color=#0A246A]) : : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1e9 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]656[/color][color=#0A246A]]: : [/color][color=#008000]; 展开整个异常链表 [/color][color=#0A246A]: [/color][color=#800080]80867541 [/color][color=#0A246A]call [/color][color=#000000]nt!ZwContinue [/color][color=#0A246A]([/color][color=#800080]8082c0b8[/color][color=#0A246A]) :< [/color][color=#800080]80867546 [/color][color=#0A246A]jmp [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1f6 [/color][color=#0A246A]([/color][color=#800080]8086754e[/color][color=#0A246A]) :: :: [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1f0 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]667[/color][color=#0A246A]]: :: [/color][color=#008000]; pExceptionRegistration 等于 EXCEPTION_CHAIN_END。 [/color][color=#0A246A]:: [/color][color=#008000]; 没有理解这里触发异常是为什么,但是不妨碍分析异常处理流程。 [/color][color=#0A246A]>: [/color][color=#800080]80867548 [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#008000]; &l_ExceptionRecord [/color][color=#0A246A]: [/color][color=#800080]80867549 [/color][color=#0A246A]call [/color][color=#000000]nt!ZwRaiseException [/color][color=#0A246A]([/color][color=#800080]8082ccd4[/color][color=#0A246A]) : : [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1f6 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]671[/color][color=#0A246A]]: > [/color][color=#800080]8086754e [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#800080]80867551 [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#800080]80867552 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#800080]80867553 [/color][color=#0A246A]call [/color][color=#000000]nt!__security_check_cookie [/color][color=#0A246A]([/color][color=#800080]80874e87[/color][color=#0A246A]) [/color][color=#800080]80867558 [/color][color=#0A246A]leave [/color][color=#800080]80867559 [/color][color=#0A246A]ret [/color][color=#800080]10h [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf [/color][color=#800080]80887be9 [/color][color=#008000]; RtlpExecuteHandlerForUnwind 的异常处理函数 [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x61 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]329[/color][color=#0A246A]]: [/color][color=#800080]80887be9 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRecord [/color][color=#800080]80887bed [/color][color=#0A246A]test dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6 [/color][color=#008000]; test pExceptionRecord->ExceptionFlags, EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND [/color][color=#800080]80887bf4 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#008000]; eax = ExceptionContinueSearch [/color][color=#800080]80887bf9 [/color][color=#0A246A]je [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x85 [/color][color=#0A246A]([/color][color=#800080]80887c0d[/color][color=#0A246A]) [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x73 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]341[/color][color=#0A246A]]: [/color][color=#008000]; 展开过程中 Handler 触发异常 [/color][color=#800080]80887bfb [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRegistration [/color][color=#800080]80887bff [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; edx = pDispatcherContext [/color][color=#800080]80887c03 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration->prev [/color][color=#800080]80887c06 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; pDispatcherContext->RegistrationPointer = pExceptionRegistration->prev, ; 然后 pDispatcherContext->RegistrationPointer 就是展开过程中正在被展开的 ; 那个 EXCEPTION_REGISTRATION_RECORD [/color][color=#800080]80887c08 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]3 [/color][color=#008000]; eax = ExceptionCollidedUnwind [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x85 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]349[/color][color=#0A246A]]: [/color][color=#800080]80887c0d [/color][color=#0A246A]ret [/color][color=#800080]10h [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf RtlpExecuteHandlerForUnwind nt!RtlpExecuteHandlerForUnwind [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]142[/color][color=#0A246A]]: [/color][color=#800080]80887b54 [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],offset [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x61 [/color][color=#0A246A]([/color][color=#800080]80887be9[/color][color=#0A246A]) [/color][color=#800080]80887b59 [/color][color=#0A246A]lea [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]ecx[/color][color=#0A246A]] [/color][color=#800080]80887b5c [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#800080]80887b5d [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#800080]80887b5e [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#800080]80887b5f [/color][color=#0A246A]xor [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#800080]80887b61 [/color][color=#0A246A]xor [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#800080]80887b63 [/color][color=#0A246A]xor [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi [/color][color=#800080]80887b65 [/color][color=#0A246A]xor [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#800080]80887b67 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRoutine [/color][color=#800080]80887b6b [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pDispatcherContext [/color][color=#800080]80887b6f [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pContext [/color][color=#800080]80887b73 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration [/color][color=#800080]80887b77 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRecord [/color][color=#800080]80887b7b [/color][color=#0A246A]call [/color][color=#000000]nt!ExecuteHandler2 [/color][color=#0A246A]([/color][color=#800080]80887b88[/color][color=#0A246A]) [/color][color=#800080]80887b80 [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#800080]80887b81 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#800080]80887b82 [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#800080]80887b83 [/color][color=#0A246A]ret [/color][color=#800080]14h [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf nt!ExecuteHandler2 nt!ExecuteHandler2 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]188[/color][color=#0A246A]]: [/color][color=#800080]80887b88 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#800080]80887b89 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp [/color][color=#800080]80887b8b [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration [/color][color=#800080]80887b8e [/color][color=#0A246A]push [/color][color=#FF8000]edx [/color][color=#008000]; _EXCEPTION_REGISTRATION_RECORD::Handler (nt!ExecuteHandler2+0x61 (80887be9)) [/color][color=#800080]80887b8f [/color][color=#0A246A]push dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#008000]; _EXCEPTION_REGISTRATION_RECORD::Next [/color][color=#800080]80887b96 [/color][color=#0A246A]mov dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]],[/color][color=#FF8000]esp[/color][color=#008000]; 注意:这里使用的是原始版本的异常处理 [/color][color=#800080]80887b9d [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; pDispatcherContext [/color][color=#800080]80887ba0 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; pContext [/color][color=#800080]80887ba3 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration [/color][color=#800080]80887ba6 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRecord [/color][color=#800080]80887ba9 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]18h[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRoutine [/color][color=#800080]80887bac [/color][color=#0A246A]call [/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRoutine(...),即 pExceptionRegistration->handler(...) [/color][color=#800080]80887bae [/color][color=#0A246A]mov [/color][color=#FF8000]esp[/color][color=#0A246A],dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#800080]80887bb5 [/color][color=#0A246A]pop dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#008000]; 摘掉当前 _EXCEPTION_REGISTRATION_RECORD [/color][color=#800080]80887bbc [/color][color=#0A246A]mov [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#FF8000]ebp [/color][color=#800080]80887bbe [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#800080]80887bbf [/color][color=#0A246A]ret [/color][color=#800080]14h[/color][/font] 代码不长,主要功能也不复杂:从异常链表头开始遍历,一直遍历到指定 EXCEPTION_REGISTRATION_RECORD,对每个遍历到的 EXCEPTION_REGISTRATION_RECORD,执行 RtlpExecuteHandlerForUnwind 进行局部展开。 这段代码里有一个细节我没想明白,或者我想复杂了。在 nt!RtlUnwind 地址 80867401 处,当展开到指定 EXCEPTION_REGISTRATION 后,RtlUnwind 通过 ZwContinue 返回,而不是使用 ret 指令。通过静态分析和动态分析我都没有找到用 ZwContinue 的好处,或者不可替代的原因。如果有朋友有不同的结论,请分享一下。 在分析全局展开时发生一件很囧的事,我反汇编完成,梳理流程的时候,总感觉“这个逻辑怎么这么熟悉,貌似在哪见过~ 难道 wrk 里有源码?”,翻开 wrk,果然有…… 不过话说回来,在反汇编分析过程让我对一些细节理解的更深刻了(也只能这么安慰自己了……)。 下面我们来看看局部展开。 在前面讲 PassThrough!_except_handler4 时,有提到该函数既负责处理异常也负责局部展开。其区分功能的标志就是判断 EXCEPTION_RECORD::ExceptionFlags 是否包含 EXCEPTION_UNWIND 标志位。可以参考 PassThrough!_except_handler4 中地址为 f87203dc 的指令: f87203dc test byte ptr [eax+4],66h ; pExceptionRecord->ExceptionFlags & EXCEPTION_UNWIND,判断是异常处理过程还是展开过程 该标志是在 RtlUnwind 中被设置的,可以参考 RtlUnwind 中地址为 808673b7 和 808673bd 出的指令: 808673b7 or dword ptr [esi+4],2 ; l_ExceptionRecord.ExceptionFlags |= EXCEPTION_UNWINDING (0x2) 808673bd or dword ptr [esi+4],6 ; l_ExceptionRecord.ExceptionFlags |= EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND (0x2 | 0x4) 反汇编代码: 首先是我整理的 _EH4_LocalUnwind 的原型: VOID fastcall _EH4_LocalUnwind( PEXCEPTION_REGISTRATION pExceptionRegistartion, ULONG ulUntilTryLevel ) [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_EH4_LocalUnwind PassThrough!_EH4_LocalUnwind [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]529[/color][color=#0A246A]]: [/color][color=#000000]f8720614 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#000000]f8720615 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ebp = pExceptionRegistartion->_ebp [/color][color=#000000]f8720619 [/color][color=#0A246A]push [/color][color=#FF8000]edx [/color][color=#008000]; ulUntilTryLevel [/color][color=#000000]f872061a [/color][color=#0A246A]push [/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistartion [/color][color=#000000]f872061b [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; push __security_cookie [/color][color=#000000]f872061f [/color][color=#0A246A]call [/color][color=#000000]PassThrough!_local_unwind4 [/color][color=#0A246A]([/color][color=#000000]f87204ec[/color][color=#0A246A]) [/color][color=#000000]f8720624 [/color][color=#0A246A]add [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]0Ch [/color][color=#000000]f8720627 [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#000000]f8720628 [/color][color=#0A246A]ret [/color][color=#800080]8 [/color][color=#000000]PassThrough!_EH4_LocalUnwind 的原型: VOID local_unwind4[/color][color=#0A246A]( [/color][color=#000000]PEXCEPTION_REGSTRATION pExceptionRegstration[/color][color=#0A246A], [/color][color=#000000]ULONG ulUntilTryLevel [/color][color=#0A246A]) [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_local_unwind4 PassThrough!_local_unwind4 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]177[/color][color=#0A246A]]: [/color][color=#000000]f87204ec [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#000000]f87204ed [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#000000]f87204ee [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#000000]f87204ef [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; edx = __security_cookie [/color][color=#000000]f87204f3 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistartion [/color][color=#000000]f87204f7 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]18h[/color][color=#0A246A]] [/color][color=#008000]; ecx = ulUntilTryLevel [/color][color=#000000]f87204fb [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#000000]f87204fc [/color][color=#0A246A]push [/color][color=#FF8000]edx [/color][color=#008000]; __security_cookie [/color][color=#000000]f87204fd [/color][color=#0A246A]push [/color][color=#FF8000]eax [/color][color=#008000]; pExceptionRegistartion [/color][color=#000000]f87204fe [/color][color=#0A246A]push [/color][color=#FF8000]ecx [/color][color=#008000]; ulUntilTryLevel [/color][color=#000000]f87204ff [/color][color=#0A246A]push [/color][color=#FF8000]ecx [/color][color=#008000]; 这里压入的值后续被 f8720513 处的指令修改 [/color][color=#000000]f8720500 [/color][color=#0A246A]push offset [/color][color=#000000]PassThrough!_unwind_handler4 [/color][color=#0A246A]([/color][color=#000000]f872056f[/color][color=#0A246A]) [/color][color=#008000]; _EXCEPTION_REGISTRATION_RECORD::handler [/color][color=#000000]f8720505 [/color][color=#0A246A]push dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#008000]; _EXCEPTION_REGISTRATION_RECORD::prev, 注意这里使用的是原始版本 [/color][color=#000000]f872050c [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#000000]PassThrough!__security_cookie [/color][color=#0A246A]([/color][color=#000000]f87220b0[/color][color=#0A246A])] [/color][color=#000000]f8720511 [/color][color=#0A246A]xor [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]esp [/color][color=#008000]; 这里是用 esp 来异或,而 esp 此时指向新 _EXCEPTION_REGISTRATION_RECORD [/color][color=#000000]f8720513 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; [esp+8] 被赋予加密后的 __security_cookie [/color][color=#000000]f8720517 [/color][color=#0A246A]mov dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]],[/color][color=#FF8000]esp [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x32 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]209[/color][color=#0A246A]]: >> [/color][color=#000000]f872051e [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]30h[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistartion [/color][color=#0A246A]:: [/color][color=#000000]f8720522 [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ebx = pExceptionRegistration->scopetable, 将 ebx 假称为 l_pCurScopeEntry [/color][color=#0A246A]:: [/color][color=#000000]f8720525 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]2Ch[/color][color=#0A246A]] [/color][color=#008000]; ecx = &__security_cookie [/color][color=#0A246A]:: [/color][color=#000000]f8720529 [/color][color=#0A246A]xor [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]] [/color][color=#008000]; 解密 scopetable [/color][color=#0A246A]:: [/color][color=#000000]f872052b [/color][color=#0A246A]mov [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRegistration->trylevel [/color][color=#0A246A]:: [/color][color=#000000]f872052e [/color][color=#0A246A]cmp [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; cmp pExceptionRegistration->trylevel,TRYLEVEL_NONE [/color][color=#0A246A]< :: [/color][color=#000000]f8720531 [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x75 [/color][color=#0A246A]([/color][color=#000000]f8720561[/color][color=#0A246A]) [/color][color=#008000]; pExceptionRegistration->trylevel 等于 TRYLEVEL_NONE,无需遍历,返回 [/color][color=#0A246A]: :: : :: [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x47 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]216[/color][color=#0A246A]]: : :: [/color][color=#000000]f8720533 [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]34h[/color][color=#0A246A]] [/color][color=#008000]; edx = ulUntilTryLevel [/color][color=#0A246A]: :: [/color][color=#000000]f8720537 [/color][color=#0A246A]cmp [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; cmp ulUntilTryLevel, TRYLEVEL_NONE [/color][color=#0A246A]:< :: [/color][color=#000000]f872053a [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x54 [/color][color=#0A246A]([/color][color=#000000]f8720540[/color][color=#0A246A]) :: :: :: :: [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x50 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]219[/color][color=#0A246A]]: :: :: [/color][color=#000000]f872053c [/color][color=#0A246A]cmp [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]edx [/color][color=#008000]; cmp pExceptionRegistration->trylevel, ulUntilTryLevel [/color][color=#0A246A]::<:: [/color][color=#000000]f872053e [/color][color=#0A246A]jbe [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x75 [/color][color=#0A246A]([/color][color=#000000]f8720561[/color][color=#0A246A]) [/color][color=#008000]; 已经遍历到指定 scopetable_entry 了,返回 [/color][color=#0A246A]::::: ::::: [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x54 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]221[/color][color=#0A246A]]: :>::: [/color][color=#000000]f8720540 [/color][color=#0A246A]lea [/color][color=#FF8000]esi[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]] : ::: [/color][color=#000000]f8720543 [/color][color=#0A246A]lea [/color][color=#FF8000]ebx[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; ebx - pExceptionRegistration->scopetable[pExceptionRegistration->trylevel] [/color][color=#0A246A]: ::: [/color][color=#000000]f8720547 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]] [/color][color=#008000]; ecx = l_pCurScopeEntry->previousTryLevel [/color][color=#0A246A]: ::: [/color][color=#000000]f8720549 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistration->trylevel = ebx->l_pCurScopeEntry->previousTryLevel [/color][color=#0A246A]: ::: [/color][color=#000000]f872054c [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; cmp pExceptionRegistration->lpfnFilter,NULL [/color][color=#0A246A]: :<: [/color][color=#000000]f8720550 [/color][color=#0A246A]jne [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x32 [/color][color=#0A246A]([/color][color=#000000]f872051e[/color][color=#0A246A]) : : : : : : [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x66 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]240[/color][color=#0A246A]]: : : : [/color][color=#000000]f8720552 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#0A246A]: : : [/color][color=#000000]f8720557 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration->lpfnHandler [/color][color=#0A246A]: : : [/color][color=#000000]f872055a [/color][color=#0A246A]call [/color][color=#000000]PassThrough!_NLG_Call [/color][color=#0A246A]([/color][color=#000000]f8720630[/color][color=#0A246A]) [/color][color=#008000]; 调用 pExceptionRegistration->lpfnHandler [/color][color=#0A246A]: : < [/color][color=#000000]f872055f [/color][color=#0A246A]jmp [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x32 [/color][color=#0A246A]([/color][color=#000000]f872051e[/color][color=#0A246A]) : : : : [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x75 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]248[/color][color=#0A246A]]: > > [/color][color=#000000]f8720561 [/color][color=#0A246A]pop dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#000000]f8720568 [/color][color=#0A246A]add [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]18h [/color][color=#000000]f872056b [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#000000]f872056c [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#000000]f872056d [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#000000]f872056e [/color][color=#0A246A]ret [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_NLG_Call PassThrough!_NLG_Call [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\nlgsupp.asm @ [/color][color=#800080]120[/color][color=#0A246A]]: [/color][color=#000000]f8720630 [/color][color=#0A246A]call [/color][color=#FF8000]eax [/color][color=#000000]f8720632 [/color][color=#0A246A]ret [/color][/font] PassThrough!_EH4_LocalUnwind 中 f8720500 处的指令用到的异常处理函数 PassThrough!_unwind_handler4 的反汇编代码: [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_unwind_handler4 PassThrough!_unwind_handler4 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]294[/color][color=#0A246A]]: [/color][color=#000000]f872056f [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRecord [/color][color=#000000]f8720573 [/color][color=#0A246A]test dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6 [/color][color=#008000]; test pExceptionRecord->ExceptionFlags, EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND [/color][color=#000000]f872057a [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#008000]; eax = ExceptionContinueSearch (1) [/color][color=#000000]f872057f [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_unwind_handler4[/color][color=#0A246A]+[/color][color=#800080]0x45 [/color][color=#0A246A]([/color][color=#000000]f87205b4[/color][color=#0A246A]) [/color][color=#000000]PassThrough!_unwind_handler4[/color][color=#0A246A]+[/color][color=#800080]0x12 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]307[/color][color=#0A246A]]: [/color][color=#008000]; 在展开过程中又触发了异常,那么处理该新异常(实际操作只是做展开,即清理掉该异常占用的资源,并没有真正处理该异常) [/color][color=#000000]f8720581 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration [/color][color=#000000]f8720585 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ecx = __security_cookie, 注意这里不是 __pExceptionRegistration->scopetable [/color][color=#000000]f8720588 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#008000]; 这里用 pExceptionRegistration 解密,PassThrough!_local_unwind4 中也正是用它进行加密的 ; 参考 f8720511 处的指令 [/color][color=#000000]f872058a [/color][color=#0A246A]call [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A]) [/color][color=#000000]f872058f [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#000000]f8720590 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]18h[/color][color=#0A246A]] [/color][color=#008000]; eax+18h 是被 PassThrough!_local_unwind4 压入栈的 ebp, ; 参考 f87204fb 处的指令 [/color][color=#000000]f8720593 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; push ulUntilTryLevel [/color][color=#000000]f8720596 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistartion [/color][color=#000000]f8720599 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; __security_cookie [/color][color=#000000]f872059c [/color][color=#0A246A]call [/color][color=#000000]PassThrough!_local_unwind4 [/color][color=#0A246A]([/color][color=#000000]f87204ec[/color][color=#0A246A]) [/color][color=#000000]f87205a1 [/color][color=#0A246A]add [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]0Ch [/color][color=#000000]f87205a4 [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#000000]f87205a5 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration [/color][color=#000000]f87205a9 [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; edx = pDispatcherContext (调整 pDispatcherContext,改变遍历顺序) [/color][color=#000000]f87205ad [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; pDispatcherContext->RegistrationPointer = pExceptionRegistration [/color][color=#000000]f87205af [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]3 [/color][color=#008000]; eax = ExceptionCollidedUnwind (3) [/color][color=#000000]PassThrough!_unwind_handler4[/color][color=#0A246A]+[/color][color=#800080]0x45 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]336[/color][color=#0A246A]]: [/color][color=#000000]f87205b4 [/color][color=#0A246A]ret [/color][/font] 到这里概要流程就讲完了。在处理异常和展开过程中多处涉及到遍历操作,咱们来总结一下这些遍历操作。 1. 在异常处理过程中,每个被"卷入是非"的异常都至少会遍历异常链表两次(如果发生嵌套异常,比如在展开过程中 EXCEPTION_REGISTRATION_RECORD::Handler 又触发异常,则会遍历更多次。不过这也可以算作是一个新异常了。看如何理解。)。 一次是在 RtlDispatchException 中,遍历的目的是找到愿意处理该异常的 _EXCEPTION_REGISTRATION_RECORD。 另一次是在展开过程中、RtlUnwind 函数内,遍历的目录是为了对每个遍历到的 EXCEPTION_REGISTRATION_RECORD 进行局部展开。 2. 同样的,每个被"卷入是非"的异常的 scopetable 也会被遍历至少两次, 一次是在 modulename!_except_handler? 中,遍历目的也是找到愿意处理该异常的 scopetable_entry。 另一次是在展开过程中、_local_unwind4 函数内,遍历的目的是找到所有指定范围内的 scopetable_entry::lpfnFilter 为 NULL 的 scopetable_entry,调用它们的 lpfnHandler (即 __finally 处理块)。 在展开过程中,__finally 代码块会被执行,在执行过程中有可能触发新的异常,增强版通过返回 ExceptionCollidedUnwind (3) 来标识这种情况(参考 PassThrough!_unwind_handler4 中 f87205af 处的指令)。咱来回顾下这类返回值: [font=Consolas][color=#000000] [/color][color=#0A246A]typedef [/color][color=#000000]enum _EXCEPTION_DISPOSITION { ExceptionContinueExecution[/color][color=#0A246A], [/color][color=#000000]ExceptionContinueSearch[/color][color=#0A246A], [/color][color=#000000]ExceptionNestedException[/color][color=#0A246A], [/color][color=#000000]ExceptionCollidedUnwind } EXCEPTION_DISPOSITION[/color][color=#008000]; [/color][/font] 前面的代码中已经展示了上述4中的三种: ExceptionContinueExecution 表示继续执行(异常已经被修复); ExceptionContinueSearch 表示继续搜索(当前搜索到的异常注册信息不处理); ExceptionCollidedUnwind 表示在展开过程中再次触发异常。 ExceptionNestedException 呢?到目前咱们还没有遇到过,什么情况会用到它? 从字面上看 ExceptionNestedException 大概意思是“嵌套的异常”,是不是可以理解为“处理异常过程中再次触发的异常”?比如类似于 ExceptionCollidedUnwind,只不过 ExceptionCollidedUnwind 是在展开过程。而 ExceptionNestedException 是在处理异常过程中? 咱们顺着这个思路去寻找,首先来看 PassThrough!_except_handler4,它是异常处理的入口了。处理和展开都是它负责的。可是翻遍了它和它的工具函数的反汇编码也没有找到它直接返回或者通过注册异常处理信息来间接返回。于是我决定继续向上层即调用者方向搜寻,于是找到了如下汇编码: [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf RtlpExecuteHandlerForException nt!RtlpExecuteHandlerForException [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]87[/color][color=#0A246A]]: [/color][color=#800080]80887b4c [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],offset [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x3a [/color][color=#0A246A]([/color][color=#800080]80887bc2[/color][color=#0A246A]) [/color][color=#800080]80887b51 [/color][color=#0A246A]jmp [/color][color=#000000]nt!ExecuteHandler [/color][color=#0A246A]([/color][color=#800080]80887b5c[/color][color=#0A246A]) [/color][color=#000000]nt!ExecuteHandler [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]160[/color][color=#0A246A]]: [/color][color=#800080]80887b5c [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#800080]80887b5d [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#800080]80887b5e [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#800080]80887b5f [/color][color=#0A246A]xor [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#800080]80887b61 [/color][color=#0A246A]xor [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#800080]80887b63 [/color][color=#0A246A]xor [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi [/color][color=#800080]80887b65 [/color][color=#0A246A]xor [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#800080]80887b67 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#800080]80887b6b [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#800080]80887b6f [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#800080]80887b73 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#800080]80887b77 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#800080]80887b7b [/color][color=#0A246A]call [/color][color=#000000]nt!ExecuteHandler2 [/color][color=#0A246A]([/color][color=#800080]80887b88[/color][color=#0A246A]) [/color][color=#800080]80887b80 [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#800080]80887b81 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#800080]80887b82 [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#800080]80887b83 [/color][color=#0A246A]ret [/color][color=#800080]14h [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf ExecuteHandler2 nt!ExecuteHandler2 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]188[/color][color=#0A246A]]: [/color][color=#800080]80887b88 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#800080]80887b89 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp [/color][color=#800080]80887b8b [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#800080]80887b8e [/color][color=#0A246A]push [/color][color=#FF8000]edx [/color][color=#800080]80887b8f [/color][color=#0A246A]push dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#800080]80887b96 [/color][color=#0A246A]mov dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]],[/color][color=#FF8000]esp [/color][color=#008000]; 注册新的异常处理结构 [/color][color=#800080]80887b9d [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#800080]80887ba0 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#800080]80887ba3 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#800080]80887ba6 [/color][color=#0A246A]push dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#800080]80887ba9 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]18h[/color][color=#0A246A]] [/color][color=#800080]80887bac [/color][color=#0A246A]call [/color][color=#FF8000]ecx [/color][color=#800080]80887bae [/color][color=#0A246A]mov [/color][color=#FF8000]esp[/color][color=#0A246A],dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#800080]80887bb5 [/color][color=#0A246A]pop dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]] [/color][color=#800080]80887bbc [/color][color=#0A246A]mov [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#FF8000]ebp [/color][color=#800080]80887bbe [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#800080]80887bbf [/color][color=#0A246A]ret [/color][color=#800080]14h [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf [/color][color=#800080]80887bc2 [/color][color=#008000]; ExecuteHandler2 使用的异常处理函数 [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x3a [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]268[/color][color=#0A246A]]: [/color][color=#800080]80887bc2 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#800080]80887bc6 [/color][color=#0A246A]test dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6 80887bcd [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#008000]; eax = ExceptionContinueSearch (1) [/color][color=#800080]80887bd2 [/color][color=#0A246A]jne [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x5e [/color][color=#0A246A]([/color][color=#800080]80887be6[/color][color=#0A246A]) [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x4c [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]279[/color][color=#0A246A]]: [/color][color=#800080]80887bd4 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#800080]80887bd8 [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#800080]80887bdc [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#800080]80887bdf [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#800080]80887be1 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]2 [/color][color=#008000]; eax = ExceptionNestedException (2) [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x5e [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]287[/color][color=#0A246A]]: [/color][color=#800080]80887be6 [/color][color=#0A246A]ret [/color][color=#800080]10h [/color][/font] RtlpExecuteHandlerForException 函数是在 RtlDispatchException 中被调用。RtlDispatchException 在遍历异常链过程中并不直接调用 EXCEPTION_REGISTRATION_RECORD::Handler,而是通过 RtlpExecuteHandlerForException 来间接调用。RtlpExecuteHandlerForException 通过 ExecuteHandler2 建立一个异常处理块。 PassThrough!_except_handler4 处理异常的过程中,如果再次触发异常,则会由地址为 80887bc2 的异常处理函数返回 ExceptionNestedException。因为这几个函数都很简单,而且跟之前分析的函数很类似,不再赘述。 分析完这些,我有个疑问还是没有解开,我个人一直很奇怪增强版的使用方式为何不能这样: __try { } __except() { } __finally { } 其中 __except 过滤块和处理块可以省略。 但是很遗憾,MSC 中 __except 和 __finally 只能选其一。(当然,咱们可以用双层 __try 来实现同样的效果,但是总感觉不太爽,特别是会导致代码块被迫缩进两次) 在分析的过程中我也发现我希望的这种方式更合理一些,__except 负责处理异常,在处理异常代码中被执行。如果没有处理异常,那么在展开过程中 __finally 代码块被执行,做一些清理操作。这样两者都存在,各负责各的,不是更好吗?不知道是不是什么历史原因。 还有一个地方我也觉得不太完美。我们分析原始版本的时候发现,原始版本自身并没有直接使用展开,RtlDispatchException 等异常处理函数并没有直接调用 RtlUnwind。后者实际上是在增强版中才用到。我个人感觉这种模型并不完美,原始版本并没有自成体系,而是与增强版纠结在一起,没有很好的分层。 另外,在实际应用中 SEH 机制可能会导致很难分析的内存泄漏。我们来看一个例子, 调用流程:func1 -> func2 其中,func1 的代码如下: VOID Func1() { __try { Func2(); } __except(EXCEPTION_EXECUTE_HANDLER) { // 一些善后处理 } } Func2 没有应用 SEH,它申请了一块内存,对这块内存进行操作,然后释放该内存。但是在操作内存时候触发异常,异常被 Func1 处理了,但是因为 Func2 没有 __finally 处理块,于是展开过程中 Func2 并没有机会去释放这块内存。结果就是:程序依然“正常”的在运行,但是实际上已经造成内存泄漏。随着程序执行,泄漏的资源可能越来越多。最后导致严重的系统故障。 遇到这种问题,程序猿通过静态分析是很难找到泄漏的原因的。 到这里差不多就啰嗦完了。最后,来一段总结。 本文只是我分析 x86 下 windows 异常处理机制过程的一些笔记的集合。因为兴趣的原因,我只分析了内核部分,应用层 SEH 我没有琢磨。感兴趣的朋友可以参考《软件调试》中的相关内容,貌似挺详细的。 后续我会抽时间再琢磨琢磨 x64 下 windows 的异常处理机制,前段时间查阅 x64 资料的时候看到其异常处理机制调整了很多,比如 EXCEPTION_REGISTRATION 不在是放在栈上,而是做成表。如果内部实现改变的较多,我会再写一份笔记来分享。sinister 师傅有过这么一段话,我很认同: “交流都是建立在平等的基础上,在抱怨氛围和环境不好的同时应该先想一想自己究竟付出了多少?只知索取不愿付出的人也就不用抱怨了,要怪也只能怪自己。发自己心得的人无非是两种目的,一是引发一些讨论,好纠正自己错误的认识,以便从中获取更多的知识使自己进步的更快。二是做一份备忘,当自己遗忘的时候能够马上找到相关资料。” 其中提到的两种目的我都有 :-) 还是那句老话,FIXME。 |
|
[原创]SEH分析笔记(X86篇)
二、MSC 提供的 EXCEPTION_REGISTRATION::handler 函数 之前咱们有说过 EXCEPTION_REGISTRATION::handler 指向由 MSC 编译器提供的一个函数,这个函数内部负责调用 scopetable[?]->lpfnFilter/lpfnHandler。这个函数通常为 module!_except_handler?,其中module为模块名,? 表示某数字。在分析过程中发现,有的模块完整实现了该函数,有的模块直接使用了系统提供的 nt!_except_handler?。不知道是因为版本的问题,还是编译选项的问题。我没有深究。 我继续以 passhThrough 模块为例,来说明这个函数。 首先需要再次说明一下我的注释习惯:后续列出来的反汇编代码中,最左边的:<>符号表示跳转,是我在分析的过程中为了方便理解流程手写的。其中 < 表示跳转源,> 是跳转目标,: 用于组成连接线。 为了方便对照,我把经过整理的 PassThrough!_except_handler4 的原型列在这里: EXCEPTION_DISPOSITION _except_handler4 ( PEXCEPTION_RECORD pExceptionRecord, PEXCEPTION_REGISTRATION pExceptionRegistration, PCONTEXT, PDISPATCHER_CONTEXT ); 反汇编代码: [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_except_handler4 PassThrough!_except_handler4 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]255[/color][color=#0A246A]]: [/color][color=#000000]f8720390 [/color][color=#0A246A]mov [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#000000]f8720392 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#000000]f8720393 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp [/color][color=#000000]f8720395 [/color][color=#0A246A]sub [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]14h [/color][color=#000000]f8720398 [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#000000]f8720399 [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; ebx = pExceptionRegistration [/color][color=#000000]f872039c [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#000000]f872039d [/color][color=#0A246A]mov [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRegistration->scopetable [/color][color=#000000]f87203a0 [/color][color=#0A246A]xor [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#000000]PassThrough!__security_cookie [/color][color=#0A246A]([/color][color=#000000]f87220b0[/color][color=#0A246A])] [/color][color=#008000]; 用 __security_cookie 对 scopetable 解密 [/color][color=#000000]f87203a6 [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#000000]f87203a7 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]] [/color][color=#000000]f87203a9 [/color][color=#0A246A]mov byte ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]1[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; ebp-1 存放的是一个 BOOLEAN 值,用来表示是否执行过任何 scopetable_entry::lpfnFilter [/color][color=#000000]f87203ad [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#800080]1 [/color][color=#008000]; ebp-8 被用来存放本函数的返回值,这里初始化为 ExceptionContinueSearch (1) [/color][color=#000000]f87203b4 [/color][color=#0A246A]lea [/color][color=#FF8000]edi[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; edi = pExceptionRegistration->_ebp [/color][color=#000000]f87203b7 [/color][color=#0A246A]cmp [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; 检查 scopetable 中坑的第一个 DWORD 值,后续来做相关的安全处理 [/color][color=#0A246A]< [/color][color=#000000]f87203ba [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x39 [/color][color=#0A246A]([/color][color=#000000]f87203c9[/color][color=#0A246A]) : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x2c [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]315[/color][color=#0A246A]]: : [/color][color=#008000]; 校验 scopetable 完整性(1) [/color][color=#0A246A]: [/color][color=#000000]f87203bc [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] : [/color][color=#000000]f87203bf [/color][color=#0A246A]add [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#0A246A]: [/color][color=#000000]f87203c1 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]] : [/color][color=#000000]f87203c4 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A]) : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x39 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]315[/color][color=#0A246A]]: : [/color][color=#008000]; 校验 scopetable 完整性(2) [/color][color=#0A246A]> [/color][color=#000000]f87203c9 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#000000]f87203cc [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#000000]f87203cf [/color][color=#0A246A]add [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#000000]f87203d1 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]] [/color][color=#000000]f87203d4 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A]) [/color][color=#008000]; 安全工作处理完毕,开始进入异常处理流程 [/color][color=#000000]f87203d9 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRecord [/color][color=#000000]f87203dc [/color][color=#0A246A]test byte ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]66h [/color][color=#008000]; pExceptionRecord->ExceptionFlags & EXCEPTION_UNWIND,判断是异常处理过程还是展开过程 [/color][color=#0A246A]< [/color][color=#000000]f87203e0 [/color][color=#0A246A]jne [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x138 [/color][color=#0A246A]([/color][color=#000000]f87204c8[/color][color=#0A246A]) : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x56 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]331[/color][color=#0A246A]]: : [/color][color=#008000]; 异常处理过程 [/color][color=#0A246A]: [/color][color=#000000]f87203e6 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; ecx = pContext [/color][color=#0A246A]: [/color][color=#000000]f87203e9 [/color][color=#0A246A]lea [/color][color=#FF8000]edx[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]14h[/color][color=#0A246A]] : [/color][color=#000000]f87203ec [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#FF8000]edx [/color][color=#008000]; ebx-4 是创建 EXCEPTION_REGISTRATION 时候预留的 xpointers 的空间,这里给它赋值 [/color][color=#0A246A]: [/color][color=#000000]f87203ef [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; ebx = pExceptionRegistration->trylevel [/color][color=#0A246A]: [/color][color=#000000]f87203f2 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]14h[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; [ebp-14] = pExceptionRecord,即 xpointers->ExceptionRecord = pExceptionRecord [/color][color=#0A246A]: [/color][color=#000000]f87203f5 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]10h[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; [ebp-10] = pContext,即 xpointers->ContextRecord = pContext [/color][color=#0A246A]: [/color][color=#000000]f87203f8 [/color][color=#0A246A]cmp [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; cmp pExceptionRegistration->trylevel, TRYLEVEL_INVALID [/color][color=#0A246A]: < [/color][color=#000000]f87203fb [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xcc [/color][color=#0A246A]([/color][color=#000000]f872045c[/color][color=#0A246A]) : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x6d [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]341[/color][color=#0A246A]]: : : [/color][color=#000000]f87203fd [/color][color=#0A246A]lea [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]ecx[/color][color=#0A246A]] : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x70 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]343[/color][color=#0A246A]]: : : > [/color][color=#000000]f8720400 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]ebx[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]] [/color][color=#008000]; 这里 *3,下面紧接着 *4,即 *12,实际上是为了跳过 x 个 scopetable_entry (大小为12个字节) [/color][color=#0A246A]: : : [/color][color=#000000]f8720403 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]eax[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; ecx = scopetable[i].lpfnFilter, 这里14h是为了跳过10h大小的坑 [/color][color=#0A246A]: : : [/color][color=#000000]f8720407 [/color][color=#0A246A]lea [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]eax[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; eax = &scopetable[i] [/color][color=#0A246A]: : : [/color][color=#000000]f872040b [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; ebp-0Ch 存放的是 pCurrentScopeTableEntry [/color][color=#0A246A]: : : [/color][color=#000000]f872040e [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]] [/color][color=#008000]; eax = scopetable[i].previousTryLevel [/color][color=#0A246A]: : : [/color][color=#000000]f8720410 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; 这里是将 ebp+8 当作局部变量使用, [ebp+8] = scopetable[i].previousTryLevel [/color][color=#0A246A]: : : [/color][color=#000000]f8720413 [/color][color=#0A246A]test [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#008000]; 判断 scopetable[i].lpfnFilter 是否为 NULL [/color][color=#0A246A]: : < : [/color][color=#000000]f8720415 [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x9b [/color][color=#0A246A]([/color][color=#000000]f872042b[/color][color=#0A246A]) : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x87 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]355[/color][color=#0A246A]]: : : : : [/color][color=#008000]; scopetable[i].lpfnFilter 不为 NULL,调用它 [/color][color=#0A246A]: : : : [/color][color=#000000]f8720417 [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#008000]; edx = pExceptionRegistration->_ebp [/color][color=#0A246A]: : : : [/color][color=#000000]f8720419 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!_EH4_CallFilterFunc [/color][color=#0A246A]([/color][color=#000000]f87205d1[/color][color=#0A246A]) : : : : [/color][color=#000000]f872041e [/color][color=#0A246A]mov byte ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]1[/color][color=#0A246A]],[/color][color=#800080]1 [/color][color=#008000]; [ebp-1] 表示是否执行过 lpfnFilter,它是个 BOOLEAN 值 [/color][color=#0A246A]: : : : [/color][color=#000000]f8720422 [/color][color=#0A246A]test [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#0A246A]: : : < : [/color][color=#000000]f8720424 [/color][color=#0A246A]jl [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xd6 [/color][color=#0A246A]([/color][color=#000000]f8720466[/color][color=#0A246A]) [/color][color=#008000]; 如果是 EXCEPTION_CONTINUE_EXECUTION (-1) 就跳 [/color][color=#0A246A]: : : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x96 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]370[/color][color=#0A246A]]: : : : : < : [/color][color=#000000]f8720426 [/color][color=#0A246A]jg [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xdf [/color][color=#0A246A]([/color][color=#000000]f872046f[/color][color=#0A246A]) [/color][color=#008000]; 如果是 EXCEPTION_EXECUTE_HANDLER (1) 就跳 [/color][color=#0A246A]: : : : : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x98 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]370[/color][color=#0A246A]]: : : : : : : [/color][color=#008000]; lpfnFilter 返回 EXCEPTION_CONTINUE_SEARCH [/color][color=#0A246A]: : : : : : [/color][color=#000000]f8720428 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = scopetable[i].previousTryLevel [/color][color=#0A246A]: : : : : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x9b [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]341[/color][color=#0A246A]]: : : > : : : [/color][color=#000000]f872042b [/color][color=#0A246A]mov [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#0A246A]: : : : : [/color][color=#000000]f872042d [/color][color=#0A246A]cmp [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; cmp scopetable[i].previousTryLevel, TRYLEVEL_INVALID [/color][color=#0A246A]: : : : < [/color][color=#000000]f8720430 [/color][color=#0A246A]jne [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x70 [/color][color=#0A246A]([/color][color=#000000]f8720400[/color][color=#0A246A]) : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xa2 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]478[/color][color=#0A246A]]: : : : : [/color][color=#000000]f8720432 [/color][color=#0A246A]cmp byte ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]1[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; 没有执行过 lpfnFilter,无需进行安全检查 [/color][color=#0A246A]: : < : : [/color][color=#000000]f8720436 [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xcc [/color][color=#0A246A]([/color][color=#000000]f872045c[/color][color=#0A246A]) : : : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xa8 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]486[/color][color=#0A246A]]: : : : : : [/color][color=#008000]; 执行过 lpfnFilter,需要校验完整性 [/color][color=#0A246A]: : : : : > > [/color][color=#000000]f8720438 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]] : : : : : : : [/color][color=#000000]f872043a [/color][color=#0A246A]cmp [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; 根据 scopetable 坑的第一个 DWORD 值判断是否需要做进一步的安全检查 [/color][color=#0A246A]: : : : : < : : [/color][color=#000000]f872043d [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xbc [/color][color=#0A246A]([/color][color=#000000]f872044c[/color][color=#0A246A]) : : : : : : : : : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xaf [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]486[/color][color=#0A246A]]: : : : : : : : : [/color][color=#008000]; 校验 scopetable 完整性(1) [/color][color=#0A246A]: : : : : : : : [/color][color=#000000]f872043f [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] : : : : : : : : [/color][color=#000000]f8720442 [/color][color=#0A246A]add [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#0A246A]: : : : : : : : [/color][color=#000000]f8720444 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]] : : : : : : : : [/color][color=#000000]f8720447 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A]) : : : : : : : : : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xbc [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]486[/color][color=#0A246A]]: : : : : : : : : [/color][color=#008000]; 校验 scopetable 完整性(2) [/color][color=#0A246A]: : : : : > : : [/color][color=#000000]f872044c [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] : : : : : : : [/color][color=#000000]f872044f [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] : : : : : : : [/color][color=#000000]f8720452 [/color][color=#0A246A]add [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#0A246A]: : : : : : : [/color][color=#000000]f8720454 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]] [/color][color=#008000]; 正常情况下 [edx+edi] 保存的是 __security_cookie 的值 [/color][color=#0A246A]: : : : : : : [/color][color=#000000]f8720457 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A]) : : : : : : : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xcc [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]495[/color][color=#0A246A]]: : > > : : : > : [/color][color=#000000]f872045c [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]] : : : : : : [/color][color=#000000]f872045f [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#0A246A]: : : : : : [/color][color=#000000]f8720460 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#0A246A]: : : : : : [/color][color=#000000]f8720461 [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#0A246A]: : : : : : [/color][color=#000000]f8720462 [/color][color=#0A246A]mov [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#FF8000]ebp [/color][color=#0A246A]: : : : : : [/color][color=#000000]f8720464 [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#0A246A]: : : : : : [/color][color=#000000]f8720465 [/color][color=#0A246A]ret : : : : : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xd6 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]367[/color][color=#0A246A]]: : : : : : : [/color][color=#008000]; lpfnFilter 返回 EXCEPTION_CONTINUE_EXECUTION [/color][color=#0A246A]: > : : : : [/color][color=#000000]f8720466 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; [ebp-8] = ExceptionContinueExecution (0) [/color][color=#0A246A]: : < : : [/color][color=#000000]f872046d [/color][color=#0A246A]jmp [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xa8 [/color][color=#0A246A]([/color][color=#000000]f8720438[/color][color=#0A246A]) : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xdf [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]396[/color][color=#0A246A]]: : : : : [/color][color=#008000]; lpfnFilter 返回 EXCEPTION_EXECUTE_HANDLER [/color][color=#0A246A]: > : : [/color][color=#000000]f872046f [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRegistration [/color][color=#0A246A]: : : [/color][color=#000000]f8720472 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!_EH4_GlobalUnwind [/color][color=#0A246A]([/color][color=#000000]f87205fa[/color][color=#0A246A]) : : : [/color][color=#000000]f8720477 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration [/color][color=#0A246A]: : : [/color][color=#000000]f872047a [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]ebx [/color][color=#008000]; cmp pExceptionRegistration->trylevel [/color][color=#0A246A]: < : : [/color][color=#000000]f872047d [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x101 [/color][color=#0A246A]([/color][color=#000000]f8720491[/color][color=#0A246A]) : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xef [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]408[/color][color=#0A246A]]: : : : : [/color][color=#000000]f872047f [/color][color=#0A246A]push offset [/color][color=#000000]PassThrough!__security_cookie [/color][color=#0A246A]([/color][color=#000000]f87220b0[/color][color=#0A246A]) : : : : [/color][color=#000000]f8720484 [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#0A246A]: : : : [/color][color=#000000]f8720485 [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#0A246A]: : : : [/color][color=#000000]f8720487 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#008000]; ecx = pExceptionRegistration [/color][color=#0A246A]: : : : [/color][color=#000000]f8720489 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!_EH4_LocalUnwind [/color][color=#0A246A]([/color][color=#000000]f8720614[/color][color=#0A246A]) : : : : [/color][color=#000000]f872048e [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x101 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]417[/color][color=#0A246A]]: : > : : [/color][color=#000000]f8720491 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ecx = scopetable[i].previousTryLevel [/color][color=#0A246A]: : : [/color][color=#000000]f8720494 [/color][color=#0A246A]mov dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistration->trylevel = scopetable[i].previousTryLevel [/color][color=#0A246A]: : : [/color][color=#000000]f8720497 [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]] : : : [/color][color=#000000]f8720499 [/color][color=#0A246A]cmp [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#0A246A]: < : : [/color][color=#000000]f872049c [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x11b [/color][color=#0A246A]([/color][color=#000000]f87204ab[/color][color=#0A246A]) : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x10e [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]431[/color][color=#0A246A]]: : : : : [/color][color=#008000]; 校验 scopetable 完整性(1) [/color][color=#0A246A]: : : : [/color][color=#000000]f872049e [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] : : : : [/color][color=#000000]f87204a1 [/color][color=#0A246A]add [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#0A246A]: : : : [/color][color=#000000]f87204a3 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]] : : : : [/color][color=#000000]f87204a6 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A]) : : : : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x11b [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]431[/color][color=#0A246A]]: : : : : [/color][color=#008000]; 校验 scopetable 完整性(2) [/color][color=#0A246A]: > : : [/color][color=#000000]f87204ab [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] : : : [/color][color=#000000]f87204ae [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] : : : [/color][color=#000000]f87204b1 [/color][color=#0A246A]add [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#0A246A]: : : [/color][color=#000000]f87204b3 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]] : : : [/color][color=#000000]f87204b6 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A]) : : : [/color][color=#008000]; 调用 lpfnHandler [/color][color=#0A246A]: : : [/color][color=#000000]f87204bb [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; eax = l_pCurrentScopeTableEntry [/color][color=#0A246A]: : : [/color][color=#000000]f87204be [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ecx = l_pCurrentScopeTableEntry->lpfnHandler [/color][color=#0A246A]: : : [/color][color=#000000]f87204c1 [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#008000]; edx = pExceptionRegistration->_ebp [/color][color=#0A246A]: : : [/color][color=#000000]f87204c3 [/color][color=#0A246A]call [/color][color=#000000]PassThrough!_EH4_TransferToHandler [/color][color=#0A246A]([/color][color=#000000]f87205e8[/color][color=#0A246A]) [/color][color=#008000]; 这里不会返回!! [/color][color=#0A246A]: : : : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x138 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]456[/color][color=#0A246A]]: > : : [/color][color=#000000]f87204c8 [/color][color=#0A246A]mov [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#0A246A]: : [/color][color=#000000]f87204cd [/color][color=#0A246A]cmp dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]edx [/color][color=#008000]; cmp pExceptionRegistration->trylevel, TRYLEVEL_INVALID [/color][color=#0A246A]< : [/color][color=#000000]f87204d0 [/color][color=#0A246A]je [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xcc [/color][color=#0A246A]([/color][color=#000000]f872045c[/color][color=#0A246A]) : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x142 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]467[/color][color=#0A246A]]: : [/color][color=#008000]; pExceptionRegistration->trylevel 不等于 TRYLEVEL_INVALID,开始局部展开 [/color][color=#0A246A]: [/color][color=#000000]f87204d2 [/color][color=#0A246A]push offset [/color][color=#000000]PassThrough!__security_cookie [/color][color=#0A246A]([/color][color=#000000]f87220b0[/color][color=#0A246A]) : [/color][color=#000000]f87204d7 [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#008000]; pExceptionRegistration->_ebp [/color][color=#0A246A]: [/color][color=#000000]f87204d8 [/color][color=#0A246A]mov [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#008000]; ecx = pExceptionRegistration [/color][color=#0A246A]: [/color][color=#000000]f87204da [/color][color=#0A246A]call [/color][color=#000000]PassThrough!_EH4_LocalUnwind [/color][color=#0A246A]([/color][color=#000000]f8720614[/color][color=#0A246A]) < [/color][color=#000000]f87204df [/color][color=#0A246A]jmp [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xa8 [/color][color=#0A246A]([/color][color=#000000]f8720438[/color][color=#0A246A]) [/color][/font] 这个函数代码不长。主要分为两个大分支,一个分支处理异常,一个分支处理展开(参考地址 f87203dc 处的 test 指令)。 处理异常的代码负责遍历 scopetable,依次调用 scopetable_entry::lpfnFilter(参考 f8720419 处代码),并针对不同的返回值做出不同的处理: 1. 返回 EXCEPTION_CONTINUE_EXECUTION,则说明异常已经被刚刚调用的 lpfnFilter 修复。返回 ExceptionContinueExecution。 2. 返回 EXCEPTION_CONTINUE_SEARCH,则继续遍历下一个 scopetable_entry。 3. 返回 EXCEPTION_EXECUTE_HANDLER,则说明当前 scopetable_entry::lpfnHandler 负责处理该异常。于是调用它。 对于展开的代码,则直接开始局部展开,即对 scopetable 进行展开。 更具体的信息,请参考上面反汇编代码中我附的注释。 有几个小点需要说一下: 1. 该函数多处使用 scopetable 中坑内的数据进行安全检查。这些操作对理解该函数流程没有帮助,可以忽略。如果觉得上面代码不纯净,可以参考我后续的附录1《Ntfs!_except_handler3 的反汇编代码》,这个函数流程更清晰简单。 2. 一旦有某 scopetable_entry::lpfnFilter 返回 EXCEPTION_EXECUTE_HANDLER,就会进行全局展开和局部展开。展开结束后会调用该 scopetable_entry::lpfnHandler,该函数即为 _except 处理域,该函数形式是一个函数,实际上只是一段不返回的代码。即这段代码中没有 ret 指令。执行完整个 _except 处理域后,会接着执行其后的指令,并不会返回 _except_handler4。 3. 该函数既启动展开,又负责展开,于是会出现类似于“重入”的现象。理解的过程中容易扰乱思路。 PassThrough!_except_handler4 在执行过程中可能会调用这几个函数: PassThrough!_EH4_CallFilterFunc、 PassThrough!_EH4_TransferToHandler、 PassThrough!_EH4_GlobalUnwind、 PassThrough!_EH4_LocalUnwind 这几个函数名很明白的说明了它们的功能: PassThrough!_EH4_CallFilterFunc 负责调用 scopetable_entry::lpfnFilter; PassThrough!_EH4_TransferToHandler 负责调用 scopetable_entry::lpfnFilter; PassThrough!_EH4_GlobalUnwind 负责全局展开; PassThrough!_EH4_LocalUnwind 负责局部展开。 来看看 _EH4_CallFilterFunc 和 _EH4_TransferToHandler 的反汇编代码,都很短。剩余两个展开相关的函数稍后咱们再来分析。 [font=Consolas][color=#000000] kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_EH4_CallFilterFunc PassThrough!_EH4_CallFilterFunc [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]408[/color][color=#0A246A]]: [/color][color=#000000]f87205d1 [/color][color=#0A246A]push [/color][color=#FF8000]ebp [/color][color=#000000]f87205d2 [/color][color=#0A246A]push [/color][color=#FF8000]esi [/color][color=#000000]f87205d3 [/color][color=#0A246A]push [/color][color=#FF8000]edi [/color][color=#000000]f87205d4 [/color][color=#0A246A]push [/color][color=#FF8000]ebx [/color][color=#000000]f87205d5 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]edx [/color][color=#000000]f87205d7 [/color][color=#0A246A]xor [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#000000]f87205d9 [/color][color=#0A246A]xor [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#000000]f87205db [/color][color=#0A246A]xor [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edx [/color][color=#000000]f87205dd [/color][color=#0A246A]xor [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi [/color][color=#000000]f87205df [/color][color=#0A246A]xor [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#000000]f87205e1 [/color][color=#0A246A]call [/color][color=#FF8000]ecx [/color][color=#008000]; lpfnFilter(); [/color][color=#000000]f87205e3 [/color][color=#0A246A]pop [/color][color=#FF8000]ebx [/color][color=#000000]f87205e4 [/color][color=#0A246A]pop [/color][color=#FF8000]edi [/color][color=#000000]f87205e5 [/color][color=#0A246A]pop [/color][color=#FF8000]esi [/color][color=#000000]f87205e6 [/color][color=#0A246A]pop [/color][color=#FF8000]ebp [/color][color=#000000]f87205e7 [/color][color=#0A246A]ret [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_EH4_TransferToHandler PassThrough!_EH4_TransferToHandler [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]450[/color][color=#0A246A]]: [/color][color=#000000]f87205e8 [/color][color=#0A246A]mov [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]edx [/color][color=#000000]f87205ea [/color][color=#0A246A]mov [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#008000]; esi = lpfnHandler [/color][color=#000000]f87205ec [/color][color=#0A246A]mov [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#000000]f87205ee [/color][color=#0A246A]xor [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#000000]f87205f0 [/color][color=#0A246A]xor [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#000000]f87205f2 [/color][color=#0A246A]xor [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#000000]f87205f4 [/color][color=#0A246A]xor [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edx [/color][color=#000000]f87205f6 [/color][color=#0A246A]xor [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#000000]f87205f8 [/color][color=#0A246A]jmp [/color][color=#FF8000]esi [/color][color=#008000]; jmp lpfnHandler [/color][/font] 到这里,咱们就以 PassThrough!_except_handler4 为例分析完了 MSC 提供的 EXCEPTION_REGISTRATION::handler 函数。这个过程中多次接触到一个名为“展开”的概念,这就是咱们要讲的第三个部分。 |
|
[原创]SEH分析笔记(X86篇)
一、SEH 创建代码 这里我没有继续使用上面的 SimpleSeh 进行分析,而是新写了一个简单的 SehTest 函数。 [font=Consolas][color=#000000] VOID SehTest[color=#000080]() { [color=#000000]ULONG ulVal [color=#000080]= [color=#800080]0[color=#000080]; [color=#000000]__try [color=#008000]// 第一个 __try 域 [color=#000080]{ [color=#000000]ulVal [color=#000080]= [color=#800080]0x11111111[color=#000080]; [color=#008000]// 最后一位为1表示“在 __try 代码块中” [color=#000080]} [color=#000000]__except[color=#000080]([color=#000000]Filter_0[color=#000080]()) { [color=#000000]ulVal [color=#000080]= [color=#800080]0x11111110[color=#000080]; [color=#008000]// 最后一位为0表示“在 __except/__finally 代码块中” [color=#000080]} [color=#000000]__try [color=#008000]// 第二个 __try 域 [color=#000080]{ [color=#000000]ulVal [color=#000080]= [color=#800080]0x22222222[color=#000080]; [color=#000000]__try [color=#008000]// 第三个 __try 域 [color=#000080]{ [color=#000000]ulVal [color=#000080]= [color=#800080]0x33333333[color=#000080]; *(([color=#000000]ULONG[color=#000080]*)[color=#000000]NULL[color=#000080]) = [color=#000000]ulVal[color=#000080]; [color=#008000]// 触发异常 [color=#000080]} [color=#000000]__finally [color=#000080]{ [color=#000000]ulVal [color=#000080]= [color=#800080]0x33333330[color=#000080]; } } [color=#000000]__except[color=#000080]([color=#000000]Filter_2[color=#000080]()) { [color=#000000]ulVal [color=#000080]= [color=#800080]0x22222220[color=#000080]; } [color=#0000FF]return[color=#000080]; } [/font] 反汇编代码如下: (需要说明一下我的命名习惯是,"l_"前缀的变量是函数的局部变量,没有任何前缀的变量是传入的参数)
来看看 scopetable 的内容: kd> dd f8721468 f8721468 fffffffe 00000000 ffffffd4 00000000 < 16个字节的坑 f8721478 [fffffffe f8720093 f8720099] [fffffffe f8721488 f87200ed f87200f3] [00000001 00000000 f8721498 f87200dc] 00000000 00000000 00000000 f87214a8 00000000 00000000 00000000 00000000 f87214b8 00000000 00000000 00000000 00000000 f87214c8 00000000 00000000 00000000 00000000 f87214d8 00000000 00000000 00000000 00000000 前16个字节是坑,坑的作用晚点再说。之后就是三个 scopetable_entry,被我用大括号扩起来了。对照前面的汇编码可以发现,scopetable_entry::lpfnFilter 和 scopetable_entry::lpfnHandler 就是汇编码中的空洞处的代码。其中,第三个 scopetable_entry::lpfnFilter 是 NULL,对照代码可以发现,是因为这是一个 __try & __finally 块,没有 lpfnFilter。 汇编代码很简单,注释里也有详细的分析过程了,我不再多啰嗦。只提两点: 1. EXCEPTION_REGISTRATION::scopetable 指针被用 __security_cookie 进行了异或加密。 2. EXCEPTION_REGISTRATION::scopetable 并不直接指向 scopetable_entry 数组,在第一个 scopetable_entry 之前有 16 个字节的坑。后续分析中会看到,它的主要作用是帮助验证 scopetable 是否被破坏。第三个 DWORD,即上文中的 ffffffd4 是一个偏移量,后续的分析过程中会看得很清楚。 |
|
[分享]在帖子里给代码加上语法高亮
// // Exception handling procedure prototypes. // NTSYSAPI DECLSPEC_NORETURN VOID NTAPI RtlRaiseStatus ( IN NTSTATUS Status ); |
|
[分享]在帖子里给代码加上语法高亮
jyyyyyyyyyyyyyyyyyyyyyyyy |
|
|
|
[原创][2011.01 更新SDI版本]2010的留念 [开源] 发个最近写的Pe工具~
http://www.smidgeonsoft.prohosting.com/pebrowse-pro-file-viewer.html 这个PE工具也不错 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值