C#-使用Harmony库实现DLL文件反射调用

devtools/2024/10/20 1:21:18/

一. Harmony工作原理

     利用C#运行时Runtime的反射机制,动态加载dll中的方法,字段,属性,实现对DLL方法的重写和代码注入。

二. Harmony下载及安装

     1.下载Harmony_lib库lib.harmony.2.3.3.nupkg

霸王•吕布 / CSharpHarmonyLib · GitCodeicon-default.png?t=N7T8https://gitcode.net/qq_35829452/csharpharmonylib     2.csproj添加reference引用

<Reference Include="0Harmony"><HintPath>..\..\Tool\C#\lib.harmony.2.3.3\lib\net48\0Harmony.dll</HintPath>
</Reference>

     3.通过创建Harmony实例,调用PatchAll()方法实现补丁类的加载

#加载已经实现的补丁类,重写原有DLL中方法
var harmonyPatch = new Harmony("patch");
harmonyPatch.PatchAll();

三. Harmony前置插桩,后置插桩

     通过在类实例上添加Harmony注解,实现补丁类,添加Prefix,Postfix实现对调用方法前,调用方法后的重写,返回值true/false决定原DLL方法是否被执行。

[HarmonyPatch(typeof(OriginalClass), "OriginalMethod")]
public class MyHarmonyPatch
{__instance获取类实例,___a获取实例变量public static bool Prefix(int ___a, string ___c, OriginalClass __instance){// 在这里编写补丁的逻辑Console.WriteLine("Patched method called!");Console.WriteLine(___c);return true; // 返回false将阻止原方法执行}public static bool Postfix(string ___c){// 在这里编写补丁的逻辑Console.WriteLine("Patched method called!");Console.WriteLine(___c);return true; // 返回false将阻止原方法执行}
}public class OriginalClass
{int a = 10;int b = 20;string c = "abc";public void OriginalMethod(){Console.WriteLine("Original method called!");}public void OtherMethod(){Console.WriteLine("Other Method called!");}
}

四. Traverse访问私有属性&私有方法

#访问私有属性
OriginalClass originalClass = new OriginalClass();
string value = Traverse.Create(originalClass).Field("a").GetValue<int>() + "a";
Console.WriteLine(value);#访问私有方法Method("12")
OriginalClass originalClass = new OriginalClass();
bool methodExisits = Traverse.Create(originalClass).Method("12").MethodExists();
Console.WriteLine(methodExisits);

     

五. AccessTool

     使用AccessTool对类进行反射,动态调用目标类的方法。

#AccessTool反射调用目标dll方法
MethodInfo method = AccessTools.Method(typeof(OriginalClass), "OtherMethod");
method.Invoke(__instance, new object[0]);#AccessTool反射调用目标dll属性字段
FieldInfo info = AccessTools.Field(typeof(OriginalClass), "b");
Console.WriteLine(info.GetValue(__instance));


http://www.ppmy.cn/devtools/10728.html

相关文章

Window系统mysql数据库定时备份脚本

将下面的内容复制到bat文件里&#xff0c;然后将5个变量进行修改&#xff1a; mysqldumpPath 你本地mysql路径 dbName 需要备份的数据库 dbUser 数据库用户名 dbPwd 数据库密码 outpurDir 备份文件输出路径 echo 取日期、时间变量值 set yy%date:~0,4% set mm%date:~5,2% set …

公钥密码学Public-Key Cryptography

公钥或非对称密码学的发展是整个密码学历史上最伟大的&#xff0c;也许是唯一真正的革命。The development of public-key, or asymmetric, cryptography is the greatest and perhaps the only true revolution in the entire history of cryptography. 公钥算法基于数学函数…

设计模式学习笔记 - 开源实战二(下):从Unix开源开发学习应对大型复杂项目开发

概述 前两骗文章&#xff0c;分别从代码编写、研发管理的角度&#xff0c;探讨了如何应对大型复杂软件开发。在研发管理这一部分&#xff0c;又讲到了比较重要的几点&#xff0c;它们分别是编码规范、单元测试、持续重构和 Code Review。其中&#xff0c;前三点在前面的文章中…

设计模式- 桥接模式(Bridge Pattern)结构|原理|优缺点|场景|示例

​​​​​​​ 设计模式&#xff08;分类&#xff09; 设计模式&#xff08;六大原则&#xff09; 创建型&#xff08;5种&#xff09; 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式 结构型&#xff08;7种&…

【C++学习】STL之空间配置器之一级空间配置器

文章目录 &#x1f4ca;什么是空间配置器✈STL 提供六大组件的了解&#x1f440;为什么需要空间配置器&#x1f44d;SGI-STL空间配置器实现原理&#x1f302;一级空间配置器的实现 &#x1f4ca;什么是空间配置器 空间配置器&#xff0c;顾名思义就是为各个容器高效的管理空间…

MySQL8.0 一主二从

1. 系统环境 cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)192.168.183.137 mysql-master 192.168.183.153 mysql-slave-1 192.168.183.154 mysql-slave-2# 关闭SELINUX sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config seten…

推荐一个在线stable-diffusion-webui,通过文字生成动画视频的网站-Ai白日梦

推荐一个可以通过文字生成动画视频的网站&#xff0c;目前网站处于公测中&#xff0c;应该是免费的。 点击新建作品 使用kimi或者gpt生成一个故事脚本 输入故事正文 新建作品&#xff0c;选择风格 我这里显示了六个风格&#xff0c;可以根据自己需要选一个 选择配音&…

LeetCode in Python 55. Jump Game (跳跃游戏)

跳跃游戏的游戏规则比较简单&#xff0c;若单纯枚举所有的跳法以判断是否能到达最后一个下标需要的时间复杂度为O()&#xff0c;为此&#xff0c;本文采用贪心策略&#xff0c;从最后一个下标开始逆着向前走&#xff0c;若能跳到第一个元素则表明可以完成跳跃游戏&#xff0c;反…