Ejemplo n.º 1
0
        /// <summary>
        /// Primitive patching. Inserts a jump to 'target' at 'site'. Works even if both methods'
        /// callers have already been compiled.
        /// </summary>
        /// <param name="site"></param>
        /// <param name="target"></param>
        private static RedirectCallsState PatchJumpTo(IntPtr site, IntPtr target)
        {
            RedirectCallsState state = new RedirectCallsState();

            // R11 is volatile.
            unsafe
            {
                byte* sitePtr = (byte*)site.ToPointer();
                state.a = *sitePtr;
                state.b = *(sitePtr + 1);
                state.c = *(sitePtr + 10);
                state.d = *(sitePtr + 11);
                state.e = *(sitePtr + 12);
                state.f = *((ulong*) (sitePtr + 2));

                *sitePtr = 0x49; // mov r11, target
                *(sitePtr + 1) = 0xBB;
                *((ulong*)(sitePtr + 2)) = (ulong)target.ToInt64();
                *(sitePtr + 10) = 0x41; // jmp r11
                *(sitePtr + 11) = 0xFF;
                *(sitePtr + 12) = 0xE3;
            }

            return state;
        }
Ejemplo n.º 2
0
        public static void EnableHook()
        {
            if (hookEnabled)
            {
                return;
            }

            try
            {
                log = RedirectionHelper.RedirectCalls
                (
                    typeof(UnityEngine.Debug).GetMethod("Log", new[] { typeof(object) }),
                    typeof(UnityLoggingHook).GetMethod("Log", new[] { typeof(object) })
                );

                logFormat = RedirectionHelper.RedirectCalls
                (
                    typeof(UnityEngine.Debug).GetMethod("LogFormat", new[] { typeof(string), typeof(object[]) }),
                    typeof(UnityLoggingHook).GetMethod("LogFormat", new[] { typeof(string), typeof(object[]) })
                );

                logWarning = RedirectionHelper.RedirectCalls
                (
                    typeof(UnityEngine.Debug).GetMethod("LogWarning", new[] { typeof(object) }),
                    typeof(UnityLoggingHook).GetMethod("LogWarning", new[] { typeof(object) })
                );

                logWarningFormat = RedirectionHelper.RedirectCalls
                (
                    typeof(UnityEngine.Debug).GetMethod("LogWarningFormat", new[] { typeof(string), typeof(object[]) }),
                    typeof(UnityLoggingHook).GetMethod("LogWarningFormat", new[] { typeof(string), typeof(object[]) })
                );

                logError = RedirectionHelper.RedirectCalls
                (
                    typeof(UnityEngine.Debug).GetMethod("LogError", new[] { typeof(object) }),
                    typeof(UnityLoggingHook).GetMethod("LogError", new[] { typeof(object) })
                );

                logErrorFormat = RedirectionHelper.RedirectCalls
                (
                    typeof(UnityEngine.Debug).GetMethod("LogErrorFormat", new[] { typeof(string), typeof(object[]) }),
                    typeof(UnityLoggingHook).GetMethod("LogErrorFormat", new[] { typeof(string), typeof(object[]) })
                );

                logException = RedirectionHelper.RedirectCalls
                (
                    typeof(UnityEngine.Debug).GetMethod("LogException", new[] { typeof(Exception) }),
                    typeof(UnityLoggingHook).GetMethod("LogException", new[] { typeof(Exception) })
                );
            }
            catch (Exception ex)
            {
                global::ModTools.Log.Error("Failed to hook Unity's debug logging, reason: " + ex.Message);
            }

            hookEnabled = true;
            global::ModTools.Log.Warning("Unity logging subsystem hooked by ModTools");
        }
        public static void Bootstrap()
        {
            if (thisGameObject == null)
            {
                thisGameObject = new GameObject();
                thisGameObject.name = "ImprovedWorkshopIntegration";
                thisGameObject.AddComponent<ImprovedWorkshopIntegration>();
                thisGameObject.transform.parent = ModTools.Instance.gameObject.transform;
            }

            if (bootstrapped)
            {
                return;
            }

            var go = GameObject.Find("(Library) WorkshopModUploadPanel");
            if (go == null)
            {
                return;
            }

            workshopModUploadPanel = go.GetComponent<WorkshopModUploadPanel>();

            if (workshopModUploadPanel == null)
            {
                return;
            }

            UITabContainer categoryContainer = GameObject.Find("CategoryContainer").GetComponent<UITabContainer>();
            var modsList = categoryContainer.Find("Mods").Find("Content");
            if (modsList == null)
            {
                return;
            }

            m_StagingPath = Util.FindField(workshopModUploadPanel, "m_StagingPath");
            m_PreviewPath = Util.FindField(workshopModUploadPanel, "m_PreviewPath");
            m_ContentPath = Util.FindField(workshopModUploadPanel, "m_ContentPath");
            m_CurrentHandle = Util.FindField(workshopModUploadPanel, "m_CurrentHandle");
            m_ShareButton = Util.FindField(workshopModUploadPanel, "m_ShareButton");
            m_TargetFolder = Util.FindField(workshopModUploadPanel, "m_TargetFolder");
            m_ShareButton = Util.FindField(workshopModUploadPanel, "m_ShareButton");
            m_Title = Util.FindField(workshopModUploadPanel, "m_Title");
            m_Desc = Util.FindField(workshopModUploadPanel, "m_Desc");
            m_ChangeNote = Util.FindField(workshopModUploadPanel, "m_ChangeNote");
            m_DefaultModPreviewTexture = Util.FindField(workshopModUploadPanel, "m_DefaultModPreviewTexture");

            reloadPreviewImage = typeof(WorkshopModUploadPanel).GetMethod("ReloadPreviewImage",
                BindingFlags.Instance | BindingFlags.NonPublic);

            startWatchingPath = typeof(WorkshopModUploadPanel).GetMethod("StartWatchingPath",
                BindingFlags.Instance | BindingFlags.NonPublic);

            revertState = RedirectionHelper.RedirectCalls
            (
                typeof(WorkshopModUploadPanel).GetMethod("SetAssetInternal",
                    BindingFlags.Instance | BindingFlags.NonPublic),
                typeof(ImprovedWorkshopIntegration).GetMethod("SetAssetInternal",
                    BindingFlags.Instance | BindingFlags.NonPublic)
            );

            bootstrapped = true;
        }
        public static void Bootstrap()
        {
            if (thisGameObject == null)
            {
                thisGameObject = new GameObject();
                thisGameObject.name = "ImprovedWorkshopIntegration";
                thisGameObject.AddComponent<ImprovedWorkshopIntegration>();
                thisGameObject.transform.parent = ModTools.Instance.gameObject.transform;
            }

            improvedModsPanelExists = CheckForImprovedModsPanel();

            if (!improvedModsPanelExists)
            {
                InitializeModSortDropDown();
            }

            if (bootstrapped)
            {
                return;
            }

            var go = GameObject.Find("(Library) WorkshopModUploadPanel");
            if (go == null)
            {
                return;
            }

            workshopModUploadPanel = go.GetComponent<WorkshopModUploadPanel>();

            if (workshopModUploadPanel == null)
            {
                return;
            }

            var modsList = GameObject.Find("ModsList");
            if (modsList == null)
            {
                return;
            }

            m_StagingPath = Util.FindField(workshopModUploadPanel, "m_StagingPath");
            m_PreviewPath = Util.FindField(workshopModUploadPanel, "m_PreviewPath");
            m_ContentPath = Util.FindField(workshopModUploadPanel, "m_ContentPath");
            m_CurrentHandle = Util.FindField(workshopModUploadPanel, "m_CurrentHandle");
            m_ShareButton = Util.FindField(workshopModUploadPanel, "m_ShareButton");
            m_TargetFolder = Util.FindField(workshopModUploadPanel, "m_TargetFolder");
            m_ShareButton = Util.FindField(workshopModUploadPanel, "m_ShareButton");
            m_Title = Util.FindField(workshopModUploadPanel, "m_Title");
            m_Desc = Util.FindField(workshopModUploadPanel, "m_Desc");
            m_ChangeNote = Util.FindField(workshopModUploadPanel, "m_ChangeNote");
            m_DefaultModPreviewTexture = Util.FindField(workshopModUploadPanel, "m_DefaultModPreviewTexture");

            reloadPreviewImage = typeof(WorkshopModUploadPanel).GetMethod("ReloadPreviewImage",
                BindingFlags.Instance | BindingFlags.NonPublic);

            startWatchingPath = typeof(WorkshopModUploadPanel).GetMethod("StartWatchingPath",
                BindingFlags.Instance | BindingFlags.NonPublic);

            revertState = RedirectionHelper.RedirectCalls
            (
                typeof(WorkshopModUploadPanel).GetMethod("SetAssetInternal",
                    BindingFlags.Instance | BindingFlags.NonPublic),
                typeof(ImprovedWorkshopIntegration).GetMethod("SetAssetInternal",
                    BindingFlags.Instance | BindingFlags.NonPublic)
            );

            if (!improvedModsPanelExists)
            {
                modsPanelBootstrapped = true;
                revertState2 = RedirectionHelper.RedirectCalls
                (
                    typeof(PackageEntry).GetMethod("FormatPackageName",
                        BindingFlags.Static | BindingFlags.NonPublic),
                    typeof(ImprovedWorkshopIntegration).GetMethod("FormatPackageName",
                        BindingFlags.Static | BindingFlags.NonPublic)
                );

                revertState3 = RedirectionHelper.RedirectCalls
                (
                    typeof(CustomContentPanel).GetMethod("RefreshPlugins",
                        BindingFlags.Instance | BindingFlags.NonPublic),
                    typeof(ImprovedWorkshopIntegration).GetMethod("RefreshPlugins",
                        BindingFlags.Static | BindingFlags.Public)
                );
            }
            else
            {
                modsPanelBootstrapped = false;
            }

            bootstrapped = true;
        }
