Example #1
0
        private void ReplaceOperands(CilMethodBody cilMethodBody)
        {
            foreach (var instruction in cilMethodBody.Instructions)
            {
                switch (instruction.OpCode.Code)
                {
                case CilCode.Br:
                case CilCode.Brtrue:
                case CilCode.Brfalse:
                    instruction.Operand = new CilInstructionLabel(cilMethodBody.Instructions[(int)instruction.Operand + 1]);
                    break;

                case CilCode.Ldloc:
                case CilCode.Stloc:
                    //NashaVM handles all local variables as type of object, which means it doesn't give us info
                    //about them. I'm planning to make something to recover them soon.
                    instruction.Operand = cilMethodBody.LocalVariables.Count > (int)instruction.Operand
                            ? cilMethodBody.LocalVariables[(int)instruction.Operand]
                            : new CilLocalVariable(cilMethodBody.Owner.Module.CorLibTypeFactory.Object);
                    if (instruction.Operand is CilLocalVariable variable && variable.Index == -1)
                    {
                        cilMethodBody.LocalVariables.Add(variable);
                    }
                    break;

                case CilCode.Ldarg:
                    instruction.Operand =
                        cilMethodBody.Owner.Parameters.GetBySignatureIndex((short)instruction.Operand);
                    break;
                }
            }
        }
        private CilInstructionCollection CreateDummyMethod(bool hasThis, int paramCount, int localCount)
        {
            var flags = hasThis
                ? MethodAttributes.Public
                : MethodAttributes.Public | MethodAttributes.Static;

            var parameterTypes = Enumerable.Repeat <TypeSignature>(_module.CorLibTypeFactory.Object, paramCount);

            var signature = hasThis
                ? MethodSignature.CreateInstance(_module.CorLibTypeFactory.Void, parameterTypes)
                : MethodSignature.CreateStatic(_module.CorLibTypeFactory.Void, parameterTypes);

            var method = new MethodDefinition("Dummy", flags, signature);

            var body = new CilMethodBody(method);

            for (int i = 0; i < localCount; i++)
            {
                body.LocalVariables.Add(new CilLocalVariable(_module.CorLibTypeFactory.Object));
            }

            method.MethodBody = body;

            return(body.Instructions);
        }
Example #3
0
        /// <inheritdoc />
        public MethodBody ReadMethodBody(MethodDefinition owner, MethodDefinitionRow row)
        {
            try
            {
                if (row.Body.CanRead)
                {
                    if (owner.IsIL)
                    {
                        var rawBody = CilRawMethodBody.FromReader(row.Body.CreateReader());
                        return(CilMethodBody.FromRawMethodBody(owner, rawBody));
                    }
                    else
                    {
                        // TODO: handle native method bodies.
                    }
                }
                else if (row.Body.IsBounded && row.Body.GetSegment() is CilRawMethodBody rawMethodBody)
                {
                    return(CilMethodBody.FromRawMethodBody(owner, rawMethodBody));
                }
            }
            catch when(!ThrowOnInvalidMethodBody)
            {
                return(null);
            }

            return(null);
        }
Example #4
0
        /// <summary>
        /// Constructs a control flow graph and a data flow graph from a CIL method body.
        /// </summary>
        /// <param name="self">The method body.</param>
        /// <param name="dataFlowGraph">The constructed data flow graph.</param>
        /// <returns>The control flow graph.</returns>
        public static ControlFlowGraph <CilInstruction> ConstructSymbolicFlowGraph(
            this CilMethodBody self,
            out DataFlowGraph <CilInstruction> dataFlowGraph)
        {
            var architecture = new CilArchitecture(self);
            var dfgBuilder   = new CilStateTransitionResolver(architecture);
            var cfgBuilder   = new SymbolicFlowGraphBuilder <CilInstruction>(
                architecture,
                self.Instructions,
                dfgBuilder);

            var ehRanges = self.ExceptionHandlers
                           .ToEchoRanges()
                           .ToArray();

            var cfg = cfgBuilder.ConstructFlowGraph(0, ehRanges);

            if (ehRanges.Length > 0)
            {
                cfg.DetectExceptionHandlerRegions(ehRanges);
            }

            dataFlowGraph = dfgBuilder.DataFlowGraph;
            return(cfg);
        }
