Exemplo n.º 1
0
        public void Import(IFile file, IMod mod)
        {
            if (file.GetType() != typeof(LdstrFile))
            {
                return;
            }

            var module = HookEndpointManager.GenerateCecilModule(mod.Code.GetName());

            var entryDict = (file as LdstrFile).LdstrEntries;

            foreach (var entryPair in entryDict)
            {
                var md = module.FindMethod(entryPair.Key);
                if (md == null)
                {
                    continue;
                }

                var method = MethodBase.GetMethodFromHandle(md.ResolveReflection().MethodHandle);

                var e = entryPair.Value;

                if (!HaveTranslation(e))
                {
                    continue;
                }

                var modification = new ILContext.Manipulator(il =>
                {
                    foreach (var instruction in il.Instrs)
                    {
                        var ins = e.Instructions.FirstOrDefault(i => instruction.MatchLdstr(i.Origin));
                        if (ins == null || string.IsNullOrEmpty(ins.Translation))
                        {
                            continue;
                        }

                        instruction.Operand = ins.Translation;

                        foreach (var label in il.Labels)
                        {
                            if (label.Target.MatchLdstr(ins.Origin))
                            {
                                label.Target = instruction;
                            }
                        }
                    }
                });

                if (!modifications.ContainsKey(method))
                {
                    HookEndpointManager.Modify(method, modification);
                    modifications.Add(method, modification);
                }
            }
        }
Exemplo n.º 2
0
        internal bool RegisterILHook(ILHook _detour, MethodBase from, ILContext.Manipulator manipulator)
        {
            Assembly owner = GetHookOwner();

            if (owner == null)
            {
                return(true); // continue with default detour creation, we just don't track it
            }
            OnILHook?.Invoke(owner, from, manipulator);
            TrackDetour(owner, _detour);
            return(true);
        }
Exemplo n.º 3
0
        protected override void ImportInternal(LdstrFile file, IMod mod, CultureInfo culture)
        {
            Terraria.ModLoader.ContentInstance.Register(Utils.GetModByName(mod.Name));
            var module = mod.Code.ManifestModule;

            var entryDict = file.LdstrEntries;

            foreach (var entryPair in entryDict)
            {
                var method = Utils.FindMethodByID(module, entryPair.Key);
                if (method == null)
                {
                    continue;
                }

                var e = entryPair.Value;

                if (!HaveTranslation(e))
                {
                    continue;
                }

                var modification = new ILContext.Manipulator(il =>
                {
                    foreach (var instruction in il.Instrs)
                    {
                        var ins = e.Instructions.FirstOrDefault(i => instruction.MatchLdstr(i.Origin));
                        if (ins == null || string.IsNullOrEmpty(ins.Translation))
                        {
                            continue;
                        }

                        instruction.Operand = ins.Translation;

                        foreach (var label in il.Labels)
                        {
                            if (label.Target.MatchLdstr(ins.Origin))
                            {
                                label.Target = instruction;
                            }
                        }
                    }
                });

                if (!modifications.ContainsKey(method))
                {
                    HookEndpointManager.Modify(method, modification);
                    modifications.Add(method, modification);
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        ///
        /// The following method is written by max480. Thanks max!
        ///
        /// Utility method to patch "coroutine" kinds of methods with IL.
        /// Those methods' code reside in a compiler-generated method, and IL.Celeste.* do not allow manipulating them directly.
        /// </summary>
        /// <param name="manipulator">Method taking care of the patching</param>
        /// <returns>The IL hook if the actual code was found, null otherwise</returns>
        public static ILHook HookCoroutine(string typeName, string methodName, ILContext.Manipulator manipulator)
        {
            // get the Celeste.exe module definition Everest loaded for us
            ModuleDefinition celeste = Everest.Relinker.SharedRelinkModuleMap["Celeste.Mod.mm"];

            // get the type
            TypeDefinition type = celeste.GetType(typeName);

            if (type == null)
            {
                return(null);
            }

            // the "coroutine" method is actually a nested type tracking the coroutine's state
            // (to make it restart from where it stopped when MoveNext() is called).
            // what we see in ILSpy and what we want to hook is actually the MoveNext() method in this nested type.
            foreach (TypeDefinition nest in type.NestedTypes)
            {
                if (nest.Name.StartsWith("<" + methodName + ">d__"))
                {
                    // check that this nested type contains a MoveNext() method
                    MethodDefinition method = nest.FindMethod("System.Boolean MoveNext()");
                    if (method == null)
                    {
                        return(null);
                    }

                    // we found it! let's convert it into basic System.Reflection stuff and hook it.
                    //Logger.Log("ExtendedVariantMode/ExtendedVariantsModule", $"Building IL hook for method {method.FullName} in order to mod {typeName}.{methodName}()");
                    Type       reflectionType       = typeof(Player).Assembly.GetType(typeName);
                    Type       reflectionNestedType = reflectionType.GetNestedType(nest.Name, BindingFlags.NonPublic);
                    MethodBase moveNextMethod       = reflectionNestedType.GetMethod("MoveNext", BindingFlags.NonPublic | BindingFlags.Instance);
                    return(new ILHook(moveNextMethod, manipulator));
                }
            }

            return(null);
        }
Exemplo n.º 5
0
        public void TestDynamicHookGen()
        {
            Assert.Equal(42, TestMethod(1, 2));


            On.MonoMod.UnitTest.DynamicHookGenTest.TestMethod += (Func <Func <int, int, int>, int, int, int>)TestMethodHook;
            Assert.Equal(42 + 1, TestMethod(1, 2));


            Func <Func <int, int, int>, int, int, int> hook = (orig, a, b) => {
                return(orig(a, b) + b);
            };

            On.MonoMod.UnitTest.DynamicHookGenTest.TestMethod += hook;
            Assert.Equal(42 + 1 + 2, TestMethod(1, 2));


            ILContext.Manipulator manip = ctx => {
                ILCursor c = new ILCursor(ctx).GotoNext(i => i.MatchRet());
                c.Emit(OpCodes.Ldc_I4_3);
                c.Emit(OpCodes.Add);
            };
            IL.MonoMod.UnitTest.DynamicHookGenTest.TestMethod += manip;
            Assert.Equal(42 + 1 + 2 + 3, TestMethod(1, 2));


            On(typeof(DynamicHookGenTest)).TestMethod -= (Func <Func <int, int, int>, int, int, int>)TestMethodHook;
            Assert.Equal(42 + 2 + 3, TestMethod(1, 2));


            OnOrIL(typeof(DynamicHookGenTest)).TestMethod -= hook;
            Assert.Equal(42 + 3, TestMethod(1, 2));


            OnOrIL(typeof(DynamicHookGenTest)).TestMethod -= manip;
            Assert.Equal(42, TestMethod(1, 2));
        }
Exemplo n.º 6
0
 public void Remove_IL(ILContext.Manipulator hook) => HookEndpointManager.Unmodify(this.method, hook);
Exemplo n.º 7
0
 public void Add_IL(ILContext.Manipulator hook) => HookEndpointManager.Modify(this.method, hook);
Exemplo n.º 8
0
 private static IDetour _NewILHook(MethodBase from, ILContext.Manipulator to) => new ILHook(from, to);