SEH不起作用的问题跟踪

关建词 _except_handler4、_except_handler3、_ValidateEH3RN


问题:

写了一个程序(shell,你懂的),发现SEH捕捉不到异常,网上搜了一下没找到相关内容,下面的代码是为了写文章简单写的例子代码

__try
{
	_asm int 3;
}
__except(1)
{
    printf("except\r\n");
}


分析:

VS2008里跟踪调试,确实没捕捉到,SEH没源码不好调,祭出OD

载入,定位到代码

012D1040 > $  55            push ebp
012D1041   .  8BEC          mov ebp,esp
012D1043   .  6A FF         push -1
012D1045   .  68 D8D02D01   push 012DD0D8
012D104A   .  68 B49A2D01   push _except_handler3igionObjecterr 'DLo>;  SE 处理程序安装
012D104F   .  64:A1 0000000>mov eax,dword ptr fs:[0]
012D1055   .  50            push eax
012D1056   .  64:8925 00000>mov dword ptr fs:[0],esp
012D105D   .  83EC 08       sub esp,8
012D1060   .  53            push ebx
012D1061   .  56            push esi
012D1062   .  57            push edi
012D1063   .  8965 E8       mov dword ptr ss:[ebp-18],esp
012D1066   .  C745 FC 00000>mov dword ptr ss:[ebp-4],0
012D106D   .  CC            int3
012D106E   .  C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
012D1075   .  EB 1D         jmp short 012D1094
012D1077   .  B8 01000000   mov eax,1
012D107C   .  C3            retn
012D107D   .  8B65 E8       mov esp,dword ptr ss:[ebp-18]
012D1080   .  68 2CCB2D01   push 012DCB2C                            ;  ASCII "except1
"
012D1085   .  E8 B7060000   call printfc_crttProcess4lockonFilterm_L>
012D108A   .  83C4 04       add esp,4
012D108D   .  C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
012D1094   >  33C0          xor eax,eax
012D1096   .  8B4D F0       mov ecx,dword ptr ss:[ebp-10]
012D1099   .  64:890D 00000>mov dword ptr fs:[0],ecx
012D10A0   .  5F            pop edi
012D10A1   .  5E            pop esi
012D10A2   .  5B            pop ebx
012D10A3   .  8BE5          mov esp,ebp
012D10A5   .  5D            pop ebp
012D10A6   .  C3            retn


可以看到代码一开始就安装了一个SEH异常处理,handler是VC内自带的 _except_handler3

转到_except_handler3(012D9AB4)下个断点,F8单步执行012D106D的 int3时触发了异常,在_except_handler3断了下来


