MSC异常处理增强设计

MSC加强的__try{}__except{}结构差不多了解了

先是压入一个结构,包含了TryLevel,Scopetable,ExceptionHandler,Next,exc_ptr(这个在只有一个try块中被跳过了),进入try块遇到异常,异常处理后进入到filter过滤函数,再视情况进入handler函数处理,处理完毕就和没有发生异常一样直接离开__try{}__except{}。

不过中间还是有一个绕不过去的_except_handler4,这个到底怎么工作的呢?怎么工作才能在发生异常之后进入到filter呢?我调试一下看看,希望能有一些收获。

产生异常时的寄存器和调用__except__handler4时的寄存器状态
eax=00000008 ebx=00dab000 ecx=00581737 edx=00b9dbb4 esi=00000000 edi=00581cf3
eip=00581042 esp=00b9f7a8 ebp=00b9f7d4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
Showx86SEH!OneException+0x42:
00581042 c70655555555    mov     dword ptr [esi],55555555h ds:002b:00000000=????????
Breakpoint 1 hit
eax=00000000 ebx=00000000 ecx=00581840 edx=77638e90 esi=00000000 edi=00000000
eip=00581840 esp=00b9f178 ebp=00b9f198 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
Showx86SEH!_except_handler4:
00581840 8bff            mov     edi,edi
Showx86SEH!_except_handler4
;0:000> u 00581840 00581915
00581840 8bff            mov     edi,edi
00581842 55              push    ebp
00581843 8bec            mov     ebp,esp
00581845 83ec18          sub     esp,18h
00581848 53              push    ebx
00581849 8b5d0c          mov     ebx,dword ptr [ebp+0Ch]
0058184c 56              push    esi
0058184d 8b7308          mov     esi,dword ptr [ebx+8]
00581850 333500705900    xor     esi,dword ptr [Showx86SEH!__security_cookie (00597000)]
00581856 57              push    edi
00581857 8b06            mov     eax,dword ptr [esi]
00581859 c645ff00        mov     byte ptr [ebp-1],0
0058185d c745f401000000  mov     dword ptr [ebp-0Ch],1
00581864 8d7b10          lea     edi,[ebx+10h]
00581867 83f8fe          cmp     eax,0FFFFFFFEh
0058186a 740d            je      Showx86SEH!_except_handler4+0x39 (00581879)
0058186c 8b4e04          mov     ecx,dword ptr [esi+4]
0058186f 03cf            add     ecx,edi
00581871 330c38          xor     ecx,dword ptr [eax+edi]
;____________________________________________________________________________
00581874 e860190000      call    Showx86SEH!__security_check_cookie (005831d9)
;____________________________________________________________________________
00581879 8b4e0c          mov     ecx,dword ptr [esi+0Ch]
0058187c 8b4608          mov     eax,dword ptr [esi+8]
0058187f 03cf            add     ecx,edi
00581881 330c38          xor     ecx,dword ptr [eax+edi]
;____________________________________________________________________________
00581884 e850190000      call    Showx86SEH!__security_check_cookie (005831d9)
;____________________以上安全检查,估计和之前进栈的加密过的eax有关___________________
00581889 8b4508          mov     eax,dword ptr [ebp+8]
0058188c f6400466        test    byte ptr [eax+4],66h
00581890 0f8519010000    jne     Showx86SEH!_except_handler4+0x16f (005819af)
00581896 8b4d10          mov     ecx,dword ptr [ebp+10h]
00581899 8d55e8          lea     edx,[ebp-18h]
0058189c 8953fc          mov     dword ptr [ebx-4],edx
0058189f 8b5b0c          mov     ebx,dword ptr [ebx+0Ch]
005818a2 8945e8          mov     dword ptr [ebp-18h],eax
005818a5 894dec          mov     dword ptr [ebp-14h],ecx
005818a8 83fbfe          cmp     ebx,0FFFFFFFEh
;___________猜测这个ebx保存的是TryLevel,不过windbg还是不是很会调试,要再观摩一下_____
;______________________这一个je直接跳转到except结束位置,有点猫腻__________________
005818ab 745f            je      Showx86SEH!_except_handler4+0xcc (0058190c)
;____________________________________________________________________________
005818ad 8d4900          lea     ecx,[ecx]
005818b0 8d045b          lea     eax,[ebx+ebx*2]
005818b3 8b4c8614        mov     ecx,dword ptr [esi+eax*4+14h]
005818b7 8d448610        lea     eax,[esi+eax*4+10h]
005818bb 8945f0          mov     dword ptr [ebp-10h],eax
005818be 8b00            mov     eax,dword ptr [eax]
005818c0 8945f8          mov     dword ptr [ebp-8],eax
005818c3 85c9            test    ecx,ecx
005818c5 7414            je      Showx86SEH!_except_handler4+0x9b (005818db)
005818c7 8bd7            mov     edx,edi
;______________________看到这个函数名字,估计就是调用filter的了____________________
;_____________________________验证了一下确实是的________________________________
005818c9 e8f4010000      call    Showx86SEH!_EH4_CallFilterFunc (00581ac2)
;____________________________这里给1有啥用呢?__________________________________
005818ce c645ff01        mov     byte ptr [ebp-1],1
;____________________________________________________________________________
005818d2 85c0            test    eax,eax
005818d4 7840            js      Showx86SEH!_except_handler4+0xd6 (00581916)
005818d6 7f47            jg      Showx86SEH!_except_handler4+0xdf (0058191f)
;________________________________这里跳转了_____________________________________

