C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)

今天在看之前收藏的一个pdf文档(介绍C#外挂的相关知识的),结合网上的东西及个人的理解才有了这篇文章。

参考文章:

【精选】一文带解读C# 动态拦截覆盖第三方进程中的函数(外挂必备)_zls365365的博客-CSDN博客

DotNetDetour - 万能的开源 .NET 代码 Hook 神器

测试环境:

visual studio 2017

.net framework 4.0

测试步骤如下:

一    第三方客户端程序编写(即要被篡改函数的客户端)

1.1  新建名为TargetClient的winform窗体应用程序,.net framework选4.0

1.2 新建类TargetTestClass,并编辑如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TargetClient
{
    public class TargetTestClass
    {
        public string Test()
        {
            return "hello world";
        }
    }
}

其中Test方法就是我们要篡改的方法

1.3  在默认的Form1窗体拖入一个按钮,并把按钮名称改为"测试",如下图:

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第1张图片

1.4  按钮点击方法如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TargetClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string ret=new TargetTestClass().Test();
            MessageBox.Show(ret);
        }
    }
}

1.5  运行并点击"测试"按钮输出英文的hello world,如下图:

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第2张图片

二  注入客户端程序编码

2.1  新建名为InjectClient的winfrom窗体程序,.net framework选4.0

2.2  添加Jlion.DotNetDetour包引用,如下图:

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第3张图片

2.3  添加名为InjectClass的类,并继承IMethodHook接口,用于编辑覆盖被篡改方法的逻辑,如下:

using DotNetDetour;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InjectClient
{
    public class InjectClass:IMethodHook
    {
        //TargetClient.TargetTestClass这个要被篡改方法的TargetTestClass类的全路径(即TargetClient.exe客户端中的类TargetTestClass的全路径,即命名空间+类名)
        //Test为被篡改的方法名,要保持一致
        [HookMethod("TargetClient.TargetTestClass")]
        public string Test()
        {
            return "世界,你好呀";
        }
        //实现一个占位方法,要被覆盖的原方法,命名格式为:被篡改的方法名+_Original
        [OriginalMethod]
        public string Test_Original()
        {
            return null; //这里写什么无所谓,能编译过即可
        }

    }
}

注意:

TargetClient.TargetTestClass这个要被篡改方法的TargetTestClass类的全路径(即TargetClient.exe客户端中的类TargetTestClass的全路径,即命名空间+类名)

Test为被篡改的方法名,要保持一致

Test_Original是要被覆盖的原方法,命名格式为:被篡改的方法名+_Original

2.3  新建方法安装注册类HookService,为注入做准备,并编辑如下:

using DotNetDetour;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InjectClient
{
    public class HookService
    {
        /// 
        /// 必须为静态方法
        /// 
        /// 暂时没用到
        /// 
        public static int Start(string paramValue)
        {
            try
            {
                MethodHook.Install();
            }
            catch
            {
                return -1;
            }
            return 1;
        }
    }
}

其中Start方法的名称根据你的喜好来起,但该方法必须是静态方法。

2.4  方法都准备好了,那就要编写注入的逻辑了,安装注入包FastWin32,如下图:

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第4张图片

2.5  新增注入服务类InjectService,并编辑如下:

using FastWin32.Diagnostics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace InjectClient
{
    public class InjectService
    {
        //注入的核心dll 路径
        public static string path = AppDomain.CurrentDomain.BaseDirectory + "InjectClient.exe";

        /// 
        /// 进程id
        /// 
        public static uint pid = 0;

        /// 
        /// 启动
        /// 
        public static void Start()
        {
            Inject();
        }


        #region 私有方法
        private static void Inject()
        {
            try
            {
                Injector.InjectManaged(pid, path, "InjectClient.HookService", "Start", "测试参数,暂时没用到", out int returnValue);
                MessageBox.Show("注入成功了呀");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion
    }
}

其中InjectClient.HookService这个名称是前面安装注册类HookService的(命名空间+类名)

Start是前面安装注册类HookService的Start方法名称

2.3  在Form1界面中拖入一个文本标签、文本框和一个按钮,布局及名称如下图:

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第5张图片

并编辑代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace InjectClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        /// 
        /// 注入按钮的逻辑
        /// 
        /// 
        /// 
        private void btnInject_Click(object sender, EventArgs e)
        {
            //获取界面输入的进程Id
            InjectService.pid = Convert.ToUInt32(this.txtPid.Text.Trim());
            InjectService.Start();
        }
    }
}

2.4  生成项目备用

三  综合测试

3.1  运行要被篡改的客户端程序TargetClient.exe,如下图:

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第6张图片

可以看到被篡改前输出还是英文的hello world

3.2  运行注入程序InjectClient.exe

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第7张图片

3.3 打开window的任务管理器,找到TargetClient.exe对应的进程Pid,如下图:

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第8张图片

可以看到TargetClient.exe对应的进程Pid为27580,你的大概率不是这个

3.4  把TargetClient.exe对应的进程Pid为27580输入到注入程序InjectClient.exe中并点击注入按钮,如下图,可以看到注入成功了

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第9张图片

3.5  再来点击TargetClient.exe的测试按钮

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)_第10张图片

可以看到输出中文的世界你好了,证明方法被成功注入。

这就可以干很多坏事了,如把别人的系统登录方法该篡改了(不管是混淆过或者没被混淆过的代码,都有方法拿到,这里就不展开了),你懂的

你可能感兴趣的:(C#编程,c#,注入,外挂,篡改,DotNetDetour,FastWin32,动态替换方法)