Example #1
0
        public void TestMethod8()
        {
            var originalClass = typeof(Class8);

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Method8");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(Class8Patch);
            var postfix    = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            patcher.AddPostfix(postfix);
            Assert.IsNotNull(patcher);

            patcher.Patch();

            var result = Class8.Method8("patched");

            Assert.IsTrue(Class8.mainRun);
            Assert.AreEqual(10, result.a);
            Assert.AreEqual(20, result.b);
        }
Example #2
0
        public void TestMethod7()
        {
            var originalClass = typeof(Class7);

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Method7");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(Class7Patch);
            var postfix    = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            patcher.AddPostfix(postfix);

            patcher.Patch();

            Class7.state2 = "before";
            var instance7 = new Class7();
            var result    = instance7.Method7("parameter");

            Console.WriteLine(Class7.state2);

            Assert.AreEqual("parameter", instance7.state1);
            Assert.AreEqual(10, result.a);
            Assert.AreEqual(20, result.b);
        }
Example #3
0
        public void TestMethod10()
        {
            var originalClass = typeof(Class10);

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Method10");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(Class10Patch);
            var postfix    = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            patcher.AddPostfix(postfix);
            patcher.Patch();

            new Class10().Method10();
            Assert.IsTrue(Class10Patch.postfixed);
            Assert.IsTrue(Class10Patch.originalResult);
        }
Example #4
0
        public void TestMethod5()
        {
            var originalClass = typeof(Class5);

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Method5");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(Class5Patch);
            var prefix     = patchClass.GetMethod("Prefix");

            Assert.IsNotNull(prefix);
            var postfix = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            Class5Patch.ResetTest();

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            patcher.AddPrefix(prefix);
            patcher.AddPostfix(postfix);
            patcher.Patch();

            new Class5().Method5("foo");
            Assert.IsTrue(Class5Patch.prefixed, "Prefix was not executed");
            Assert.IsTrue(Class5Patch.postfixed, "Prefix was not executed");
        }
Example #5
0
        public void TestPatchUnpatch()
        {
            var originalClass = typeof(Class9);

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("ToString");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(Class9Patch);
            var prefix     = patchClass.GetMethod("Prefix");

            Assert.IsNotNull(prefix);
            var postfix = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            patcher.AddPrefix(prefix);
            patcher.AddPostfix(postfix);
            patcher.Patch();

            var instanceB = new Harmony("test");

            Assert.IsNotNull(instanceB);

            instanceB.UnpatchAll("test");
        }
Example #6
0
        public void TestMethod0()
        {
            var originalClass = typeof(Class0);

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Method0");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(Class0Patch);
            var postfix    = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            patcher.AddPostfix(postfix);
            patcher.Patch();

            var result = new Class0().Method0();

            Assert.AreEqual("patched", result);
        }
Example #7
0
        static Main()
        {
            var harmony = new Harmony("Garthor.More_Traits");

            harmony.PatchAll();

            // Get all types in the Compatibility namespace
            var types = from x in Assembly.GetExecutingAssembly().GetTypes()
                        where x.IsClass && x.Namespace == "Garthor_More_Traits.Compatibility"
                        select x;

            // Iterate through types tagged with the PatchIfMod attribute
            foreach (var t in types)
            {
                var attr = t.GetCustomAttribute <Compatibility.PatchIfModAttribute>();
                if (attr != null && attr.IsModLoaded())
                {
                    Dictionary <MethodBase, PatchProcessor> patches = new Dictionary <MethodBase, PatchProcessor>();
                    foreach (var method in t.GetMethods())
                    {
                        foreach (var harmonyPatch in method.GetCustomAttributes <HarmonyPatch>())
                        {
                            // First add a PatchProcessor for the method we're targeting to the patches list, if not already present
                            MethodBase mb = harmonyPatch.info.declaringType.GetMethod(harmonyPatch.info.methodName);
                            if (!patches.ContainsKey(mb))
                            {
                                patches.Add(mb, new PatchProcessor(harmony, mb));
                            }
                            PatchProcessor patch = patches[mb];
                            // Next add this method to the prefix, postfix, transpiler, or finalizer lists, as appropriate
                            // (bit repetitive, but it's short and would be a bit convoluted to improve it)
                            if (method.GetCustomAttributes <HarmonyPrefix>().Any())
                            {
                                patch.AddPrefix(new HarmonyMethod(method));
                            }
                            if (method.GetCustomAttributes <HarmonyPostfix>().Any())
                            {
                                patch.AddPostfix(new HarmonyMethod(method));
                            }
                            if (method.GetCustomAttributes <HarmonyTranspiler>().Any())
                            {
                                patch.AddTranspiler(new HarmonyMethod(method));
                            }
                            if (method.GetCustomAttributes <HarmonyFinalizer>().Any())
                            {
                                patch.AddFinalizer(new HarmonyMethod(method));
                            }
                        }
                    }
                    // Apply the patches for this mod
                    foreach (PatchProcessor processor in patches.Values)
                    {
                        processor.Patch();
                    }
                }
            }
        }
