public static IntPtr GetIl2CppClass(string assemblyName, string namespaze, string className) { if (!ourImagesMap.TryGetValue(assemblyName, out var image)) { LogSupport.Error($"Assembly {assemblyName} is not registered in il2cpp"); return(IntPtr.Zero); } var clazz = il2cpp_class_from_name(image, namespaze, className); return(clazz); }
public static IntPtr GetIl2CppField(IntPtr clazz, string fieldName) { if (clazz == IntPtr.Zero) { return(IntPtr.Zero); } var field = il2cpp_class_get_field_from_name(clazz, fieldName); if (field == IntPtr.Zero) { LogSupport.Error($"Field {fieldName} was not found on class {Marshal.PtrToStringAnsi(il2cpp_class_get_name(clazz))}"); } return(field); }
static IL2CPP() { var domain = il2cpp_domain_get(); if (domain == IntPtr.Zero) { LogSupport.Error("No il2cpp domain found; sad!"); return; } uint assembliesCount = 0; var assemblies = il2cpp_domain_get_assemblies(domain, ref assembliesCount); for (var i = 0; i < assembliesCount; i++) { var image = il2cpp_assembly_get_image(assemblies[i]); var name = Marshal.PtrToStringAnsi(il2cpp_image_get_name(image)); ourImagesMap[name] = image; } }
public static IntPtr GetIl2CppNestedType(IntPtr enclosingType, string nestedTypeName) { if (enclosingType == IntPtr.Zero) { return(IntPtr.Zero); } IntPtr iter = IntPtr.Zero; IntPtr nestedTypePtr; if (il2cpp_class_is_inflated(enclosingType)) { LogSupport.Trace("Original class was inflated, falling back to reflection"); if (GetNestedTypeViaReflection == null) { // todo: clean up this ugly reflection hack GetNestedTypeViaReflection = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(it => it.GetName().Name == "UnhollowerRuntimeLib") ?.GetType("UnhollowerRuntimeLib.RuntimeReflectionHelper") ?.GetMethod("GetNestedTypeViaReflection", BindingFlags.Static | BindingFlags.Public)?.CreateDelegate(typeof(Func <IntPtr, string, IntPtr>)) as Func <IntPtr, string, IntPtr>; } var result = GetNestedTypeViaReflection?.Invoke(enclosingType, nestedTypeName); if (result != null) { return(result.Value); } } while ((nestedTypePtr = il2cpp_class_get_nested_types(enclosingType, ref iter)) != IntPtr.Zero) { if (Marshal.PtrToStringAnsi(il2cpp_class_get_name(nestedTypePtr)) == nestedTypeName) { return(nestedTypePtr); } } LogSupport.Error($"Nested type {nestedTypeName} on {Marshal.PtrToStringAnsi(il2cpp_class_get_name(enclosingType))} not found!"); return(IntPtr.Zero); }
public static IntPtr GetIl2CppMethod(IntPtr clazz, string methodName, params string[] argTypes) { if (clazz == IntPtr.Zero) { return(NativeStructUtils.GetMethodInfoForMissingMethod(methodName + "(" + string.Join(", ", argTypes) + ")")); } for (var index = 0; index < argTypes.Length; index++) { var argType = argTypes[index]; argTypes[index] = Regex.Replace(argType, "\\`\\d+", "").Replace('/', '.'); } var methodsSeen = 0; var lastMethod = IntPtr.Zero; IntPtr iter = IntPtr.Zero; IntPtr method; while ((method = il2cpp_class_get_methods(clazz, ref iter)) != IntPtr.Zero) { if (Marshal.PtrToStringAnsi(il2cpp_method_get_name(method)) != methodName) { continue; } if (il2cpp_method_get_param_count(method) != argTypes.Length) { continue; } methodsSeen++; lastMethod = method; var badType = false; for (var i = 0; i < argTypes.Length; i++) { var paramType = il2cpp_method_get_param(method, (uint)i); var typeName = Marshal.PtrToStringAnsi(il2cpp_type_get_name(paramType)); if (typeName != argTypes[i]) { badType = true; break; } } if (badType) { continue; } return(method); } var className = Marshal.PtrToStringAnsi(il2cpp_class_get_name(clazz)); LogSupport.Trace($"Method {className}::{methodName} was stubbed with a random matching method of the same name"); if (methodsSeen == 1) { return(lastMethod); } LogSupport.Trace($"Unable to find method {className}::{methodName}; signature follows"); foreach (var argType in argTypes) { LogSupport.Trace($" {argType}"); } LogSupport.Trace("Available methods of this name follow:"); iter = IntPtr.Zero; while ((method = il2cpp_class_get_methods(clazz, ref iter)) != IntPtr.Zero) { if (Marshal.PtrToStringAnsi(il2cpp_method_get_name(method)) != methodName) { continue; } var nParams = il2cpp_method_get_param_count(method); LogSupport.Trace("Method starts"); for (var i = 0; i < nParams; i++) { var paramType = il2cpp_method_get_param(method, (uint)i); var typeName = Marshal.PtrToStringAnsi(il2cpp_type_get_name(paramType)); LogSupport.Trace($" {typeName}"); } return(method); } return(NativeStructUtils.GetMethodInfoForMissingMethod(className + "::" + methodName + "(" + string.Join(", ", argTypes) + ")")); }
public static IntPtr GetIl2CppMethod(IntPtr clazz, string methodName, params string[] argTypes) { if (clazz == IntPtr.Zero) { return(IntPtr.Zero); } for (var index = 0; index < argTypes.Length; index++) { var argType = argTypes[index]; argTypes[index] = Regex.Replace(argType, "\\`\\d+", "").Replace('/', '.'); } var methodsSeen = 0; var lastMethod = IntPtr.Zero; IntPtr iter = IntPtr.Zero; IntPtr method; while ((method = il2cpp_class_get_methods(clazz, ref iter)) != IntPtr.Zero) { if (Marshal.PtrToStringAnsi(il2cpp_method_get_name(method)) != methodName) { continue; } if (il2cpp_method_get_param_count(method) != argTypes.Length) { continue; } methodsSeen++; lastMethod = method; var badType = false; for (var i = 0; i < argTypes.Length; i++) { var paramType = il2cpp_method_get_param(method, (uint)i); var typeName = Marshal.PtrToStringAnsi(il2cpp_type_get_name(paramType)); if (typeName != argTypes[i]) { badType = true; break; } } if (badType) { continue; } return(method); } if (methodsSeen == 1) { return(lastMethod); } LogSupport.Log($"Unable to find method {Marshal.PtrToStringAnsi(il2cpp_class_get_name(clazz))}::{methodName}; signature follows"); foreach (var argType in argTypes) { LogSupport.Log($" {argType}"); } LogSupport.Log("Available methods of this name follow:"); iter = IntPtr.Zero; while ((method = il2cpp_class_get_methods(clazz, ref iter)) != IntPtr.Zero) { if (Marshal.PtrToStringAnsi(il2cpp_method_get_name(method)) != methodName) { continue; } // if(il2cpp_method_get_param_count(method) != argTypes.Length) // continue; var nParams = il2cpp_method_get_param_count(method); LogSupport.Log("Method starts"); for (var i = 0; i < nParams; i++) { var paramType = il2cpp_method_get_param(method, (uint)i); var typeName = Marshal.PtrToStringAnsi(il2cpp_type_get_name(paramType)); LogSupport.Log($" {typeName}"); } return(method); } return(IntPtr.Zero); }