一文带解读C# 动态拦截覆盖第三方进程中的函数(外挂必备)

一、前言

由于项目需要,最近研究了一下跨进程通讯改写第三方程序中的方法(运行中),把自己程序中的目标方法直接覆盖第三方程序中的方法函数;一直没有头绪,通过搜索引擎找了一大堆解决方案,资料甚是稀少,最后功夫不负有心人,经过两天的研究,终于在github 上找到两个开源的代码,通过两个开源代码结合起来即可实现我的需求。下面进一步来分析实践原理,后面会把源代码地址贴上来;通过该文章分享,你会知道怎样通过注入一个dll模块改写第三方运行的程序中的某个方法,在里面实现自己的业务,这个场景在做外挂程序中特别实用!!!

二、场景

假如有一个第三方应用程序,这时候需要对第三方应用程序进行方法拦截,比如第三方应用程序中的某个操作需要用我们的业务覆盖掉他们的业务,那这种情况下我们有什么好的方案解决呢?我们不可能修改第三方程序的代码,那有什么方案可以解决呢?其实我们还是有办法进行”修改“第三方程序的代码的,怎么”修改“呢,请看下面实践原理,下面带你走入不一样的代码世界!!!!

三、实践

原理简化图:

这里实践我就直接写两个客户端程序来进行代码上的演示

3.1. 实现原理

  • Hook 目标方法:需要改写拦截第三方程序的指定的方法,那就得需要Hook 该方法,经过查找资料在github上找到开源代码DotNetDetour,但是开源作者是从.net framework 4.5开始支持,不支持.net framework 4.0, 我的需求需要运行在老爷机xp 上,故必须要支持4.0 的框架,所有我fork了一份把源代码做了修改支持到了.net framework 4.0 框架,fork 源代码地址:https://github.com/a312586670/DotNetDetour

  • Inject 注入dll到目标进程 写好针对目标进程的方法Hooke dll 模块后需要考虑把该dll模块注入到第三方程序进程中,这样才可以实现完全的hook成功,改写目标进程的方法,我这里使用fastWin32 开源代码,代码地址如下:https://github.com/a312586670/FastWin32

3.2 创建第三方程序Demo

这里为了演示,我自己创建了一个目标客户端程序,主要有如下核心代码方法:

public class ProcessService
{public string GetProcessInfo(){return "这是TargetClient 客户端(第三方程序)";}public ProcessResponse GetProcessInfo(ProcessRequest request){return new ProcessResponse(){Name = "这是TargetClient 客户端(第三方程序)",Version = request.Version};}
}

UI界面交互代码如下:

 /// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void btnInfo_Click(object sender, RoutedEventArgs e){var service = new ProcessService();this.txtInfo.Text = service.GetProcessInfo();}private void btnComplateInfo_Click(object sender, RoutedEventArgs e){var service = new ProcessService();var response = service.GetProcessInfo(new ProcessRequest() { Version = "v-Demo 1.0 版本" });this.txtInfo.Text = response.Name + response.Version;}}

上面代码中有两个按钮事件,分别调用了ProcessService 的两个方法,我们先来运行目标客户端Demo程序,分别点击两个按钮运行结果如下:

3.3 创建核心Hook类库

好了,上面我们的目标第三方Demo程序已经写好了,接下来我们需要写一个核心的Jlion.Process.HookCore类库 改写目标的ProcessService 的两个方法。我这里建了一个Jlion.Process.HookCore类库,通过nuget包引用我fork 后的DotNetDetour 类库,如下图:应用成功后我们建立核心的hook 方法,代码如下:

  public class ProcessHookService : IMethodHook{[HookMethod("Jlion.Process.Target.Client.ProcessService", null, null)]public string GetProcessInfo(){TextHelper.LogInfo($"这是Jlion.Process.HookCore.HookService dll. 改写TargetClient 客户端 的GetProcessInfo 方法后得到的结果");return "这是Jlion.Process.HookCore.HookService dll. 改写TargetClient 客户端 的GetProcessInfo 方法后得到的结果";}[OriginalMethod]public string GetProcessInfo_Original(){return null;}[HookMethod("Jlion.Process.Target.Client.ProcessService", null, null)]public object GetProcessInfo([RememberType("Jlion.Process.Target.Client.Model.ProcessRequest", false)] object request){var json = JsonConvert.SerializeObject(request);TextHelper.LogInfo($"json:{json}");var name = "这是Jlion.Process.HookCore.HookService dll. 改写TargetClient 客户端的GetProcessInfo(obj)后得到的结果";return new ProcessResponse(){Name = name,Version = "改写的dll 版本"};}[OriginalMethod]public object GetProcessInfo_Original([RememberType("Jlion.Process.Target.Client.Model.ProcessRequest", false)] object request){return null;}}

