static void ParseFields(TypeDef clazz) { foreach (var rid in currentModule.Metadata.GetFieldRidList(clazz.Rid)) { var field = currentModule.ResolveField(rid); if (field == null) { continue; } var fieldName = field.Name.Replace("::", "_").Replace("<", "").Replace(">", "").Replace("k__BackingField", "").Replace(".", "_").Replace("`", "_"); if (fieldName.Equals("auto") || fieldName.Equals("register")) { fieldName += "_"; } var fieldType = Il2CppTypeToCppType(field.FieldType); var fieldOffset = GetFieldOffset(field); currentFile.Write(string.Format("\ttemplate <typename T = {0}>", fieldType)); currentFile.WriteLine(string.Format(" {0}{1}& {2}() {{", (field.IsStatic ? "static " : ""), "T", fieldName)); if (field.IsStatic) { currentFile.WriteLine(string.Format("\t\treturn *({0}*)((uintptr_t)StaticClass()->static_fields + {1});", "T", fieldOffset)); } else { currentFile.WriteLine(string.Format("\t\treturn *({0}*)((uintptr_t)this + {1});", "T", fieldOffset)); } currentFile.WriteLine("\t}"); } }
internal static void FixProxyCall() { var globalTypes = _moduleDefMd?.Types.Where(t => t.Namespace == string.Empty).ToArray(); var decryptor = (globalTypes ?? throw new InvalidOperationException()).Single(t => t.Name.StartsWith("{", StringComparison.Ordinal) && t.Name.EndsWith("}", StringComparison.Ordinal)).Methods.Single(m => !m.IsInstanceConstructor && m.Parameters.Count == 1); foreach (var typeDef in globalTypes) { var cctor = typeDef.FindStaticConstructor(); if (cctor is null || !cctor.Body.Instructions.Any(i => i.OpCode == OpCodes.Call && i.Operand == decryptor)) { continue; } switch (_module) { case not null: { foreach (var fieldInfo in _module.ResolveType(typeDef.MDToken.ToInt32()) .GetFields(BindingFlags.NonPublic | BindingFlags.Static) !) { var proxyFieldToken = fieldInfo.MetadataToken; var proxyFieldDef = _moduleDefMd?.ResolveField((uint)proxyFieldToken - 0x4000000); var realMethod = ((Delegate)fieldInfo.GetValue(null) !).Method; if (Utils.IsDynamicMethod(realMethod)) { var dynamicMethodBodyReader = new DynamicMethodBodyReader(_moduleDefMd, realMethod); dynamicMethodBodyReader.Read(); var instructionList = dynamicMethodBodyReader.GetMethod().Body.Instructions; ReplaceAllOperand(proxyFieldDef, instructionList[instructionList.Count - 2].OpCode, (MemberRef)instructionList[instructionList.Count - 2].Operand); } else { ReplaceAllOperand(proxyFieldDef, realMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, (MemberRef)_moduleDefMd.Import(realMethod)); } } break; } } } }
public static dnlib.DotNet.Emit.Instruction CreateInstr(Instruction instr, MethodDef meth) { switch (instr.Code) { case OpCode.Add: Stack.Pop(); Stack.Pop(); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Add)); case OpCode.Call: Tuple <short, int, bool> tuple = (Tuple <short, int, bool>)instr.Operand; ModuleDefMD str = ModuleDefMD.Load(GetReference(tuple.Item1)); IMethod meh = (IMethod)str.ResolveToken((uint)tuple.Item2); module.Import(meh); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Call, module.Import(meh))); case OpCode.Cgt: Stack.Pop(); Stack.Pop(); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Cgt)); case OpCode.Clt: Stack.Pop(); Stack.Pop(); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Clt)); // case OpCode.Cmp: // return dnlib.DotNet.Emit.Instruction.Create(OpCodes.C); case OpCode.Div: Stack.Pop(); Stack.Pop(); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Div)); case OpCode.Dup: object value = Stack.Pop(); Stack.Push(value); Stack.Push(value); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Dup)); case OpCode.Jf: Stack.Pop(); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ldstr, string.Format("BrFalse|{0}", meth.Body.Instructions[(int)instr.Operand]))); case OpCode.Jmp: return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ldstr, string.Format("Br|{0}", meth.Body.Instructions[(int)instr.Operand]))); case OpCode.Jt: Stack.Pop(); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ldstr, string.Format("BrTrue|{0}", meth.Body.Instructions[(int)instr.Operand]))); case OpCode.Int32: Stack.Push((int)instr.Operand); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ldc_I4, (int)instr.Operand)); case OpCode.Ldarg: //A fix Stack.Push(meth.Parameters[(int)((short)instr.Operand)]); return(dnlib.DotNet.Emit.Instruction.Create(ldarg(Convert.ToInt32(instr.Operand)))); case OpCode.Ldfld: Stack.Pop(); int item2 = ((Tuple <short, int>)instr.Operand).Item2; FieldDef fld = module.ResolveField((uint)item2); Stack.Push(fld.InitialValue); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ldfld, fld)); case OpCode.Ldloc: //A fix Local l = meth.Body.Variables[(short)instr.Operand]; Stack.Push(l); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ldloc, l)); case OpCode.Mul: return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Mul)); case OpCode.Int64: Stack.Push((int)instr.Operand); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ldc_I8, (long)instr.Operand)); case OpCode.Newarr: Stack.Pop(); Tuple <short, int> tuple3 = (Tuple <short, int>)instr.Operand; Stack.Push(module.ResolveTypeDef((uint)tuple3.Item2)); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Newarr, module.ResolveTypeDef((uint)tuple3.Item2))); case OpCode.Null: return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Nop)); case OpCode.Pop: Stack.Pop(); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Pop)); case OpCode.Ret: return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ret)); case OpCode.Stfld: Stack.Pop(); int item22 = ((Tuple <short, int>)instr.Operand).Item2; return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Stfld, module.ResolveField((uint)item22))); case OpCode.Stloc: var loc = Stack.Pop(); Local ll = meth.Body.Variables.Add(new Local(module.Import(loc.GetType()).ToTypeSig())); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Stloc, ll)); case OpCode.String: Stack.Push((string)instr.Operand); return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Ldstr, (string)instr.Operand)); default: return(dnlib.DotNet.Emit.Instruction.Create(OpCodes.Nop)); } }