Example #8
0
        static HarmonyLoader()
        {
            // load directly embedded patches

            var harmony = new Harmony("harmony-loader-" + Guid.NewGuid().ToString("N"));

            var assembly = Assembly.GetExecutingAssembly();

            foreach (var type in assembly.GetTypes())
            {
                foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    var harmonyMethods = HarmonyMethodExtensions.GetFromMethod(method);
                    if (harmonyMethods is null || !harmonyMethods.Any())
                    {
                        continue;
                    }
                    var merged = new HarmonyMethod()
                    {
                        methodType = MethodType.Normal
                    }.Merge(HarmonyMethod.Merge(harmonyMethods));

                    Logger.LogDebug($"found method: {method} / {merged}");

                    var proc = new PatchProcessor(harmony);

                    proc.AddOriginal(PatchProcessor.GetOriginalMethod(merged) /*(MethodBase) Info.OfMethod<PatchProcessor>("GetOriginalMethod").Invoke(null, new[] {merged})*/);

                    if (method.GetCustomAttributes <HarmonyTranspiler>().Any())
                    {
                        proc.AddTranspiler(method);
                    }
                    if (method.GetCustomAttributes <HarmonyPrefix>().Any())
                    {
                        proc.AddPrefix(method);
                    }
                    if (method.GetCustomAttributes <HarmonyPostfix>().Any())
                    {
                        proc.AddPostfix(method);
                    }
                    if (method.GetCustomAttributes <HarmonyFinalizer>().Any())
                    {
                        proc.AddFinalizer(method);
                    }

                    proc.Patch();
                }
            }

            // load the normal style of patches
            Harmony.CreateAndPatchAll(typeof(AutoLoadManager).Assembly);
        }
Example #9
0
        static HarmonyLoader()
        {
            // load directly embedded patches

            var harmony = new Harmony("harmony-loader-" + Guid.NewGuid().ToString("N"));

            var assembly = Assembly.GetExecutingAssembly();

            foreach (var type in assembly.GetTypes())
            {
                foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    var harmonyMethods = HarmonyMethodExtensions.GetFromMethod(method);
                    if (harmonyMethods is null || !harmonyMethods.Any())
                    {
                        continue;
                    }
                    var merged = new HarmonyMethod()
                    {
                        methodType = MethodType.Normal
                    }.Merge(HarmonyMethod.Merge(harmonyMethods));

                    Logger.LogDebug($"found method: {method} / {merged}");

#if BepInEx
                    var proc = new PatchProcessor(harmony);
                    proc.AddOriginal(PatchProcessor.GetOriginalMethod(merged));
#elif UMM
                    var proc = new PatchProcessor(harmony, merged.GetOriginalMethod());
#endif

                    if (method.GetCustomAttributes <HarmonyTranspiler>().Any())
                    {
                        proc.AddTranspiler(method);
                    }
                    if (method.GetCustomAttributes <HarmonyPrefix>().Any())
                    {
                        proc.AddPrefix(method);
                    }
                    if (method.GetCustomAttributes <HarmonyPostfix>().Any())
                    {
                        proc.AddPostfix(method);
                    }
                    if (method.GetCustomAttributes <HarmonyFinalizer>().Any())
                    {
                        proc.AddFinalizer(method);
                    }

                    proc.Patch();
                }
            }
        }
