public GlobalMethodRefToConstantAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            var globalAddress = instruction.GetRipBasedInstructionMemoryAddress();

            MethodData = LibCpp2IlMain.GetMethodDefinitionByGlobalAddress(globalAddress);
            var(type, genericParams) = Utils.TryLookupTypeDefByName(MethodData !.DeclaringType.FullName);

            if (type == null)
            {
                Console.WriteLine("Failed to lookup managed type for declaring type of " + MethodData.GlobalKey + ", which is " + MethodData.DeclaringType.FullName);
                return;
            }

            ResolvedMethod = type.Methods.FirstOrDefault(m => m.Name == MethodData.Name);

            if (ResolvedMethod == null)
            {
                return;
            }

            var destReg = instruction.Op0Kind == OpKind.Register ? Utils.GetRegisterNameNew(instruction.Op0Register) : null;
            var name    = ResolvedMethod.Name;

            ConstantWritten = context.MakeConstant(typeof(MethodDefinition), ResolvedMethod, name, destReg);
        }
Exemple #2
0
        public LoadVirtualFunctionPointerAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            regReadFrom = Utils.GetRegisterNameNew(instruction.MemoryBase);
            var inReg = context.GetOperandInRegister(regReadFrom);

            if (!(inReg is ConstantDefinition cons) || !(cons.Value is Il2CppClassIdentifier klass))
            {
                return;
            }

            classReadFrom = klass.backingType;

            var readOffset = instruction.MemoryDisplacement;

            methodPointerRead = Utils.GetMethodFromReadKlassOffset((int)readOffset);

            if (methodPointerRead == null)
            {
                return;
            }

            var regPutInto = Utils.GetRegisterNameNew(instruction.Op0Register);

            if (regPutInto == "rsp")
            {
                //todo how do we handle this kind of instruction - does it even exist?
                // var stackOffset = Utils.GetOperandMemoryOffset(instruction.Operands[0]);
                // context.PushToStack(context.MakeConstant(typeof(MethodDefinition), methodPointerRead), stackOffset);
            }
            else
            {
                destinationConstant = context.MakeConstant(typeof(MethodDefinition), methodPointerRead, reg: regPutInto);
            }
        }
Exemple #3
0
        public InterfaceOffsetsReadAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            var regName     = Utils.GetRegisterNameNew(instruction.MemoryBase);
            var regConstant = context.GetConstantInReg(regName);

            _loadedFor       = (Il2CppClassIdentifier)regConstant.Value;
            InterfaceOffsets = _loadedFor.backingType.InterfaceOffsets;

            _destReg          = Utils.GetRegisterNameNew(instruction.Op0Register);
            _destinationConst = context.MakeConstant(typeof(Il2CppInterfaceOffset[]), InterfaceOffsets, reg: _destReg);
        }
Exemple #4
0
        public ComparisonAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            var r0           = Utils.GetRegisterNameNew(instruction.Op0Register);
            var r1           = Utils.GetRegisterNameNew(instruction.Op1Register);
            var ripBasedAddr = instruction.GetRipBasedInstructionMemoryAddress();

            if (r0 != "rsp")
            {
                ArgumentOne = instruction.Op0Kind == OpKind.Register
                    ? context.GetOperandInRegister(r0)
                    : instruction.Op0Kind.IsImmediate()
                        ? context.MakeConstant(typeof(int), instruction.GetImmediate(0))
                        : LibCpp2IlMain.GetAnyGlobalByAddress(ripBasedAddr).Offset == ripBasedAddr
                            ? context.MakeConstant(typeof(GlobalIdentifier), LibCpp2IlMain.GetAnyGlobalByAddress(ripBasedAddr))
                            : context.MakeConstant(typeof(UnknownGlobalAddr), new UnknownGlobalAddr(ripBasedAddr));
            }
            if (r1 != "rsp")
            {
                ArgumentTwo = instruction.Op1Kind == OpKind.Register
                    ? context.GetOperandInRegister(r1)
                    : instruction.Op1Kind.IsImmediate()
                        ? context.MakeConstant(typeof(int), instruction.GetImmediate(1))
                        :  LibCpp2IlMain.GetAnyGlobalByAddress(ripBasedAddr).Offset == ripBasedAddr
                            ? context.MakeConstant(typeof(GlobalIdentifier), LibCpp2IlMain.GetAnyGlobalByAddress(ripBasedAddr))
                            : context.MakeConstant(typeof(UnknownGlobalAddr), new UnknownGlobalAddr(ripBasedAddr));
            }
        }
        public GlobalStringRefToConstantAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            var globalAddress = instruction.GetRipBasedInstructionMemoryAddress();

            ResolvedString = LibCpp2IlMain.GetLiteralByAddress(globalAddress);

            if (ResolvedString == null)
            {
                return;
            }

            var destReg = instruction.Op0Kind == OpKind.Register ? Utils.GetRegisterNameNew(instruction.Op0Register) : null;

            ConstantWritten = context.MakeConstant(typeof(string), ResolvedString, null, destReg);
        }
        public GlobalTypeRefToConstantAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            var globalAddress = instruction.GetRipBasedInstructionMemoryAddress();
            var typeData      = LibCpp2IlMain.GetTypeGlobalByAddress(globalAddress);

            var(type, genericParams) = Utils.TryLookupTypeDefByName(typeData !.ToString());
            ResolvedType             = type;

            if (ResolvedType == null)
            {
                return;
            }

            _destReg = instruction.Op0Kind == OpKind.Register ? Utils.GetRegisterNameNew(instruction.Op0Register) : null;
            var name = ResolvedType.Name;

            ConstantWritten = context.MakeConstant(typeof(TypeDefinition), ResolvedType, name, _destReg);
        }
        public LoadInterfaceMethodDataAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            if (context.GetConstantInReg("rcx") is {} castConstant &&
                castConstant.Value is NewSafeCastResult castResult &&
                context.GetConstantInReg("rdx") is {} interfaceConstant &&
                interfaceConstant.Value is TypeDefinition interfaceType &&
                context.GetConstantInReg("r8") is {} slotConstant &&
                slotConstant.Value is int slot &&
                context.Actions.FirstOrDefault(a => a is LocateSpecificInterfaceOffsetAction) is LocateSpecificInterfaceOffsetAction locator
                )
            {
                _invokedOn     = castResult.original;
                _interfaceType = interfaceType;
                _slotNumber    = slot;
                resolvedMethod = SharedState.VirtualMethodsBySlot[(ushort)(locator._matchingInterfaceOffset.offset + _slotNumber)];

                _resultConstant = context.MakeConstant(typeof(MethodDefinition), resolvedMethod, reg: "rax");
            }
        }
Exemple #8
0
        public SafeCastAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            var inReg = context.GetOperandInRegister("rcx");

            castSource = inReg is LocalDefinition local ? local : inReg is ConstantDefinition cons && cons.Value is NewSafeCastResult result ? result.original : null;
            var destOp = context.GetOperandInRegister("rdx");

            if (destOp is ConstantDefinition cons2 && cons2.Type == typeof(TypeDefinition))
            {
                destinationType = (TypeDefinition)cons2.Value;
            }

            if (destinationType == null || castSource == null)
            {
                return;
            }

            _castResult = context.MakeConstant(typeof(NewSafeCastResult), new NewSafeCastResult
            {
                castTo   = destinationType,
                original = castSource
            }, reg: "rax");
        }