CLR 有胖或小的异常框架

CLR have fat or small exception frame?

本文关键字:异常 框架 CLR      更新时间:2023-10-16

如何检测IMAGE_COR_ILMETHOD_SECT_EH必须使用"小"或"胖"?我也在内部 CLR 结构/操作码细节中寻找其他内容。下面的答案回答了这个问题和许多其他问题。

/*RVA:0*/ typedef union IMAGE_COR_ILMETHOD{
IMAGE_COR_ILMETHOD_TINY       Tiny;
IMAGE_COR_ILMETHOD_FAT        Fat;} IMAGE_COR_ILMETHOD;
/*PC = RVA + sizeof( IMAGE_COR_ILMETHOD) = 12 or 4 byte*/ ... Code
/*EH = PC+CodeSize */typedef union IMAGE_COR_ILMETHOD_SECT_EH{
    IMAGE_COR_ILMETHOD_SECT_EH_SMALL Small;
    IMAGE_COR_ILMETHOD_SECT_EH_FAT Fat;
} IMAGE_COR_ILMETHOD_SECT_EH;

https://github.com/dotnet/coreclr/blob/master/src/inc/corhdr.h

例如

public static Main(string args[]){
   int i=0;
   try{
     Console.Write("OK");
   } catch(Exception){
   i++
   }
0000 4D 5A 90 00 MZ-header 
0250 2A 02 17 8C 06 00 00 01 51 2a 00 
RVA: 1B 30 02 00  // IMAGE_COR_ILMETHOD_FAT
     1D 00 00 00  CodeSize= 29 
     01 00 00 11  Locals  = 11000001
PC0: 00 16 0A              i=0 
PC3  00 72 01 00 00 70     try{
     28 04 00 00 0A     call Console.Write
     00 00 DE 09 
PC12:26 00 06 17 58 0A  00 DE 00 00 2A  (2A is ret command)     
     00 00 00 01 10 00   // IMAGE_COR_ILMETHOD_SECT_EH  ??? 1=count
     00 00        CorExceptionFlag Flags 
     03 00        TryOffset 
     0F           TryLength 
     12 00        HandlerOffset 
     09           HandlerLength 
     08 00 00 01  ClassToken

在这种情况下,我们有小的EH框架。如何检测我们有小框架或胖框架?

   struct IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL{
       CorExceptionFlag    Flags         : 16;
       unsigned            TryOffset     : 16;
       unsigned            TryLength     : 8;  // relative to start of try block
       unsigned            HandlerOffset : 16;
       unsigned            HandlerLength : 8;  // relative to start of  handler
       union {
         DWORD       ClassToken;
         DWORD       FilterOffset;
       };
    } IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL;
typedef struct IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT
{
  CorExceptionFlag    Flags;
  DWORD               TryOffset;
  DWORD               TryLength;      // relative to start of try block
  DWORD               HandlerOffset;
  DWORD               HandlerLength;  // relative to start of handler
  union {
    DWORD           ClassToken;     // use for type-based exception handlers
    DWORD           FilterOffset;   // use for filter-based exception handlers (COR_ILEXCEPTION_FILTER is set)
};
} IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT;

这在 ECMA-335 的分区 II 第 25.4.5 节中有所介绍。

如果在Kind字段(结构的第一个字节)中设置了CorILMethod_Sect_FatFormat位(0x40),则应使用fat,否则很小。Kind字段可以通过Small.SectSmall.KindFat.SectFat.Kind访问,两者都应该有效。