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)); } }
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); }
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); } }
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); }
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"); }
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 !];
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"); }