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); }
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); }
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; }
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); }
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); }
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; }
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); }
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); }
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; }
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; }
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; }