Beispiel #1
0
        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();
        }
Beispiel #2
0
 /// <exception cref="T:PatchworkLauncher.PatchingProcessException">Cannot patch manifest during the patching process</exception>
 public static void TryPatchManifest(this AssemblyPatcher patcher, PatchInstruction patch, PatchGroup patchGroup, ProgressObject patchProgress)
 {
     try
     {
         patcher.PatchManifest(patch.Patch, patchProgress.ToMonitor());
     }
     catch (PatchException patchException)
     {
         throw new PatchingProcessException(patchException)
               {
                   AssociatedInstruction = patch,
                   AssociatedPatchGroup  = patchGroup,
                   Step = PatchProcessingStep.ApplyingSpecificPatch
               };
     }
 }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        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++;
            }
        }
Beispiel #5
0
		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++;
			}
		}