原创 关于_ValidateEH3RN收藏

新一篇: 纪念逝去的Borland | 旧一篇: Microsoft可移植可执行文件和通用目标文件格式文件规范v8.1修订版(Microsoft Portable Executable and Common Object File Format Specification Revision 8.1)

 
 
关于_ValidateEH3RN
 

  Windows XP SP2中对结构化异常处理做了一些改动,在_except_handler3中增加了对_ValidateEH3RN的调用。这个函数的代码非常长,在Visual Studio .NET 2003调试器和IDA Pro的帮助下,我重写了这个函数的源代码。然后我用命令行“cl /c /Ob1 /Z7 /Zl _ValidateEH3RN.c”进行编译并用Visual Studio .NET 2003附带的DUMPBIN工具反汇编了生成的目标文件以及Microsoft提供的目标文件(其单线程调试版本在crt\src\intel\xst_lib目录中)。当我用Beyond Compare比较生成的两个汇编语言文件时,我惊奇地发现,在生成的308行汇编代码中,前217行两者完全一样,后面的90行代码除了使用的寄存器不同(也就是说,假设其中一个使用的是EAX,另一个使用的可能是EDX)外,两者并无任何差别。结果我写的代码比Microsoft提供的代码大两个字节。我花了许多时间阅读MSDN中与编译器以及调试器相关的文档,但都不能解决这个问题。就连Google也帮不了忙。我将此问题贴在OpenRCE以及MSDN论坛中的Visual C++版块上,但至今无一人响应。希望高手不吝赐教

下面是_ValidateEH3RN.c文件:

// The macro was get from the makefile in the CRT source direcotry

#define WIN32_LEAN_AND_MEAN
 

#include 
<windows.h>


#define TRYLEVEL_NONE -1    // For convenient


// The following two structures were get with the help of Visual Studio debugger

typedef 
struct _SCOPETABLE_ENTRY {

     DWORD EnclosingLevel;

     PVOID FilterFunc;

     PVOID HandlerFunc;

} SCOPETABLE_ENTRY, 
*PSCOPETABLE_ENTRY;

 

typedef 
struct _EH3_EXCEPTION_REGISTRATION {

     
struct _EH3_EXCEPTION_REGISTRATION *Next;

     PVOID ExceptionHandler;

     PSCOPETABLE_ENTRY ScopeTable;

     DWORD TryLevel;

} EH3_EXCEPTION_REGISTRATION, 
*PEH3_EXCEPTION_REGISTRATION;

 

// Copy from winnt.h (Windows Server 2003 SP1 DDKincwnet directory)

#define PcTeb 0x18

__inline 
struct _TEB * NtCurrentTeb( void ) { __asm mov eax, fs:[PcTeb] }

 

// Global variables

INT      nValidPages
=0;

PVOID    rgValidPages[
0x10]={NULL};

BOOL lModifying
=FALSE;

 

// The calling convention was get from the disassembly code of __except_handler3

// The parameter was get in the "Call Stack" window of Visual Studio debugger

// The local variables and their order were get in the "Locals" window

int __cdecl _ValidateEH3RN(

                   PEH3_EXCEPTION_REGISTRATION pRN)

