public void TestHooks() { Console.WriteLine("Hooks: none"); TestObject.TestStep(5, 6, 8); Console.WriteLine(); IDetour hookTestMethodA = new Hook( typeof(TestObject).GetMethod("TestMethod", BindingFlags.Instance | BindingFlags.Public), typeof(HookTest).GetMethod("TestMethod_A", BindingFlags.Static | BindingFlags.Public) ); IDetour hookTestStaticMethodA = new Hook( typeof(TestObject).GetMethod("TestStaticMethod", BindingFlags.Static | BindingFlags.Public), typeof(HookTest).GetMethod("TestStaticMethod_A", BindingFlags.Static | BindingFlags.Public) ); IDetour hookTestVoidMethodA = new Hook( typeof(TestObject).GetMethod("TestVoidMethod", BindingFlags.Static | BindingFlags.Public), typeof(HookTest).GetMethod("TestVoidMethod_A", BindingFlags.Static | BindingFlags.Public) ); Console.WriteLine("Hooks: A"); TestObject.TestStep(42, 12, 1); Console.WriteLine(); IDetour hookTestMethodB = new Hook( typeof(TestObject).GetMethod("TestMethod", BindingFlags.Instance | BindingFlags.Public), typeof(HookTest).GetMethod("TestMethod_B", BindingFlags.Static | BindingFlags.Public) ); IDetour hookTestStaticMethodB = new Hook( typeof(TestObject).GetMethod("TestStaticMethod", BindingFlags.Static | BindingFlags.Public), new Func <Func <int, int, int>, int, int, int>((orig, a, b) => { return(orig(a, b) + 2); }) ); IDetour hookTestVoidMethodB = new Hook( typeof(TestObject).GetMethod("TestVoidMethod", BindingFlags.Static | BindingFlags.Public), new Action <Action <int, int>, int, int>((orig, a, b) => { Console.WriteLine("Hook B"); TestObject.VoidResult += 2; orig(a, b); }) ); Console.WriteLine("Hooks: A + B"); TestObject.TestStep(42 + 42, 12 + 2, 3); Console.WriteLine(); hookTestMethodA.Undo(); hookTestStaticMethodA.Undo(); hookTestVoidMethodA.Undo(); Console.WriteLine("Hooks: B"); TestObject.TestStep(5 + 42, 6 + 2, 12); Console.WriteLine(); hookTestMethodB.Undo(); hookTestStaticMethodB.Undo(); hookTestVoidMethodB.Undo(); Console.WriteLine("Detours: none"); TestObject.TestStep(5, 6, 8); Console.WriteLine(); }
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, default),
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(); }