/// <summary> /// Initializes a new instance of the MethodWeaver class. /// </summary> /// <param name="rewriter">The <see cref="IMethodRewriter"/> instance that will modify the existing method.</param> /// <param name="instructionProvider">The provider that will obtain the original instructions for the target method.</param> /// <param name="filter">The filter that determines which methods should be modified.</param> public MethodWeaver(IMethodRewriter rewriter, IInstructionProvider instructionProvider, Func <MethodReference, bool> filter) { _filter = filter; _rewriter = rewriter; _instructionProvider = instructionProvider; }
/// <summary> /// Initializes a new instance of the MethodWeaver class. /// </summary> /// <param name="rewriter">The <see cref="IMethodRewriter"/> instance that will modify the existing method.</param> /// <param name="instructionProvider">The provider that will obtain the original instructions for the target method.</param> /// <param name="filter">The filter that determines which methods should be modified.</param> public MethodWeaver(IMethodRewriter rewriter, IInstructionProvider instructionProvider, Func<MethodReference, bool> filter) { _filter = filter; _rewriter = rewriter; _instructionProvider = instructionProvider; }
/// <summary> /// Transforms the methods in the <paramref name="target"/> using the given method rewriter. /// </summary> /// <param name="target">The transformation target.</param> /// <param name="rewriter">The method rewriter.</param> /// <param name="filter">The method filter that determines which methods will be rewritten.</param> public static void WeaveWith(this IReflectionVisitable target, IMethodRewriter rewriter, Func <MethodReference, bool> filter) { var weaver = new MethodWeaver(rewriter, filter); target.Accept(weaver); }
internal AssemblyRewriter( Configuration configuration, IEnumerable<SetupTarget> targets, IMethodRewriter methodRewriter, IModuleFilter moduleFilter) : this(configuration, new SetupTargetCollection(targets), methodRewriter, moduleFilter) { }
/// <summary> /// Initializes a new instance of the <see cref="TypeRewriter"/> class. /// </summary> /// <param name="mscorlib">The mscorlib assembly definition used for setting up.</param> /// <param name="useDllImport">Whether to use DllImport instead of GetProcAddress for native calls.</param> /// <param name="methodRewriter"> /// The <see cref="IMethodRewriter"/> implementation to use for rewriting methods inside a type. /// </param> public TypeRewriter ( AssemblyDefinition mscorlib, bool useDllImport, IMethodRewriter methodRewriter ) { _boolType = mscorlib.MainModule.GetType(typeof(bool).FullName); _useDllImport = useDllImport; _methodRewriter = methodRewriter ?? throw new ArgumentNullException(nameof(methodRewriter)); }
internal AssemblyRewriter( Configuration configuration, IEnumerable <IRewriteTarget> targets, IMethodRewriter methodRewriter, IModuleFilter moduleFilter) : this( configuration, new RewriteTargetCollection(targets), methodRewriter, moduleFilter) { }
internal AssemblyRewriter( Configuration configuration, IRewriteTargetCollection rewriteTargetCollection, IMethodRewriter methodRewriter, IModuleFilter moduleFilter) { ArgumentChecker.NotNull(configuration, () => configuration); ArgumentChecker.NotNull(rewriteTargetCollection, () => rewriteTargetCollection); ArgumentChecker.NotNull(methodRewriter, () => methodRewriter); ArgumentChecker.NotNull(moduleFilter, () => moduleFilter); _configuration = configuration; _rewriteTargetCollection = rewriteTargetCollection; _methodRewriter = methodRewriter; _moduleFilter = moduleFilter; }
internal AssemblyRewriter( Configuration configuration, ISetupTargetCollection setupTargetCollection, IMethodRewriter methodRewriter, IModuleFilter moduleFilter) { ArgumentChecker.NotNull(configuration, () => configuration); ArgumentChecker.NotNull(setupTargetCollection, () => setupTargetCollection); ArgumentChecker.NotNull(methodRewriter, () => methodRewriter); ArgumentChecker.NotNull(moduleFilter, () => moduleFilter); _configuration = configuration; _setupTargetCollection = setupTargetCollection; _methodRewriter = methodRewriter; _moduleFilter = moduleFilter; }
internal AssemblyRewriter( Configuration configuration, IAssemblyResolver assemblyResolver, IEnumerable <IRewriteTarget> targets, IMethodRewriter methodRewriter, IModuleFilter moduleFilter, IEnumerable <IAssemblyPostProcessor> postProcessors) : this( configuration, assemblyResolver, new RewriteTargetCollection(targets), methodRewriter, moduleFilter, postProcessors) { }
internal AssemblyRewriter( Configuration configuration, IAssemblyResolver assemblyResolver, IRewriteTargetCollection rewriteTargetCollection, IMethodRewriter methodRewriter, IModuleFilter moduleFilter, IEnumerable <IAssemblyPostProcessor> postProcessors) { ArgumentChecker.NotNull(configuration, nameof(configuration)); ArgumentChecker.NotNull(assemblyResolver, nameof(assemblyResolver)); ArgumentChecker.NotNull(rewriteTargetCollection, nameof(rewriteTargetCollection)); ArgumentChecker.NotNull(methodRewriter, nameof(methodRewriter)); ArgumentChecker.NotNull(moduleFilter, nameof(moduleFilter)); ArgumentChecker.NotNull(moduleFilter, nameof(postProcessors)); _configuration = configuration; _assemblyResolver = assemblyResolver; _rewriteTargetCollection = rewriteTargetCollection; _methodRewriter = methodRewriter; _moduleFilter = moduleFilter; _postProcessors = postProcessors; }
/// <summary> /// Initializes a new instance of the MethodWeaver class. /// </summary> /// <param name="rewriter">The <see cref="IMethodRewriter"/> instance that will modify the existing method.</param> /// <param name="filter">The filter that determines which methods should be modified.</param> public MethodWeaver(IMethodRewriter rewriter, Func<MethodReference, bool> filter) : this(rewriter, new InstructionProvider(), filter) { }
/// <summary> /// Transforms the methods in the <paramref name="target"/> using the given method rewriter. /// </summary> /// <param name="target">The transformation target.</param> /// <param name="rewriter">The method rewriter.</param> /// <param name="filter">The method filter that determines which methods will be rewritten.</param> public static void WeaveWith(this IReflectionVisitable target, IMethodRewriter rewriter, Func<MethodReference, bool> filter) { var weaver = new MethodWeaver(rewriter, filter); target.Accept(weaver); }
internal AssemblyRewriter(IMethodRewriter methodRewriter, IModuleFilter moduleFilter) : this(methodRewriter, moduleFilter, Enumerable.Empty <IAssemblyPostProcessor>()) { }
/// <summary> /// Initializes a new instance of the MethodWeaver class. /// </summary> /// <param name="rewriter">The <see cref="IMethodRewriter"/> instance that will modify the existing method.</param> /// <param name="filter">The filter that determines which methods should be modified.</param> public MethodWeaver(IMethodRewriter rewriter, Func <MethodReference, bool> filter) : this(rewriter, new InstructionProvider(), filter) { }
/// <summary>Rewrite the types referenced by an assembly.</summary> /// <param name="assembly">The assembly to rewrite.</param> public void RewriteAssembly(AssemblyDefinition assembly) { ModuleDefinition module = assembly.Modules.Single(); // technically an assembly can have multiple modules, but none of the build tools (including MSBuild) support it; simplify by assuming one module // remove old assembly references bool shouldRewrite = false; for (int i = 0; i < module.AssemblyReferences.Count; i++) { if (this.AssemblyMap.RemoveNames.Any(name => module.AssemblyReferences[i].Name == name)) { this.Monitor.Log($"removing reference to {module.AssemblyReferences[i]}", LogLevel.Trace); shouldRewrite = true; module.AssemblyReferences.RemoveAt(i); i--; } } if (!shouldRewrite) { return; } // add target assembly references foreach (AssemblyNameReference target in this.AssemblyMap.TargetReferences.Values) { this.Monitor.Log($" adding reference to {target}", LogLevel.Trace); module.AssemblyReferences.Add(target); } // rewrite type scopes to use target assemblies IEnumerable <TypeReference> typeReferences = module.GetTypeReferences().OrderBy(p => p.FullName); string lastTypeLogged = null; foreach (TypeReference type in typeReferences) { this.ChangeTypeScope(type, shouldLog: type.FullName != lastTypeLogged); lastTypeLogged = type.FullName; } // rewrite incompatible methods IMethodRewriter[] methodRewriters = Constants.GetMethodRewriters().ToArray(); foreach (MethodDefinition method in this.GetMethods(module)) { // skip methods with no rewritable method bool hasMethodToRewrite = method.Body.Instructions.Any(op => (op.OpCode == OpCodes.Call || op.OpCode == OpCodes.Callvirt) && methodRewriters.Any(rewriter => rewriter.ShouldRewrite((MethodReference)op.Operand))); if (!hasMethodToRewrite) { continue; } // rewrite method references method.Body.SimplifyMacros(); ILProcessor cil = method.Body.GetILProcessor(); Instruction[] instructions = cil.Body.Instructions.ToArray(); foreach (Instruction op in instructions) { if (op.OpCode == OpCodes.Call || op.OpCode == OpCodes.Callvirt) { IMethodRewriter rewriter = methodRewriters.FirstOrDefault(p => p.ShouldRewrite((MethodReference)op.Operand)); if (rewriter != null) { MethodReference methodRef = (MethodReference)op.Operand; this.Monitor.Log($"rewriting method reference {methodRef.DeclaringType.FullName}.{methodRef.Name}", LogLevel.Trace); rewriter.Rewrite(module, cil, op, methodRef, this.AssemblyMap); } } } method.Body.OptimizeMacros(); } }
internal AssemblyRewriter(IMethodRewriter methodRewriter, IModuleFilter moduleFilter) : this(new Configuration(), new List<SetupTarget>(), methodRewriter, moduleFilter) { }
internal AssemblyRewriter(IMethodRewriter methodRewriter, IModuleFilter moduleFilter) : this(new Configuration(), new List <SetupTarget>(), methodRewriter, moduleFilter) { }
internal AssemblyRewriter(IMethodRewriter methodRewriter, IModuleFilter moduleFilter, IEnumerable <IAssemblyPostProcessor> postProcessors) : this(new Configuration(), new CecilAssemblyResolver(), new List <SetupTarget>(), methodRewriter, moduleFilter, postProcessors) { }