一. 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));