Example #10
0
        public override void LoadPlugin()
        {
            base.LoadPlugin();
            HarmonyInstance = new Harmony("PlayerIPPatch");
            Logger.Log("Player IP Patch by ShimmyMySherbet (great job nelson!)");
            Logger.Log("Patching IP Methods...");
            MethodInfo     PatchBase = typeof(SteamGameServerNetworking).GetMethod("GetP2PSessionState");
            PatchProcessor Processor = HarmonyInstance.CreateProcessor(PatchBase);

            Processor.AddPostfix(new HarmonyMethod(typeof(PlayerIPPatch).GetMethod("PostFixObj")));
            Processor.Patch();
            Logger.Log("Patched!");
        }
Example #11
0
        public void TestMethod2()
        {
            var originalClass = typeof(Class2);

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Method2");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(Class2Patch);
            var prefix     = patchClass.GetMethod("Prefix");
            var postfix    = patchClass.GetMethod("Postfix");
            var transpiler = patchClass.GetMethod("Transpiler");

            Assert.IsNotNull(prefix);
            Assert.IsNotNull(postfix);
            Assert.IsNotNull(transpiler);

            Class2Patch.ResetTest();

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            patcher.AddPrefix(prefix);
            patcher.AddPostfix(postfix);
            patcher.AddTranspiler(transpiler);

            patcher.Patch();
            // unsafe
            // {
            //     var patchedCode = *(byte*) originalMethodStartPre;
            //     if (IntPtr.Size == sizeof(long))
            //         Assert.IsTrue(patchedCode == 0x48);
            //     else
            //         Assert.IsTrue(patchedCode == 0x68);
            // }

            new Class2().Method2();
            Assert.IsTrue(Class2Patch.prefixed, "Prefix was not executed");
            Assert.IsTrue(Class2Patch.originalExecuted, "Original was not executed");
            Assert.IsTrue(Class2Patch.postfixed, "Postfix was not executed");
        }
Example #12
0
        public void TestGenericStructReturnTypes()
        {
            TestGenericStructReturnTypes_Patch.Prepare();

            var originalClass = typeof(MyList <>).MakeGenericType(typeof(int));

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("GetEnumerator");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(TestGenericStructReturnTypes_Patch);
            var postfix    = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            _ = patcher.AddPostfix(postfix);
            _ = patcher.Patch();

            var list = new MyList <int> {
                list = new List <int>()
                {
                    1, 2, 3
                }
            };

            var enumerator = list.GetEnumerator();
            var result     = new List <int>();

            while (enumerator.MoveNext())
            {
                result.Add(enumerator.Current);
            }

            Assert.AreEqual(3, result.Count);
            Assert.AreEqual(100, result[0]);
            Assert.AreEqual(200, result[1]);
            Assert.AreEqual(300, result[2]);
        }
Example #13
0
        public void TestReverseTranspilerPatching()
        {
            var class0 = new Class0Reverse();

            var result1 = class0.Method("al-gin-Ori", 123);

            Assert.AreEqual("Original123Prolog", result1);

            var originalClass = typeof(Class0Reverse);

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Method");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(Class0ReversePatch);
            var postfix    = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            //Harmony.DEBUG = true;
            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);

            patcher.AddPostfix(new HarmonyMethod(postfix));
            patcher.Patch();

            var standin = patchClass.GetMethod("StringOperation");

            Assert.IsNotNull(standin);

            var reversePatcher = instance.CreateReversePatcher(originalMethod, standin);

            reversePatcher.Patch();

            var result2 = class0.Method("al-gin-Ori", 456);

            Assert.AreEqual("EpilogOriginal", result2);
        }
