private void Awake()
        {
            var detour = new NativeDetour(typeof(Resources).GetMethod(nameof(Resources.UnloadUnusedAssets)),
                                          typeof(ResourceUnloadOptimizations).GetMethod(nameof(RunUnloadUnusedAssets)));

            detour.Apply();
            originalUnload = detour.GenerateTrampoline <Func <AsyncOperation> >();
        }
        internal static void InitHooks()
        {
            var detour = new NativeDetour(
                typeof(SurvivorCatalog).GetMethodCached("Init"),
                typeof(SurvivorAPI).GetMethodCached(nameof(Init)));

            detour.Apply();
        }
Beispiel #3
0
        public static AbstractPhysicalObject Orig_AbstractPhysicalObjectFromString(World world, string str)
        {
            // Generating a trampoline may cause a segfault
            apofsDetour.Undo();
            AbstractPhysicalObject ret = SaveState.AbstractPhysicalObjectFromString(world, str);

            apofsDetour.Apply();
            return(ret);
        }
Beispiel #4
0
        protected override void Apply(IntPtr from)
        {
            var hookPtr =
                Marshal.GetFunctionPointerForDelegate(new PrintFDelegate(OnUnityLog));
            var det = new NativeDetour(from, hookPtr, new NativeDetourConfig {
                ManualApply = true
            });

            original = det.GenerateTrampoline <PrintFDelegate>();
            det.Apply();
        }
        private static void InstallHooks()
        {
            var target      = AccessTools.Method(typeof(Resources), nameof(Resources.UnloadUnusedAssets));
            var replacement = AccessTools.Method(typeof(Hooks), nameof(Hooks.UnloadUnusedAssetsHook));

            var detour = new NativeDetour(target, replacement);

            detour.Apply();

            _originalUnload = detour.GenerateTrampoline <Func <AsyncOperation> >();

            HarmonyWrapper.PatchAll(typeof(Hooks));
        }
        public static unsafe bool Refresh(void *target)
        {
            Stack <NativeDetour> detours = _GetDetours((long)target);

            if (detours.Count == 0)
            {
                return(false);
            }
            NativeDetour detour = detours.Peek();

            detour.Apply();
            return(true);
        }
        internal static Func <T, TResult> PatchGetter <T, TResult>(string propertyToPatch, Func <T, TResult> replacementGetter)
        {
            BindingFlags baseFlags  = BindingFlags.Public | BindingFlags.NonPublic;
            MethodInfo   origGetter = typeof(TextAsset).GetProperty(propertyToPatch, baseFlags | BindingFlags.Instance)?.GetGetMethod();

            if (origGetter is null)
            {
                throw new ArgumentException($"Unable to patch { propertyToPatch }. Property not found.");
            }

            NativeDetour detour = new NativeDetour(origGetter, replacementGetter.Method);

            detour.Apply();
            Logger.Log(LogLevel.Debug, $"patched: {origGetter.ReturnType} {nameof(TextAsset)}.{origGetter.Name}()");
            return(detour.GenerateTrampoline <Func <T, TResult> >());
        }
Beispiel #8
0
        public override void Apply()
        {
            // The process to patch native methods is as follows:
            // 1. Create a managed proxy method that calls NativeDetour's trampoline (we need to cache it
            //    because we don't know the trampoline method when generating the DMD).
            // 2. Pass the proxy to the normal Harmony manipulator to apply prefixes, postfixes, transpilers, etc.
            // 3. NativeDetour the method to the managed proxy
            // 4. Cache the NativeDetour's trampoline (technically we wouldn't need to, this is just a workaround
            //    for MonoMod's API.

            if (IsRunningOnDotNetCore)
            {
                Logger.Log(Logger.LogChannel.Warn, () => $"Patch target {Original.GetID()} is marked as extern. " +
                           "Extern methods may not be patched because of inlining behaviour of coreclr (refer to https://github.com/dotnet/coreclr/pull/8263)." +
                           "If you need to patch externs, consider using pure NativeDetour instead.");
            }


            var prevDmd = _dmd;

            _nativeDetour?.Dispose();

            _dmd = GenerateManagedOriginal();
            var ctx = new ILContext(_dmd.Definition);

            HarmonyManipulator.Manipulate(Original, Original.GetPatchInfo(), ctx);

            var target = _dmd.Generate();

            _nativeDetour = new NativeDetour(Original, target, new NativeDetourConfig
            {
                ManualApply = true
            });

            lock (TrampolineCache)
            {
                if (prevDmd != null)
                {
                    TrampolineCache.Remove(prevDmd.GetHashCode());
                }

                TrampolineCache[_dmd.GetHashCode()] = CreateDelegate(_trampolineDelegateType, _nativeDetour.GenerateTrampoline(_invokeTrampolineMethod));
            }

            _nativeDetour.Apply();
        }
