/// <summary> /// Creates a CIL method body from a raw CIL method body. /// </summary> /// <param name="method">The method that owns the method body.</param> /// <param name="rawBody">The raw method body.</param> /// <param name="operandResolver">The object instance to use for resolving operands of an instruction in the /// method body.</param> /// <returns>The method body.</returns> public static CilMethodBody FromRawMethodBody(MethodDefinition method, CilRawMethodBody rawBody, ICilOperandResolver operandResolver = null) { var result = new CilMethodBody(method); if (operandResolver is null) operandResolver = result; // Read raw instructions. var reader = new ByteArrayReader(rawBody.Code); var disassembler = new CilDisassembler(reader); result.Instructions.AddRange(disassembler.ReadAllInstructions()); // Read out extra metadata. if (rawBody is CilRawFatMethodBody fatBody) { result.MaxStack = fatBody.MaxStack; result.InitializeLocals = fatBody.InitLocals; ReadLocalVariables(method.Module, result, fatBody); ReadExceptionHandlers(fatBody, result); } else { result.MaxStack = 8; result.InitializeLocals = false; } // Resolve operands. foreach (var instruction in result.Instructions) instruction.Operand = ResolveOperand(result, instruction, operandResolver) ?? instruction.Operand; return result; }
private static FieldRvaRow FindFieldRvaRow(TablesStream tablesStream, MetadataToken cctorToken, MetadataToken fieldToken) { var reader = tablesStream .GetTable <MethodDefinitionRow>(TableIndex.Method) .GetByRid(cctorToken.Rid) .Body.CreateReader(); var body = CilRawMethodBody.FromReader(ThrowErrorListener.Instance, reader); var disassembler = new CilDisassembler(new ByteArrayReader(body.Code)); var initialValueFieldToken = MetadataToken.Zero; var instructions = disassembler.ReadAllInstructions(); for (int i = 0; i < instructions.Count; i++) { if (instructions[i].OpCode.Code == CilCode.Ldtoken && instructions[i + 2].OpCode.Code == CilCode.Stsfld && (MetadataToken)instructions[i + 2].Operand == fieldToken) { initialValueFieldToken = (MetadataToken)instructions[i].Operand; break; } } Assert.NotEqual(MetadataToken.Zero, initialValueFieldToken); Assert.True(tablesStream .GetTable <FieldRvaRow>(TableIndex.FieldRva) .TryGetRowByKey(1, initialValueFieldToken.Rid, out var fieldRvaRow)); return(fieldRvaRow); }
private void RunTest(string sExp, params byte[] bytes) { var image = new LoadedImage(Address.Ptr32(0x0100000), bytes); var dasm = new CilDisassembler(image.CreateLeReader(0)).GetEnumerator(); Assert.IsTrue(dasm.MoveNext()); var instr = dasm.Current; Assert.AreEqual(sExp, instr.ToString()); }
private void RunTest(string sExp, params byte[] bytes) { var image = new MemoryArea(Address.Ptr32(0x0100000), bytes); var dasm = new CilDisassembler(image.CreateLeReader(0)).GetEnumerator(); Assert.IsTrue(dasm.MoveNext()); var instr = dasm.Current; Assert.AreEqual(sExp, instr.ToString()); }
/// <summary> /// Creates a CIL method body from a dynamic method. /// </summary> /// <param name="method">The method that owns the method body.</param> /// <param name="dynamicMethodObj">The Dynamic Method/Delegate/DynamicResolver.</param> /// <param name="operandResolver"> /// The object instance to use for resolving operands of an instruction in the /// method body. /// </param> /// <param name="importer"> /// The object instance to use for importing operands of an instruction in the /// method body. /// </param> /// <returns>The method body.</returns> public static CilMethodBody FromDynamicMethod( MethodDefinition method, object dynamicMethodObj, ICilOperandResolver operandResolver = null, ReferenceImporter importer = null) { if (!(method.Module is SerializedModuleDefinition module)) { throw new ArgumentException("Method body should reference a serialized module."); } var result = new CilMethodBody(method); operandResolver ??= new CilOperandResolver(method.Module, result); importer ??= new ReferenceImporter(method.Module); dynamicMethodObj = DynamicMethodHelper.ResolveDynamicResolver(dynamicMethodObj); //Get Runtime Fields var code = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_code"); var scope = FieldReader.ReadField <object>(dynamicMethodObj, "m_scope"); var tokenList = FieldReader.ReadField <List <object> >(scope, "m_tokens"); var localSig = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_localSignature"); var ehHeader = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_exceptionHeader"); var ehInfos = FieldReader.ReadField <IList <object> >(dynamicMethodObj, "m_exceptions"); // Read raw instructions. var reader = new ByteArrayReader(code); var disassembler = new CilDisassembler(reader); result.Instructions.AddRange(disassembler.ReadAllInstructions()); //Local Variables DynamicMethodHelper.ReadLocalVariables(result, method, localSig); //Exception Handlers DynamicMethodHelper.ReadReflectionExceptionHandlers(result, ehInfos, ehHeader, importer); // Resolve all operands. foreach (var instruction in result.Instructions) { instruction.Operand = DynamicMethodHelper.ResolveOperandReflection(module.ReaderContext, result, instruction, operandResolver, tokenList, importer) ?? instruction.Operand; } return(result); }
private void RunTest(string sExp, params byte[] bytes) { var image = new ByteMemoryArea(Address.Ptr32(0x0100000), bytes); var sc = new ServiceContainer(); sc.AddService <ITestGenerationService>(new UnitTestGenerationService(sc)); var arch = new CilArchitecture { Services = sc, }; var dasm = new CilDisassembler(arch, image.CreateLeReader(0)).GetEnumerator(); Assert.IsTrue(dasm.MoveNext()); var instr = dasm.Current; Assert.AreEqual(sExp, instr.ToString()); }
public void ShortInlineVariable() { var rawCode = new DataSegment(new byte[] { 0x11, 0x01, // ldloc.s 1 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Ldloc_S, (byte)1), new CilInstruction(2, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void InlineArgument() { var rawCode = new DataSegment(new byte[] { 0xFE, 0x09, 0x01, 0x00, // ldarg 1 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Ldarg, (ushort)1), new CilInstruction(4, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void InlineTok() { var rawCode = new DataSegment(new byte[] { 0xD0, 0x02, 0x00, 0x00, 0x01, // ldtoken 0x01000002 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Ldtoken, new MetadataToken(0x01000002)), new CilInstruction(5, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void InlineI() { var rawCode = new DataSegment(new byte[] { 0x20, 0x04, 0x03, 0x02, 0x01, // ldc.i4 0x01020304 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Ldc_I4, 0x01020304), new CilInstruction(5, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadInstructions()); }
public void InlineMethod() { var rawCode = new DataSegment(new byte[] { 0x28, 0x01, 0x00, 0x00, 0x0A, // call 0x0A000001 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Call, new MetadataToken(0x0A000001)), new CilInstruction(5, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void InlineI8() { var rawCode = new DataSegment(new byte[] { 0x21, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, // ldc.i8 0x0102030405060708 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Ldc_I8, 0x0102030405060708), new CilInstruction(9, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void ShortInlineI() { var rawCode = new DataSegment(new byte[] { 0x1F, 0x12, // ldc.i4.s 0x12 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Ldc_I4_S, (sbyte)0x12), new CilInstruction(2, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void InlineType() { var rawCode = new DataSegment(new byte[] { 0x02, // ldarg.0 0x74, 0x02, 0x00, 0x00, 0x01, // castclass 0x01000002 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Ldarg_0), new CilInstruction(1, CilOpCodes.Castclass, new MetadataToken(0x01000002)), new CilInstruction(6, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void ShortInlineBrTarget() { var rawCode = new DataSegment(new byte[] { 0x2B, 0x02, // br IL_0004 0x00, // nop 0x00, // nop 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Br_S, new CilOffsetLabel(0x0004)), new CilInstruction(2, CilOpCodes.Nop), new CilInstruction(3, CilOpCodes.Nop), new CilInstruction(4, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadInstructions()); }
public void InlineBrTarget() { var rawCode = new DataSegment(new byte[] { 0x38, 0x02, 0x00, 0x00, 0x00, // br IL_0007 0x00, // nop 0x00, // nop 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Br, new CilOffsetLabel(0x0007)), new CilInstruction(5, CilOpCodes.Nop), new CilInstruction(6, CilOpCodes.Nop), new CilInstruction(7, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void InlineSwitch() { var rawCode = new DataSegment(new byte[] { 0x45, 0x03, 0x00, 0x00, 0x00, // switch 0x02, 0x00, 0x00, 0x00, // IL_0013 0x04, 0x00, 0x00, 0x00, // IL_0015 0x06, 0x00, 0x00, 0x00, // IL_0017 0x00, // nop 0x00, // nop 0x00, // nop 0x00, // nop 0x00, // nop 0x00, // nop 0x2A // ret }); var expectedLabels = new[] { 0x0013, 0x0015, 0x0017 } .Select(offset => new CilOffsetLabel(offset)) .Cast <ICilLabel>() .ToArray(); var expected = new[] { new CilInstruction(0, CilOpCodes.Switch, expectedLabels), new CilInstruction(17, CilOpCodes.Nop), new CilInstruction(18, CilOpCodes.Nop), new CilInstruction(19, CilOpCodes.Nop), new CilInstruction(20, CilOpCodes.Nop), new CilInstruction(21, CilOpCodes.Nop), new CilInstruction(22, CilOpCodes.Nop), new CilInstruction(23, CilOpCodes.Ret) }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }
public void InlineNone() { var rawCode = new DataSegment(new byte[] { 0x00, // nop 0x17, // ldc.i4.1 0x18, // ldc.i4.2 0x58, // add 0x2A // ret }); var expected = new[] { new CilInstruction(0, CilOpCodes.Nop), new CilInstruction(1, CilOpCodes.Ldc_I4_1), new CilInstruction(2, CilOpCodes.Ldc_I4_2), new CilInstruction(3, CilOpCodes.Add), new CilInstruction(4, CilOpCodes.Ret), }; var disassembler = new CilDisassembler(rawCode.CreateReader()); Assert.Equal(expected, disassembler.ReadAllInstructions()); }