/// <inheritdoc/> public override void Execute(ILProcessorAttribute attribute) { var targetMethod = attribute?.Method ?? Method.Name; var targetMethodDefinition = TargetAssembly.MainModule.GetType(attribute.Type.FullName).GetMethod(targetMethod); var il = targetMethodDefinition.Body.GetILProcessor(); if (!MethodInfo.IsStatic) { CliAssert.Fail("The ILProcessorModule method must be static."); } var parameters = MethodInfo.GetParameters(); if (parameters.Length != 3) { CliAssert.Fail("The ILProcessorModule method must exactly have 3 arguments, of types 'ILProcessor', 'ILProcessor', and 'AssemblyDefinition'."); } var types = new Type[] { typeof(ILProcessor), typeof(MethodDefinition), typeof(AssemblyDefinition) }; for (int i = 0; i < types.Length; i++) { if (parameters[i].ParameterType != types[i]) { CliAssert.Fail($"Expected parameter {i} to be of type {types[i].FullName}, but was actually {parameters[i].ParameterType.FullName}."); } } MethodInfo.Invoke(null, new object[] { il, targetMethodDefinition, TargetAssembly }); }
public ValueTask ExecuteAsync(IConsole _) { _logger.Settings.DebugVerbosity = (int)Verbosity; _sw.Start(); _logger.LogInformation($"UniversalUnityHooks v{Program.Version}"); _logger.LogDebug($"System Version: {Environment.OSVersion}", 3); if (Target == null) { _logger.LogWarning("Target is null, defaulting to '?_Data/Managed/Assembly-CSharp.dll'."); Target = Util.FindAssemblyCSharp(Directory.GetCurrentDirectory()); } _logger.LogDebug($"Input: '{string.Join(",", Files)}'\nTarget: '{Target}'", 3); // TODO: More asserts, especially on input files CliAssert.IsRequired(Target, "Target Assembly (target,t)"); CliAssert.IsFile(Target); CliAssert.HasExtension(Target, ".dll"); _logger.LogDebug("Asserts passed, adding resolver...", 2); if (AddTargetDirectoryResolve) { ResolveDirectories.Add(Target.Directory); } var resolver = Util.CreateAssemblyResolver(ResolveDirectories); if (File.Exists(Target.FullName + ".clean")) { _logger.LogDebug($"IO: '.clean' File exists, overwriting target assembly with clean file...", 4); File.Delete(Target.FullName); File.Copy(Target.FullName + ".clean", Target.FullName, true); } _logger.LogDebug($"IO: Reading assembly from '{Target.FullName}'...", 4); var targetDefinition = AssemblyDefinition.ReadAssembly(Target.FullName, new ReaderParameters { AssemblyResolver = resolver }); var modules = new List <IModule>(); modules.Add(new HookModule()); modules.Add(new AddMethodModule()); modules.Add(new ILProcessorModule()); modules.Add(new Modules.LowLevelModule()); _logger.LogDebug($"{modules.Count} Module(s) loaded.", 2); Files = Util.FlattenDirectory(Files, "*.dll"); foreach (var input in Files) { ReadAndExecute(input, modules, targetDefinition); } _logger.NewLine(); if (!DryRun) { WriteChanges(targetDefinition); } if (CopyToTarget) { CopyInputFiles(); } _logger.LogInformation($"Operation completed. Operation took {_sw.ElapsedMilliseconds}ms."); return(default);
/// <inheritdoc/> public override void Execute(LowLevelModuleAttribute attribute) { var injector = new Injector(ExecutingAssembly, TargetAssembly); if (!MethodInfo.IsStatic) { CliAssert.Fail("The LowLevelModule method must be static."); } var parameters = MethodInfo.GetParameters(); if (parameters.Length != 1 || parameters[0].ParameterType != typeof(Injector)) { CliAssert.Fail("The LowLevelModule method must exactly have one argument, of type 'Injector'."); } MethodInfo.Invoke(null, new object[] { injector }); }