Beispiel #9
0
        internal static void InitHooks()
        {
            var detour = new NativeDetour(
                typeof(SurvivorCatalog).GetMethodCached("Init"),
                typeof(SurvivorAPI).GetMethodCached(nameof(Init)));

            detour.Apply();

            On.RoR2.SurvivorCatalog.GetSurvivorDef += (orig, index) => GetSurvivorDef(index);

            // TODO: THIS IS A HOTFIX, WHY IS THE FIRST CHARACTERBODY NULL
            On.RoR2.UI.LogBook.LogBookController.BuildCategories += orig => {
                typeof(BodyCatalog).SetFieldValue("bodyPrefabBodyComponents",
                                                  typeof(BodyCatalog)
                                                  .GetFieldValue <CharacterBody[]>("bodyPrefabBodyComponents")
                                                  .Where(x => x != null).ToArray());
                return(orig());
            };
        }
Beispiel #10
0
        internal static void InitHooks()
        {
            var detour = new NativeDetour(typeof(SurvivorCatalog).GetMethod("Init", BindingFlags.NonPublic | BindingFlags.Static),
                                          typeof(SurvivorAPI).GetMethod(nameof(Init), BindingFlags.Public | BindingFlags.Static));

            detour.Apply();

            On.RoR2.SurvivorCatalog.GetSurvivorDef += (orig, survivorIndex) =>
            {
                //orig is the original method and SurvivorIndex is the variable that is given to the original GetSurvivorDef
                if (survivorIndex < 0 || (int)survivorIndex > SurvivorDefinitions.Count)
                {
                    return(null);
                }

                return(SurvivorDefinitions[(int)survivorIndex]);
                //by never doing orig(), the original method is never executed whenever it's called, effectively being replaced
            };
        }
Beispiel #11
0
        public static void Install()
        {
            if (_applied)
            {
                return;
            }

            new Hook(AccessTools.Method(AccessTools.Inner(typeof(ILHook), "Context"), "Refresh"),
                     AccessTools.Method(typeof(StackTraceFixes), nameof(OnILChainRefresh))).Apply();

            var nat = new NativeDetour(AccessTools.Method(typeof(Assembly), nameof(Assembly.GetExecutingAssembly)),
                                       AccessTools.Method(typeof(StackTraceFixes), nameof(GetAssemblyFix)));

            nat.Apply();
            _realGetAss = nat.GenerateTrampoline <Func <Assembly> >();

            new Hook(AccessTools.Method(typeof(StackFrame), nameof(StackFrame.GetMethod)),
                     AccessTools.Method(typeof(StackTraceFixes), nameof(GetMethodFix))).Apply();

            _applied = true;
        }
        /// <inheritdoc />
        public override MethodBase DetourTo(MethodBase replacement)
        {
            nativeDetour?.Dispose();

            nativeDetour = new NativeDetour(Original, replacement, new NativeDetourConfig {
                ManualApply = true
            });

            lock (TrampolineCache)
            {
                if (currentOriginal >= 0)
                {
                    TrampolineCache.Remove(currentOriginal);
                }
                currentOriginal = newOriginal;
                TrampolineCache[currentOriginal] = CreateDelegate(trampolineDelegateType,
                                                                  nativeDetour.GenerateTrampoline(invokeTrampolineMethod));
            }

            nativeDetour.Apply();
            return(replacement);
        }
Beispiel #13
0
        internal static void InitHooks()
        {
            ResourcesLoadDetour = new NativeDetour(
                typeof(Resources).GetMethod("Load", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string), typeof(Type) }, null),
                typeof(ResourcesAPI).GetMethod(nameof(OnResourcesLoad), BindingFlags.Static | BindingFlags.NonPublic)
                );
            _origLoad = ResourcesLoadDetour.GenerateTrampoline <d_ResourcesLoad>();
            ResourcesLoadDetour.Apply();

            ResourcesLoadAsyncDetour = new NativeDetour(
                typeof(Resources).GetMethod("LoadAsyncInternal", BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(string), typeof(Type) }, null),
                typeof(ResourcesAPI).GetMethod(nameof(OnResourcesLoadAsync), BindingFlags.Static | BindingFlags.NonPublic)
                );
            _origResourcesLoadAsync = ResourcesLoadAsyncDetour.GenerateTrampoline <d_ResourcesAsyncLoad>();
            ResourcesLoadAsyncDetour.Apply();

            ResourcesLoadAllDetour = new NativeDetour(
                typeof(Resources).GetMethod("LoadAll", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string), typeof(Type) }, null),
                typeof(ResourcesAPI).GetMethod(nameof(OnResourcesLoadAll), BindingFlags.Static | BindingFlags.NonPublic)
                );
            _origLoadAll = ResourcesLoadAllDetour.GenerateTrampoline <d_ResourcesLoadAll>();
            ResourcesLoadAllDetour.Apply();
        }