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


    一. 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引用

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

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

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

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

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

    1. [HarmonyPatch(typeof(OriginalClass), "OriginalMethod")]
    2. public class MyHarmonyPatch
    3. {
    4. __instance获取类实例,___a获取实例变量
    5. public static bool Prefix(int ___a, string ___c, OriginalClass __instance)
    6. {
    7. // 在这里编写补丁的逻辑
    8. Console.WriteLine("Patched method called!");
    9. Console.WriteLine(___c);
    10. return true; // 返回false将阻止原方法执行
    11. }
    12. public static bool Postfix(string ___c)
    13. {
    14. // 在这里编写补丁的逻辑
    15. Console.WriteLine("Patched method called!");
    16. Console.WriteLine(___c);
    17. return true; // 返回false将阻止原方法执行
    18. }
    19. }
    20. public class OriginalClass
    21. {
    22. int a = 10;
    23. int b = 20;
    24. string c = "abc";
    25. public void OriginalMethod()
    26. {
    27. Console.WriteLine("Original method called!");
    28. }
    29. public void OtherMethod()
    30. {
    31. Console.WriteLine("Other Method called!");
    32. }
    33. }

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

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

         

    五. AccessTool

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

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

  • 相关阅读:
    Arrays.asList 和 null 类型
    Fedora安装腾讯会议
    寄快递怎么自动给收件人发短信通知?
    微信小程序:点击按钮出现右侧弹窗
    11.3 读图举例
    如何创建加载项(1)
    网络工具Netwox和Wireshark详解
    通过C语言实现计算机模拟疫情扩散
    消息队列kafka
    MySQL中获取时间的方法
  • 原文地址:https://blog.csdn.net/qq_35829452/article/details/137994918