CLR 有胖异常框架还是小异常框架?
CLR have fat or small exception frame?
如何检测IMAGE_COR_ILMETHOD_SECT_EH必须使用Small还是Fat?
我还 instrest 其他内部 CLR structure/opcode 细节。下面的回答回答了这个问题和许多其他问题。
/*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,否则small。 Kind
字段可以通过 Small.SectSmall.Kind
或 Fat.SectFat.Kind
访问,两者都应该有效。
如何检测IMAGE_COR_ILMETHOD_SECT_EH必须使用Small还是Fat? 我还 instrest 其他内部 CLR structure/opcode 细节。下面的回答回答了这个问题和许多其他问题。
/*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,否则small。 Kind
字段可以通过 Small.SectSmall.Kind
或 Fat.SectFat.Kind
访问,两者都应该有效。