今天在看之前收藏的一个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窗体拖入一个按钮,并把按钮名称改为"测试",如下图:
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,如下图:
二 注入客户端程序编码
2.1 新建名为InjectClient的winfrom窗体程序,.net framework选4.0
2.2 添加Jlion.DotNetDetour包引用,如下图:
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,如下图:
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界面中拖入一个文本标签、文本框和一个按钮,布局及名称如下图:
并编辑代码如下:
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,如下图:
可以看到被篡改前输出还是英文的hello world
3.2 运行注入程序InjectClient.exe
3.3 打开window的任务管理器,找到TargetClient.exe对应的进程Pid,如下图:
可以看到TargetClient.exe对应的进程Pid为27580,你的大概率不是这个
3.4 把TargetClient.exe对应的进程Pid为27580输入到注入程序InjectClient.exe中并点击注入按钮,如下图,可以看到注入成功了
3.5 再来点击TargetClient.exe的测试按钮
可以看到输出中文的世界你好了,证明方法被成功注入。
这就可以干很多坏事了,如把别人的系统登录方法该篡改了(不管是混淆过或者没被混淆过的代码,都有方法拿到,这里就不展开了),你懂的