Exemplo n.º 1
0
        public static void Install()
        {
            if (_applied)
            {
                return;
            }

            try
            {
                var refreshDet = new Detour(AccessTools.Method(AccessTools.Inner(typeof(ILHook), "Context"), "Refresh"),
                                            AccessTools.Method(typeof(StackTraceFixes), nameof(OnILChainRefresh)));
                _origRefresh = refreshDet.GenerateTrampoline <Action <object> >();

                var getMethodDet = new Detour(AccessTools.Method(typeof(StackFrame), nameof(StackFrame.GetMethod)),
                                              AccessTools.Method(typeof(StackTraceFixes), nameof(GetMethodFix)));
                _origGetMethod = getMethodDet.GenerateTrampoline <Func <StackFrame, MethodBase> >();

                var nat = new NativeDetour(AccessTools.Method(typeof(Assembly), nameof(Assembly.GetExecutingAssembly)),
                                           AccessTools.Method(typeof(StackTraceFixes), nameof(GetAssemblyFix)));
                _realGetAss = nat.GenerateTrampoline <Func <Assembly> >();
            }
            catch (Exception e)
            {
                Logger.LogText(Logger.LogChannel.Error, $"Failed to apply stack trace fix: ({e.GetType().FullName}) {e.Message}");
            }
            _applied = true;
        }
Exemplo n.º 2
0
        public static void Install()
        {
            if (_applied)
            {
                return;
            }

            var refreshDet = new Detour(AccessTools.Method(AccessTools.Inner(typeof(ILHook), "Context"), "Refresh"),
                                        AccessTools.Method(typeof(StackTraceFixes), nameof(OnILChainRefresh)));

            _origRefresh = refreshDet.GenerateTrampoline <Action <object> >();

            var getMethodDet = new Detour(AccessTools.Method(typeof(StackFrame), nameof(StackFrame.GetMethod)),
                                          AccessTools.Method(typeof(StackTraceFixes), nameof(GetMethodFix)));

            _origGetMethod = getMethodDet.GenerateTrampoline <Func <StackFrame, MethodBase> >();

            var nat = new NativeDetour(AccessTools.Method(typeof(Assembly), nameof(Assembly.GetExecutingAssembly)),
                                       AccessTools.Method(typeof(StackTraceFixes), nameof(GetAssemblyFix)));

            _realGetAss = nat.GenerateTrampoline <Func <Assembly> >();

            _applied = true;
        }
Exemplo n.º 3
0
        public static void InstallDispatchHandler(MethodBase method)
        {
            var method_token = MethodToken(method);

            if (_DispatchHandlers.Contains(method_token))
            {
                _Logger.Debug($"Not installing dispatch handler for {method.Name} ({method_token}) - it's already installed");
                return;
            }

            var parms = method.GetParameters();

            int ptypes_offs = 1;

            if (method.IsStatic)
            {
                ptypes_offs = 0;
            }

            var ptypes = new Type[parms.Length + ptypes_offs];

            if (!method.IsStatic)
            {
                ptypes[0] = method.DeclaringType;
            }
            for (int i = 0; i < parms.Length; i++)
            {
                ptypes[i + ptypes_offs] = parms[i].ParameterType;
            }

            var method_returns = false;

            if (method is MethodInfo)
            {
                if (((MethodInfo)method).ReturnType != typeof(void))
                {
                    method_returns = true;
                }
            }

            var dm = new DynamicMethod(
                $"DISPATCH HANDLER FOR METHOD TOKEN {method_token}",
                method is MethodInfo ? ((MethodInfo)method).ReturnType : typeof(void),
                ptypes,
                method.Module,
                skipVisibility: true
                );

            var il = dm.GetILGenerator();

            var loc_args = il.DeclareLocal(typeof(object[]));

            loc_args.SetLocalSymInfo("args");

            var loc_target = il.DeclareLocal(typeof(object));

            loc_target.SetLocalSymInfo("target");

            if (method.IsStatic)
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                il.Emit(OpCodes.Ldarg_0);
            }
            il.Emit(OpCodes.Stloc, loc_target);

            int ary_size = ptypes.Length - 1;

            if (method.IsStatic)
            {
                ary_size = ptypes.Length;
            }

            il.Emit(OpCodes.Ldc_I4, ary_size);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, loc_args);

            for (int i = 0; i < ary_size; i++)
            {
                il.Emit(OpCodes.Ldloc, loc_args);
                il.Emit(OpCodes.Ldc_I4, i);
                il.Emit(OpCodes.Ldarg, i + ptypes_offs);
                if (ptypes[i + ptypes_offs].IsValueType)
                {
                    il.Emit(OpCodes.Box, ptypes[i + ptypes_offs]);
                }
                il.Emit(OpCodes.Stelem, typeof(object));
            }

            il.Emit(OpCodes.Ldc_I8, method_token);
            il.Emit(OpCodes.Ldloc, loc_target);
            il.Emit(OpCodes.Ldloc, loc_args);

            il.Emit(OpCodes.Call, _HandleDispatchMethod);

            if (!method_returns)
            {
                il.Emit(OpCodes.Pop);
            }
            if (method_returns && method is MethodInfo && ((MethodInfo)method).ReturnType.IsValueType)
            {
                il.Emit(OpCodes.Unbox_Any, ((MethodInfo)method).ReturnType);
            }
            il.Emit(OpCodes.Ret);

            var detour = new Detour(
                from: method,
                to: dm
                );

            _Detours[method_token]     = detour;
            _Trampolines[method_token] = detour.GenerateTrampoline();
            _DispatchHandlers.Add(method_token);

            _Logger.Debug($"Installed dispatch handler for {method.Name} (token {method_token})");
        }
