Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of PatchDumper v1.0.0
patchers/PatchDumper/PatchDumperPatcher.dll
Decompiled 7 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 7 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) { } } }