Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of PatchDumper v1.0.0
patchers/PatchDumper/PatchDumperPatcher.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MonoMod.RuntimeDetour.HookGen; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")] [assembly: AssemblyCompany("PatchDumperPatcher")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e84cbf52fe999cf0bffaaf174136208d93cdfee5")] [assembly: AssemblyProduct("PatchDumperPatcher")] [assembly: AssemblyTitle("PatchDumperPatcher")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PatchDumperPatcher { public class BaseDetourInfo { public IDetour Detour { get; } public Assembly Owner { get; } public virtual MethodBase From { get; } public virtual MethodBase To { get; } public BaseDetourInfo(IDetour detour, MethodBase from, MethodBase to, Assembly owner) { Detour = detour ?? throw new ArgumentNullException("detour"); Owner = owner; From = from; To = to; } } internal static class Log { private static readonly ManualLogSource _logSource = Logger.CreateLogSource("PatchDumperPatcher"); private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber) { int num = callerPath.LastIndexOf("PatchDumperPatcher\\"); if (num >= 0) { callerPath = callerPath.Substring(num + "PatchDumperPatcher\\".Length); } return $"{callerPath}:{callerLineNumber} ({callerMemberName}) "; } internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogDebug((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Debug_NoCallerPrefix(object data) { _logSource.LogDebug(data); } internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogError((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Error_NoCallerPrefix(object data) { _logSource.LogError(data); } internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogFatal((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Fatal_NoCallerPrefix(object data) { _logSource.LogFatal(data); } internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogInfo((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Info_NoCallerPrefix(object data) { _logSource.LogInfo(data); } internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogMessage((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Message_NoCallerPrefix(object data) { _logSource.LogMessage(data); } internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogWarning((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Warning_NoCallerPrefix(object data) { _logSource.LogWarning(data); } } internal class NativeDetourInfo : BaseDetourInfo { private readonly NativeDetour _nativeDetour; private readonly IntPtr _fromPtr; private MethodBase _from; private readonly IntPtr _toPtr; private MethodBase _to; public override MethodBase From { get { if (_from == null) { _from = findPinnedMethodFromPtr(_fromPtr); } return _from; } } public override MethodBase To { get { if (_to == null) { _to = findPinnedMethodFromPtr(_toPtr); } return _to; } } private MethodBase findPinnedMethodFromPtr(IntPtr ptr) { foreach (MethodBase item in _nativeDetour._Pinned) { IntPtr nativeStart = DetourHelper.GetNativeStart(DetourHelper.Pin<MethodBase>(item)); if (nativeStart == ptr) { return item; } } return null; } internal NativeDetourInfo(NativeDetour detour, IntPtr from, IntPtr to, Assembly owner) : base((IDetour)(object)detour, null, null, owner) { _nativeDetour = detour; _fromPtr = from; _toPtr = to; } } public static class PatcherMain { private static readonly List<BaseDetourInfo> _activeDetours; public static readonly ReadOnlyCollection<BaseDetourInfo> ActiveDetours; private static bool _activeDetoursDirty; private static readonly Dictionary<MethodBase, List<BaseDetourInfo>> _activeDetoursMap; private static readonly ReadOnlyDictionary<MethodBase, List<BaseDetourInfo>> _readOnlyActiveDetoursMap; private static readonly string[] _hookTypes; private static readonly string[] _ignoreAssemblies; public static ReadOnlyDictionary<MethodBase, List<BaseDetourInfo>> ActiveDetoursMap { get { refreshActiveDetours(); return _readOnlyActiveDetoursMap; } } public static IEnumerable<string> TargetDLLs { get; } private static void refreshActiveDetours() { if (!_activeDetoursDirty) { return; } _activeDetoursDirty = false; _activeDetoursMap.Clear(); foreach (BaseDetourInfo activeDetour in _activeDetours) { if (!(activeDetour.From == null)) { if (!_activeDetoursMap.TryGetValue(activeDetour.From, out var value)) { value = new List<BaseDetourInfo>(); _activeDetoursMap.Add(activeDetour.From, value); } value.Add(activeDetour); } } } static PatcherMain() { _activeDetours = new List<BaseDetourInfo>(); ActiveDetours = _activeDetours.AsReadOnly(); _activeDetoursDirty = false; _activeDetoursMap = new Dictionary<MethodBase, List<BaseDetourInfo>>(); _readOnlyActiveDetoursMap = new ReadOnlyDictionary<MethodBase, List<BaseDetourInfo>>(_activeDetoursMap); _hookTypes = new string[4] { typeof(Hook).FullName, typeof(ILHook).FullName, typeof(Detour).FullName, typeof(NativeDetour).FullName }; _ignoreAssemblies = new string[1] { typeof(HookEndpointManager).Assembly.GetName().Name }; TargetDLLs = Array.Empty<string>(); Array.Sort(_hookTypes, (IComparer<string>?)StringComparer.OrdinalIgnoreCase); Array.Sort(_ignoreAssemblies, (IComparer<string>?)StringComparer.OrdinalIgnoreCase); } public static void Patch(AssemblyDefinition assembly) { } public static void Initialize() { Util.AppendDelegate(ref Hook.OnDetour, registerHook); Util.AppendDelegate(ref Hook.OnUndo, unregisterDetour); Util.AppendDelegate(ref ILHook.OnDetour, registerILHook); Util.AppendDelegate(ref ILHook.OnUndo, unregisterDetour); Util.AppendDelegate(ref Detour.OnDetour, registerDetour); Util.AppendDelegate(ref Detour.OnUndo, unregisterDetour); Util.AppendDelegate(ref NativeDetour.OnDetour, registerNativeDetour); Util.AppendDelegate(ref NativeDetour.OnUndo, unregisterDetour); } private static void registerDetourInfo(BaseDetourInfo detourInfo) { _activeDetours.Add(detourInfo); _activeDetoursDirty = true; } private static bool unregisterDetour(IDetour detour) { if (_activeDetours.RemoveAll((BaseDetourInfo d) => d.Detour == detour) > 0) { _activeDetoursDirty = true; } return true; } private static bool registerHook(Hook hook, MethodBase from, MethodBase to, object target) { registerDetourInfo(new BaseDetourInfo((IDetour)(object)hook, from, to, findHookOwner())); return true; } private static bool registerILHook(ILHook hook, MethodBase method, Manipulator manipulator) { registerDetourInfo(new BaseDetourInfo((IDetour)(object)hook, method, ((Delegate)(object)manipulator).Method, findHookOwner())); return true; } private static bool registerDetour(Detour detour, MethodBase from, MethodBase to) { registerDetourInfo(new BaseDetourInfo((IDetour)(object)detour, from, to, findHookOwner())); return true; } private static bool registerNativeDetour(NativeDetour nativeDetour, MethodBase method, IntPtr from, IntPtr to) { registerDetourInfo(new NativeDetourInfo(nativeDetour, from, to, findHookOwner())); return true; } private static Assembly findHookOwner(StackTrace stackTrace = null) { if (stackTrace == null) { stackTrace = new StackTrace(); } StackFrame[] frames = stackTrace.GetFrames(); Assembly assembly = null; for (int num = frames.Length - 1; num >= 0; num--) { Type type = frames[num].GetMethod()?.DeclaringType; if (!(type == null) && Array.BinarySearch<string>(_hookTypes, type.FullName, (IComparer<string>?)StringComparer.OrdinalIgnoreCase) >= 0) { for (num++; num < frames.Length; num++) { Assembly assembly2 = frames[num].GetMethod()?.DeclaringType?.Assembly; if (!(assembly2 == null)) { string name = assembly2.GetName().Name; if (Array.BinarySearch(_ignoreAssemblies, name, (IComparer<string>?)StringComparer.OrdinalIgnoreCase) < 0 && !name.StartsWith("MMHOOK_", StringComparison.OrdinalIgnoreCase)) { assembly = assembly2; break; } } } break; } } if (!(assembly != null)) { Log.Warning($"Failed to find owner assembly for stack trace {stackTrace}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumperPatcher\\PatcherMain.cs", "findHookOwner", 175); } return assembly; } } internal static class Util { public static void AppendDelegate<TDelegate>(ref TDelegate del, TDelegate add) where TDelegate : Delegate { del = (TDelegate)Delegate.Combine(del, add); } public static void RemoveDelegate<TDelegate>(ref TDelegate del, TDelegate remove, bool all) where TDelegate : Delegate { del = (TDelegate)(all ? Delegate.RemoveAll(del, remove) : Delegate.Remove(del, remove)); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/PatchDumper/PatchDumper.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HG.Reflection; using HarmonyLib; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; using Mono.Collections.Generic; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MonoMod.Utils; using PatchDumperPatcher; using RoR2; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")] [assembly: AssemblyCompany("PatchDumper")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e84cbf52fe999cf0bffaaf174136208d93cdfee5")] [assembly: AssemblyProduct("PatchDumper")] [assembly: AssemblyTitle("PatchDumper")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PatchDumper { public static class HookExtensions { public static bool TryGetUnderlyingDetour(this IDetour detour, out Detour underlying) { Hook val = (Hook)(object)((detour is Hook) ? detour : null); if (val == null) { ILHook val2 = (ILHook)(object)((detour is ILHook) ? detour : null); if (val2 != null) { underlying = val2._Ctx.Detour; } else { underlying = null; } } else { underlying = val.Detour; } return underlying != null; } } internal static class Log { internal static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber) { int num = callerPath.LastIndexOf("PatchDumper\\"); if (num >= 0) { callerPath = callerPath.Substring(num + "PatchDumper\\".Length); } return $"{callerPath}:{callerLineNumber} ({callerMemberName}) "; } [Conditional("DEBUG")] internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogDebug((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } [Conditional("DEBUG")] internal static void Debug_NoCallerPrefix(object data) { _logSource.LogDebug(data); } internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogError((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Error_NoCallerPrefix(object data) { _logSource.LogError(data); } internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogFatal((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Fatal_NoCallerPrefix(object data) { _logSource.LogFatal(data); } internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogInfo((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Info_NoCallerPrefix(object data) { _logSource.LogInfo(data); } internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogMessage((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Message_NoCallerPrefix(object data) { _logSource.LogMessage(data); } internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogWarning((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Warning_NoCallerPrefix(object data) { _logSource.LogWarning(data); } } [BepInPlugin("Gorakh.PatchDumper", "PatchDumper", "1.0.0")] public class PatchDumperPlugin : BaseUnityPlugin { public const string PluginGUID = "Gorakh.PatchDumper"; public const string PluginAuthor = "Gorakh"; public const string PluginName = "PatchDumper"; public const string PluginVersion = "1.0.0"; internal static PatchDumperPlugin Instance { get; private set; } private void Awake() { Stopwatch stopwatch = Stopwatch.StartNew(); Log.Init(((BaseUnityPlugin)this).Logger); Instance = SingletonHelper.Assign<PatchDumperPlugin>(Instance, this); stopwatch.Stop(); Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds"); } private void OnDestroy() { Instance = SingletonHelper.Unassign<PatchDumperPlugin>(Instance, this); } [ConCommand(commandName = "dump_hooks")] private static void CCDumpHooks(ConCommandArgs args) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_002b: Expected O, but got Unknown AssemblyDefinition val = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition("Hooks", new Version(0, 0, 0, 0)), "Hooks.dll", new ModuleParameters { Kind = (ModuleKind)0 }); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { val.MainModule.AssemblyReferences.Add(AssemblyNameReference.Parse(assembly.FullName)); } PatchDumperProcessor patchDumperProcessor = new PatchDumperProcessor(val); foreach (var (method, detours) in PatcherMain.ActiveDetoursMap) { patchDumperProcessor.AddDetours(method, detours); } patchDumperProcessor.Validate(); patchDumperProcessor.OutputAssembly.Write(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location), "Hooks.dll")); } } internal class PatchDumperProcessor { private static readonly Assembly _harmonyAssembly = typeof(Harmony).Assembly; public readonly AssemblyDefinition OutputAssembly; private readonly TypeReference _attributeTypeRef; private readonly TypeReference _voidTypeRef; private readonly TypeReference _stringTypeRef; private readonly MethodDefinition _patchInfoAttributeConstructor; private readonly Dictionary<Type, TypeDefinition> _cachedContainerTypes = new Dictionary<Type, TypeDefinition>(); public PatchDumperProcessor(AssemblyDefinition outputAssembly) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown OutputAssembly = outputAssembly; ModuleDefinition mainModule = OutputAssembly.MainModule; _attributeTypeRef = mainModule.ImportReference(typeof(Attribute)); _voidTypeRef = mainModule.ImportReference(typeof(void)); _stringTypeRef = mainModule.ImportReference(typeof(string)); TypeDefinition val = new TypeDefinition("", "PatchInfoAttribute", (TypeAttributes)1048832, _attributeTypeRef); _patchInfoAttributeConstructor = new MethodDefinition(".ctor", (MethodAttributes)6278, _voidTypeRef); ((MethodReference)_patchInfoAttributeConstructor).Parameters.Add(new ParameterDefinition("type", (ParameterAttributes)0, _stringTypeRef)); ((MethodReference)_patchInfoAttributeConstructor).Parameters.Add(new ParameterDefinition("owner", (ParameterAttributes)0, _stringTypeRef)); val.Methods.Add(_patchInfoAttributeConstructor); OutputAssembly.MainModule.Types.Add(val); } private TypeDefinition getOrCreateContainerType(Type type) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown if (type.IsGenericType) { type = type.GetGenericTypeDefinition(); } if (_cachedContainerTypes.TryGetValue(type, out var value)) { return value; } string text = type.Name; int num = text.IndexOf('`'); if (num >= 0) { text = text.Remove(num); } Type declaringType = type.DeclaringType; TypeDefinition val; if (declaringType != null) { TypeDefinition orCreateContainerType = getOrCreateContainerType(declaringType); val = new TypeDefinition("", text, (TypeAttributes)385); orCreateContainerType.NestedTypes.Add(val); } else { string @namespace = type.Namespace; @namespace = ((!string.IsNullOrEmpty(@namespace)) ? ("Hook." + @namespace) : "Hook"); val = new TypeDefinition(@namespace, text, (TypeAttributes)385); OutputAssembly.MainModule.Types.Add(val); } _cachedContainerTypes.Add(type, val); return val; } public void AddDetours(MethodBase method, List<BaseDetourInfo> detours) { if (method == null || detours == null) { return; } int count = detours.Count; if (count <= 0) { return; } List<BaseDetourInfo> list = new List<BaseDetourInfo>(count); List<BaseDetourInfo> list2 = new List<BaseDetourInfo>(count); List<BaseDetourInfo> list3 = new List<BaseDetourInfo>(count); List<BaseDetourInfo> list4 = new List<BaseDetourInfo>(count); foreach (BaseDetourInfo detour2 in detours) { IDetour detour = detour2.Detour; IDetour val = detour; if (!(val is Hook)) { if (!(val is ILHook)) { if (!(val is NativeDetour)) { if (val is Detour) { list4.Add(detour2); } } else { list3.Add(detour2); } } else { list2.Add(detour2); } } else { list.Add(detour2); } } foreach (BaseDetourInfo detour3 in detours) { if (detour3.Detour.TryGetUnderlyingDetour(out var underlyingDetour)) { list4.RemoveAll((BaseDetourInfo d) => d.Detour == underlyingDetour); } } sortDetours<ILHook>(list2); sortDetours<Detour>(list4); addILHookMethods(method, list2); Log.Info_NoCallerPrefix(GeneralExtensions.FullDescription(method) + " detours:"); foreach (BaseDetourInfo detour4 in detours) { string name = ((object)detour4.Detour).GetType().Name; MethodBase to = detour4.To; Log.Info_NoCallerPrefix(" " + name + ": " + (((object)to != null) ? GeneralExtensions.FullDescription(to) : null)); } } private void addILHookMethods(MethodBase method, List<BaseDetourInfo> ilHookDetourInfos) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown if (!MethodBaseExtensions.HasMethodBody(method)) { Log.Error("Method has no body, cannot dump il hooks: " + GeneralExtensions.FullDescription(method), "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "addILHookMethods", 161); } else { if (ilHookDetourInfos.Count <= 0) { return; } Log.Info("Dumping IL hooks for " + GeneralExtensions.FullDescription(method) + ":", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "addILHookMethods", 168); TypeDefinition orCreateContainerType = getOrCreateContainerType(method.DeclaringType); DynamicMethodDefinition val = new DynamicMethodDefinition(method); try { MethodDefinition definition = val.Definition; ((MemberReference)definition).Name = method.Name; definition.DeclaringType = orCreateContainerType; definition.CustomAttributes.Clear(); IILReferenceBag referenceBag = (IILReferenceBag)new RuntimeILReferenceBag(); foreach (BaseDetourInfo ilHookDetourInfo in ilHookDetourInfos) { ILHook val2 = (ILHook)ilHookDetourInfo.Detour; Log.Info(" - Applying manipulator " + GeneralExtensions.FullDescription((MethodBase)((Delegate)(object)val2.Manipulator).Method), "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "addILHookMethods", 184); ILContext val3 = new ILContext(definition); try { val3.ReferenceBag = referenceBag; try { val3.Invoke(val2.Manipulator); } catch (Exception arg) { Log.Error_NoCallerPrefix($"Exception invoking hook ILManipulator {GeneralExtensions.FullDescription((MethodBase)((Delegate)(object)val2.Manipulator).Method)}: {arg}"); } } finally { ((IDisposable)val3)?.Dispose(); } } addPatchInfoAttributes(definition, ilHookDetourInfos); importMethodReferences(definition); orCreateContainerType.Methods.Add(definition); } finally { ((IDisposable)val)?.Dispose(); } } } private void addPatchInfoAttributes(MethodDefinition method, List<BaseDetourInfo> detourInfos) { foreach (BaseDetourInfo detourInfo in detourInfos) { addPatchInfoAttribute(method, detourInfo); } } private void addPatchInfoAttribute(MethodDefinition method, BaseDetourInfo detourInfo) { if (detourInfo.Owner == _harmonyAssembly) { Patches patchInfo = Harmony.GetPatchInfo(detourInfo.From); if (patchInfo != null) { bool flag = false; foreach (Patch prefix in patchInfo.Prefixes) { addPatchAttribute("HarmonyPrefix", prefix); flag = true; } foreach (Patch postfix in patchInfo.Postfixes) { addPatchAttribute("HarmonyPostfix", postfix); flag = true; } foreach (Patch transpiler in patchInfo.Transpilers) { addPatchAttribute("HarmonyTranspiler", transpiler); flag = true; } foreach (Patch finalizer in patchInfo.Finalizers) { addPatchAttribute("HarmonyFinalizer", finalizer); flag = true; } foreach (Patch iLManipulator in patchInfo.ILManipulators) { addPatchAttribute("HarmonyManipulator", iLManipulator); flag = true; } if (flag) { return; } } } addAttribute(((object)detourInfo.Detour).GetType().Name, detourInfo.Owner?.FullName); void addAttribute(string type, string owner) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(type)) { type = string.Empty; } if (string.IsNullOrEmpty(owner)) { owner = string.Empty; } CustomAttribute val = new CustomAttribute((MethodReference)(object)_patchInfoAttributeConstructor); val.ConstructorArguments.Add(new CustomAttributeArgument(_stringTypeRef, (object)type)); val.ConstructorArguments.Add(new CustomAttributeArgument(_stringTypeRef, (object)owner)); method.CustomAttributes.Add(val); } void addPatchAttribute(string type, Patch patch) { addAttribute(type, patch.PatchMethod?.DeclaringType?.Assembly?.FullName); } } private void importMethodReferences(MethodDefinition method) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0193: Unknown result type (might be due to invalid IL or missing references) ((MethodReference)method).ReturnType = OutputAssembly.MainModule.ImportReference(((MethodReference)method).ReturnType); Enumerator<ParameterDefinition> enumerator = ((MethodReference)method).Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; ((ParameterReference)current).ParameterType = OutputAssembly.MainModule.ImportReference(((ParameterReference)current).ParameterType); } } finally { ((IDisposable)enumerator).Dispose(); } Enumerator<CustomAttribute> enumerator2 = method.CustomAttributes.GetEnumerator(); try { while (enumerator2.MoveNext()) { CustomAttribute current2 = enumerator2.Current; current2.Constructor = OutputAssembly.MainModule.ImportReference(current2.Constructor); } } finally { ((IDisposable)enumerator2).Dispose(); } Enumerator<VariableDefinition> enumerator3 = method.Body.Variables.GetEnumerator(); try { while (enumerator3.MoveNext()) { VariableDefinition current3 = enumerator3.Current; ((VariableReference)current3).VariableType = OutputAssembly.MainModule.ImportReference(((VariableReference)current3).VariableType); } } finally { ((IDisposable)enumerator3).Dispose(); } Enumerator<ExceptionHandler> enumerator4 = method.Body.ExceptionHandlers.GetEnumerator(); try { while (enumerator4.MoveNext()) { ExceptionHandler current4 = enumerator4.Current; if (current4.CatchType != null) { current4.CatchType = OutputAssembly.MainModule.ImportReference(current4.CatchType); } } } finally { ((IDisposable)enumerator4).Dispose(); } Enumerator<Instruction> enumerator5 = method.Body.Instructions.GetEnumerator(); try { while (enumerator5.MoveNext()) { Instruction current5 = enumerator5.Current; object operand = current5.Operand; object obj = operand; IMetadataTokenProvider val = (IMetadataTokenProvider)((obj is IMetadataTokenProvider) ? obj : null); if (val == null) { if (obj is MethodBase methodBase && methodBase.DeclaringType != null) { current5.Operand = OutputAssembly.MainModule.ImportReference(methodBase); } } else { current5.Operand = Extensions.ImportReference(OutputAssembly.MainModule, val); } } } finally { ((IDisposable)enumerator5).Dispose(); } } private static void sortDetours<TDetour>(List<BaseDetourInfo> detourInfos) where TDetour : ISortableDetour { if (detourInfos == null || detourInfos.Count <= 1) { return; } List<TDetour> list = new List<TDetour>(detourInfos.Count); foreach (BaseDetourInfo detourInfo in detourInfos) { list.Add((TDetour)(object)detourInfo.Detour); } DetourSorter<TDetour>.Sort(list); for (int i = 0; i < list.Count; i++) { TDetour detour = list[i]; int num = detourInfos.FindIndex(i, (BaseDetourInfo d) => d.Detour == (object)detour); if (num == -1) { throw new InvalidOperationException("Failed to find detour in list, collection was modified"); } if (num != i) { int index = i; int index2 = num; BaseDetourInfo value = detourInfos[num]; BaseDetourInfo value2 = detourInfos[i]; detourInfos[index] = value; detourInfos[index2] = value2; } } } public void Validate() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05a9: Unknown result type (might be due to invalid IL or missing references) //IL_05ad: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Invalid comparison between Unknown and I4 //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Invalid comparison between Unknown and I4 //IL_008f: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Invalid comparison between Unknown and I4 //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Invalid comparison between Unknown and I4 //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) Enumerator<ModuleDefinition> enumerator = OutputAssembly.Modules.GetEnumerator(); try { while (enumerator.MoveNext()) { ModuleDefinition current = enumerator.Current; List<TypeDefinition> list = new List<TypeDefinition>(); foreach (TypeDefinition allType in ModuleDefinitionRocks.GetAllTypes(current)) { List<MethodDefinition> list2 = new List<MethodDefinition>(); Enumerator<MethodDefinition> enumerator3 = allType.Methods.GetEnumerator(); try { while (enumerator3.MoveNext()) { MethodDefinition current3 = enumerator3.Current; bool flag = false; Enumerator<Instruction> enumerator4 = current3.Body.Instructions.GetEnumerator(); try { while (enumerator4.MoveNext()) { Instruction current4 = enumerator4.Current; OpCode opCode = current4.OpCode; if ((int)((OpCode)(ref opCode)).FlowControl == 2) { if (current4.Operand is MethodBase methodBase) { try { current4.Operand = current.ImportReference(methodBase); Log.Info($"Converted invalid call operand {GeneralExtensions.FullDescription(methodBase)} to {current4.Operand} at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 375); } catch (Exception ex) { Log.Error($"Failed to convert invalid call operand {GeneralExtensions.FullDescription(methodBase)} at {current4.Offset:X4} in {((MemberReference)current3).FullName}: {ex}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 379); } } if (!(current4.Operand is IMethodSignature)) { Log.Error(string.Format("Invalid call operand {0} ({1}) at {2:X4} in {3}", current4.Operand, current4.Operand?.GetType()?.FullName ?? "null", current4.Offset, ((MemberReference)current3).FullName), "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 385); flag = true; } } opCode = current4.OpCode; OperandType operandType = ((OpCode)(ref opCode)).OperandType; OperandType val = operandType; if ((int)val == 1 || (int)val == 4 || val - 11 <= 1) { if (current4.Operand is FieldInfo fieldInfo) { try { current4.Operand = current.ImportReference(fieldInfo); Log.Info($"Converted invalid inline field operand {fieldInfo.DeclaringType.FullName}.{fieldInfo.Name} to {current4.Operand} at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 402); } catch (Exception ex2) { Log.Error($"Failed to convert invalid inline field operand {fieldInfo.DeclaringType.FullName}.{fieldInfo.Name} at {current4.Offset:X4} in {((MemberReference)current3).FullName}: {ex2}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 406); } } else if (current4.Operand is MethodBase methodBase2) { try { current4.Operand = current.ImportReference(methodBase2); Log.Info($"Converted invalid inline method operand {GeneralExtensions.FullDescription(methodBase2)} to {current4.Operand} at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 414); } catch (Exception ex3) { Log.Error($"Failed to convert invalid inline method operand {GeneralExtensions.FullDescription(methodBase2)} at {current4.Offset:X4} in {((MemberReference)current3).FullName}: {ex3}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 418); } } else if (current4.Operand is Type type) { try { current4.Operand = current.ImportReference(type); Log.Info($"Converted invalid inline type operand {GeneralExtensions.FullDescription(type)} to {current4.Operand} at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 426); } catch (Exception ex4) { Log.Error($"Failed to convert invalid inline type operand {GeneralExtensions.FullDescription(type)} at {current4.Offset:X4} in {((MemberReference)current3).FullName}: {ex4}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 430); } } else if (!(current4.Operand is IMetadataTokenProvider)) { Log.Warning($"Unknown inline operand {current4.Operand} ({current4.Operand?.GetType()?.FullName}) at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 435); } if (!(current4.Operand is IMetadataTokenProvider)) { object[] array = new object[6]; opCode = current4.OpCode; array[0] = ((OpCode)(ref opCode)).OperandType; opCode = current4.OpCode; array[1] = ((OpCode)(ref opCode)).Name; array[2] = current4.Operand; array[3] = current4.Operand?.GetType()?.FullName ?? "null"; array[4] = current4.Offset; array[5] = ((MemberReference)current3).FullName; Log.Error(string.Format("Invalid {0} ({1}) operand {2} ({3}) at {4:X4} in {5}", array), "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 440); flag = true; } } object operand = current4.Operand; IMemberDefinition val2 = (IMemberDefinition)((operand is IMemberDefinition) ? operand : null); if (val2 != null && val2.DeclaringType == null) { Log.Error($"Invalid member reference in method {((MemberReference)current3).FullName} at {current4.Offset:X4} ({val2})", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 451); flag = true; } } } finally { ((IDisposable)enumerator4).Dispose(); } if (flag) { list2.Add(current3); } } } finally { ((IDisposable)enumerator3).Dispose(); } foreach (MethodDefinition item in list2) { allType.Methods.Remove(item); } } } } finally { ((IDisposable)enumerator).Dispose(); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }