Example #1
0
        /// <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;
        }
Example #2
0
        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());
 }
Example #4
0
        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());
        }
Example #5
0
        /// <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());
        }
Example #10
0
        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());
        }
Example #15
0
        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());
        }