Example #5
0
        public void ReadDynamicMethod()
        {
            var module = ModuleDefinition.FromFile(typeof(TDynamicMethod).Assembly.Location);

            var type = module.TopLevelTypes.First(t => t.Name == nameof(TDynamicMethod));

            var method = type.Methods.FirstOrDefault(m => m.Name == nameof(TDynamicMethod.GenerateDynamicMethod));

            DynamicMethod generateDynamicMethod = TDynamicMethod.GenerateDynamicMethod();

            //Dynamic method => CilMethodBody
            var body = CilMethodBody.FromDynamicMethod(method, generateDynamicMethod);

            Assert.NotNull(body);

            Assert.NotEmpty(body.Instructions);

            Assert.Equal(body.Instructions.Select(q => q.OpCode), new CilOpCode[]
            {
                CilOpCodes.Ldarg_0,
                CilOpCodes.Call,
                CilOpCodes.Ldarg_1,
                CilOpCodes.Ret
            });
        }
 private void CloneLocalVariables(MemberCloneContext context, CilMethodBody body, CilMethodBody clonedBody)
 {
     foreach (var variable in body.LocalVariables)
     {
         var clonedVariable = new CilLocalVariable(context.Importer.ImportTypeSignature(variable.VariableType));
         clonedBody.LocalVariables.Add(clonedVariable);
     }
 }
