Пример #1
0
        LinkedList <Instruction[]> SpiltStatements(InstrBlock block, Trace trace, CFContext ctx)
        {
            var statements       = new LinkedList <Instruction[]>();
            var currentStatement = new List <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;
                    break;
                }
                if ((instr.OpCode.OpCodeType != OpCodeType.Prefix && trace.AfterStack[instr.Offset] == 0) &&
                    (shouldSpilt || ctx.Intensity > ctx.Random.NextDouble()))
                {
                    statements.AddLast(currentStatement.ToArray());
                    currentStatement.Clear();
                }
            }

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

            return(statements);
        }
Пример #2
0
        private LinkedList <Instruction[]> SpiltStatements(InstrBlock block, MethodTrace trace, CFContext ctx)
        {
            var statements       = new LinkedList <Instruction[]>();
            var currentStatement = new List <Instruction>();

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

                bool nextIsBrTarget = i + 1 < block.Instructions.Count && trace.IsBranchTarget(trace.OffsetToIndexMap(block.Instructions[i + 1].Offset));

                if ((instr.OpCode.OpCodeType != OpCodeType.Prefix && trace.AfterStackDepths[trace.OffsetToIndexMap(instr.Offset)] == 0) &&
                    (nextIsBrTarget || ctx.Intensity > ctx.Random.NextDouble()))
                {
                    statements.AddLast(currentStatement.ToArray());
                    currentStatement.Clear();
                }
            }

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

            return(statements);
        }
Пример #3
0
        private 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;
        }
Пример #4
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:
                    if (trace.AfterStack[instr.Offset] != 0)
                    {
                        if (instr.Operand is Instruction)
                        {
                            requiredInstr.Add((Instruction)instr.Operand);
                        }
                        else
                        {
                            foreach (var target in (Instruction[])instr.Operand)
                            {
                                requiredInstr.Add(target);
                            }
                            shouldSpilt = false;
                        }
                    }
                    shouldSpilt = true;
                    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);
        }
Пример #5
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;
                }
                else if (HasInstructionSeq(block.Instructions, i, Code.Dup, Code.Ldvirtftn, Code.Newobj))
                {
                    skipCount = 2;
                }
                else if (HasInstructionSeq(block.Instructions, i, Code.Ldc_I4, Code.Newarr, Code.Dup, Code.Ldtoken, Code.Call))                  // Array initializer
                {
                    skipCount = 4;
                }
                else if (HasInstructionSeq(block.Instructions, i, Code.Ldftn, Code.Newobj))                  // Create delegate to function
                {
                    skipCount = 1;
                }
                currentFragment.Add(block.Instructions[i]);

                if (skipCount == -1 && ctx.Intensity > ctx.Random.NextDouble())
                {
                    fragments.AddLast(currentFragment.ToArray());
                    currentFragment.Clear();
                }
            }

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

            return(fragments);
        }
Пример #6
0
        LinkedList<Instruction[]> SpiltStatements(InstrBlock block, Trace trace, CFContext ctx)
        {
            var statements = new LinkedList<Instruction[]>();
            var currentStatement = new List<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;
                        break;
                }
                if ((instr.OpCode.OpCodeType != OpCodeType.Prefix && (trace.AfterStack[instr.Offset] == 0 || instr.IsBr())) &&
                    (shouldSpilt || ctx.Intensity > ctx.Random.NextDouble())) {
                    statements.AddLast(currentStatement.ToArray());
                    currentStatement.Clear();
                }
            }

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

            return statements;
        }
Пример #7
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)
                    {
                        parent?.Children.Add(ehScope.Item1);
                        scopeStack.Push(ehScope.Item1);
                    }

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

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

                ScopeBlock scope = scopeStack.Peek();
                if (!(scope.Children.LastOrDefault() is InstrBlock block))
                {
                    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);
        }
Пример #8
0
        LinkedList <Instruction[]> SpiltFragments(InstrBlock block, CFContext ctx)
        {
            var fragments       = new LinkedList <Instruction[]>();
            var currentFragment = new List <Instruction>();

            var skipCount = -1;

            for (var 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);
        }
Пример #9
0
        LinkedList<Instruction[]> SpiltStatements(InstrBlock block, MethodTrace trace, CFContext ctx)
        {
            var statements = new LinkedList<Instruction[]>();
            var currentStatement = new List<Instruction>();

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

                bool nextIsBrTarget = i + 1 < block.Instructions.Count && trace.IsBranchTarget(trace.OffsetToIndexMap(block.Instructions[i + 1].Offset));

                if ((instr.OpCode.OpCodeType != OpCodeType.Prefix && trace.AfterStackDepths[trace.OffsetToIndexMap(instr.Offset)] == 0) &&
                    (nextIsBrTarget || ctx.Intensity > ctx.Random.NextDouble())) {
                    statements.AddLast(currentStatement.ToArray());
                    currentStatement.Clear();
                }
            }

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

            return statements;
        }
Пример #10
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:
                        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);
                                shouldSpilt = false;
                            }
                        }
                        shouldSpilt = true;
                        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;
        }
Пример #11
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;
		}