{

     MEMORY_BASIC_INFORMATION mbi;

     PIMAGE_SECTION_HEADER pSection;

     PVOID pScopePage;

     INT iValid;

     UINT iSection;

     INT iValid2;

     PNT_TIB pTIB;

     PSCOPETABLE_ENTRY pScopeTable;

     INT nFilters;

     PVOID pTmp;

     PIMAGE_NT_HEADERS pNTHeader;

     PIMAGE_DOS_HEADER pDOSHeader;

     PIMAGE_OPTIONAL_HEADER pOptHeader;

     DWORD level;

     DWORD rvaScopeTable;

 

     pScopeTable 
= pRN->ScopeTable;

 

     
// Align at DWORD boundary ?

     
if ((DWORD)pScopeTable & 0x3)

     {

         
return 0;

     }

 

     
// Get the TIB

     pTIB 
= (PNT_TIB)NtCurrentTeb();

 

     
// Out of the stack limit ?

     
if ((PVOID)pScopeTable >= (PVOID)pTIB->StackLimit 

         
&& (PVOID)pScopeTable < (PVOID)pTIB->StackBase)

     {

         
return 0;

     }

 

     
if (pRN->TryLevel == TRYLEVEL_NONE)

     {

         
return 1;

     }

 

     
// Get the count of filters

     
for (nFilters=0, level=0; level<=pRN->TryLevel; level++)

     {

         DWORD enclosing 
= pScopeTable[level].EnclosingLevel;

         
if (enclosing != TRYLEVEL_NONE && enclosing >= level)

         {

              
return 0;

         }

 

         
if (pScopeTable[level].FilterFunc != NULL)

              nFilters
++;

     }

     

     
if (nFilters

         
&& ((PVOID)*(PDWORD)((PBYTE)pRN-8< pTIB->StackLimit   // (pRN-8) -> saved ESP

              
|| (PVOID)*(PDWORD)((PBYTE)pRN-8>= (PVOID)pRN))

     {

         
return 0;

     }

 

     pScopePage 
= (PVOID)((DWORD)pScopeTable & 0xFFFFF000);  // Align at 4KB page boundary

     

     
for (iValid=0; iValid<nValidPages; iValid++)

     {

         
if (rgValidPages[iValid] == pScopePage)

         {

              
if (iValid>0 && !InterlockedExchange(&lModifying, 1))

              {

                   
if (rgValidPages[iValid] != pScopePage)

                   {

                       
for (iValid=nValidPages-1; iValid>=0; iValid--)

                       {

                            
if (rgValidPages[iValid] == pScopePage)

                                 
break;

                       }

                       

                       
if (iValid < 0)

                       {

                            
if (nValidPages < 0x10)

                                 nValidPages
++;

 

                            iValid 
= nValidPages - 1;

                       }

                       
else

                       {

                            
if (iValid == 0)

                            {

                                 InterlockedExchange(
&lModifying, 0);

                                 
return 1;

                            }

                       }

                   }

                   

                   
for (iValid2=0; iValid2<=iValid; iValid2++)

                   {

                       
// swap

                       pTmp 
= rgValidPages[iValid2];

                       rgValidPages[iValid2] 
= pScopePage;

                       pScopePage 
= pTmp;

                   }

                   

                   InterlockedExchange(
&lModifying, 0);

              }

 

              
return 1;

         }

     }    
/* end of for */

     

     
// See the last part of Win32 Q&A, MSJ, May 1996 issue

     
if (!VirtualQuery((LPCVOID)pScopeTable, &mbi, sizeof(mbi))

         
|| mbi.Type != MEM_IMAGE)

     {

         
return -1;

     }

 

     
if (!(mbi.Protect & (PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)))

     {

         
goto exit_success;

     }

 

     pDOSHeader 
= (PIMAGE_DOS_HEADER)mbi.AllocationBase;

     
if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)

     {

         
return -1;

     }

 

     pNTHeader 
= (PIMAGE_NT_HEADERS)((PBYTE)pDOSHeader + pDOSHeader->e_lfanew);

     
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)

     {

         
return -1;

     }

 

     pOptHeader 
= (PIMAGE_OPTIONAL_HEADER)&pNTHeader->OptionalHeader;

     
if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)

     {

         
return -1;

     }

 

     rvaScopeTable 
= (PBYTE)pScopeTable - (PBYTE)pDOSHeader;

     iSection 
= 0;

 

     
// The offical method to get the section table in PE-COFF specification

     pSection 
= IMAGE_FIRST_SECTION(pNTHeader);         // Defined in WINNT.H

     
if (iSection < (UINT)pNTHeader->FileHeader.NumberOfSections)

     {

         
if (rvaScopeTable >= pSection->VirtualAddress 

              
&& rvaScopeTable < pSection->VirtualAddress + pSection->Misc.VirtualSize 

              
&& pSection->Characteristics & IMAGE_SCN_MEM_WRITE)

         {

              
return 0;

         }

     }

     
else

     {

         
return -1;

     }

 

exit_success:

 

     
if (InterlockedExchange(&lModifying, 1))

     {

         
return 1;

     }

 

     
for (iValid=nValidPages; iValid>0; iValid--)

     {

         
if (rgValidPages[iValid-1== pScopePage)

              
break;

     }

 

     
if (!iValid)

     {

         
for (iValid=(nValidPages>0xF)?0xF:nValidPages, iValid2=0; iValid2<=iValid; iValid2++)

         {

              
// swap

              pTmp 
= rgValidPages[iValid2];

              rgValidPages[iValid2] 
= pScopePage;

              pScopePage 
= pTmp;

         }

 

         
if (nValidPages < 0x10)

              nValidPages
++;

     }

 

     InterlockedExchange(
&lModifying, 0);

     
return 1;

}

 

下面是DUMPBIN输出的_ValidateEH3RN.obj的反汇编结果:

Microsoft (R) COFF/PE Dumper Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file _ValidateEH3RN.obj

File Type: COFF OBJECT

__ValidateEH3RN:
  
0000000055                 push        ebp
  
00000001: 8B EC              mov         ebp,esp
  
