예제 #1
0
        private void Compile(RPContext ctx, CilBody body, out Func <int, int> expCompiled, out Expression inverse)
        {
            var var    = new Variable("{VAR}");
            var result = new Variable("{RESULT}");

            Expression expression;

            ctx.DynCipher.GenerateExpressionPair(
                ctx.Random,
                new VariableExpression {
                Variable = var
            }, new VariableExpression {
                Variable = result
            },
                ctx.Depth, out expression, out inverse);

            expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
                          .GenerateCIL(expression)
                          .Compile <Func <int, int> >();
        }
예제 #2
0
        ControlFlowGraph(CilBody body)
        {
            try
            {
                this.body   = body;
                instrBlocks = new int[body.Instructions.Count];
                blocks      = new List <ControlFlowBlock>();

                indexMap = new Dictionary <Instruction, int>();
                for (int i = 0; i < body.Instructions.Count; i++)
                {
                    indexMap.Add(body.Instructions[i], i);
                }
            }

            catch
            {
                Console.WriteLine(" EXCCCCC ");
            }
        }
예제 #3
0
        public static Instruction FindInstrSeqStart(this CilBody body, OpCode[] instrs, int startIndex = 0)
        {
            for (int i = startIndex; i <= body.Instructions.Count - instrs.Length; i++)
            {
                for (int j = 0; j < instrs.Length; j++)
                {
                    if (!CodeEqIgnoreS(body.Instructions[i + j].OpCode.Code, instrs[j].Code))
                    {
                        goto next_try;
                    }
                }

                return(body.Instructions[i]);

next_try:
                ;
            }

            return(null);
        }
예제 #4
0
        /// <summary>
        /// Strips the given Type's method bodies and nested Types.
        /// </summary>
        private static void StripType(TypeDef type)
        {
            CilBody throwNullBody = new CilBody
            {
                Instructions = { new Instruction(OpCodes.Ldnull), new Instruction(OpCodes.Throw) }
            };


            foreach (MethodDef method in type.Methods)
            {
                if (method.HasBody)
                {
                    method.Body = throwNullBody;
                }
            }

            foreach (TypeDef nestedType in type.NestedTypes)
            {
                StripType(nestedType);
            }
        }
예제 #5
0
 /// <summary>
 ///     Replaces the specified instruction reference with another instruction.
 /// </summary>
 /// <param name="body">The method body.</param>
 /// <param name="target">The instruction to replace.</param>
 /// <param name="newInstr">The new instruction.</param>
 public static void ReplaceReference(this CilBody body, Instruction target, Instruction newInstr)
 {
     foreach (ExceptionHandler eh in body.ExceptionHandlers)
     {
         if (eh.TryStart == target)
         {
             eh.TryStart = newInstr;
         }
         if (eh.TryEnd == target)
         {
             eh.TryEnd = newInstr;
         }
         if (eh.HandlerStart == target)
         {
             eh.HandlerStart = newInstr;
         }
         if (eh.HandlerEnd == target)
         {
             eh.HandlerEnd = newInstr;
         }
     }
     foreach (Instruction instr in body.Instructions)
     {
         if (instr.Operand == target)
         {
             instr.Operand = newInstr;
         }
         else if (instr.Operand is Instruction[])
         {
             var targets = (Instruction[])instr.Operand;
             for (int i = 0; i < targets.Length; i++)
             {
                 if (targets[i] == target)
                 {
                     targets[i] = newInstr;
                 }
             }
         }
     }
 }
예제 #6
0
파일: PdbState.cs 프로젝트: slamj1/dnlib
        void AddSequencePoints(CilBody body, SymbolMethod method)
        {
            int instrIndex = 0;

            foreach (var sp in method.SequencePoints)
            {
                var instr = GetInstruction(body.Instructions, sp.Offset, ref instrIndex);
                if (instr == null)
                {
                    continue;
                }
                var seqPoint = new SequencePoint()
                {
                    Document    = Add_NoLock(new PdbDocument(sp.Document)),
                    StartLine   = sp.Line,
                    StartColumn = sp.Column,
                    EndLine     = sp.EndLine,
                    EndColumn   = sp.EndColumn,
                };
                instr.SequencePoint = seqPoint;
            }
        }
예제 #7
0
        private void EncodeNumeric(SpectreContext spctx, MethodDef method, int i)
        {
            body = method.Body;
            int key = LeetRandom.rnd.Next(0, int.MaxValue);

            FieldDef field = new FieldDefUser(Guid.NewGuid().ToString(), new FieldSig(spctx.ManifestModule.CorLibTypes.Int32), FieldAttributes.Public | FieldAttributes.Static);

            //Add Field
            spctx.GlobalType.Fields.Add(field);
            int cctorbdycount = spctx.cctor.Body.Instructions.Count;

            //Init Field
            spctx.cctor.Body.Instructions.Insert(cctorbdycount - 1, Instruction.Create(OpCodes.Stsfld, field));
            spctx.cctor.Body.Instructions.Insert(cctorbdycount - 1, Instruction.CreateLdcI4(key));

            int operand    = body.Instructions[i].GetLdcI4Value();
            int newoperand = EncodeNum(operand, key);

            body.Instructions[i] = Instruction.CreateLdcI4(newoperand);
            body.Instructions.Insert(i + 1, Instruction.Create(OpCodes.Ldsfld, field)); // insert int field
            body.Instructions.Insert(i + 2, Instruction.Create(OpCodes.Call, decryptionmethod));
        }
