unity版本: 2018.4.6f1
https://github.com/Tencent/InjectFix
學習項目 void87/InjectFixLearn (github.com)
安裝
編譯
- Window下打開源碼包的Source\VSProj\build_for_unity.bat,UNITY_HOME變量的值修改為指向本機unity安裝目錄
- 運行build_for_unity.bat
復制
這里對應的是一個Unity工程目錄
- IFixToolKit拷貝到Unity項目的Assets同級目錄
- Assets/IFix,Assets/Plugins拷貝到Unity項目的Assets下
HelloWorld
HelloWorld(編輯器下體驗iFix)
1. 模擬有bug的項目
原始Calculator(加和乘都是錯的)

namespace IFix.Test { //HelloworldCfg.cs里配置了這個類型 public class Calculator { //修改成正確的邏輯后,打開如下注釋,生成的補丁將修正該函數 //[Patch] public int Add(int a, int b) { return a * b; } public int Sub(int a, int b) { return a / b; } } }
配置類HelloworldCfg

using System.Collections.Generic; using IFix; using System; // 1. 配置類必須打[Configure]標簽 // 2. 必須放Editor目錄 [Configure] public class HelloworldCfg { [IFix] static IEnumerable<Type> hotfix { get { return new List<Type>() { typeof(IFix.Test.Calculator) }; } } }
Helloworld

using UnityEngine; using IFix.Core; using System.IO; using System.Diagnostics; // 跑不同仔細看文檔Doc/example.md public class Helloworld : MonoBehaviour { // check and load patchs void Start () { VirtualMachine.Info = (s) => UnityEngine.Debug.Log(s); //try to load patch for Assembly-CSharp.dll var patch = Resources.Load<TextAsset>("Assembly-CSharp.patch"); if (patch != null) { UnityEngine.Debug.Log("loading Assembly-CSharp.patch ..."); var sw = Stopwatch.StartNew(); PatchManager.Load(new MemoryStream(patch.bytes)); UnityEngine.Debug.Log("patch Assembly-CSharp.patch, using " + sw.ElapsedMilliseconds + " ms"); } test(); } //[IFix.Patch] void test() { var calc = new IFix.Test.Calculator(); //test calc.Add UnityEngine.Debug.Log("10 + 9 = " + calc.Add(10, 9)); //test calc.Sub UnityEngine.Debug.Log("10 - 2 = " + calc.Sub(10, 2)); } }
2. 修復Bug
修改后的Calculator(模擬修bug后,生成文件 Assembly-CSharp.patch.bytes)

namespace IFix.Test { //HelloworldCfg.cs里配置了這個類型 public class Calculator { //修改成正確的邏輯后,打開如下注釋,生成的補丁將修正該函數 [Patch] public int Add(int a, int b) { return a + b; // return a * b; } public int Sub(int a, int b) { return a / b; } } }
修復bug后,點擊生成
3. 回滾到有bug的代碼,模擬發包(包里有bug)
將代碼還原成有bug的代碼

namespace IFix.Test { //HelloworldCfg.cs里配置了這個類型 public class Calculator { //修改成正確的邏輯后,打開如下注釋,生成的補丁將修正該函數 //[Patch] public int Add(int a, int b) { return a * b; } public int Sub(int a, int b) { return a / b; } }
點擊.一個版本的包只需要點一次
將Assembly-CSharp.patch.bytes拷貝到
啟動帶有Assembly-CSharp.patch.bytes補丁的代碼
各種測試
IFix.Patch 測試
IFix.Patch 支持普通方法

// IFix.Patch支持普通方法 [IFix.Patch] public int Add(int a, int b) { return a * b; }
IFix.Patch 不支持泛型方法

// IFix.Patch 不支持泛型方法 [IFix.Patch] public void GenericMethod<T>(T t) { UnityEngine.Debug.Log("GenericMethod<T>: " + t); }
參考
IFix.Patch 支持普通方法中調用泛型方法

// IFix.Patch 支持普通方法 [IFix.Patch] public int Add(int a, int b) { // IFix.Patch 支持普通方法中調用泛型方法 InnerGenericMethod<string>("arg"); return a * b; } public void InnerGenericMethod<T>(T t) { UnityEngine.Debug.Log("InnerGenericMethod: " + t); }
參考
IFix.Patch 不支持字段

// IFix.Patch 不支持字段 [IFix.Patch] public string TestField = "TestField";
IFix.Patch 支持普通協程

// IFix.Patch 支持普通協程 [IFix.Patch] public IEnumerator PatchEnumerator() { yield return new WaitForSeconds(1); UnityEngine.Debug.Log("Wait 1 Second"); }
IFix.Patch 不支持構造函數

// IFix.Patch 不支持構造函數 [IFix.Patch] public Calculator() { }
參考
IFix.Patch 支持getter,setter函數

private string testField = "testField"; public string TestProperty { [IFix.Patch] get { return testField; } [IFix.Patch] set { testField = value; } }
參考
IFix.Interpret
IFix.Interpret 支持不帶泛型方法的新憎類

// IFix.Interpret 支持不帶泛型方法的新增類 [IFix.Interpret] public class NewClass { public Action<object> act; public string testField = "TestField"; public NewClass(string cons) { UnityEngine.Debug.Log("NewClass.Constructor"); } }
IFix.Interpret 不支持帶泛型方法的新增類

// IFix.Interpret 不支持帶泛型方法的新增類 [IFix.Interpret] public class PatchClass { public void PatchGenericMethod<T>(T t) { UnityEngine.Debug.Log(t); } }
IFix.Interpret 支持新增普通方法

// IFix.Interpret 支持新增普通方法 [IFix.Interpret] public void PatchMethod() { UnityEngine.Debug.Log("PatchMethod"); }
參考
IFix.Interpret 不支持新增泛型方法

// IFix.Interpret 不支持新增泛型方法 [IFix.Interpret] public void PatchGenericMethod<T>(T t) { UnityEngine.Debug.Log("PatchGenericMethod"); }
IFix.Interpret 支持新增類繼承新增類

[IFix.Interpret] public class PatchBaseClass { public void BaseMethod() { UnityEngine.Debug.Log("BaseMethod"); } } // IFix.Interpret 支持新增類繼承新增類 [IFix.Interpret] public class PatchChildClass : PatchBaseClass { public void ChildMethod() { UnityEngine.Debug.Log("ChildMethod"); } }
參考
IFix.Interpret 不支持字段

// IFix.Patch 不支持字段 [IFix.Interpret] public string TestField = "TestField";
參考
IFix.Interpret 不支持構造函數

// IFix.Interpret 不支持構造函數 [IFix.Interpret] public Calculator() { }
IFix.Interpret支持協程,但有限制

// 非熱更代碼里用過 IEnumerator private IEnumerator IE_Main() { yield return new WaitForEndOfFrame(); Debug.Log("IE_Main"); } [IFix.Interpret] private IEnumerator IE_Patch() { // 非熱更代碼里用過 IEnumerator, 熱更代碼里可以使用 yield return new WaitForSeconds(1); yield return new WaitForEndOfFrame(); yield return 0; yield return null; Debug.Log("IE_Patch"); yield break; }

[IFix.Interpret] public IEnumerator IE_Patch() { // 非熱更代碼里沒有用過 IEnumerator, 熱更代碼里不可以使用 yield return new WaitForSeconds(1); yield return new WaitForEndOfFrame(); yield return 0; yield return null; Debug.Log("IE_Patch"); yield break; }
參考
IFix.Interpret不支持Struct
參考
IFix.CustomBridge
熱更代碼新增實現非熱更代碼里的接口時,需要在非熱更代碼里增加處理, 熱更代碼目前不支持繼承非熱更代碼里的原生類

using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class Test : MonoBehaviour { [IFix.Patch] void Start() { PatchClassInheritInterface pcii = new PatchClassInheritInterface(); pcii.TestInterfaceMethod(); //PatchClassInheritClass pcic = new PatchClassInheritClass(); //pcic.TestMethod(); } } // 非熱更接口 public interface TestInterface { void TestInterfaceMethod(); } // 熱更新增類能繼承非熱更原生接口 [IFix.Interpret] public class PatchClassInheritInterface : TestInterface { public void TestInterfaceMethod() { UnityEngine.Debug.Log("TestInterfaceMethod"); } } //// 非熱更類 //public class TestClass { // public virtual void TestMethod() { // Debug.Log("TestMethod"); // } //} //// 熱更新增類不能繼承非熱更原生類 //[IFix.Interpret] //public class PatchClassInheritClass : TestClass { // public override void TestMethod() { // Debug.Log("TestMethod"); // } //} // 要在非熱更代碼里提前加上 [IFix.CustomBridge] public static class AdditionalBridge { static List<Type> bridge = new List<Type>() { typeof(TestInterface), // typeof(TestClass) // 目前不支持, 熱更新增類繼承非熱更原生接口 }; }
參考
CustomBridge的新增類只支持interface,不支持class
IL2CPP相關
Some questions about Fix in IL2CPP mode
版本相關
async
Instruction
使用 build_for_unity.bat 生成的 Instruction.cs

/* * Tencent is pleased to support the open source community by making InjectFix available. * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. * InjectFix is licensed under the MIT License, except for the third-party components listed in the file 'LICENSE' which may be subject to their corresponding license terms. * This file is subject to the terms and conditions defined in file 'LICENSE', which is part of this source code package. */ namespace IFix.Core { public enum Code { Newobj, //Pseudo instruction StackSpace, Ldelem_I8, Pop, Ldelem_U4, Constrained, Throw, Ldc_R4, Cpblk, Sizeof, Stind_I8, Not, Cpobj, Unaligned, Ldelem_U1, Ldelem_I1, CallExtern, Ldelem_R4, Conv_Ovf_I2_Un, Sub, Sub_Ovf_Un, Stind_R8, Ldind_U1, Ldsflda, Ble, Localloc, Ldstr, Add, Stelem_R4, Unbox_Any, Conv_U, Initblk, Leave, Stind_I, Conv_I2, Cgt, Stind_I1, Stind_I2, Conv_Ovf_U1, Ckfinite, Ldind_U2, Ldfld, Box, Conv_Ovf_U, Bgt_Un, Bge_Un, Break, Blt, Ldc_I8, Conv_Ovf_U8_Un, Conv_R4, Stelem_Any, Beq, Volatile, Ldind_U4, //Calli, Ldloca, Ldtype, // custom Ldelema, Ldobj, Mkrefany, Newanon, Ldelem_I4, Stobj, Mul, Ldloc, Stind_Ref, Ldelem_R8, Stsfld, Rem_Un, Callvirt, Ldind_I2, Shr, No, Stind_R4, Ldind_I8, Conv_R_Un, Sub_Ovf, Initobj, Ldind_Ref, Refanytype, Stelem_I2, Ldlen, Stelem_I8, Ldind_I1, Ldarg, Conv_Ovf_I, Shl, Ldelem_Any, Stloc, Brfalse, Conv_Ovf_I4, Bge, Endfilter, Stelem_Ref, Conv_U1, Newarr, Ldelem_Ref, Conv_Ovf_I8_Un, Conv_Ovf_U8, Brtrue, Castclass, Conv_U8, Stelem_I, Dup, Conv_Ovf_I2, Readonly, Stelem_R8, Conv_Ovf_U1_Un, Conv_Ovf_I8, Ldind_R4, Clt_Un, Starg, Conv_I4, Add_Ovf, Conv_Ovf_I_Un, Ldtoken, Conv_Ovf_I4_Un, Ldind_R8, Conv_Ovf_U4_Un, Ldc_R8, Ldelem_U2, Div, Conv_I8, Mul_Ovf_Un, Cgt_Un, Unbox, Ldnull, Ldvirtftn, Callvirtvirt, Ble_Un, Conv_Ovf_U2, Endfinally, Div_Un, Bgt, Conv_Ovf_I1, Ldarga, Br, Conv_I1, Ldelem_I2, Arglist, Conv_Ovf_U4, Ceq, And, Stfld, Conv_R8, Stind_I4, Refanyval, Ldelem_I, Tail, Blt_Un, Rethrow, Call, Jmp, Conv_U4, Shr_Un, Stelem_I1, Stelem_I4, Ldsfld, Conv_Ovf_U2_Un, Mul_Ovf, Ldc_I4, Ldind_I, Ldflda, Ret, Nop, Conv_I, Neg, Conv_Ovf_I1_Un, Clt, Conv_U2, Bne_Un, Switch, Isinst, Ldftn, Conv_Ovf_U_Un, Rem, Ldind_I4, Xor, Add_Ovf_Un, Or, } [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct Instruction { /// <summary> /// 指令MAGIC /// </summary> public const ulong INSTRUCTION_FORMAT_MAGIC = 5158825760788742785; /// <summary> /// 當前指令 /// </summary> public Code Code; /// <summary> /// 操作數 /// </summary> public int Operand; } public enum ExceptionHandlerType { Catch = 0, Filter = 1, Finally = 2, Fault = 4 } public sealed class ExceptionHandler { public System.Type CatchType; public int CatchTypeId; public int HandlerEnd; public int HandlerStart; public ExceptionHandlerType HandlerType; public int TryEnd; public int TryStart; } }
反編譯 IFix.exe 后的相關代碼

using System; namespace IFix.Core { // Token: 0x02000002 RID: 2 public enum Code { // Token: 0x04000002 RID: 2 Newobj, // Token: 0x04000003 RID: 3 StackSpace, // Token: 0x04000004 RID: 4 Ldelem_I8, // Token: 0x04000005 RID: 5 Pop, // Token: 0x04000006 RID: 6 Ldelem_U4, // Token: 0x04000007 RID: 7 Constrained, // Token: 0x04000008 RID: 8 Throw, // Token: 0x04000009 RID: 9 Ldc_R4, // Token: 0x0400000A RID: 10 Cpblk, // Token: 0x0400000B RID: 11 Sizeof, // Token: 0x0400000C RID: 12 Stind_I8, // Token: 0x0400000D RID: 13 Not, // Token: 0x0400000E RID: 14 Cpobj, // Token: 0x0400000F RID: 15 Unaligned, // Token: 0x04000010 RID: 16 Ldelem_U1, // Token: 0x04000011 RID: 17 Ldelem_I1, // Token: 0x04000012 RID: 18 CallExtern, // Token: 0x04000013 RID: 19 Ldelem_R4, // Token: 0x04000014 RID: 20 Conv_Ovf_I2_Un, // Token: 0x04000015 RID: 21 Sub, // Token: 0x04000016 RID: 22 Sub_Ovf_Un, // Token: 0x04000017 RID: 23 Stind_R8, // Token: 0x04000018 RID: 24 Ldind_U1, // Token: 0x04000019 RID: 25 Ldsflda, // Token: 0x0400001A RID: 26 Ble, // Token: 0x0400001B RID: 27 Localloc, // Token: 0x0400001C RID: 28 Ldstr, // Token: 0x0400001D RID: 29 Add, // Token: 0x0400001E RID: 30 Stelem_R4, // Token: 0x0400001F RID: 31 Unbox_Any, // Token: 0x04000020 RID: 32 Conv_U, // Token: 0x04000021 RID: 33 Initblk, // Token: 0x04000022 RID: 34 Leave, // Token: 0x04000023 RID: 35 Stind_I, // Token: 0x04000024 RID: 36 Conv_I2, // Token: 0x04000025 RID: 37 Cgt, // Token: 0x04000026 RID: 38 Stind_I1, // Token: 0x04000027 RID: 39 Stind_I2, // Token: 0x04000028 RID: 40 Conv_Ovf_U1, // Token: 0x04000029 RID: 41 Ckfinite, // Token: 0x0400002A RID: 42 Ldind_U2, // Token: 0x0400002B RID: 43 Ldfld, // Token: 0x0400002C RID: 44 Box, // Token: 0x0400002D RID: 45 Conv_Ovf_U, // Token: 0x0400002E RID: 46 Bgt_Un, // Token: 0x0400002F RID: 47 Bge_Un, // Token: 0x04000030 RID: 48 Break, // Token: 0x04000031 RID: 49 Blt, // Token: 0x04000032 RID: 50 Ldc_I8, // Token: 0x04000033 RID: 51 Conv_Ovf_U8_Un, // Token: 0x04000034 RID: 52 Conv_R4, // Token: 0x04000035 RID: 53 Stelem_Any, // Token: 0x04000036 RID: 54 Beq, // Token: 0x04000037 RID: 55 Volatile, // Token: 0x04000038 RID: 56 Ldind_U4, // Token: 0x04000039 RID: 57 Ldloca, // Token: 0x0400003A RID: 58 Ldtype, // Token: 0x0400003B RID: 59 Ldelema, // Token: 0x0400003C RID: 60 Ldobj, // Token: 0x0400003D RID: 61 Mkrefany, // Token: 0x0400003E RID: 62 Newanon, // Token: 0x0400003F RID: 63 Ldelem_I4, // Token: 0x04000040 RID: 64 Stobj, // Token: 0x04000041 RID: 65 Mul, // Token: 0x04000042 RID: 66 Ldloc, // Token: 0x04000043 RID: 67 Stind_Ref, // Token: 0x04000044 RID: 68 Ldelem_R8, // Token: 0x04000045 RID: 69 Stsfld, // Token: 0x04000046 RID: 70 Rem_Un, // Token: 0x04000047 RID: 71 Callvirt, // Token: 0x04000048 RID: 72 Ldind_I2, // Token: 0x04000049 RID: 73 Shr, // Token: 0x0400004A RID: 74 No, // Token: 0x0400004B RID: 75 Stind_R4, // Token: 0x0400004C RID: 76 Ldind_I8, // Token: 0x0400004D RID: 77 Conv_R_Un, // Token: 0x0400004E RID: 78 Sub_Ovf, // Token: 0x0400004F RID: 79 Initobj, // Token: 0x04000050 RID: 80 Ldind_Ref, // Token: 0x04000051 RID: 81 Refanytype, // Token: 0x04000052 RID: 82 Stelem_I2, // Token: 0x04000053 RID: 83 Ldlen, // Token: 0x04000054 RID: 84 Stelem_I8, // Token: 0x04000055 RID: 85 Ldind_I1, // Token: 0x04000056 RID: 86 Ldarg, // Token: 0x04000057 RID: 87 Conv_Ovf_I, // Token: 0x04000058 RID: 88 Shl, // Token: 0x04000059 RID: 89 Ldelem_Any, // Token: 0x0400005A RID: 90 Stloc, // Token: 0x0400005B RID: 91 Brfalse, // Token: 0x0400005C RID: 92 Conv_Ovf_I4, // Token: 0x0400005D RID: 93 Bge, // Token: 0x0400005E RID: 94 Endfilter, // Token: 0x0400005F RID: 95 Stelem_Ref, // Token: 0x04000060 RID: 96 Conv_U1, // Token: 0x04000061 RID: 97 Newarr, // Token: 0x04000062 RID: 98 Ldelem_Ref, // Token: 0x04000063 RID: 99 Conv_Ovf_I8_Un, // Token: 0x04000064 RID: 100 Conv_Ovf_U8, // Token: 0x04000065 RID: 101 Brtrue, // Token: 0x04000066 RID: 102 Castclass, // Token: 0x04000067 RID: 103 Conv_U8, // Token: 0x04000068 RID: 104 Stelem_I, // Token: 0x04000069 RID: 105 Dup, // Token: 0x0400006A RID: 106 Conv_Ovf_I2, // Token: 0x0400006B RID: 107 Readonly, // Token: 0x0400006C RID: 108 Stelem_R8, // Token: 0x0400006D RID: 109 Conv_Ovf_U1_Un, // Token: 0x0400006E RID: 110 Conv_Ovf_I8, // Token: 0x0400006F RID: 111 Ldind_R4, // Token: 0x04000070 RID: 112 Clt_Un, // Token: 0x04000071 RID: 113 Starg, // Token: 0x04000072 RID: 114 Conv_I4, // Token: 0x04000073 RID: 115 Add_Ovf, // Token: 0x04000074 RID: 116 Conv_Ovf_I_Un, // Token: 0x04000075 RID: 117 Ldtoken, // Token: 0x04000076 RID: 118 Conv_Ovf_I4_Un, // Token: 0x04000077 RID: 119 Ldind_R8, // Token: 0x04000078 RID: 120 Conv_Ovf_U4_Un, // Token: 0x04000079 RID: 121 Ldc_R8, // Token: 0x0400007A RID: 122 Ldelem_U2, // Token: 0x0400007B RID: 123 Div, // Token: 0x0400007C RID: 124 Conv_I8, // Token: 0x0400007D RID: 125 Mul_Ovf_Un, // Token: 0x0400007E RID: 126 Cgt_Un, // Token: 0x0400007F RID: 127 Unbox, // Token: 0x04000080 RID: 128 Ldnull, // Token: 0x04000081 RID: 129 Ldvirtftn, // Token: 0x04000082 RID: 130 Callvirtvirt, // Token: 0x04000083 RID: 131 Ble_Un, // Token: 0x04000084 RID: 132 Conv_Ovf_U2, // Token: 0x04000085 RID: 133 Endfinally, // Token: 0x04000086 RID: 134 Div_Un, // Token: 0x04000087 RID: 135 Bgt, // Token: 0x04000088 RID: 136 Conv_Ovf_I1, // Token: 0x04000089 RID: 137 Ldarga, // Token: 0x0400008A RID: 138 Br, // Token: 0x0400008B RID: 139 Conv_I1, // Token: 0x0400008C RID: 140 Ldelem_I2, // Token: 0x0400008D RID: 141 Arglist, // Token: 0x0400008E RID: 142 Conv_Ovf_U4, // Token: 0x0400008F RID: 143 Ceq, // Token: 0x04000090 RID: 144 And, // Token: 0x04000091 RID: 145 Stfld, // Token: 0x04000092 RID: 146 Conv_R8, // Token: 0x04000093 RID: 147 Stind_I4, // Token: 0x04000094 RID: 148 Refanyval, // Token: 0x04000095 RID: 149 Ldelem_I, // Token: 0x04000096 RID: 150 Tail, // Token: 0x04000097 RID: 151 Blt_Un, // Token: 0x04000098 RID: 152 Rethrow, // Token: 0x04000099 RID: 153 Call, // Token: 0x0400009A RID: 154 Jmp, // Token: 0x0400009B RID: 155 Conv_U4, // Token: 0x0400009C RID: 156 Shr_Un, // Token: 0x0400009D RID: 157 Stelem_I1, // Token: 0x0400009E RID: 158 Stelem_I4, // Token: 0x0400009F RID: 159 Ldsfld, // Token: 0x040000A0 RID: 160 Conv_Ovf_U2_Un, // Token: 0x040000A1 RID: 161 Mul_Ovf, // Token: 0x040000A2 RID: 162 Ldc_I4, // Token: 0x040000A3 RID: 163 Ldind_I, // Token: 0x040000A4 RID: 164 Ldflda, // Token: 0x040000A5 RID: 165 Ret, // Token: 0x040000A6 RID: 166 Nop, // Token: 0x040000A7 RID: 167 Conv_I, // Token: 0x040000A8 RID: 168 Neg, // Token: 0x040000A9 RID: 169 Conv_Ovf_I1_Un, // Token: 0x040000AA RID: 170 Clt, // Token: 0x040000AB RID: 171 Conv_U2, // Token: 0x040000AC RID: 172 Bne_Un, // Token: 0x040000AD RID: 173 Switch, // Token: 0x040000AE RID: 174 Isinst, // Token: 0x040000AF RID: 175 Ldftn, // Token: 0x040000B0 RID: 176 Conv_Ovf_U_Un, // Token: 0x040000B1 RID: 177 Rem, // Token: 0x040000B2 RID: 178 Ldind_I4, // Token: 0x040000B3 RID: 179 Xor, // Token: 0x040000B4 RID: 180 Add_Ovf_Un, // Token: 0x040000B5 RID: 181 Or } }

using System; namespace IFix.Core { // Token: 0x02000003 RID: 3 public struct Instruction { // Token: 0x040000B6 RID: 182 public const ulong INSTRUCTION_FORMAT_MAGIC = 5158825760788742785UL; // Token: 0x040000B7 RID: 183 public Code Code; // Token: 0x040000B8 RID: 184 public int Operand; } }

using System; namespace IFix.Core { // Token: 0x02000004 RID: 4 public enum ExceptionHandlerType { // Token: 0x040000BA RID: 186 Catch, // Token: 0x040000BB RID: 187 Filter, // Token: 0x040000BC RID: 188 Finally, // Token: 0x040000BD RID: 189 Fault = 4 } }

using System; namespace IFix.Core { // Token: 0x02000005 RID: 5 public sealed class ExceptionHandler { // Token: 0x06000001 RID: 1 RVA: 0x000020EC File Offset: 0x000002EC public ExceptionHandler() { } // Token: 0x040000BE RID: 190 public Type CatchType; // Token: 0x040000BF RID: 191 public int CatchTypeId; // Token: 0x040000C0 RID: 192 public int HandlerEnd; // Token: 0x040000C1 RID: 193 public int HandlerStart; // Token: 0x040000C2 RID: 194 public ExceptionHandlerType HandlerType; // Token: 0x040000C3 RID: 195 public int TryEnd; // Token: 0x040000C4 RID: 196 public int TryStart; } }
參考
各種Issue
Close
多個 Assembly Definition 的template file 怎么設置?
添加配置文件,添加python構建腳本用於跨平台構建,添加混淆key支持
Warning: read ./Library/ScriptAssemblies/Assembly-CSharp.dll with symbol fail
執行"InjectFix/Fix"后提示please install the ToolKit
修改源碼導出新的dll后,xcode工程導出報錯,像是IL2CPP轉方法報錯了 IFix.Core.EvaluationStackOperation::ToObject
編輯器下除了reimport unity工程,有沒有更好的方法回滾Inject了之后的dll
Unhandled Exception:System.Exception: Utils/<ReadBinaryFileAsync>d__0 is CompilerGenerated
The type or namespace name `IFix' could not be found
Exception: instruction magic not match
【優化IFix報錯日志】使用debug模式運行ifix.exe,報錯日志里包含源碼文件和行信息,方便查問題
求增加一個Inject和Fix時的UI效果!提醒用戶正在Inject或者Fix中!
【實現建議】不用IDMAP,只使用IDTagAttribute。
Error: the new assembly must not be inject, please reimport the project!
當使用 .net4.x async await來進行異步編程時,inject 階段報異常
> 我也碰到了類似的問題,最簡化代碼如下,當注入class A的時候將會報錯
Unity2019.2.15f1版本打包出來會出現未注入的情況
Unity2019.3.0f3 沒有Editor\Data\Mono\bin\gmcs
UnityEditor熱更沒問題,打包到Android后Load報錯
【BugReport】結構體初始化如果不使用new關鍵字,會報錯
虛函數中如果用關鍵詞in修飾struct類型的參數,inject后執行會報錯
Fix 和 inject 時彈出 warnning ,並且在Editor下沒有看到效果
當hotfix的代碼導致游戲崩潰,幾乎無法查找明確的堆棧入口信息或者明確的方法信息
最新版本無法生成IFix.Core.dll和IFix.exe
在編輯器模式下初始化Inject報錯因為我使用了linq配置
子類沒有override父類的函數,打Interpret標簽不會生效
IEnumerator<T>的Current在解釋執行下報錯
[fixbug] CustomBridge 注入跨dll的delegate,InjectFix 時報錯
Unity2019 iOS注入失敗,Unity2018 iOS注入成功
CustomBridge屬性可以做到自動給程序集的所有Delegate和Interface加上Wrapper嗎?
請教 Non-static method requires a target 錯誤
Open
為什么說:InjectFix在對Unity協程,閉包的支持中其實是包含了對新增class的支持?
無法訪問Unity的 Debug.unityLogger.logEnabled 屬性
TargetException: Non-static method requires a target
使用了BurstCompile的類和結構體不能進行注入,否則加載patch之后會報burst的錯誤
2019.3.8再編譯build_for_unity.bat時找不到gmcs目錄
請教下GetTagMethods與GetTagClasses中assembly.CodeBase.IndexOf("ScriptAssemblies") != -1的用意。
//case Code.Stelem_Any: //0.03166702% 泛型中使用?泛型不支持解析,所以不會碰到這指令(我遇到了這個指令沒被實現的異常)
增加方法沒參數的情況會拋異常Exception: can not load field[*]
雜項
對程序集里的所有方法Inject
// 1. 配置類必須打[Configure]標簽 // 2. 必須放Editor目錄 [Configure] public class HelloworldCfg { [IFix] static IEnumerable<Type> hotfix { get { return (from type in Assembly.Load("Assembly-CSharp").GetTypes() select type); } } }
[Patch](補丁修改方法)標簽,Inject前后DLL對比
為每個方法生成一個枚舉ID
2021.6.3 更新
現在已經支持新增字段
相關文章
https://m.ithome.com/html/444969.htm
https://www.zhihu.com/question/345639690/answer/825301379