一文带解读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解讀及使用
總結
以上是生活随笔為你收集整理的一文带解读C# 动态拦截覆盖第三方进程中的函数(外挂必备)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 揭秘!微软 Build 2020 开发者
- 下一篇: Sql Server之旅——第二站 理解