0000000383 EC 5C           sub         esp,5Ch
  
00000006: 8B 45 08           mov         eax,dword ptr [ebp+8]
  
00000009: 8B 48 08           mov         ecx,dword ptr [eax+8]
  0000000C: 
89 4D E0           mov         dword ptr [ebp-20h],ecx
  0000000F: 8B 
55 E0           mov         edx,dword ptr [ebp-20h]
  
0000001283 E2 03           and         edx,3
  
0000001574 07              je          0000001E
  
0000001733 C0              xor         eax,eax
  
00000019: E9 C8 03 00 00     jmp         000003E6
  0000001E: 
64 A1 18 00 00 00  mov         eax,dword ptr fs:[00000018h]
  
0000002489 45 DC           mov         dword ptr [ebp-24h],eax
  
00000027: 8B 45 DC           mov         eax,dword ptr [ebp-24h]
  0000002A: 8B 4D E0           mov         ecx,dword ptr [ebp
-20h]
  0000002D: 3B 
48 08           cmp         ecx,dword ptr [eax+8]
  
0000003072 12              jb          00000044
  
00000032: 8B 55 DC           mov         edx,dword ptr [ebp-24h]
  
00000035: 8B 45 E0           mov         eax,dword ptr [ebp-20h]
  
00000038: 3B 42 04           cmp         eax,dword ptr [edx+4]
  0000003B: 
73 07              jae         00000044
  0000003D: 
33 C0              xor         eax,eax
  0000003F: E9 A2 
03 00 00     jmp         000003E6
  
00000044: 8B 4D 08           mov         ecx,dword ptr [ebp+8]
  
0000004783 79 0C FF        cmp         dword ptr [ecx+0Ch],0FFFFFFFFh
  0000004B: 
75 0A              jne         00000057
  0000004D: B8 
01 00 00 00     mov         eax,1
  
00000052: E9 8F 03 00 00     jmp         000003E6
  
00000057: C7 45 E4 00 00 00  mov         dword ptr [ebp-1Ch],0
            
00
  0000005E: C7 
45 F8 00 00 00  mov         dword ptr [ebp-8],0
            
00
  
00000065: EB 09              jmp         00000070
  
00000067: 8B 55 F8           mov         edx,dword ptr [ebp-8]
  0000006A: 
83 C2 01           add         edx,1
  0000006D: 
89 55 F8           mov         dword ptr [ebp-8],edx
  
00000070: 8B 45 08           mov         eax,dword ptr [ebp+8]
  
00000073: 8B 4D F8           mov         ecx,dword ptr [ebp-8]
  
00000076: 3B 48 0C           cmp         ecx,dword ptr [eax+0Ch]
  
0000007977 3F              ja          000000BA
  0000007B: 8B 
55 F8           mov         edx,dword ptr [ebp-8]
  0000007E: 6B D2 0C           imul        edx,edx,0Ch
  
00000081: 8B 45 E0           mov         eax,dword ptr [ebp-20h]
  
00000084: 8B 0C 10           mov         ecx,dword ptr [eax+edx]
  
0000008789 4D A8           mov         dword ptr [ebp-58h],ecx
  0000008A: 
83 7D A8 FF        cmp         dword ptr [ebp-58h],0FFFFFFFFh
  0000008E: 
74 0F              je          0000009F
  
00000090: 8B 55 A8           mov         edx,dword ptr [ebp-58h]
  
00000093: 3B 55 F8           cmp         edx,dword ptr [ebp-8]
  
0000009672 07              jb          0000009F
  
0000009833 C0              xor         eax,eax
  0000009A: E9 
47 03 00 00     jmp         000003E6
  0000009F: 8B 
45 F8           mov         eax,dword ptr [ebp-8]
  000000A2: 6B C0 0C           imul        eax,eax,0Ch
  000000A5: 8B 4D E0           mov         ecx,dword ptr [ebp
-20h]
  000000A8: 
83 7C 01 04 00     cmp         dword ptr [ecx+eax+4],0
  000000AD: 
74 09              je          000000B8
  000000AF: 8B 
55 E4           mov         edx,dword ptr [ebp-1Ch]
  000000B2: 
83 C2 01           add         edx,1
  000000B5: 
89 55 E4           mov         dword ptr [ebp-1Ch],edx
  000000B8: EB AD              jmp         
00000067
  000000BA: 
83 7D E4 00        cmp         dword ptr [ebp-1Ch],0
  000000BE: 
74 20              je          000000E0
  000000C0: 8B 
45 08           mov         eax,dword ptr [ebp+8]
  000000C3: 8B 4D DC           mov         ecx,dword ptr [ebp
-24h]
  000000C6: 8B 
