摘要:InjectFix项目是腾讯研发团队用于给Unity项目代码逻辑热修复实现的的解决方案,可用于Unity业务的bug修复,支持Unity全系列,全平台。
InjectFix项目是腾讯研发团队用于给Unity项目代码逻辑热修复实现的的解决方案,可用于Unity业务的bug修复,支持Unity全系列,全平台。
项目本身提供了HelloWorld的Demo案例,按照案例操作即可。
public class Calculator{public int Add(int a, int b){return a * b;}}首先,Calculator使用乘法来实现错误的Add方法,现在我们先改成正确的为return a * b,然后打一个补丁。然后再把代码还原为错误乘法return a * b,对项目进行注入操作。将打的补丁Assembly-CSharp.patch.bytes拷贝到\Assets\IFix\Resources下,重新执行,可以看到已经修复到新逻辑,说明补丁产生了效果。
在进行打补丁调用CodeTranslator.Process方法处理时,会调用getMethodId方法,执行allocMethodId为每个方法分配一个自增的ID,然后通过变量Dictionary> codes映射存储该方法的所有指令。
然后调用CodeTranslatorSerialize序列化成补丁,把方法的指令列表,挨个写入到补丁文件中。
除了方法的指令,还要把方法和方法的ID写入补丁文件。
执行注入操作会对我们原来的代码进行打桩,根据WrappersManagerImpl.IsPatched查看是否有补丁,有补丁的话就跳转运行虚拟机指令。
这里的注入逻辑可以查看CodeTranslator.idAccessInject按照ID的方式注入逻辑:
调用IL处理器ILProcessor的插入方法,来实现打桩的逻辑。通过对比发现,IL的插入代码逻辑和生成的IL指令分别对应。
游戏运行启动时,会调用PatchManager.Load加载补丁文件,解析所有方法的指令列表,针对每个补丁文件会生成一个虚拟机VirtualMachine,维护所有指令。
实例化补丁方法的管理器WrappersManagerImpl,通过读取补丁文件获取所有方法ID,调用CreateWrapper生成补丁方法,根据方法的索引进行赋值
方法被注入之后,会先判断是否有补丁,决定是否执行补丁逻辑。补丁逻辑,例如这里的WrappersManagerImpl.GetPatch(4).__Gen_Wrap_1(this, a, b) 逻辑,最终会执行虚拟机VirtualMachine.Execute方法,其内部就是遍历方法的所有指令,然后按照操作码和数据进行执行
来源:极客码农