Decompiled source of MonoDetour BepInEx 5 Resonite v0.7.5
Renderer/BepInEx/patchers/0.com.github.MonoDetour.BepInEx.5.dll
Decompiled 3 weeks 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.5.0")] [assembly: AssemblyInformationalVersion("0.7.5+00379e1a07f34624316c37f1b0aa58b5f9bcf6b9")] [assembly: AssemblyProduct("MonoDetour.BepInEx.5")] [assembly: AssemblyTitle("MonoDetour.BepInEx.5")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.5.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() { //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; 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_0002: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0021: 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) LogLevel val; if ((int)channel <= 4) { if ((int)channel != 0) { if ((int)channel != 4) { goto IL_0029; } val = (LogLevel)32; } else { val = (LogLevel)0; } } else if ((int)channel != 8) { if ((int)channel != 16) { goto IL_0029; } val = (LogLevel)2; } else { val = (LogLevel)4; } LogLevel val2 = val; Log.Log(val2, (object)message); return; IL_0029: throw new ArgumentOutOfRangeException("channel", "A log can only have a single known channel."); } public static void Patch(AssemblyDefinition _) { } } }
Renderer/BepInEx/patchers/com.github.MonoDetour.Interop.HarmonyX.dll
Decompiled 3 weeks 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.5.0")] [assembly: AssemblyInformationalVersion("0.7.5+00379e1a07f34624316c37f1b0aa58b5f9bcf6b9")] [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.5.0")] [module: UnverifiableCode] [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.Interop.HarmonyX { 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() { if (initialized) { return; } initialized = true; TrackInstructions.Init(); if (anyFailed) { MonoDetourLogger.Log((LogChannel)16, "HarmonyX interop module has completely 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(); 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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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; HookTargetRecords.SwapOriginalInstructionsCollection(method, new ReadOnlyCollection<Instruction>(newOriginalInstructions)); HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(body.Method); 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; } } } } 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 Func<ILEmitter, VariableDefinition?> <3>__GetRunOriginalParamVar; public static Func<ILEmitter, bool> <4>__RunOriginalParamLogic; 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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_0703: Unknown result type (might be due to invalid IL or missing references) //IL_075f: Unknown result type (might be due to invalid IL or missing references) //IL_07ab: Unknown result type (might be due to invalid IL or missing references) //IL_07be: Unknown result type (might be due to invalid IL or missing references) //IL_081a: Unknown result type (might be due to invalid IL or missing references) //IL_084f: Unknown result type (might be due to invalid IL or missing references) //IL_0862: Unknown result type (might be due to invalid IL or missing references) //IL_08c6: Unknown result type (might be due to invalid IL or missing references) //IL_08d9: 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 start_RunOriginalParamLogic = null; Instruction end_RunOriginalParamLogic = null; Instruction end_RetLogic = null; Instruction ilEmitterField = null; 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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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.InsertBranchOver(ldarg0_RunOriginalParam, declareVar_RunOriginalParam); w.InsertBeforeStealLabels(declareVar_RunOriginalParam.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>(GetRunOriginalParamVar)) })); w.InsertAfter(declareVar_RunOriginalParam, (IEnumerable<Instruction>)new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Pop))); w.InsertBranchOverIfTrue(start_RunOriginalParamLogic, end_RunOriginalParamLogic, (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, bool>(RunOriginalParamLogic)) })); 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_080c: Unknown result type (might be due to invalid IL or missing references) //IL_081f: Unknown result type (might be due to invalid IL or missing references) //IL_087b: Unknown result type (might be due to invalid IL or missing references) //IL_08c0: Unknown result type (might be due to invalid IL or missing references) //IL_08d4: Unknown result type (might be due to invalid IL or missing references) //IL_08e7: Unknown result type (might be due to invalid IL or missing references) //IL_094b: Unknown result type (might be due to invalid IL or missing references) //IL_095f: Unknown result type (might be due to invalid IL or missing references) //IL_09c3: Unknown result type (might be due to invalid IL or missing references) //IL_09d7: Unknown result type (might be due to invalid IL or missing references) //IL_0a40: Unknown result type (might be due to invalid IL or missing references) //IL_0a54: Unknown result type (might be due to invalid IL or missing references) //IL_0a67: 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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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((IMonoDetourLogSource)(object)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))); w.InsertBranchOver(ldarg0_RunOriginalParam, declareVar_RunOriginalParam); w.InsertBeforeStealLabels(declareVar_RunOriginalParam.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>(GetRunOriginalParamVar)) })); w.InsertAfter(declareVar_RunOriginalParam, (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 VariableDefinition? GetRunOriginalParamVar(ILEmitter ilEmitter) { MethodDefinition method = ilEmitter.IL.Body.Method; HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(method); return hookTargetInfo.PrefixInfo.ControlFlow; } private static bool RunOriginalParamLogic(ILEmitter il) { MethodDefinition method = il.IL.Body.Method; HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(method); if (hookTargetInfo.PrefixInfo.ControlFlowImplemented) { return true; } hookTargetInfo.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((IMonoDetourLogSource)(object)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) { } } } [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(); } }
Renderer/BepInEx/core/com.github.MonoDetour.dll
Decompiled 3 weeks 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.5.0")] [assembly: AssemblyInformationalVersion("0.7.5+00379e1a07f34624316c37f1b0aa58b5f9bcf6b9")] [assembly: AssemblyProduct("MonoDetour")] [assembly: AssemblyTitle("MonoDetour")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.5.0")] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { <ModuleInitialization>F34D4C8E80BA55CF2DF46033D6935630EF80CDE4B828E451B074E18291EB971BE__ModuleInitialization.InitializeModule(); } } 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.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ConstantExpectedAttribute : Attribute { public object? Min { get; set; } public object? Max { get; set; } } [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.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; } } internal static class <ModuleInitialization>F34D4C8E80BA55CF2DF46033D6935630EF80CDE4B828E451B074E18291EB971BE__ModuleInitialization { [ModuleInitializer] internal static void InitializeModule() { ILHookInstructionILLabelCastFixes.InitHook(); ILHookDMDManipulation.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 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; } private MonoDetourHook(MethodBase target, MethodBase manipulator, Delegate? manipulatorDelegate, Type applierType, MonoDetourManager owner, MonoDetourConfig? config = null, bool applyByDefault = true) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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); Applier = ProxyILHookConstructor.ConstructILHook(target, new Manipulator(monoDetourHookApplier.ApplierManipulator), (IMonoDetourConfig?)(object)config, owner.Id); 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 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) { Type[] typesFromAssembly = MonoDetourUtils.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { if (MonoDetourUtils.TryGetCustomAttribute<IMonoDetourTargets>(type, out IMonoDetourTargets _)) { InvokeHookInitializers(type); } } } public static void InvokeHookInitializers(Type type) { MethodInfo[] methods = type.GetMethods((BindingFlags)(-1)); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (MonoDetourUtils.TryGetCustomAttribute<MonoDetourHookInitializeAttribute>(methodInfo, out MonoDetourHookInitializeAttribute _)) { methodInfo.Invoke(null, null); } } } 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 MonoDetourUtils { public static bool TryGetCustomAttribute<T>(MemberInfo member, [NotNullWhen(true)] out T? attribute) { attribute = default(T); IEnumerable<Attribute> customAttributes = member.GetCustomAttributes(); foreach (Attribute item in customAttributes) { if (item is T) { T val = (T)(object)((item is T) ? item : null); attribute = val; return true; } } return false; } public static Type[] GetTypesFromAssembly(Assembly assembly) { try { Type[] types = assembly.GetTypes(); for (int i = 0; i < types.Length; i++) { if (types[i] == null) { return types.Where((Type type) => (object)type != null).ToArray(); } } return types; } catch (ReflectionTypeLoadException ex) { return ex.Types.Where((Type type) => (object)type != null).ToArray(); } } } } 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, IL = 4, Warning = 8, Error = 0x10 } private static LogChannel GlobalFilter { get; set; } = LogChannel.Warning | LogChannel.Error; internal static event LogReceiver? OnLog; private static string LogChannelToString(LogChannel channel) { return channel switch { LogChannel.None => "None ", LogChannel.IL => "IL ", LogChannel.Warning => "Warning", LogChannel.Error => "Error ", _ => throw new NotSupportedException(), }; } internal static bool IsEnabledFor(LogChannel caller, LogChannel channel) { return (caller & channel) != 0; } 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?.Invoke(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?.Invoke(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?.Invoke(channel, message); } } } internal static void Log(LogChannel channel, string message) { if (IsEnabledFor(GlobalFilter, channel)) { if (MonoDetourLogger.OnLog == null) { DefaultLog(channel, message); } else { MonoDetourLogger.OnLog?.Invoke(channel, message); } } } private static void DefaultLog(LogChannel channel, string message) { ConsoleColor color = channel switch { LogChannel.Warning => ConsoleColor.Yellow, LogChannel.Error => ConsoleColor.Red, _ => Console.ForegroundColor, }; LogWithColor("[" + LogChannelToString(channel) + ": MonoDetour] " + message, color); } private static void LogWithColor(string message, ConsoleColor color) { ConsoleColor foregroundColor = Console.ForegroundColor; Console.ForegroundColor = color; Console.Error.WriteLine(message); Console.ForegroundColor = foregroundColor; } } } 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); 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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."); MethodInfo methodInfo = type.GetMethod("Refresh") ?? throw new NullReferenceException("Method 'Refresh' 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, 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) })) { Console.WriteLine(il); throw new NullReferenceException("DMD construction not found."); } 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) { IInformationalMethodBody informationalBody; try { informationalBody = body.CreateInformationalSnapshotJIT().AnnotateErrors(); } catch { throw new Exception("MonoDetour failed to analyze invalid program.", ex); } throw new InvalidProgramException(informationalBody.ToErrorMessageString(), ex); } } internal static class ProxyILHookConstructor { private static Dictionary<IMonoDetourConfig, ILHookConfig>? interfaceToConfig; 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) //IL_0086: Expected O, but got Unknown //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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0050: 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_0057: Expected O, but got Unknown if (interfaceToConfig == null) { interfaceToConfig = new Dictionary<IMonoDetourConfig, ILHookConfig>(); } if (config == null) { DetourContext val = DetourContextGetCurrent(); if (val != null) { ILHookConfig iLHookConfig = val.ILHookConfig; if (!iLHookConfig.ManualApply) { ILHookConfig 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 }); } if (!interfaceToConfig.TryGetValue(config, out var value)) { ILHookConfig val2 = default(ILHookConfig); val2.ID = config.OverrideId ?? id; val2.Priority = config.Priority; val2.Before = config.Before; val2.After = config.After; val2.ManualApply = true; value = val2; interfaceToConfig.Add(config, value); return new ILHook(target, manipulator, value); } return new ILHook(target, manipulator, value); } } } 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) { ReadOnlyCollection<Instruction> originalInstructions = HookTargetRecords.GetOriginalInstructions(il.Method); ILManipulationInfo info = new ILManipulationInfo(il, Hook.Target, originalInstructions); invoker(info); } } 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: 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); ReadOnlyCollection<Instruction> originalInstructions = HookTargetRecords.GetOriginalInstructions(il.Method); ILWeaver w = new ILWeaver(new ILManipulationInfo(il, Hook.Target, originalInstructions)); 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(); } w.HandlerApply(handler); 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_0510: Unknown result type (might be due to invalid IL or missing references) HookTargetRecords.HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(il); ReadOnlyCollection<Instruction> originalInstructions = HookTargetRecords.GetOriginalInstructions(il.Method); ILWeaver w = new ILWeaver(new ILManipulationInfo(il, Hook.Target, originalInstructions)); 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>(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))); } } } w.HandlerApply(handler); 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; } internal HookTargetInfo(MethodDefinition method, VariableDefinition? returnValue) { PrefixInfo = new TargetPrefixInfo(method); ReturnValue = returnValue; } } public class TargetPrefixInfo { public VariableDefinition ControlFlow { get; } public VariableDefinition TemporaryControlFlow { get; } public bool ControlFlowImplemented { get; private set; } internal TargetPrefixInfo(MethodDefinition method) { ControlFlow = method.DeclareVariable(typeof(int)); TemporaryControlFlow = method.DeclareVariable(typeof(int)); } public void SetControlFlowImplemented() { ControlFlowImplemented = true; } } 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; } throw new Exception("Tried to get original instructions for a method which MonoDetour does not know about."); } internal static void SwapOriginalInstructionsCollection(MethodDefinition method, ReadOnlyCollection<Instruction> replacement) { ILHookDMDManipulation.s_MethodDefinitionToOriginalInstructions.Remove(method); ILHookDMDManipulation.s_MethodDefinitionToOriginalInstructions.Add(method, 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); 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) { Exception ex2 = ex; MethodBase manipulator = hook.Manipulator; MethodBase target = hook.Target; string targetTypeName = target.DeclaringType?.FullName; hook.Owner.Log(MonoDetourLogger.LogChannel.Error, () => $"Hook '{manipulator}' targeting method '{target}' from type '{targetTypeName}'" + " threw an exception, and its MonoDetourManager's hooks will be disposed.\n" + $"The Exception that was thrown: {ex2}"); try { if (!hook.Owner.CallOnHookThrew(hook)) { hook.Owner.Log(MonoDetourLogger.LogChannel.Warning, () => "No disposal event handler for the MonoDetourManager was registered."); } } catch (Exception ex3) { Exception ex4 = ex3; Exception disposalEx = ex4; hook.Owner.Log(MonoDetourLogger.LogChannel.Error, () => $"Disposal event handler threw an exception:\n{disposalEx}"); } finally { hook.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<int, Delegate> getDelegate) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (hook.Manipulator.IsStatic) { return w.Create(OpCodes.Call, hook.Manipulator); } ThrowIfHookManipulatorDelegateIsNull(hook, out Delegate manipulatorDelegate); w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2] { w.Create(OpCodes.Ldc_I4, id), w.CreateCall(getDelegate) })); MethodInfo method = manipulatorDelegate.GetType().GetMethod("Invoke"); return w.Create(OpCodes.Callvirt, (MethodBase)method); } [Conditional("DEBUG")] internal static void DebugValidateCILValidatorNoErrors(IReadOnlyMonoDetourHook hook, MethodBody body) { IInformationalMethodBody informationalMethodBody = body.CreateInformationalSnapshotJIT().AnnotateErrors(); if (informationalMethodBody.HasErrors()) { hook.Owner.Log(MonoDetourLogger.LogChannel.Error, "Hook CIL validation failed! " + hook.Manipulator.Name + "\n" + informationalMethodBody.ToErrorMessageString()); } } } } namespace MonoDetour.Cil { public static class ILContextExtensions { public static string ToAnalyzedString(this ILContext context) { return context.Body.CreateInformationalSnapshotJIT().AnnotateErrors().ToStringWithAnnotations(); } } public class ILManipulationInfo { public delegate void Manipulator(ILManipulationInfo info); private static readonly ReadOnlyCollection<Instruction> emptyCollection = new ReadOnlyCollection<Instruction>(new List<Instruction>()); private ILContext? _original; public MethodBase? Original { get; } public ILContext Context { get; } public ReadOnlyCollection<Instruction> OriginalInstructions { get; } public ILContext UnmanipulatedContext { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0027: Expected O, but got Unknown ILContext obj = _original; if (obj == null) { ILContext val = new ILContext(new DynamicMethodDefinition(Original).Definition); ILContext val2 = val; _original = val; obj = val2; } return obj; } } public ILManipulationInfo(ILContext il, MethodBase? original = null, ReadOnlyCollection<Instruction>? originalInstructions = null) { Original = original; Context = il; OriginalInstructions = originalInstructions ?? emptyCollection; base..ctor(); } public override string ToString() { return Context.ToAnalyzedString(); } } public class ILWeaver : IMonoDetourLogSource { private enum InsertType { BeforeAndStealLabels, Before, After } private enum MatchPassType { StrictNoOriginalPass, RelaxedAllowOriginalPass, IsOriginalPass } private const string obsoleteMessageRemoveAt = "Removing a range by count is prone to causing invalid IL if the target method's instructions have changed. Use ILWeaver.InsertBranchOver instead as it doesn't have this design flaw. Note that these two methods behave slightly differently; please read the method's remarks in detail."; private Instruction current; private readonly List<ILLabel> pendingFutureNextInsertLabels = new List<ILLabel>(); private const string gotoMatchingDocsLink = "<insert documentation link here>"; public ILManipulationInfo ManipulationInfo { get; } public ILContext Context { get; } public ILProcessor IL => Context.IL; public MethodBody Body => Context.Body; public MethodDefinition Method => Context.Method; public Collection<Instruction> Instructions => Context.Instrs; public Instruction Current { get { return current; } set { CurrentTo(value); } } public Instruction Previous => Current.Previous; public Instruction Next => Current.Next; public Instruction First => Instructions[0]; public Instruction Last { get { Collection<Instruction> instructions = Instructions; return instructions[instructions.Count - 1]; } } public int Index { get { return Instructions.IndexOf(Current); } set { CurrentTo(value); } } public MonoDetourLogger.LogChannel LogFilter { get; set; } = MonoDetourLogger.LogChannel.Warning | MonoDetourLogger.LogChannel.Error; public ILWeaver(ILManipulationInfo il) { ManipulationInfo = Helpers.ThrowIfNull(il, "il"); Context = il.Context; current = Context.Instrs[0]; } public ILWeaver(ILWeaver weaver, bool copyState = true) : this(weaver.ManipulationInfo) { if (copyState) { Current = weaver.Current; } } public ILWeaver New() { return new ILWeaver(this, copyState: false); } public ILWeaver Clone() { return new ILWeaver(this); } public IEnumerable<ILLabel> GetIncomingLabelsForCurrent() { return Context.GetIncomingLabels(Current); } public IEnumerable<ILLabel> GetIncomingLabelsFor(Instruction target) { return Context.GetIncomingLabels(target); } public ILWeaver RetargetLabels(IEnumerable<ILLabel> labels, Instruction target) { foreach (ILLabel label in labels) { label.InteropSetTarget(target); } return this; } public ILWeaver RetargetLabels(ILLabel? label, Instruction target) { label?.InteropSetTarget(target); return this; } public ILLabel DefineLabel() { return Context.DefineLabel(); } public ILWeaver DefineLabel(out ILLabel label) { label = Context.DefineLabel(); return this; } public ILWeaver MarkLabelTo(Instruction target, ILLabel label) { Helpers.ThrowIfNull<Instruction>(target, "target"); label.InteropSetTarget(target); return this; } public ILWeaver DefineAndMarkLabelTo(Instruction target, out ILLabel markedLabel) { Helpers.ThrowIfNull<Instruction>(target, "target"); markedLabel = Context.DefineLabel(target); return this; } public ILLabel DefineAndMarkLabelTo(Instruction target) { DefineAndMarkLabelTo(target, out ILLabel markedLabel); return markedLabel; } public ILWeaver MarkLabelToFutureNextInsert(ILLabel label) { Helpers.ThrowIfNull<ILLabel>(label, "label"); pendingFutureNextInsertLabels.Add(label); return this; } public ILWeaver DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel) { futureMarkedLabel = Context.DefineLabel(); pendingFutureNextInsertLabels.Add(futureMarkedLabel); return this; } public ILLabel DefineAndMarkLabelToFutureNextInsert() { DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel); return futureMarkedLabel; } public ILWeaver MarkLabelToCurrentOrFutureNextInsert(ILLabel label) { Helpers.ThrowIfNull<ILLabel>(label, "label"); label.InteropSetTarget(Current); pendingFutureNextInsertLabels.Add(label); return this; } public ILWeaver DefineAndMarkLabelToCurrentOrFutureNextInsert(out ILLabel futureMarkedLabel) { futureMarkedLabel = Context.DefineLabel(Current); pendingFutureNextInsertLabels.Add(futureMarkedLabel); return this; } public ILLabel DefineAndMarkLabelToCurrentOrFutureNextInsert() { DefineAndMarkLabelToCurrentOrFutureNextInsert(out ILLabel futureMarkedLabel); return futureMarkedLabel; } public ILWeaver MarkLabelToCurrent(ILLabel label) { Helpers.ThrowIfNull<ILLabel>(label, "label"); label.InteropSetTarget(Current); return this; } public ILWeaver DefineAndMarkLabelToCurrent(out ILLabel markedLabel) { markedLabel = Context.DefineLabel(Current); return this; } public ILLabel DefineAndMarkLabelToCurrent() { DefineAndMarkLabelToCurrent(out ILLabel markedLabel); return markedLabel; } public ILWeaver MarkLabelToCurrentPrevious(ILLabel label) { Helpers.ThrowIfNull<ILLabel>(label, "label"); label.InteropSetTarget(Current.Previous); return this; } public ILWeaver DefineAndMarkLabelToCurrentPrevious(out ILLabel markedLabel) { markedLabel = Context.DefineLabel(Current.Previous); return this; } public ILLabel DefineAndMarkLabelToCurrentPrevious() { DefineAndMarkLabelToCurrentPrevious(out ILLabel markedLabel); return markedLabel; } public ILWeaver MarkLabelToCurrentNext(ILLabel label) { Helpers.ThrowIfNull<ILLabel>(label, "label"); label.InteropSetTarget(Current.Next); return this; } public ILWeaver DefineAndMarkLabelToCurrentNext(out ILLabel markedLabel) { markedLabel = Context.DefineLabel(Current.Next); return this; } public ILLabel DefineAndMarkLabelToCurrentNext() { DefineAndMarkLabelToCurrentNext(out ILLabel markedLabel); return markedLabel; } public VariableDefinition DeclareVariable(Type type) { DeclareVariable(type, out VariableDefinition variableDefinition); return variableDefinition; } public ILWeaver DeclareVariable(Type type, out VariableDefinition variableDefinition) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown variableDefinition = new VariableDefinition(Context.Import(type)); Body.Variables.Add(variableDefinition); return this; } public ILWeaver Replace(Instruction target, Instruction replacement) { InsertAfter(target, new <>z__ReadOnlySingleElementList<Instruction>(replacement)); Remove(target, out ILLabel orphanedLabel); RetargetLabels(orphanedLabel, replacement); return this; } public ILWeaver ReplaceCurrent(Instruction replacement) { Replace(Current, replacement); return this; } [Obsolete("Removing a range by count is prone to causing invalid IL if the target method's instructions have changed. Use ILWeaver.InsertBranchOver instead as it doesn't have this design flaw. Note that these two methods behave slightly differently; please read the method's remarks in detail.")] public ILWeaver RemoveAt(int index, int instructions, out IEnumerable<ILLabel> orphanedLabels) { int num = index + instructions - 1; int index2 = Index; if (instructions < 0) { throw new IndexOutOfRangeException("Can not remove a negative amount of instructions."); } if (num > Instructions.Count) { throw new IndexOutOfRangeException("Attempted to remove more instructions than there are available."); } if (index2 >= index && index2 <= num) { Current = Instructions[num + 1]; } List<ILLabel> list = new List<ILLabel>(); while (instructions-- > 0) { foreach (ILLabel incomingLabel in Context.GetIncomingLabels(Instructions[index])) { list.Add(incomingLabel); } Instructions.RemoveAt(index); } orphanedLabels = list; return this; } [Obsolete("Removing a range by count is prone to causing invalid IL if the target method's instructions have changed. Use ILWeaver.InsertBranchOver instead as it doesn't have this design flaw. Note that these two methods behave slightly differently; please read the method's remarks in detail.")] public ILWeaver RemoveAtCurrent(int instructions, out IEnumerable<ILLabel> orphanedLabels) { return RemoveAt(Index, instructions, out orphanedLabels); } public ILWeaver Remove(Instruction instruction, out ILLabel? orphanedLabel) { RemoveAt(Instructions.IndexOf(instruction), 1, out IEnumerable<ILLabel> orphanedLabels); orphanedLabel = orphanedLabels.FirstOrDefault(); return this; } public ILWeaver RemoveCurrent(out ILLabel? orphanedLabel) { Instruction next = Next; Remove(Current, out orphanedLabel); CurrentTo(next); return this; } public ILWeaver HandlerCreateCatch(Type? catchType, out WeaverExceptionCatchHandler handler) { handler = new WeaverExceptionCatchHandler(Extensions.Import(IL, catchType ?? typeof(Exception))); return this; } public ILWeaver HandlerCreateFilter(Type? catchType, out WeaverExceptionFilterHandler handler) { handler = new WeaverExceptionFilterHandler(Extensions.Import(IL, catchType ?? typeof(Exception))); return this; } public ILWeaver HandlerCreateFinally(out WeaverExceptionFinallyHandler handler) { handler = new WeaverExceptionFinallyHandler(); return this; } public ILWeaver HandlerCreateFault(out WeaverExceptionFaultHandler handler) { handler = new WeaverExceptionFaultHandler(); return this; } public ILWeaver HandlerSetTryStart(ILLabel tryStart, IWeaverExceptionHandler handler) { handler.TryStart = tryStart; return this; } public ILWeaver HandlerSetTryStart(Instruction tryStart, IWeaverExceptionHandler handler) { handler.TryStart = Context.DefineLabel(tryStart); return this; } public ILWeaver HandlerSetTryEnd(ILLabel tryEnd, IWeaverExceptionHandler handler) { handler.TryEnd = tryEnd; return this; } public ILWeaver HandlerSetTryEnd(Instruction tryEnd, IWeaverExceptionHandler handler) { handler.TryEnd = Context.DefineLabel(tryEnd); return this; } public ILWeaver HandlerSetFilterStart(ILLabel filterStart, WeaverExceptionFilterHandler handler) { handler.FilterStart = filterStart; return this; } public ILWeaver HandlerSetFilterStart(Instruction filterStart, WeaverExceptionFilterHandler handler) { handler.FilterStart = Context.DefineLabel(filterStart); return this; } public ILWeaver HandlerSetHandlerStart(ILLabel handlerStart, IWeaverExceptionHandler handler) { handler.HandlerStart = handlerStart; return this; } public ILWeaver HandlerSetHandlerStart(Instruction handlerStart, IWeaverExceptionHandler handler) { handler.HandlerStart = Context.DefineLabel(handlerStart); return this; } public ILWeaver HandlerSetHandlerEnd(ILLabel handlerEnd, IWeaverExceptionHandler handler) { handler.HandlerEnd = handlerEnd; return this; } public ILWeaver HandlerSetHandlerEnd(Instruction handlerEnd, IWeaverExceptionHandler handler) { handler.HandlerEnd = Context.DefineLabel(handlerEnd); return this; } public ILWeaver HandlerWrapTryCatchStackSizeNonZeroOnCurrent(Type? catchType, [ParamCollection] IEnumerable<Instruction> catchInstructions) { IEnumerable<Instruction> catchInstructions2 = catchInstructions; return HandlerWrapTryCatchStackSizeNonZeroOnCurrent(catchType, delegate { InsertAfterCurrent(catchInstructions2); }); } public ILWeaver HandlerWrapTryCatchStackSizeNonZeroOnCurrent(Type? catchType, Action writeCatch) { Action writeCatch2 = writeCatch; Instruction afterCatch; return HandlerWrapTryCatchStackSizeNonZero(catchType, Current, out afterCatch, delegate(Instruction tryEnd) { CurrentTo(tryEnd); writeCatch2(); return Current; }).CurrentTo(afterCatch); } public ILWeaver HandlerWrapTryCatchStackSizeNonZero(Type? catchType, Instruction origin, out Instruction afterCatch, [ParamCollection] IEnumerable<Instruction> catchInstructions) { IEnumerable<Instruction> catchInstructions2 = catchInstructions; HandlerWrapTryCatchStackSizeNonZero(catchType, origin, out afterCatch, delegate(Instruction tryEnd) { InsertAfter(tryEnd, catchInstructions2); return catchInstructions2.Last(); }); return this; } public ILWeaver HandlerWrapTryCatchStackSizeNonZero(Type? catchType, Instruction origin, out Instruction afterCatch, Func<Instruction, Instruction> writeCatch) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) HandlerCreateCatch(catchType, out WeaverExceptionCatchHandler handler); var (tryStart, val) = GetStackSizeZeroAreaContinuous(origin); HandlerSetTryStart(tryStart, handler); HandlerSetTryEnd(val, handler); Instruction val2 = writeCatch(val); HandlerSetHandlerEnd(val2, handler); afterCatch = val2.Next; if (afterCatch == null) { afterCatch = Create(OpCodes.Nop); InsertAfter(val2, new <>z__ReadOnlySingleElementList<Instruction>(afterCatch)); } HandlerApply(handler); return this; } public ILWeaver HandlerApply(IWeaverExceptionHandler handler) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Invalid comparison between Unknown and I4 //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Invalid comparison between Unknown and I4 //IL_02c7: U
Renderer/BepInEx/core/com.github.MonoDetour.Reflection.dll
Decompiled 3 weeks 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.5.0")] [assembly: AssemblyInformationalVersion("0.7.5+00379e1a07f34624316c37f1b0aa58b5f9bcf6b9")] [assembly: AssemblyProduct("MonoDetour.Reflection")] [assembly: AssemblyTitle("MonoDetour.Reflection")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.5.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 3 weeks agousing System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; 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.5.0")] [assembly: AssemblyInformationalVersion("0.7.5+00379e1a07f34624316c37f1b0aa58b5f9bcf6b9")] [assembly: AssemblyProduct("MonoDetour.Bindings.Reorg")] [assembly: AssemblyTitle("MonoDetour.Bindings.Reorg")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")] [assembly: AssemblyVersion("0.7.5.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; } else { IsReorg = false; } } } } 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 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>(); private static bool TryGetDetourConfig<TKey>(this IDictionary<TKey, object> data, TKey key, [NotNullWhen(true)] out DetourConfig? value) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown if (data.TryGetValue(key, out object value2)) { value = (DetourConfig)value2; return true; } value = null; return false; } [MethodImpl(MethodImplOptions.NoInlining)] internal static ILHook ConstructILHook(MethodBase target, Manipulator manipulator, IMonoDetourConfig? config, string id) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown if (config == null) { DetourConfig defaultConfig = DetourContext.GetDefaultConfig(); if (defaultConfig == null) { if (!idToConfig.TryGetDetourConfig(id, out DetourConfig value)) { value = new DetourConfig(id, (int?)0, (IEnumerable<string>)null, (IEnumerable<string>)null); idToConfig.TryAdd(id, value); } return new ILHook(target, manipulator, value, false); } if (!defaultConfig.Priority.HasValue) { if (!configToConfig.TryGetDetourConfig(defaultConfig, out DetourConfig value2)) { value2 = defaultConfig.WithPriority((int?)0); configToConfig.TryAdd(defaultConfig, value2); } return new ILHook(target, manipulator, value2, false); } return new ILHook(target, manipulator, defaultConfig, false); } if (!interfaceToConfig.TryGetDetourConfig(config, out DetourConfig value3)) { value3 = new DetourConfig(config.OverrideId ?? id, (int?)config.Priority, config.Before, config.After); interfaceToConfig.TryAdd(config, value3); } return new ILHook(target, manipulator, value3, false); } } } namespace MonoDetour.Bindings.Reorg.MonoModUtils { internal static class ReorgFastDelegateInvokers { [MethodImpl(MethodImplOptions.NoInlining)] internal static (MethodInfo Invoker, Type Delegate)? GetDelegateInvoker(Type delegateType) { return FastDelegateInvokers.GetDelegateInvoker(delegateType); } } internal static class ReorgILContext { [CompilerGenerated] private sealed class <GetReference>d__2 : 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__2(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_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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) DynamicReferenceCell val; switch (<>1__state) { default: return false; case 0: { <>1__state = -1; if ((object)Self_GetValueT_ii == null) { Self_GetValueT_ii = typeof(DynamicReferenceManager).GetMethod("GetValueT", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[2] { typeof(int), typeof(int) }, null) ?? throw new InvalidOperationException("GetValueT doesn't exist?!?!?!?"); } <cellRef>5__2 = context.GetReferenceCell(id); <il>5__3 = context.IL; ILProcessor obj2 = <il>5__3; OpCode ldc_I2 = OpCodes.Ldc_I4; val = (DynamicReferenceCell)<cellRef>5__2; <>2__current = obj2.Create(ldc_I2, ((DynamicReferenceCell)(ref val)).Index); <>1__state = 1; return true; } case 1: { <>1__state = -1; ILProcessor obj = <il>5__3; OpCode ldc_I = OpCodes.Ldc_I4; val = (DynamicReferenceCell)<cellRef>5__2; <>2__current = obj.Create(ldc_I, ((DynamicReferenceCell)(ref val)).Hash); <>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__2 <GetReference>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetReference>d__ = this; } else { <GetReference>d__ = new <GetReference>d__2(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; [MethodImpl(MethodImplOptions.NoInlining)] internal static int AddReference<T>(ILContext context, in T value) { return context.AddReference<T>(ref value); } [MethodImpl(MethodImplOptions.NoInlining)] [IteratorStateMachine(typeof(<GetReference>d__2))] internal static IEnumerable<Instruction> GetReference(Type type, ILContext context, int id) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetReference>d__2(-2) { <>3__type = type, <>3__context = context, <>3__id = id }; } } internal static class ReorgILCursor { [MethodImpl(MethodImplOptions.NoInlining)] internal static int EmitReference<T>(ILCursor cursor, in T? t) { return cursor.EmitReference<T>(ref t); } } internal static class ReorgILLabel { [MethodImpl(MethodImplOptions.NoInlining)] internal static Instruction? GetTarget(ILLabel label) { return label.Target; } [MethodImpl(MethodImplOptions.NoInlining)] internal static void SetTarget(ILLabel label, Instruction value) { label.Target = value; } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] 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] [DebuggerNonUserCode] 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] [DebuggerNonUserCode] 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] [DebuggerNonUserCode] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } }