示例#1
0
		/// <summary>
		///     Replaces the placeholder call in method with actual instruction sequence.
		/// </summary>
		/// <param name="method">The methodto process.</param>
		/// <param name="repl">The function replacing the argument of placeholder call with actual instruction sequence.</param>
		public static void ReplacePlaceholder(MethodDef method, Func<Instruction[], Instruction[]> repl) {
			MethodTrace trace = new MethodTrace(method).Trace();
			for (int i = 0; i < method.Body.Instructions.Count; i++) {
				Instruction instr = method.Body.Instructions[i];
				if (instr.OpCode == OpCodes.Call) {
					var operand = (IMethod)instr.Operand;
					if (operand.DeclaringType.FullName == mutationType &&
					    operand.Name == "Placeholder") {
						int[] argIndexes = trace.TraceArguments(instr);
						if (argIndexes == null)
							throw new ArgumentException("Failed to trace placeholder argument.");

						int argIndex = argIndexes[0];
						Instruction[] arg = method.Body.Instructions.Skip(argIndex).Take(i - argIndex).ToArray();
						for (int j = 0; j < arg.Length; j++)
							method.Body.Instructions.RemoveAt(argIndex);
						method.Body.Instructions.RemoveAt(argIndex);
						arg = repl(arg);
						for (int j = arg.Length - 1; j >= 0; j--)
							method.Body.Instructions.Insert(argIndex, arg[j]);
						return;
					}
				}
			}
		}
示例#2
0
		/// <inheritdoc />
		public MethodTrace Trace(MethodDef method) {
			if (method == null)
				throw new ArgumentNullException("method");
			return cache.GetValueOrDefaultLazy(method, m => cache[m] = new MethodTrace(m)).Trace();
		}
示例#3
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;
        }