Decompiled source of MonoDetour BepInEx 5 Resonite v0.7.14
Renderer/BepInEx/patchers/0.com.github.MonoDetour.BepInEx.5.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; using MonoDetour.Interop.HarmonyX; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Hamunii")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.7.14.0")] [assembly: AssemblyInformationalVersion("0.7.14+0d55abe3fd0d330206803b376c57bc7135c48257")] [assembly: AssemblyProduct("MonoDetour.BepInEx.5")] [assembly: AssemblyTitle("MonoDetour.BepInEx.5")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.14.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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.Logging { internal static class Patcher { [CompilerGenerated] private static class <>O { public static LogReceiver <0>__LogHandler; } internal static ManualLogSource Log = Logger.CreateLogSource("MonoDetour"); public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>(); public static void Initialize() { Environment.SetEnvironmentVariable("MONODETOUR_MANUAL_INIT", "1", EnvironmentVariableTarget.Process); Init(); } [MethodImpl(MethodImplOptions.NoInlining)] private static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<0>__LogHandler; if (obj == null) { LogReceiver val = LogHandler; <>O.<0>__LogHandler = val; obj = (object)val; } MonoDetourLogger.OnLog += (LogReceiver)obj; ModuleInitialization.Initialize(); HarmonyXInterop.Initialize(); } private static void LogHandler(LogChannel channel, string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected I4, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) LogLevel val; switch ((int)channel) { default: if ((int)channel != 8) { if ((int)channel != 16) { goto case 1; } val = (LogLevel)2; break; } val = (LogLevel)4; break; case 0: val = (LogLevel)0; break; case 2: val = (LogLevel)16; break; case 4: val = (LogLevel)16; break; case 1: case 3: throw new ArgumentOutOfRangeException("channel", "A log can only have a single known channel."); } LogLevel val2 = val; Log.Log(val2, (object)message); } public static void Patch(AssemblyDefinition _) { } } }
Renderer/BepInEx/core/com.github.MonoDetour.Interop.HarmonyX.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using HarmonyLib.Internal.Patching; using HarmonyLib.Internal.Util; using HarmonyLib.Public.Patching; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoDetour.Cil; using MonoDetour.DetourTypes.Manipulation; using MonoDetour.Interop.MonoModUtils; using MonoDetour.Logging; using MonoMod.Cil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("MonoDetour.UnitTests")] [assembly: IgnoresAccessChecksTo("0Harmony")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Hamunii")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.7.14.0")] [assembly: AssemblyInformationalVersion("0.7.14+0d55abe3fd0d330206803b376c57bc7135c48257")] [assembly: AssemblyProduct("MonoDetour.Interop.HarmonyX")] [assembly: AssemblyTitle("MonoDetour.Interop.HarmonyX")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.7.14.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Length; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Length; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return ((ICollection<T>)_items).Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { ((ICollection<T>)_items).CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return ((IList<T>)_items).IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T> { object IEnumerator.Current => _item; T IEnumerator<T>.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => 1; T IReadOnlyList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection<T>.Count => 1; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer<T>.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { if (!EqualityComparer<T>.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(_item); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return EqualityComparer<T>.Default.Equals(_item, item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { if (!EqualityComparer<T>.Default.Equals(_item, item)) { return -1; } return 0; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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.Interop.HarmonyX { internal static class EnforcePersistentInstructions { [CompilerGenerated] private static class <>O { public static Manipulator <0>__ILHook_HarmonyManipulator_MakeReturnLabel; public static Func<ILEmitter, HookTargetInfo> <1>__GetHookTargetInfo; public static Func<Instruction, HookTargetInfo, bool> <2>__IsPersistent; } internal static readonly MonoDetourManager persistentManager = new MonoDetourManager("com.github.MonoDetour.Interop.HarmonyX"); internal static void Init() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown MethodInfo method = typeof(HarmonyManipulator).GetMethod("MakeReturnLabel", BindingFlags.Instance | BindingFlags.NonPublic); if ((object)method == null) { MonoDetourLogger.Log(persistentManager, (LogChannel)16, "HarmonyManipulator.MakeReturnLabel doesn't exist!"); return; } MonoDetourManager obj = persistentManager; object obj2 = <>O.<0>__ILHook_HarmonyManipulator_MakeReturnLabel; if (obj2 == null) { Manipulator val = ILHook_HarmonyManipulator_MakeReturnLabel; <>O.<0>__ILHook_HarmonyManipulator_MakeReturnLabel = val; obj2 = (object)val; } obj.ILHook((MethodBase)method, (Manipulator)obj2, (MonoDetourConfig)null, true); } private static void ILHook_HarmonyManipulator_MakeReturnLabel(ILManipulationInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) HarmonyXInterop.anyFailed = true; ILWeaver w = new ILWeaver(info); Instruction loopStartOnLocSet = null; Instruction loopEnd = null; int locInstruction = 0; int num2 = default(int); FieldReference val6 = default(FieldReference); MethodReference val5 = default(MethodReference); int num = default(int); ILLabel val4 = default(ILLabel); ILWeaverResult val = w.MatchRelaxed(new Predicate<Instruction>[7] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num2), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val6), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref locInstruction), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val5) && w.SetInstructionTo(ref loopEnd, x), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<IEnumerator>(x, "MoveNext"), (Instruction x) => ILPatternMatchingExt.MatchBrtrue(x, ref val4) }); if (!val.IsValid) { MonoDetourLogger.Log(persistentManager, (LogChannel)16, val.FailureMessage); return; } MethodReference val3 = default(MethodReference); val = w.MatchRelaxed(new Predicate<Instruction>[2] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val3), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, locInstruction) && w.SetInstructionTo(ref loopStartOnLocSet, x) }); if (!val.IsValid) { MonoDetourLogger.Log(persistentManager, (LogChannel)16, val.FailureMessage); return; } VariableDefinition val2 = w.DeclareVariable(typeof(HookTargetInfo)); w.InsertBefore(w.First, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[4] { w.Create(OpCodes.Ldarg_0), w.Create<HarmonyManipulator>(OpCodes.Ldfld, "il"), w.CreateCall((Delegate)new Func<ILEmitter, HookTargetInfo>(GetHookTargetInfo)), w.Create(OpCodes.Stloc, val2) })); w.InsertBranchOverIfTrue(loopStartOnLocSet.Next, loopEnd, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Ldloc, locInstruction), w.Create(OpCodes.Ldloc, val2), w.CreateCall((Delegate)new Func<Instruction, HookTargetInfo, bool>(IsPersistent)) })); HarmonyXInterop.anyFailed = false; } private static HookTargetInfo GetHookTargetInfo(ILEmitter il) { return HookTargetRecords.GetHookTargetInfo(il.IL.Body.Method); } private static bool IsPersistent(Instruction instruction, HookTargetInfo info) { return info.IsPersistentInstruction(instruction); } } public static class HarmonyXInterop { internal const string ManagerName = "com.github.MonoDetour.Interop.HarmonyX"; private static bool initialized; internal static bool anyFailed; public static void Initialize() { try { InternalInitialize(); } catch (Exception arg) { MonoDetourLogger.Log((LogChannel)16, $"HarmonyX interop exploded while trying to initialize: {arg}"); Dispose(); } } private static void InternalInitialize() { if (initialized) { return; } initialized = true; TrackInstructions.Init(); if (anyFailed) { MonoDetourLogger.Log((LogChannel)16, "HarmonyX interop module has completely failed to initialize."); return; } EnforcePersistentInstructions.Init(); if (anyFailed) { MonoDetourLogger.Log((LogChannel)16, "HarmonyX interop module has partly failed to initialize."); return; } TrackPatches.Init(); if (anyFailed) { MonoDetourLogger.Log((LogChannel)16, "HarmonyX interop module has partly failed to initialize."); } } internal static void Dispose() { TrackInstructions.instructionManager.DisposeHooks(); EnforcePersistentInstructions.persistentManager.DisposeHooks(); TrackPatches.patchManager.DisposeHooks(); initialized = false; } } internal static class TrackInstructions { [CompilerGenerated] private static class <>O { public static Manipulator <0>__ILHook_ILManipulator_WriteTo; public static Func<ILManipulator, MethodBody, Dictionary<CodeInstruction, (Instruction, bool)>> <1>__MapInstructions; public static Func<Dictionary<CodeInstruction, (Instruction, bool)>, List<Instruction>> <2>__CreateInstructionsList; public static Func<Dictionary<CodeInstruction, (Instruction, bool)>, Dictionary<Instruction, Instruction>> <3>__CreateOldToNewDictionary; public static Action<MethodBody, CodeInstruction, Dictionary<CodeInstruction, (Instruction, bool)>, List<Instruction>, Dictionary<Instruction, Instruction>> <4>__MapInstruction; public static Action<MethodBody, List<Instruction>, Dictionary<Instruction, Instruction>> <5>__UpdateOriginalInstructions; } internal static readonly MonoDetourManager instructionManager = new MonoDetourManager("com.github.MonoDetour.Interop.HarmonyX"); internal static void Init() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown MethodInfo method = typeof(ILManipulator).GetMethod("WriteTo"); if ((object)method == null) { MonoDetourLogger.Log(instructionManager, (LogChannel)16, "ILManipulator.WriteTo doesn't exist!"); return; } MonoDetourManager obj = instructionManager; object obj2 = <>O.<0>__ILHook_ILManipulator_WriteTo; if (obj2 == null) { Manipulator val = ILHook_ILManipulator_WriteTo; <>O.<0>__ILHook_ILManipulator_WriteTo = val; obj2 = (object)val; } obj.ILHook((MethodBase)method, (Manipulator)obj2, (MonoDetourConfig)null, true); } private static void ILHook_ILManipulator_WriteTo(ILManipulationInfo info) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020f: 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_022f: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) HarmonyXInterop.anyFailed = true; ILWeaver val = new ILWeaver(info); if (!val.Body.HasExceptionHandlers) { MonoDetourLogger.Log(instructionManager, (LogChannel)16, "ILManipulator.WriteTo has no Exception handlers!"); return; } ILLabel val2 = default(ILLabel); if (!ILPatternMatchingExt.MatchBr(val.Body.ExceptionHandlers[0].TryStart, ref val2)) { MonoDetourLogger.Log(instructionManager, (LogChannel)16, "ILManipulator.WriteTo first try block's first instruction is not br!"); return; } Instruction val3 = InteropILLabel.InteropGetTarget(val2); val.CurrentTo(val3); int num = default(int); if (!ILPatternMatchingExt.MatchLdloc(val3, ref num)) { MonoDetourLogger.Log(instructionManager, (LogChannel)16, "ILManipulator.WriteTo first try block's first instruction's branch target is not Ldloc! " + $"Instead it is: '{val3}'"); return; } int num2 = ((((VariableReference)val.Body.Variables[num]).VariableType != val.Context.Import(typeof(CodeInstruction))) ? (num + 1) : num); VariableDefinition val4 = val.DeclareVariable(typeof(Dictionary<CodeInstruction, (Instruction, bool)>)); VariableDefinition val5 = val.DeclareVariable(typeof(List<Instruction>)); VariableDefinition val6 = val.DeclareVariable(typeof(Dictionary<Instruction, Instruction>)); val.InsertBefore(val.First, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[10] { val.Create(OpCodes.Ldarg_0), val.Create(OpCodes.Ldarg_1), val.CreateCall((Delegate)new Func<ILManipulator, MethodBody, Dictionary<CodeInstruction, (Instruction, bool)>>(MapInstructions)), val.Create(OpCodes.Stloc, val4), val.Create(OpCodes.Ldloc, val4), val.CreateCall((Delegate)new Func<Dictionary<CodeInstruction, (Instruction, bool)>, List<Instruction>>(CreateInstructionsList)), val.Create(OpCodes.Stloc, val5), val.Create(OpCodes.Ldloc, val4), val.CreateCall((Delegate)new Func<Dictionary<CodeInstruction, (Instruction, bool)>, Dictionary<Instruction, Instruction>>(CreateOldToNewDictionary)), val.Create(OpCodes.Stloc, val6) })); val.InsertBeforeCurrent((IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[6] { val.Create(OpCodes.Ldarg_1), val.Create(OpCodes.Ldloc, num2), val.Create(OpCodes.Ldloc, val4), val.Create(OpCodes.Ldloc, val5), val.Create(OpCodes.Ldloc, val6), val.CreateCall((Delegate)new Action<MethodBody, CodeInstruction, Dictionary<CodeInstruction, (Instruction, bool)>, List<Instruction>, Dictionary<Instruction, Instruction>>(MapInstruction)) })); val.InsertBeforeStealLabels(val.Last, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[4] { val.Create(OpCodes.Ldarg_1), val.Create(OpCodes.Ldloc, val5), val.Create(OpCodes.Ldloc, val6), val.CreateCall((Delegate)new Action<MethodBody, List<Instruction>, Dictionary<Instruction, Instruction>>(UpdateOriginalInstructions)) })); HarmonyXInterop.anyFailed = false; } private static Dictionary<CodeInstruction, (Instruction, bool)> MapInstructions(ILManipulator manipulator, MethodBody body) { ReadOnlyCollection<Instruction> originalInstructions = HookTargetRecords.GetOriginalInstructions(body.Method); HashSet<Instruction> hashSet = new HashSet<Instruction>(); foreach (Instruction item in originalInstructions) { hashSet.Add(item); } HashSet<Instruction> hashSet2 = hashSet; IEnumerable<RawInstruction> codeInstructions = manipulator.codeInstructions; Dictionary<CodeInstruction, (Instruction, bool)> dictionary = new Dictionary<CodeInstruction, (Instruction, bool)>(codeInstructions.Count()); foreach (RawInstruction item2 in codeInstructions) { dictionary.Add(item2.Instruction, (item2.CILInstruction, hashSet2.Contains(item2.CILInstruction))); } return dictionary; } private static List<Instruction> CreateInstructionsList(Dictionary<CodeInstruction, (Instruction, bool)> harmonyToCecil) { return new List<Instruction>(harmonyToCecil.Count); } private static Dictionary<Instruction, Instruction> CreateOldToNewDictionary(Dictionary<CodeInstruction, (Instruction, bool)> harmonyToCecil) { return new Dictionary<Instruction, Instruction>(harmonyToCecil.Count); } private static void MapInstruction(MethodBody body, CodeInstruction cur, Dictionary<CodeInstruction, (Instruction, bool)> harmonyToCecil, List<Instruction> newOriginalInstructions, Dictionary<Instruction, Instruction> oldToNew) { if (!harmonyToCecil.TryGetValue(cur, out (Instruction, bool) value)) { return; } Collection<Instruction> instructions = body.Instructions; Instruction val = instructions[instructions.Count - 1]; if (!oldToNew.ContainsKey(value.Item1)) { oldToNew.Add(value.Item1, val); if (value.Item2) { newOriginalInstructions.Add(val); } } } private static void UpdateOriginalInstructions(MethodBody body, List<Instruction> newOriginalInstructions, Dictionary<Instruction, Instruction> oldToNew) { MethodDefinition method = body.Method; HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(body.Method); HookTargetRecords.SwapOriginalInstructionsCollection(method, hookTargetInfo, new ReadOnlyCollection<Instruction>(newOriginalInstructions)); List<Instruction> firstPostfixInstructions = hookTargetInfo.PostfixInfo.FirstPostfixInstructions; for (int i = 0; i < firstPostfixInstructions.Count; i++) { Instruction key = firstPostfixInstructions[i]; if (oldToNew.TryGetValue(key, out Instruction value)) { firstPostfixInstructions[i] = value; } } Instruction[] array = hookTargetInfo.PersistentInstructions.ToArray(); hookTargetInfo.PersistentInstructions.Clear(); Instruction[] array2 = array; foreach (Instruction key2 in array2) { if (oldToNew.TryGetValue(key2, out Instruction value2)) { hookTargetInfo.MarkPersistentInstruction(value2); } } } } internal static class TrackPatches { [CompilerGenerated] private static class <>O { public static Manipulator <0>__ILHook_HarmonyManipulator_WritePrefixes; public static Manipulator <1>__ILHook_HarmonyManipulator_WritePostfixes; public static Func<ILEmitter, VariableDefinition?> <2>__GetRetVar; public static Action<HarmonyManipulator, ILEmitter, VariableDefinition> <3>__RunOriginalParamInit; public static Func<HarmonyManipulator, ILEmitter, VariableDefinition, bool> <4>__RunOriginalParamBranchLogic; public static Action<ILEmitter> <5>__ReturnLogic; public static <>A{00000001}<List<Label>, ILEmitter> <6>__AddStlocToLabelList; public static <>A{00000001}<List<Label>, Label> <7>__AddToLabelList; public static <>A{00000001}<List<Label>, ILEmitter> <8>__LabelsToMonoDetourPostfixes; } internal static readonly MonoDetourManager patchManager = new MonoDetourManager("com.github.MonoDetour.Interop.HarmonyX"); internal static void Init() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown MethodInfo method = typeof(HarmonyManipulator).GetMethod("WritePrefixes", BindingFlags.Instance | BindingFlags.NonPublic); if ((object)method == null) { MonoDetourLogger.Log(patchManager, (LogChannel)16, "HarmonyManipulator.WritePrefixes doesn't exist!"); return; } MethodInfo method2 = typeof(HarmonyManipulator).GetMethod("WritePostfixes", BindingFlags.Instance | BindingFlags.NonPublic); if ((object)method2 == null) { MonoDetourLogger.Log(patchManager, (LogChannel)16, "HarmonyManipulator.WritePostfixes doesn't exist!"); return; } MonoDetourManager obj = patchManager; object obj2 = <>O.<0>__ILHook_HarmonyManipulator_WritePrefixes; if (obj2 == null) { Manipulator val = ILHook_HarmonyManipulator_WritePrefixes; <>O.<0>__ILHook_HarmonyManipulator_WritePrefixes = val; obj2 = (object)val; } obj.ILHook((MethodBase)method, (Manipulator)obj2, (MonoDetourConfig)null, true); if (HarmonyXInterop.anyFailed) { patchManager.Dispose(); return; } MonoDetourManager obj3 = patchManager; object obj4 = <>O.<1>__ILHook_HarmonyManipulator_WritePostfixes; if (obj4 == null) { Manipulator val2 = ILHook_HarmonyManipulator_WritePostfixes; <>O.<1>__ILHook_HarmonyManipulator_WritePostfixes = val2; obj4 = (object)val2; } obj3.ILHook((MethodBase)method2, (Manipulator)obj4, (MonoDetourConfig)null, true); if (HarmonyXInterop.anyFailed) { patchManager.Dispose(); } } private static void ILHook_HarmonyManipulator_WritePrefixes(ILManipulationInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0713: Unknown result type (might be due to invalid IL or missing references) //IL_0726: Unknown result type (might be due to invalid IL or missing references) //IL_0782: Unknown result type (might be due to invalid IL or missing references) //IL_07b1: Unknown result type (might be due to invalid IL or missing references) //IL_07c4: Unknown result type (might be due to invalid IL or missing references) //IL_07d7: Unknown result type (might be due to invalid IL or missing references) //IL_07f5: Unknown result type (might be due to invalid IL or missing references) //IL_085a: Unknown result type (might be due to invalid IL or missing references) //IL_086d: Unknown result type (might be due to invalid IL or missing references) //IL_0880: Unknown result type (might be due to invalid IL or missing references) //IL_089e: Unknown result type (might be due to invalid IL or missing references) //IL_08fd: Unknown result type (might be due to invalid IL or missing references) //IL_0910: Unknown result type (might be due to invalid IL or missing references) HarmonyXInterop.anyFailed = true; ILWeaver w = new ILWeaver(info); Instruction ldarg0_ResultVar = null; Instruction declareVar_ResultVar = null; Instruction init_runOriginal = null; Instruction start_RunOriginalParamLogic = null; Instruction end_RunOriginalParamLogic = null; Instruction end_RetLogic = null; Instruction ilEmitterField = null; int loc_runOriginal = -1; FieldReference val24 = default(FieldReference); int num7 = default(int); IMetadataTokenProvider val23 = default(IMetadataTokenProvider); MethodReference val22 = default(MethodReference); MethodReference val21 = default(MethodReference); ILLabel val20 = default(ILLabel); FieldReference val19 = default(FieldReference); int num6 = default(int); ILWeaverResult val = w.MatchRelaxed(new Predicate<Instruction>[12] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val24), (Instruction x) => ILPatternMatchingExt.MatchLdsfld<HarmonyManipulator>(x, "ResultVar"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num7), (Instruction x) => ILPatternMatchingExt.MatchLdtoken(x, ref val23), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val22), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val21), (Instruction x) => ILPatternMatchingExt.MatchBrtrue(x, ref val20), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0) && w.SetInstructionTo(ref ldarg0_ResultVar, x), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val19) && w.SetInstructionTo(ref ilEmitterField, x), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num6), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<ILEmitter>(x, "DeclareVariable") && w.SetInstructionTo(ref declareVar_ResultVar, x) }); if (!val.IsValid) { FieldReference val18 = default(FieldReference); int num5 = default(int); IMetadataTokenProvider val17 = default(IMetadataTokenProvider); MethodReference val16 = default(MethodReference); ILLabel val15 = default(ILLabel); FieldReference val14 = default(FieldReference); int num4 = default(int); val = w.MatchRelaxed(new Predicate<Instruction>[11] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val18), (Instruction x) => ILPatternMatchingExt.MatchLdsfld<HarmonyManipulator>(x, "ResultVar"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num5), (Instruction x) => ILPatternMatchingExt.MatchLdtoken(x, ref val17), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val16), (Instruction x) => ILPatternMatchingExt.MatchBeq(x, ref val15), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0) && w.SetInstructionTo(ref ldarg0_ResultVar, x), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val14) && w.SetInstructionTo(ref ilEmitterField, x), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num4), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<ILEmitter>(x, "DeclareVariable") && w.SetInstructionTo(ref declareVar_ResultVar, x) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, val.FailureMessage); return; } } FieldReference val13 = default(FieldReference); MethodReference val12 = default(MethodReference); FieldReference val11 = default(FieldReference); MethodReference val10 = default(MethodReference); val = w.MatchRelaxed(new Predicate<Instruction>[9] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val13), (Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(OpCodes), "Ldc_I4_1"), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val12), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val11), (Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(OpCodes), "Stloc"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref loc_runOriginal), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val10) && w.SetInstructionTo(ref init_runOriginal, x) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, val.FailureMessage); return; } FieldReference val9 = default(FieldReference); int num3 = default(int); MethodReference val8 = default(MethodReference); FieldReference val7 = default(FieldReference); int num2 = default(int); MethodReference val6 = default(MethodReference); val = w.MatchRelaxed(new Predicate<Instruction>[10] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0) && w.SetInstructionTo(ref start_RunOriginalParamLogic, x), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val9), (Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(OpCodes), "Ldloc"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num3), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val8), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val7), (Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(OpCodes), "Brfalse"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num2), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val6) && w.SetInstructionTo(ref end_RunOriginalParamLogic, x) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, val.FailureMessage); return; } FieldReference val5 = default(FieldReference); FieldReference val4 = default(FieldReference); int num = default(int); MethodReference val3 = default(MethodReference); ILLabel val2 = default(ILLabel); val = w.MatchRelaxed(new Predicate<Instruction>[7] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val5), (Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, ref val4), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val3) && w.SetInstructionTo(ref end_RetLogic, x), (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 1), (Instruction x) => ILPatternMatchingExt.MatchRet(x) || ILPatternMatchingExt.MatchBr(x, ref val2) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, val.FailureMessage); return; } w.InsertBranchOver(ldarg0_ResultVar, declareVar_ResultVar); w.InsertBeforeStealLabels(declareVar_ResultVar.Next, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldfld, ilEmitterField.Operand), w.CreateCall((Delegate)new Func<ILEmitter, VariableDefinition>(GetRetVar)) })); w.InsertAfter(declareVar_ResultVar, (IEnumerable<Instruction>)new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Pop))); w.InsertAfter(init_runOriginal, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[5] { w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldfld, ilEmitterField.Operand), w.Create(OpCodes.Ldloc, loc_runOriginal), w.CreateCall((Delegate)new Action<HarmonyManipulator, ILEmitter, VariableDefinition>(RunOriginalParamInit)) })); w.InsertBranchOverIfTrue(start_RunOriginalParamLogic, end_RunOriginalParamLogic, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[5] { w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldfld, ilEmitterField.Operand), w.Create(OpCodes.Ldloc, loc_runOriginal), w.CreateCall((Delegate)new Func<HarmonyManipulator, ILEmitter, VariableDefinition, bool>(RunOriginalParamBranchLogic)) })); w.InsertAfter(end_RetLogic, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldfld, ilEmitterField.Operand), w.CreateCall((Delegate)new Action<ILEmitter>(ReturnLogic)) })); HarmonyXInterop.anyFailed = false; } private static void ILHook_HarmonyManipulator_WritePostfixes(ILManipulationInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0751: Unknown result type (might be due to invalid IL or missing references) //IL_0764: Unknown result type (might be due to invalid IL or missing references) //IL_07c0: Unknown result type (might be due to invalid IL or missing references) //IL_0805: Unknown result type (might be due to invalid IL or missing references) //IL_0819: Unknown result type (might be due to invalid IL or missing references) //IL_082c: Unknown result type (might be due to invalid IL or missing references) //IL_0890: Unknown result type (might be due to invalid IL or missing references) //IL_08a4: Unknown result type (might be due to invalid IL or missing references) //IL_0908: Unknown result type (might be due to invalid IL or missing references) //IL_091c: Unknown result type (might be due to invalid IL or missing references) //IL_0985: Unknown result type (might be due to invalid IL or missing references) //IL_0999: Unknown result type (might be due to invalid IL or missing references) //IL_09ac: Unknown result type (might be due to invalid IL or missing references) HarmonyXInterop.anyFailed = true; ILWeaver w = new ILWeaver(info); Instruction ldarg0_ResultVar = null; Instruction ldarg0_RunOriginalParam = null; Instruction declareVar_ResultVar = null; Instruction declareVar_RunOriginalParam = null; Instruction emitStloc = null; Instruction startLabel_1 = null; Instruction startLabel_2 = null; Instruction ilEmitterField = null; FieldReference val24 = default(FieldReference); int num9 = default(int); IMetadataTokenProvider val23 = default(IMetadataTokenProvider); MethodReference val22 = default(MethodReference); MethodReference val21 = default(MethodReference); ILLabel val20 = default(ILLabel); FieldReference val19 = default(FieldReference); int num8 = default(int); ILWeaverResult val = w.MatchRelaxed(new Predicate<Instruction>[12] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val24), (Instruction x) => ILPatternMatchingExt.MatchLdsfld<HarmonyManipulator>(x, "ResultVar"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num9), (Instruction x) => ILPatternMatchingExt.MatchLdtoken(x, ref val23), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val22), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val21), (Instruction x) => ILPatternMatchingExt.MatchBrtrue(x, ref val20), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0) && w.SetInstructionTo(ref ldarg0_ResultVar, x), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val19) && w.SetInstructionTo(ref ilEmitterField, x), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num8), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<ILEmitter>(x, "DeclareVariable") && w.SetInstructionTo(ref declareVar_ResultVar, x) }); if (!val.IsValid) { FieldReference val18 = default(FieldReference); int num7 = default(int); IMetadataTokenProvider val17 = default(IMetadataTokenProvider); MethodReference val16 = default(MethodReference); ILLabel val15 = default(ILLabel); FieldReference val14 = default(FieldReference); int num6 = default(int); val = w.MatchRelaxed(new Predicate<Instruction>[11] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val18), (Instruction x) => ILPatternMatchingExt.MatchLdsfld<HarmonyManipulator>(x, "ResultVar"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num7), (Instruction x) => ILPatternMatchingExt.MatchLdtoken(x, ref val17), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val16), (Instruction x) => ILPatternMatchingExt.MatchBeq(x, ref val15), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0) && w.SetInstructionTo(ref ldarg0_ResultVar, x), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val14) && w.SetInstructionTo(ref ilEmitterField, x), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num6), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<ILEmitter>(x, "DeclareVariable") && w.SetInstructionTo(ref declareVar_ResultVar, x) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, val.FailureMessage); return; } } FieldReference val13 = default(FieldReference); FieldReference val12 = default(FieldReference); IMetadataTokenProvider val11 = default(IMetadataTokenProvider); MethodReference val10 = default(MethodReference); val = w.MatchRelaxed(new Predicate<Instruction>[8] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val13), (Instruction x) => ILPatternMatchingExt.MatchLdsfld<HarmonyManipulator>(x, "RunOriginalParam"), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0) && w.SetInstructionTo(ref ldarg0_RunOriginalParam, x), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val12), (Instruction x) => ILPatternMatchingExt.MatchLdtoken(x, ref val11), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val10), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<ILEmitter>(x, "DeclareVariable") && w.SetInstructionTo(ref declareVar_RunOriginalParam, x) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, val.FailureMessage); return; } int num5 = default(int); ILLabel val9 = default(ILLabel); FieldReference val8 = default(FieldReference); int num4 = default(int); val = w.MatchRelaxed(new Predicate<Instruction>[7] { (Instruction x) => ILPatternMatchingExt.MatchAnd(x) || ILPatternMatchingExt.MatchLdloc(x, ref num5), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val9), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val8), (Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(OpCodes), "Stloc"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num4), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<ILEmitter>(x, "Emit") && w.SetInstructionTo(ref emitStloc, x) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, val.FailureMessage); return; } int num3 = default(int); FieldReference val7 = default(FieldReference); MethodReference val6 = default(MethodReference); int num2 = default(int); val = w.MatchRelaxed(new Predicate<Instruction>[5] { (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num3), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val7), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val6), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num2) && w.SetInstructionTo(ref startLabel_1, x) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, "3: " + val.FailureMessage); return; } MethodReference val5 = default(MethodReference); FieldReference val4 = default(FieldReference); MethodReference val3 = default(MethodReference); int num = default(int); val = w.MatchRelaxed(new Predicate<Instruction>[6] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val5), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val4), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val3), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num) && w.SetInstructionTo(ref startLabel_2, x) }); if (!val.IsValid) { MonoDetourLogger.Log(patchManager, (LogChannel)16, "4: " + val.FailureMessage); return; } w.InsertBranchOver(ldarg0_ResultVar, declareVar_ResultVar); w.InsertBeforeStealLabels(declareVar_ResultVar.Next, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldfld, ilEmitterField.Operand), w.CreateCall((Delegate)new Func<ILEmitter, VariableDefinition>(GetRetVar)) })); w.InsertAfter(declareVar_ResultVar, (IEnumerable<Instruction>)new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Pop))); VariableDefinition val2 = w.DeclareVariable(typeof(List<Label>)); w.InsertAfter(emitStloc, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[4] { w.Create(OpCodes.Ldloca, val2), w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldfld, ilEmitterField.Operand), w.CreateCall((Delegate)new <>A{00000001}<List<Label>, ILEmitter>(AddStlocToLabelList)) })); w.InsertAfter(startLabel_1, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Ldloca, val2), w.Create(OpCodes.Ldloc, startLabel_1.Operand), w.CreateCall((Delegate)new <>A{00000001}<List<Label>, Label>(AddToLabelList)) })); w.InsertAfter(startLabel_2, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Ldloca, val2), w.Create(OpCodes.Ldloc, startLabel_2.Operand), w.CreateCall((Delegate)new <>A{00000001}<List<Label>, Label>(AddToLabelList)) })); w.InsertBeforeStealLabels(w.Last, (IEnumerable<Instruction>)new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[4] { w.Create(OpCodes.Ldloca, val2), w.Create(OpCodes.Ldarg_0), w.Create(OpCodes.Ldfld, ilEmitterField.Operand), w.CreateCall((Delegate)new <>A{00000001}<List<Label>, ILEmitter>(LabelsToMonoDetourPostfixes)) })); HarmonyXInterop.anyFailed = false; } private static void AddStlocToLabelList(ref List<Label>? labels, ILEmitter il) { if (labels == null) { labels = new List<Label>(); } Collection<Instruction> instructions = il.IL.Body.Instructions; Label item = il.DeclareLabelFor(instructions[instructions.Count - 2]); labels.Add(item); } private static void AddToLabelList(ref List<Label>? labels, Label label) { if (labels == null) { labels = new List<Label>(); } labels.Add(label); } private static void LabelsToMonoDetourPostfixes(ref List<Label>? labels, ILEmitter il) { if (labels == null) { return; } foreach (Label label in labels) { HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(il.IL.Body.Method); hookTargetInfo.PostfixInfo.FirstPostfixInstructions.Add(label.instruction); } } private static VariableDefinition? GetRetVar(ILEmitter ilEmitter) { MethodDefinition method = ilEmitter.IL.Body.Method; HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(method); return hookTargetInfo.ReturnValue; } private static void RunOriginalParamInit(HarmonyManipulator manipulator, ILEmitter il, VariableDefinition runOriginal) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) int num = default(int); if (MonoDetourHook.HasActiveControlFlowMonoDetourHooks(manipulator.original, ref num)) { MethodDefinition method = il.IL.Body.Method; HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(method); TargetPrefixInfo prefixInfo = hookTargetInfo.PrefixInfo; VariableDefinition controlFlow = prefixInfo.ControlFlow; if (num != prefixInfo.AppliedControlFlowPrefixes) { il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ldloc, controlFlow); il.Emit(OpCodes.Sub); il.Emit(OpCodes.Ldloc, runOriginal); il.Emit(OpCodes.And); il.Emit(OpCodes.Stloc, runOriginal); } } } private static bool RunOriginalParamBranchLogic(HarmonyManipulator manipulator, ILEmitter il, VariableDefinition runOriginal) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) MethodDefinition method = il.IL.Body.Method; HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(method); TargetPrefixInfo prefixInfo = hookTargetInfo.PrefixInfo; VariableDefinition controlFlow = prefixInfo.ControlFlow; int num = default(int); if (!MonoDetourHook.HasActiveControlFlowMonoDetourHooks(manipulator.original, ref num) && !prefixInfo.ControlFlowImplemented) { return false; } if (prefixInfo.ControlFlowImplemented) { il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ldloc, runOriginal); il.Emit(OpCodes.Sub); if (num > prefixInfo.AppliedControlFlowPrefixes) { il.Emit(OpCodes.Ldloc, controlFlow); il.Emit(OpCodes.Or); } il.Emit(OpCodes.Stloc, controlFlow); return true; } prefixInfo.SetControlFlowImplemented(); return false; } private static void ReturnLogic(ILEmitter il) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) MethodDefinition method = il.IL.Body.Method; HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(method); if (hookTargetInfo.PostfixInfo.FirstPostfixInstructions.FirstOrDefault() == null) { return; } foreach (Instruction firstPostfixInstruction in hookTargetInfo.PostfixInfo.FirstPostfixInstructions) { if (il.IL.Body.Instructions.Contains(firstPostfixInstruction)) { il.Emit(OpCodes.Br, il.DeclareLabelFor(firstPostfixInstruction)); return; } } MonoDetourLogger.Log(patchManager, (LogChannel)8, "While applying HarmonyX Prefixes: No postfix labels found despite postfixes being applied on the method. " + $"Postfixes might not run on method '{il.IL.Body.Method}'. "); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }
Renderer/BepInEx/core/com.github.MonoDetour.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoDetour; using MonoDetour.Bindings.Reorg; using MonoDetour.Bindings.Reorg.MonoModUtils; using MonoDetour.Bindings.Reorg.RuntimeDetour; using MonoDetour.Cil; using MonoDetour.Cil.Analysis; using MonoDetour.DetourTypes; using MonoDetour.DetourTypes.Manipulation; using MonoDetour.Interop.Cecil; using MonoDetour.Interop.MonoModUtils; using MonoDetour.Interop.RuntimeDetour; using MonoDetour.Logging; using MonoDetour.Reflection.Unspeakable; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MonoMod.SourceGen.Internal; using MonoMod.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("com.github.MonoDetour.Interop.HarmonyX")] [assembly: InternalsVisibleTo("MonoDetour.UnitTests")] [assembly: InternalsVisibleTo("0.com.github.MonoDetour.BepInEx.5")] [assembly: InternalsVisibleTo("0.com.github.MonoDetour.BepInEx.6")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Hamunii")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Easy and convenient .NET detouring library, powered by MonoMod.RuntimeDetour.")] [assembly: AssemblyFileVersion("0.7.14.0")] [assembly: AssemblyInformationalVersion("0.7.14+0d55abe3fd0d330206803b376c57bc7135c48257")] [assembly: AssemblyProduct("MonoDetour")] [assembly: AssemblyTitle("MonoDetour")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.14.0")] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { ModuleInitialization.InitializeModule(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Length; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Length; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return ((ICollection<T>)_items).Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { ((ICollection<T>)_items).CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return ((IList<T>)_items).IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T> { object IEnumerator.Current => _item; T IEnumerator<T>.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => 1; T IReadOnlyList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection<T>.Count => 1; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer<T>.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { if (!EqualityComparer<T>.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(_item); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return EqualityComparer<T>.Default.Equals(_item, item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { if (!EqualityComparer<T>.Default.Equals(_item, item)) { return -1; } return 0; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 System { [ExcludeFromCodeCoverage] internal readonly struct Index : IEquatable<Index> { private static class ThrowHelper { [DoesNotReturn] public static void ThrowValueArgumentOutOfRange_NeedNonNegNumException() { throw new ArgumentOutOfRangeException("value", "Non-negative number required."); } } private readonly int _value; public static Index Start => new Index(0); public static Index End => new Index(-1); public int Value { get { if (_value < 0) { return ~_value; } return _value; } } public bool IsFromEnd => _value < 0; [MethodImpl(MethodImplOptions.AggressiveInlining)] public Index(int value, bool fromEnd = false) { if (value < 0) { ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException(); } if (fromEnd) { _value = ~value; } else { _value = value; } } private Index(int value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Index FromStart(int value) { if (value < 0) { ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException(); } return new Index(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Index FromEnd(int value) { if (value < 0) { ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException(); } return new Index(~value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetOffset(int length) { int num = _value; if (IsFromEnd) { num += length + 1; } return num; } public override bool Equals([NotNullWhen(true)] object? value) { if (value is Index) { return _value == ((Index)value)._value; } return false; } public bool Equals(Index other) { return _value == other._value; } public override int GetHashCode() { return _value; } public static implicit operator Index(int value) { return FromStart(value); } public override string ToString() { if (IsFromEnd) { return ToStringFromEnd(); } return ((uint)Value).ToString(); } private string ToStringFromEnd() { return "^" + Value; } } [ExcludeFromCodeCoverage] internal readonly struct Range : IEquatable<Range> { private static class HashHelpers { public static int Combine(int h1, int h2) { uint num = (uint)(h1 << 5) | ((uint)h1 >> 27); return ((int)num + h1) ^ h2; } } private static class ThrowHelper { [DoesNotReturn] public static void ThrowArgumentOutOfRangeException() { throw new ArgumentOutOfRangeException("length"); } } public Index Start { get; } public Index End { get; } public static Range All => Index.Start..Index.End; public Range(Index start, Index end) { Start = start; End = end; } public override bool Equals([NotNullWhen(true)] object? value) { if (value is Range range && range.Start.Equals(Start)) { return range.End.Equals(End); } return false; } public bool Equals(Range other) { if (other.Start.Equals(Start)) { return other.End.Equals(End); } return false; } public override int GetHashCode() { return HashHelpers.Combine(Start.GetHashCode(), End.GetHashCode()); } public override string ToString() { return Start.ToString() + ".." + End; } public static Range StartAt(Index start) { return start..Index.End; } public static Range EndAt(Index end) { return Index.Start..end; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public (int Offset, int Length) GetOffsetAndLength(int length) { Index start = Start; int num = ((!start.IsFromEnd) ? start.Value : (length - start.Value)); Index end = End; int num2 = ((!end.IsFromEnd) ? end.Value : (length - end.Value)); if ((uint)num2 > (uint)length || (uint)num > (uint)num2) { ThrowHelper.ThrowArgumentOutOfRangeException(); } return (num, num2 - num); } } } namespace System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiresPreviewFeaturesAttribute : Attribute { public string? Message { get; } public string? Url { get; set; } public RequiresPreviewFeaturesAttribute() { } public RequiresPreviewFeaturesAttribute(string? message) { Message = message; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)] [ExcludeFromCodeCoverage] internal sealed class AsyncMethodBuilderAttribute : Attribute { public Type BuilderType { get; } public AsyncMethodBuilderAttribute(Type builderType) { BuilderType = builderType; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CollectionBuilderAttribute : Attribute { public Type BuilderType { get; } public string MethodName { get; } public CollectionBuilderAttribute(Type builderType, string methodName) { BuilderType = builderType; MethodName = methodName; } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; set; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute { public string[] Arguments { get; } public InterpolatedStringHandlerArgumentAttribute(string argument) { Arguments = new string[1] { argument }; } public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) { Arguments = arguments; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class OverloadResolutionPriorityAttribute : Attribute { public int Priority { get; } public OverloadResolutionPriorityAttribute(int priority) { Priority = priority; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)] [ExcludeFromCodeCoverage] internal sealed class ParamCollectionAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiredMemberAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal sealed class RequiresLocationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ConstantExpectedAttribute : Attribute { public object? Min { get; set; } public object? Max { get; set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ExperimentalAttribute : Attribute { public string DiagnosticId { get; } public string? UrlFormat { get; set; } public ExperimentalAttribute(string diagnosticId) { DiagnosticId = diagnosticId; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class StringSyntaxAttribute : Attribute { public const string CompositeFormat = "CompositeFormat"; public const string DateOnlyFormat = "DateOnlyFormat"; public const string DateTimeFormat = "DateTimeFormat"; public const string EnumFormat = "EnumFormat"; public const string GuidFormat = "GuidFormat"; public const string Json = "Json"; public const string NumericFormat = "NumericFormat"; public const string Regex = "Regex"; public const string TimeOnlyFormat = "TimeOnlyFormat"; public const string TimeSpanFormat = "TimeSpanFormat"; public const string Uri = "Uri"; public const string Xml = "Xml"; public string Syntax { get; } public object?[] Arguments { get; } public StringSyntaxAttribute(string syntax) { Syntax = syntax; Arguments = new object[0]; } public StringSyntaxAttribute(string syntax, params object?[] arguments) { Syntax = syntax; Arguments = arguments; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class UnscopedRefAttribute : Attribute { } } namespace MonoMod.SourceGen.Internal { internal sealed class CodeBuilder { private readonly StringBuilder sb; private readonly char indentChar = ' '; private readonly int indentAmount; private int indentLevel; private bool didWriteIndent; public CodeBuilder(StringBuilder sb, int indentAmount = 4) { this.sb = sb; this.indentAmount = indentAmount; } public CodeBuilder WriteHeader() { WriteLine("// <auto-generated />"); WriteLine("#pragma warning disable"); WriteLine("#nullable enable"); WriteLine("using PrefixDetour = global::MonoDetour.DetourTypes.PrefixDetour;"); WriteLine("using PostfixDetour = global::MonoDetour.DetourTypes.PostfixDetour;"); WriteLine("using ILHookDetour = global::MonoDetour.DetourTypes.ILHookDetour;"); return this; } public CodeBuilder OpenBlock() { return WriteLine('{').IncreaseIndent(); } public CodeBuilder CloseBlock() { return DecreaseIndent().WriteLine('}'); } public CodeBuilder IncreaseIndent() { indentLevel++; return this; } public CodeBuilder DecreaseIndent() { indentLevel--; return this; } public CodeBuilder RemoveIndent() { indentLevel = 0; return this; } private void WriteIndentIfNeeded() { if (!didWriteIndent) { if (indentLevel > 0) { sb.Append(indentChar, indentLevel * indentAmount); } didWriteIndent = true; } } public CodeBuilder Write(int i) { return Write(i.ToString(CultureInfo.InvariantCulture)); } public CodeBuilder Write(string? s) { WriteIndentIfNeeded(); sb.Append(s); return this; } public CodeBuilder Write(char c) { WriteIndentIfNeeded(); sb.Append(c); return this; } public CodeBuilder WriteLine(int i) { return WriteLine(i.ToString(CultureInfo.InvariantCulture)); } public CodeBuilder WriteLine(string s) { WriteIndentIfNeeded(); sb.AppendLine(s); didWriteIndent = false; return this; } public CodeBuilder WriteLine(char c) { WriteIndentIfNeeded(); sb.Append(c).AppendLine(); didWriteIndent = false; return this; } public CodeBuilder WriteLine() { sb.AppendLine(); didWriteIndent = false; return this; } public override string ToString() { return sb.ToString(); } } } namespace MonoDetour { internal static class Helpers { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T ThrowIfNull<T>([NotNull] T? argument, [CallerArgumentExpression("argument")] string name = "") { if (argument == null) { ThrowArgumentNull(name); } return argument; } [DoesNotReturn] private static void ThrowArgumentNull(string argName) { throw new ArgumentNullException(argName); } } public interface IMonoDetourHook : IReadOnlyMonoDetourHook, IDisposable { void Apply(); void Undo(); } public interface IReadOnlyMonoDetourHook { MethodBase Target { get; } MethodBase Manipulator { get; } Delegate? ManipulatorDelegate { get; } MonoDetourManager Owner { get; } MonoDetourConfig? Config { get; } bool IsValid { get; } bool IsApplied { get; } } internal static class ModuleInitialization { private static bool isInitialized; [ModuleInitializer] internal static void InitializeModule() { string environmentVariable = Environment.GetEnvironmentVariable("MONODETOUR_MANUAL_INIT"); if (!(environmentVariable == "1")) { Initialize(); } } internal static void Initialize() { if (!isInitialized) { isInitialized = true; MonoDetourLogger.ParseEnvironmentVariables(); ILHookInstructionILLabelCastFixes.InitHook(); ILHookDMDManipulation.InitHook(); LegacyILHookAntiExploder.InitHook(); } } } public class MonoDetourConfig : IMonoDetourConfig { public string? OverrideId { get; } public int Priority { get; } public IEnumerable<string> Before { get; } public IEnumerable<string> After { get; } public MonoDetourConfig(int priority = 0, IEnumerable<string>? before = null, IEnumerable<string>? after = null, string? overrideId = null) { Priority = priority; Before = AsFixedSize(before ?? Array.Empty<string>()); After = AsFixedSize(after ?? Array.Empty<string>()); OverrideId = overrideId; } private static IEnumerable<string> AsFixedSize(IEnumerable<string> enumerable) { if (enumerable == Enumerable.Empty<string>()) { return enumerable; } if (enumerable is ICollection<string>) { return enumerable; } return enumerable.ToArray(); } public MonoDetourConfig WithPriority(int priority) { return new MonoDetourConfig(priority, Before, After, OverrideId); } public MonoDetourConfig WithBefore(IEnumerable<string> before) { return new MonoDetourConfig(Priority, before, After, OverrideId); } public MonoDetourConfig WithBefore(params string[] before) { return WithBefore(before.AsEnumerable()); } public MonoDetourConfig WithAfter(IEnumerable<string> after) { return new MonoDetourConfig(Priority, Before, after, OverrideId); } public MonoDetourConfig WithAfter(params string[] after) { return WithAfter(after.AsEnumerable()); } public MonoDetourConfig AddBefore(IEnumerable<string> before) { return WithBefore(Before.Concat(before)); } public MonoDetourConfig AddBefore(params string[] before) { return AddBefore(before.AsEnumerable()); } public MonoDetourConfig AddAfter(IEnumerable<string> after) { return WithAfter(After.Concat(after)); } public MonoDetourConfig AddAfter(params string[] after) { return AddAfter(after.AsEnumerable()); } } public class MonoDetourHook : IMonoDetourHook, IReadOnlyMonoDetourHook, IDisposable { private static readonly Dictionary<MethodBase, List<IReadOnlyMonoDetourHook>> s_TargetToHooks = new Dictionary<MethodBase, List<IReadOnlyMonoDetourHook>>(); private static readonly ConditionalWeakTable<Manipulator, MonoDetourHook> s_ManipulatorToHook = new ConditionalWeakTable<Manipulator, MonoDetourHook>(); private static readonly object tableLock = new object(); private bool isDisposed; public MethodBase Target { get; } public MethodBase Manipulator { get; } public Delegate? ManipulatorDelegate { get; } public MonoDetourManager Owner { get; } public MonoDetourConfig? Config { get; } public ILHook Applier { get; } public Type ApplierType { get; } public bool IsValid => Applier.IsValid; public bool IsApplied => Applier.IsApplied; private MonoDetourHook(MethodBase target, MethodBase manipulator, Delegate? manipulatorDelegate, Type applierType, MonoDetourManager owner, MonoDetourConfig? config = null, bool applyByDefault = true) { //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown Target = Helpers.ThrowIfNull(target, "target"); Manipulator = Helpers.ThrowIfNull(manipulator, "manipulator"); Owner = Helpers.ThrowIfNull(owner, "owner"); ManipulatorDelegate = manipulatorDelegate; ApplierType = applierType; Config = config; IMonoDetourHookApplier monoDetourHookApplier = (IMonoDetourHookApplier)Activator.CreateInstance(applierType); monoDetourHookApplier.Hook = this; owner.Hooks.Add(this); Type declaringType = Manipulator.DeclaringType; string text = (((object)declaringType != null) ? (declaringType.FullName + "." + Manipulator.Name) : Manipulator.Name); Type declaringType2 = Target.DeclaringType; string text2 = (((object)declaringType2 != null) ? (declaringType2.FullName + "." + Target.Name) : Target.Name); string text3; if (ApplierType.Name.EndsWith("Detour", StringComparison.Ordinal)) { string name = ApplierType.Name; text3 = name.Substring(0, name.Length - 6); } else { text3 = ApplierType.Name; } string text4 = (applyByDefault ? "Applied" : "Constructed"); owner.Log(MonoDetourLogger.LogChannel.Info, text4 + " " + text3 + " '" + text + "' targeting '" + text2 + "'"); Manipulator val = new Manipulator(monoDetourHookApplier.ApplierManipulator); Applier = ProxyILHookConstructor.ConstructILHook(target, val, (IMonoDetourConfig?)(object)config, owner.Id); lock (tableLock) { s_ManipulatorToHook.Add(val, this); if (s_TargetToHooks.TryGetValue(Target, out List<IReadOnlyMonoDetourHook> value)) { value.Add(this); } else { s_TargetToHooks.Add(Target, new List<IReadOnlyMonoDetourHook>(1) { this }); } } if (applyByDefault) { Applier.Apply(); } } public static MonoDetourHook Create<TApplier>(MethodBase target, Delegate manipulator, MonoDetourManager owner, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier { return new MonoDetourHook(target, Helpers.ThrowIfNull(manipulator, "manipulator").Method, manipulator, typeof(TApplier), owner, config, applyByDefault); } public static MonoDetourHook Create<TApplier>(MethodBase target, MethodBase manipulator, MonoDetourManager owner, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier { return new MonoDetourHook(target, manipulator, null, typeof(TApplier), owner, config, applyByDefault); } public static bool TryGetFrom(Manipulator key, [NotNullWhen(true)] out MonoDetourHook? monoDetourHook) { return s_ManipulatorToHook.TryGetValue(key, out monoDetourHook); } internal static bool HasActiveControlFlowMonoDetourHooks(MethodBase target, out int count) { count = 0; if (!s_TargetToHooks.TryGetValue(target, out List<IReadOnlyMonoDetourHook> value)) { return false; } foreach (IReadOnlyMonoDetourHook item in value) { if (item.IsApplied && item.ModifiesControlFlow()) { count++; } } return count > 0; } public void Apply() { Applier.Apply(); } public void Undo() { Applier.Undo(); } public void Dispose() { if (!isDisposed) { Applier.Dispose(); GC.SuppressFinalize(this); isDisposed = true; } } } [AttributeUsage(AttributeTargets.Method, Inherited = false)] public class MonoDetourHookInitializeAttribute : Attribute { } public class MonoDetourManager : IDisposable, IMonoDetourLogSource { private bool isDisposed; public string Id { get; } = Helpers.ThrowIfNull(id, "id"); public MonoDetourLogger.LogChannel LogFilter { get; set; } = MonoDetourLogger.LogChannel.Warning | MonoDetourLogger.LogChannel.Error; public List<IMonoDetourHook> Hooks { get; } = new List<IMonoDetourHook>(); public event Action<IReadOnlyMonoDetourHook>? OnHookThrew; public MonoDetourManager(string id) { } private void ThrowIfDisposed() { if (!isDisposed) { return; } throw new ObjectDisposedException(ToString()); } internal bool CallOnHookThrew(IReadOnlyMonoDetourHook hook) { if (this.OnHookThrew == null) { return false; } this.OnHookThrew(hook); return true; } public static void InvokeHookInitializers(Assembly assembly, bool reportUnloadableTypes = true) { Type[] typesFromAssembly = ReflectionUtils.GetTypesFromAssembly(assembly, reportUnloadableTypes); foreach (Type type in typesFromAssembly) { if (ReflectionUtils.HasCustomAttribute<IMonoDetourTargets>(type, reportUnloadableTypes)) { InvokeHookInitializers(type, reportUnloadableTypes); } } } public static void InvokeHookInitializers(Assembly assembly) { InvokeHookInitializers(assembly, reportUnloadableTypes: true); } public static void InvokeHookInitializers(Type type, bool reportUnloadableTypes = true) { MethodInfo[] methods = type.GetMethods((BindingFlags)(-1)); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (ReflectionUtils.HasCustomAttribute<MonoDetourHookInitializeAttribute>(methodInfo, reportUnloadableTypes)) { methodInfo.Invoke(null, null); } } } public static void InvokeHookInitializers(Type type) { InvokeHookInitializers(type, reportUnloadableTypes: true); } public void ApplyHooks() { Hooks.ForEach(delegate(IMonoDetourHook x) { x.Apply(); }); } public void UndoHooks() { Hooks.ForEach(delegate(IMonoDetourHook x) { x.Undo(); }); } public void DisposeHooks() { Hooks.ForEach(delegate(IMonoDetourHook x) { x.Dispose(); }); Hooks.Clear(); } public MonoDetourHook ILHook(Delegate target, ILManipulationInfo.Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true) { return ILHook(target.Method, manipulator, config, applyByDefault); } public MonoDetourHook ILHook(MethodBase target, ILManipulationInfo.Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true) { return Hook<ILHookDetour>(target, manipulator, config, applyByDefault); } public MonoDetourHook Hook<TApplier>(Delegate target, Delegate manipulator, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier { return Hook<TApplier>(target.Method, manipulator, config, applyByDefault); } public MonoDetourHook Hook<TApplier>(MethodBase target, Delegate manipulator, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier { ThrowIfDisposed(); return MonoDetourHook.Create<TApplier>(target, manipulator, this, config, applyByDefault); } public MonoDetourHook Hook<TApplier>(MethodBase target, MethodBase manipulator, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier { ThrowIfDisposed(); return MonoDetourHook.Create<TApplier>(target, manipulator, this, config, applyByDefault); } public void Dispose() { if (!isDisposed) { DisposeHooks(); GC.SuppressFinalize(this); isDisposed = true; } } } public interface IMonoDetourTargets { } internal static class ReflectionUtils { public static bool HasCustomAttribute<T>(MemberInfo member, bool reportUnloadableTypes) { IEnumerable<Attribute> customAttributes; try { customAttributes = member.GetCustomAttributes(); } catch (TypeLoadException) { if (!reportUnloadableTypes) { return false; } bool flag = false; foreach (CustomAttributeData customAttribute in member.CustomAttributes) { try { if (typeof(T).IsAssignableFrom(customAttribute.AttributeType)) { flag = true; break; } } catch (TypeLoadException) { } } if (flag) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Warning, "[InvokeHookInitializers]" + $" Skipping '{member}' ({member.Module.Assembly.GetName().Name}) due to unloadable type." + " Use 'reportUnloadableTypes: false' to hide this message."); } return false; } foreach (Attribute item in customAttributes) { if (item is T) { return true; } } return false; } public static Type[] GetTypesFromAssembly(Assembly assembly, bool reportUnloadableTypes) { try { Type[] types = assembly.GetTypes(); for (int i = 0; i < types.Length; i++) { if (types[i] == null) { ReportUnloadableAssemblyTypes(assembly, reportUnloadableTypes); return types.Where((Type type) => (object)type != null).ToArray(); } } return types; } catch (ReflectionTypeLoadException ex) { ReportUnloadableAssemblyTypes(assembly, reportUnloadableTypes); return ex.Types.Where((Type type) => (object)type != null).ToArray(); } } private static void ReportUnloadableAssemblyTypes(Assembly assembly, bool reportUnloadableTypes) { if (reportUnloadableTypes) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Warning, "[InvokeHookInitializers] Unloadable type(s) found in '" + assembly.GetName().Name + "'. If such a type has hook initializers, they will be skipped. Use 'reportUnloadableTypes: false' to hide this message."); } } } } namespace MonoDetour.Logging { internal interface IMonoDetourLogSource { MonoDetourLogger.LogChannel LogFilter { get; set; } } public static class MonoDetourLogger { internal delegate void LogReceiver(LogChannel channel, string message); [Flags] public enum LogChannel { None = 0, Info = 2, IL = 4, Warning = 8, Error = 0x10 } private static LogChannel GlobalFilter { get; set; } = LogChannel.Warning | LogChannel.Error; private static LogChannel OverrideFilter { get; set; } = LogChannel.None; internal static event LogReceiver? OnLog; private static string LogChannelToString(LogChannel channel) { return channel switch { LogChannel.None => "None ", LogChannel.Info => "Info ", LogChannel.IL => "IL ", LogChannel.Warning => "Warning", LogChannel.Error => "Error ", _ => throw new NotSupportedException(), }; } internal static void ParseEnvironmentVariables() { string text = "MONODETOUR_LOG_OVERRIDE"; string environmentVariable = Environment.GetEnvironmentVariable(text); if (environmentVariable == null) { return; } string[] array = environmentVariable.Split(new char[1] { ':' }); string[] array2 = array; foreach (string text2 in array2) { if (!Enum.TryParse<LogChannel>(text2, ignoreCase: true, out var result)) { Log(LogChannel.Error, "Failed to parse value '" + text2 + "' in '" + environmentVariable + "' from environment variable '" + text + "'"); } else { OverrideFilter |= result; } } } internal static bool IsEnabledFor(LogChannel caller, LogChannel channel) { return ((caller | OverrideFilter) & channel) != 0; } internal static void Log(this MonoDetourManager caller, LogChannel channel, Func<string> message) { if (IsEnabledFor(caller.LogFilter, channel)) { string message2 = "[" + caller.Id + "] " + message(); if (MonoDetourLogger.OnLog == null) { DefaultLog(channel, message2); } else { MonoDetourLogger.OnLog(channel, message2); } } } internal static void Log(this IMonoDetourLogSource caller, LogChannel channel, Func<string> message) { if (IsEnabledFor(caller.LogFilter, channel)) { if (MonoDetourLogger.OnLog == null) { DefaultLog(channel, message()); } else { MonoDetourLogger.OnLog(channel, message()); } } } internal static void Log(LogChannel channel, Func<string> message) { if (IsEnabledFor(GlobalFilter, channel)) { if (MonoDetourLogger.OnLog == null) { DefaultLog(channel, message()); } else { MonoDetourLogger.OnLog(channel, message()); } } } internal static void Log(this MonoDetourManager caller, LogChannel channel, string message) { if (IsEnabledFor(caller.LogFilter, channel)) { message = "[" + caller.Id + "] " + message; if (MonoDetourLogger.OnLog == null) { DefaultLog(channel, message); } else { MonoDetourLogger.OnLog(channel, message); } } } internal static void Log(this IMonoDetourLogSource caller, LogChannel channel, string message) { if (IsEnabledFor(caller.LogFilter, channel)) { if (MonoDetourLogger.OnLog == null) { DefaultLog(channel, message); } else { MonoDetourLogger.OnLog(channel, message); } } } internal static void Log(LogChannel channel, string message) { if (IsEnabledFor(GlobalFilter, channel)) { if (MonoDetourLogger.OnLog == null) { DefaultLog(channel, message); } else { MonoDetourLogger.OnLog(channel, message); } } } private static void DefaultLog(LogChannel channel, string message) { LogWithChannel("[" + LogChannelToString(channel) + ": MonoDetour] " + message, channel); } private static void LogWithChannel(string message, LogChannel channel) { ConsoleColor foregroundColor = channel switch { LogChannel.Warning => ConsoleColor.Yellow, LogChannel.Error => ConsoleColor.Red, _ => Console.ForegroundColor, }; ConsoleColor foregroundColor2 = Console.ForegroundColor; Console.ForegroundColor = foregroundColor; if (channel == LogChannel.Error && MonoModVersion.IsReorg) { Console.Error.WriteLine(message); } else { Console.Out.WriteLine(message); } Console.ForegroundColor = foregroundColor2; } } } namespace MonoDetour.Interop.RuntimeDetour { internal static class ILHookDMDManipulation { [CompilerGenerated] private static class <>O { public static Manipulator <0>__GetDMDBeforeManipulation; public static ILManipulationInfo.Manipulator <1>__TryCatchAnalyzeCompilationReorg; public static ILManipulationInfo.Manipulator <2>__TryCatchAnalyzeCompilationLegacy; public static Func<DynamicMethodDefinition, DynamicMethodDefinition> <3>__BorrowDMD; public static Action<InvalidProgramException, DynamicMethodDefinition> <4>__AnalyzeMethod; public static Func<DynamicMethodDefinition, MethodBody> <5>__GetMethodBody; public static Action<InvalidProgramException, MethodBody> <6>__AnalyzeMethodBody; } internal static readonly ConditionalWeakTable<MethodDefinition, ReadOnlyCollection<Instruction>> s_MethodDefinitionToOriginalInstructions = new ConditionalWeakTable<MethodDefinition, ReadOnlyCollection<Instruction>>(); internal static readonly ConditionalWeakTable<MethodDefinition, MethodBase> s_MethodDefinitionToOriginalMethod = new ConditionalWeakTable<MethodDefinition, MethodBase>(); private static ConstructorInfo dmdConstructor = null; private static ILHook getDmdBeforeManipulationHook = null; private static readonly MonoDetourManager m = new MonoDetourManager(typeof(ILHookDMDManipulation).Assembly.GetName().Name); internal static MethodInfo? legacyContextRefreshMethod; private static bool initialized; internal static void InitHook() { if (initialized) { return; } initialized = true; try { if (MonoModVersion.IsReorg) { InitHookReorg(); } else { InitHookLegacy(); } } catch (Exception innerException) { throw new NotSupportedException("MonoDetour doesn't seem to support this MonoMod version, please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'", innerException); } } private static void InitHookReorg() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown dmdConstructor = typeof(DynamicMethodDefinition).GetConstructor(new Type[1] { typeof(DynamicMethodDefinition) }) ?? throw new NullReferenceException("DMD constructor not found."); Type type = Type.GetType("MonoMod.RuntimeDetour.DetourManager+ManagedDetourState, MonoMod.RuntimeDetour") ?? throw new NullReferenceException("Type 'MonoMod.RuntimeDetour.DetourManager+ManagedDetourState, MonoMod.RuntimeDetour' not found."); MethodInfo methodInfo = type.GetMethod("UpdateEndOfChain", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new NullReferenceException("Method 'UpdateEndOfChain' not found."); object obj = <>O.<0>__GetDMDBeforeManipulation; if (obj == null) { Manipulator val = GetDMDBeforeManipulation; <>O.<0>__GetDMDBeforeManipulation = val; obj = (object)val; } getDmdBeforeManipulationHook = new ILHook((MethodBase)methodInfo, (Manipulator)obj); m.ILHook(methodInfo, TryCatchAnalyzeCompilationReorg); } private static void InitHookLegacy() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown dmdConstructor = typeof(DynamicMethodDefinition).GetConstructor(new Type[1] { typeof(MethodBase) }) ?? throw new NullReferenceException("DMD constructor not found."); Type type = Type.GetType("MonoMod.RuntimeDetour.ILHook+Context, MonoMod.RuntimeDetour") ?? throw new NullReferenceException("Type 'MonoMod.RuntimeDetour.ILHook+Context, MonoMod.RuntimeDetour' not found."); legacyContextRefreshMethod = type.GetMethod("Refresh") ?? throw new NullReferenceException("Method 'Refresh' not found."); MethodInfo? methodInfo = legacyContextRefreshMethod; object obj = <>O.<0>__GetDMDBeforeManipulation; if (obj == null) { Manipulator val = GetDMDBeforeManipulation; <>O.<0>__GetDMDBeforeManipulation = val; obj = (object)val; } getDmdBeforeManipulationHook = new ILHook((MethodBase)methodInfo, (Manipulator)obj); m.ILHook(legacyContextRefreshMethod, TryCatchAnalyzeCompilationLegacy); } private static void GetDMDBeforeManipulation(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchNewobj(x, (MethodBase)dmdConstructor) })) { throw new NullReferenceException("DMD construction not found. " + il.ToAnalyzedString()); } val.EmitDelegate<Func<DynamicMethodDefinition, DynamicMethodDefinition>>((Func<DynamicMethodDefinition, DynamicMethodDefinition>)BorrowDMD); } private static DynamicMethodDefinition BorrowDMD(DynamicMethodDefinition dmd) { MethodDefinition definition = dmd.Definition; ReadOnlyCollection<Instruction> value = ((IEnumerable<Instruction>)definition.Body.Instructions).ToList().AsReadOnly(); s_MethodDefinitionToOriginalInstructions.Add(definition, value); s_MethodDefinitionToOriginalMethod.Add(definition, dmd.OriginalMethod); return dmd; } private static void TryCatchAnalyzeCompilationReorg(ILManipulationInfo info) { //IL_0163: Unknown result type (might be due to invalid IL or missing references) ILWeaver w = new ILWeaver(info); int localIndexDmd = 0; Instruction tryStart = null; MethodReference val3 = default(MethodReference); int num2 = default(int); MethodReference val2 = default(MethodReference); int num = default(int); MethodReference val = default(MethodReference); w.MatchRelaxed((Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref localIndexDmd), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val3), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num2), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val2) && w.SetInstructionTo(ref tryStart, x), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val) && w.SetCurrentTo(x)).Extract(out ILWeaverResult result); if (!result.IsValid) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "MonoDetour's invalid IL analysis failed to be applied. Please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'"); MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, result.FailureMessage); return; } w.HandlerCreateCatch(typeof(InvalidProgramException), out WeaverExceptionCatchHandler handler); w.HandlerSetTryStart(tryStart, handler); w.HandlerSetTryEnd(w.Current, handler); w.InsertAfterCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2] { w.Create(OpCodes.Ldloc, localIndexDmd), w.CreateCall(new Action<InvalidProgramException, DynamicMethodDefinition>(AnalyzeMethod)) })); w.HandlerSetHandlerEnd(w.Current, handler); w.HandlerApply(handler); } private static void TryCatchAnalyzeCompilationLegacy(ILManipulationInfo info) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) ILWeaver w = new ILWeaver(info); int localIndexDmd = 0; int num4 = default(int); w.MatchRelaxed((Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref localIndexDmd) && w.SetCurrentTo(x), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<DynamicMethodDefinition>(x, "Generate"), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num4)).Extract(out ILWeaverResult result); if (!result.IsValid) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "MonoDetour's invalid IL analysis failed to be applied. Please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'"); MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, result.FailureMessage); return; } VariableDefinition variable = w.DeclareVariable(typeof(MethodBody)); w.InsertAfterCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Dup), w.CreateCall(new Func<DynamicMethodDefinition, MethodBody>(GetMethodBody)), w.Create(OpCodes.Stloc, variable) })); Instruction tryStart = null; int num3 = default(int); int num2 = default(int); FieldReference val4 = default(FieldReference); int num = default(int); FieldReference val3 = default(FieldReference); MethodReference val2 = default(MethodReference); FieldReference val = default(FieldReference); w.MatchRelaxed((Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num3) && w.SetInstructionTo(ref tryStart, x), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num2), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val4), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchLdsflda(x, ref val3), (Instruction x) => ILPatternMatchingExt.MatchNewobj(x, ref val2), (Instruction x) => ILPatternMatchingExt.MatchStfld(x, ref val) && w.SetCurrentTo(x)).Extract(out result); if (!result.IsValid) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "MonoDetour's invalid IL analysis failed to be applied. Please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'"); MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, result.FailureMessage); return; } w.HandlerCreateCatch(typeof(InvalidProgramException), out WeaverExceptionCatchHandler handler); w.HandlerSetTryStart(tryStart, handler); w.HandlerSetTryEnd(w.Current, handler); w.InsertAfterCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2] { w.Create(OpCodes.Ldloc, variable), w.CreateCall(new Action<InvalidProgramException, MethodBody>(AnalyzeMethodBody)) })); w.HandlerSetHandlerEnd(w.Current, handler); w.HandlerApply(handler); } private static MethodBody GetMethodBody(DynamicMethodDefinition dmd) { return dmd.Definition.Body; } private static void AnalyzeMethod(InvalidProgramException ex, DynamicMethodDefinition dmd) { AnalyzeMethodBody(ex, dmd.Definition.Body); } private static void AnalyzeMethodBody(InvalidProgramException ex, MethodBody body) { string message; try { message = body.CreateInformationalSnapshotJIT().AnnotateErrors().ToErrorMessageString(); } catch (Exception ex2) { throw new Exception("MonoDetour failed to analyze invalid program: " + ex2, ex); } throw new InvalidProgramException(message, ex); } } internal static class LegacyILHookAntiExploder { private static readonly MonoDetourManager antiExploderManager = new MonoDetourManager(typeof(LegacyILHookAntiExploder).Assembly.GetName().Name); private static bool initialized; internal static void InitHook() { if (initialized) { return; } initialized = true; try { if (!MonoModVersion.IsReorg) { InitHookLegacy(); } } catch (Exception innerException) { throw new NotSupportedException("MonoDetour doesn't seem to support this MonoMod version, please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'", innerException); } } private static void InitHookLegacy() { Type typeFromHandle = typeof(ILHook); MethodInfo target = typeFromHandle.GetMethod("Apply") ?? throw new NullReferenceException("Method 'Apply' not found."); if ((object)ILHookDMDManipulation.legacyContextRefreshMethod == null) { throw new NullReferenceException("ILHook.Context.Refresh is null"); } antiExploderManager.ILHook(target, TryCatchILHookApply); } private static void TryCatchILHookApply(ILManipulationInfo info) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) ILWeaver w = new ILWeaver(info); ILWeaverResult iLWeaverResult = w.MatchRelaxed((Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, (MethodBase)ILHookDMDManipulation.legacyContextRefreshMethod) && w.SetCurrentTo(x)); if (!iLWeaverResult.IsValid) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "MonoDetour's ILHook.Apply anti-exploder failed to be applied. Please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'"); MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, iLWeaverResult.FailureMessage); } else { w.HandlerWrapTryCatchStackSizeNonZeroOnCurrent(null, new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2] { w.Create(OpCodes.Ldarg_0), w.CreateCall(new Action<Exception, ILHook>(UndoFailedILHook)) })); } } private static void UndoFailedILHook(Exception ex, ILHook ilHook) { if (!ilHook.IsValid) { return; } try { ilHook.Undo(); } catch (Exception ex2) { throw new Exception("Undoing ILHook failed: " + ex2, ex); } throw new Exception("ILHook failed to apply and was disabled.", ex); } } internal static class ProxyILHookConstructor { private static readonly ILHook detourContextHook; static ProxyILHookConstructor() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if (!MonoModVersion.IsReorg) { detourContextHook = new ILHook((MethodBase)new Func<DetourContext>(DetourContextGetCurrent).Method, new Manipulator(ILHook_DetourContextGetCurrent)); } } private static void ILHook_DetourContextGetCurrent(ILContext il) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) MethodInfo methodInfo = typeof(DetourContext).GetProperty("Current", BindingFlags.Static | BindingFlags.NonPublic).GetGetMethod(nonPublic: true) ?? throw new NullReferenceException("Couldn't find 'DetourContext.get_Current'."); ILCursor val = new ILCursor(il); val.Body.Instructions.Clear(); val.Emit(OpCodes.Call, (MethodBase)methodInfo); val.Emit(OpCodes.Ret); } [MethodImpl(MethodImplOptions.NoInlining)] private static DetourContext DetourContextGetCurrent() { throw new NotImplementedException("DetourContextGetCurrent wasn't initialized."); } internal static ILHook ConstructILHook(MethodBase target, Manipulator manipulator, IMonoDetourConfig? config, string id) { if (MonoModVersion.IsReorg) { return ReorgILHook.ConstructILHook(target, manipulator, config, id); } return ConstructLegacyILHook(target, manipulator, config, id); } [MethodImpl(MethodImplOptions.NoInlining)] private static ILHook ConstructLegacyILHook(MethodBase target, Manipulator manipulator, IMonoDetourConfig? config, string id) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown ILHookConfig val2; if (config == null) { DetourContext val = DetourContextGetCurrent(); if (val != null) { ILHookConfig iLHookConfig = val.ILHookConfig; if (!iLHookConfig.ManualApply) { val2 = iLHookConfig; val2.ManualApply = true; ILHookConfig val3 = val2; return new ILHook(target, manipulator, val3); } return new ILHook(target, manipulator, iLHookConfig); } return new ILHook(target, manipulator, new ILHookConfig { ID = id, ManualApply = true }); } val2 = default(ILHookConfig); val2.ID = config.OverrideId ?? id; val2.Priority = config.Priority; val2.Before = config.Before; val2.After = config.After; val2.ManualApply = true; ILHookConfig val4 = val2; return new ILHook(target, manipulator, val4); } } } namespace MonoDetour.Interop.MonoModUtils { internal static class InteropFastDelegateInvokers { private static MethodInfo? getDelegateInvoker; internal static (MethodInfo Invoker, Type Delegate)? GetDelegateInvoker(ILContext il, Type delegateType) { if (!MonoModVersion.IsReorg) { return LegacyGetDelegateInvoker(il, delegateType); } return ReorgFastDelegateInvokers.GetDelegateInvoker(delegateType); } [MethodImpl(MethodImplOptions.NoInlining)] private static (MethodInfo Invoker, Type Delegate)? LegacyGetDelegateInvoker(ILContext il, Type delegateType) { IILReferenceBag referenceBag = il.ReferenceBag; RuntimeILReferenceBag val = (RuntimeILReferenceBag)(object)((referenceBag is RuntimeILReferenceBag) ? referenceBag : null); if (val == null) { throw new Exception("ReferenceBag is not RuntimeILReferenceBag! If you are not in an ILHook managed by MonoMod, do not use this method."); } if ((object)getDelegateInvoker == null) { Type typeFromHandle = typeof(RuntimeILReferenceBag); MethodInfo method = typeFromHandle.GetMethod("GetDelegateInvoker"); getDelegateInvoker = method; } MethodInfo methodInfo = getDelegateInvoker.MakeGenericMethod(delegateType); MethodInfo methodInfo2 = (MethodInfo)methodInfo.Invoke(val, Array.Empty<object>()); if ((object)methodInfo2 == null) { return null; } return (methodInfo2, delegateType); } } internal static class InteropILContext { [CompilerGenerated] private sealed class <LegacyGetReference>d__4 : IEnumerable<Instruction>, IEnumerable, IEnumerator<Instruction>, IEnumerator, IDisposable { private int <>1__state; private Instruction <>2__current; private int <>l__initialThreadId; private ILContext context; public ILContext <>3__context; private Type t; public Type <>3__t; private ILWeaver w; public ILWeaver <>3__w; private int id; public int <>3__id; private MethodInfo <delegateInvoker>5__2; Instruction? IEnumerator<Instruction>.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LegacyGetReference>d__4(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <delegateInvoker>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; IILReferenceBag referenceBag = context.ReferenceBag; RuntimeILReferenceBag val = (RuntimeILReferenceBag)(object)((referenceBag is RuntimeILReferenceBag) ? referenceBag : null); if (val == null) { throw new Exception("ReferenceBag is not RuntimeILReferenceBag! If you are not in an ILHook managed by MonoMod, do not use this method."); } if ((object)getGetter == null) { Type typeFromHandle = typeof(RuntimeILReferenceBag); MethodInfo method = typeFromHandle.GetMethod("GetGetter"); getGetter = method; } MethodInfo methodInfo = getGetter.MakeGenericMethod(t); <delegateInvoker>5__2 = (MethodInfo)methodInfo.Invoke(val, Array.Empty<object>()); <>2__current = w.Create(OpCodes.Ldc_I4, id); <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = w.Create(OpCodes.Call, (MethodBase)<delegateInvoker>5__2); <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<Instruction> IEnumerable<Instruction>.GetEnumerator() { <LegacyGetReference>d__4 <LegacyGetReference>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <LegacyGetReference>d__ = this; } else { <LegacyGetReference>d__ = new <LegacyGetReference>d__4(0); } <LegacyGetReference>d__.t = <>3__t; <LegacyGetReference>d__.context = <>3__context; <LegacyGetReference>d__.w = <>3__w; <LegacyGetReference>d__.id = <>3__id; return <LegacyGetReference>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Instruction>)this).GetEnumerator(); } } private static MethodInfo? getGetter; internal static int InteropAddReference<T>(this ILContext context, in T? t) { if (!MonoModVersion.IsReorg) { return LegacyAddReference(context, t); } return ReorgILContext.AddReference<T>(context, ref t); } [MethodImpl(MethodImplOptions.NoInlining)] private static int LegacyAddReference<T>(ILContext context, T? t) { return context.AddReference<T>(t); } internal static IEnumerable<Instruction> InteropGetReference(this ILContext context, ILWeaver weaver, int id, Delegate @delegate) { if (!MonoModVersion.IsReorg) { return LegacyGetReference(@delegate.GetType(), context, weaver, id); } return ReorgILContext.GetReference(@delegate.GetType(), context, id); } [MethodImpl(MethodImplOptions.NoInlining)] [IteratorStateMachine(typeof(<LegacyGetReference>d__4))] private static IEnumerable<Instruction> LegacyGetReference(Type t, ILContext context, ILWeaver w, int id) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LegacyGetReference>d__4(-2) { <>3__t = t, <>3__context = context, <>3__w = w, <>3__id = id }; } } internal static class InteropILCursor { internal static int InteropEmitReference<T>(this ILCursor cursor, in T? t) { if (!MonoModVersion.IsReorg) { return LegacyEmitReference(cursor, t); } return ReorgILCursor.EmitReference<T>(cursor, ref t); } [MethodImpl(MethodImplOptions.NoInlining)] private static int LegacyEmitReference<T>(ILCursor cursor, T? t) { return cursor.EmitReference<T>(t); } internal static int InteropEmitReferenceBefore<T>(this ILContext context, Instruction target, in T? t) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new ILCursor(context).Goto(target, (MoveType)0, false).InteropEmitReference(in t); } internal static void EmitGetReferenceBefore<T>(ILContext context, Instruction target, int id) where T : Delegate { //IL_0001: Unknown result type (might be due to invalid IL or missing references) new ILCursor(context).Goto(target, (MoveType)0, false).EmitGetReference<T>(id); } internal static int EmitDelegateBefore<T>(ILContext context, Instruction target, in T cb) where T : Delegate { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new ILCursor(context).Goto(target, (MoveType)0, false).EmitDelegate<T>(cb); } } internal static class InteropILLabel { internal static Instruction? InteropGetTarget(this ILLabel label) { if (!MonoModVersion.IsReorg) { return LegacyGetTarget(label); } return ReorgILLabel.GetTarget(label); } internal static void InteropSetTarget(this ILLabel label, Instruction value) { if (MonoModVersion.IsReorg) { ReorgILLabel.SetTarget(label, value); } else { LegacySetTarget(label, value); } } [MethodImpl(MethodImplOptions.NoInlining)] private static Instruction? LegacyGetTarget(ILLabel label) { return label.Target; } [MethodImpl(MethodImplOptions.NoInlining)] private static Instruction? LegacySetTarget(ILLabel label, Instruction value) { return label.Target = value; } } } namespace MonoDetour.Interop.Cecil { internal static class ILHookInstructionILLabelCastFixes { [CompilerGenerated] private static class <>O { public static Manipulator <0>__ILHook_Instruction_ToString; public static Manipulator <1>__ILHook_Instruction_GetSize; public static Func<object, object> <2>__IfILLabelThenReturnTargetInstruction; public static Func<object, object> <3>__IfILLabelArrayThenReturnTargetInstruction; } private static ILHook castILLabelToInstructionToStringILHook; private static ILHook castILLabelToInstructionGetSizeILHook; private static bool initialized; internal static void InitHook() { if (initialized) { return; } initialized = true; try { InitHookToString(); InitHookGetSize(); } catch (Exception innerException) { throw new NotSupportedException("MonoDetour doesn't seem to support this Mono.Cecil version, please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Instruction).Assembly}'", innerException); } } private static void InitHookToString() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown MethodInfo? method = typeof(Instruction).GetMethod("ToString", Array.Empty<Type>()); object obj = <>O.<0>__ILHook_Instruction_ToString; if (obj == null) { Manipulator val = ILHook_Instruction_ToString; <>O.<0>__ILHook_Instruction_ToString = val; obj = (object)val; } castILLabelToInstructionToStringILHook = new ILHook((MethodBase)method, (Manipulator)obj); } private static void InitHookGetSize() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown MethodInfo? method = typeof(Instruction).GetMethod("GetSize", Array.Empty<Type>()); object obj = <>O.<1>__ILHook_Instruction_GetSize; if (obj == null) { Manipulator val = ILHook_Instruction_GetSize; <>O.<1>__ILHook_Instruction_GetSize = val; obj = (object)val; } castILLabelToInstructionGetSizeILHook = new ILHook((MethodBase)method, (Manipulator)obj); } private static void ILHook_Instruction_ToString(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (!val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCastclass<Instruction>(x) })) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "ILHook_Instruction_ToString] Could not find 'castclass Mono.Cecil.Cil.Instruction'!"); return; } val.EmitDelegate<Func<object, object>>((Func<object, object>)IfILLabelThenReturnTargetInstruction); if (!val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCastclass<Instruction[]>(x) })) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "ILHook_Instruction_ToString] Could not find 'castclass class Mono.Cecil.Cil.Instruction[]'!"); } else { val.EmitDelegate<Func<object, object>>((Func<object, object>)IfILLabelArrayThenReturnTargetInstruction); } } private static void ILHook_Instruction_GetSize(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (!val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCastclass<Instruction[]>(x) })) { MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "[ILHook_Instruction_GetSize] Could not find 'castclass class Mono.Cecil.Cil.Instruction[]'!"); } else { val.EmitDelegate<Func<object, object>>((Func<object, object>)IfILLabelArrayThenReturnTargetInstruction); } } private static object? IfILLabelThenReturnTargetInstruction(object operand) { ILLabel val = (ILLabel)((operand is ILLabel) ? operand : null); if (val != null) { return val.InteropGetTarget() ?? throw new NullReferenceException("ILLabel.Target must not not be null!"); } return operand; } private static object IfILLabelArrayThenReturnTargetInstruction(object operand) { if (operand is ILLabel[] source) { return source.Select((ILLabel l) => l.InteropGetTarget()).ToArray(); } return operand; } } } namespace MonoDetour.DetourTypes { public class ILHookDetour : IMonoDetourHookApplier { private IReadOnlyMonoDetourHook _hook; private ILManipulationInfo.Manipulator invoker; public IReadOnlyMonoDetourHook Hook { get { return _hook; } set { _hook = value; invoker = ((ILManipulationInfo.Manipulator)_hook.ManipulatorDelegate) ?? ((ILManipulationInfo.Manipulator)Delegate.CreateDelegate(typeof(ILManipulationInfo.Manipulator), (Hook.Manipulator as MethodInfo) ?? throw new InvalidCastException("Hook Manipulator method is not MethodInfo!"))); } } public void ApplierManipulator(ILContext il) { ILContext il2 = il; Action invokeOnManipulatorFinished; ILManipulationInfo info = new ILManipulationInfo(il2, Hook.Target, out invokeOnManipulatorFinished); invoker(info); invokeOnManipulatorFinished(); Hook.Owner.Log(MonoDetourLogger.LogChannel.IL, delegate { IInformationalMethodBody arg = il2.Body.CreateInformationalSnapshotJIT().AnnotateErrors(); return $"Manipulated by ILHook: {Hook.Manipulator.Name} ({Hook.Owner.Id}):\n{arg}"; }); } } public interface IMonoDetourHookApplier { IReadOnlyMonoDetourHook Hook { get; set; } void ApplierManipulator(ILContext il); } public class PostfixDetour : IMonoDetourHookApplier { private IReadOnlyMonoDetourHook hook; private static readonly List<Delegate> postfixDelegates = new List<Delegate>(); private static readonly List<IReadOnlyMonoDetourHook> postfixHooks = new List<IReadOnlyMonoDetourHook>(); private int delegateId = -1; private int hookId = -1; public IReadOnlyMonoDetourHook Hook { get { return hook; } set { hook = value; hookId = postfixHooks.Count; postfixHooks.Add(hook); Delegate manipulatorDelegate = value.ManipulatorDelegate; if ((object)manipulatorDelegate != null) { delegateId = postfixDelegates.Count; postfixDelegates.Add(manipulatorDelegate); } } } private static Delegate GetDelegate(int id) { return postfixDelegates[id]; } private static IReadOnlyMonoDetourHook GetHook(int id) { return postfixHooks[id]; } public void ApplierManipulator(ILContext il) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) if (Hook.ModifiesControlFlow()) { throw new NotSupportedException("A PostfixDetour may not modify control flow."); } HookTargetRecords.HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(il); Action invokeOnManipulatorFinished; ILWeaver w = new ILWeaver(new ILManipulationInfo(il, Hook.Target, out invokeOnManipulatorFinished)); w.CurrentTo(w.Last); List<Instruction> firstPostfixInstructions = hookTargetInfo.PostfixInfo.FirstPostfixInstructions; ILLabel label = RedirectEarlyReturnsToLabel(w, hookTargetInfo); IEnumerable<ILLabel> incomingLabelsFor = w.GetIncomingLabelsFor(label.InteropGetTarget()); w.MarkLabelToFutureNextInsert(label); w.HandlerCreateCatch(null, out WeaverExceptionCatchHandler handler); w.DefineLabel(out ILLabel label2); w.HandlerSetTryStart(label2, handler); Instruction callMaybeInsertGetDelegate; if (hookTargetInfo.ReturnValue != null) { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Stloc, hookTargetInfo.ReturnValue))); w.MarkLabelToFutureNextInsert(label2); callMaybeInsertGetDelegate = Utils.GetCallMaybeInsertGetDelegate(w, Hook, delegateId, GetDelegate); w.EmitParamsAndReturnValueBeforeCurrent(hookTargetInfo.ReturnValue, Hook); } else { w.MarkLabelToFutureNextInsert(label2); callMaybeInsertGetDelegate = Utils.GetCallMaybeInsertGetDelegate(w, Hook, delegateId, GetDelegate); w.EmitParamsBeforeCurrent(Hook); } w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(callMaybeInsertGetDelegate)); w.HandlerSetTryEnd(w.Previous, handler); w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Ldc_I4, hookId), w.CreateCall(new Func<int, IReadOnlyMonoDetourHook>(GetHook)), w.CreateCall(new Action<Exception, IReadOnlyMonoDetourHook>(Utils.DisposeBadHooks)) })); w.HandlerSetHandlerEnd(w.Previous, handler); if (hookTargetInfo.ReturnValue != null) { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldloc, hookTargetInfo.ReturnValue))); } else { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Nop))); } w.RetargetLabels(incomingLabelsFor, label.InteropGetTarget()); firstPostfixInstructions.Add(label.InteropGetTarget()); Enumerator<ExceptionHandler> enumerator = il.Body.ExceptionHandlers.GetEnumerator(); try { while (enumerator.MoveNext()) { ExceptionHandler current = enumerator.Current; if (current.HandlerEnd == w.Last) { current.HandlerEnd = label.InteropGetTarget(); } } } finally { ((IDisposable)enumerator).Dispose(); } invokeOnManipulatorFinished(); Hook.Owner.Log(MonoDetourLogger.LogChannel.IL, delegate { IInformationalMethodBody arg = w.Body.CreateInformationalSnapshotJIT().AnnotateErrors(); return $"Manipulated by Postfix: {Hook.Manipulator.Name} ({Hook.Owner.Id}):\n{arg}"; }); } private static ILLabel RedirectEarlyReturnsToLabel(ILWeaver w, HookTargetRecords.HookTargetInfo info) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0200: 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_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) List<Instruction> firstPostfixInstructions = info.PostfixInfo.FirstPostfixInstructions; VariableDefinition? returnValue = info.ReturnValue; int? num = ((returnValue != null) ? new int?(((VariableReference)returnValue).Index) : null); if (w.Body.Instructions.Count == 0) { w.Body.Instructions.Add(w.Create(OpCodes.Nop)); } Collection<Instruction> instructions = w.Body.Instructions; Instruction last = w.Last; w.DefineAndMarkLabelTo(last, out ILLabel markedLabel); bool flag = false; foreach (Instruction item in ((IEnumerable<Instruction>)w.Body.Instructions).Where((Instruction ins) => ILPatternMatchingExt.MatchRet(ins))) { flag = true; Instruction next = item.Next; if (next == null) { continue; } if (num.HasValue) { int valueOrDefault = num.GetValueOrDefault(); Instruction next2 = next.Next; if (((next2 != null) ? next2.Next : null) != null) { Instruction previous = item.Previous; if (((previous != null) ? new bool?(ILPatternMatchingExt.MatchLdloc(previous, valueOrDefault)) : null) ?? false) { if (next.Next.OpCode == OpCodes.Ret && ILPatternMatchingExt.MatchLdloc(next, valueOrDefault)) { continue; } Instruction previous2 = item.Previous.Previous; OpCode? val = ((previous2 != null) ? new OpCode?(previous2.OpCode) : null); OpCode ret = OpCodes.Ret; if (val.HasValue && val.GetValueOrDefault() == ret) { Instruction previous3 = item.Previous.Previous.Previous; if (((previous3 != null) ? new bool?(ILPatternMatchingExt.MatchLdloc(previous3, valueOrDefault)) : null) ?? false) { continue; } } } } } else if (next.Next != null) { if (next.OpCode == OpCodes.Ret) { continue; } Instruction previous4 = item.Previous; OpCode? val = ((previous4 != null) ? new OpCode?(previous4.OpCode) : null); OpCode ret = OpCodes.Ret; if (val.HasValue && val.GetValueOrDefault() == ret) { continue; } } bool flag2 = false; foreach (Instruction item2 in firstPostfixInstructions) { if (item2 != null && instructions.IndexOf(item) < instructions.IndexOf(item2)) { item.OpCode = OpCodes.Br; item.Operand = item2; flag2 = true; break; } } if (!flag2) { item.OpCode = OpCodes.Br; item.Operand = markedLabel; } } last.OpCode = (flag ? OpCodes.Ret : OpCodes.Nop); last.Operand = null; return markedLabel; } } public class PrefixDetour : IMonoDetourHookApplier { private IReadOnlyMonoDetourHook hook; private static readonly List<Delegate> prefixDelegates = new List<Delegate>(); private static readonly List<IReadOnlyMonoDetourHook> prefixHooks = new List<IReadOnlyMonoDetourHook>(); private int delegateId = -1; private int hookId = -1; public IReadOnlyMonoDetourHook Hook { get { return hook; } set { hook = value; hookId = prefixHooks.Count; prefixHooks.Add(hook); Delegate manipulatorDelegate = value.ManipulatorDelegate; if ((object)manipulatorDelegate != null) { delegateId = prefixDelegates.Count; prefixDelegates.Add(manipulatorDelegate); } } } private static Delegate GetDelegate(int id) { return prefixDelegates[id]; } private static IReadOnlyMonoDetourHook GetHook(int id) { return prefixHooks[id]; } public void ApplierManipulator(ILContext il) { //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) HookTargetRecords.HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(il); Action invokeOnManipulatorFinished; ILWeaver w = new ILWeaver(new ILManipulationInfo(il, Hook.Target, out invokeOnManipulatorFinished)); bool flag = Hook.ModifiesControlFlow() && hookTargetInfo.ReturnValue != null; w.HandlerCreateCatch(null, out WeaverExceptionCatchHandler handler); w.DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel); w.HandlerSetTryStart(futureMarkedLabel, handler); Instruction callMaybeInsertGetDelegate = Utils.GetCallMaybeInsertGetDelegate(w, Hook, delegateId, GetDelegate); if (flag) { w.EmitParamsAndReturnValueBeforeCurrent(hookTargetInfo.ReturnValue, Hook); } else { w.EmitParamsBeforeCurrent(Hook); } w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(callMaybeInsertGetDelegate)); if (Hook.ModifiesControlFlow()) { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Stloc, hookTargetInfo.PrefixInfo.TemporaryControlFlow))); } w.HandlerSetTryEnd(w.Previous, handler); w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3] { w.Create(OpCodes.Ldc_I4, hookId), w.CreateCall(new Func<int, IReadOnlyMonoDetourHook>(GetHook)), w.CreateCall(new Action<Exception, IReadOnlyMonoDetourHook>(Utils.DisposeBadHooks)) })); w.HandlerSetHandlerEnd(w.Previous, handler); if (Hook.ModifiesControlFlow()) { Instruction val = w.Create(OpCodes.Switch, new object()); w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2] { w.Create(OpCodes.Ldloc, hookTargetInfo.PrefixInfo.TemporaryControlFlow), val })); w.DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel2); for (int i = 0; i < 2; i++) { if (hookTargetInfo.ReturnValue != null) { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldloc, hookTargetInfo.ReturnValue))); } w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(hookTargetInfo.MarkPersistentInstruction(w.Create(OpCodes.Ret)))); } w.DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel3); w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2] { w.Create(OpCodes.Ldc_I4_1), w.Create(OpCodes.Stloc, hookTargetInfo.PrefixInfo.ControlFlow) })); w.DefineAndMarkLabelToCurrentOrFutureNextInsert(out ILLabel futureMarkedLabel4); val.Operand = new ILLabel[3] { futureMarkedLabel4, futureMarkedLabel3, futureMarkedLabel2 }; } if (!hookTargetInfo.PrefixInfo.ControlFlowImplemented) { hookTargetInfo.PrefixInfo.SetControlFlowImplemented(); w.DefineAndMarkLabelToCurrent(out ILLabel markedLabel); w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2] { w.Create(OpCodes.Ldloc, hookTargetInfo.PrefixInfo.ControlFlow), w.Create(OpCodes.Brfalse, (object)markedLabel) })); if (hookTargetInfo.ReturnValue != null) { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldloc, hookTargetInfo.ReturnValue))); } if (hookTargetInfo.PostfixInfo.FirstPostfixInstructions.FirstOrDefault() == null) { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ret))); } else { bool flag2 = false; foreach (Instruction firstPostfixInstruction in hookTargetInfo.PostfixInfo.FirstPostfixInstructions) { if (w.Body.Instructions.Contains(firstPostfixInstruction)) { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Br, firstPostfixInstruction))); flag2 = true; break; } } if (!flag2) { Hook.Owner.Log(MonoDetourLogger.LogChannel.Warning, "While applying Prefix: " + Hook.Manipulator.Name + " (" + Hook.Owner.Id + "): No postfix labels found despite postfixes being applied on the method. " + $"Postfixes might not run on method '{Hook.Target}'. "); w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ret))); } } } invokeOnManipulatorFinished(); if (Hook.ModifiesControlFlow()) { hookTargetInfo.PrefixInfo.MarkControlFlowPrefixAsApplied(); } Hook.Owner.Log(MonoDetourLogger.LogChannel.IL, delegate { IInformationalMethodBody arg = w.Body.CreateInformationalSnapshotJIT().AnnotateErrors(); return $"Manipulated by Prefix: {Hook.Manipulator.Name} ({Hook.Owner.Id}):\n{arg}"; }); } } public enum ReturnFlow { None, SkipOriginal, HardReturn } } namespace MonoDetour.DetourTypes.Manipulation { public static class HookTargetRecords { public class HookTargetInfo { public TargetPrefixInfo PrefixInfo { get; } public TargetPostfixInfo PostfixInfo { get; } = new TargetPostfixInfo(); public VariableDefinition? ReturnValue { get; } public ReadOnlyCollection<Instruction> OriginalInstructions { get; internal set; } internal HashSet<Instruction> PersistentInstructions { get; } = new HashSet<Instruction>(); internal HookTargetInfo(MethodDefinition method, VariableDefinition? returnValue, ReadOnlyCollection<Instruction> originalInstructions) { PrefixInfo = new TargetPrefixInfo(method); ReturnValue = returnValue; OriginalInstructions = originalInstructions; } internal Instruction MarkPersistentInstruction(Instruction instruction) { PersistentInstructions.Add(instruction); return instruction; } internal bool IsPersistentInstruction(Instruction instruction) { return PersistentInstructions.Contains(instruction); } } public class TargetPrefixInfo { public VariableDefinition ControlFlow { get; } public VariableDefinition TemporaryControlFlow { get; } public bool ControlFlowImplemented { get; private set; } internal int AppliedControlFlowPrefixes { get; private set; } internal TargetPrefixInfo(MethodDefinition method) { ControlFlow = method.DeclareVariable(typeof(int)); TemporaryControlFlow = method.DeclareVariable(typeof(int)); } public void SetControlFlowImplemented() { ControlFlowImplemented = true; } internal void MarkControlFlowPrefixAsApplied() { AppliedControlFlowPrefixes++; } } public class TargetPostfixInfo { public List<Instruction> FirstPostfixInstructions { get; } = new List<Instruction>(); internal TargetPostfixInfo() { } } private static readonly ConditionalWeakTable<MethodDefinition, HookTargetInfo> s_MethodToInfo = new ConditionalWeakTable<MethodDefinition, HookTargetInfo>(); internal static ReadOnlyCollection<Instruction> GetOriginalInstructions(MethodDefinition method) { ConditionalWeakTable<MethodDefinition, ReadOnlyCollection<Instruction>> s_MethodDefinitionToOriginalInstructions = ILHookDMDManipulation.s_MethodDefinitionToOriginalInstructions; if (s_MethodDefinitionToOriginalInstructions.TryGetValue(method, out var value)) { return value; } return new ReadOnlyCollection<Instruction>(new List<Instruction>()); } internal static void SwapOriginalInstructionsCollection(MethodDefinition method, HookTargetInfo info, ReadOnlyCollection<Instruction> replacement) { ILHookDMDManipulation.s_MethodDefinitionToOriginalInstructions.Remove(method); ILHookDMDManipulation.s_MethodDefinitionToOriginalInstructions.Add(method, replacement); info.OriginalInstructions = replacement; } public static HookTargetInfo GetHookTargetInfo(ILContext il) { return GetHookTargetInfo(il.Method); } public static HookTargetInfo GetHookTargetInfo(MethodDefinition method) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if (s_MethodToInfo.TryGetValue(method, out HookTargetInfo value)) { return value; } VariableDefinition val = null; if ((int)((MethodReference)method).ReturnType.MetadataType != 1) { val = new VariableDefinition(((MethodReference)method).ReturnType); method.Body.Variables.Add(val); } value = new HookTargetInfo(method, val, GetOriginalInstructions(method)); s_MethodToInfo.Add(method, value); return value; } private static VariableDefinition DeclareVariable(this MethodDefinition method, Type type) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown VariableDefinition val = new VariableDefinition(((MemberReference)method).Module.ImportReference(type)); method.Body.Variables.Add(val); return val; } } internal static class Utils { private static void WriteSpeakableEnumerator(ILWeaver w, Type speakableEnumeratorType, Type enumeratorType) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) MethodInfo method = speakableEnumeratorType.GetMethod("PreBuildFieldReferenceGetters"); method.Invoke(null, new object[1] { enumeratorType }); MethodInfo method2 = speakableEnumeratorType.GetMethod("GetOrCreate"); w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Call, (MethodBase)method2))); } public static bool ModifiesControlFlow(this IReadOnlyMonoDetourHook hook) { if (hook.Manipulator is MethodInfo methodInfo) { return methodInfo.ReturnType == typeof(ReturnFlow); } return false; } public static void EmitParamsAndReturnValueBeforeCurrent(this ILWeaver w, VariableDefinition returnValue, IReadOnlyMonoDetourHook hook) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) Helpers.ThrowIfNull<VariableDefinition>(returnValue, "returnValue"); w.EmitParamsBeforeCurrent(hook); w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldloca, returnValue))); } public static void EmitParamsBeforeCurrent(this ILWeaver w, IReadOnlyMonoDetourHook hook) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) bool isStatic = hook.Target.IsStatic; Enumerator<ParameterDefinition> enumerator = ((MethodReference)w.Method).Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; if (!isStatic && ((ParameterReference)current).Index == 0) { Type parameterType = hook.Manipulator.GetParameters().First().ParameterType; if (typeof(ISpeakableEnumerator).IsAssignableFrom(parameterType)) { Type enumeratorType = hook.Target.DeclaringType ?? throw new NullReferenceException("Declaring type of target method is null!"); w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldarg, ((ParameterReference)current).Index))); WriteSpeakableEnumerator(w, parameterType, enumeratorType); } else { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldarg, ((ParameterReference)current).Index))); } } else if (((ParameterReference)current).ParameterType.IsByReference) { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldarg, ((ParameterReference)current).Index))); } else { w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldarga, ((ParameterReference)current).Index))); } } } finally { ((IDisposable)enumerator).Dispose(); } } internal static void DisposeBadHooks(Exception ex, IReadOnlyMonoDetourHook hook) { IReadOnlyMonoDetourHook hook2 = hook; Exception ex2 = ex; MethodBase manipulator = hook2.Manipulator; MethodBase target = hook2.Target; string text = target.DeclaringType?.FullName; int hooksCount = hook2.Owner.Hooks.Count; hook2.Owner.Log(MonoDetourLogger.LogChannel.Error, () => "Exception caught in a hook belonging to MonoDetourManager '" + hook2.Owner.Id + "'" + $" (disposing all {hooksCount} of its hooks in an attempt to minimize potential damage):\n" + ex2); try { if (!hook2.Owner.CallOnHookThrew(hook2)) { hook2.Owner.Log(MonoDetourLogger.LogChannel.Warning, () => "No disposal event handler for the MonoDetourManager was registered. You can subscribe to the MonoDetourManager.OnHookThrew event to clean up the rest of your resources."); } } catch (Exception ex3) { Exception ex4 = ex3; Exception disposalEx = ex4; hook2.Owner.Log(MonoDetourLogger.LogChannel.Error, () => $"Disposal event handler threw an exception:\n{disposalEx}"); } finally { hook2.Owner.DisposeHooks(); } } internal static void ThrowIfHookManipulatorDelegateIsNull(IReadOnlyMonoDetourHook hook, out Delegate manipulatorDelegate) { Delegate manipulatorDelegate2 = hook.ManipulatorDelegate; if ((object)manipulatorDelegate2 != null) { manipulatorDelegate = manipulatorDelegate2; return; } throw new NullReferenceException("IReadOnlyMonoDetourHook.Manipulator is not static, and IReadOnlyMonoDetourHook.ManipulatorDelegate is null. Please use a constructor which takes a Delegate instead of a MethodBase for Manipulator."); } internal static Instruction GetCallMaybeInsertGetDelegate(ILWeaver w, IReadOnlyMonoDetourHook hook, int id, Func<
Renderer/BepInEx/core/com.github.MonoDetour.Reflection.dll
Decompiled 2 days agousing System; using System.Collections; 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.Cil; using MonoMod.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Hamunii")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.7.14.0")] [assembly: AssemblyInformationalVersion("0.7.14+0d55abe3fd0d330206803b376c57bc7135c48257")] [assembly: AssemblyProduct("MonoDetour.Reflection")] [assembly: AssemblyTitle("MonoDetour.Reflection")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.14.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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.Reflection.Unspeakable { public delegate ref T EnumeratorFieldReferenceGetter<T>(IEnumerator instance); internal static class <EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T> { internal static readonly ConcurrentDictionary<(Type, int), EnumeratorFieldReferenceGetter<T>> s_FieldToRef = new ConcurrentDictionary<(Type, int), EnumeratorFieldReferenceGetter<T>>(); internal static readonly ConcurrentDictionary<(Type, string), EnumeratorFieldReferenceGetter<T>> s_3ToRef = new ConcurrentDictionary<(Type, string), EnumeratorFieldReferenceGetter<T>>(); } public static class EnumeratorReflection { private const string DeclaringTypeNull = "Declaring type of method is null!"; public static void EnumeratorFastFieldReferenceThis<T>(this MethodInfo methodInfo, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference) { enumeratorFieldReference = methodInfo.EnumeratorFastFieldReferenceThis<T>(); } public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReferenceThis<T>(this MethodInfo methodInfo) { return methodInfo.DeclaringType?.EnumeratorFastFieldReferenceThis<T>() ?? throw new NullReferenceException("Declaring type of method is null!"); } public static void EnumeratorFastFieldReferenceThis<T>(this Type enumeratorType, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference) { enumeratorFieldReference = enumeratorType.EnumeratorFastFieldReferenceThis<T>(); } public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReferenceThis<T>(this Type enumeratorType) { return enumeratorType.EnumeratorFastFieldReference<T>(4); } public static void EnumeratorFastFieldReferenceCurrent<T>(this MethodInfo methodInfo, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference) { enumeratorFieldReference = methodInfo.EnumeratorFastFieldReferenceCurrent<T>(); } public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReferenceCurrent<T>(this MethodInfo methodInfo) { return methodInfo.DeclaringType?.EnumeratorFastFieldReferenceCurrent<T>() ?? throw new NullReferenceException("Declaring type of method is null!"); } public static void EnumeratorFastFieldReferenceCurrent<T>(this Type enumeratorType, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference) { enumeratorFieldReference = enumeratorType.EnumeratorFastFieldReferenceCurrent<T>(); } public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReferenceCurrent<T>(this Type enumeratorType) { return enumeratorType.EnumeratorFastFieldReference<T>(2); } public static void EnumeratorFastFieldReferenceState(this MethodInfo methodInfo, ref EnumeratorFieldReferenceGetter<int> enumeratorFieldReference) { enumeratorFieldReference = methodInfo.EnumeratorFastFieldReferenceState(); } public static EnumeratorFieldReferenceGetter<int> EnumeratorFastFieldReferenceState(this MethodInfo methodInfo) { return methodInfo.DeclaringType?.EnumeratorFastFieldReferenceState() ?? throw new NullReferenceException("Declaring type of method is null!"); } public static void EnumeratorFastFieldReferenceState(this Type enumeratorType, ref EnumeratorFieldReferenceGetter<int> enumeratorFieldReference) { enumeratorFieldReference = enumeratorType.EnumeratorFastFieldReferenceState(); } public static EnumeratorFieldReferenceGetter<int> EnumeratorFastFieldReferenceState(this Type enumeratorType) { return enumeratorType.EnumeratorFastFieldReference<int>(1); } public static void EnumeratorFastFieldReference<T>(this MethodInfo methodInfo, string fieldName, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference) { enumeratorFieldReference = methodInfo.EnumeratorFastFieldReference<T>(fieldName); } public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReference<T>(this MethodInfo methodInfo, string fieldName) { return methodInfo.DeclaringType?.EnumeratorFastFieldReference<T>(fieldName) ?? throw new NullReferenceException("Declaring type of method is null!"); } public static void EnumeratorFastFieldReference<T>(this Type enumeratorType, string fieldName, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference) { enumeratorFieldReference = enumeratorType.EnumeratorFastFieldReference<T>(fieldName); } private static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReference<T>(this Type enumeratorType, int fieldId) { if (<EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>.s_FieldToRef.TryGetValue((enumeratorType, fieldId), out EnumeratorFieldReferenceGetter<T> value)) { return value; } string text = fieldId switch { 1 => "<>1__state", 2 => "<>2__current", 3 => throw new ArgumentException("field id 3 is not constant."), 4 => "<>4__this", _ => throw new ArgumentOutOfRangeException("fieldId", $"Valid values are 1, 2, and 4. The value provided was: {fieldId}"), }; FieldInfo fieldInfo = enumeratorType.GetField(text, (BindingFlags)(-1)) ?? throw new NullReferenceException($"'{text}' field not found on type {enumeratorType}."); if (!typeof(T).IsAssignableFrom(fieldInfo.FieldType)) { throw new InvalidCastException($"{typeof(T)} is not assignable from '{text}' field type {fieldInfo.FieldType}"); } value = CreateFastFieldReference<T>(fieldInfo); <EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>.s_FieldToRef.TryAdd((enumeratorType, fieldId), value); return value; } public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReference<T>(this Type enumeratorType, string fieldName) { if (<EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>.s_3ToRef.TryGetValue((enumeratorType, fieldName), out EnumeratorFieldReferenceGetter<T> value)) { return value; } FieldInfo fieldInfo = enumeratorType.GetField(fieldName, (BindingFlags)(-1)) ?? throw new NullReferenceException($"'{fieldName}' field not found on type {enumeratorType}."); if (!typeof(T).IsAssignableFrom(fieldInfo.FieldType)) { throw new InvalidCastException($"{typeof(T)} is not assignable from '{fieldName}' field type {fieldInfo.FieldType}"); } value = CreateFastFieldReference<T>(fieldInfo); <EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>.s_3ToRef.TryAdd((enumeratorType, fieldName), value); return value; } private static EnumeratorFieldReferenceGetter<T> CreateFastFieldReference<T>(FieldInfo fieldInfo) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) DynamicMethodDefinition val = new DynamicMethodDefinition("FastFieldReference", typeof(T).MakeByRefType(), new Type[1] { typeof(object) }); ILProcessor iLProcessor = val.GetILProcessor(); iLProcessor.Emit(OpCodes.Ldarg_0); Extensions.Emit(iLProcessor, OpCodes.Ldflda, fieldInfo); iLProcessor.Emit(OpCodes.Ret); return Extensions.CreateDelegate<EnumeratorFieldReferenceGetter<T>>((MethodBase)val.Generate()); } } public interface ISpeakableEnumerator { } public sealed class SpeakableEnumerator<TCurrent, TThis> : ISpeakableEnumerator { private readonly EnumeratorFieldReferenceGetter<TThis> getThisRef; private readonly EnumeratorFieldReferenceGetter<TCurrent> getCurrentRef; private readonly EnumeratorFieldReferenceGetter<int> getStateRef; private readonly IEnumerator<TCurrent> instance; private static readonly ConditionalWeakTable<IEnumerator<TCurrent>, SpeakableEnumerator<TCurrent, TThis>> s_EnumeratorToSpeakable = new ConditionalWeakTable<IEnumerator<TCurrent>, SpeakableEnumerator<TCurrent, TThis>>(); public TThis This => getThisRef(instance); public IEnumerator<TCurrent> Enumerator => instance; public TCurrent Current { get { return getCurrentRef(instance); } set { getCurrentRef(instance) = value; } } public int State { get { return getStateRef(instance); } set { getStateRef(instance) = value; } } public SpeakableEnumerator(IEnumerator<TCurrent> instance) { Type type = instance.GetType(); this.instance = instance; getCurrentRef = type.EnumeratorFastFieldReferenceCurrent<TCurrent>(); getStateRef = type.EnumeratorFastFieldReferenceState(); getThisRef = type.EnumeratorFastFieldReferenceThis<TThis>(); } public static void PreBuildFieldReferenceGetters(Type type) { SpeakableEnumerator<TCurrent>.PreBuildFieldReferenceGetters(type); type.EnumeratorFastFieldReferenceThis<TThis>(); } public static SpeakableEnumerator<TCurrent, TThis> GetOrCreate(IEnumerator<TCurrent> instance) { if (s_EnumeratorToSpeakable.TryGetValue(instance, out SpeakableEnumerator<TCurrent, TThis> value)) { return value; } value = new SpeakableEnumerator<TCurrent, TThis>(instance); s_EnumeratorToSpeakable.Add(instance, value); return value; } } public sealed class SpeakableEnumerator<TCurrent> : ISpeakableEnumerator { private readonly EnumeratorFieldReferenceGetter<TCurrent> getCurrentRef; private readonly EnumeratorFieldReferenceGetter<int> getStateRef; private readonly IEnumerator<TCurrent> instance; private static readonly ConditionalWeakTable<IEnumerator<TCurrent>, SpeakableEnumerator<TCurrent>> s_EnumeratorToSpeakable = new ConditionalWeakTable<IEnumerator<TCurrent>, SpeakableEnumerator<TCurrent>>(); public IEnumerator<TCurrent> Enumerator => instance; public TCurrent Current { get { return getCurrentRef(instance); } set { getCurrentRef(instance) = value; } } public int State { get { return getStateRef(instance); } set { getStateRef(instance) = value; } } public SpeakableEnumerator(IEnumerator<TCurrent> instance) { Type type = instance.GetType(); this.instance = instance; getCurrentRef = type.EnumeratorFastFieldReferenceCurrent<TCurrent>(); getStateRef = type.EnumeratorFastFieldReferenceState(); } public static void PreBuildFieldReferenceGetters(Type type) { type.EnumeratorFastFieldReferenceCurrent<TCurrent>(); type.EnumeratorFastFieldReferenceState(); } public static SpeakableEnumerator<TCurrent> GetOrCreate(IEnumerator<TCurrent> instance) { if (s_EnumeratorToSpeakable.TryGetValue(instance, out SpeakableEnumerator<TCurrent> value)) { return value; } value = new SpeakableEnumerator<TCurrent>(instance); s_EnumeratorToSpeakable.Add(instance, value); return value; } } }
Renderer/BepInEx/core/com.github.MonoDetour.Bindings.Reorg.dll
Decompiled 2 days agousing System; using System.Collections; 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.14.0")] [assembly: AssemblyInformationalVersion("0.7.14+0d55abe3fd0d330206803b376c57bc7135c48257")] [assembly: AssemblyProduct("MonoDetour.Bindings.Reorg")] [assembly: AssemblyTitle("MonoDetour.Bindings.Reorg")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.14.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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<string> Before { get; } IEnumerable<string> 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<string>? before = null, IEnumerable<string>? after = null); private static Func<object> detourContext_GetDefaultConfig = null; private static ILHookConstructor newILHook = null; private static DetourConfigConstructor newDetourConfig = null; private static Func<object, int?> detourConfigPriority = null; private static MethodInfo detourConfig_WithPriority = null; private static readonly ConcurrentDictionary<IMonoDetourConfig, object> interfaceToConfig = new ConcurrentDictionary<IMonoDetourConfig, object>(); private static readonly ConcurrentDictionary<object, object> configToConfig = new ConcurrentDictionary<object, object>(); private static readonly ConcurrentDictionary<string, object> idToConfig = new ConcurrentDictionary<string, object>(); 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<Func<object>>((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<ILHookConstructor>((MethodBase)val.Generate()); } finally { ((IDisposable)val)?.Dispose(); } ConstructorInfo constructor2 = type.GetConstructor(new Type[4] { typeof(string), typeof(int?), typeof(IEnumerable<string>), typeof(IEnumerable<string>) }); DynamicMethodDefinition val2 = new DynamicMethodDefinition("iLHookConstructor", typeof(object), new Type[4] { typeof(string), typeof(int?), typeof(IEnumerable<string>), typeof(IEnumerable<string>) }); 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<DetourConfigConstructor>((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<Func<object, int?>>((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<GetDelegateInvokerSig>((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<T>(ILContext context, in T? value); private static class Container<T> { internal static Signature<T> AddReference => <AddReference>k__BackingField ?? (<AddReference>k__BackingField = Extensions.CreateDelegate<Signature<T>>((MethodBase)addReferenceMethod.MakeGenericMethod(typeof(T)))); } [CompilerGenerated] private sealed class <GetReference>d__9 : IEnumerable<Instruction>, IEnumerable, IEnumerator<Instruction>, IEnumerator, IDisposable { private int <>1__state; private Instruction <>2__current; private int <>l__initialThreadId; private ILContext context; public ILContext <>3__context; private int id; public int <>3__id; private Type type; public Type <>3__type; private object <cellRef>5__2; private ILProcessor <il>5__3; Instruction IEnumerator<Instruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetReference>d__9(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <cellRef>5__2 = null; <il>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <cellRef>5__2 = getReferenceCell.Invoke(context, new object[1] { id }); <il>5__3 = context.IL; <>2__current = Extensions.Create(<il>5__3, OpCodes.Ldc_I4, cellRef_get_Index.Invoke(<cellRef>5__2, Array.Empty<object>())); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = Extensions.Create(<il>5__3, OpCodes.Ldc_I4, cellRef_get_Hash.Invoke(<cellRef>5__2, Array.Empty<object>())); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = <il>5__3.Create(OpCodes.Call, ((MemberReference)<il>5__3.Body.Method).Module.ImportReference((MethodBase)Self_GetValueT_ii.MakeGenericMethod(type))); <>1__state = 3; return true; case 3: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<Instruction> IEnumerable<Instruction>.GetEnumerator() { <GetReference>d__9 <GetReference>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetReference>d__ = this; } else { <GetReference>d__ = new <GetReference>d__9(0); } <GetReference>d__.type = <>3__type; <GetReference>d__.context = <>3__context; <GetReference>d__.id = <>3__id; return <GetReference>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Instruction>)this).GetEnumerator(); } } 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<T>(ILContext context, in T value) { return Container<T>.AddReference(context, in value); } [MethodImpl(MethodImplOptions.NoInlining)] [IteratorStateMachine(typeof(<GetReference>d__9))] internal static IEnumerable<Instruction> GetReference(Type type, ILContext context, int id) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetReference>d__9(-2) { <>3__type = type, <>3__context = context, <>3__id = id }; } } internal static class ReorgILCursor { private delegate int Signature<T>(ILCursor cursor, in T? t); private static class Container<T> { internal static Signature<T> EmitReference => <EmitReference>k__BackingField ?? (<EmitReference>k__BackingField = Extensions.CreateDelegate<Signature<T>>((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<T>(ILCursor cursor, in T? t) { return Container<T>.EmitReference(cursor, in t); } } internal static class ReorgILLabel { private static Func<ILLabel, Instruction> get_Target; private static Action<ILLabel, Instruction> set_Target; internal static void Init() { PropertyInfo property = typeof(ILLabel).GetProperty("Target"); set_Target = Extensions.CreateDelegate<Action<ILLabel, Instruction>>((MethodBase)property.GetSetMethod()); get_Target = Extensions.CreateDelegate<Func<ILLabel, Instruction>>((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); } } }