我这里就不详细的写DotNetDetour 的使用,需要知道它的使用可以访问 https://github.com/a312586670/DotNetDetour 查看具体的文档

核心的Jlion.Process.HookCore hook 类库 也已经创建完了,接下来还需要创建一个初始化Hook的服务类(特别重要),并且还必须是静态方法,代码如下:

 public class HookService{/// <summary>/// Hook 初始化/// </summary>/// <param name="msg"></param>/// <returns></returns>public static int Start(string msg){try{TextHelper.LogInfo("开始"+msg);MethodHook.Install();}catch{return -1;}return 1;}}

到这一步基本上Jlion.Process.HookCore Hook 核心的类库已经创建完了

3.4 模块注入客户端程序

创建客户端后需要引用FastWin32类库,如下图:

客户端注入Dll核心代码如下:

public class InjectService
{//注入的核心dll 路径public static string path = AppDomain.CurrentDomain.BaseDirectory+ "Jlion.Process.HookCore.dll";/// <summary>/// 进程id/// </summary>public static uint pid = 0;/// <summary>/// 启动/// </summary>public static void Start(){Inject();}#region 私有方法private static void Inject(){try{Injector.InjectManaged(pid, path, "Jlion.Process.HookCore.HookService", "Start", "ss", out int returnValue);}catch (Exception ex){}}#endregion}

代码中核心的代码是Injector.InjectManaged(),该方法有如下两个重构方法:

参数说明:

  • processId:目标进程的进程id ->pid

  • assemblyPath:核心Hook 注入的dll 绝对路径

  • typeName:Hook 初始化方法的命名空间,一般注入一个模块dll后需要执行的入口初始化方法,这里是Hook 核心dll 中的HookService.Start 方法的命名空间(Jlion.Process.HookCore.HookService)

  • methodName : 注入后执行的方法名称

  • argument : 方法所需要的参数

  • returnValue:返回注入后运行的方法返回值

客户端UI 核心代码如下:
/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void btnInject_Click(object sender, RoutedEventArgs e){InjectService.pid = Convert.ToUInt32(txbPid.Text.Trim());InjectService.Start();}}

这里核心的注入Client Demo 也写完了,我们把注入的客户端也运行起来,输入目标的进程pid(也可以程序中查找目标进程Id),运行后再来执行上面创建的第三方程序的两个按钮,结果如下:通过编写客户端程序点击注入dll后,再点击第三方程序的两个按钮事件,结果如下:可以看到点击后,运行的结果已经被动态注入的Jlion.Process.HookCore.dll改写了,不过上面的代码也可以改写后同时还运行原有目标的方法就是通过调用'_Original'后缀结尾的方法,方法体返回null即可。

四、总结

通过DotNetDetour 框架可以编写对目标进程的方法进行Hook 重写,使用新的方法覆盖第三方进程的方法,也可以继续执行第三方的方法。通过FastWin32调用Win32 API 把开发的dll模块注入到第三方进程中,同时注入后执行初始化方法,可以进行原有的Hook方法进行覆盖。到这里是不是感觉很神奇,它可以在以下场景中使用:

  • 想必大家想到的就是外挂程序,通过改写目标程序的方法进行外挂处理,写上自己的覆盖业务

  • 灰产地带比较实用

  • 破解第三方收费软件等等用途

感兴趣的朋友可以下载Demo 源代码玩一玩:github 源代码地址:https://github.com/a312586670/processClientDemo

往期精彩回顾



  • 【.net core】电商平台升级之微服务架构应用实战

  • .Net Core微服务架构技术栈的那些事

  • Asp.Net Core 中IdentityServer4 授权中心之应用实战

  • Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式

  • Asp.Net Core 中IdentityServer4 授权流程及刷新Token

  • Asp.Net Core 中IdentityServer4 实战之 Claim详解

  • Asp.Net Core 中IdentityServer4 实战之角色授权详解

  • Asp.Net Core 中间件应用实战中你不知道的那些事

  • Asp.Net Core Filter 深入浅出的那些事-AOP

  • Asp.Net Core EndPoint 终结点路由工作原理解读

  • ASP.NET CORE 内置的IOC解读及使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sql Server之旅——第二站 理解讨厌的表扫描

很久以前我们在写sql的时候&#xff0c;最怕的一件事情就是sql莫名奇妙的超级慢&#xff0c;慢的是几根烟抽完&#xff0c;那个小球还在一直转。。。这个着急也只有当事人才明白&#xff0c;后来听说有个什么“评估执行计划“&#xff0c;后来的后来才明白应该避免表扫描。。。…

Sql Server之旅——第一站 那些给我们带来福利的系统视图

本来想这个系列写点什么好呢&#xff0c;后来想想大家作为程序员&#xff0c;用的最多的莫过于数据库了&#xff0c;但是事实上很多像我这样工作在一线的码农&#xff0c;对sql 都一知半解&#xff0c;别谈优化和对数据库底层的认识了&#xff0c;我也是这样。。。一&#xff1…

[C++11]继承构造函数

C11中提供的继承构造函数可以让派生类直接使用基类的构造函数&#xff0c;而无需自己再写构造函数&#xff0c;尤其是在基类有很多构造函数的情况下&#xff0c;可以极大地简化派生类构造函数的编写。 先来看没有继承构造函数之前的处理方式: 代码如下: #include <iostrea…

.NET 程序员的 Playground :LINQPad

如果想执行一个简单的 C# 语句并获得运行结果&#xff0c;通常我们需要做几个步骤才能达成&#xff1a;打开 Visual Studio 并新建一个控制台项目。在 Program.cs 中编写代码并保存。点击运行按钮或者 F5 运行程序并查看结果。通常来说这并不会产生问题。但如果你和笔者一样为 …

JAVA 点菜系统数据库课程设计

点菜系统数据库课程设计 效果图 数据库建表 CREATE TABLE OrderDish (orderid int not null,money int,primary key(orderid) );CREATE TABLE Dish (id varchar(20) not null,name nchar(10),price int,type nchar(10),primary key(id) ); insert into Dish values(zhushi0,水…

[C++11]委托构造函数

委托构造函数允许使用同一个类中的一个构造函数调用其他的构造函数&#xff0c;从而简化相关变量的初始化。 注意点: 1.这种链式的构造函数调用不能形成一个闭环(死循环)&#xff0c;否则会在运行期抛异常。 2.如果要进行多层构造函数的链式调用&#xff0c;建议将构造函数的…

基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目

首先&#xff0c;默认咱们已经有了.net core 3.1的开发环境&#xff0c;如果你没有&#xff0c;快去下载... https://dotnet.microsoft.com/download由于项目是基于abp vNext开发的&#xff0c;所以开发之前建议去撸一遍abp官方文档&#xff0c;https://docs.abp.io/en/abp/lat…

[C++11]统一的数据初始化方式 - 初始化列表

关于C中的变量&#xff0c;数组&#xff0c;对象等都有不同的初始化方法&#xff0c;在这些繁琐的初始化方法中没有任何一种方式适用于所有的情况。为了统一初始化方式&#xff0c;并且让初始化行为具有确定的效果&#xff0c;在C11中提出了列表初始化的概念。 代码如下: #in…

Sql Server之旅——第三站 解惑那些背了多年聚集索引的人

说到聚集索引&#xff0c;我想每个码农都明白&#xff0c;但是也有很多像我这样的伪程序员&#xff0c;只能用死记硬背来解决这个问题&#xff0c;什么表中只能建一个聚集索引&#xff0c;然后又扯到了目录查找来帮助读者记忆。。。。问题就在这里&#xff0c;我们不是学文科&a…

懂「互联网语」的程序员,是个狠人。

借用一下时下很火的「互联网语」做程序员的乐趣是只有进场的人才能获得的红利与程序员相处绝对是令人WOW的用户体验但是别真信那些个程序员说的话哪怕有无数江湖传言为他背书不然你良久建立的心智模型会在瞬间就崩塌毕竟头部程序员和腰腿部程序员之间的壁垒打通不了也许你暂时还…

c语言oj合法标识符,YTUOJ-C语言合法标识符

Description输入一个字符串&#xff0c;判断其是否是C的合法标识符。Input输入数据包含多个测试实例&#xff0c;数据的第一行是一个整数n,表示测试实例的个数&#xff0c;然后是n行输入数据&#xff0c;每行是一个长度不超过50的字符串。Output对于每组输入数据&#xff0c;输…

[C++11]initializer_lisr模板类的使用

代码如下: #include <iostream> using namespace std;void func(initializer_list<int> ls) {auto it ls.begin();for (; it ! ls.end(); it){cout << *it << " ";}cout << endl; }int main() {func({ 1,2,5,12,23 });return 0; }测…

linux tcp 创建,Linux下tcp服务器创建的步骤

创建一个socket&#xff0c;使用函数socket()socket(套接字)实质上提供了进程通信的端点&#xff0c;进程通信之前&#xff0c;双方首先必须建立各自的一个端点&#xff0c;否则没有办法通信。通过socket将IP地址和端口绑定之后&#xff0c;客户端就可以和服务器通信了#include…

基于 abp vNext 和 .NET Core 开发博客项目 - 数据访问和代码优先

上一篇文章完善了项目中的代码&#xff0c;接入了Swagger。本篇主要使用Entity Framework Core完成对数据库的访问&#xff0c;以及使用Code-First的方式进行数据迁移&#xff0c;自动创建表结构。数据访问在.EntityFrameworkCore项目中添加我们的数据访问上下文对象MeowvBlogD…

[C++11]使用using和typedef给模板定义别名

using语法和typedef一样&#xff0c;并不会创建出新的类型&#xff0c;它们只是给某些类型定义了新的别名。using相较于typedef的优势在于定义函数指针别名时看起来更加直观&#xff0c;并且可以给模板定义别名。 使用typedef给模板定义别名: 无法直接使用typedef给模板定义别…

Azure Show|第一期 开播啦!嘉宾梁迪李卓恒李佳芮

欢迎来到Azure Show!Azure ShowAzure Show 是由微软最有价值专家、微软技术社区区域总监卢建晖和微软开发者关系PM朱兴亮共同发起的一个关于微软Azure、开源技术、还有技术社区相关的线上节目。每期节目由MVP面对面、开源故事、从零开始以及Azure101组成&#xff0c;邀请微软技…

基于 abp vNext 和 .NET Core 开发博客项目 - 完善与美化,Swagger登场

上一篇文章(https://www.cnblogs.com/meowv/p/12896898.html)已经成功将博客项目跑起来了&#xff0c;那么本篇主要是将之前遗留的问题解决&#xff0c;现在的代码看起来可能还是比较混乱&#xff0c;有大量与之无关的代码存在里面&#xff0c;对于强迫症患者来说真的是零容忍。…

[C++11]基于范围的for循环

C11提供了一种新型的for循环形式 - 基于范围的for循环 语法: for (declaration : expression) {//循环体 }在上面的语法格式中&#xff0c;declaration表示遍历声明&#xff0c;在遍历过程中&#xff0c;当前被遍历到的元素会被存储到声明的变量中&#xff0c;expression是要…

c语言画笔的使用方法,新手必看:Photoshop笔刷画笔工具基本使用教程

本文为Photoshop初学者提供基本的Photoshop笔刷画笔工具的基本使用方法,这可以说是Photoshop最重要的功能。希望初学PS朋友认真学习&#xff0c;有所帮助&#xff01;工具/原料Photoshop CC 2014或者其他较新版本的psPhotoshop笔刷画笔工具介绍&#xff1a;1、画笔工具在哪里呢…

基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来

上一篇文章(https://www.cnblogs.com/meowv/p/12896177.html)已经成功创建了博客项目&#xff0c;但是abp默认给我们引用了许多项目中用不到的组件。本篇文章将给项目进行瘦身&#xff0c;删掉对我们来说暂时用不到的组件。讲解各个模块之间的关系&#xff0c;写一个Hello Worl…