Skip to content
This repository has been archived by the owner on Oct 16, 2024. It is now read-only.

Hiding subversions from IReflectionManager #46

Merged
merged 3 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions Marsey/Stealthsey/Hidesey.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -62,7 +60,7 @@ public static class Hidesey
{
private static List<Assembly> _hideseys = new List<Assembly>();
private static bool _initialized;
private static bool _caching;
internal static bool caching;

/// <summary>
/// Starts Hidesey. Patches GetAssemblies, GetReferencedAssemblies and hides Harmony from assembly list.
Expand Down Expand Up @@ -122,6 +120,7 @@ public static void Disperse()
/// </summary>
public static void PostLoad()
{
Veil.Patch();
HWID.Force();
DiscordRPC.Patch();

Expand All @@ -143,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;
}

/// <summary>
Expand Down Expand Up @@ -184,7 +183,7 @@ public static void HidePatch(Assembly marsey)
}

/// <summary>
/// Undermines system functions, hides what doesnt belong from view
/// Undermines system functions, hides what doesn't belong from view
/// </summary>
/// <exception cref="HideseyException">Thrown if ThrowOnFail is true and any of the patches fails to apply</exception>
private static void Perjurize()
Expand Down Expand Up @@ -260,7 +259,7 @@ public static AssemblyName[] LyingReference(AssemblyName[] original)
public static Type[] LyingTyper(Type[] original)
{
IEnumerable<Type> hiddentypes = Facade.GetTypes();
if (!_caching)
if (!caching)
return original.Except(hiddentypes).ToArray();

Type[] cached = Facade.Cached;
Expand All @@ -275,4 +274,27 @@ public static Type[] LyingTyper(Type[] original)

#endregion

/// <summary>
/// Checks if the call was made by or concerns the content pack
/// </summary>
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;
}

}
86 changes: 86 additions & 0 deletions Marsey/Stealthsey/Veil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System.Reflection;
using HarmonyLib;
using JetBrains.Annotations;
using Marsey.Handbreak;
using Marsey.Misc;

namespace Marsey.Stealthsey;

/// <summary>
/// Hide subversions from IReflectionManager
/// </summary>
internal static class Veil
{
private static List<string?> HiddenAssemblies = [];
private static IEnumerable<Type> _veilCache = [];

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 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 AsmPrefix(ref IReadOnlyList<Assembly> __result, object __instance)
{
List<Assembly>? originalAssemblies = Traverse.Create(__instance).Field("assemblies").GetValue<List<Assembly>>();
if (originalAssemblies == null)
{
__result = new List<Assembly>().AsReadOnly();
return false;
}

// Filter out assemblies whose names are in HiddenAssemblies
List<Assembly> 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;
}

[UsedImplicitly]
private static void TypePost(ref IEnumerable<Type> __result)
{
if (!Hidesey.FromContent()) return;

MarseyLogger.Log(MarseyLogger.LogType.TRCE, "Passed fromcontent check with negative?");

if (Hidesey.caching && _veilCache.Any())
{
__result = _veilCache;
return;
}

IEnumerable<Type> hiddenTypes = Facade.GetTypes();
_veilCache = __result.Except(hiddenTypes).AsEnumerable();
__result = _veilCache;
}

public static void Hide(Assembly asm)
{
string? name = asm.GetName().Name;
if (name != null) HiddenAssemblies.Add(name);
}
}
3 changes: 3 additions & 0 deletions Marsey/Subversion/Subverse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
Loading