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