012D9AB4 >/$  55            push ebp                                 ;  结构异常处理程序
012D9AB5  |.  8BEC          mov ebp,esp
012D9AB7  |.  83EC 08       sub esp,8
012D9ABA  |.  53            push ebx
012D9ABB  |.  56            push esi
012D9ABC  |.  57            push edi
012D9ABD  |.  55            push ebp
012D9ABE  |.  FC            cld
012D9ABF  |.  8B5D 0C       mov ebx,dword ptr ss:[ebp+C]
012D9AC2  |.  8B45 08       mov eax,dword ptr ss:[ebp+8]
012D9AC5  |.  F740 04 06000>test dword ptr ds:[eax+4],6
012D9ACC  |.  0F85 C3000000 jnz 012D9B95
012D9AD2  |.  8945 F8       mov dword ptr ss:[ebp-8],eax
012D9AD5  |.  8B45 10       mov eax,dword ptr ss:[ebp+10]
012D9AD8  |.  8945 FC       mov dword ptr ss:[ebp-4],eax
012D9ADB  |.  8D45 F8       lea eax,dword ptr ss:[ebp-8]
012D9ADE  |.  8943 FC       mov dword ptr ds:[ebx-4],eax
012D9AE1  |.  8B73 0C       mov esi,dword ptr ds:[ebx+C]
012D9AE4  |.  8B7B 08       mov edi,dword ptr ds:[ebx+8]
012D9AE7  |.  53            push ebx
012D9AE8  |.  E8 E3010000   call _ValidateEH3RNssAndSpinCountrr 'DLo>
012D9AED  |.  83C4 04       add esp,4
012D9AF0  |.  0BC0          or eax,eax
012D9AF2  |.  0F8E 8F000000 jle 012D9B87
012D9AF8  |>  83FE FF       /cmp esi,-1
012D9AFB  |.  0F84 8D000000 |je 012D9B8E
012D9B01  |.  8D0C76        |lea ecx,dword ptr ds:[esi+esi*2]
012D9B04  |.  8B448F 04     |mov eax,dword ptr ds:[edi+ecx*4+4]
012D9B08  |.  0BC0          |or eax,eax
012D9B0A  |.  74 66         |je short 012D9B72
012D9B0C  |.  56            |push esi
012D9B0D  |.  55            |push ebp
012D9B0E  |.  8D6B 10       |lea ebp,dword ptr ds:[ebx+10]
012D9B11  |.  33DB          |xor ebx,ebx
012D9B13  |.  33C9          |xor ecx,ecx
012D9B15  |.  33D2          |xor edx,edx
012D9B17  |.  33F6          |xor esi,esi
012D9B19  |.  33FF          |xor edi,edi
012D9B1B  |.  FFD0          |call eax
012D9B1D  |.  5D            |pop ebp
012D9B1E  |.  5E            |pop esi
012D9B1F  |.  8B5D 0C       |mov ebx,dword ptr ss:[ebp+C]
012D9B22  |.  0BC0          |or eax,eax
012D9B24  |.  74 4C         |je short 012D9B72
012D9B26  |.  78 58         |js short 012D9B80
012D9B28  |.  6A 01         |push 1
012D9B2A  |.  FF75 08       |push dword ptr ss:[ebp+8]
012D9B2D  |.  E8 9B000000   |call CallDestructExceptionObjecterr 'DL>
012D9B32  |.  83C4 08       |add esp,8
012D9B35  |.  8B7B 08       |mov edi,dword ptr ds:[ebx+8]
012D9B38  |.  53            |push ebx
012D9B39  |.  E8 1EF3FFFF   |call __global_unwind2ion0tabionFilterm_>
012D9B3E  |.  83C4 04       |add esp,4
012D9B41  |.  8D6B 10       |lea ebp,dword ptr ds:[ebx+10]
012D9B44  |.  56            |push esi
012D9B45  |.  53            |push ebx
012D9B46  |.  E8 76F3FFFF   |call __local_unwind2tcrit for 'DLog::m_>
012D9B4B  |.  83C4 08       |add esp,8
012D9B4E  |.  8D0C76        |lea ecx,dword ptr ds:[esi+esi*2]
012D9B51  |.  6A 01         |push 1
012D9B53  |.  8B448F 08     |mov eax,dword ptr ds:[edi+ecx*4+8]
012D9B57  |.  E8 15F4FFFF   |call _NLG_Notifylized_serrlagstertePara>
012D9B5C  |.  8B048F        |mov eax,dword ptr ds:[edi+ecx*4]
012D9B5F  |.  8943 0C       |mov dword ptr ds:[ebx+C],eax
012D9B62  |.  8B448F 08     |mov eax,dword ptr ds:[edi+ecx*4+8]
012D9B66  |.  33DB          |xor ebx,ebx
012D9B68  |.  33C9          |xor ecx,ecx
012D9B6A  |.  33D2          |xor edx,edx
012D9B6C  |.  33F6          |xor esi,esi
012D9B6E  |.  33FF          |xor edi,edi
012D9B70  |.  FFD0          |call eax
012D9B72  |>  8B7B 08       |mov edi,dword ptr ds:[ebx+8]
012D9B75  |.  8D0C76        |lea ecx,dword ptr ds:[esi+esi*2]
012D9B78  |.  8B348F        |mov esi,dword ptr ds:[edi+ecx*4]
012D9B7B  |.^ E9 78FFFFFF   \jmp 012D9AF8
012D9B80  |>  B8 00000000   mov eax,0
012D9B85  |.  EB 23         jmp short 012D9BAA
012D9B87  |>  8B45 08       mov eax,dword ptr ss:[ebp+8]
012D9B8A  |.  8348 04 08    or dword ptr ds:[eax+4],8
012D9B8E  |>  B8 01000000   mov eax,1
012D9B93  |.  EB 15         jmp short 012D9BAA
012D9B95  |>  55            push ebp
012D9B96  |.  8D6B 10       lea ebp,dword ptr ds:[ebx+10]
012D9B99  |.  6A FF         push -1
012D9B9B  |.  53            push ebx
012D9B9C  |.  E8 20F3FFFF   call __local_unwind2tcrit for 'DLog::m_L>
012D9BA1  |.  83C4 08       add esp,8
012D9BA4  |.  5D            pop ebp
012D9BA5  |.  B8 01000000   mov eax,1
012D9BAA  |>  5D            pop ebp
012D9BAB  |.  5F            pop edi
012D9BAC  |.  5E            pop esi
012D9BAD  |.  5B            pop ebx
012D9BAE  |.  8BE5          mov esp,ebp
012D9BB0  |.  5D            pop ebp
012D9BB1  \.  C3            retn