Ejemplo n.º 5
0
        public static void Bootstrap()
        {
            if (thisGameObject == null)
            {
                thisGameObject      = new GameObject();
                thisGameObject.name = "ImprovedWorkshopIntegration";
                thisGameObject.AddComponent <ImprovedWorkshopIntegration>();
                thisGameObject.transform.parent = ModTools.Instance.gameObject.transform;
            }

            improvedModsPanelExists = CheckForImprovedModsPanel();

            if (!improvedModsPanelExists)
            {
                InitializeModSortDropDown();
            }

            if (bootstrapped)
            {
                return;
            }

            var go = GameObject.Find("(Library) WorkshopModUploadPanel");

            if (go == null)
            {
                return;
            }

            workshopModUploadPanel = go.GetComponent <WorkshopModUploadPanel>();

            if (workshopModUploadPanel == null)
            {
                return;
            }

            var modsList = GameObject.Find("ModsList");

            if (modsList == null)
            {
                return;
            }

            m_StagingPath              = Util.FindField(workshopModUploadPanel, "m_StagingPath");
            m_PreviewPath              = Util.FindField(workshopModUploadPanel, "m_PreviewPath");
            m_ContentPath              = Util.FindField(workshopModUploadPanel, "m_ContentPath");
            m_CurrentHandle            = Util.FindField(workshopModUploadPanel, "m_CurrentHandle");
            m_ShareButton              = Util.FindField(workshopModUploadPanel, "m_ShareButton");
            m_TargetFolder             = Util.FindField(workshopModUploadPanel, "m_TargetFolder");
            m_ShareButton              = Util.FindField(workshopModUploadPanel, "m_ShareButton");
            m_Title                    = Util.FindField(workshopModUploadPanel, "m_Title");
            m_Desc                     = Util.FindField(workshopModUploadPanel, "m_Desc");
            m_ChangeNote               = Util.FindField(workshopModUploadPanel, "m_ChangeNote");
            m_DefaultModPreviewTexture = Util.FindField(workshopModUploadPanel, "m_DefaultModPreviewTexture");

            reloadPreviewImage = typeof(WorkshopModUploadPanel).GetMethod("ReloadPreviewImage",
                                                                          BindingFlags.Instance | BindingFlags.NonPublic);

            startWatchingPath = typeof(WorkshopModUploadPanel).GetMethod("StartWatchingPath",
                                                                         BindingFlags.Instance | BindingFlags.NonPublic);

            revertState = RedirectionHelper.RedirectCalls
                          (
                typeof(WorkshopModUploadPanel).GetMethod("SetAssetInternal",
                                                         BindingFlags.Instance | BindingFlags.NonPublic),
                typeof(ImprovedWorkshopIntegration).GetMethod("SetAssetInternal",
                                                              BindingFlags.Instance | BindingFlags.NonPublic)
                          );

            if (!improvedModsPanelExists)
            {
                modsPanelBootstrapped = true;
                revertState2          = RedirectionHelper.RedirectCalls
                                        (
                    typeof(PackageEntry).GetMethod("FormatPackageName",
                                                   BindingFlags.Static | BindingFlags.NonPublic),
                    typeof(ImprovedWorkshopIntegration).GetMethod("FormatPackageName",
                                                                  BindingFlags.Static | BindingFlags.NonPublic)
                                        );

                revertState3 = RedirectionHelper.RedirectCalls
                               (
                    typeof(CustomContentPanel).GetMethod("RefreshPlugins",
                                                         BindingFlags.Instance | BindingFlags.NonPublic),
                    typeof(ImprovedWorkshopIntegration).GetMethod("RefreshPlugins",
                                                                  BindingFlags.Static | BindingFlags.Public)
                               );
            }
            else
            {
                modsPanelBootstrapped = false;
            }

            bootstrapped = true;
        }
Ejemplo n.º 6
0
 public static void RevertRedirect(MethodInfo from, RedirectCallsState state)
 {
     var fptr1 = from.MethodHandle.GetFunctionPointer();
     RevertJumpTo(fptr1, state);
 }
Ejemplo n.º 7
0
 private static void RevertJumpTo(IntPtr site, RedirectCallsState state)
 {
     unsafe
     {
         byte* sitePtr = (byte*)site.ToPointer();
         *sitePtr = state.a; // mov r11, target
         *(sitePtr + 1) = state.b;
         *((ulong*)(sitePtr + 2)) = state.f;
         *(sitePtr + 10) = state.c; // jmp r11
         *(sitePtr + 11) = state.d;
         *(sitePtr + 12) = state.e;
     }
 }