public void Read(ReaderContext ctxt, BlobReader reader, bool isFat, Func <OpCode, Row, object> resolveRow) { if (isFat) { Flags = (CorILExceptionClause)reader.ReadUInt32(); TryOffset = (int)reader.ReadUInt32(); TryLength = (int)reader.ReadUInt32(); HandlerOffset = (int)reader.ReadUInt32(); HandlerLength = (int)reader.ReadUInt32(); } else { Flags = (CorILExceptionClause)reader.ReadUInt16(); TryOffset = (int)reader.ReadUInt16(); TryLength = (int)reader.ReadByte(); HandlerOffset = (int)reader.ReadUInt16(); HandlerLength = (int)reader.ReadByte(); } var rowRef = default(TokenRef); rowRef.Read(ctxt, reader); rowRef.ResolveIndexes(ctxt); Class = rowRef.Value == null ? null : resolveRow(OpCode.Ldobj, rowRef.Value); if (Flags == CorILExceptionClause.Filter) { FilterOffset = (int)reader.ReadUInt32(); } }
public void Read(ReaderContext ctxt, BlobReader reader, bool isFat, Func<OpCode, Row, object> resolveRow) { if (isFat) { Flags = (CorILExceptionClause)reader.ReadUInt32(); TryOffset = (int)reader.ReadUInt32(); TryLength = (int)reader.ReadUInt32(); HandlerOffset = (int)reader.ReadUInt32(); HandlerLength = (int)reader.ReadUInt32(); } else { Flags = (CorILExceptionClause)reader.ReadUInt16(); TryOffset = (int)reader.ReadUInt16(); TryLength = (int)reader.ReadByte(); HandlerOffset = (int)reader.ReadUInt16(); HandlerLength = (int)reader.ReadByte(); } var rowRef = default(TokenRef); rowRef.Read(ctxt, reader); rowRef.ResolveIndexes(ctxt); Class = rowRef.Value == null ? null : resolveRow(OpCode.Ldobj, rowRef.Value); if (Flags == CorILExceptionClause.Filter) FilterOffset = (int)reader.ReadUInt32(); }
private bool ReadMethodDataSection(ReaderContext ctxt, BlobReader reader, Func <OpCode, Row, object> resolveRow) { reader.Align(4); var flags = (CorILMethodSect)reader.ReadByte(); if ((flags & CorILMethodSect.EHTable) == 0) { throw new PEException("unrecognised method data section"); } var isFat = (flags & CorILMethodSect.FatFormat) != 0; var count = default(uint); if (isFat) { var size = reader.ReadUInt24(); if (size < 4 || (size - 4) % 24 != 0) { throw new InvalidOperationException("invalid method data section"); } count = (size - 4) / 24; } else { var size = (uint)reader.ReadByte(); // NOTE: Looks live VB emits size without including the 4 byte header... if (size < 4 || (size - 4) % 12 != 0) { throw new InvalidOperationException("invalid method data section"); } var padding = reader.ReadUInt16(); if (padding != 0) { throw new PEException("unexpected data"); } count = (size - 4) / 12; } for (var i = 0; i < count; i++) { var c = new ExceptionHandlingClause(); c.Read(ctxt, reader, isFat, resolveRow); ExceptionHandlingClauses.Add(c); } return((flags & CorILMethodSect.MoreSects) != 0); }
public void Read(ReaderContext ctxt, BlobReader reader, uint beginOffset, Func<OpCode, Row, object> resolveRow) { Offset = (int)(reader.Offset - beginOffset); OpCode = (OpCode)reader.ReadByte(); if (OpCode == OpCode.Prefix1) OpCode = (OpCode)((ushort)OpCode << 8 | reader.ReadByte()); Value = default(object); switch (OpCode) { case OpCode.Nop: case OpCode.Break: case OpCode.Ldarg_0: case OpCode.Ldarg_1: case OpCode.Ldarg_2: case OpCode.Ldarg_3: case OpCode.Ldloc_0: case OpCode.Ldloc_1: case OpCode.Ldloc_2: case OpCode.Ldloc_3: case OpCode.Stloc_0: case OpCode.Stloc_1: case OpCode.Stloc_2: case OpCode.Stloc_3: case OpCode.Ldnull: case OpCode.Ldc_i4_m1: case OpCode.Ldc_i4_0: case OpCode.Ldc_i4_1: case OpCode.Ldc_i4_2: case OpCode.Ldc_i4_3: case OpCode.Ldc_i4_4: case OpCode.Ldc_i4_5: case OpCode.Ldc_i4_6: case OpCode.Ldc_i4_7: case OpCode.Ldc_i4_8: case OpCode.Dup: case OpCode.Pop: case OpCode.Ret: case OpCode.Ldind_i1: case OpCode.Ldind_u1: case OpCode.Ldind_i2: case OpCode.Ldind_u2: case OpCode.Ldind_i4: case OpCode.Ldind_u4: case OpCode.Ldind_i8: case OpCode.Ldind_i: case OpCode.Ldind_r4: case OpCode.Ldind_r8: case OpCode.Ldind_ref: case OpCode.Stind_ref: case OpCode.Stind_i1: case OpCode.Stind_i2: case OpCode.Stind_i4: case OpCode.Stind_i8: case OpCode.Stind_r4: case OpCode.Stind_r8: case OpCode.Add: case OpCode.Sub: case OpCode.Mul: case OpCode.Div: case OpCode.Div_un: case OpCode.Rem: case OpCode.Rem_un: case OpCode.And: case OpCode.Or: case OpCode.Xor: case OpCode.Shl: case OpCode.Shr: case OpCode.Shr_un: case OpCode.Neg: case OpCode.Not: case OpCode.Conv_i1: case OpCode.Conv_i2: case OpCode.Conv_i4: case OpCode.Conv_i8: case OpCode.Conv_r4: case OpCode.Conv_r8: case OpCode.Conv_u4: case OpCode.Conv_u8: case OpCode.Conv_r_un: case OpCode.Throw: case OpCode.Conv_ovf_i1_un: case OpCode.Conv_ovf_i2_un: case OpCode.Conv_ovf_i4_un: case OpCode.Conv_ovf_i8_un: case OpCode.Conv_ovf_u1_un: case OpCode.Conv_ovf_u2_un: case OpCode.Conv_ovf_u4_un: case OpCode.Conv_ovf_u8_un: case OpCode.Conv_ovf_i_un: case OpCode.Conv_ovf_u_un: case OpCode.Ldlen: case OpCode.Ldelem_i1: case OpCode.Ldelem_u1: case OpCode.Ldelem_i2: case OpCode.Ldelem_u2: case OpCode.Ldelem_i4: case OpCode.Ldelem_u4: case OpCode.Ldelem_i8: case OpCode.Ldelem_i: case OpCode.Ldelem_r4: case OpCode.Ldelem_r8: case OpCode.Ldelem_ref: case OpCode.Stelem_i: case OpCode.Stelem_i1: case OpCode.Stelem_i2: case OpCode.Stelem_i4: case OpCode.Stelem_i8: case OpCode.Stelem_r4: case OpCode.Stelem_r8: case OpCode.Stelem_ref: case OpCode.Conv_ovf_i1: case OpCode.Conv_ovf_u1: case OpCode.Conv_ovf_i2: case OpCode.Conv_ovf_u2: case OpCode.Conv_ovf_i4: case OpCode.Conv_ovf_u4: case OpCode.Conv_ovf_i8: case OpCode.Conv_ovf_u8: case OpCode.Ckfinite: case OpCode.Conv_u2: case OpCode.Conv_u1: case OpCode.Conv_i: case OpCode.Conv_ovf_i: case OpCode.Conv_ovf_u: case OpCode.Add_ovf: case OpCode.Add_ovf_un: case OpCode.Mul_ovf: case OpCode.Mul_ovf_un: case OpCode.Sub_ovf: case OpCode.Sub_ovf_un: case OpCode.Endfinally: case OpCode.Stind_i: case OpCode.Conv_u: case OpCode.Prefix7: case OpCode.Prefix6: case OpCode.Prefix5: case OpCode.Prefix4: case OpCode.Prefix3: case OpCode.Prefix2: case OpCode.Prefix1: case OpCode.Prefixref: case OpCode.Arglist: case OpCode.Ceq: case OpCode.Cgt: case OpCode.Cgt_un: case OpCode.Clt: case OpCode.Clt_un: case OpCode.Localloc: case OpCode.Endfilter: case OpCode.Volatile: case OpCode.Tailcall: case OpCode.Cpblk: case OpCode.Initblk: case OpCode.Rethrow: case OpCode.Refanytype: case OpCode.Readonly: break; case OpCode.Br: case OpCode.Brfalse: case OpCode.Brtrue: case OpCode.Beq: case OpCode.Bge: case OpCode.Bgt: case OpCode.Ble: case OpCode.Blt: case OpCode.Bne_un: case OpCode.Bge_un: case OpCode.Bgt_un: case OpCode.Ble_un: case OpCode.Blt_un: case OpCode.Leave: { // NOTE: Delta is w.r.t. start of next instruction var delta = reader.ReadInt32(); Value = (int)(reader.Offset - beginOffset) + delta; } break; case OpCode.Br_s: case OpCode.Brfalse_s: case OpCode.Brtrue_s: case OpCode.Beq_s: case OpCode.Bge_s: case OpCode.Bgt_s: case OpCode.Ble_s: case OpCode.Blt_s: case OpCode.Bne_un_s: case OpCode.Bge_un_s: case OpCode.Bgt_un_s: case OpCode.Ble_un_s: case OpCode.Blt_un_s: case OpCode.Leave_s: { var delta = reader.ReadSByte(); Value = (int)(reader.Offset - beginOffset) + delta; } break; case OpCode.Ldc_i4_s: Value = (int)reader.ReadSByte(); break; case OpCode.Unaligned: case OpCode.Ldarg_s: case OpCode.Ldarga_s: case OpCode.Starg_s: case OpCode.Ldloc_s: case OpCode.Ldloca_s: case OpCode.Stloc_s: Value = (int)reader.ReadByte(); break; case OpCode.Ldc_i4: Value = reader.ReadInt32(); break; case OpCode.Ldarg: case OpCode.Ldarga: case OpCode.Starg: case OpCode.Ldloc: case OpCode.Ldloca: case OpCode.Stloc: Value = (int)reader.ReadUInt32(); break; case OpCode.Ldc_i8: Value = reader.ReadInt64(); break; case OpCode.Ldc_r4: Value = reader.ReadSingle(); break; case OpCode.Ldc_r8: Value = reader.ReadDouble(); break; case OpCode.Ldstr: Value = ReadUserString(ctxt, reader); break; case OpCode.Switch: { var numTargets = (int)reader.ReadUInt32(); var targets = new Seq<int>(numTargets); // Read as offsets from end of switch, then fixup to offsets from start of instructions for (var i = 0; i < numTargets; i++) targets.Add(reader.ReadInt32()); for (var i = 0; i < numTargets; i++) targets[i] = (int)(reader.Offset - beginOffset) + targets[i]; Value = targets; } break; case OpCode.Calli: case OpCode.Ldfld: case OpCode.Ldflda: case OpCode.Stfld: case OpCode.Ldsfld: case OpCode.Ldsflda: case OpCode.Stsfld: case OpCode.Jmp: case OpCode.Call: case OpCode.Callvirt: case OpCode.Newobj: case OpCode.Ldftn: case OpCode.Ldvirtftn: case OpCode.Ldtoken: case OpCode.Cpobj: case OpCode.Ldobj: case OpCode.Castclass: case OpCode.Isinst: case OpCode.Unbox: case OpCode.Stobj: case OpCode.Box: case OpCode.Newarr: case OpCode.Ldelema: case OpCode.Ldelem: case OpCode.Stelem: case OpCode.Unbox_any: case OpCode.Refanyval: case OpCode.Mkrefany: case OpCode.Initobj: case OpCode.Constrained: case OpCode.Sizeof: Value = resolveRow(OpCode, ReadToken(ctxt, reader)); break; default: throw new PEException("unrecognised opcode"); } }
private bool ReadMethodDataSection(ReaderContext ctxt, BlobReader reader, Func<OpCode, Row, object> resolveRow) { reader.Align(4); var flags = (CorILMethodSect)reader.ReadByte(); if ((flags & CorILMethodSect.EHTable) == 0) throw new PEException("unrecognised method data section"); var isFat = (flags & CorILMethodSect.FatFormat) != 0; var count = default(uint); if (isFat) { var size = reader.ReadUInt24(); if (size < 4 || (size - 4) % 24 != 0) throw new InvalidOperationException("invalid method data section"); count = (size - 4) / 24; } else { var size = (uint)reader.ReadByte(); // NOTE: Looks live VB emits size without including the 4 byte header... if (size < 4 || (size - 4) % 12 != 0) throw new InvalidOperationException("invalid method data section"); var padding = reader.ReadUInt16(); if (padding != 0) throw new PEException("unexpected data"); count = (size - 4) / 12; } for (var i = 0; i < count; i++) { var c = new ExceptionHandlingClause(); c.Read(ctxt, reader, isFat, resolveRow); ExceptionHandlingClauses.Add(c); } return (flags & CorILMethodSect.MoreSects) != 0; }
public void Read(ReaderContext ctxt, BlobReader reader, Func<OpCode, Row, object> resolveRow) { ExceptionHandlingClauses = new Seq<ExceptionHandlingClause>(); var firstByte = reader.ReadByte(); var formatKind = (CorILMethod)(firstByte & 0x3); var bodySize = default(uint); var more = default(bool); switch (formatKind) { case CorILMethod.TinyFormat: { MaxStack = 8; bodySize = (uint)(firstByte >> 2); break; } case CorILMethod.FatFormat: { var secondByte = reader.ReadByte(); var flags = (CorILMethod)(((ushort)(secondByte & 0x7) << 8) | (ushort)firstByte); IsInitLocals = (flags & CorILMethod.InitLocals) != 0; var headerSize = (secondByte >> 4) & 0x7; if (headerSize != 3) throw new PEException("unexpected method body header size"); MaxStack = (int)reader.ReadUInt16(); bodySize = reader.ReadUInt32(); LocalVarRef.Read(ctxt, reader); LocalVarRef.ResolveIndexes(ctxt); more = (flags & CorILMethod.MoreSects) != 0; break; } default: throw new InvalidOperationException("invalid method body format"); } if (bodySize > 0) { var beginOffset = reader.Offset; var endOffset = reader.Offset + bodySize; var n = 0; while (reader.Offset < endOffset) { n++; Instruction.Skip(reader); } reader.Offset = beginOffset; Instructions = new Instruction[n]; for (var i = 0; i < n; i++) Instructions[i].Read(ctxt, reader, beginOffset, resolveRow); } while (more) more = ReadMethodDataSection(ctxt, reader, resolveRow); }
public static void Skip(BlobReader reader) { var opCode = (OpCode)reader.ReadByte(); if (opCode == OpCode.Prefix1) { opCode = (OpCode)((ushort)opCode << 8 | reader.ReadByte()); } switch (opCode) { case OpCode.Nop: case OpCode.Break: case OpCode.Ldarg_0: case OpCode.Ldarg_1: case OpCode.Ldarg_2: case OpCode.Ldarg_3: case OpCode.Ldloc_0: case OpCode.Ldloc_1: case OpCode.Ldloc_2: case OpCode.Ldloc_3: case OpCode.Stloc_0: case OpCode.Stloc_1: case OpCode.Stloc_2: case OpCode.Stloc_3: case OpCode.Ldnull: case OpCode.Ldc_i4_m1: case OpCode.Ldc_i4_0: case OpCode.Ldc_i4_1: case OpCode.Ldc_i4_2: case OpCode.Ldc_i4_3: case OpCode.Ldc_i4_4: case OpCode.Ldc_i4_5: case OpCode.Ldc_i4_6: case OpCode.Ldc_i4_7: case OpCode.Ldc_i4_8: case OpCode.Dup: case OpCode.Pop: case OpCode.Ret: case OpCode.Ldind_i1: case OpCode.Ldind_u1: case OpCode.Ldind_i2: case OpCode.Ldind_u2: case OpCode.Ldind_i4: case OpCode.Ldind_u4: case OpCode.Ldind_i8: case OpCode.Ldind_i: case OpCode.Ldind_r4: case OpCode.Ldind_r8: case OpCode.Ldind_ref: case OpCode.Stind_ref: case OpCode.Stind_i1: case OpCode.Stind_i2: case OpCode.Stind_i4: case OpCode.Stind_i8: case OpCode.Stind_r4: case OpCode.Stind_r8: case OpCode.Add: case OpCode.Sub: case OpCode.Mul: case OpCode.Div: case OpCode.Div_un: case OpCode.Rem: case OpCode.Rem_un: case OpCode.And: case OpCode.Or: case OpCode.Xor: case OpCode.Shl: case OpCode.Shr: case OpCode.Shr_un: case OpCode.Neg: case OpCode.Not: case OpCode.Conv_i1: case OpCode.Conv_i2: case OpCode.Conv_i4: case OpCode.Conv_i8: case OpCode.Conv_r4: case OpCode.Conv_r8: case OpCode.Conv_u4: case OpCode.Conv_u8: case OpCode.Conv_r_un: case OpCode.Throw: case OpCode.Conv_ovf_i1_un: case OpCode.Conv_ovf_i2_un: case OpCode.Conv_ovf_i4_un: case OpCode.Conv_ovf_i8_un: case OpCode.Conv_ovf_u1_un: case OpCode.Conv_ovf_u2_un: case OpCode.Conv_ovf_u4_un: case OpCode.Conv_ovf_u8_un: case OpCode.Conv_ovf_i_un: case OpCode.Conv_ovf_u_un: case OpCode.Ldlen: case OpCode.Ldelem_i1: case OpCode.Ldelem_u1: case OpCode.Ldelem_i2: case OpCode.Ldelem_u2: case OpCode.Ldelem_i4: case OpCode.Ldelem_u4: case OpCode.Ldelem_i8: case OpCode.Ldelem_i: case OpCode.Ldelem_r4: case OpCode.Ldelem_r8: case OpCode.Ldelem_ref: case OpCode.Stelem_i: case OpCode.Stelem_i1: case OpCode.Stelem_i2: case OpCode.Stelem_i4: case OpCode.Stelem_i8: case OpCode.Stelem_r4: case OpCode.Stelem_r8: case OpCode.Stelem_ref: case OpCode.Conv_ovf_i1: case OpCode.Conv_ovf_u1: case OpCode.Conv_ovf_i2: case OpCode.Conv_ovf_u2: case OpCode.Conv_ovf_i4: case OpCode.Conv_ovf_u4: case OpCode.Conv_ovf_i8: case OpCode.Conv_ovf_u8: case OpCode.Ckfinite: case OpCode.Conv_u2: case OpCode.Conv_u1: case OpCode.Conv_i: case OpCode.Conv_ovf_i: case OpCode.Conv_ovf_u: case OpCode.Add_ovf: case OpCode.Add_ovf_un: case OpCode.Mul_ovf: case OpCode.Mul_ovf_un: case OpCode.Sub_ovf: case OpCode.Sub_ovf_un: case OpCode.Endfinally: case OpCode.Stind_i: case OpCode.Conv_u: case OpCode.Prefix7: case OpCode.Prefix6: case OpCode.Prefix5: case OpCode.Prefix4: case OpCode.Prefix3: case OpCode.Prefix2: case OpCode.Prefix1: case OpCode.Prefixref: case OpCode.Arglist: case OpCode.Ceq: case OpCode.Cgt: case OpCode.Cgt_un: case OpCode.Clt: case OpCode.Clt_un: case OpCode.Localloc: case OpCode.Endfilter: case OpCode.Volatile: case OpCode.Tailcall: case OpCode.Cpblk: case OpCode.Initblk: case OpCode.Rethrow: case OpCode.Refanytype: case OpCode.Readonly: break; case OpCode.Br_s: case OpCode.Brfalse_s: case OpCode.Brtrue_s: case OpCode.Beq_s: case OpCode.Bge_s: case OpCode.Bgt_s: case OpCode.Ble_s: case OpCode.Blt_s: case OpCode.Bne_un_s: case OpCode.Bge_un_s: case OpCode.Bgt_un_s: case OpCode.Ble_un_s: case OpCode.Blt_un_s: case OpCode.Leave_s: case OpCode.Ldc_i4_s: reader.ReadSByte(); break; case OpCode.Unaligned: case OpCode.Ldarg_s: case OpCode.Ldarga_s: case OpCode.Starg_s: case OpCode.Ldloc_s: case OpCode.Ldloca_s: case OpCode.Stloc_s: reader.ReadByte(); break; case OpCode.Br: case OpCode.Brfalse: case OpCode.Brtrue: case OpCode.Beq: case OpCode.Bge: case OpCode.Bgt: case OpCode.Ble: case OpCode.Blt: case OpCode.Bne_un: case OpCode.Bge_un: case OpCode.Bgt_un: case OpCode.Ble_un: case OpCode.Blt_un: case OpCode.Leave: case OpCode.Ldc_i4: reader.ReadInt32(); break; case OpCode.Ldfld: case OpCode.Ldflda: case OpCode.Stfld: case OpCode.Ldsfld: case OpCode.Ldsflda: case OpCode.Stsfld: case OpCode.Calli: case OpCode.Ldstr: case OpCode.Ldtoken: case OpCode.Cpobj: case OpCode.Ldobj: case OpCode.Castclass: case OpCode.Isinst: case OpCode.Unbox: case OpCode.Stobj: case OpCode.Box: case OpCode.Newarr: case OpCode.Ldelema: case OpCode.Ldelem: case OpCode.Stelem: case OpCode.Unbox_any: case OpCode.Refanyval: case OpCode.Mkrefany: case OpCode.Initobj: case OpCode.Constrained: case OpCode.Sizeof: case OpCode.Ldarg: case OpCode.Ldarga: case OpCode.Starg: case OpCode.Ldloc: case OpCode.Ldloca: case OpCode.Stloc: case OpCode.Jmp: case OpCode.Call: case OpCode.Callvirt: case OpCode.Newobj: case OpCode.Ldftn: case OpCode.Ldvirtftn: reader.ReadUInt32(); break; case OpCode.Ldc_i8: reader.ReadInt64(); break; case OpCode.Ldc_r4: reader.ReadSingle(); break; case OpCode.Ldc_r8: reader.ReadDouble(); break; case OpCode.Switch: { var numTargets = (int)reader.ReadUInt32(); for (var i = 0; i < numTargets; i++) { reader.ReadInt32(); } break; } default: throw new PEException("unrecognised opcode"); } }
public void Read(ReaderContext ctxt, BlobReader reader, uint beginOffset, Func <OpCode, Row, object> resolveRow) { Offset = (int)(reader.Offset - beginOffset); OpCode = (OpCode)reader.ReadByte(); if (OpCode == OpCode.Prefix1) { OpCode = (OpCode)((ushort)OpCode << 8 | reader.ReadByte()); } Value = default(object); switch (OpCode) { case OpCode.Nop: case OpCode.Break: case OpCode.Ldarg_0: case OpCode.Ldarg_1: case OpCode.Ldarg_2: case OpCode.Ldarg_3: case OpCode.Ldloc_0: case OpCode.Ldloc_1: case OpCode.Ldloc_2: case OpCode.Ldloc_3: case OpCode.Stloc_0: case OpCode.Stloc_1: case OpCode.Stloc_2: case OpCode.Stloc_3: case OpCode.Ldnull: case OpCode.Ldc_i4_m1: case OpCode.Ldc_i4_0: case OpCode.Ldc_i4_1: case OpCode.Ldc_i4_2: case OpCode.Ldc_i4_3: case OpCode.Ldc_i4_4: case OpCode.Ldc_i4_5: case OpCode.Ldc_i4_6: case OpCode.Ldc_i4_7: case OpCode.Ldc_i4_8: case OpCode.Dup: case OpCode.Pop: case OpCode.Ret: case OpCode.Ldind_i1: case OpCode.Ldind_u1: case OpCode.Ldind_i2: case OpCode.Ldind_u2: case OpCode.Ldind_i4: case OpCode.Ldind_u4: case OpCode.Ldind_i8: case OpCode.Ldind_i: case OpCode.Ldind_r4: case OpCode.Ldind_r8: case OpCode.Ldind_ref: case OpCode.Stind_ref: case OpCode.Stind_i1: case OpCode.Stind_i2: case OpCode.Stind_i4: case OpCode.Stind_i8: case OpCode.Stind_r4: case OpCode.Stind_r8: case OpCode.Add: case OpCode.Sub: case OpCode.Mul: case OpCode.Div: case OpCode.Div_un: case OpCode.Rem: case OpCode.Rem_un: case OpCode.And: case OpCode.Or: case OpCode.Xor: case OpCode.Shl: case OpCode.Shr: case OpCode.Shr_un: case OpCode.Neg: case OpCode.Not: case OpCode.Conv_i1: case OpCode.Conv_i2: case OpCode.Conv_i4: case OpCode.Conv_i8: case OpCode.Conv_r4: case OpCode.Conv_r8: case OpCode.Conv_u4: case OpCode.Conv_u8: case OpCode.Conv_r_un: case OpCode.Throw: case OpCode.Conv_ovf_i1_un: case OpCode.Conv_ovf_i2_un: case OpCode.Conv_ovf_i4_un: case OpCode.Conv_ovf_i8_un: case OpCode.Conv_ovf_u1_un: case OpCode.Conv_ovf_u2_un: case OpCode.Conv_ovf_u4_un: case OpCode.Conv_ovf_u8_un: case OpCode.Conv_ovf_i_un: case OpCode.Conv_ovf_u_un: case OpCode.Ldlen: case OpCode.Ldelem_i1: case OpCode.Ldelem_u1: case OpCode.Ldelem_i2: case OpCode.Ldelem_u2: case OpCode.Ldelem_i4: case OpCode.Ldelem_u4: case OpCode.Ldelem_i8: case OpCode.Ldelem_i: case OpCode.Ldelem_r4: case OpCode.Ldelem_r8: case OpCode.Ldelem_ref: case OpCode.Stelem_i: case OpCode.Stelem_i1: case OpCode.Stelem_i2: case OpCode.Stelem_i4: case OpCode.Stelem_i8: case OpCode.Stelem_r4: case OpCode.Stelem_r8: case OpCode.Stelem_ref: case OpCode.Conv_ovf_i1: case OpCode.Conv_ovf_u1: case OpCode.Conv_ovf_i2: case OpCode.Conv_ovf_u2: case OpCode.Conv_ovf_i4: case OpCode.Conv_ovf_u4: case OpCode.Conv_ovf_i8: case OpCode.Conv_ovf_u8: case OpCode.Ckfinite: case OpCode.Conv_u2: case OpCode.Conv_u1: case OpCode.Conv_i: case OpCode.Conv_ovf_i: case OpCode.Conv_ovf_u: case OpCode.Add_ovf: case OpCode.Add_ovf_un: case OpCode.Mul_ovf: case OpCode.Mul_ovf_un: case OpCode.Sub_ovf: case OpCode.Sub_ovf_un: case OpCode.Endfinally: case OpCode.Stind_i: case OpCode.Conv_u: case OpCode.Prefix7: case OpCode.Prefix6: case OpCode.Prefix5: case OpCode.Prefix4: case OpCode.Prefix3: case OpCode.Prefix2: case OpCode.Prefix1: case OpCode.Prefixref: case OpCode.Arglist: case OpCode.Ceq: case OpCode.Cgt: case OpCode.Cgt_un: case OpCode.Clt: case OpCode.Clt_un: case OpCode.Localloc: case OpCode.Endfilter: case OpCode.Volatile: case OpCode.Tailcall: case OpCode.Cpblk: case OpCode.Initblk: case OpCode.Rethrow: case OpCode.Refanytype: case OpCode.Readonly: break; case OpCode.Br: case OpCode.Brfalse: case OpCode.Brtrue: case OpCode.Beq: case OpCode.Bge: case OpCode.Bgt: case OpCode.Ble: case OpCode.Blt: case OpCode.Bne_un: case OpCode.Bge_un: case OpCode.Bgt_un: case OpCode.Ble_un: case OpCode.Blt_un: case OpCode.Leave: { // NOTE: Delta is w.r.t. start of next instruction var delta = reader.ReadInt32(); Value = (int)(reader.Offset - beginOffset) + delta; } break; case OpCode.Br_s: case OpCode.Brfalse_s: case OpCode.Brtrue_s: case OpCode.Beq_s: case OpCode.Bge_s: case OpCode.Bgt_s: case OpCode.Ble_s: case OpCode.Blt_s: case OpCode.Bne_un_s: case OpCode.Bge_un_s: case OpCode.Bgt_un_s: case OpCode.Ble_un_s: case OpCode.Blt_un_s: case OpCode.Leave_s: { var delta = reader.ReadSByte(); Value = (int)(reader.Offset - beginOffset) + delta; } break; case OpCode.Ldc_i4_s: Value = (int)reader.ReadSByte(); break; case OpCode.Unaligned: case OpCode.Ldarg_s: case OpCode.Ldarga_s: case OpCode.Starg_s: case OpCode.Ldloc_s: case OpCode.Ldloca_s: case OpCode.Stloc_s: Value = (int)reader.ReadByte(); break; case OpCode.Ldc_i4: Value = reader.ReadInt32(); break; case OpCode.Ldarg: case OpCode.Ldarga: case OpCode.Starg: case OpCode.Ldloc: case OpCode.Ldloca: case OpCode.Stloc: Value = (int)reader.ReadUInt32(); break; case OpCode.Ldc_i8: Value = reader.ReadInt64(); break; case OpCode.Ldc_r4: Value = reader.ReadSingle(); break; case OpCode.Ldc_r8: Value = reader.ReadDouble(); break; case OpCode.Ldstr: Value = ReadUserString(ctxt, reader); break; case OpCode.Switch: { var numTargets = (int)reader.ReadUInt32(); var targets = new Seq <int>(numTargets); // Read as offsets from end of switch, then fixup to offsets from start of instructions for (var i = 0; i < numTargets; i++) { targets.Add(reader.ReadInt32()); } for (var i = 0; i < numTargets; i++) { targets[i] = (int)(reader.Offset - beginOffset) + targets[i]; } Value = targets; } break; case OpCode.Calli: case OpCode.Ldfld: case OpCode.Ldflda: case OpCode.Stfld: case OpCode.Ldsfld: case OpCode.Ldsflda: case OpCode.Stsfld: case OpCode.Jmp: case OpCode.Call: case OpCode.Callvirt: case OpCode.Newobj: case OpCode.Ldftn: case OpCode.Ldvirtftn: case OpCode.Ldtoken: case OpCode.Cpobj: case OpCode.Ldobj: case OpCode.Castclass: case OpCode.Isinst: case OpCode.Unbox: case OpCode.Stobj: case OpCode.Box: case OpCode.Newarr: case OpCode.Ldelema: case OpCode.Ldelem: case OpCode.Stelem: case OpCode.Unbox_any: case OpCode.Refanyval: case OpCode.Mkrefany: case OpCode.Initobj: case OpCode.Constrained: case OpCode.Sizeof: Value = resolveRow(OpCode, ReadToken(ctxt, reader)); break; default: throw new PEException("unrecognised opcode"); } }
public static LocalVarMemberSig ReadLocalVar(ReaderContext ctxt, BlobReader reader) { var tag = (MemberSigTag)reader.ReadByte(); var res = new LocalVarMemberSig { Tag = tag }; res.ReadRest(ctxt, reader); return res; }
public void Read(ReaderContext ctxt, BlobReader reader, Func <OpCode, Row, object> resolveRow) { ExceptionHandlingClauses = new Seq <ExceptionHandlingClause>(); var firstByte = reader.ReadByte(); var formatKind = (CorILMethod)(firstByte & 0x3); var bodySize = default(uint); var more = default(bool); switch (formatKind) { case CorILMethod.TinyFormat: { MaxStack = 8; bodySize = (uint)(firstByte >> 2); break; } case CorILMethod.FatFormat: { var secondByte = reader.ReadByte(); var flags = (CorILMethod)(((ushort)(secondByte & 0x7) << 8) | (ushort)firstByte); IsInitLocals = (flags & CorILMethod.InitLocals) != 0; var headerSize = (secondByte >> 4) & 0x7; if (headerSize != 3) { throw new PEException("unexpected method body header size"); } MaxStack = (int)reader.ReadUInt16(); bodySize = reader.ReadUInt32(); LocalVarRef.Read(ctxt, reader); LocalVarRef.ResolveIndexes(ctxt); more = (flags & CorILMethod.MoreSects) != 0; break; } default: throw new InvalidOperationException("invalid method body format"); } if (bodySize > 0) { var beginOffset = reader.Offset; var endOffset = reader.Offset + bodySize; var n = 0; while (reader.Offset < endOffset) { n++; Instruction.Skip(reader); } reader.Offset = beginOffset; Instructions = new Instruction[n]; for (var i = 0; i < n; i++) { Instructions[i].Read(ctxt, reader, beginOffset, resolveRow); } } while (more) { more = ReadMethodDataSection(ctxt, reader, resolveRow); } }
public static MethodMemberSig ReadMethod(ReaderContext ctxt, BlobReader reader) { var tag = (MemberSigTag)reader.ReadByte(); var res = new MethodMemberSig { Tag = tag }; res.ReadRest(ctxt, reader); return res; }
public static MemberSig Read(ReaderContext ctxt, BlobReader reader) { var tag = (MemberSigTag)reader.ReadByte(); var res = default(MemberSig); switch (tag & MemberSigTag.MASK) { case MemberSigTag.FIELD: res = new FieldMemberSig(); break; case MemberSigTag.PROPERTY: res = new PropertyMemberSig { Tag = tag }; break; case MemberSigTag.LOCAL_SIG: res = new LocalVarMemberSig(); break; case MemberSigTag.GENERICINST: res = new MethodSpecMemberSig(); break; default: res = new MethodMemberSig { Tag = tag }; break; } res.ReadRest(ctxt, reader); return res; }
public void Read(IImSeq<CustomAttributePropertyType> fixedArgTypes, BlobReader reader, Func<string, CustomAttributePropertyType> resolveType) { var fieldArgs = default(Map<string, CustomAttributeProperty>); var propertyArgs = default(Map<string, CustomAttributeProperty>); if (reader.AtEndOfBlob) { if (fixedArgTypes.Count > 0) throw new PEException("expected fixed arguments in custom attribute"); FixedArgs = Constants.EmptyCustomAttributeProperties; FieldArgs = Constants.EmptyNamedCustomAttributueProperties; PropertyArgs = Constants.EmptyNamedCustomAttributueProperties; } else { if (reader.ReadUInt16() != prolog) throw new PEException("invalid custom attribute"); if (fixedArgTypes.Count > 0) { var fixedArgs = new Seq<CustomAttributeProperty>(fixedArgTypes.Count); for (var i = 0; i < fixedArgTypes.Count; i++) { var type = fixedArgTypes[i]; fixedArgs.Add (new CustomAttributeProperty { Type = type, Value = type.ReadValue(reader, resolveType) }); } FixedArgs = fixedArgs; } else FixedArgs = Constants.EmptyCustomAttributeProperties; var numNamed = reader.ReadUInt16(); for (var i = 0; i < numNamed; i++) { var tag = (TypeSigTag)reader.ReadByte(); var type = CustomAttributePropertyType.Read(reader, resolveType); var nm = reader.ReadUTF8SizedString(); var prop = new CustomAttributeProperty { Type = type, Value = type.ReadValue(reader, resolveType) }; if (tag == TypeSigTag.CUSTOM_ATTRIBUTE_FIELD) { if (fieldArgs == null) fieldArgs = new Map<string, CustomAttributeProperty>(); if (fieldArgs.ContainsKey(nm)) throw new PEException("duplicate named field in custom attribute"); fieldArgs.Add(nm, prop); } else if (tag == TypeSigTag.CUSTOM_ATTRIBUTE_PROPERTY) { if (propertyArgs == null) propertyArgs = new Map<string, CustomAttributeProperty>(); if (propertyArgs.ContainsKey(nm)) throw new PEException("duplicate named property in custom attribute"); propertyArgs.Add(nm, prop); } else throw new PEException("invalid custom attribute"); } FieldArgs = fieldArgs ?? Constants.EmptyNamedCustomAttributueProperties; PropertyArgs = propertyArgs ?? Constants.EmptyNamedCustomAttributueProperties; } }
public override object ReadValue(BlobReader reader, Func<string, CustomAttributePropertyType> resolveType) { switch (Type) { case PrimitiveType.Boolean: return reader.ReadByte() == 0 ? false : true; case PrimitiveType.Char: return (char)reader.ReadUInt16(); case PrimitiveType.Int8: return reader.ReadSByte(); case PrimitiveType.Int16: return reader.ReadInt16(); case PrimitiveType.Int32: return reader.ReadInt32(); case PrimitiveType.Int64: return reader.ReadInt64(); case PrimitiveType.UInt8: return reader.ReadByte(); case PrimitiveType.UInt16: return reader.ReadUInt16(); case PrimitiveType.UInt32: return reader.ReadUInt32(); case PrimitiveType.UInt64: return reader.ReadUInt64(); case PrimitiveType.IntNative: case PrimitiveType.UIntNative: throw new PEException("cannot read native integers"); case PrimitiveType.Single: return reader.ReadSingle(); case PrimitiveType.Double: return reader.ReadDouble(); case PrimitiveType.String: return reader.ReadUTF8SizedString(); case PrimitiveType.Type: return new TypeCustomAttributePropertyValue { Name = reader.ReadUTF8SizedString() }; case PrimitiveType.Object: case PrimitiveType.TypedRef: case PrimitiveType.Void: throw new PEException("invalid type tag in custom attribute"); default: throw new ArgumentOutOfRangeException(); } }
public static CustomAttributePropertyType Read(BlobReader reader, Func<string, CustomAttributePropertyType> resolveType) { var tag = (TypeSigTag)reader.ReadByte(); var res = default(CustomAttributePropertyType); switch (tag) { case TypeSigTag.SZARRAY: res = new ArrayCustomAttributePropertyType(); break; case TypeSigTag.CUSTOM_ATTRIBUTE_BOXED_ARGUMENT: res = new ObjectCustomAttributePropertyType(); break; case TypeSigTag.CUSTOM_ATTRIBUTE_ENUM: { var typeName = reader.ReadUTF8SizedString(); res = resolveType(typeName); if (!(res is EnumCustomAttributePropertyType)) throw new PEException("invalid enumeration type in custom attribute"); break; } default: res = new PrimitiveCustomAttributePropertyType { Type = PrimitiveTypeSig.FromTag(tag) }; break; } res.ReadRest(reader, resolveType); return res; }
public static void Skip(BlobReader reader) { var opCode = (OpCode)reader.ReadByte(); if (opCode == OpCode.Prefix1) opCode = (OpCode)((ushort)opCode << 8 | reader.ReadByte()); switch (opCode) { case OpCode.Nop: case OpCode.Break: case OpCode.Ldarg_0: case OpCode.Ldarg_1: case OpCode.Ldarg_2: case OpCode.Ldarg_3: case OpCode.Ldloc_0: case OpCode.Ldloc_1: case OpCode.Ldloc_2: case OpCode.Ldloc_3: case OpCode.Stloc_0: case OpCode.Stloc_1: case OpCode.Stloc_2: case OpCode.Stloc_3: case OpCode.Ldnull: case OpCode.Ldc_i4_m1: case OpCode.Ldc_i4_0: case OpCode.Ldc_i4_1: case OpCode.Ldc_i4_2: case OpCode.Ldc_i4_3: case OpCode.Ldc_i4_4: case OpCode.Ldc_i4_5: case OpCode.Ldc_i4_6: case OpCode.Ldc_i4_7: case OpCode.Ldc_i4_8: case OpCode.Dup: case OpCode.Pop: case OpCode.Ret: case OpCode.Ldind_i1: case OpCode.Ldind_u1: case OpCode.Ldind_i2: case OpCode.Ldind_u2: case OpCode.Ldind_i4: case OpCode.Ldind_u4: case OpCode.Ldind_i8: case OpCode.Ldind_i: case OpCode.Ldind_r4: case OpCode.Ldind_r8: case OpCode.Ldind_ref: case OpCode.Stind_ref: case OpCode.Stind_i1: case OpCode.Stind_i2: case OpCode.Stind_i4: case OpCode.Stind_i8: case OpCode.Stind_r4: case OpCode.Stind_r8: case OpCode.Add: case OpCode.Sub: case OpCode.Mul: case OpCode.Div: case OpCode.Div_un: case OpCode.Rem: case OpCode.Rem_un: case OpCode.And: case OpCode.Or: case OpCode.Xor: case OpCode.Shl: case OpCode.Shr: case OpCode.Shr_un: case OpCode.Neg: case OpCode.Not: case OpCode.Conv_i1: case OpCode.Conv_i2: case OpCode.Conv_i4: case OpCode.Conv_i8: case OpCode.Conv_r4: case OpCode.Conv_r8: case OpCode.Conv_u4: case OpCode.Conv_u8: case OpCode.Conv_r_un: case OpCode.Throw: case OpCode.Conv_ovf_i1_un: case OpCode.Conv_ovf_i2_un: case OpCode.Conv_ovf_i4_un: case OpCode.Conv_ovf_i8_un: case OpCode.Conv_ovf_u1_un: case OpCode.Conv_ovf_u2_un: case OpCode.Conv_ovf_u4_un: case OpCode.Conv_ovf_u8_un: case OpCode.Conv_ovf_i_un: case OpCode.Conv_ovf_u_un: case OpCode.Ldlen: case OpCode.Ldelem_i1: case OpCode.Ldelem_u1: case OpCode.Ldelem_i2: case OpCode.Ldelem_u2: case OpCode.Ldelem_i4: case OpCode.Ldelem_u4: case OpCode.Ldelem_i8: case OpCode.Ldelem_i: case OpCode.Ldelem_r4: case OpCode.Ldelem_r8: case OpCode.Ldelem_ref: case OpCode.Stelem_i: case OpCode.Stelem_i1: case OpCode.Stelem_i2: case OpCode.Stelem_i4: case OpCode.Stelem_i8: case OpCode.Stelem_r4: case OpCode.Stelem_r8: case OpCode.Stelem_ref: case OpCode.Conv_ovf_i1: case OpCode.Conv_ovf_u1: case OpCode.Conv_ovf_i2: case OpCode.Conv_ovf_u2: case OpCode.Conv_ovf_i4: case OpCode.Conv_ovf_u4: case OpCode.Conv_ovf_i8: case OpCode.Conv_ovf_u8: case OpCode.Ckfinite: case OpCode.Conv_u2: case OpCode.Conv_u1: case OpCode.Conv_i: case OpCode.Conv_ovf_i: case OpCode.Conv_ovf_u: case OpCode.Add_ovf: case OpCode.Add_ovf_un: case OpCode.Mul_ovf: case OpCode.Mul_ovf_un: case OpCode.Sub_ovf: case OpCode.Sub_ovf_un: case OpCode.Endfinally: case OpCode.Stind_i: case OpCode.Conv_u: case OpCode.Prefix7: case OpCode.Prefix6: case OpCode.Prefix5: case OpCode.Prefix4: case OpCode.Prefix3: case OpCode.Prefix2: case OpCode.Prefix1: case OpCode.Prefixref: case OpCode.Arglist: case OpCode.Ceq: case OpCode.Cgt: case OpCode.Cgt_un: case OpCode.Clt: case OpCode.Clt_un: case OpCode.Localloc: case OpCode.Endfilter: case OpCode.Volatile: case OpCode.Tailcall: case OpCode.Cpblk: case OpCode.Initblk: case OpCode.Rethrow: case OpCode.Refanytype: case OpCode.Readonly: break; case OpCode.Br_s: case OpCode.Brfalse_s: case OpCode.Brtrue_s: case OpCode.Beq_s: case OpCode.Bge_s: case OpCode.Bgt_s: case OpCode.Ble_s: case OpCode.Blt_s: case OpCode.Bne_un_s: case OpCode.Bge_un_s: case OpCode.Bgt_un_s: case OpCode.Ble_un_s: case OpCode.Blt_un_s: case OpCode.Leave_s: case OpCode.Ldc_i4_s: reader.ReadSByte(); break; case OpCode.Unaligned: case OpCode.Ldarg_s: case OpCode.Ldarga_s: case OpCode.Starg_s: case OpCode.Ldloc_s: case OpCode.Ldloca_s: case OpCode.Stloc_s: reader.ReadByte(); break; case OpCode.Br: case OpCode.Brfalse: case OpCode.Brtrue: case OpCode.Beq: case OpCode.Bge: case OpCode.Bgt: case OpCode.Ble: case OpCode.Blt: case OpCode.Bne_un: case OpCode.Bge_un: case OpCode.Bgt_un: case OpCode.Ble_un: case OpCode.Blt_un: case OpCode.Leave: case OpCode.Ldc_i4: reader.ReadInt32(); break; case OpCode.Ldfld: case OpCode.Ldflda: case OpCode.Stfld: case OpCode.Ldsfld: case OpCode.Ldsflda: case OpCode.Stsfld: case OpCode.Calli: case OpCode.Ldstr: case OpCode.Ldtoken: case OpCode.Cpobj: case OpCode.Ldobj: case OpCode.Castclass: case OpCode.Isinst: case OpCode.Unbox: case OpCode.Stobj: case OpCode.Box: case OpCode.Newarr: case OpCode.Ldelema: case OpCode.Ldelem: case OpCode.Stelem: case OpCode.Unbox_any: case OpCode.Refanyval: case OpCode.Mkrefany: case OpCode.Initobj: case OpCode.Constrained: case OpCode.Sizeof: case OpCode.Ldarg: case OpCode.Ldarga: case OpCode.Starg: case OpCode.Ldloc: case OpCode.Ldloca: case OpCode.Stloc: case OpCode.Jmp: case OpCode.Call: case OpCode.Callvirt: case OpCode.Newobj: case OpCode.Ldftn: case OpCode.Ldvirtftn: reader.ReadUInt32(); break; case OpCode.Ldc_i8: reader.ReadInt64(); break; case OpCode.Ldc_r4: reader.ReadSingle(); break; case OpCode.Ldc_r8: reader.ReadDouble(); break; case OpCode.Switch: { var numTargets = (int)reader.ReadUInt32(); for (var i = 0; i < numTargets; i++) reader.ReadInt32(); break; } default: throw new PEException("unrecognised opcode"); } }
public RVA BaseOfData; // == start of .reloc or .rsrc section, whichever is lower public void Read(ReaderContext ctxt, BlobReader reader) { var actualMagic = reader.ReadUInt16(); if (actualMagic != magic) throw new PEException("invalid PEHeaderStandardFields.Magic"); LMajor = reader.ReadByte(); if (LMajor < lMajorLow || LMajor > lMajorHigh) throw new PEException("invalid PEHeaderStandardFields.LMajor"); var actualLMinor = reader.ReadByte(); if (actualLMinor != lMinor) throw new PEException("invalid PEHeaderStandardFields.LMinor"); CodeSize = reader.ReadUInt32(); InitializedDataSize = reader.ReadUInt32(); var actualUninitializedDataSize = reader.ReadUInt32(); if (actualUninitializedDataSize != uninitializedDataSize) throw new PEException("invalid PEHeaderStandardFields.UninitializedDataSize"); EntryPoint.Read(reader); BaseOfCode.Read(reader); BaseOfData.Read(reader); if (ctxt.Tracer != null) { ctxt.Tracer.AppendLine(String.Format("PEHeaderStandardFields.CodeSize: {0:x8}", CodeSize)); ctxt.Tracer.AppendLine (String.Format("PEHeaderStandardFields.InitializedDataSize: {0:x8}", InitializedDataSize)); } }
public static PropertyMemberSig ReadProperty(ReaderContext ctxt, BlobReader reader) { var tag = (MemberSigTag)reader.ReadByte(); var res = new PropertyMemberSig { Tag = tag }; res.ReadRest(ctxt, reader); return res; }