using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoDetour.Bindings.Reorg.MonoModUtils; using MonoDetour.Bindings.Reorg.RuntimeDetour; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MonoMod.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("com.github.MonoDetour")] [assembly: InternalsVisibleTo("com.github.MonoDetour.ILWeaver")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Hamunii")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.7.15.0")] [assembly: AssemblyInformationalVersion("0.7.15+1a18a29676a2bb7aac7cc682a044e466d5c9708d")] [assembly: AssemblyProduct("MonoDetour.Bindings.Reorg")] [assembly: AssemblyTitle("MonoDetour.Bindings.Reorg")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.15.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MonoDetour.Bindings.Reorg { internal static class MonoModVersion { internal static bool IsReorg { get; } static MonoModVersion() { Type type = Type.GetType("MonoMod.Utils.ArchitectureKind, MonoMod.Utils"); if ((object)type != null) { IsReorg = true; InitAll(); } else { IsReorg = false; } } private static void InitAll() { ReorgILHook.Init(); ReorgILLabel.Init(); ReorgILCursor.Init(); ReorgILContext.Init(); ReorgFastDelegateInvokers.Init(); } } } namespace MonoDetour.Bindings.Reorg.RuntimeDetour { internal interface IMonoDetourConfig { string? OverrideId { get; } int Priority { get; } IEnumerable Before { get; } IEnumerable After { get; } } internal static class ReorgILHook { private delegate ILHook ILHookConstructor(MethodBase source, Manipulator manip, object? config, bool applyByDefault); private delegate object DetourConfigConstructor(string id, int? priority = null, IEnumerable? before = null, IEnumerable? after = null); private static Func detourContext_GetDefaultConfig = null; private static ILHookConstructor newILHook = null; private static DetourConfigConstructor newDetourConfig = null; private static Func detourConfigPriority = null; private static MethodInfo detourConfig_WithPriority = null; private static readonly ConcurrentDictionary interfaceToConfig = new ConcurrentDictionary(); private static readonly ConcurrentDictionary configToConfig = new ConcurrentDictionary(); private static readonly ConcurrentDictionary idToConfig = new ConcurrentDictionary(); internal static void Init() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Expected O, but got Unknown //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) detourContext_GetDefaultConfig = Extensions.CreateDelegate>((MethodBase)typeof(DetourContext).GetMethod("GetDefaultConfig", BindingFlags.Static | BindingFlags.Public)); Type type = Type.GetType("MonoMod.RuntimeDetour.DetourConfig, MonoMod.RuntimeDetour"); detourConfig_WithPriority = type.GetMethod("WithPriority", new Type[1] { typeof(int?) }); ConstructorInfo constructor = typeof(ILHook).GetConstructor(new Type[4] { typeof(MethodBase), typeof(Manipulator), type, typeof(bool) }); DynamicMethodDefinition val = new DynamicMethodDefinition("newILHook", typeof(ILHook), new Type[4] { typeof(MethodBase), typeof(Manipulator), typeof(object), typeof(bool) }); try { ILProcessor iLProcessor = val.GetILProcessor(); iLProcessor.Emit(OpCodes.Ldarg_0); iLProcessor.Emit(OpCodes.Ldarg_1); iLProcessor.Emit(OpCodes.Ldarg_2); iLProcessor.Emit(OpCodes.Ldarg_3); Extensions.Emit(iLProcessor, OpCodes.Newobj, (MethodBase)constructor); iLProcessor.Emit(OpCodes.Ret); newILHook = Extensions.CreateDelegate((MethodBase)val.Generate()); } finally { ((IDisposable)val)?.Dispose(); } ConstructorInfo constructor2 = type.GetConstructor(new Type[4] { typeof(string), typeof(int?), typeof(IEnumerable), typeof(IEnumerable) }); DynamicMethodDefinition val2 = new DynamicMethodDefinition("iLHookConstructor", typeof(object), new Type[4] { typeof(string), typeof(int?), typeof(IEnumerable), typeof(IEnumerable) }); try { ILProcessor iLProcessor2 = val2.GetILProcessor(); iLProcessor2.Emit(OpCodes.Ldarg_0); iLProcessor2.Emit(OpCodes.Ldarg_1); iLProcessor2.Emit(OpCodes.Ldarg_2); iLProcessor2.Emit(OpCodes.Ldarg_3); Extensions.Emit(iLProcessor2, OpCodes.Newobj, (MethodBase)constructor2); iLProcessor2.Emit(OpCodes.Ret); newDetourConfig = Extensions.CreateDelegate((MethodBase)val2.Generate()); } finally { ((IDisposable)val2)?.Dispose(); } MethodInfo getMethod = type.GetProperty("Priority").GetGetMethod(); DynamicMethodDefinition val3 = new DynamicMethodDefinition("get_Priority", typeof(int?), new Type[1] { typeof(object) }); try { ILProcessor iLProcessor3 = val3.GetILProcessor(); iLProcessor3.Emit(OpCodes.Ldarg_0); Extensions.Emit(iLProcessor3, OpCodes.Callvirt, (MethodBase)getMethod); iLProcessor3.Emit(OpCodes.Ret); detourConfigPriority = Extensions.CreateDelegate>((MethodBase)val3.Generate()); } finally { ((IDisposable)val3)?.Dispose(); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static ILHook ConstructILHook(MethodBase target, Manipulator manipulator, IMonoDetourConfig? config, string id) { if (config == null) { object obj = detourContext_GetDefaultConfig(); if (obj == null) { if (!idToConfig.TryGetValue(id, out object value)) { value = newDetourConfig(id, 0); idToConfig.TryAdd(id, value); } return newILHook(target, manipulator, value, applyByDefault: false); } if (detourConfigPriority(obj).HasValue) { return newILHook(target, manipulator, obj, applyByDefault: false); } if (!configToConfig.TryGetValue(obj, out object value2)) { value2 = detourConfig_WithPriority.Invoke(obj, new object[1] { 0 }); configToConfig.TryAdd(obj, value2); } return newILHook(target, manipulator, value2, applyByDefault: false); } if (!interfaceToConfig.TryGetValue(config, out object value3)) { value3 = newDetourConfig(config.OverrideId ?? id, config.Priority, config.Before, config.After); interfaceToConfig.TryAdd(config, value3); } return newILHook(target, manipulator, value3, applyByDefault: false); } } } namespace MonoDetour.Bindings.Reorg.MonoModUtils { internal static class ReorgFastDelegateInvokers { private delegate(MethodInfo, Type)? GetDelegateInvokerSig(Type type); private static GetDelegateInvokerSig? getDelegateInvoker; private static MethodInfo getDelegateInvokerMethod; internal static void Init() { Type type = Type.GetType("MonoMod.Cil.FastDelegateInvokers, MonoMod.Utils"); getDelegateInvokerMethod = type.GetMethod("GetDelegateInvoker", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Type) }, null); try { getDelegateInvoker = Extensions.CreateDelegate((MethodBase)getDelegateInvokerMethod); } catch (ArgumentException) when ((object)Type.GetType("Mono.Runtime") != null) { } } [MethodImpl(MethodImplOptions.NoInlining)] internal static (MethodInfo Invoker, Type Delegate)? GetDelegateInvoker(Type delegateType) { if (getDelegateInvoker == null) { return ((MethodInfo, Type)?)getDelegateInvokerMethod.Invoke(null, new object[1] { delegateType }); } return getDelegateInvoker(delegateType); } } internal static class ReorgILContext { private delegate int Signature(ILContext context, in T? value); private static class Container { internal static Signature AddReference => k__BackingField ?? (k__BackingField = Extensions.CreateDelegate>((MethodBase)addReferenceMethod.MakeGenericMethod(typeof(T)))); } private static MethodInfo Self_GetValueT_ii; private static MethodInfo addReferenceMethod; private static MethodInfo cellRef_get_Index; private static MethodInfo cellRef_get_Hash; private static MethodInfo getReferenceCell; internal static void Init() { addReferenceMethod = typeof(ILContext).GetMethod("AddReference") ?? throw new NullReferenceException(); Type type = Type.GetType("MonoMod.Utils.DynamicReferenceManager, MonoMod.Utils"); Self_GetValueT_ii = type.GetMethod("GetValueT", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[2] { typeof(int), typeof(int) }, null) ?? throw new InvalidOperationException("GetValueT doesn't exist?!?!?!?"); Type type2 = Type.GetType("MonoMod.Utils.DynamicReferenceCell, MonoMod.Utils"); getReferenceCell = typeof(ILContext).GetMethod("GetReferenceCell"); cellRef_get_Index = type2.GetProperty("Index").GetGetMethod(); cellRef_get_Hash = type2.GetProperty("Hash").GetGetMethod(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static int AddReference(ILContext context, in T value) { return Container.AddReference(context, in value); } [MethodImpl(MethodImplOptions.NoInlining)] internal static IEnumerable GetReference(Type type, ILContext context, int id) { object cellRef = getReferenceCell.Invoke(context, new object[1] { id }); ILProcessor il = context.IL; yield return Extensions.Create(il, OpCodes.Ldc_I4, cellRef_get_Index.Invoke(cellRef, Array.Empty())); yield return Extensions.Create(il, OpCodes.Ldc_I4, cellRef_get_Hash.Invoke(cellRef, Array.Empty())); yield return il.Create(OpCodes.Call, ((MemberReference)il.Body.Method).Module.ImportReference((MethodBase)Self_GetValueT_ii.MakeGenericMethod(type))); } } internal static class ReorgILCursor { private delegate int Signature(ILCursor cursor, in T? t); private static class Container { internal static Signature EmitReference => k__BackingField ?? (k__BackingField = Extensions.CreateDelegate>((MethodBase)emitReferenceMethod.MakeGenericMethod(typeof(T)))); } private static MethodInfo emitReferenceMethod; internal static void Init() { emitReferenceMethod = typeof(ILCursor).GetMethod("EmitReference") ?? throw new NullReferenceException(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static int EmitReference(ILCursor cursor, in T? t) { return Container.EmitReference(cursor, in t); } } internal static class ReorgILLabel { private static Func get_Target; private static Action set_Target; internal static void Init() { PropertyInfo property = typeof(ILLabel).GetProperty("Target"); set_Target = Extensions.CreateDelegate>((MethodBase)property.GetSetMethod()); get_Target = Extensions.CreateDelegate>((MethodBase)property.GetGetMethod()); } [MethodImpl(MethodImplOptions.NoInlining)] internal static Instruction? GetTarget(ILLabel label) { return get_Target(label); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void SetTarget(ILLabel label, Instruction value) { set_Target(label, value); } } }