Beispiel #1
0
        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}");
            }
        }
Beispiel #2
0
        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));
            }
        }