private static void PatchTest() { var targetPath = @"..\..\..\Patchwork.Tests.Target\bin\debug\Patchwork.Tests.Target.dll";; var dir = Path.GetDirectoryName(targetPath); var fn = Path.GetFileNameWithoutExtension(targetPath); var ext = Path.GetExtension(targetPath); var newFileName = string.Format("{0}.patched{1}", fn, ext); var newTarget = Path.Combine(dir, newFileName); File.Copy(targetPath, newTarget, true); var patcher = new AssemblyPatcher(newTarget, log: Log); var patchPath = typeof(Patchwork.Tests.Patch.TestClass).Assembly.Location; var maker = new ManifestCreator(); var manifest = maker.CreateManifest(patchPath); patcher.PatchManifest(manifest, null); patcher.WriteTo(newTarget); Log.Information("Loading assembly into memory..."); var loaded = Assembly.LoadFrom(newTarget); Log.Information("Invoking method"); var module = loaded.GetModules()[0]; var types = module.FindTypes((typ, o) => typ.Name.Contains("EntryPoint"), null); var foundType = types.Single(); var method = foundType.GetMethod("StandardTests"); try { var ret = method.Invoke(null, null); Log.Information("Result: {@Result}", ret); } catch (TargetInvocationException ex) { throw ex.InnerException; } Console.ReadKey(); }
private static void PatchGame(ILogger log) { log.Information("Creating {0}", Paths.PatchedAssemblyFolder); Directory.CreateDirectory(Paths.PatchedAssemblyFolder); log.Information("Loading original assembly {0}", Paths.OriginalAssembly); var patcher = new AssemblyPatcher(Paths.OriginalAssembly, log); patcher.EmbedHistory = false; patcher.UseBackup = false; log.Information("Patching"); patcher.PatchAssembly(typeof(W2PWMod.ModType).Assembly.Location); log.Information("Saving patched file"); patcher.WriteTo(Paths.PatchedAssembly); }
private static void PatchGame(string version, string copyToFolder, bool runPeVerify) { if (!Directory.Exists(copyToFolder)) { Log.Information("Creating copy to folder."); Directory.CreateDirectory(copyToFolder); } //+ Path-related var copyToPath = Path.Combine(copyToFolder, @"Assembly-CSharp.dll"); var originalDllPath = Path.Combine(RelativePaths.DllSourcesPath, version, "Assembly-CSharp.dll"); //+ Creating patcher var patcher = new AssemblyPatcher(originalDllPath, ImplicitImportSetting.OnlyCompilerGenerated, Log) { EmbedHistory = false }; //+ Patching assemblies patcher.PatchAssembly(typeof (IEModType).Assembly.Location); //add more lines to patch more things //+ End if (runPeVerify) { Console.WriteLine( "Running PEVerify on the assembly to check the IL for errors. Please wait."); Log.Information(patcher.RunPeVerify(ignoreErrors: _ignoreErrors)); } patcher.WriteTo(copyToPath); LogFile.Flush(); Console.WriteLine("Press any key to close."); Console.Read(); }
private static void PatchGame(string version, string copyToFolder, bool runPeVerify) { if (!Directory.Exists(copyToFolder)) { Log.Information("Creating copy to folder."); Directory.CreateDirectory(copyToFolder); } //+ Path-related var copyToPath = Path.Combine(copyToFolder, @"Assembly-CSharp.dll"); var originalDllPath = Path.Combine(RelativePaths.DllSourcesPath, version, "Assembly-CSharp.dll"); //+ Creating patcher var patcher = new AssemblyPatcher(originalDllPath, ImplicitImportSetting.OnlyCompilerGenerated, Log); //+ Patching assemblies patcher.PatchAssembly(typeof (IEModType).Assembly.Location); //add more lines to patch more things //+ End patcher.WriteTo(copyToPath); if (runPeVerify) { Console.WriteLine( "Going to run PEVerify to check the IL for errors. Press ESC to cancel, or any other key to continue."); if (Console.ReadKey().Key != ConsoleKey.Escape) { RunPEVerify(copyToPath); //RunILSpy(copyToPath); //RunILSpy(typeof (IEModType).Assembly.Location); } } }
private void ApplyInstructions(IEnumerable<PatchGroup> patchGroups, ProgressObject po) { //TODO: Use a different progress tracking system and make the entire patching operation more recoverable and fault-tolerant. //TODO: Refactor this method. patchGroups = patchGroups.ToList(); var appInfo = AppInfo; var logger = Logger; var fileProgress = new ProgressObject(); po.Child.Value = fileProgress; var patchProgress = new ProgressObject(); fileProgress.Child.Value = patchProgress; var myAttributesAssembly = typeof (AppInfo).Assembly; var attributesAssemblyName = Path.GetFileName(myAttributesAssembly.Location); var history = new List<XmlFileHistory>(); po.TaskTitle.Value = "Patching Game"; po.TaskText.Value = appInfo.AppName; po.Total.Value = patchGroups.Count(); foreach (var patchGroup in patchGroups) { var patchCount = patchGroup.Instructions.Count; po.TaskTitle.Value = $"Patching {appInfo.AppName}"; var targetFile = patchGroup.TargetPath; po.TaskText.Value = Path.GetFileName(targetFile); //Note that Path.Combine(FILENAME, "..", OTHER_FILENAME) doesn't work on Mono but does work on .NET. var dir = Path.GetDirectoryName(targetFile); var localAssemblyName = Path.Combine(dir, attributesAssemblyName); var copy = true; fileProgress.TaskTitle.Value = "Patching File"; fileProgress.Total.Value = 2 + patchCount; fileProgress.Current.Value++; var backupModified = PatchingHelper.GetBackupForModified(targetFile); var backupOrig = PatchingHelper.GetBackupForOriginal(targetFile); fileProgress.TaskText.Value = "Applying Patch"; if (!PatchingHelper.DoesFileMatchPatchList(backupModified, targetFile, patchGroup.Instructions) || Preferences.AlwaysPatch) { if (File.Exists(localAssemblyName)) { try { var localAssembly = AssemblyCache.Default.ReadAssembly(localAssemblyName); if (localAssembly.GetAssemblyMetadataString() == myAttributesAssembly.GetAssemblyMetadataString()) { copy = false; } } catch (Exception ex) { Logger.Warning(ex, $"Failed to read local attributes assembly so it will be overwritten."); //if reading the assembly failed for any reason, just ignore... } } if (copy) { File.Copy(myAttributesAssembly.Location, localAssemblyName, true); } var patcher = new AssemblyPatcher(targetFile, logger) { EmbedHistory = true }; foreach (var patch in patchGroup.Instructions) { try { patcher.PatchManifest(patch.Patch, patchProgress.ToMonitor()); } catch (PatchException ex) { throw new PatchingProcessException(ex) { AssociatedInstruction = patch, AssociatedPatchGroup = patchGroup, Step = PatchProcessingStep.ApplyingSpecificPatch }; } fileProgress.Current.Value++; } patchProgress.TaskText.Value = ""; patchProgress.TaskTitle.Value = ""; fileProgress.Current.Value++; fileProgress.TaskText.Value = "Writing Assembly"; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { fileProgress.TaskText.Value = "Running PEVerify..."; var targetFolder = Path.GetDirectoryName(targetFile); try { var peOutput = patcher.RunPeVerify(new PEVerifyInput { AssemblyResolutionFolder = targetFolder, IgnoreErrors = AppInfo.IgnorePEVerifyErrors.ToList() }); logger.Information(peOutput.Output); } catch (Exception ex) { logger.Error(ex, "Failed to run PEVerify on the assembly."); } } try { patcher.WriteTo(backupModified); } catch (Exception ex) { throw new PatchingProcessException(ex) { AssociatedInstruction = null, AssociatedPatchGroup = patchGroup, Step = PatchProcessingStep.WritingToFile }; } } else { fileProgress.Current.Value += patchCount; } try { PatchingHelper.SwitchFilesSafely(backupModified, targetFile, backupOrig); } catch (Exception ex) { throw new PatchingProcessException(ex) { AssociatedInstruction = null, AssociatedPatchGroup = patchGroup, Step = PatchProcessingStep.PerformingSwitch }; } AssemblyCache.Default.ClearCache(); po.Current.Value++; } }
private static void PatchGame() { //+ Path-related var copyToPath = Paths.YourNormalManagedFolder + @"\Assembly-CSharp.dll"; var originalDllPath = Path.Combine(Paths.YourDllSourcesPath, "Assembly-CSharp.dll"); //+ Creating patcher var patcher = new AssemblyPatcher(originalDllPath, ImplicitImportSetting.OnlyCompilerGenerated, Serilog.Log.Logger); //+ Patching assemblies patcher.PatchAssembly(typeof (IEModType).Assembly.Location); //add more lines to patch more things //+ End patcher.WriteTo(copyToPath); Console.WriteLine("Going to run PEVerify to check the IL for errors. Press ESC to cancel, or any other key to continue."); if (Console.ReadKey().Key != ConsoleKey.Escape) { RunPEVerify(copyToPath); //RunILSpy(copyToPath); } }