Example #7
0
        public static object ResolveOperandReflection(ModuleReaderContext context, CilMethodBody methodBody, CilInstruction instruction,
                                                      ICilOperandResolver resolver, List <object> tokens, ReferenceImporter importer)
        {
            switch (instruction.OpCode.OperandType)
            {
            case CilOperandType.InlineBrTarget:
            case CilOperandType.ShortInlineBrTarget:
                return(methodBody.Instructions
                       .GetByOffset(((ICilLabel)instruction.Operand).Offset)
                       ?.CreateLabel());

            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
                return(ReadToken(context, ((MetadataToken)instruction.Operand).ToUInt32(), tokens, importer));

            case CilOperandType.InlineString:
                return(ReadToken(context, ((MetadataToken)instruction.Operand).ToUInt32(), tokens, importer));

            case CilOperandType.InlineSwitch:
                var result = new List <ICilLabel>();
                var labels = (IList <ICilLabel>)instruction.Operand;
                for (int i = 0; i < labels.Count; i++)
                {
                    var label  = labels[i];
                    var target = methodBody.Instructions.GetByOffset(label.Offset);
                    result.Add(target != null
                            ? new CilInstructionLabel(target)
                            : label);
                }

                return(result);

            case CilOperandType.InlineVar:
            case CilOperandType.ShortInlineVar:
                return(resolver.ResolveLocalVariable(Convert.ToInt32(instruction.Operand)));

            case CilOperandType.InlineArgument:
            case CilOperandType.ShortInlineArgument:
                return(resolver.ResolveParameter(Convert.ToInt32(instruction.Operand)));

            case CilOperandType.InlineI:
            case CilOperandType.InlineI8:
            case CilOperandType.InlineNone:
            case CilOperandType.InlineR:
            case CilOperandType.ShortInlineI:
            case CilOperandType.ShortInlineR:
                return(instruction.Operand);

            case CilOperandType.InlinePhi:
                throw new NotSupportedException();

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Example #8
0
 /// <summary>
 /// Initalize Disassembler.
 /// </summary>
 /// <param name="owner">Method That Get Disassembled.</param>
 /// <param name="source">Raw Cawk Code.</param>
 public Disassembler(MethodDefinition owner,
                     byte[] source)
 {
     Owner     = owner ?? throw new ArgumentNullException("OwnerMethod is Required.");
     Data      = source ?? throw new ArgumentNullException("Main Data Must Be Not Null.");
     _reader   = new(new MemoryStream(Data));
     _importer = new(Owner.Module);
     _body     = new CilMethodBody(Owner);
 }
Example #9
0
        public static void ReadLocalVariables(this CilMethodBody methodBody, MethodDefinition method, byte[] localSig)
        {
            var locals = CallingConventionSignature.FromReader(method.Module, new ByteArrayReader(localSig)) as LocalVariablesSignature;

            for (var i = 0; i < locals?.VariableTypes.Count; i++)
            {
                methodBody.LocalVariables.Add(new CilLocalVariable(locals.VariableTypes[i]));
            }
        }
Example #10
0
 /// <summary>
 /// Creates a new instance of the <see cref="CilVirtualMachine"/>. 
 /// </summary>
 /// <param name="methodBody">The method body to emulate.</param>
 /// <param name="is32Bit">Indicates whether the virtual machine should run in 32-bit mode or in 64-bit mode.</param>
 public CilVirtualMachine(CilMethodBody methodBody, bool is32Bit)
     : this
     (
         methodBody.Owner.Module,
         new ListInstructionProvider<CilInstruction>(new CilArchitecture(methodBody), methodBody.Instructions),
         is32Bit
     )
 {
 }
Example #11
0
        internal MethodDefinition(MetadataImage image, MetadataRow <FileSegment, MethodImplAttributes, MethodAttributes, uint, uint, uint> row)
            : base(row.MetadataToken)
        {
            _image = image;
            var stringStream = image.Header.GetStream <StringStream>();
            var blobStream   = image.Header.GetStream <BlobStream>();

            ImplAttributes = row.Column2;
            Attributes     = row.Column3;
            _name          = new LazyValue <string>(() => stringStream.GetStringByOffset(row.Column4));

            IBinaryStreamReader blobReader;

            if (blobStream.TryCreateBlobReader(row.Column5, out blobReader))
            {
                _signature = new LazyValue <MethodSignature>(() => MethodSignature.FromReader(image, blobReader));
            }

            _methodBody = new LazyValue <MethodBody>(() =>
            {
                var rawBody = row.Column1 as CilRawMethodBody;
                if (rawBody != null)
                {
                    return(CilMethodBody.FromRawMethodBody(this, rawBody));
                }

                // TODO: handler for native methods.
                return(null);
            });

            _declaringType = new LazyValue <TypeDefinition>(() =>
            {
                var table   = image.Header.GetStream <TableStream>().GetTable(MetadataTokenType.TypeDef);
                var typeRow = table.GetRowClosestToKey(5, row.MetadataToken.Rid);
                return((TypeDefinition)table.GetMemberFromRow(image, typeRow));
            });

            _pinvokeMap = new LazyValue <ImplementationMap>(() =>
            {
                if (!row.Column3.HasFlag(MethodAttributes.PInvokeImpl))
                {
                    return(null);
                }

                var table  = (ImplementationMapTable)image.Header.GetStream <TableStream>().GetTable(MetadataTokenType.ImplMap);
                var mapRow = table.FindImplementationMapOfOwner(row.MetadataToken);
                return(mapRow != null ? (ImplementationMap)table.GetMemberFromRow(image, mapRow) : null);
            });

            Parameters = new RangedMemberCollection <MethodDefinition, ParameterDefinition>(this, MetadataTokenType.Param, 5, GetParamOwner, SetParamOwner);

            CustomAttributes     = new CustomAttributeCollection(this);
            SecurityDeclarations = new SecurityDeclarationCollection(this);
            GenericParameters    = new GenericParameterCollection(this);
        }
 public RecompilerContext(CilMethodBody methodBody, ModuleDefinition targetModule,
                          ILToCilRecompiler recompiler, IVMFunctionResolver exportResolver)
 {
     MethodBody        = methodBody ?? throw new ArgumentNullException(nameof(methodBody));
     TargetModule      = targetModule ?? throw new ArgumentNullException(nameof(targetModule));
     Recompiler        = recompiler ?? throw new ArgumentNullException(nameof(recompiler));
     ExportResolver    = exportResolver ?? throw new ArgumentNullException(nameof(exportResolver));
     ReferenceImporter = new ReferenceImporter(targetModule);
     TypeHelper        = new TypeHelper(ReferenceImporter);
     _genericContexts.Push(new GenericContext(null, null));
 }
Example #13
0
        public static void ValidateCode(string code, CilMethodBody body)
        {
            var builder = new StringBuilder();

            foreach (var instruction in body.Instructions)
            {
                builder.AppendLine(String.Format("{0}{1}", instruction.OpCode.Name,
                                                 instruction.Operand != null ? " " + instruction.OperandToString() : String.Empty));
            }
            Assert.True(code.TrimEnd() == builder.ToString().TrimEnd());
        }
Example #14
0
        public static object ResolveOperandReflection(this CilMethodBody methodBody, CilInstruction instruction,
                                                      ICilOperandResolver resolver, List <object> Tokens, ReferenceImporter Importer)
        {
            switch (instruction.OpCode.OperandType)
            {
            case CilOperandType.InlineBrTarget:
            case CilOperandType.ShortInlineBrTarget:
                return(new CilInstructionLabel(
                           methodBody.Instructions.GetByOffset(((ICilLabel)instruction.Operand).Offset)));

            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
                return(ReadToken(((MetadataToken)instruction.Operand).ToUInt32(), Tokens, Importer));

            case CilOperandType.InlineString:
                return(ReadToken(((MetadataToken)instruction.Operand).ToUInt32(), Tokens, Importer));

            case CilOperandType.InlineSwitch:
                var result = new List <ICilLabel>();
                var labels = (IEnumerable <ICilLabel>)instruction.Operand;
                foreach (var label in labels)
                {
                    var target = methodBody.Instructions.GetByOffset(label.Offset);
                    result.Add(target == null ? label : new CilInstructionLabel(target));
                }
                return(result);

            case CilOperandType.InlineVar:
            case CilOperandType.ShortInlineVar:
                return(resolver.ResolveLocalVariable(Convert.ToInt32(instruction.Operand)));

            case CilOperandType.InlineArgument:
            case CilOperandType.ShortInlineArgument:
                return(resolver.ResolveParameter(Convert.ToInt32(instruction.Operand)));

            case CilOperandType.InlineI:
            case CilOperandType.InlineI8:
            case CilOperandType.InlineNone:
            case CilOperandType.InlineR:
            case CilOperandType.ShortInlineI:
            case CilOperandType.ShortInlineR:
                return(instruction.Operand);

            case CilOperandType.InlinePhi:
                throw new NotSupportedException();

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        /// <summary>
        /// Create a Dynamic Method Definition
        /// </summary>
        /// <param name="module">Target Module</param>
        /// <param name="dynamicMethodObj">Dynamic Method / Delegate / DynamicResolver</param>
        public DynamicMethodDefinition(ModuleDefinition module, object dynamicMethodObj) :
            base(new MetadataToken(TableIndex.Method, 0))
        {
            dynamicMethodObj = DynamicMethodHelper.ResolveDynamicResolver(dynamicMethodObj);
            var methodBase = FieldReader.ReadField <MethodBase>(dynamicMethodObj, "m_method");

            Module        = module;
            Name          = methodBase.Name;
            Attributes    = (MethodAttributes)methodBase.Attributes;
            Signature     = new ReferenceImporter(module).ImportMethodSignature(ResolveSig(methodBase, module));
            CilMethodBody = CilMethodBody.FromDynamicMethod(this, dynamicMethodObj);
        }
Example #16
0
        public CodeGenerationContext(CilMethodBody methodBody, VMConstants constants, CilVariable flagVariable,
                                     TypeDefinition flagHelperType)
        {
            MethodBody    = methodBody;
            Constants     = constants;
            _flagVariable = flagVariable;
            VmHelperType  = flagHelperType;

            ReferenceImporter = new ReferenceImporter(TargetModule);

            _arg0   = new CilVariable("__arg0", TargetModule.CorLibTypeFactory.UInt32);
            _arg1   = new CilVariable("__arg1", TargetModule.CorLibTypeFactory.UInt32);
            _result = new CilVariable("__result", TargetModule.CorLibTypeFactory.UInt32);
        }
        public static CilMethodBody CreateBody(this VirtualizedMethod virtualizedMethod)
        {
            var body = new CilMethodBody(virtualizedMethod.Parent);

            for (var i = 0; i < virtualizedMethod.Instructions.Count; i++)
            {
                body.Instructions.Add(CreateInstruction(virtualizedMethod, virtualizedMethod.Instructions[i]));
            }
            body.Instructions.CalculateOffsets();

            var locals  = body.Instructions.Where(q => q.IsStloc() || q.IsLdloc()).ToList();
            var highest = 0;

            if (locals.Count > 0)
            {
                highest = (int)locals.OrderByDescending(q => (int)q.Operand)
                          .First().Operand + 1;
            }
            for (var i = 0; i < highest; i++)
            {
                body.LocalVariables.Add(
                    new CilLocalVariable(virtualizedMethod.Parent.Module.CorLibTypeFactory.Object));
            }
            for (var i = 0; i < body.Instructions.Count; i++)
            {
                switch (body.Instructions[i].OpCode.Code)
                {
                case CilCode.Br:
                case CilCode.Brfalse:
                case CilCode.Brtrue:
                    body.Instructions[i].Operand =
                        body.Instructions[(int)body.Instructions[i].Operand].CreateLabel();
                    break;

                case CilCode.Ldloc:
                case CilCode.Stloc:
                    body.Instructions[i].Operand = body.LocalVariables[(int)body.Instructions[i].Operand];
                    break;

                case CilCode.Ldarg:
                case CilCode.Starg:
                    body.Instructions[i].Operand =
                        virtualizedMethod.Parent.Parameters.GetBySignatureIndex((int)body.Instructions[i].Operand);
                    break;
                }
            }

            body.ComputeMaxStack();
            return(body);
        }
Example #18
0
        public static void ReadReflectionExceptionHandlers(this CilMethodBody methodBody,
                                                           IList <object> ehInfos, byte[] ehHeader, ReferenceImporter importer)
        {
            if (ehHeader != null && ehHeader.Length > 4)
            {
                //Sample needed!
                throw new NotImplementedException("Exception Handlers From ehHeader Not Supported Yet.");
            }
            if (ehInfos != null && ehInfos.Count > 0)
            {
                foreach (var ehInfo in ehInfos)
                {
                    for (int i = 0; i < FieldReader.ReadField <int>(ehInfo, "m_currentCatch"); i++)
                    {
                        //Get ExceptionHandlerInfo Field Values
                        var endFinally      = FieldReader.ReadField <int>(ehInfo, "m_endFinally");
                        var endFinallyLabel = endFinally < 0
                            ? null
                            : methodBody.Instructions.GetByOffset(endFinally)?.CreateLabel() ??
                                              new CilOffsetLabel(endFinally);
                        var endTry      = FieldReader.ReadField <int>(ehInfo, "m_endAddr");
                        var endTryLabel = methodBody.Instructions.GetByOffset(endTry)?.CreateLabel() ??
                                          new CilOffsetLabel(endTry);
                        var handlerEnd    = FieldReader.ReadField <int[]>(ehInfo, "m_catchEndAddr")[i];
                        var exceptionType = FieldReader.ReadField <Type[]>(ehInfo, "m_catchClass")[i];
                        var handlerStart  = FieldReader.ReadField <int[]>(ehInfo, "m_catchAddr")[i];
                        var tryStart      = FieldReader.ReadField <int>(ehInfo, "m_startAddr");
                        var handlerType   = (CilExceptionHandlerType)FieldReader.ReadField <int[]>(ehInfo, "m_type")[i];

                        //Create the handler
                        var handler = new CilExceptionHandler
                        {
                            HandlerType = handlerType,
                            TryStart    = methodBody.Instructions.GetByOffset(tryStart)?.CreateLabel() ??
                                          new CilOffsetLabel(tryStart),
                            TryEnd       = handlerType == CilExceptionHandlerType.Finally ? endFinallyLabel : endTryLabel,
                            FilterStart  = null,
                            HandlerStart = methodBody.Instructions.GetByOffset(handlerStart)?.CreateLabel() ??
                                           new CilOffsetLabel(handlerStart),
                            HandlerEnd = methodBody.Instructions.GetByOffset(handlerEnd)?.CreateLabel() ??
                                         new CilOffsetLabel(handlerEnd),
                            ExceptionType = exceptionType != null?importer.ImportType(exceptionType) : null
                        };

                        methodBody.ExceptionHandlers.Add(handler);
                    }
                }
            }
        }
Example #19
0
        private CilMethodBody RebuildAndLookup(CilMethodBody methodBody)
        {
            var module = methodBody.Owner.Module;

            string tempFile = Path.GetTempFileName();

            module.Write(tempFile);

            var stream = new MemoryStream();

            module.Write(stream);

            var newModule = ModuleDefinition.FromBytes(stream.ToArray());

            return(GetMethodBodyInModule(newModule, methodBody.Owner.Name));
        }
Example #20
0
        public CilMethodBody RecompileCilMethodBody(NashaMethodBody nashaMethodBody)
        {
            var body = new CilMethodBody(nashaMethodBody.NashaMethod.Parent.Method);

            foreach (var instruction in nashaMethodBody.Instructions)
            {
                var cilInstruction = RecompileInstruction(instruction);
                body.Instructions.Add(cilInstruction);
                Context.Logger.Info($"Recompiled Nasha Instruction {instruction} Into Cil Instruction {cilInstruction}");
            }
            //After converting Nasha instruction to cil some instructions will need to be edited after.
            //Ex: Br - 30 =>
            //    Br - (Cil Label of Instruction with index 30)
            ReplaceOperands(body);
            return(body);
        }
Example #21
0
        public static void ReadLocalVariables(CilMethodBody methodBody, MethodDefinition method, byte[] localSig)
        {
            if (!(method.Module is SerializedModuleDefinition module))
            {
                throw new ArgumentException("Method body should reference a serialized module.");
            }

            var localsSignature = (LocalVariablesSignature)CallingConventionSignature.FromReader(
                new BlobReadContext(module.ReaderContext),
                new ByteArrayReader(localSig));

            for (int i = 0; i < localsSignature?.VariableTypes.Count; i++)
            {
                methodBody.LocalVariables.Add(new CilLocalVariable(localsSignature.VariableTypes[i]));
            }
        }
Example #22
0
        public static void ReadReflectionExceptionHandlers(CilMethodBody methodBody,
                                                           IList <object> ehInfos, byte[] ehHeader, ReferenceImporter importer)
        {
            //Sample needed!
            if (ehHeader != null && ehHeader.Length > 4)
            {
                throw new NotImplementedException("Exception handlers from ehHeader not supported yet.");
            }

            if (ehInfos != null && ehInfos.Count > 0)
            {
                foreach (var ehInfo in ehInfos)
                {
                    InterpretEHInfo(methodBody, importer, ehInfo);
                }
            }
        }
Example #23
0
        public CilMethodBody Compile(MethodDefinition method, CilCompilationUnit unit)
        {
            var methodBody = new CilMethodBody(method);

            var context = new CodeGenerationContext(methodBody, _constants, unit.FlagVariable, _flagHelperType);

            var cilGenerator = new CilCodeGenerator(context);

            context.CodeGenerator = cilGenerator;

            // Traverse and recompile the AST.
            methodBody.Instructions.AddRange(unit.AcceptVisitor(cilGenerator));

            // Add variables to the method body.
            if (context.Variables.Count > 0)
            {
                foreach (var variable in context.Variables.Values)
                {
                    methodBody.LocalVariables.Add(variable);
                }
                methodBody.InitializeLocals = true;
            }

            methodBody.Instructions.OptimizeMacros();

            // Add all generated exception handlers to the method body.
            var handlers = context.ExceptionHandlers.Values.ToList();

            handlers.Sort(new EHComparer());
            foreach (var handler in handlers)
            {
                if (EnableExceptionHandlerValidation)
                {
                    AssertValidityExceptionHandler(method, handler);
                }
                methodBody.ExceptionHandlers.Add(handler);
            }

            if (!EnableStackVerification)
            {
                methodBody.ComputeMaxStackOnBuild = false;
                methodBody.MaxStack = ushort.MaxValue;
            }

            return(methodBody);
        }
Example #24
0
        /// <summary>
        /// Creates a new CIL architecture description based on a CIL method body.
        /// </summary>
        /// <param name="parentBody">The method body.</param>
        public CilArchitecture(CilMethodBody parentBody)
        {
            MethodBody = parentBody ?? throw new ArgumentNullException(nameof(parentBody));

            _variables = parentBody.LocalVariables
                         .Select(v => new CilVariable(v))
                         .ToArray();

            _parameters = parentBody.Owner.Parameters
                          .Select(p => new CilParameter(p))
                          .ToList();

            if (parentBody.Owner.Signature.HasThis)
            {
                _parameters.Insert(0, new CilParameter(parentBody.Owner.Parameters.ThisParameter));
            }
        }
Example #25
0
        /// <summary>
        /// Clones a CIL method body.
        /// </summary>
        /// <param name="body">The method body to clone.</param>
        /// <param name="newOwner">The method to add the cloned method body to.</param>
        /// <returns>The cloned method body.</returns>
        private CilMethodBody CloneCilMethodBody(CilMethodBody body, MethodDefinition newOwner)
        {
            var newBody = new CilMethodBody(newOwner)
            {
                InitLocals = body.InitLocals,
                MaxStack   = body.MaxStack,
            };

            if (body.Signature != null)
            {
                newBody.Signature = _importer.ImportStandAloneSignature(body.Signature);
            }

            CloneInstructions(body, newBody);
            CloneExceptionHandlers(body, newBody);

            return(newBody);
        }
Example #26
0
        private void CloneInstructions(CilMethodBody body, CilMethodBody newBody)
        {
            var branchInstructions = new List <CilInstruction>();
            var switchInstructions = new List <CilInstruction>();

            foreach (var instruction in body.Instructions)
            {
                object operand = instruction.Operand;
                if (operand is IMemberReference)
                {
                    operand = _importer.ImportReference((IMemberReference)operand);
                }

                var newInstruction = new CilInstruction(instruction.Offset, instruction.OpCode, operand);
                newBody.Instructions.Add(newInstruction);
                switch (instruction.OpCode.OperandType)
                {
                case CilOperandType.InlineBrTarget:
                case CilOperandType.ShortInlineBrTarget:
                    branchInstructions.Add(newInstruction);
                    break;

                case CilOperandType.InlineSwitch:
                    switchInstructions.Add(newInstruction);
                    break;
                }
            }

            foreach (var branch in branchInstructions)
            {
                branch.Operand = newBody.GetInstructionByOffset(((CilInstruction)branch.Operand).Offset);
            }

            foreach (var @switch in switchInstructions)
            {
                var targets    = (IEnumerable <CilInstruction>)@switch.Operand;
                var newTargets = new List <CilInstruction>();
                foreach (var target in targets)
                {
                    newTargets.Add(newBody.GetInstructionByOffset(target.Offset));
                }
                @switch.Operand = newTargets;
            }
        }
        private CilMethodBody CloneCilMethodBody(MemberCloneContext context, MethodDefinition method)
        {
            var body = method.CilMethodBody;

            var clonedMethod = (MethodDefinition)context.ClonedMembers[method];

            // Clone method body header.
            var clonedBody = new CilMethodBody(clonedMethod);

            clonedBody.InitializeLocals = body.InitializeLocals;
            clonedBody.MaxStack         = body.MaxStack;

            // Clone contents.
            CloneLocalVariables(context, body, clonedBody);
            CloneCilInstructions(context, body, clonedBody);
            CloneExceptionHandlers(context, body, clonedBody);

            return(clonedBody);
        }
Example #28
0
        /// <summary>
        /// Constructs a control flow graph from a CIL method body.
        /// </summary>
        /// <param name="self">The method body.</param>
        /// <returns>The control flow graph.</returns>
        public static ControlFlowGraph <CilInstruction> ConstructStaticFlowGraph(this CilMethodBody self)
        {
            var architecture = new CilArchitecture(self);
            var cfgBuilder   = new StaticFlowGraphBuilder <CilInstruction>(
                architecture,
                self.Instructions,
                architecture.SuccessorResolver);

            var ehRanges = self.ExceptionHandlers
                           .ToEchoRanges()
                           .ToArray();

            var cfg = cfgBuilder.ConstructFlowGraph(0, ehRanges);

            if (ehRanges.Length > 0)
            {
                cfg.DetectExceptionHandlerRegions(ehRanges);
            }
            return(cfg);
        }
Example #29
0
        private static CilMethodBody CreateDummyMethodBody()
        {
            var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true);
            var image    = assembly.NetDirectory.MetadataHeader.LockMetadata();

            var type = new TypeDefinition("SomeType", "SomeMethod");

            image.Assembly.Modules[0].TopLevelTypes.Add(type);

            var method = new MethodDefinition("SomeMethod",
                                              MethodAttributes.Public,
                                              new MethodSignature(image.TypeSystem.Void));

            type.Methods.Add(method);

            var methodBody = new CilMethodBody(method);

            method.MethodBody = methodBody;
            return(methodBody);
        }
        private CilInstruction CloneInstruction(MemberCloneContext context, CilMethodBody clonedBody, CilInstruction instruction)
        {
            var clonedInstruction = new CilInstruction(instruction.Offset, instruction.OpCode);

            switch (instruction.OpCode.OperandType)
            {
            case CilOperandType.InlineBrTarget:
            case CilOperandType.ShortInlineBrTarget:
            case CilOperandType.InlineSwitch:
                // Fix up later when all instructions are added.
                clonedInstruction.Operand = instruction.Operand;
                break;

            case CilOperandType.InlineI:
            case CilOperandType.InlineI8:
            case CilOperandType.InlineNone:
            case CilOperandType.InlineR:
            case CilOperandType.InlineString:
            case CilOperandType.ShortInlineI:
            case CilOperandType.ShortInlineR:
                clonedInstruction.Operand = instruction.Operand;
                break;

            case CilOperandType.InlineField:
                clonedInstruction.Operand = context.Importer.ImportField((IFieldDescriptor)instruction.Operand);
                break;

            case CilOperandType.InlineMethod:
                clonedInstruction.Operand = context.Importer.ImportMethod((IMethodDescriptor)instruction.Operand);
                break;

            case CilOperandType.InlineSig:
                if (instruction.Operand is StandAloneSignature standalone)
                {
                    instruction.Operand = new StandAloneSignature(standalone.Signature switch
                    {
                        MethodSignature signature => context.Importer.ImportMethodSignature(signature),
                        GenericInstanceMethodSignature signature => context.Importer.ImportGenericInstanceMethodSignature(signature),
                        _ => throw new NotImplementedException()
                    });
                }