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("\nVersion x86 Debug\n");

                    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("\nVersion x86 Release\n");
                    *tar = *inj;
#endif
                }
                else
                {
                    long* inj = (long*)destinationMethod.MethodHandle.Value.ToPointer() + 1;
                    long* tar = (long*)sourceMethod.MethodHandle.Value.ToPointer() + 1;
                    Console.WriteLine("\nVersion x64 Release\n");
                    *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;
                }
            }
        }
    }
}
复制代码

 

posted on   空明流光  阅读(2385)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2013-12-23 c# webBrowser控件与js的交互

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示