예제 #8
0
        static List <BasicBlock <CILInstrList> > SplitBlocks(CilBody body, HashSet <Instruction> headers,
                                                             HashSet <Instruction> entries)
        {
            int         nextBlockId     = 0;
            int         currentBlockId  = -1;
            Instruction currentBlockHdr = null;
            var         blocks          = new List <BasicBlock <CILInstrList> >();

            var instrList = new CILInstrList();

            for (int i = 0; i < body.Instructions.Count; i++)
            {
                Instruction instr = body.Instructions[i];
                if (headers.Contains(instr))
                {
                    if (currentBlockHdr != null)
                    {
                        Instruction footer = body.Instructions[i - 1];

                        Debug.Assert(instrList.Count > 0);
                        blocks.Add(new BasicBlock <CILInstrList>(currentBlockId, instrList));
                        instrList = new CILInstrList();
                    }

                    currentBlockId  = nextBlockId++;
                    currentBlockHdr = instr;
                }

                instrList.Add(instr);
            }
            if (blocks.Count == 0 || blocks[blocks.Count - 1].Id != currentBlockId)
            {
                Instruction footer = body.Instructions[body.Instructions.Count - 1];

                Debug.Assert(instrList.Count > 0);
                blocks.Add(new BasicBlock <CILInstrList>(currentBlockId, instrList));
            }
            return(blocks);
        }
예제 #9
0
        //https://github.com/0xd4d/dnlib/blob/master/Examples/Example3.cs
        public static void Run(string encrypted, string writedir)
        {
            //create module
            var mod = new ModuleDefUser(RandomString()); mod.Kind = ModuleKind.Console;
            // create and add asm in module
            var asm = new AssemblyDefUser(RandomString(), new Version(random.Next(1, 9), random.Next(1, 9), random.Next(1, 9), random.Next(1, 9)));

            asm.Modules.Add(mod);
            // create startup class for ep
            var startUpType = new TypeDefUser(RandomString(), RandomString(), mod.CorLibTypes.Object.TypeDefOrRef);

            startUpType.Attributes = TypeAttributes.NotPublic | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.AnsiClass;
            mod.Types.Add(startUpType);
            //create ep method main(string[] args)
            var entryPoint = new MethodDefUser("Main", MethodSig.CreateStatic(mod.CorLibTypes.Void, new SZArraySig(mod.CorLibTypes.String)));

            entryPoint.Attributes     = MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot;
            entryPoint.ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.Managed;
            entryPoint.ParamDefs.Add(new ParamDefUser("args", 1));
            startUpType.Methods.Add(entryPoint);
            mod.EntryPoint = entryPoint;
            var epBody = new CilBody();

            entryPoint.Body = epBody;
            // add instructions in ep method
            epBody.Instructions.Add(OpCodes.Nop.ToInstruction());
            epBody.Instructions.Add(OpCodes.Ldstr.ToInstruction(encrypted));
            epBody.Instructions.Add(OpCodes.Call.ToInstruction(entryPoint.Module.Import(typeof(System.Convert).GetMethod("FromBase64String", new Type[] { typeof(string) }))));
            epBody.Instructions.Add(OpCodes.Call.ToInstruction(entryPoint.Module.Import(typeof(System.Reflection.Assembly).GetMethod("Load", new Type[] { typeof(byte[]) }))));
            epBody.Instructions.Add(OpCodes.Callvirt.ToInstruction(entryPoint.Module.Import(typeof(System.Reflection.Assembly).GetMethod("get_EntryPoint", new Type[0]))));
            epBody.Instructions.Add(OpCodes.Ldnull.ToInstruction());
            epBody.Instructions.Add(OpCodes.Ldc_I4_1.ToInstruction());
            epBody.Instructions.Add(OpCodes.Newarr.ToInstruction(entryPoint.Module.Import(typeof(System.Object))));
            epBody.Instructions.Add(OpCodes.Callvirt.ToInstruction(entryPoint.Module.Import(typeof(System.Reflection.MethodBase).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) }))));
            epBody.Instructions.Add(OpCodes.Pop.ToInstruction());
            epBody.Instructions.Add(OpCodes.Ret.ToInstruction());
            // save new file
            mod.Write(writedir.Replace(".exe", "_packed.exe"));
        }
예제 #10
0
        void Compile(CilBody body)
        {
            var var    = new Variable("{VAR}");
            var result = new Variable("{RESULT}");

            ctx.DynCipher.GenerateExpressionPair(
                ctx.Random,
                new VariableExpression {
                Variable = var
            }, new VariableExpression {
                Variable = result
            },
                ctx.Depth, out expression, out inverse);

            expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
                          .GenerateCIL(expression)
                          .Compile <Func <int, int> >();

            invCompiled = new List <Instruction>();
            new CodeGen(stateVar, ctx, invCompiled).GenerateCIL(inverse);
            body.MaxStack += (ushort)ctx.Depth;
        }