继续单步走,到 012D9AF2 时exe为0, jle 转走到012D9B87,然后退出 _except_handler3,这里并没有调用我们自身的handler就退出了

所以确定 012D9AF2  这里不应该跳的,这里exe的值为0 ,而eax来自 call_ValidateEH3RN

在 012D9AE8一个断点,F2重来,F9让它断在012D9AE8,再F7跟进去


012D9CD0 > $  8BFF          mov edi,edi
012D9CD2   .  55            push ebp
012D9CD3   .  8BEC          mov ebp,esp
012D9CD5   .  6A FE         push -2
012D9CD7   .  68 E8D02D01   push 012DD0E8
012D9CDC   .  68 E02A2D01   push _except_handler4regionectaterr 'DLo>
012D9CE1   .  64:A1 0000000>mov eax,dword ptr fs:[0]
012D9CE7   .  50            push eax
012D9CE8   .  83EC 30       sub esp,30
012D9CEB   .  53            push ebx
012D9CEC   .  56            push esi
012D9CED   .  57            push edi
012D9CEE   .  A1 18EB2D01   mov eax,dword ptr ds:[__security_cookieo>
012D9CF3   .  3145 F8       xor dword ptr ss:[ebp-8],eax
012D9CF6   .  33C5          xor eax,ebp
012D9CF8   .  50            push eax
012D9CF9   .  8D45 F0       lea eax,dword ptr ss:[ebp-10]
012D9CFC   .  64:A3 0000000>mov dword ptr fs:[0],eax
012D9D02   .  8965 E8       mov dword ptr ss:[ebp-18],esp
012D9D05   .  8B75 08       mov esi,dword ptr ss:[ebp+8]
012D9D08   .  8B56 08       mov edx,dword ptr ds:[esi+8]
012D9D0B   .  8955 E4       mov dword ptr ss:[ebp-1C],edx
012D9D0E   .  F6C2 03       test dl,3
012D9D11   .  74 14         je short 012D9D27
012D9D13   >  33C0          xor eax,eax
012D9D15   .  8B4D F0       mov ecx,dword ptr ss:[ebp-10]
012D9D18   .  64:890D 00000>mov dword ptr fs:[0],ecx
012D9D1F   .  59            pop ecx
012D9D20   .  5F            pop edi
012D9D21   .  5E            pop esi
012D9D22   .  5B            pop ebx
012D9D23   .  8BE5          mov esp,ebp
012D9D25   .  5D            pop ebp
012D9D26   .  C3            retn
012D9D27   >  64:A1 1800000>mov eax,dword ptr fs:[18]
012D9D2D   .  8B48 08       mov ecx,dword ptr ds:[eax+8]
012D9D30   .  894D E0       mov dword ptr ss:[ebp-20],ecx
012D9D33   .  3BD1          cmp edx,ecx
012D9D35   .  72 05         jb short 012D9D3C
012D9D37   .  3B50 04       cmp edx,dword ptr ds:[eax+4]
012D9D3A   .^ 72 D7         jb short 012D9D13
012D9D3C   >  8B7E 0C       mov edi,dword ptr ds:[esi+C]
012D9D3F   .  897D DC       mov dword ptr ss:[ebp-24],edi
012D9D42   .  83FF FF       cmp edi,-1
012D9D45   .  0F84 B7020000 je 012DA002
012D9D4B   .  33DB          xor ebx,ebx
012D9D4D   .  33C0          xor eax,eax
012D9D4F   .  8BCA          mov ecx,edx
012D9D51   >  8B31          mov esi,dword ptr ds:[ecx]
012D9D53   .  83FE FF       cmp esi,-1
012D9D56   .  74 04         je short 012D9D5C
012D9D58   .  3BF0          cmp esi,eax
012D9D5A   .^ 73 B7         jnb short 012D9D13
012D9D5C   >  8379 04 00    cmp dword ptr ds:[ecx+4],0
012D9D60   .  74 05         je short 012D9D67
012D9D62   .  BB 01000000   mov ebx,1
012D9D67   >  40            inc eax
012D9D68   .  83C1 0C       add ecx,0C
012D9D6B   .  3BC7          cmp eax,edi
012D9D6D   .^ 76 E2         jbe short 012D9D51
012D9D6F   .  85DB          test ebx,ebx
012D9D71   .  74 0F         je short 012D9D82
012D9D73   .  8B4D 08       mov ecx,dword ptr ss:[ebp+8]
012D9D76   .  8B41 F8       mov eax,dword ptr ds:[ecx-8]
012D9D79   .  3B45 E0       cmp eax,dword ptr ss:[ebp-20]
012D9D7C   .^ 72 95         jb short 012D9D13
012D9D7E   .  3BC1          cmp eax,ecx
012D9D80   .^ 73 91         jnb short 012D9D13
012D9D82   >  8BC2          mov eax,edx
012D9D84   .  25 00F0FFFF   and eax,FFFFF000
012D9D89   .  8945 E0       mov dword ptr ss:[ebp-20],eax
012D9D8C   .  33F6          xor esi,esi
012D9D8E   .  8B0D 08FC2D01 mov ecx,dword ptr ds:[nValidPagesngerLis>
012D9D94   >  3BF1          cmp esi,ecx
012D9D96   .  0F8D 2F010000 jge 012D9ECB
012D9D9C   .  8B1CF5 10FC2D>mov ebx,dword ptr ds:[esi*8+rgValidPages>
012D9DA3   .  8B3CF5 14FC2D>mov edi,dword ptr ds:[esi*8+12DFC14]
012D9DAA   .  3BD8          cmp ebx,eax
012D9DAC   .  0F85 4C010000 jnz 012D9EFE
012D9DB2   .  C745 FC 00000>mov dword ptr ss:[ebp-4],0
012D9DB9   .  57            push edi
012D9DBA   .  E8 71D6FFFF   call _ValidateImageBasenolockonFilterm_L>
012D9DBF   .  83C4 04       add esp,4
012D9DC2   .  85C0          test eax,eax
012D9DC4   .  0F84 F7000000 je 012D9EC1
012D9DCA   .  8B45 E4       mov eax,dword ptr ss:[ebp-1C]
012D9DCD   .  50            push eax
012D9DCE   .  8B4D DC       mov ecx,dword ptr ss:[ebp-24]
012D9DD1   .  E8 3AFEFFFF   call ValidateScopeTableHandlersFilterm_L>
012D9DD6   .  83C4 04       add esp,4
012D9DD9   .  85C0          test eax,eax
012D9DDB   .  0F84 E0000000 je 012D9EC1
012D9DE1   .  8B4D 08       mov ecx,dword ptr ss:[ebp+8]
012D9DE4   .  8B51 04       mov edx,dword ptr ds:[ecx+4]
012D9DE7   .  2BD7          sub edx,edi
012D9DE9   .  52            push edx
012D9DEA   .  57            push edi
012D9DEB   .  E8 80D6FFFF   call _FindPESectionfoListFlagsterteParam>
012D9DF0   .  83C4 08       add esp,8
012D9DF3   .  85C0          test eax,eax
012D9DF5   .  0F84 C6000000 je 012D9EC1
012D9DFB   .  C745 FC FEFFF>mov dword ptr ss:[ebp-4],-2
012D9E02   .  85F6          test esi,esi
012D9E04   .  0F8E F8010000 jle 012DA002
012D9E0A   .  B8 01000000   mov eax,1
012D9E0F   .  B9 0CFC2D01   mov ecx,offset lModifyingr::fGetTemplate>
012D9E14   .  8701          xchg dword ptr ds:[ecx],eax
012D9E16   .  85C0          test eax,eax
012D9E18   .  0F85 E4010000 jnz 012DA002
012D9E1E   .  8B45 E0       mov eax,dword ptr ss:[ebp-20]
012D9E21   .  3904F5 10FC2D>cmp dword ptr ds:[esi*8+rgValidPagesoldt>
012D9E28   .  74 3E         je short 012D9E68
012D9E2A   .  8B0D 08FC2D01 mov ecx,dword ptr ds:[nValidPagesngerLis>
012D9E30   .  8D71 FF       lea esi,dword ptr ds:[ecx-1]
012D9E33   .  85F6          test esi,esi
012D9E35   .  7C 22         jl short 012D9E59
012D9E37   >  3904F5 10FC2D>cmp dword ptr ds:[esi*8+rgValidPagesoldt>
012D9E3E   .  74 07         je short 012D9E47
012D9E40   .  83EE 01       sub esi,1
012D9E43   .^ 79 F2         jns short 012D9E37
012D9E45   .  EB 0E         jmp short 012D9E55
012D9E47   >  8B1CF5 10FC2D>mov ebx,dword ptr ds:[esi*8+rgValidPages>
012D9E4E   .  8B3CF5 14FC2D>mov edi,dword ptr ds:[esi*8+12DFC14]
012D9E55   >  85F6          test esi,esi
012D9E57   .  7D 11         jge short 012D9E6A
012D9E59   >  83F9 10       cmp ecx,10
012D9E5C   .  7D 07         jge short 012D9E65
012D9E5E   .  41            inc ecx
012D9E5F   .  890D 08FC2D01 mov dword ptr ds:[nValidPagesngerListcit>
012D9E65   >  8D71 FF       lea esi,dword ptr ds:[ecx-1]
012D9E68   >  85F6          test esi,esi
012D9E6A   >  0F8E 89010000 jle 012D9FF9
012D9E70   .  33C0          xor eax,eax
012D9E72   .  85F6          test esi,esi
012D9E74   .  0F8C 7F010000 jl 012D9FF9
012D9E7A   .  8D9B 00000000 lea ebx,dword ptr ds:[ebx]
012D9E80   >  8B0CC5 10FC2D>mov ecx,dword ptr ds:[eax*8+rgValidPages>
012D9E87   .  8B14C5 14FC2D>mov edx,dword ptr ds:[eax*8+12DFC14]
012D9E8E   .  891CC5 10FC2D>mov dword ptr ds:[eax*8+rgValidPagesoldt>
012D9E95   .  893CC5 14FC2D>mov dword ptr ds:[eax*8+12DFC14],edi
012D9E9C   .  8BD9          mov ebx,ecx
012D9E9E   .  8BFA          mov edi,edx
012D9EA0   .  40            inc eax
012D9EA1   .  3BC6          cmp eax,esi
012D9EA3   .^ 7E DB         jle short 012D9E80
012D9EA5   .  E9 4F010000   jmp 012D9FF9
012D9EAA   .  8B4D EC       mov ecx,dword ptr ss:[ebp-14]
012D9EAD   .  8B11          mov edx,dword ptr ds:[ecx]
012D9EAF   .  8B02          mov eax,dword ptr ds:[edx]
012D9EB1   .  33C9          xor ecx,ecx
012D9EB3   .  3D 050000C0   cmp eax,C0000005
012D9EB8   .  0f94c1        sete cl
012D9EBB   .  8BC1          mov eax,ecx
012D9EBD   .  C3            retn
012D9EBE   .  8B65 E8       mov esp,dword ptr ss:[ebp-18]
012D9EC1   >  C745 FC FEFFF>mov dword ptr ss:[ebp-4],-2
012D9EC8   .  8B55 E4       mov edx,dword ptr ss:[ebp-1C]
012D9ECB   >  6A 1C         push 1C                                  ; /BufSize = 1C (28.)
012D9ECD   .  8D45 C0       lea eax,dword ptr ss:[ebp-40]            ; |
012D9ED0   .  50            push eax                                 ; |Buffer
012D9ED1   .  52            push edx                                 ; |Address
012D9ED2   .  FF15 0CB12D01 call dword ptr ds:[<&KERNEL32.VirtualQue>; \VirtualQuery
012D9ED8   .  85C0          test eax,eax
012D9EDA   .  0F84 22010000 je 012DA002
012D9EE0   .  817D D8 00000>cmp dword ptr ss:[ebp-28],1000000
012D9EE7   .  74 1B         je short 012D9F04
012D9EE9   >  83C8 FF       or eax,FFFFFFFF
012D9EEC   .  8B4D F0       mov ecx,dword ptr ss:[ebp-10]
012D9EEF   .  64:890D 00000>mov dword ptr fs:[0],ecx
012D9EF6   .  59            pop ecx
012D9EF7   .  5F            pop edi
012D9EF8   .  5E            pop esi
012D9EF9   .  5B            pop ebx
012D9EFA   .  8BE5          mov esp,ebp
012D9EFC   .  5D            pop ebp
012D9EFD   .  C3            retn
012D9EFE   >  46            inc esi
012D9EFF   .^ E9 90FEFFFF   jmp 012D9D94
012D9F04   >  8B7D C4       mov edi,dword ptr ss:[ebp-3C]
012D9F07   .  57            push edi
012D9F08   .  E8 23D5FFFF   call _ValidateImageBasenolockonFilterm_L>
012D9F0D   .  83C4 04       add esp,4
012D9F10   .  85C0          test eax,eax
012D9F12   .^ 74 D5         je short 012D9EE9
012D9F14   .  F645 D4 CC    test byte ptr ss:[ebp-2C],0CC
012D9F18   .  74 24         je short 012D9F3E
012D9F1A   .  8B4D E4       mov ecx,dword ptr ss:[ebp-1C]
012D9F1D   .  2BCF          sub ecx,edi
012D9F1F   .  51            push ecx
012D9F20   .  57            push edi
012D9F21   .  E8 4AD5FFFF   call _FindPESectionfoListFlagsterteParam>
012D9F26   .  83C4 08       add esp,8
012D9F29   .  85C0          test eax,eax
012D9F2B   .^ 0F84 E2FDFFFF je 012D9D13
012D9F31   .  F740 24 00000>test dword ptr ds:[eax+24],80000000
012D9F38   .^ 0F85 D5FDFFFF jnz 012D9D13
012D9F3E   >  8B55 E4       mov edx,dword ptr ss:[ebp-1C]
012D9F41   .  52            push edx
012D9F42   .  8B4D DC       mov ecx,dword ptr ss:[ebp-24]
012D9F45   .  E8 C6FCFFFF   call ValidateScopeTableHandlersFilterm_L>
012D9F4A   .  83C4 04       add esp,4
012D9F4D   .  85C0          test eax,eax
012D9F4F   .^ 0F84 BEFDFFFF je 012D9D13
012D9F55   .  8B45 08       mov eax,dword ptr ss:[ebp+8]
012D9F58   .  8B48 04       mov ecx,dword ptr ds:[eax+4]
012D9F5B   .  2BCF          sub ecx,edi
012D9F5D   .  51            push ecx
012D9F5E   .  57            push edi
012D9F5F   .  E8 0CD5FFFF   call _FindPESectionfoListFlagsterteParam>
012D9F64   .  83C4 08       add esp,8
012D9F67   .  85C0          test eax,eax
012D9F69   .^ 0F84 A4FDFFFF je 012D9D13
012D9F6F   .  BA 01000000   mov edx,1
012D9F74   .  B8 0CFC2D01   mov eax,offset lModifyingr::fGetTemplate>
012D9F79   .  8710          xchg dword ptr ds:[eax],edx
012D9F7B   .  85D2          test edx,edx
012D9F7D   .  0F85 7F000000 jnz 012DA002
012D9F83   .  8B3D 08FC2D01 mov edi,dword ptr ds:[nValidPagesngerLis>
012D9F89   .  8BC7          mov eax,edi
012D9F8B   .  85FF          test edi,edi
012D9F8D   .  7E 16         jle short 012D9FA5
012D9F8F   .  8D0CFD 08FC2D>lea ecx,dword ptr ds:[edi*8+nValidPagesn>
012D9F96   >  8B11          mov edx,dword ptr ds:[ecx]
012D9F98   .  3B55 E0       cmp edx,dword ptr ss:[ebp-20]
012D9F9B   .  74 08         je short 012D9FA5
012D9F9D   .  48            dec eax
012D9F9E   .  83E9 08       sub ecx,8
012D9FA1   .  85C0          test eax,eax
012D9FA3   .^ 7F F1         jg short 012D9F96
012D9FA5   >  85C0          test eax,eax
012D9FA7   .  75 46         jnz short 012D9FEF
012D9FA9   .  83FF 0F       cmp edi,0F
012D9FAC   .  8D70 0F       lea esi,dword ptr ds:[eax+F]
012D9FAF   .  7F 02         jg short 012D9FB3
012D9FB1   .  8BF7          mov esi,edi
012D9FB3   >  8B4D E0       mov ecx,dword ptr ss:[ebp-20]
012D9FB6   .  8B55 C4       mov edx,dword ptr ss:[ebp-3C]
012D9FB9   .  85F6          test esi,esi
012D9FBB   .  7C 24         jl short 012D9FE1
012D9FBD   .  B8 10FC2D01   mov eax,offset rgValidPagesoldtionObject>
012D9FC2   .  8D5E 01       lea ebx,dword ptr ds:[esi+1]
012D9FC5   >  8B30          mov esi,dword ptr ds:[eax]
012D9FC7   .  8B78 04       mov edi,dword ptr ds:[eax+4]
012D9FCA   .  8908          mov dword ptr ds:[eax],ecx
012D9FCC   .  8950 04       mov dword ptr ds:[eax+4],edx
012D9FCF   .  8BCE          mov ecx,esi
012D9FD1   .  8BD7          mov edx,edi
012D9FD3   .  83C0 08       add eax,8
012D9FD6   .  83EB 01       sub ebx,1
012D9FD9   .^ 75 EA         jnz short 012D9FC5
012D9FDB   .  8B3D 08FC2D01 mov edi,dword ptr ds:[nValidPagesngerLis>
012D9FE1   >  83FF 10       cmp edi,10
012D9FE4   .  7D 13         jge short 012D9FF9
012D9FE6   .  47            inc edi
012D9FE7   .  893D 08FC2D01 mov dword ptr ds:[nValidPagesngerListcit>
012D9FED   .  EB 0A         jmp short 012D9FF9
012D9FEF   >  8B4D C4       mov ecx,dword ptr ss:[ebp-3C]
012D9FF2   .  890CC5 0CFC2D>mov dword ptr ds:[eax*8+lModifyingr::fGe>
012D9FF9   >  B8 0CFC2D01   mov eax,offset lModifyingr::fGetTemplate>
012D9FFE   .  33D2          xor edx,edx
012DA000   .  8710          xchg dword ptr ds:[eax],edx
012DA002   >  B8 01000000   mov eax,1
012DA007   .  8B4D F0       mov ecx,dword ptr ss:[ebp-10]
012DA00A   .  64:890D 00000>mov dword ptr fs:[0],ecx
012DA011   .  59            pop ecx
012DA012   .  5F            pop edi
012DA013   .  5E            pop esi
012DA014   .  5B            pop ebx
012DA015   .  8BE5          mov esp,ebp
012DA017   .  5D            pop ebp
012DA018   .  C3            retn

进来了_ValidateEH3RN,这个函数比较长,单步跟了一下,发现不太好跟,要弄明白整个函数不容易

网上找_ValidateEH3RN 的内容,几乎没有,百度没找到,google被墙了,最后换bing找到了看雪的一篇文章

http://bbs.pediy.com/showthread.php?t=49878

作者zhzhtst把_ValidateEH3RN给逆了一遍,还原成了C代码,这个只能膜拜了


对着源码在OD里跟,最后发现在这里返回0了

if (rvaScopeTable >= pSection->VirtualAddress 

   && rvaScopeTable < pSection->VirtualAddress + pSection->Misc.VirtualSize 
   && pSection->Characteristics & IMAGE_SCN_MEM_WRITE)
  {
   return 0;
  }

前面的条件都正常,唯一特别的就是 pSection->Characteristics & IMAGE_SCN_MEM_WRITE 这里了,这里如果区段属性为可写就返回0

看了下我写的程序,区段属性确实为可写,写Shell,大家都知道的,我把所有区段都合并到一起了,刚好SEH的ScopeTable和代码在同一个区段,并且区段为可写

#pragma comment(linker, "/merge:.data=.text")
#pragma comment(linker, "/merge:.rdata=.text")
#pragma comment(linker, "/section:.text,RWE")

原因是找到了,__ValidateEH3RN 会验证SEH的ScopeTable区段是否在笫一个区段并且区段为可写,可写就返失败

怎么解决这个问题呢,写Shell时因为和数据段合并了,区段为可写是必须的

刚开始没想到别的办法,就想手动把 __ValidateEH3RN 给 patch掉,让它直接返回1,或者把_except_handler3里的call _ValidateEH3RN nop掉

手动把call _ValidateEH3RN 给nop掉后发现功能正常,能正常调用我们的 SEH Handler

后来想了想总觉得这样猥琐的处理不太好,应该有其它的解决办法,难道这么多人写Shell就我一个人遇到这个问题了么,难道别人没遇到

然后重新建了一个工程(实际上面的调试分析时是在我现在的工程里调试的,比较复杂的代码),写了一个简答的SEH,同样合并区段,使区段可写

测试发现没问题,SEH正常,难道是我这工程有问题

然后一番对比修改测试,发现当工程设置里的 /GS 开关打开 /GS时运行正常, 当关闭 /GS时不正常

对比生成的代码发现, 打开 /GS时生成的 SEH Handler是 _except_handler4,关闭时生成的Handler是 _except_handler3

而_except_handler4里并不调用__ValidateEH3RN,所以运行正常


当时为了生成的Shell代码最精简,不让VS生成无关紧要的代码就把优化全开,不相关的功能全关了,所以 /GS也是关的

最后把 /GS 打开编译运行正常


结论:

1、VS在打开 /GS时生成的 SEH Handler是 _except_handler4,关闭时生成的Handler是 _except_handler3

2、_except_handler3里会调用_ValidateEH3RN 进行一系列的检查,包括ScopeTable区段是否在笫一个区段并且区段为可写

3、写Shell时默认使 /GS 打开即可,否则在使用了合并区段并且区段可写时使用SEH会出问题



你可能感兴趣的:(SEH不起作用的问题跟踪)