zoukankan      html  css  js  c++  java
  • C# Hook 方法

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    
    namespace MethodHookSample
    {
        class Program
        {
            static void Main(string[] args)
            {
                Target target = new Target();
                var methodAdd = typeof(Target).GetMethod("Add", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                var methodMinus = typeof(Target).GetMethod("Minus", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                MethodHooker.HookMethod(methodAdd, methodMinus);
                var result = target.Add(5, 4);
                Console.Write("5 + 4 = " + result);
                Console.Read();
            }
        }
    
        public class Target
        {
            [MethodImpl(MethodImplOptions.NoInlining)]
            public int Add(int a, int b)
            {
                return a + b;
            }
    
            [MethodImpl(MethodImplOptions.NoInlining)]
            public int Minus(int a, int b)
            {
                return a - b;
            }
        }
    
        public class MethodHooker
        {
            public static void HookMethod(MethodInfo sourceMethod, MethodInfo destinationMethod)
            {
                RuntimeHelpers.PrepareMethod(sourceMethod.MethodHandle);
                RuntimeHelpers.PrepareMethod(destinationMethod.MethodHandle);
    
                if (sourceMethod.IsVirtual)
                {
                    HookVirtualMethod(sourceMethod, destinationMethod);
                    return;
                }
    
                unsafe
                {
                    if (IntPtr.Size == 4)
                    {
                        int* inj = (int*)destinationMethod.MethodHandle.Value.ToPointer() + 2;
                        int* tar = (int*)sourceMethod.MethodHandle.Value.ToPointer() + 2;
    #if DEBUG
                        Console.WriteLine("
    Version x86 Debug
    ");
    
                        byte* injInst = (byte*)*inj;
                        byte* tarInst = (byte*)*tar;
    
                        int* injSrc = (int*)(injInst + 1);
                        int* tarSrc = (int*)(tarInst + 1);
    
                        *tarSrc = (((int)injInst + 5) + *injSrc) - ((int)tarInst + 5);
    #else
                        Console.WriteLine("
    Version x86 Release
    ");
                        *tar = *inj;
    #endif
                    }
                    else
                    {
                        long* inj = (long*)destinationMethod.MethodHandle.Value.ToPointer() + 1;
                        long* tar = (long*)sourceMethod.MethodHandle.Value.ToPointer() + 1;
                        Console.WriteLine("
    Version x64 Release
    ");
                        *tar = *inj;
                    }
                }
            }
    
            static void HookVirtualMethod(MethodInfo sourceMethod, MethodInfo destinationMethod)
            {
                unsafe
                {
                    UInt64* methodDesc = (UInt64*)(sourceMethod.MethodHandle.Value.ToPointer());
                    int index = (int)(((*methodDesc) >> 32) & 0xFF);
                    if (IntPtr.Size == 4)
                    {
                        uint* classStart = (uint*)sourceMethod.DeclaringType.TypeHandle.Value.ToPointer();
                        classStart += 10;
                        classStart = (uint*)*classStart;
                        uint* tar = classStart + index;
                        uint* inj = (uint*)destinationMethod.MethodHandle.Value.ToPointer() + 2;
                        *tar = *inj;
                    }
                    else
                    {
                        ulong* classStart = (ulong*)sourceMethod.DeclaringType.TypeHandle.Value.ToPointer();
                        classStart += 8;
                        classStart = (ulong*)*classStart;
                        ulong* tar = classStart + index;
                        ulong* inj = (ulong*)destinationMethod.MethodHandle.Value.ToPointer() + 1;
                        *tar = *inj;
                    }
                }
            }
        }
    }
  • 相关阅读:
    一道网易面试题
    OC的引用计数
    ReplayKit2 采集音视频回调格式分析
    《剑指offer3- 从末尾到头打印链表》
    《剑指offer
    《剑指offer
    ReplayKit2:声音回调时间戳问题
    UILable在Autolayout模式下面自动调节字体大小
    建表手写语句
    oracle创建主键序列和在ibatis中应用
  • 原文地址:https://www.cnblogs.com/nanfei/p/12084481.html
Copyright © 2011-2022 走看看