50 F8           mov         edx,dword ptr [eax-8]
  000000C9: 3B 
51 08           cmp         edx,dword ptr [ecx+8]
  000000CC: 
72 0B              jb          000000D9
  000000CE: 8B 
45 08           mov         eax,dword ptr [ebp+8]
  000000D1: 8B 
48 F8           mov         ecx,dword ptr [eax-8]
  000000D4: 3B 4D 
08           cmp         ecx,dword ptr [ebp+8]
  000000D7: 
72 07              jb          000000E0
  000000D9: 
33 C0              xor         eax,eax
  000000DB: E9 
06 03 00 00     jmp         000003E6
  000000E0: 8B 
55 E0           mov         edx,dword ptr [ebp-20h]
  000000E3: 
81 E2 00 F0 FF FF  and         edx,0FFFFF000h
  000000E9: 
89 55 CC           mov         dword ptr [ebp-34h],edx
  000000EC: C7 
45 D0 00 00 00  mov         dword ptr [ebp-30h],0
            
00
  000000F3: EB 
09              jmp         000000FE
  000000F5: 8B 
45 D0           mov         eax,dword ptr [ebp-30h]
  000000F8: 
83 C0 01           add         eax,1
  000000FB: 
89 45 D0           mov         dword ptr [ebp-30h],eax
  000000FE: 8B 4D D0           mov         ecx,dword ptr [ebp
-30h]
  
00000101: 3B 0D 00 00 00 00  cmp         ecx,dword ptr [_nValidPages]
  
00000107: 0F 8D 11 01 00 00  jge         0000021E
  0000010D: 8B 
55 D0           mov         edx,dword ptr [ebp-30h]
  
00000110: 8B 04 95 00 00 00  mov         eax,dword ptr [edx*4]
            
00
  
00000117: 3B 45 CC           cmp         eax,dword ptr [ebp-34h]
  0000011A: 0F 
85 F9 00 00 00  jne         00000219
  
0000012083 7D D0 00        cmp         dword ptr [ebp-30h],0
  
00000124: 0F 8E E5 00 00 00  jle         0000020F
  0000012A: 6A 
01              push        1
  0000012C: 
68 00 00 00 00     push        offset _lModifying
  
00000131: FF 15 00 00 00 00  call        dword ptr [__imp__InterlockedExchange@8]
  
0000013785 C0              test        eax,eax
  
00000139: 0F 85 D0 00 00 00  jne         0000020F
  0000013F: 8B 4D D0           mov         ecx,dword ptr [ebp
-30h]
  
00000142: 8B 14 8D 00 00 00  mov         edx,dword ptr [ecx*4]
            
00
  
00000149: 3B 55 CC           cmp         edx,dword ptr [ebp-34h]
  0000014C: 
74 78              je          000001C6
  0000014E: A1 
00 00 00 00     mov         eax,dword ptr [_nValidPages]
  
0000015383 E8 01           sub         eax,1
  
0000015689 45 D0           mov         dword ptr [ebp-30h],eax
  
00000159: EB 09              jmp         00000164
  0000015B: 8B 4D D0           mov         ecx,dword ptr [ebp
-30h]
  0000015E: 
83 E9 01           sub         ecx,1
  
0000016189 4D D0           mov         dword ptr [ebp-30h],ecx
  
0000016483 7D D0 00        cmp         dword ptr [ebp-30h],0
  
00000168: 7C 13              jl          0000017D
  0000016A: 8B 
55 D0           mov         edx,dword ptr [ebp-30h]
  0000016D: 8B 
04 95 00 00 00  mov         eax,dword ptr [edx*4]
            
00
  
00000174: 3B 45 CC           cmp         eax,dword ptr [ebp-34h]
  
0000017775 02              jne         0000017B
  
00000179: EB 02              jmp         0000017D
  0000017B: EB DE              jmp         0000015B
  0000017D: 
83 7D D0 00        cmp         dword ptr [ebp-30h],0
  
00000181: 7D 26              jge         000001A9
  
0000018383 3D 00 00 00 00  cmp         dword ptr [_nValidPages],10h
            
10
  0000018A: 7D 0F              jge         0000019B
  0000018C: 8B 0D 
00 00 00 00  mov         ecx,dword ptr [_nValidPages]
  
0000019283 C1 01           add         ecx,1
  
0000019589 0D 00 00 00 00  mov         dword ptr [_nValidPages],ecx
  0000019B: 8B 
15 00 00 00 00  mov         edx,dword ptr [_nValidPages]
  000001A1: 
83 EA 01           sub         edx,1
  000001A4: 