Exemplo n.º 4
0
        public void TestDetours()
        {
            Console.WriteLine("Detours: none");
            TestObject.TestStep(5, 6, 8);
            Console.WriteLine();

            // Three examples of using Detour.
            // Note that if you need non-layered, low-level hooks, you can use NativeDetour instead.
            // This is also why the variable type is IDetour.
            // System.Linq.Expressions, thanks to leo (HookedMethod) for telling me about how to (ab)use MethodCallExpression!
            IDetour detourTestMethodA = new Detour(
                () => default(TestObject).TestMethod(default(int), default(int)),
                () => TestMethod_A(default(TestObject), default(int), default(int))
                );
            // Method references as delegates.
            IDetour detourTestStaticMethodA = new Detour <Func <int, int, int> >(
                TestObject.TestStaticMethod,
                TestStaticMethod_A
                );
            // MethodBase, old syntax.
            IDetour detourTestVoidMethodA = new Detour(
                typeof(TestObject).GetMethod("TestVoidMethod", BindingFlags.Static | BindingFlags.Public),
                typeof(DetourTest).GetMethod("TestVoidMethod_A", BindingFlags.Static | BindingFlags.Public)
                );

            Console.WriteLine("Detours: A");
            TestObject.TestStep(42, 12, 1);
            Console.WriteLine("Testing trampoline, should invoke orig, TestVoidMethod(2, 3)");
            detourTestVoidMethodA.GenerateTrampoline <Action <int, int> >()(2, 3);
            Console.WriteLine();

            IDetour detourTestMethodB = new Detour(
                () => default(TestObject).TestMethod(default(int), default(int)),
                () => TestMethod_B(default(TestObject), default(int), default(int))
                );
            IDetour detourTestStaticMethodB = new Detour(
                () => TestObject.TestStaticMethod(default(int), default(int)),
                () => TestStaticMethod_B(default(int), default(int))
                );
            IDetour detourTestVoidMethodB = new Detour(
                () => TestObject.TestVoidMethod(default(int), default(int)),
                () => TestVoidMethod_B(default(int), default(int))
                );

            Console.WriteLine("Detours: A + B");
            TestObject.TestStep(120, 8, 2);
            Console.WriteLine("Testing trampoline, should invoke hook A, TestVoidMethod(2, 3)");
            Action <int, int> trampolineTestVoidMethodB = detourTestVoidMethodB.GenerateTrampoline <Action <int, int> >();

            trampolineTestVoidMethodB(2, 3);
            Console.WriteLine();

            detourTestMethodA.Undo();
            detourTestStaticMethodA.Undo();
            detourTestVoidMethodA.Undo();
            Console.WriteLine("Detours: B");
            TestObject.TestStep(120, 8, 2);
            Console.WriteLine("Testing trampoline, should invoke orig, TestVoidMethod(2, 3)");
            trampolineTestVoidMethodB(2, 3);
            Console.WriteLine();

            detourTestMethodB.Undo();
            detourTestStaticMethodB.Undo();
            detourTestVoidMethodB.Undo();
            Console.WriteLine("Detours: none");
            TestObject.TestStep(5, 6, 8);
            Console.WriteLine();
        }