public static void Hook(this IntPtr targetPtr, MethodInfo patch) { unsafe { MelonUtils.NativeHookAttach(targetPtr, patch !.MethodHandle.GetFunctionPointer()); } }
private static unsafe void PatchICall <T>(string name, out T original, string patchName) where T : MulticastDelegate { var originalPointer = IL2CPP.il2cpp_resolve_icall(name); if (originalPointer == IntPtr.Zero) { MelonLogger.LogWarning($"ICall {name} was not found, not patching"); original = null; return; } var target = typeof(FinitizerMod).GetMethod(patchName, BindingFlags.Static | BindingFlags.NonPublic); Imports.Hook((IntPtr)(&originalPointer), target !.MethodHandle.GetFunctionPointer()); original = Marshal.GetDelegateForFunctionPointer <T>(originalPointer); }
public static void Patch() { unsafe { var setupMethod = typeof(PageWorldInfo).GetMethods() .Where(m => m.Name.StartsWith("Method_Public_Void_ApiWorld_ApiWorldInstance_Boolean_Boolean_") && !m.Name.Contains("PDM")) .OrderBy(m => m.GetCustomAttribute <CallerCountAttribute>().Count) .Last(); // Thanks to Knah var originalMethod = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(setupMethod).GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&originalMethod), typeof(WorldInfoSetup).GetMethod(nameof(Postfix), BindingFlags.Static | BindingFlags.Public) ! .MethodHandle.GetFunctionPointer()); worldInfoSetupDelegate = Marshal.GetDelegateForFunctionPointer <WorldInfoSetupDelegate>(originalMethod); } }
public override void OnApplicationStart() { AdvancedSafetySettings.RegisterSettings(); var matchingMethods = typeof(AssetManagement) .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Where(it => it.Name.StartsWith("Method_Public_Static_Object_Object_Vector3_Quaternion_Boolean_Boolean_Boolean_") && it.GetParameters().Length == 6).ToList(); foreach (var matchingMethod in matchingMethods) { unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(matchingMethod).GetValue(null); ObjectInstantiateDelegate originalInstantiateDelegate = null; ObjectInstantiateDelegate replacement = (assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer) => ObjectInstantiatePatch(assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer, originalInstantiateDelegate); ourPinnedDelegates.Add(replacement); Imports.Hook((IntPtr)(&originalMethodPointer), Marshal.GetFunctionPointerForDelegate(replacement)); originalInstantiateDelegate = Marshal.GetDelegateForFunctionPointer <ObjectInstantiateDelegate>(originalMethodPointer); } } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumA).GetMethod( nameof(AMEnumA.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchA), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextA = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchB), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextB = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumC).GetMethod( nameof(AMEnumC.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchC), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextC = originalMethodPointer; } unsafe { var originalMethodInfo = (Il2CppMethodInfo *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); var methodInfoCopy = (Il2CppMethodInfo *)Marshal.AllocHGlobal(Marshal.SizeOf <Il2CppMethodInfo>()); * methodInfoCopy = *originalMethodInfo; ourInvokeMethodInfo = (IntPtr)methodInfoCopy; } PortalHiding.OnApplicationStart(); AvatarHiding.OnApplicationStart(harmonyInstance); if (MelonHandler.Mods.Any(it => it.Info.SystemType.Name == nameof(UiExpansionKitMod))) { typeof(UiExpansionKitSupport).GetMethod(nameof(UiExpansionKitSupport.OnApplicationStart), BindingFlags.Static | BindingFlags.Public) !.Invoke(null, new object[0]); } }
private static IntPtr GetDetour(string name) { return(typeof(ModPatches).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static) !.MethodHandle.GetFunctionPointer()); }
public override void OnApplicationStart() { ModPrefs.RegisterCategory(SettingsCategory, "Sparkle Be Gone"); ModPrefs.RegisterPrefBool(SettingsCategory, StartSparkleSetting, false, "Show start sparkle"); ModPrefs.RegisterPrefBool(SettingsCategory, EndSparksSetting, false, "Show end sparks"); ModPrefs.RegisterPrefBool(SettingsCategory, EndFlareSetting, true, "Show end flare"); ModPrefs.RegisterPrefBool(SettingsCategory, RecolorSparksSetting, false, "Recolor sparks"); ModPrefs.RegisterPrefBool(SettingsCategory, RecolorBeamsSetting, true, "Recolor beams"); ModPrefs.RegisterPrefString(SettingsCategory, BeamColorSetting, "25 50 255 255", "Beam color (r g b a)"); var method = typeof(VRCSpaceUiPointer).GetMethod(nameof(VRCSpaceUiPointer.LateUpdate), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); { using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("SparkleBeGone.sparklebegone"); using var memStream = new MemoryStream((int)stream.Length); stream.CopyTo(memStream); var bundle = AssetBundle.LoadFromMemory_Internal(memStream.ToArray(), 0); myWhiteLaserTexture = bundle.LoadAsset_Internal("Assets/SparkleBeGone/sniper_beam_white.png", Il2CppType.Of <Texture2D>()).Cast <Texture2D>(); myWhiteLaserTexture.hideFlags |= HideFlags.DontUnloadUnusedAsset; } unsafe { var originalPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(method).GetValue(null); CompatHook((IntPtr)(&originalPointer), typeof(SparkleBeGoneMod).GetMethod(nameof(CursorLateUpdatePatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourOriginalLateUpdate = Marshal.GetDelegateForFunctionPointer <VoidDelegate>(originalPointer); } MelonCoroutines.Start(InitThings()); }
private static IntPtr GetDetour(string name) { return(typeof(AdvancedInviteSystem).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static) !.MethodHandle.GetFunctionPointer()); }
public static void OnApplicationStart() { unsafe { var originalMethod = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod( typeof(ObjectInstantiator).GetMethod(nameof(ObjectInstantiator._InstantiateObject))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethod), typeof(PortalHiding).GetMethod(nameof(InstantiateObjectPatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourDelegate = Marshal.GetDelegateForFunctionPointer <InstantiateObjectDelegate>(originalMethod); } }
public static unsafe void ApplyPatches() { try { // PDM's are scary:( MethodInfo avatarChangedMethod = typeof(VRCAvatarManager).GetMethods().FirstOrDefault(method => method.Name.StartsWith("Method_Private_Void_ApiAvatar_GameObject_Action_1_Boolean_")); IntPtr original = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(avatarChangedMethod).GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&original), typeof(ImmersiveTouch).GetMethod(nameof(ImmersiveTouch.OnAvatarChanged), BindingFlags.Static | BindingFlags.Public) !.MethodHandle.GetFunctionPointer()); avatarChangedDelegate = Marshal.GetDelegateForFunctionPointer <AvatarChangedDelegate>(original); } catch (Exception e) { MelonLogger.Error($"Failed to patch: OnAvatarChanged\n{e}"); } try { IntPtr original = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(DynamicBone).GetMethod(nameof(DynamicBone.Method_Private_Void_Boolean_0))).GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&original), typeof(ImmersiveTouch).GetMethod(nameof(ImmersiveTouch.OnUpdateParticles), BindingFlags.Static | BindingFlags.Public) !.MethodHandle.GetFunctionPointer()); updateParticlesDelegate = Marshal.GetDelegateForFunctionPointer <UpdateParticlesDelegate>(original); } catch (Exception e) { MelonLogger.Error($"Failed to patch: OnUpdateParticles\n{e}"); } try { IntPtr original = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(DynamicBoneCollider).GetMethod(nameof(DynamicBoneCollider.Method_Public_Void_byref_Vector3_Single_0))).GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&original), typeof(ImmersiveTouch).GetMethod(nameof(ImmersiveTouch.OnCollide), BindingFlags.Static | BindingFlags.Public) !.MethodHandle.GetFunctionPointer()); collideDelegate = Marshal.GetDelegateForFunctionPointer <CollideDelegate>(original); } catch (Exception e) { MelonLogger.Error($"Failed to patch: OnCollide\n{e}"); } }
public static void OnApplicationStart(HarmonyInstance harmony) { if (File.Exists(BlockedAvatarsMakersFilePath)) { ourBlockedAvatarAuthors.Clear(); foreach (var it in File.ReadAllLines(BlockedAvatarsMakersFilePath, Encoding.UTF8)) { var split = it.Split(new[] { '͏', ' ' }, 2, StringSplitOptions.RemoveEmptyEntries); if (split.Length == 2) { ourBlockedAvatarAuthors[split[0].Trim()] = split[1]; } } } if (File.Exists(BlockedAvatarsFilePath)) { ourBlockedAvatars.Clear(); foreach (var it in File.ReadAllLines(BlockedAvatarsFilePath, Encoding.UTF8)) { var split = it.Split(new[] { '͏', ' ' }, 2, StringSplitOptions.RemoveEmptyEntries); if (split.Length == 2) { ourBlockedAvatars[split[0].Trim()] = split[1]; } } } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(VRCAvatarManager).GetMethod( nameof(VRCAvatarManager.Method_Public_Boolean_ApiAvatar_String_Single_MulticastDelegateNPublicSealedVoGaVRBoUnique_0))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AvatarHiding).GetMethod(nameof(SwitchAvatarPatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourSwitchAvatar = Marshal.GetDelegateForFunctionPointer <SwitchAvatarDelegate>(originalMethodPointer); } foreach (var methodInfo in typeof(FeaturePermissionManager).GetMethods() .Where(it => it.Name.StartsWith("Method_Public_Boolean_APIUser_byref_EnumPublicSealedva5vUnique_") && it.GetCustomAttribute <CallerCountAttribute>().Count > 0)) { harmony.Patch(methodInfo, postfix: new HarmonyMethod(typeof(AvatarHiding), nameof(CanUseCustomAvatarPostfix))); } }
public override void OnApplicationStart() { AdvancedSafetySettings.RegisterSettings(); var matchingMethods = typeof(AssetManagement) .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Where(it => it.Name.StartsWith("Method_Public_Static_Object_Object_Vector3_Quaternion_Boolean_Boolean_Boolean_") && it.GetParameters().Length == 6).ToList(); foreach (var matchingMethod in matchingMethods) { unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(matchingMethod).GetValue(null); ObjectInstantiateDelegate originalInstantiateDelegate = null; ObjectInstantiateDelegate replacement = (assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer) => ObjectInstantiatePatch(assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer, originalInstantiateDelegate); ourPinnedDelegates.Add(replacement); MelonUtils.NativeHookAttach((IntPtr)(&originalMethodPointer), Marshal.GetFunctionPointerForDelegate(replacement)); originalInstantiateDelegate = Marshal.GetDelegateForFunctionPointer <ObjectInstantiateDelegate>(originalMethodPointer); } } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumA).GetMethod( nameof(AMEnumA.MoveNext))) .GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchA), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextA = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchB), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextB = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumC).GetMethod( nameof(AMEnumC.MoveNext))) .GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchC), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextC = originalMethodPointer; } unsafe { var originalMethodInfo = (Il2CppMethodInfo *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); var methodInfoCopy = (Il2CppMethodInfo *)Marshal.AllocHGlobal(Marshal.SizeOf <Il2CppMethodInfo>()); * methodInfoCopy = *originalMethodInfo; ourInvokeMethodInfo = (IntPtr)methodInfoCopy; } foreach (ProcessModule module in Process.GetCurrentProcess().Modules) { if (!module.FileName.Contains("UnityPlayer")) { continue; } // ProduceHelper<AudioMixer,0>::Produce, thanks to Ben for finding an adjacent method ourAudioMixerReadPointer = module.BaseAddress + 0x4997C0; var patchDelegate = new AudioMixerReadDelegate(AudioMixerReadPatch); ourPinnedDelegates.Add(patchDelegate); unsafe { fixed(IntPtr *mixerReadAddress = &ourAudioMixerReadPointer) MelonUtils.NativeHookAttach((IntPtr)mixerReadAddress, Marshal.GetFunctionPointerForDelegate(patchDelegate)); ourAudioMixerReadDelegate = Marshal.GetDelegateForFunctionPointer <AudioMixerReadDelegate>(ourAudioMixerReadPointer); } break; } SceneManager.add_sceneLoaded(new Action <Scene, LoadSceneMode>((s, _) => { if (s.buildIndex == -1) { ourCanReadAudioMixers = false; MelonDebug.Msg("No reading audio mixers anymore"); } })); SceneManager.add_sceneUnloaded(new Action <Scene>(s => { if (s.buildIndex == -1) { // allow loading mixers from world assetbundles ourCanReadAudioMixers = true; MelonDebug.Msg("Can read audio mixers now"); } })); PortalHiding.OnApplicationStart(); AvatarHiding.OnApplicationStart(Harmony); if (MelonHandler.Mods.Any(it => it.Info.SystemType.Name == nameof(UiExpansionKitMod))) { typeof(UiExpansionKitSupport).GetMethod(nameof(UiExpansionKitSupport.OnApplicationStart), BindingFlags.Static | BindingFlags.Public) !.Invoke(null, new object[0]); } }
public override void OnApplicationStart() { advInvPreferencesCategory = MelonPreferences.CreateCategory("AdvancedInvites", "Advanced Invites"); advInvPreferencesCategory.CreateEntry("DeleteNotifications", InviteHandler.DeleteNotifications, "Delete Notification After Successful Use"); advInvPreferencesCategory.CreateEntry("BlacklistEnabled", blacklistEnabled, "Blacklist System"); advInvPreferencesCategory.CreateEntry("WhitelistEnabled", whitelistEnabled, "Whitelist System"); advInvPreferencesCategory.CreateEntry("NotificationVolume", .8f, "Notification Volume"); advInvPreferencesCategory.CreateEntry("JoinMeNotifyRequest", joinMeNotifyRequest, "Join Me Req Notification Sound"); advInvPreferencesCategory.CreateEntry("IgnoreBusyStatus", ignoreBusyStatus, "Ignore Busy Status"); advInvPreferencesCategory.CreateEntry("InviteSoundEnabled", true, "Invite Sound"); advInvPreferencesCategory.CreateEntry("InviteRequestSoundEnabled", true, "Invite-Request Sound"); advInvPreferencesCategory.CreateEntry("VoteToKickSoundEnabled", false, "Vote-Kick Sound", true); advInvPreferencesCategory.CreateEntry("FriendRequestSoundEnabled", false, "Friend-Request Sound", true); OnPreferencesLoaded(); Localization.Load(); #if DEBUG DebugTesting.Test(); try { MethodInfo sendNotificationMethod = typeof(NotificationManager).GetMethod( nameof(NotificationManager.Method_Public_Void_String_String_String_String_NotificationDetails_ArrayOf_Byte_0), BindingFlags.Public | BindingFlags.Instance); Harmony.Patch(sendNotificationMethod, new HarmonyMethod( typeof(AdvancedInviteSystem).GetMethod(nameof(SendNotificationPatch), BindingFlags.NonPublic | BindingFlags.Static))); } catch (Exception e) { MelonLogger.Error("Error Patching SendNotification: " + e.Message); } #endif try { unsafe { // Appears to be NotificationManager.Method_Private_Void_Notification_1 MethodInfo acceptNotificationMethod = typeof(NotificationManager).GetMethods(BindingFlags.Public | BindingFlags.Instance).Single( m => m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Notification) && m.XRefScanFor("AcceptNotification for notification:")); IntPtr originalMethod = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(acceptNotificationMethod).GetValue(null); MelonUtils.NativeHookAttach( (IntPtr)(&originalMethod), typeof(AdvancedInviteSystem).GetMethod(nameof(AcceptNotificationPatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle .GetFunctionPointer()); acceptNotificationDelegate = Marshal.GetDelegateForFunctionPointer <AcceptNotificationDelegate>(originalMethod); } } catch (Exception e) { MelonLogger.Error("Error Patching AcceptNotification: " + e.Message); } try { //Appears to be NotificationManager.Method_Private_String_Notification_1 MethodInfo addNotificationMethod = typeof(NotificationManager).GetMethods(BindingFlags.Public | BindingFlags.Instance).Single( m => m.Name.StartsWith("Method_Private_") && m.ReturnType == typeof(string) && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Notification) && m.XRefScanFor("imageUrl")); Harmony.Patch( addNotificationMethod, postfix: new HarmonyMethod( typeof(AdvancedInviteSystem).GetMethod(nameof(AddNotificationPatch), BindingFlags.NonPublic | BindingFlags.Static))); } catch (Exception e) { MelonLogger.Error("Error Patching AddNotification: " + e.Message); } UserPermissionHandler.LoadSettings(); WorldPermissionHandler.LoadSettings(); MelonCoroutines.Start(WaitForVrChatUiManager()); }
public override void OnApplicationStart() { ModPrefs.RegisterCategory(ModCategory, "Mirror Resolution"); ModPrefs.RegisterPrefInt(ModCategory, MaxResPref, 4096, "Max eye texture size"); ModPrefs.RegisterPrefInt(ModCategory, MirrorMsaaPref, 0, "Mirror MSAA (0=default)"); ModPrefs.RegisterPrefBool(ModCategory, AllMirrorsAutoPref, false, "Force auto resolution"); unsafe { var methodInfo = Il2CppType.Of <VRC_MirrorReflection>().GetMethod(nameof(VRC_MirrorReflection.GetReflectionData), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var originalMethodPointer = *(IntPtr *)IL2CPP.il2cpp_method_get_from_reflection(methodInfo.Pointer); CompatHook((IntPtr)(&originalMethodPointer), typeof(MirrorResolutionUnlimiterMod).GetMethod(nameof(GetReflectionData), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); } OnModSettingsApplied(); if (AppDomain.CurrentDomain.GetAssemblies().Any(it => it.GetName().Name.StartsWith("UIExpansionKit"))) { MelonModLogger.Log("Adding UIExpansionKit buttons"); typeof(UiExtensionsAddon) .GetMethod(nameof(UiExtensionsAddon.Init), System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static) ! .Invoke(null, new object[0]); } }
public static void Patch() { unsafe { var setupMethod = typeof(PlayerManager).GetMethods() .Where(method => method.Name.StartsWith("Method_Public_Static_IEnumerable_1_Player_Vector3_Single_Nullable_1_Int32_Func_2_Player_Boolean_")) .OrderBy(UnhollowerSupport.GetIl2CppMethodCallerCount).Last(); var originalMethod = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(setupMethod).GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&originalMethod), typeof(PlayerIEnumerableSetup).GetMethod(nameof(EnumerableSetup), BindingFlags.Static | BindingFlags.Public) !.MethodHandle.GetFunctionPointer()); _playerIEnumerableSetupDelegate = Marshal.GetDelegateForFunctionPointer <PlayerIEnumerableSetupDelegate>(originalMethod); } }
private static void ApplyPatches() { PatchICall("UnityEngine.Transform::" + nameof(Transform.set_position_Injected), out ourOriginalTransformSetter, nameof(SetTransformVectorPatch)); PatchICall("UnityEngine.Transform::" + nameof(Transform.set_rotation_Injected), out ourOriginalTransformRotSetter, nameof(SetTransformQuaternionPatch)); PatchICall("UnityEngine.Transform::" + nameof(Transform.SetPositionAndRotation_Injected), out ourOriginalTransformTwinSetter, nameof(SetTransformVectorQuaternionPatch)); PatchICall("UnityEngine.Rigidbody::" + nameof(Rigidbody.set_position_Injected), out ourOriginalRigidbodyPosSetter, nameof(SetRigidbodyPosPatch)); PatchICall("UnityEngine.Rigidbody::" + nameof(Rigidbody.set_rotation_Injected), out ourOriginalRigidbodyRotSetter, nameof(SetRigidbodyRotPatch)); PatchICall("UnityEngine.Rigidbody::" + nameof(Rigidbody.MovePosition_Injected), out ourOriginalRigidbodyPosMove, nameof(SetRigidbodyPosMovePatch)); PatchICall("UnityEngine.Rigidbody::" + nameof(Rigidbody.MoveRotation_Injected), out ourOriginalRigidbodyRotMove, nameof(SetRigidbodyRotMovePatch)); PatchICall("UnityEngine.Rigidbody::" + nameof(Rigidbody.set_velocity_Injected), out ourOriginalRigidbodyVelSetter, nameof(SetRigidbodyVelPatch)); PatchICall("UnityEngine.Rigidbody::" + nameof(Rigidbody.set_angularVelocity_Injected), out ourOriginalRigidbodyAvSetter, nameof(SetRigidbodyAvPatch)); // These two were originally used to deserialize stuff from photon, but it seems like the vector one is not used anymore unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(PhotonSerializers).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly).Single(it => { var parameters = it.GetParameters(); if (it.ReturnType != typeof(void) || parameters.Length != 3 || it.Name.Contains("_PDM_") || parameters[1].ParameterType != typeof(Vector3).MakeByRefType()) { return(false); } return(true); })) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(FinitizerMod).GetMethod(nameof(VectorPatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourOriginalVectorMethod = Marshal.GetDelegateForFunctionPointer <VectorMethod>(originalMethodPointer); } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(PhotonSerializers).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly).Single(it => { var parameters = it.GetParameters(); if (it.ReturnType != typeof(void) || parameters.Length != 3 || it.Name.Contains("_PDM_") || parameters[1].ParameterType != typeof(Quaternion).MakeByRefType()) { return(false); } return(true); })) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(FinitizerMod).GetMethod(nameof(QuaternionPatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourOriginalQuaternionMethod = Marshal.GetDelegateForFunctionPointer <QuaternionMethod>(originalMethodPointer); } MelonLogger.Log("Things patching complete"); }
public override unsafe void OnApplicationStart() { try { var settingsCategory = "HWIDPatch"; MelonPrefs.RegisterCategory(settingsCategory, "HWID Patch"); MelonPrefs.RegisterString(settingsCategory, "HWID", "", hideFromList: true); var newId = MelonPrefs.GetString(settingsCategory, "HWID"); if (newId.Length != SystemInfo.deviceUniqueIdentifier.Length) { var random = new System.Random(Environment.TickCount); var bytes = new byte[SystemInfo.deviceUniqueIdentifier.Length / 2]; random.NextBytes(bytes); newId = string.Join("", bytes.Select(it => it.ToString("x2"))); MelonPrefs.SetString(settingsCategory, "HWID", newId); } ourGeneratedHwidString = new Il2CppSystem.Object(IL2CPP.ManagedStringToIl2Cpp(newId)); var icallName = "UnityEngine.SystemInfo::GetDeviceUniqueIdentifier"; var icallAddress = IL2CPP.il2cpp_resolve_icall(icallName); if (icallAddress == IntPtr.Zero) { MelonLogger.LogError("Can't resolve the icall, not patching"); return; } CompatHook((IntPtr)(&icallAddress), typeof(HWIDPatchMod).GetMethod(nameof(GetDeviceIdPatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); MelonLogger.Log("Patched HWID; below two should match:"); MelonLogger.Log($"Current: {SystemInfo.deviceUniqueIdentifier}"); MelonLogger.Log($"Target: {newId}"); } catch (Exception ex) { MelonLogger.LogError(ex.ToString()); } }
public static void DoPatch() { unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod( typeof(ApiModel).GetMethods().Single(it => it.Name == nameof(ApiModel.SetApiFieldsFromJson) && it.GetParameters().Length == 2)) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(ApiSnifferPatch).GetMethod(nameof(ApiSnifferStatic)) !.MethodHandle.GetFunctionPointer()); ourOriginalApiPopulate = Marshal.GetDelegateForFunctionPointer <ApiPopulateDelegate>(originalMethodPointer); } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(ImageDownloaderClosureType.GetMethod(nameof(ImageDownloaderClosure._DownloadImageInternal_b__0))).GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(ApiSnifferPatch).GetMethod(nameof(ImageSnifferPatch)) !.MethodHandle.GetFunctionPointer()); ourOriginalOnDone = Marshal.GetDelegateForFunctionPointer <ImageDownloaderOnDoneDelegate>(originalMethodPointer); } }
public override void OnApplicationStart() { AdvancedSafetySettings.RegisterSettings(); var matchingMethods = typeof(AssetManagement) .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Where(it => it.Name.StartsWith("Method_Public_Static_Object_Object_Vector3_Quaternion_Boolean_Boolean_Boolean_") && it.GetParameters().Length == 6).ToList(); MethodBase patchTarget = null; foreach (var methodInfo in typeof(AssetManagement).GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) { foreach (var it in XrefScanner.XrefScan(methodInfo)) { if (it.Type != XrefType.Method) { continue; } var methodBase = it.TryResolve(); if (methodBase == null) { continue; } if (matchingMethods.Contains(methodBase)) { patchTarget = methodBase; goto haveTarget; } } } haveTarget: if (patchTarget != null) { unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(patchTarget).GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(ObjectInstantiatePatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourOriginalInstantiate = Marshal.GetDelegateForFunctionPointer <ObjectInstantiateDelegate>(originalMethodPointer); } } else { MelonLogger.LogError("Patch target for object instantiation not found, avatar filtering will not work"); } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumA).GetMethod( nameof(AMEnumA.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchA), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextA = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchB), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextB = originalMethodPointer; } unsafe { var originalMethodInfo = (Il2CppMethodInfo *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); var methodInfoCopy = (Il2CppMethodInfo *)Marshal.AllocHGlobal(Marshal.SizeOf <Il2CppMethodInfo>()); * methodInfoCopy = *originalMethodInfo; ourInvokeMethodInfo = (IntPtr)methodInfoCopy; } PortalHiding.OnApplicationStart(); AvatarHiding.OnApplicationStart(); if (MelonHandler.Mods.Any(it => it.Info.SystemType.Name == nameof(UiExpansionKitMod))) { typeof(UiExpansionKitSupport).GetMethod(nameof(UiExpansionKitSupport.OnApplicationStart), BindingFlags.Static | BindingFlags.Public) !.Invoke(null, new object[0]); } }