Beispiel #1
0
        LinkedList <Instruction[]> SpiltStatements(InstrBlock block, Trace trace, CFContext ctx)
        {
            var statements       = new LinkedList <Instruction[]>();
            var currentStatement = new List <Instruction>();

            // Instructions that must be included in the ccurrent statement to ensure all outgoing
            // branches have stack = 0
            var requiredInstr = new HashSet <Instruction>();

            for (int i = 0; i < block.Instructions.Count; i++)
            {
                Instruction instr = block.Instructions[i];
                currentStatement.Add(instr);

                bool shouldSpilt = i + 1 < block.Instructions.Count && trace.HasMultipleSources(block.Instructions[i + 1].Offset);
                switch (instr.OpCode.FlowControl)
                {
                case FlowControl.Branch:
                case FlowControl.Cond_Branch:
                case FlowControl.Return:
                case FlowControl.Throw:
                    shouldSpilt = true;
                    if (trace.AfterStack[instr.Offset] != 0)
                    {
                        if (instr.Operand is Instruction)
                        {
                            requiredInstr.Add((Instruction)instr.Operand);
                        }
                        else if (instr.Operand is Instruction[])
                        {
                            foreach (var target in (Instruction[])instr.Operand)
                            {
                                requiredInstr.Add(target);
                            }
                        }
                    }
                    break;
                }
                requiredInstr.Remove(instr);
                if ((instr.OpCode.OpCodeType != OpCodeType.Prefix && trace.AfterStack[instr.Offset] == 0 &&
                     requiredInstr.Count == 0) &&
                    (shouldSpilt || ctx.Intensity > ctx.Random.NextDouble()))
                {
                    statements.AddLast(currentStatement.ToArray());
                    currentStatement.Clear();
                }
            }

            if (currentStatement.Count > 0)
            {
                statements.AddLast(currentStatement.ToArray());
            }

            return(statements);
        }
Beispiel #2
0
        LinkedList <Instruction[]> SpiltFragments(InstrBlock block, CFContext ctx)
        {
            var fragments       = new LinkedList <Instruction[]>();
            var currentFragment = new List <Instruction>();

            int skipCount = -1;

            for (int i = 0; i < block.Instructions.Count; i++)
            {
                if (skipCount != -1)
                {
                    if (skipCount > 0)
                    {
                        currentFragment.Add(block.Instructions[i]);
                        skipCount--;
                        continue;
                    }
                    fragments.AddLast(currentFragment.ToArray());
                    currentFragment.Clear();

                    skipCount = -1;
                }

                if (block.Instructions[i].OpCode.OpCodeType == OpCodeType.Prefix)
                {
                    skipCount = 1;
                    currentFragment.Add(block.Instructions[i]);
                }
                if (i + 2 < block.Instructions.Count &&
                    block.Instructions[i + 0].OpCode.Code == Code.Dup &&
                    block.Instructions[i + 1].OpCode.Code == Code.Ldvirtftn &&
                    block.Instructions[i + 2].OpCode.Code == Code.Newobj)
                {
                    skipCount = 2;
                    currentFragment.Add(block.Instructions[i]);
                }
                if (i + 4 < block.Instructions.Count &&
                    block.Instructions[i + 0].OpCode.Code == Code.Ldc_I4 &&
                    block.Instructions[i + 1].OpCode.Code == Code.Newarr &&
                    block.Instructions[i + 2].OpCode.Code == Code.Dup &&
                    block.Instructions[i + 3].OpCode.Code == Code.Ldtoken &&
                    block.Instructions[i + 4].OpCode.Code == Code.Call)                 // Array initializer
                {
                    skipCount = 4;
                    currentFragment.Add(block.Instructions[i]);
                }
                if (i + 1 < block.Instructions.Count &&
                    block.Instructions[i + 0].OpCode.Code == Code.Ldftn &&
                    block.Instructions[i + 1].OpCode.Code == Code.Newobj)
                {
                    skipCount = 1;
                    currentFragment.Add(block.Instructions[i]);
                }
                currentFragment.Add(block.Instructions[i]);

                if (ctx.Intensity > ctx.Random.NextDouble())
                {
                    fragments.AddLast(currentFragment.ToArray());
                    currentFragment.Clear();
                }
            }

            if (currentFragment.Count > 0)
            {
                fragments.AddLast(currentFragment.ToArray());
            }

            return(fragments);
        }