Example #14
0
        public void Test_InjectingBaseClassField()
        {
            var testInstance = new InjectFieldSubClass();

            testInstance.Method("foo");
            Assert.AreEqual("foo", testInstance.TestValue);

            var originalClass = testInstance.GetType();

            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Method");

            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(InjectFieldSubClass_Patch);
            var postfix    = patchClass.GetMethod("Postfix");

            Assert.IsNotNull(postfix);

            var instance = new Harmony("test");

            Assert.IsNotNull(instance);

            instance.Patch(originalMethod, postfix: new HarmonyMethod(postfix));

            var patcher = new PatchProcessor(instance, originalMethod);

            Assert.IsNotNull(patcher);
            _ = patcher.AddPostfix(postfix);
            Assert.IsNotNull(patcher);

            _ = patcher.Patch();

            testInstance.Method("bar");
            Assert.AreEqual("patched", testInstance.TestValue);
        }
Example #15
0
        public void TestNativePatch()
        {
            // Currently NativeDetours don't work properly on .NET Core (except when running in debug mode)
            // ¯\_(ツ)_/¯
#if NETCOREAPP3_0
            return;
#endif
            var originalClass = typeof(NativeClass);
            Assert.IsNotNull(originalClass);
            var originalMethod = originalClass.GetMethod("Rand");
            Assert.IsNotNull(originalMethod);

            var patchClass = typeof(NativeClassPatch);
            var prefix     = patchClass.GetMethod("Prefix");
            Assert.IsNotNull(prefix);
            var postfix = patchClass.GetMethod("Postfix");
            Assert.IsNotNull(postfix);
            var transpiler = patchClass.GetMethod("Transpiler");
            Assert.IsNotNull(transpiler);

            var instance = new Harmony("test-native");
            Assert.IsNotNull(instance);

            var patcher = new PatchProcessor(instance, originalMethod);
            Assert.IsNotNull(patcher);
            patcher.AddPrefix(prefix);
            patcher.AddPostfix(postfix);
            patcher.AddTranspiler(transpiler);
            patcher.Patch();

            var result = NativeClass.Rand();
            Assert.AreEqual(-1, result);
            Assert.IsTrue(NativeClassPatch.prefixCalled, "Prefix wasn't run");
            Assert.IsTrue(NativeClassPatch.postfixCalled, "Postfix wasn't run");
            Assert.IsTrue(NativeClassPatch.transpilerCalled, "Transpiler wasn't run");
        }
Example #16
0
 /// <summary>
 ///     Apply a postfix to the original method
 /// </summary>
 /// <param name="action">Postfix to apply</param>
 /// <typeparam name="T">Postfix delegate type</typeparam>
 /// <returns>Current patch processor</returns>
 public PatchComposer Postfix <T>(T action) where T : Delegate
 {
     processor.AddPostfix(GetPatchMethod(action));
     return(this);
 }
Example #17
0
 public ProcessorInfo AddPostfix(HarmonyMethod postfix)
 {
     processor.AddPostfix(postfix);
     return(this);
 }
