欢迎光临散文网 会员登陆 & 注册

12.Unity-MonoCecil 方法重定向 初探

2023-04-30 13:07 作者:机智的小草yns  | 我要投稿

Cecil是一个用来生成和检查“ECMA CIL”格式的程序和类库的一个类库。用来对IL层的代码注入,达到代码重定向的作用。

通过了解MonoCecil,了解IL码写法,了解IL热更框架的原理

对于Unity方法重定向,还是更加推荐其他开源项目:

比如MonoHook,UnityHook,DotNetHook等等,找一个合适就可以。


使用MonoCecil实现方法重定向

将Test() 重定向为 Test2()


使用监视器的按钮执行Test函数

执行的Test函数的按钮

注入前的输出结果

注入前


注入后执行Test方法, 方法已经重定向到Test2()

注入后


下面展示如何实现

环境需要: Mono.Cecil.dll、Mono.Cecil.Mdb.dll、Mono.Cecil.Pdb.dl

这里直接借用ILRuntime的

XiaoCaoTest类需要放在AssemblyDef的环境中


注入逻辑

在编辑器中执行一次DoInject()

首先获取必要数据:AssemblyDefinitionTypeDefinition


获取完数据->执行注入InjectMethod

1.获取方法1(MethodDefinition)->获取方法1的IL指令

2.在指令前插入新指令: InsertBefore

    输入参数->无参数->自身 ->  OpCodes.Ldarg_0 

    调用方法2 OpCodes.Call , method2

    return中断 -> OpCodes.Ret



其他函数

获取AssemblyDef

dll文件一般放在项目的 Library\ScriptAssemblies中

计算注入后的函数偏移值

必要Using补充


缺点:是在dll文件中注入,当编辑器重新编译时,dll中注入的内容会消失。需要重新注入。

而自动注入的方法也过于麻烦。


自动注入的思路:

使用[InitializeOnLoadMethod]标记配合

CompilationPipeline.assemblyCompilationFinished += CallBack

注册编译完成的回调,执行注入。

但还要注意,一个dll只能注入一次,注入多次,注入的结果会累加在dll中。

所以就需要一个变量来缓存是否已经注入过。可以在目标类加入一个标记用的方法,如果方法存在则说明注入过,不需要注入。

这类自动注入,在其他热更框架上应该都做得很好。










12.Unity-MonoCecil 方法重定向 初探的评论 (共 条)

分享到微博请遵守国家法律