Beispiel #3
0
        public static ScopeBlock ParseBody(CilBody body)
        {
            var ehScopes = new Dictionary <ExceptionHandler, Tuple <ScopeBlock, ScopeBlock, ScopeBlock> >();

            foreach (ExceptionHandler eh in body.ExceptionHandlers)
            {
                var tryBlock = new ScopeBlock(BlockType.Try, eh);

                var handlerType = BlockType.Handler;

                if (eh.HandlerType == ExceptionHandlerType.Finally)
                {
                    handlerType = BlockType.Finally;
                }
                else if (eh.HandlerType == ExceptionHandlerType.Fault)
                {
                    handlerType = BlockType.Fault;
                }

                var handlerBlock = new ScopeBlock(handlerType, eh);

                if (eh.FilterStart != null)
                {
                    var filterBlock = new ScopeBlock(BlockType.Filter, eh);
                    ehScopes[eh] = Tuple.Create(tryBlock, handlerBlock, filterBlock);
                }
                else
                {
                    ehScopes[eh] = Tuple.Create(tryBlock, handlerBlock, (ScopeBlock)null);
                }
            }

            var root       = new ScopeBlock(BlockType.Normal, null);
            var scopeStack = new Stack <ScopeBlock>();

            scopeStack.Push(root);
            foreach (Instruction instr in body.Instructions)
            {
                foreach (ExceptionHandler eh in body.ExceptionHandlers)
                {
                    Tuple <ScopeBlock, ScopeBlock, ScopeBlock> ehScope = ehScopes[eh];

                    if (instr == eh.TryEnd)
                    {
                        scopeStack.Pop();
                    }

                    if (instr == eh.HandlerEnd)
                    {
                        scopeStack.Pop();
                    }

                    if (eh.FilterStart != null && instr == eh.HandlerStart)
                    {
                        // Filter must precede handler immediately
                        Debug.Assert(scopeStack.Peek().Type == BlockType.Filter);
                        scopeStack.Pop();
                    }
                }
                foreach (ExceptionHandler eh in body.ExceptionHandlers.Reverse())
                {
                    Tuple <ScopeBlock, ScopeBlock, ScopeBlock> ehScope = ehScopes[eh];
                    ScopeBlock parent = scopeStack.Count > 0 ? scopeStack.Peek() : null;

                    if (instr == eh.TryStart)
                    {
                        if (parent != null)
                        {
                            parent.Children.Add(ehScope.Item1);
                        }
                        scopeStack.Push(ehScope.Item1);
                    }

                    if (instr == eh.HandlerStart)
                    {
                        if (parent != null)
                        {
                            parent.Children.Add(ehScope.Item2);
                        }
                        scopeStack.Push(ehScope.Item2);
                    }

                    if (instr == eh.FilterStart)
                    {
                        if (parent != null)
                        {
                            parent.Children.Add(ehScope.Item3);
                        }
                        scopeStack.Push(ehScope.Item3);
                    }
                }

                ScopeBlock scope = scopeStack.Peek();
                var        block = scope.Children.LastOrDefault() as InstrBlock;
                if (block == null)
                {
                    scope.Children.Add(block = new InstrBlock());
                }
                block.Instructions.Add(instr);
            }
            foreach (ExceptionHandler eh in body.ExceptionHandlers)
            {
                if (eh.TryEnd == null)
                {
                    scopeStack.Pop();
                }
                if (eh.HandlerEnd == null)
                {
                    scopeStack.Pop();
                }
            }
            Debug.Assert(scopeStack.Count == 1);
            return(root);
        }