Example #18
0
        public void AttemptProhibitedPatch(Harmony h)
        {
            testName = "TEST/" +
                       "API/ACL2/" +
                       typeof(HarmonyHelper).Assembly.GetName().Name + " " +
                       typeof(HarmonyHelper).Assembly.GetName().Version;

            PatchProcessor processor       = null;
            MethodInfo     prohibitedPatch = null;

            try
            {
                var        targetName = "CompareTo";
                MethodInfo target     = typeof(Patch).GetMethod(targetName,
                                                                BindingFlags.Instance |
                                                                BindingFlags.Static |
                                                                BindingFlags.Public |
                                                                BindingFlags.NonPublic);
                if (target == null)
                {
                    throw new TestFailed($"Target fn ({targetName}) was not found.");
                }
                processor = h.CreateProcessor(target);
                if (processor == null)
                {
                    UnityEngine.Debug.Log($"[{testName}] INFO - Processor=null. BAD");
                    throw new TestFailed($"Failed to create processor.");
                }

                prohibitedPatch = typeof(ACLPatchDefinitions).GetMethod("ProhibitedPatch",
                                                                        BindingFlags.Instance |
                                                                        BindingFlags.Static |
                                                                        BindingFlags.Public |
                                                                        BindingFlags.NonPublic);
                if (prohibitedPatch == null)
                {
                    throw new TestFailed("Patch fn (ProhibitedPatch) was not found.");
                }

                processor.AddPostfix(prohibitedPatch);
                processor.Patch();
                throw new TestFailed("Installing a prohibited patch did not throw HarmonyModACLException");
            }
            catch (TestFailed ex)
            {
                UnityEngine.Debug.Log($"[{testName}] ERROR : {ex.Message}. BAD");
                throw ex;
            }
            catch (Exception ex)
            {
                if (ex.GetType().Name != "HarmonyModACLException")
                {
                    throw new TestFailed($"Installing a prohibited patch failed but not because of ACL: {ex.Message}");
                }
                UnityEngine.Debug.Log($"[{testName}] INFO - Attempting to install a prohibited patch was blocked ({ex.Message}). OK.");
            }
            finally
            {
                if (processor != null && prohibitedPatch != null)
                {
                    try
                    {
                        processor.Unpatch(prohibitedPatch);
                    }
                    catch (Exception ex)
                    {
                        if (ex.GetType().Name != "HarmonyModACLException")
                        {
                            throw new TestFailed($"Uninstalling a prohibited patch failed but not because of ACL: {ex.Message}");
                        }
                        UnityEngine.Debug.Log($"[{testName}] INFO - Attempting to remove a prohibited patch was blocked ({ex.Message}). OK.");
                    }
                }
                else
                {
                    throw new TestFailed($"Prohibited patch test is broken. processor={processor != null} patch={prohibitedPatch != null}");
                }
            }
        }
Example #19
0
        public bool CompileAndGenerateProcessor(string patchSource)
        {
            Unpatch();

            try
            {
                patchProcessor = ExplorerCore.Harmony.CreateProcessor(TargetMethod);

                // Dynamically compile the patch method

                var codeBuilder = new StringBuilder();

                codeBuilder.AppendLine($"public class DynamicPatch_{DateTime.Now.Ticks}");
                codeBuilder.AppendLine("{");
                codeBuilder.AppendLine(patchSource);
                codeBuilder.AppendLine("}");

                scriptEvaluator.Run(codeBuilder.ToString());

                if (ScriptEvaluator._reportPrinter.ErrorsCount > 0)
                {
                    throw new FormatException($"Unable to compile the generated patch!");
                }

                // TODO: Publicize MCS to avoid this reflection
                // Get the most recent Patch type in the source file
                var typeContainer = ((CompilationSourceFile)fi_sourceFile.GetValue(scriptEvaluator))
                                    .Containers
                                    .Last(it => it.MemberName.Name.StartsWith("DynamicPatch_"));
                // Get the TypeSpec from the TypeDefinition, then get its "MetaInfo" (System.Type)
                var patchClass = ((TypeSpec)pi_Definition.GetValue((Class)typeContainer, null)).GetMetaInfo();

                // Create the harmony patches as defined

                postfix = patchClass.GetMethod("Postfix", ReflectionUtility.FLAGS);
                if (postfix != null)
                {
                    patchProcessor.AddPostfix(new HarmonyMethod(postfix));
                }

                prefix = patchClass.GetMethod("Prefix", ReflectionUtility.FLAGS);
                if (prefix != null)
                {
                    patchProcessor.AddPrefix(new HarmonyMethod(prefix));
                }

                finalizer = patchClass.GetMethod("Finalizer", ReflectionUtility.FLAGS);
                if (finalizer != null)
                {
                    patchProcessor.AddFinalizer(new HarmonyMethod(finalizer));
                }

                transpiler = patchClass.GetMethod("Transpiler", ReflectionUtility.FLAGS);
                if (transpiler != null)
                {
                    patchProcessor.AddTranspiler(new HarmonyMethod(transpiler));
                }

                return(true);
            }
            catch (Exception ex)
            {
                ExplorerCore.LogWarning($"Exception creating patch processor for target method {TargetMethod.FullDescription()}!\r\n{ex}");
                return(false);
            }
        }