From bdb49dbc1e338bd5b36fa2ea10a471130324d5ef Mon Sep 17 00:00:00 2001 From: Conchelle Date: Tue, 28 May 2024 22:34:45 +0300 Subject: [PATCH 1/3] Hiding assemblies from IReflectionManager --- Marsey/Stealthsey/Hidesey.cs | 3 +- Marsey/Stealthsey/Veil.cs | 58 +++++++++++++++++++++++++++++++++++ Marsey/Subversion/Subverse.cs | 3 ++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 Marsey/Stealthsey/Veil.cs diff --git a/Marsey/Stealthsey/Hidesey.cs b/Marsey/Stealthsey/Hidesey.cs index 60a5921..7bc77a9 100644 --- a/Marsey/Stealthsey/Hidesey.cs +++ b/Marsey/Stealthsey/Hidesey.cs @@ -122,6 +122,7 @@ public static void Disperse() /// public static void PostLoad() { + Veil.Patch(); HWID.Force(); DiscordRPC.Patch(); @@ -184,7 +185,7 @@ public static void HidePatch(Assembly marsey) } /// - /// Undermines system functions, hides what doesnt belong from view + /// Undermines system functions, hides what doesn't belong from view /// /// Thrown if ThrowOnFail is true and any of the patches fails to apply private static void Perjurize() diff --git a/Marsey/Stealthsey/Veil.cs b/Marsey/Stealthsey/Veil.cs new file mode 100644 index 0000000..8012ec2 --- /dev/null +++ b/Marsey/Stealthsey/Veil.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using HarmonyLib; +using JetBrains.Annotations; +using Marsey.Handbreak; +using Marsey.Misc; + +namespace Marsey.Stealthsey; + +/// +/// Hide extra assemblies from IReflectionManager +/// +internal static class Veil +{ + private static List HiddenAssemblies = []; + + internal static void Patch() + { + Type? CRM = Helpers.TypeFromQualifiedName("Robust.Shared.Reflection.ReflectionManager"); + if (CRM == null) return; + + MarseyLogger.Log(MarseyLogger.LogType.DEBG, "Veil", "Patching."); + + MethodInfo AsmGetter = AccessTools.PropertyGetter(CRM, "Assemblies"); + MethodInfo Prefix = AccessTools.Method(typeof(Veil), "Prefix"); + Manual.Patch(AsmGetter, Prefix, HarmonyPatchType.Prefix); + } + + [UsedImplicitly] + private static bool Prefix(ref IReadOnlyList __result, object __instance) + { + List? originalAssemblies = Traverse.Create(__instance).Field("assemblies").GetValue>(); + if (originalAssemblies == null) + { + __result = new List().AsReadOnly(); + return false; + } + + // Filter out assemblies whose names are in HiddenAssemblies + List veiledAssemblies = originalAssemblies + .Where(asm => + { + string? value = asm.GetName().Name; + return value != null && !HiddenAssemblies.Contains(value); + }) + .ToList(); + + MarseyLogger.Log(MarseyLogger.LogType.TRCE, "Veil", $"Hidden {HiddenAssemblies.Count} assemblies."); + // Return the filtered list as a read-only list + __result = veiledAssemblies.AsReadOnly(); + return false; + } + + public static void Hide(Assembly asm) + { + string? name = asm.GetName().Name; + if (name != null) HiddenAssemblies.Add(name); + } +} diff --git a/Marsey/Subversion/Subverse.cs b/Marsey/Subversion/Subverse.cs index 03e7c85..78a5ea8 100644 --- a/Marsey/Subversion/Subverse.cs +++ b/Marsey/Subversion/Subverse.cs @@ -64,6 +64,9 @@ private static void Postfix(object __instance) Assembly subverterAssembly = Assembly.LoadFrom(path); MarseyLogger.Log(MarseyLogger.LogType.DEBG, "Subversion", $"Sideloading {path}"); AssemblyFieldHandler.InitLogger(subverterAssembly, subverterAssembly.FullName); + + // Stealthsey methods + Veil.Hide(subverterAssembly); Sedition.InitSedition(subverterAssembly, subverterAssembly.FullName); loadGameAssemblyMethod.Invoke(__instance, new object[] { subverterAssembly }); From fdcd5218b3761e4b8fa804f839dd1ed06c7f02a5 Mon Sep 17 00:00:00 2001 From: Conchelle Date: Wed, 29 May 2024 18:44:09 +0300 Subject: [PATCH 2/3] Hide subversions from contentpack --- Marsey/Stealthsey/Hidesey.cs | 35 ++++++++++++++++++++++++++++------- Marsey/Stealthsey/Veil.cs | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/Marsey/Stealthsey/Hidesey.cs b/Marsey/Stealthsey/Hidesey.cs index 7bc77a9..c367f99 100644 --- a/Marsey/Stealthsey/Hidesey.cs +++ b/Marsey/Stealthsey/Hidesey.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Collections.Generic; +using System.Diagnostics; using System.Reflection; using System.Runtime.Loader; using HarmonyLib; @@ -62,7 +60,7 @@ public static class Hidesey { private static List _hideseys = new List(); private static bool _initialized; - private static bool _caching; + internal static bool caching; /// /// Starts Hidesey. Patches GetAssemblies, GetReferencedAssemblies and hides Harmony from assembly list. @@ -144,8 +142,8 @@ public static void Cleanup() private static void ToggleCaching() { - MarseyLogger.Log(MarseyLogger.LogType.DEBG, $"Caching is set to {!_caching}"); - _caching = !_caching; + MarseyLogger.Log(MarseyLogger.LogType.DEBG, $"Caching is set to {!caching}"); + caching = !caching; } /// @@ -261,7 +259,7 @@ public static AssemblyName[] LyingReference(AssemblyName[] original) public static Type[] LyingTyper(Type[] original) { IEnumerable hiddentypes = Facade.GetTypes(); - if (!_caching) + if (!caching) return original.Except(hiddentypes).ToArray(); Type[] cached = Facade.Cached; @@ -276,4 +274,27 @@ public static Type[] LyingTyper(Type[] original) #endregion + /// + /// Checks if the call was made by or concerns the content pack + /// + internal static bool FromContent() + { + StackTrace stackTrace = new(); + //MarseyLogger.Log(MarseyLogger.LogType.TRCE, "Veil", $"Stacktrace check called, given {stackTrace.GetFrames().Length} frames."); + + foreach (StackFrame frame in stackTrace.GetFrames()) + { + MethodBase? method = frame.GetMethod(); + if (method == null || method.DeclaringType == null) continue; + string? namespaceName = method.DeclaringType.Namespace; + if (!string.IsNullOrEmpty(namespaceName) && namespaceName.StartsWith("Content.")) + { + //MarseyLogger.Log(MarseyLogger.LogType.INFO, "Veil", "Hidden types from a contentpack check!"); + return true; + } + } + + return false; + } + } diff --git a/Marsey/Stealthsey/Veil.cs b/Marsey/Stealthsey/Veil.cs index 8012ec2..9745d3d 100644 --- a/Marsey/Stealthsey/Veil.cs +++ b/Marsey/Stealthsey/Veil.cs @@ -7,11 +7,12 @@ namespace Marsey.Stealthsey; /// -/// Hide extra assemblies from IReflectionManager +/// Hide subversions from IReflectionManager /// internal static class Veil { private static List HiddenAssemblies = []; + private static IEnumerable _veilCache; internal static void Patch() { @@ -21,12 +22,21 @@ internal static void Patch() MarseyLogger.Log(MarseyLogger.LogType.DEBG, "Veil", "Patching."); MethodInfo AsmGetter = AccessTools.PropertyGetter(CRM, "Assemblies"); - MethodInfo Prefix = AccessTools.Method(typeof(Veil), "Prefix"); - Manual.Patch(AsmGetter, Prefix, HarmonyPatchType.Prefix); + MethodInfo AsmPrefix = AccessTools.Method(typeof(Veil), "AsmPrefix"); + Manual.Patch(AsmGetter, AsmPrefix, HarmonyPatchType.Prefix); + + MethodInfo FindAllTypes = AccessTools.Method(CRM, "FindAllTypes"); + MethodInfo GetAllChildren = AccessTools.Method(CRM, "GetAllChildren", new[] { typeof(Type), typeof(bool) }); + MethodInfo FindTypesWithAttribute = AccessTools.Method(CRM, "FindTypesWithAttribute", new[] { typeof(Type) }); + MethodInfo TypePost = AccessTools.Method(typeof(Veil), "TypePost"); + + Manual.Patch(FindAllTypes, TypePost, HarmonyPatchType.Postfix); + Manual.Patch(GetAllChildren, TypePost, HarmonyPatchType.Postfix); + Manual.Patch(FindTypesWithAttribute, TypePost, HarmonyPatchType.Postfix); } [UsedImplicitly] - private static bool Prefix(ref IReadOnlyList __result, object __instance) + private static bool AsmPrefix(ref IReadOnlyList __result, object __instance) { List? originalAssemblies = Traverse.Create(__instance).Field("assemblies").GetValue>(); if (originalAssemblies == null) @@ -50,6 +60,24 @@ private static bool Prefix(ref IReadOnlyList __result, object __instan return false; } + [UsedImplicitly] + private static void TypePost(ref IEnumerable __result) + { + if (!Hidesey.FromContent()) return; + + MarseyLogger.Log(MarseyLogger.LogType.TRCE, "Passed fromcontent check with negative?"); + + if (Hidesey.caching && _veilCache.Any()) + { + __result = _veilCache; + return; + } + + IEnumerable hiddenTypes = Facade.GetTypes(); + _veilCache = __result.Except(hiddenTypes).AsEnumerable(); + __result = _veilCache; + } + public static void Hide(Assembly asm) { string? name = asm.GetName().Name; From 1981312b11d860b495384db94f26338365923fac Mon Sep 17 00:00:00 2001 From: Conchelle Date: Wed, 29 May 2024 18:50:54 +0300 Subject: [PATCH 3/3] Warn --- Marsey/Stealthsey/Veil.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marsey/Stealthsey/Veil.cs b/Marsey/Stealthsey/Veil.cs index 9745d3d..a601456 100644 --- a/Marsey/Stealthsey/Veil.cs +++ b/Marsey/Stealthsey/Veil.cs @@ -12,7 +12,7 @@ namespace Marsey.Stealthsey; internal static class Veil { private static List HiddenAssemblies = []; - private static IEnumerable _veilCache; + private static IEnumerable _veilCache = []; internal static void Patch() {