예제 #11
0
        void IProtector.ProtectionPhase(Context krawk)
        {
            foreach (ModuleDef module in krawk.Assembly.Modules)
            {
                foreach (TypeDef type in module.Types)
                {
                    foreach (MethodDef method in type.Methods)
                    {
                        if (!method.HasBody)
                        {
                            continue;
                        }
                        if (method.HasBody)
                        {
                            if (!method.Body.HasInstructions)
                            {
                                continue;
                            }
                        }

                        body = method.Body;
                        for (int i = 0; i < body.Instructions.Count; i++)
                        {
                            if (method.Body.Instructions[i].OpCode == OpCodes.Ldstr)
                            {
                                Mutate(krawk, method, i, "String");
                                i += 2;
                            }
                            if (method.Body.Instructions[i].IsLdcI4())
                            {
                                Mutate(krawk, method, i, "Int");
                            }
                        }
                        body.SimplifyBranches();
                        body.OptimizeBranches();
                    }
                }
            }
        }
        /// <summary>
        /// Inserts a group of instructions into the method as the arbitrary last.
        /// </summary>
        public static void AppendLast(this CilBody body, IEnumerable <Instruction> instructions)
        {
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }
            if (instructions == null)
            {
                throw new ArgumentNullException(nameof(instructions));
            }

            var ret = body.Instructions.Last();

            if (ret == null || ret.OpCode != OpCodes.Ret)
            {
                throw new ArgumentOutOfRangeException(nameof(body));
            }

            var list = instructions.ToList();

            if (!list.Any())
            {
                return;
            }

            var first = list.First();

            ret.OpCode  = first.OpCode;
            ret.Operand = first.Operand;

            list.Remove(first);
            list.Add(OpCodes.Ret.ToInstruction());

            foreach (var instruction in list)
            {
                body.Instructions.Add(instruction);
            }
        }
예제 #13
0
        /// <summary>
        ///     Constructs a CFG from the specified method body.
        /// </summary>
        /// <param name="body">The method body.</param>
        /// <returns>The CFG of the given method body.</returns>
        public static ControlFlowGraph Construct(CilBody body)
        {
            var graph = new ControlFlowGraph(body);

            if (body.Instructions.Count == 0)
            {
                return(graph);
            }

            // Populate block headers
            var blockHeaders = new HashSet <Instruction>();
            var entryHeaders = new HashSet <Instruction>();

            graph.PopulateBlockHeaders(blockHeaders, entryHeaders);

            // Split blocks
            graph.SplitBlocks(blockHeaders, entryHeaders);

            // Link blocks
            graph.LinkBlocks();

            return(graph);
        }
예제 #14
0
        /// <summary>
        /// Finds all branches. Returns list of source offset->target offset mapping.
        /// Multiple entries for the same source offset are possible (switch statements).
        /// The result is sorted by source offset.
        /// </summary>
        List <KeyValuePair <Instruction, Instruction> > FindAllBranches(CilBody body)
        {
            var result = new List <KeyValuePair <Instruction, Instruction> >();

            foreach (Instruction inst in body.Instructions)
            {
                switch (inst.OpCode.OperandType)
                {
                case OperandType.InlineBrTarget:
                case OperandType.ShortInlineBrTarget:
                    result.Add(new KeyValuePair <Instruction, Instruction>(inst, (Instruction)inst.Operand));
                    break;

                case OperandType.InlineSwitch:
                    foreach (Instruction target in (Instruction[])inst.Operand)
                    {
                        result.Add(new KeyValuePair <Instruction, Instruction>(inst, target));
                    }
                    break;
                }
            }
            return(result);
        }
예제 #15
0
        void ProcessMethod(CilBody body, CFContext ctx)
        {
            if (!MaxStackCalculator.GetMaxStack(body.Instructions, body.ExceptionHandlers, out var maxStack))
            {
                ctx.Context.Logger.Error("Failed to calcuate maxstack.");
                throw new ConfuserException(null);
            }
            body.MaxStack = (ushort)maxStack;
            var root = BlockParser.ParseBody(body);

            GetMangler(ctx.Type).Mangle(body, root, ctx);

            body.Instructions.Clear();
            root.ToBody(body);
            foreach (var eh in body.ExceptionHandlers)
            {
                var index = body.Instructions.IndexOf(eh.TryEnd) + 1;
                eh.TryEnd     = index < body.Instructions.Count ? body.Instructions[index] : null;
                index         = body.Instructions.IndexOf(eh.HandlerEnd) + 1;
                eh.HandlerEnd = index < body.Instructions.Count ? body.Instructions[index] : null;
            }
            body.KeepOldMaxStack = true;
        }
예제 #16
0
        public CfGraph(CilBody body)
        {
            _body = body;
            var c = body.Instructions.Count;

            _instrBlocks = new int[c];
            _blocks      = new List <CfBlock>();

            _indexMap = new Dictionary <Instruction, int>();
            for (var i = 0; i < c; i++)
            {
                _indexMap.Add(body.Instructions[i], i);
            }
            if (c > 0)
            {
                var blockHeaders = new HashSet <Instruction>();
                var entryHeaders = new HashSet <Instruction>();
                PopulateBlockHeaders(blockHeaders, entryHeaders);
                SplitBlocks(blockHeaders, entryHeaders);
                LinkBlocks();
                MapHandlers();
            }
        }
예제 #17
0
        private static MethodDefUser AddPropertySetter(TypeSig propertyType,
                                                       string setterName, MethodAttributes attributes,
                                                       IField backingField, ModuleDef module)
        {
            var methodSig = new MethodSig(CallingConvention.HasThis, 0, module.CorLibTypes.Void);

            methodSig.Params.Add(propertyType);

            var setter = new MethodDefUser(setterName,
                                           methodSig,
                                           MethodImplAttributes.Managed | MethodImplAttributes.IL, attributes);

            var body = new CilBody();

            body.Instructions.Emit(OpCodes.Ldarg_0);
            body.Instructions.Emit(OpCodes.Ldarg_1);
            body.Instructions.Emit(OpCodes.Stfld, backingField);
            body.Instructions.Emit(OpCodes.Ret);

            setter.Body = body;

            return(setter);
        }
