一. Harmony工作原理
利用C#运行时Runtime的反射机制,动态加载dll中的方法,字段,属性,实现对DLL方法的重写和代码注入。
二. Harmony下载及安装
1.下载Harmony_lib库lib.harmony.2.3.3.nupkg
霸王•吕布 / CSharpHarmonyLib · GitCodehttps://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));