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 static int GetMethodIndexFromMethod(Il2CppMethodDefinition methodDefinition) { if (LibCpp2IlMain.TheMetadata == null) { return(-1); } for (var i = 0; i < LibCpp2IlMain.TheMetadata.methodDefs.Length; i++) { if (LibCpp2IlMain.TheMetadata.methodDefs[i] == methodDefinition) { return(i); } } return(-1); }
public CallManagedFunctionAction(MethodAnalysis context, Instruction instruction) : base(context, instruction) { var jumpTarget = instruction.NearBranchTarget; var objectMethodBeingCalledOn = context.GetLocalInReg("rcx"); var listOfCallableMethods = LibCpp2IlMain.GetManagedMethodImplementationsAtAddress(jumpTarget); if (listOfCallableMethods == null) { return; } Il2CppMethodDefinition possibleTarget = null; if (objectMethodBeingCalledOn?.Type != null) { //Direct instance methods take priority possibleTarget = listOfCallableMethods.FirstOrDefault(m => !m.IsStatic && Utils.AreManagedAndCppTypesEqual(LibCpp2ILUtils.WrapType(m.DeclaringType !), objectMethodBeingCalledOn.Type) && CheckParameters(m, context, true)); //todo check args and null out if (possibleTarget == null) { //Base class instance methods possibleTarget = listOfCallableMethods.FirstOrDefault(m => !m.IsStatic && Utils.IsManagedTypeAnInstanceOfCppOne(LibCpp2ILUtils.WrapType(m.DeclaringType !), objectMethodBeingCalledOn.Type) && CheckParameters(m, context, true)); } //check args again. } //Check static methods if (possibleTarget == null) { possibleTarget = listOfCallableMethods.FirstOrDefault(m => m.IsStatic && CheckParameters(m, context, false)); } if (possibleTarget != null) { target = SharedState.UnmanagedToManagedMethods[possibleTarget]; return; } // SharedState.MethodsByAddress.TryGetValue(jumpTarget, out target); }
private static string GetModifiers(Il2CppMethodDefinition methodDef) { if (methodModifiers.TryGetValue(methodDef, out string str)) { return(str); } var access = methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK; switch (access) { case METHOD_ATTRIBUTE_PRIVATE: str += "private "; break; case METHOD_ATTRIBUTE_PUBLIC: str += "public "; break; case METHOD_ATTRIBUTE_FAMILY: str += "protected "; break; case METHOD_ATTRIBUTE_ASSEM: case METHOD_ATTRIBUTE_FAM_AND_ASSEM: str += "internal "; break; case METHOD_ATTRIBUTE_FAM_OR_ASSEM: str += "protected internal "; break; } if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) != 0) { str += "static "; } if ((methodDef.flags & METHOD_ATTRIBUTE_ABSTRACT) != 0) { str += "abstract "; if ((methodDef.flags & METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) == METHOD_ATTRIBUTE_REUSE_SLOT) { str += "override "; } } else if ((methodDef.flags & METHOD_ATTRIBUTE_FINAL) != 0) { if ((methodDef.flags & METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) == METHOD_ATTRIBUTE_REUSE_SLOT) { str += "sealed override "; } } else if ((methodDef.flags & METHOD_ATTRIBUTE_VIRTUAL) != 0) { if ((methodDef.flags & METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) == METHOD_ATTRIBUTE_NEW_SLOT) { str += "virtual "; } else { str += "override "; } } if ((methodDef.flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) != 0) { str += "extern "; } methodModifiers.Add(methodDef, str); return(str); }