예제 #1
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));
            }
        }
예제 #2
0
        private bool CheckParameters(Il2CppMethodDefinition method, MethodAnalysis context, bool isInstance)
        {
            var actualArgs = new List <IAnalysedOperand>();

            if (!isInstance)
            {
                actualArgs.Add(context.GetOperandInRegister("rcx") ?? context.GetOperandInRegister("xmm0"));
            }

            actualArgs.Add(context.GetOperandInRegister("rdx") ?? context.GetOperandInRegister("xmm1"));
            actualArgs.Add(context.GetOperandInRegister("r8") ?? context.GetOperandInRegister("xmm2"));
            actualArgs.Add(context.GetOperandInRegister("r9") ?? context.GetOperandInRegister("xmm3"));

            foreach (var parameterData in method.Parameters !)
            {
                if (actualArgs.Count(a => a != null) == 0)
                {
                    return(false);
                }

                var arg = actualArgs.RemoveAndReturn(0);
                switch (arg)
                {
                case ConstantDefinition cons when cons.Type.FullName != parameterData.Type.ToString():                    //Constant type mismatch
                case LocalDefinition local when !Utils.IsManagedTypeAnInstanceOfCppOne(parameterData.Type, local.Type !): //Local type mismatch
                    return(false);
                }
            }

            if (actualArgs.Any(a => a != null && !context.IsEmptyRegArg(a)))
            {
                return(false); //Left over args - it's probably not this one
            }
            return(true);
        }
예제 #3
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);
            }
        }
예제 #4
0
        public RegToRegMoveAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            originalReg = Utils.GetRegisterNameNew(instruction.Op1Register);
            newReg      = Utils.GetRegisterNameNew(instruction.Op0Register);
            beingMoved  = context.GetOperandInRegister(originalReg);

            context.SetRegContent(newReg, beingMoved);
        }
예제 #5
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");
        }
예제 #6
0
        public ClassPointerLoadAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            destReg = Utils.GetRegisterNameNew(instruction.Op0Register);
            if (instruction.Op0Register == Register.RSP)
            {
                Console.WriteLine("WARNING: CLASS POINTER LOAD DEST IS STACK.");
            }

            var sourceReg = Utils.GetRegisterNameNew(instruction.MemoryBase);
            var inReg     = context.GetOperandInRegister(sourceReg);

            localCopiedFrom = inReg is LocalDefinition local ? local : inReg is ConstantDefinition cons && cons.Value is NewSafeCastResult result ? result.original : null;
            if (localCopiedFrom == null)
            {
                return;
            }

            var cppTypeDef = SharedState.MonoToCppTypeDefs[localCopiedFrom.Type !];
예제 #7
0
        public CallVirtualMethodAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
        {
            var inReg = context.GetOperandInRegister(Utils.GetRegisterNameNew(instruction.MemoryBase));

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

            var classReadFrom = klass.backingType;

            var readOffset = instruction.MemoryDisplacement;

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

            if (Called == null)
            {
                return;
            }

            CalledOn = context.GetLocalInReg("rcx");
        }