예제 #18
0
        private void ProcessMethod(CilBody body, CFContext ctx)
        {
            uint maxStack;

            if (!MaxStackCalculator.GetMaxStack(body.Instructions, body.ExceptionHandlers, out maxStack))
            {
                ctx.Context.Logger.Error("Failed to calcuate maxstack.");
                throw new ConfuserException(null);
            }
            body.MaxStack = (ushort)maxStack;
            ScopeBlock root = BlockParser.ParseBody(body);

            GetMangler(ctx.Type).Mangle(body, root, ctx);

            body.Instructions.Clear();
            root.ToBody(body);
            foreach (ExceptionHandler eh in body.ExceptionHandlers)
            {
                eh.TryEnd     = body.Instructions[body.Instructions.IndexOf(eh.TryEnd) + 1];
                eh.HandlerEnd = body.Instructions[body.Instructions.IndexOf(eh.HandlerEnd) + 1];
            }
            body.KeepOldMaxStack = true;
        }
예제 #19
0
        private void btnDeobf_Click(object sender, EventArgs e)
        {
            ModuleDefMD md = ModuleDefMD.Load(tbin.Text);

            if (!IsObfuscator(md))
            {
                MessageBox.Show(null, "This Assembly is not protected with Orange Heap!", NAME, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                foreach (var type in md.Types)
                {
                    foreach (var method in type.Methods)
                    {
                        if (!method.HasBody)
                        {
                            continue;
                        }
                        CilBody body = method.Body;
                        body.KeepOldMaxStack = true;
                        for (int i = 0; i < body.Instructions.Count; i++)
                        {
                            if (body.Instructions[i].OpCode == OpCodes.Ldstr &&
                                body.Instructions[i + 1].OpCode == OpCodes.Call &&
                                body.Instructions[i + 1].Operand == target)
                            {
                                body.Instructions[i].Operand     = decryptstring(body.Instructions[i].Operand.ToString());
                                body.Instructions[i + 1].Operand = null;
                                body.Instructions[i + 1].OpCode  = OpCodes.Nop;
                            }
                        }
                    }
                }
                md.Write(tbout.Text);
                MessageBox.Show(null, "Saved Assembly to: " + tbout.Text, NAME, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
예제 #20
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="module">The .NET protected ModuleDefMD</param>
 /// <param name="Methoddecryption">The method which decrypt the strings</param>
 public static void DecryptStringsInMethod(ModuleDefMD module, MethodDef Methoddecryption)
 {
     foreach (TypeDef type in module.Types)
     {
         foreach (MethodDef method in type.Methods)
         {
             if (!method.HasBody)
             {
                 break;
             }
             for (int i = 0; i < method.Body.Instructions.Count; i++)
             {
                 if (method.Body.Instructions[i].OpCode == OpCodes.Call)
                 {
                     if (method.Body.Instructions[i].Operand.ToString().ToLower().Contains(Typedecryption.Name.ToLower()))
                     {
                         Type2Remove.Add(Typedecryption);
                         var CalledDecMethod = (MethodDef)method.Body.Instructions[i].Operand;
                         var decryptedstring = ExtractStringFromMethod(CalledDecMethod);
                         if (decryptedstring == "[DEObfuscar] Error")
                         {
                             //
                         }
                         else
                         {
                             CilBody body = method.Body;
                             body.Instructions[i].OpCode  = OpCodes.Ldstr;
                             body.Instructions[i].Operand = decryptedstring;
                             DeobedStringNumber           = DeobedStringNumber + 1;
                         }
                     }
                 }
             }
         }
     }
 }
예제 #21
0
        static void Main(string[] args)
        {
            string[]      file       = File.ReadAllLines("precomp.psnbin");
            ModuleDefUser mod        = newmod("PointySnakeModule");
            MethodDefUser entryPoint = new MethodDefUser("Main", MethodSig.CreateStatic(mod.CorLibTypes.Int32, new SZArraySig(mod.CorLibTypes.String)));

            startUpType = new TypeDefUser("PointySnake", "Program", mod.CorLibTypes.Object.TypeDefOrRef);
            mod.Types.Add(startUpType);
            entryPoint.Attributes     = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot;
            entryPoint.ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.Managed | MethodImplAttributes.AggressiveOptimization;
            entryPoint.ParamDefs.Add(new ParamDefUser("args", 1));
            var epBody = new CilBody();

            entryPoint.Body        = epBody;
            startUpType.Attributes = TypeAttributes.Public;
            startUpType.Methods.Add(entryPoint);
            mod.EntryPoint = entryPoint;
            currentfunc    = mod.EntryPoint;
            foreach (string line in file)
            {
                WriteInstruction(line, mod, currentfunc.Body);
            }
            if (epBody.Instructions.Count == 0 || epBody.Instructions[epBody.Instructions.Count - 1].OpCode != OpCodes.Ret)
            {
                entryPoint.Body.Instructions.Add(OpCodes.Ldc_I4_0.ToInstruction());
                entryPoint.Body.Instructions.Add(OpCodes.Ret.ToInstruction());
            }
            entryPoint.Body.OptimizeBranches();
            entryPoint.Body.OptimizeMacros();
            Console.WriteLine("done");
            var options = new ModuleWriterOptions(mod);

            options.PEHeadersOptions.Machine = dnlib.PE.Machine.AMD64;
            mod.Write("executable.exe", options);
            awaitbutton();
        }
예제 #22
0
        private void ResolveBody(MethodDef methodDef, MosaMethod.Mutator method, CilBody body, GenericArgumentResolver resolver)
        {
            method.LocalVariables.Clear();
            int index = 0;

            foreach (var variable in body.Variables)
            {
                method.LocalVariables.Add(new MosaLocal(
                                              variable.Name ?? "V_" + index,
                                              metadata.Loader.GetType(resolver.Resolve(variable.Type)),
                                              variable.Type.IsPinned));
                index++;
            }

            method.ExceptionBlocks.Clear();
            foreach (var eh in body.ExceptionHandlers)
            {
                method.ExceptionBlocks.Add(new MosaExceptionHandler(
                                               (ExceptionHandlerType)eh.HandlerType,
                                               ResolveOffset(body, eh.TryStart),
                                               ResolveOffset(body, eh.TryEnd),
                                               ResolveOffset(body, eh.HandlerStart),
                                               ResolveOffset(body, eh.HandlerEnd),
                                               eh.CatchType == null ? null : metadata.Loader.GetType(resolver.Resolve(eh.CatchType.ToTypeSig())),
                                               eh.FilterStart == null ? null : (int?)eh.FilterStart.Offset
                                               ));
            }

            method.MaxStack = methodDef.Body.MaxStack;

            method.Code.Clear();
            for (int i = 0; i < body.Instructions.Count; i++)
            {
                method.Code.Add(ResolveInstruction(methodDef, body, i, resolver));
            }
        }
        void ProcessMethod(CilBody body, CFContext ctx)
        {
            uint maxStack;

            if (!MaxStackCalculator.GetMaxStack(body.Instructions, body.ExceptionHandlers, out maxStack))
            {
                ctx.Context.Logger.Error("Failed to calcuate maxstack.");
                throw new ConfuserException(null);
            }
            body.MaxStack = (ushort)maxStack;
            ScopeBlock root = BlockParser.ParseBody(body);

            GetMangler(ctx.Type).Mangle(body, root, ctx);

            body.Instructions.Clear();
            root.ToBody(body);
            if (body.PdbMethod != null)
            {
                body.PdbMethod = new PdbMethod()
                {
                    Scope = new PdbScope()
                    {
                        Start = body.Instructions.First(),
                        End   = body.Instructions.Last()
                    }
                };
            }
            foreach (ExceptionHandler eh in body.ExceptionHandlers)
            {
                var index = body.Instructions.IndexOf(eh.TryEnd) + 1;
                eh.TryEnd     = index < body.Instructions.Count ? body.Instructions[index] : null;
                index         = body.Instructions.IndexOf(eh.HandlerEnd) + 1;
                eh.HandlerEnd = index < body.Instructions.Count ? body.Instructions[index] : null;
            }
            body.KeepOldMaxStack = true;
        }
예제 #24
0
        /// <summary>
        /// Initializes a <see cref="CilBody"/> with information found in the PDB file. The
        /// instructions in <paramref name="body"/> must have valid offsets. This method is
        /// automatically called by <see cref="ModuleDefMD"/> and you don't need to explicitly call
        /// it.
        /// </summary>
        /// <param name="body">Method body</param>
        /// <param name="methodRid">Method row ID</param>
        public void InitializeDontCall(CilBody body, uint methodRid)
        {
            if (reader == null || body == null)
            {
                return;
            }
            var token = new SymbolToken((int)(0x06000000 + methodRid));
            ISymbolMethod method;

#if THREAD_SAFE
            theLock.EnterWriteLock(); try {
#endif
            method = reader.GetMethod(token);
            if (method != null)
            {
                body.Scope = CreateScope(body, method.RootScope);
                AddSequencePoints(body, method);
            }
            //TODO: reader.GetSymAttribute()
#if THREAD_SAFE
        }
        finally { theLock.ExitWriteLock(); }
#endif
        }
예제 #25
0
 public abstract void ToBody(CilBody body);
예제 #26
0
        static PdbScope CreateScope(CilBody body, ISymbolScope symScope)
        {
            if (symScope == null)
            {
                return(null);
            }

            // Don't use recursive calls
            var stack = new Stack <CreateScopeState>();
            var state = new CreateScopeState()
            {
                SymScope = symScope
            };

recursive_call:
            int instrIndex = 0;

            state.PdbScope = new PdbScope()
            {
                Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex),
                End   = GetInstruction(body.Instructions, state.SymScope.EndOffset, ref instrIndex),
            };

            foreach (var symLocal in state.SymScope.GetLocals())
            {
                if (symLocal.AddressKind != SymAddressKind.ILOffset)
                {
                    continue;
                }

                int localIndex = symLocal.AddressField1;
                if ((uint)localIndex >= (uint)body.Variables.Count)
                {
                    continue;
                }
                var local = body.Variables[localIndex];
                local.Name = symLocal.Name;
                var attributes = symLocal.Attributes;
                if (attributes is int)
                {
                    local.PdbAttributes = (int)attributes;
                }
                state.PdbScope.Variables.Add(local);
            }

            foreach (var ns in state.SymScope.GetNamespaces())
            {
                state.PdbScope.Namespaces.Add(ns.Name);
            }

            // Here's the now somewhat obfuscated for loop
            state.ChildrenIndex = 0;
            state.Children      = state.SymScope.GetChildren();
do_return:
            if (state.ChildrenIndex < state.Children.Length)
            {
                var child = state.Children[state.ChildrenIndex];
                stack.Push(state);
                state = new CreateScopeState()
                {
                    SymScope = child
                };
                goto recursive_call;
            }

            if (stack.Count == 0)
            {
                return(state.PdbScope);
            }

            // Return from recursive call, and execute the last part of the for loop
            var newPdbScope = state.PdbScope;

            state = stack.Pop();
            state.PdbScope.Scopes.Add(newPdbScope);
            state.ChildrenIndex++;
            goto do_return;
        }
예제 #27
0
            public Trace(CilBody body, bool hasReturnValue)
            {
                RefCount    = new Dictionary <uint, int>();
                BrRefs      = new Dictionary <uint, List <Instruction> >();
                BeforeStack = new Dictionary <uint, int>();
                AfterStack  = new Dictionary <uint, int>();

                body.UpdateInstructionOffsets();

                foreach (ExceptionHandler eh in body.ExceptionHandlers)
                {
                    BeforeStack[eh.TryStart.Offset]     = 0;
                    BeforeStack[eh.HandlerStart.Offset] = (eh.HandlerType != ExceptionHandlerType.Finally ? 1 : 0);
                    if (eh.FilterStart != null)
                    {
                        BeforeStack[eh.FilterStart.Offset] = 1;
                    }
                }

                int currentStack = 0;

                for (int i = 0; i < body.Instructions.Count; i++)
                {
                    var instr = body.Instructions[i];

                    if (BeforeStack.ContainsKey(instr.Offset))
                    {
                        currentStack = BeforeStack[instr.Offset];
                    }

                    BeforeStack[instr.Offset] = currentStack;
                    instr.UpdateStack(ref currentStack, hasReturnValue);
                    AfterStack[instr.Offset] = currentStack;

                    uint offset;
                    switch (instr.OpCode.FlowControl)
                    {
                    case FlowControl.Branch:
                        offset = ((Instruction)instr.Operand).Offset;
                        if (!BeforeStack.ContainsKey(offset))
                        {
                            BeforeStack[offset] = currentStack;
                        }

                        Increment(RefCount, offset);
                        BrRefs.AddListEntry(offset, instr);

                        currentStack = 0;
                        continue;

                    case FlowControl.Call:
                        if (instr.OpCode.Code == Code.Jmp)
                        {
                            currentStack = 0;
                        }
                        break;

                    case FlowControl.Cond_Branch:
                        if (instr.OpCode.Code == Code.Switch)
                        {
                            foreach (Instruction target in (Instruction[])instr.Operand)
                            {
                                if (!BeforeStack.ContainsKey(target.Offset))
                                {
                                    BeforeStack[target.Offset] = currentStack;
                                }

                                Increment(RefCount, target.Offset);
                                BrRefs.AddListEntry(target.Offset, instr);
                            }
                        }
                        else
                        {
                            offset = ((Instruction)instr.Operand).Offset;
                            if (!BeforeStack.ContainsKey(offset))
                            {
                                BeforeStack[offset] = currentStack;
                            }

                            Increment(RefCount, offset);
                            BrRefs.AddListEntry(offset, instr);
                        }
                        break;

                    case FlowControl.Meta:
                    case FlowControl.Next:
                    case FlowControl.Break:
                        break;

                    case FlowControl.Return:
                    case FlowControl.Throw:
                        continue;

                    default:
                        throw new UnreachableException();
                    }

                    if (i + 1 < body.Instructions.Count)
                    {
                        offset = body.Instructions[i + 1].Offset;
                        Increment(RefCount, offset);
                    }
                }
            }
예제 #28
0
        public override void Mangle(CilBody body, ScopeBlock root, CFContext ctx)
        {
            Trace trace = new Trace(body, ctx.Method.ReturnType.RemoveModifiers().ElementType != ElementType.Void);
            var   local = new Local(ctx.Method.Module.CorLibTypes.UInt32);

            body.Variables.Add(local);
            body.InitLocals = true;

            body.MaxStack += 2;
            IPredicate predicate = null;

            if (ctx.Predicate == PredicateType.Normal)
            {
                predicate = new NormalPredicate(ctx);
            }
            else if (ctx.Predicate == PredicateType.Expression)
            {
                predicate = new ExpressionPredicate(ctx);
            }
            else if (ctx.Predicate == PredicateType.x86)
            {
                predicate = new x86Predicate(ctx);
            }

            foreach (InstrBlock block in GetAllBlocks(root))
            {
                LinkedList <Instruction[]> statements = SpiltStatements(block, trace, ctx);

                // Make sure .ctor is executed before switch
                if (ctx.Method.IsInstanceConstructor)
                {
                    var newStatement = new List <Instruction>();
                    while (statements.First != null)
                    {
                        newStatement.AddRange(statements.First.Value);
                        Instruction lastInstr = statements.First.Value.Last();
                        statements.RemoveFirst();
                        if (lastInstr.OpCode == OpCodes.Call && ((IMethod)lastInstr.Operand).Name == ".ctor")
                        {
                            break;
                        }
                    }
                    statements.AddFirst(newStatement.ToArray());
                }

                if (statements.Count < 3)
                {
                    continue;
                }

                int i;

                var keyId = Enumerable.Range(0, statements.Count).ToArray();
                ctx.Random.Shuffle(keyId);
                var key = new int[keyId.Length];
                for (i = 0; i < key.Length; i++)
                {
                    var q = ctx.Random.NextInt32() & 0x7fffffff;
                    key[i] = q - q % statements.Count + keyId[i];
                }

                var statementKeys = new Dictionary <Instruction, int>();
                LinkedListNode <Instruction[]> current = statements.First;
                i = 0;
                while (current != null)
                {
                    if (i != 0)
                    {
                        statementKeys[current.Value[0]] = key[i];
                    }
                    i++;
                    current = current.Next;
                }

                var statementLast = new HashSet <Instruction>(statements.Select(st => st.Last()));

                Func <IList <Instruction>, bool> hasUnknownSource;
                hasUnknownSource = instrs => instrs.Any(instr =>
                {
                    if (trace.HasMultipleSources(instr.Offset))
                    {
                        return(true);
                    }
                    List <Instruction> srcs;
                    if (trace.BrRefs.TryGetValue(instr.Offset, out srcs))
                    {
                        // Target of switch => assume unknown
                        if (srcs.Any(src => src.Operand is Instruction[]))
                        {
                            return(true);
                        }

                        // Not within current instruction block / targeted in first statement
                        if (srcs.Any(src => src.Offset <= statements.First.Value.Last().Offset ||
                                     src.Offset >= block.Instructions.Last().Offset))
                        {
                            return(true);
                        }

                        // Not targeted by the last of statements
                        if (srcs.Any(src => statementLast.Contains(src)))
                        {
                            return(true);
                        }
                    }
                    return(false);
                });

                var switchInstr = new Instruction(OpCodes.Switch);
                var switchHdr   = new List <Instruction>();

                if (predicate != null)
                {
                    predicate.Init(body);
                    switchHdr.Add(Instruction.CreateLdcI4(predicate.GetSwitchKey(key[1])));
                    predicate.EmitSwitchLoad(switchHdr);
                }
                else
                {
                    switchHdr.Add(Instruction.CreateLdcI4(key[1]));
                }

                switchHdr.Add(Instruction.Create(OpCodes.Dup));
                switchHdr.Add(Instruction.Create(OpCodes.Stloc, local));
                switchHdr.Add(Instruction.Create(OpCodes.Ldc_I4, statements.Count));
                switchHdr.Add(Instruction.Create(OpCodes.Rem_Un));
                switchHdr.Add(switchInstr);

                ctx.AddJump(switchHdr, statements.Last.Value[0]);
                ctx.AddJunk(switchHdr);

                var operands = new Instruction[statements.Count];
                current = statements.First;
                i       = 0;
                while (current.Next != null)
                {
                    var newStatement = new List <Instruction>(current.Value);

                    if (i != 0)
                    {
                        // Convert to switch
                        bool converted = false;

                        if (newStatement.Last().IsBr())
                        {
                            // Unconditional

                            var target = (Instruction)newStatement.Last().Operand;
                            int brKey;
                            if (!trace.IsBranchTarget(newStatement.Last().Offset) &&
                                statementKeys.TryGetValue(target, out brKey))
                            {
                                var targetKey = predicate != null?predicate.GetSwitchKey(brKey) : brKey;

                                var unkSrc = hasUnknownSource(newStatement);

                                newStatement.RemoveAt(newStatement.Count - 1);

                                if (unkSrc)
                                {
                                    newStatement.Add(Instruction.Create(OpCodes.Ldc_I4, targetKey));
                                }
                                else
                                {
                                    var thisKey = key[i];
                                    var r       = ctx.Random.NextInt32();
                                    newStatement.Add(Instruction.Create(OpCodes.Ldloc, local));
                                    newStatement.Add(Instruction.CreateLdcI4(r));
                                    newStatement.Add(Instruction.Create(OpCodes.Mul));
                                    newStatement.Add(Instruction.Create(OpCodes.Ldc_I4, (thisKey * r) ^ targetKey));
                                    newStatement.Add(Instruction.Create(OpCodes.Xor));
                                }

                                ctx.AddJump(newStatement, switchHdr[1]);
                                ctx.AddJunk(newStatement);
                                operands[keyId[i]] = newStatement[0];
                                converted          = true;
                            }
                        }
                        else if (newStatement.Last().IsConditionalBranch())
                        {
                            // Conditional

                            var target = (Instruction)newStatement.Last().Operand;
                            int brKey;
                            if (!trace.IsBranchTarget(newStatement.Last().Offset) &&
                                statementKeys.TryGetValue(target, out brKey))
                            {
                                bool   unkSrc  = hasUnknownSource(newStatement);
                                int    nextKey = key[i + 1];
                                OpCode condBr  = newStatement.Last().OpCode;
                                newStatement.RemoveAt(newStatement.Count - 1);

                                if (ctx.Random.NextBoolean())
                                {
                                    condBr = InverseBranch(condBr);
                                    int tmp = brKey;
                                    brKey   = nextKey;
                                    nextKey = tmp;
                                }

                                var thisKey = key[i];
                                int r = 0, xorKey = 0;
                                if (!unkSrc)
                                {
                                    r      = ctx.Random.NextInt32();
                                    xorKey = thisKey * r;
                                }

                                Instruction brKeyInstr   = Instruction.CreateLdcI4(xorKey ^ (predicate != null ? predicate.GetSwitchKey(brKey) : brKey));
                                Instruction nextKeyInstr = Instruction.CreateLdcI4(xorKey ^ (predicate != null ? predicate.GetSwitchKey(nextKey) : nextKey));
                                Instruction pop          = Instruction.Create(OpCodes.Pop);

                                newStatement.Add(Instruction.Create(condBr, brKeyInstr));
                                newStatement.Add(nextKeyInstr);
                                newStatement.Add(Instruction.Create(OpCodes.Dup));
                                newStatement.Add(Instruction.Create(OpCodes.Br, pop));
                                newStatement.Add(brKeyInstr);
                                newStatement.Add(Instruction.Create(OpCodes.Dup));
                                newStatement.Add(pop);

                                if (!unkSrc)
                                {
                                    newStatement.Add(Instruction.Create(OpCodes.Ldloc, local));
                                    newStatement.Add(Instruction.CreateLdcI4(r));
                                    newStatement.Add(Instruction.Create(OpCodes.Mul));
                                    newStatement.Add(Instruction.Create(OpCodes.Xor));
                                }

                                ctx.AddJump(newStatement, switchHdr[1]);
                                ctx.AddJunk(newStatement);
                                operands[keyId[i]] = newStatement[0];
                                converted          = true;
                            }
                        }

                        if (!converted)
                        {
                            // Normal

                            var targetKey = predicate != null?predicate.GetSwitchKey(key[i + 1]) : key[i + 1];

                            if (!hasUnknownSource(newStatement))
                            {
                                var thisKey = key[i];
                                var r       = ctx.Random.NextInt32();
                                newStatement.Add(Instruction.Create(OpCodes.Ldloc, local));
                                newStatement.Add(Instruction.CreateLdcI4(r));
                                newStatement.Add(Instruction.Create(OpCodes.Mul));
                                newStatement.Add(Instruction.Create(OpCodes.Ldc_I4, (thisKey * r) ^ targetKey));
                                newStatement.Add(Instruction.Create(OpCodes.Xor));
                            }
                            else
                            {
                                newStatement.Add(Instruction.Create(OpCodes.Ldc_I4, targetKey));
                            }

                            ctx.AddJump(newStatement, switchHdr[1]);
                            ctx.AddJunk(newStatement);
                            operands[keyId[i]] = newStatement[0];
                        }
                    }
                    else
                    {
                        operands[keyId[i]] = switchHdr[0];
                    }

                    current.Value = newStatement.ToArray();
                    current       = current.Next;
                    i++;
                }
                operands[keyId[i]]  = current.Value[0];
                switchInstr.Operand = operands;

                Instruction[] first = statements.First.Value;
                statements.RemoveFirst();
                Instruction[] last = statements.Last.Value;
                statements.RemoveLast();

                List <Instruction[]> newStatements = statements.ToList();
                ctx.Random.Shuffle(newStatements);

                block.Instructions.Clear();
                block.Instructions.AddRange(first);
                block.Instructions.AddRange(switchHdr);
                foreach (var statement in newStatements)
                {
                    block.Instructions.AddRange(statement);
                }
                block.Instructions.AddRange(last);
            }
        }
예제 #29
0
        (string methodName, DkmClrCompilationResultFlags flags) AddMethod(TypeSig type, int index, bool isLocal)
        {
            var methodName = methodNamePrefix + methodNameIndex++.ToString();

            var callConv = CallingConvention.Default;

            if (sourceMethod.MethodSig.Generic)
            {
                callConv |= CallingConvention.Generic;
            }
            var methodSig = new MethodSig(callConv, sourceMethod.MethodSig.GenParamCount);

            methodSig.RetType = generatedModule.Import(type.RemovePinnedAndModifiers());
            if (methodSig.RetType.IsByRef)
            {
                methodSig.RetType = methodSig.RetType.Next.RemovePinnedAndModifiers();
            }

            if (lastMethodSig != null)
            {
                foreach (var p in lastMethodSig.Params)
                {
                    methodSig.Params.Add(p);
                }
            }
            else
            {
                if (sourceMethod.MethodSig.HasThis)
                {
                    methodSig.Params.Add(generatedModule.Import(sourceMethod.DeclaringType).ToTypeSig());
                }
                foreach (var p in sourceMethod.MethodSig.Params)
                {
                    methodSig.Params.Add(generatedModule.Import(p));
                }
            }

            const MethodImplAttributes methodImplFlags = MethodImplAttributes.IL | MethodImplAttributes.Managed;
            const MethodAttributes     methodFlags     = MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.ReuseSlot;
            var method = new MethodDefUser(methodName, methodSig, methodImplFlags, methodFlags);

            getLocalsType.Methods.Add(method);

            foreach (var gp in sourceMethod.GenericParameters)
            {
                method.GenericParameters.Add(Clone(gp));
            }

            var body = new CilBody();

            method.Body     = body;
            body.InitLocals = true;
            if (sourceMethod.Body != null)
            {
                foreach (var l in sourceMethod.Body.Variables)
                {
                    body.Variables.Add(new Local(generatedModule.Import(l.Type), l.Name));
                }
            }
            body.Instructions.Add(CreateLoadVariable(method, body.Variables, index, isLocal));
            if (type.RemovePinnedAndModifiers().GetElementType() == ElementType.ByRef)
            {
                body.Instructions.Add(LoadIndirect(type.RemovePinnedAndModifiers().Next.RemovePinnedAndModifiers()));
            }
            body.Instructions.Add(Instruction.Create(OpCodes.Ret));

            lastMethodSig = methodSig;
            var flags = DkmClrCompilationResultFlags.None;

            if (methodSig.RetType.RemovePinnedAndModifiers().GetElementType() == ElementType.Boolean)
            {
                flags |= DkmClrCompilationResultFlags.BoolResult;
            }
            return(methodName, flags);
        }
예제 #30
0
 public void Write(CilBody body)
 {
     body.Instructions.Clear();
     Commit(body);
 }