89 55 D0           mov         dword ptr [ebp-30h],edx
  000001A7: EB 1D              jmp         000001C6
  000001A9: 
83 7D D0 00        cmp         dword ptr [ebp-30h],0
  000001AD: 
75 17              jne         000001C6
  000001AF: 6A 
00              push        0
  000001B1: 
68 00 00 00 00     push        offset _lModifying
  000001B6: FF 
15 00 00 00 00  call        dword ptr [__imp__InterlockedExchange@8]
  000001BC: B8 
01 00 00 00     mov         eax,1
  000001C1: E9 
20 02 00 00     jmp         000003E6
  000001C6: C7 
45 D8 00 00 00  mov         dword ptr [ebp-28h],0
            
00
  000001CD: EB 
09              jmp         000001D8
  000001CF: 8B 
45 D8           mov         eax,dword ptr [ebp-28h]
  000001D2: 
83 C0 01           add         eax,1
  000001D5: 
89 45 D8           mov         dword ptr [ebp-28h],eax
  000001D8: 8B 4D D8           mov         ecx,dword ptr [ebp
-28h]
  000001DB: 3B 4D D0           cmp         ecx,dword ptr [ebp
-30h]
  000001DE: 7F 
22              jg          00000202
  000001E0: 8B 
55 D8           mov         edx,dword ptr [ebp-28h]
  000001E3: 8B 
04 95 00 00 00  mov         eax,dword ptr [edx*4]
            
00
  000001EA: 
89 45 E8           mov         dword ptr [ebp-18h],eax
  000001ED: 8B 4D D8           mov         ecx,dword ptr [ebp
-28h]
  000001F0: 8B 
55 CC           mov         edx,dword ptr [ebp-34h]
  000001F3: 
89 14 8D 00 00 00  mov         dword ptr [ecx*4],edx
            
00
  000001FA: 8B 
45 E8           mov         eax,dword ptr [ebp-18h]
  000001FD: 
89 45 CC           mov         dword ptr [ebp-34h],eax
  
00000200: EB CD              jmp         000001CF
  
00000202: 6A 00              push        0
  
0000020468 00 00 00 00     push        offset _lModifying
  
00000209: FF 15 00 00 00 00  call        dword ptr [__imp__InterlockedExchange@8]
  0000020F: B8 
01 00 00 00     mov         eax,1
  
00000214: E9 CD 01 00 00     jmp         000003E6
  
00000219: E9 D7 FE FF FF     jmp         000000F5
  0000021E: 6A 1C              push        1Ch
  
00000220: 8D 4D AC           lea         ecx,[ebp-54h]
  
0000022351                 push        ecx
  
00000224: 8B 55 E0           mov         edx,dword ptr [ebp-20h]
  
0000022752                 push        edx
  
00000228: FF 15 00 00 00 00  call        dword ptr [__imp__VirtualQuery@12]
  0000022E: 
85 C0              test        eax,eax
  
0000023074 09              je          0000023B
  
0000023281 7D C4 00 00 00  cmp         dword ptr [ebp-3Ch],1000000h
            
01
  
0000023974 08              je          00000243
  0000023B: 
83 C8 FF           or          eax,0FFFFFFFFh
  0000023E: E9 A3 
01 00 00     jmp         000003E6
  
00000243: 8B 45 C0           mov         eax,dword ptr [ebp-40h]
  
0000024625 CC 00 00 00     and         eax,0CCh
  0000024B: 
75 05              jne         00000252
  0000024D: E9 C0 
00 00 00     jmp         $exit_success$19845
  
00000252: 8B 4D B0           mov         ecx,dword ptr [ebp-50h]
  
0000025589 4D F0           mov         dword ptr [ebp-10h],ecx
  
00000258: 8B 55 F0           mov         edx,dword ptr [ebp-10h]
  0000025B: 0F B7 
02           movzx       eax,word ptr [edx]
  0000025E: 3D 4D 5A 
00 00     cmp         eax,5A4Dh
  
0000026374 08              je          0000026D
  
0000026583 C8 FF           or          eax,0FFFFFFFFh
  
00000268: E9 79 01 00 00     jmp         000003E6
  0000026D: 8B 4D F0           mov         ecx,dword ptr [ebp
-10h]
  
00000270: 8B 55 F0           mov         edx,dword ptr [ebp-10h]
  
0000027303 51 3C           add         edx,dword ptr [ecx+3Ch]
  
0000027689 55 EC           mov         dword ptr [ebp-14h],edx
  
00000279: 8B 45 EC           mov         eax,dword ptr [ebp-14h]
  0000027C: 
81 38 50 45 00