EXCEPTION_EXECUTE_HANDLER 1
EXCEPTION_CONTINUE_SEARCH 0
EXCEPTION_CONTINUE_EXECUTION -1
从中可以看出调用__Showx86SEH!_EH4_CallFilterFunc__返回了EXCEPTION_EXECUTE_HANDLER,表示可以处理好

005818d8 8b45f8          mov     eax,dword ptr [ebp-8]
005818db 8bd8            mov     ebx,eax
005818dd 83f8fe          cmp     eax,0FFFFFFFEh
005818e0 75ce            jne     Showx86SEH!_except_handler4+0x70 (005818b0)
005818e2 807dff00        cmp     byte ptr [ebp-1],0
005818e6 7424            je      Showx86SEH!_except_handler4+0xcc (0058190c)
005818e8 8b06            mov     eax,dword ptr [esi]
005818ea 83f8fe          cmp     eax,0FFFFFFFEh
005818ed 740d            je      Showx86SEH!_except_handler4+0xbc (005818fc)
;_except_handler4+143
005818ef 8b4e04          mov     ecx,dword ptr [esi+4]
005818f2 03cf            add     ecx,edi
005818f4 330c38          xor     ecx,dword ptr [eax+edi]
;____________________________________________________________________________
005818f7 e8dd180000      call    Showx86SEH!__security_check_cookie (005831d9)
;____________________________________________________________________________
005818fc 8b4e0c          mov     ecx,dword ptr [esi+0Ch]
005818ff 8b5608          mov     edx,dword ptr [esi+8]
00581902 03cf            add     ecx,edi
00581904 330c3a          xor     ecx,dword ptr [edx+edi]
;____________________________________________________________________________
00581907 e8cd180000      call    Showx86SEH!__security_check_cookie (005831d9)
;____________________________________________________________________________
0058190c 8b45f4          mov     eax,dword ptr [ebp-0Ch]
0058190f 5f              pop     edi
00581910 5e              pop     esi
00581911 5b              pop     ebx
00581912 8be5            mov     esp,ebp
00581914 5d              pop     ebp
00581915 c3              ret
Showx86SEH!_except_handler4+0xdf
;0:000> u Showx86SEH!_except_handler4+0xdf 005819aa
0058191f 8b4d08          mov     ecx,dword ptr [ebp+8]
00581922 813963736de0    cmp     dword ptr [ecx],0E06D7363h
00581928 7529            jne     Showx86SEH!_except_handler4+0x113 (00581953)
0058192a 833d8c9b590000  cmp     dword ptr [Showx86SEH!_pDestructExceptionObject (00599b8c)],0
00581931 7420            je      Showx86SEH!_except_handler4+0x113 (00581953)
00581933 688c9b5900      push    offset Showx86SEH!_pDestructExceptionObject (00599b8c)
00581938 e843190000      call    Showx86SEH!_IsNonwritableInCurrentImage (00583280)
0058193d 83c404          add     esp,4
00581940 85c0            test    eax,eax
00581942 740f            je      Showx86SEH!_except_handler4+0x113 (00581953)
00581944 8b5508          mov     edx,dword ptr [ebp+8]
00581947 6a01            push    1
00581949 52              push    edx
0058194a ff158c9b5900    call    dword ptr [Showx86SEH!_pDestructExceptionObject (00599b8c)]
00581950 83c408          add     esp,8
00581953 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
00581956 8b5508          mov     edx,dword ptr [ebp+8]
00581959 e894010000      call    Showx86SEH!_EH4_GlobalUnwind2 (00581af2)
0058195e 8b450c          mov     eax,dword ptr [ebp+0Ch]
00581961 39580c          cmp     dword ptr [eax+0Ch],ebx
00581964 7412            je      Showx86SEH!_except_handler4+0x138 (00581978)
00581966 6800705900      push    offset Showx86SEH!__security_cookie (00597000)
0058196b 57              push    edi
0058196c 8bd3            mov     edx,ebx
0058196e 8bc8            mov     ecx,eax
00581970 e896010000      call    Showx86SEH!_EH4_LocalUnwind (00581b0b)
00581975 8b450c          mov     eax,dword ptr [ebp+0Ch]
00581978 8b4df8          mov     ecx,dword ptr [ebp-8]
0058197b 89480c          mov     dword ptr [eax+0Ch],ecx
0058197e 8b06            mov     eax,dword ptr [esi]
00581980 83f8fe          cmp     eax,0FFFFFFFEh
00581983 740d            je      Showx86SEH!_except_handler4+0x152 (00581992)
00581985 8b4e04          mov     ecx,dword ptr [esi+4]
00581988 03cf            add     ecx,edi
0058198a 330c38          xor     ecx,dword ptr [eax+edi]
0058198d e847180000      call    Showx86SEH!__security_check_cookie (005831d9)
00581992 8b4e0c          mov     ecx,dword ptr [esi+0Ch]
00581995 8b5608          mov     edx,dword ptr [esi+8]
00581998 03cf            add     ecx,edi
0058199a 330c3a          xor     ecx,dword ptr [edx+edi]
0058199d e837180000      call    Showx86SEH!__security_check_cookie (005831d9)
005819a2 8b45f0          mov     eax,dword ptr [ebp-10h]
005819a5 8b4808          mov     ecx,dword ptr [eax+8]
005819a8 8bd7            mov     edx,edi
;__________________________这个函数调用了handler________________________
005819aa e82a010000      call    Showx86SEH!_EH4_TransferToHandler (00581ad9)
;____________________________________________________________________
005819af bafeffffff      mov     edx,0FFFFFFFEh
005819b4 39530c          cmp     dword ptr [ebx+0Ch],edx
005819b7 0f844fffffff    je      Showx86SEH!_except_handler4+0xcc (0058190c)
005819bd 6800705900      push    offset Showx86SEH!__security_cookie (00597000)
005819c2 57              push    edi
005819c3 8bcb            mov     ecx,ebx
005819c5 e841010000      call    Showx86SEH!_EH4_LocalUnwind (00581b0b)
005819ca e919ffffff      jmp     Showx86SEH!_except_handler4+0xa8 (005818e8)
005819cf cc              int     3