Decompiled source of BepInExPack Romestead v0.4.1
BepInExPack/BepInEx/core/0Harmony.dll
Decompiled a day 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.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using System.Threading; using HarmonyLib.Internal.Patching; using HarmonyLib.Internal.RuntimeFixes; using HarmonyLib.Internal.Util; using HarmonyLib.Public.Patching; using HarmonyLib.Tools; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Mdb; using Mono.Cecil.Pdb; using Mono.Cecil.Rocks; using Mono.Collections.Generic; using Mono.CompilerServices.SymbolWriter; using MonoMod.Cil; using MonoMod.Core.Platforms; using MonoMod.RuntimeDetour; using MonoMod.Utils; using MonoMod.Utils.Cil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: ComVisible(false)] [assembly: InternalsVisibleTo("HarmonyTests")] [assembly: InternalsVisibleTo("MonoMod.Utils.Cil.ILGeneratorProxy")] [assembly: Guid("69aee16a-b6e7-4642-8081-3928b32455df")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("BepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © BepInEx 2022")] [assembly: AssemblyDescription("A general non-destructive patch library for .NET and Mono modules")] [assembly: AssemblyFileVersion("2.16.1.0")] [assembly: AssemblyInformationalVersion("2.16.1+02a98f540fa12ac4656f189a3cf67b0c96cc68f7")] [assembly: AssemblyProduct("HarmonyX")] [assembly: AssemblyTitle("0Harmony")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/BepInEx/HarmonyX")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.16.1.0")] [assembly: TypeForwardedTo(typeof(AssemblyAttributes))] [assembly: TypeForwardedTo(typeof(AssemblyDefinition))] [assembly: TypeForwardedTo(typeof(AssemblyHashAlgorithm))] [assembly: TypeForwardedTo(typeof(AssemblyNameDefinition))] [assembly: TypeForwardedTo(typeof(AssemblyNameReference))] [assembly: TypeForwardedTo(typeof(AssemblyResolutionException))] [assembly: TypeForwardedTo(typeof(ByReferenceType))] [assembly: TypeForwardedTo(typeof(CallSite))] [assembly: TypeForwardedTo(typeof(Code))] [assembly: TypeForwardedTo(typeof(ConstantDebugInformation))] [assembly: TypeForwardedTo(typeof(CustomDebugInformation))] [assembly: TypeForwardedTo(typeof(CustomDebugInformationKind))] [assembly: TypeForwardedTo(typeof(DebugInformation))] [assembly: TypeForwardedTo(typeof(Document))] [assembly: TypeForwardedTo(typeof(DocumentHashAlgorithm))] [assembly: TypeForwardedTo(typeof(DocumentLanguage))] [assembly: TypeForwardedTo(typeof(DocumentLanguageVendor))] [assembly: TypeForwardedTo(typeof(DocumentType))] [assembly: TypeForwardedTo(typeof(ExceptionHandler))] [assembly: TypeForwardedTo(typeof(ExceptionHandlerType))] [assembly: TypeForwardedTo(typeof(FlowControl))] [assembly: TypeForwardedTo(typeof(ILProcessor))] [assembly: TypeForwardedTo(typeof(ImageDebugDirectory))] [assembly: TypeForwardedTo(typeof(ImageDebugHeader))] [assembly: TypeForwardedTo(typeof(ImageDebugHeaderEntry))] [assembly: TypeForwardedTo(typeof(ImageDebugType))] [assembly: TypeForwardedTo(typeof(ImportDebugInformation))] [assembly: TypeForwardedTo(typeof(ImportTarget))] [assembly: TypeForwardedTo(typeof(ImportTargetKind))] [assembly: TypeForwardedTo(typeof(Instruction))] [assembly: TypeForwardedTo(typeof(InstructionOffset))] [assembly: TypeForwardedTo(typeof(ISymbolReader))] [assembly: TypeForwardedTo(typeof(ISymbolReaderProvider))] [assembly: TypeForwardedTo(typeof(ISymbolWriter))] [assembly: TypeForwardedTo(typeof(ISymbolWriterProvider))] [assembly: TypeForwardedTo(typeof(MethodBody))] [assembly: TypeForwardedTo(typeof(MethodDebugInformation))] [assembly: TypeForwardedTo(typeof(OpCode))] [assembly: TypeForwardedTo(typeof(OpCodes))] [assembly: TypeForwardedTo(typeof(OpCodeType))] [assembly: TypeForwardedTo(typeof(OperandType))] [assembly: TypeForwardedTo(typeof(ScopeDebugInformation))] [assembly: TypeForwardedTo(typeof(SequencePoint))] [assembly: TypeForwardedTo(typeof(StackBehaviour))] [assembly: TypeForwardedTo(typeof(SymbolsNotFoundException))] [assembly: TypeForwardedTo(typeof(SymbolsNotMatchingException))] [assembly: TypeForwardedTo(typeof(VariableAttributes))] [assembly: TypeForwardedTo(typeof(VariableDebugInformation))] [assembly: TypeForwardedTo(typeof(VariableDefinition))] [assembly: TypeForwardedTo(typeof(VariableReference))] [assembly: TypeForwardedTo(typeof(CustomAttribute))] [assembly: TypeForwardedTo(typeof(CustomAttributeArgument))] [assembly: TypeForwardedTo(typeof(CustomAttributeNamedArgument))] [assembly: TypeForwardedTo(typeof(EventAttributes))] [assembly: TypeForwardedTo(typeof(EventDefinition))] [assembly: TypeForwardedTo(typeof(EventReference))] [assembly: TypeForwardedTo(typeof(ExportedType))] [assembly: TypeForwardedTo(typeof(FieldAttributes))] [assembly: TypeForwardedTo(typeof(FieldDefinition))] [assembly: TypeForwardedTo(typeof(FieldReference))] [assembly: TypeForwardedTo(typeof(GenericInstanceMethod))] [assembly: TypeForwardedTo(typeof(GenericInstanceType))] [assembly: TypeForwardedTo(typeof(GenericParameter))] [assembly: TypeForwardedTo(typeof(GenericParameterAttributes))] [assembly: TypeForwardedTo(typeof(GenericParameterConstraint))] [assembly: TypeForwardedTo(typeof(GenericParameterType))] [assembly: TypeForwardedTo(typeof(IAssemblyResolver))] [assembly: TypeForwardedTo(typeof(ICustomAttributeProvider))] [assembly: TypeForwardedTo(typeof(IGenericParameterProvider))] [assembly: TypeForwardedTo(typeof(IMemberDefinition))] [assembly: TypeForwardedTo(typeof(IMetadataImporter))] [assembly: TypeForwardedTo(typeof(IMetadataImporterProvider))] [assembly: TypeForwardedTo(typeof(IMetadataResolver))] [assembly: TypeForwardedTo(typeof(IMetadataScope))] [assembly: TypeForwardedTo(typeof(IMetadataTokenProvider))] [assembly: TypeForwardedTo(typeof(IMethodSignature))] [assembly: TypeForwardedTo(typeof(InterfaceImplementation))] [assembly: TypeForwardedTo(typeof(IReflectionImporter))] [assembly: TypeForwardedTo(typeof(IReflectionImporterProvider))] [assembly: TypeForwardedTo(typeof(ManifestResourceAttributes))] [assembly: TypeForwardedTo(typeof(MarshalInfo))] [assembly: TypeForwardedTo(typeof(MdbReader))] [assembly: TypeForwardedTo(typeof(MemberReference))] [assembly: TypeForwardedTo(typeof(MetadataKind))] [assembly: TypeForwardedTo(typeof(MetadataScopeType))] [assembly: TypeForwardedTo(typeof(MetadataToken))] [assembly: TypeForwardedTo(typeof(MetadataType))] [assembly: TypeForwardedTo(typeof(MethodAttributes))] [assembly: TypeForwardedTo(typeof(MethodCallingConvention))] [assembly: TypeForwardedTo(typeof(MethodDefinition))] [assembly: TypeForwardedTo(typeof(MethodImplAttributes))] [assembly: TypeForwardedTo(typeof(MethodReference))] [assembly: TypeForwardedTo(typeof(MethodReturnType))] [assembly: TypeForwardedTo(typeof(MethodSemanticsAttributes))] [assembly: TypeForwardedTo(typeof(ModuleAttributes))] [assembly: TypeForwardedTo(typeof(ModuleCharacteristics))] [assembly: TypeForwardedTo(typeof(ModuleDefinition))] [assembly: TypeForwardedTo(typeof(ModuleKind))] [assembly: TypeForwardedTo(typeof(ModuleParameters))] [assembly: TypeForwardedTo(typeof(ModuleReference))] [assembly: TypeForwardedTo(typeof(NativeType))] [assembly: TypeForwardedTo(typeof(ParameterAttributes))] [assembly: TypeForwardedTo(typeof(ParameterDefinition))] [assembly: TypeForwardedTo(typeof(ParameterReference))] [assembly: TypeForwardedTo(typeof(NativePdbReader))] [assembly: TypeForwardedTo(typeof(NativePdbWriter))] [assembly: TypeForwardedTo(typeof(PInvokeAttributes))] [assembly: TypeForwardedTo(typeof(PInvokeInfo))] [assembly: TypeForwardedTo(typeof(PropertyAttributes))] [assembly: TypeForwardedTo(typeof(PropertyDefinition))] [assembly: TypeForwardedTo(typeof(PropertyReference))] [assembly: TypeForwardedTo(typeof(ReaderParameters))] [assembly: TypeForwardedTo(typeof(ReadingMode))] [assembly: TypeForwardedTo(typeof(ResolutionException))] [assembly: TypeForwardedTo(typeof(Resource))] [assembly: TypeForwardedTo(typeof(ResourceType))] [assembly: TypeForwardedTo(typeof(IILVisitor))] [assembly: TypeForwardedTo(typeof(ILParser))] [assembly: TypeForwardedTo(typeof(ModuleDefinitionRocks))] [assembly: TypeForwardedTo(typeof(TypeDefinitionRocks))] [assembly: TypeForwardedTo(typeof(SecurityAction))] [assembly: TypeForwardedTo(typeof(SecurityAttribute))] [assembly: TypeForwardedTo(typeof(SecurityDeclaration))] [assembly: TypeForwardedTo(typeof(TargetArchitecture))] [assembly: TypeForwardedTo(typeof(TargetRuntime))] [assembly: TypeForwardedTo(typeof(TokenType))] [assembly: TypeForwardedTo(typeof(TypeAttributes))] [assembly: TypeForwardedTo(typeof(TypeDefinition))] [assembly: TypeForwardedTo(typeof(TypeReference))] [assembly: TypeForwardedTo(typeof(TypeSpecification))] [assembly: TypeForwardedTo(typeof(TypeSystem))] [assembly: TypeForwardedTo(typeof(WriterParameters))] [assembly: TypeForwardedTo(typeof(Collection<>))] [assembly: TypeForwardedTo(typeof(AnonymousScopeEntry))] [assembly: TypeForwardedTo(typeof(CapturedScope))] [assembly: TypeForwardedTo(typeof(CapturedVariable))] [assembly: TypeForwardedTo(typeof(CodeBlockEntry))] [assembly: TypeForwardedTo(typeof(CompileUnitEntry))] [assembly: TypeForwardedTo(typeof(LineNumberEntry))] [assembly: TypeForwardedTo(typeof(LineNumberTable))] [assembly: TypeForwardedTo(typeof(LocalVariableEntry))] [assembly: TypeForwardedTo(typeof(MethodEntry))] [assembly: TypeForwardedTo(typeof(MonoSymbolFile))] [assembly: TypeForwardedTo(typeof(NamespaceEntry))] [assembly: TypeForwardedTo(typeof(OffsetTable))] [assembly: TypeForwardedTo(typeof(ScopeVariable))] [assembly: TypeForwardedTo(typeof(SourceFileEntry))] [assembly: TypeForwardedTo(typeof(CecilILGenerator))] [assembly: TypeForwardedTo(typeof(ILGeneratorShim))] [assembly: TypeForwardedTo(typeof(DMDEmitDynamicMethodGenerator))] [assembly: TypeForwardedTo(typeof(DMDGenerator<>))] [assembly: TypeForwardedTo(typeof(DynamicMethodDefinition))] [assembly: TypeForwardedTo(typeof(Extensions))] [assembly: TypeForwardedTo(typeof(ICallSiteGenerator))] [assembly: TypeForwardedTo(typeof(ReflectionHelper))] [assembly: TypeForwardedTo(typeof(Relinker))] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace JetBrains.Annotations { [AttributeUsage(AttributeTargets.All)] internal sealed class UsedImplicitlyAttribute : Attribute { public ImplicitUseKindFlags UseKindFlags { get; } public ImplicitUseTargetFlags TargetFlags { get; } public UsedImplicitlyAttribute() : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { } public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags) : this(useKindFlags, ImplicitUseTargetFlags.Default) { } public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags) : this(ImplicitUseKindFlags.Default, targetFlags) { } public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) { UseKindFlags = useKindFlags; TargetFlags = targetFlags; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter | AttributeTargets.GenericParameter)] internal sealed class MeansImplicitUseAttribute : Attribute { [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; } [UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; } public MeansImplicitUseAttribute() : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { } public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags) : this(useKindFlags, ImplicitUseTargetFlags.Default) { } public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags) : this(ImplicitUseKindFlags.Default, targetFlags) { } public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) { UseKindFlags = useKindFlags; TargetFlags = targetFlags; } } [Flags] internal enum ImplicitUseKindFlags { Default = 7, Access = 1, Assign = 2, InstantiatedWithFixedConstructorSignature = 4, InstantiatedNoFixedConstructorSignature = 8 } [Flags] internal enum ImplicitUseTargetFlags { Default = 1, Itself = 1, Members = 2, WithInheritors = 4, WithMembers = 3 } } namespace HarmonyLib { public class DelegateTypeFactory { private class DelegateEntry { public CallingConvention? callingConvention; public Type delegateType; } private static int counter; private static readonly Dictionary<MethodInfo, List<DelegateEntry>> TypeCache = new Dictionary<MethodInfo, List<DelegateEntry>>(); private static readonly MethodBase CallingConvAttr = AccessTools.Constructor(typeof(UnmanagedFunctionPointerAttribute), new Type[1] { typeof(CallingConvention) }); public static readonly DelegateTypeFactory instance = new DelegateTypeFactory(); public Type CreateDelegateType(Type returnType, Type[] argTypes) { return CreateDelegateType(returnType, argTypes, null); } public Type CreateDelegateType(Type returnType, Type[] argTypes, CallingConvention? convention) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) counter++; AssemblyDefinition val = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition($"HarmonyDTFAssembly{counter}", new Version(1, 0)), $"HarmonyDTFModule{counter}", (ModuleKind)0); ModuleDefinition module = val.MainModule; TypeDefinition val2 = new TypeDefinition("", $"HarmonyDTFType{counter}", (TypeAttributes)257); val2.BaseType = module.ImportReference(typeof(MulticastDelegate)); TypeDefinition val3 = val2; module.Types.Add(val3); if (convention.HasValue) { CustomAttribute val4 = new CustomAttribute(module.ImportReference(CallingConvAttr)); val4.ConstructorArguments.Add(new CustomAttributeArgument(module.ImportReference(typeof(CallingConvention)), (object)convention.Value)); val3.CustomAttributes.Add(val4); } MethodDefinition val5 = new MethodDefinition(".ctor", (MethodAttributes)4230, module.ImportReference(typeof(void))) { ImplAttributes = (MethodImplAttributes)3 }; Extensions.AddRange<ParameterDefinition>(((MethodReference)val5).Parameters, (IEnumerable<ParameterDefinition>)(object)new ParameterDefinition[2] { new ParameterDefinition(module.ImportReference(typeof(object))), new ParameterDefinition(module.ImportReference(typeof(IntPtr))) }); val3.Methods.Add(val5); MethodDefinition val6 = new MethodDefinition("Invoke", (MethodAttributes)198, module.ImportReference(returnType)) { ImplAttributes = (MethodImplAttributes)3 }; Extensions.AddRange<ParameterDefinition>(((MethodReference)val6).Parameters, ((IEnumerable<Type>)argTypes).Select((Func<Type, ParameterDefinition>)((Type t) => new ParameterDefinition(module.ImportReference(t))))); val3.Methods.Add(val6); Assembly assembly = ReflectionHelper.Load(val.MainModule); return assembly.GetType($"HarmonyDTFType{counter}"); } public Type CreateDelegateType(MethodInfo method) { return CreateDelegateType(method, null); } public Type CreateDelegateType(MethodInfo method, CallingConvention? convention) { DelegateEntry delegateEntry; if (TypeCache.TryGetValue(method, out var value) && (delegateEntry = value.FirstOrDefault((DelegateEntry e) => e.callingConvention == convention)) != null) { return delegateEntry.delegateType; } if (value == null) { value = (TypeCache[method] = new List<DelegateEntry>()); } delegateEntry = new DelegateEntry { delegateType = CreateDelegateType(method.ReturnType, method.GetParameters().Types().ToArray(), convention), callingConvention = convention }; value.Add(delegateEntry); return delegateEntry.delegateType; } } [Obsolete("Use AccessTools.FieldRefAccess<T, S> for fields and AccessTools.MethodDelegate<Func<T, S>> for property getters")] [EditorBrowsable(EditorBrowsableState.Never)] public delegate S GetterHandler<in T, out S>(T source); [Obsolete("Use AccessTools.FieldRefAccess<T, S> for fields and AccessTools.MethodDelegate<Action<T, S>> for property setters")] [EditorBrowsable(EditorBrowsableState.Never)] public delegate void SetterHandler<in T, in S>(T source, S value); public delegate T InstantiationHandler<out T>(); public static class FastAccess { public static InstantiationHandler<T> CreateInstantiationHandler<T>() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown ConstructorInfo constructor = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Array.Empty<Type>(), null); if ((object)constructor == null) { throw new ApplicationException($"The type {typeof(T)} must declare an empty constructor (the constructor may be private, internal, protected, protected internal, or public)."); } DynamicMethodDefinition val = new DynamicMethodDefinition("InstantiateObject_" + typeof(T).Name, typeof(T), (Type[])null); ILGenerator iLGenerator = val.GetILGenerator(); iLGenerator.Emit(OpCodes.Newobj, constructor); iLGenerator.Emit(OpCodes.Ret); return Extensions.CreateDelegate<InstantiationHandler<T>>((MethodBase)val.Generate()); } [Obsolete("Use AccessTools.MethodDelegate<Func<T, S>>(PropertyInfo.GetGetMethod(true))")] [EditorBrowsable(EditorBrowsableState.Never)] public static GetterHandler<T, S> CreateGetterHandler<T, S>(PropertyInfo propertyInfo) { MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true); DynamicMethodDefinition val = CreateGetDynamicMethod<T, S>(propertyInfo.DeclaringType); ILGenerator iLGenerator = val.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Call, getMethod); iLGenerator.Emit(OpCodes.Ret); return Extensions.CreateDelegate<GetterHandler<T, S>>((MethodBase)val.Generate()); } [Obsolete("Use AccessTools.FieldRefAccess<T, S>(fieldInfo)")] [EditorBrowsable(EditorBrowsableState.Never)] public static GetterHandler<T, S> CreateGetterHandler<T, S>(FieldInfo fieldInfo) { DynamicMethodDefinition val = CreateGetDynamicMethod<T, S>(fieldInfo.DeclaringType); ILGenerator iLGenerator = val.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, fieldInfo); iLGenerator.Emit(OpCodes.Ret); return Extensions.CreateDelegate<GetterHandler<T, S>>((MethodBase)val.Generate()); } [Obsolete("Use AccessTools.FieldRefAccess<T, S>(name) for fields and AccessTools.MethodDelegate<Func<T, S>>(AccessTools.PropertyGetter(typeof(T), name)) for properties")] [EditorBrowsable(EditorBrowsableState.Never)] public static GetterHandler<T, S> CreateFieldGetter<T, S>(params string[] names) { foreach (string name in names) { FieldInfo field = typeof(T).GetField(name, AccessTools.all); if ((object)field != null) { return CreateGetterHandler<T, S>(field); } PropertyInfo property = typeof(T).GetProperty(name, AccessTools.all); if ((object)property != null) { return CreateGetterHandler<T, S>(property); } } return null; } [Obsolete("Use AccessTools.MethodDelegate<Action<T, S>>(PropertyInfo.GetSetMethod(true))")] [EditorBrowsable(EditorBrowsableState.Never)] public static SetterHandler<T, S> CreateSetterHandler<T, S>(PropertyInfo propertyInfo) { MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: true); DynamicMethodDefinition val = CreateSetDynamicMethod<T, S>(propertyInfo.DeclaringType); ILGenerator iLGenerator = val.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Call, setMethod); iLGenerator.Emit(OpCodes.Ret); return Extensions.CreateDelegate<SetterHandler<T, S>>((MethodBase)val.Generate()); } [Obsolete("Use AccessTools.FieldRefAccess<T, S>(fieldInfo)")] [EditorBrowsable(EditorBrowsableState.Never)] public static SetterHandler<T, S> CreateSetterHandler<T, S>(FieldInfo fieldInfo) { DynamicMethodDefinition val = CreateSetDynamicMethod<T, S>(fieldInfo.DeclaringType); ILGenerator iLGenerator = val.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Stfld, fieldInfo); iLGenerator.Emit(OpCodes.Ret); return Extensions.CreateDelegate<SetterHandler<T, S>>((MethodBase)val.Generate()); } private static DynamicMethodDefinition CreateGetDynamicMethod<T, S>(Type type) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown return new DynamicMethodDefinition("DynamicGet_" + type.Name, typeof(S), new Type[1] { typeof(T) }); } private static DynamicMethodDefinition CreateSetDynamicMethod<T, S>(Type type) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown return new DynamicMethodDefinition("DynamicSet_" + type.Name, typeof(void), new Type[2] { typeof(T), typeof(S) }); } } public delegate object FastInvokeHandler(object target, params object[] parameters); public static class MethodInvoker { public static FastInvokeHandler GetHandler(MethodInfo methodInfo, bool directBoxValueAccess = false) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown DynamicMethodDefinition val = new DynamicMethodDefinition("FastInvoke_" + methodInfo.Name + "_" + (directBoxValueAccess ? "direct" : "indirect"), typeof(object), new Type[2] { typeof(object), typeof(object[]) }); ILGenerator iLGenerator = val.GetILGenerator(); if (!methodInfo.IsStatic) { Emit(iLGenerator, OpCodes.Ldarg_0); EmitUnboxIfNeeded(iLGenerator, methodInfo.DeclaringType); } bool flag = true; ParameterInfo[] parameters = methodInfo.GetParameters(); for (int i = 0; i < parameters.Length; i++) { Type type = parameters[i].ParameterType; bool isByRef = type.IsByRef; if (isByRef) { type = type.GetElementType(); } bool isValueType = type.IsValueType; if (isByRef && isValueType && !directBoxValueAccess) { Emit(iLGenerator, OpCodes.Ldarg_1); EmitFastInt(iLGenerator, i); } Emit(iLGenerator, OpCodes.Ldarg_1); EmitFastInt(iLGenerator, i); if (isByRef && !isValueType) { Emit(iLGenerator, OpCodes.Ldelema, typeof(object)); continue; } Emit(iLGenerator, OpCodes.Ldelem_Ref); if (!isValueType) { continue; } if (!isByRef || !directBoxValueAccess) { Emit(iLGenerator, OpCodes.Unbox_Any, type); if (isByRef) { Emit(iLGenerator, OpCodes.Box, type); Emit(iLGenerator, OpCodes.Dup); if (flag) { flag = false; iLGenerator.DeclareLocal(typeof(object), pinned: false); } Emit(iLGenerator, OpCodes.Stloc_0); Emit(iLGenerator, OpCodes.Stelem_Ref); Emit(iLGenerator, OpCodes.Ldloc_0); Emit(iLGenerator, OpCodes.Unbox, type); } } else { Emit(iLGenerator, OpCodes.Unbox, type); } } if (methodInfo.IsStatic) { EmitCall(iLGenerator, OpCodes.Call, methodInfo); } else { EmitCall(iLGenerator, OpCodes.Callvirt, methodInfo); } if (methodInfo.ReturnType == typeof(void)) { Emit(iLGenerator, OpCodes.Ldnull); } else { EmitBoxIfNeeded(iLGenerator, methodInfo.ReturnType); } Emit(iLGenerator, OpCodes.Ret); return Extensions.CreateDelegate<FastInvokeHandler>((MethodBase)val.Generate()); } internal static void Emit(ILGenerator il, OpCode opcode) { il.Emit(opcode); } internal static void Emit(ILGenerator il, OpCode opcode, Type type) { il.Emit(opcode, type); } internal static void EmitCall(ILGenerator il, OpCode opcode, MethodInfo methodInfo) { il.EmitCall(opcode, methodInfo, null); } private static void EmitUnboxIfNeeded(ILGenerator il, Type type) { if (type.IsValueType) { Emit(il, OpCodes.Unbox_Any, type); } } private static void EmitBoxIfNeeded(ILGenerator il, Type type) { if (type.IsValueType) { Emit(il, OpCodes.Box, type); } } internal static void EmitFastInt(ILGenerator il, int value) { switch (value) { case -1: il.Emit(OpCodes.Ldc_I4_M1); return; case 0: il.Emit(OpCodes.Ldc_I4_0); return; case 1: il.Emit(OpCodes.Ldc_I4_1); return; case 2: il.Emit(OpCodes.Ldc_I4_2); return; case 3: il.Emit(OpCodes.Ldc_I4_3); return; case 4: il.Emit(OpCodes.Ldc_I4_4); return; case 5: il.Emit(OpCodes.Ldc_I4_5); return; case 6: il.Emit(OpCodes.Ldc_I4_6); return; case 7: il.Emit(OpCodes.Ldc_I4_7); return; case 8: il.Emit(OpCodes.Ldc_I4_8); return; } if (value > -129 && value < 128) { il.Emit(OpCodes.Ldc_I4_S, (sbyte)value); } else { il.Emit(OpCodes.Ldc_I4, value); } } } public delegate ref T RefResult<T>(); internal class AccessCache { internal enum MemberType { Any, Static, Instance } private const BindingFlags BasicFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty; private static readonly Dictionary<MemberType, BindingFlags> declaredOnlyBindingFlags = new Dictionary<MemberType, BindingFlags> { { MemberType.Any, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty }, { MemberType.Instance, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty }, { MemberType.Static, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty } }; private readonly Dictionary<Type, Dictionary<string, FieldInfo>> declaredFields = new Dictionary<Type, Dictionary<string, FieldInfo>>(); private readonly Dictionary<Type, Dictionary<string, PropertyInfo>> declaredProperties = new Dictionary<Type, Dictionary<string, PropertyInfo>>(); private readonly Dictionary<Type, Dictionary<string, Dictionary<int, MethodBase>>> declaredMethods = new Dictionary<Type, Dictionary<string, Dictionary<int, MethodBase>>>(); private readonly Dictionary<Type, Dictionary<string, FieldInfo>> inheritedFields = new Dictionary<Type, Dictionary<string, FieldInfo>>(); private readonly Dictionary<Type, Dictionary<string, PropertyInfo>> inheritedProperties = new Dictionary<Type, Dictionary<string, PropertyInfo>>(); private readonly Dictionary<Type, Dictionary<string, Dictionary<int, MethodBase>>> inheritedMethods = new Dictionary<Type, Dictionary<string, Dictionary<int, MethodBase>>>(); private static T Get<T>(Dictionary<Type, Dictionary<string, T>> dict, Type type, string name, Func<T> fetcher) { lock (dict) { if (!dict.TryGetValue(type, out var value)) { value = (dict[type] = new Dictionary<string, T>()); } if (!value.TryGetValue(name, out var value2)) { value2 = (value[name] = fetcher()); } return value2; } } private static T Get<T>(Dictionary<Type, Dictionary<string, Dictionary<int, T>>> dict, Type type, string name, Type[] arguments, Func<T> fetcher) { lock (dict) { if (!dict.TryGetValue(type, out var value)) { value = (dict[type] = new Dictionary<string, Dictionary<int, T>>()); } if (!value.TryGetValue(name, out var value2)) { value2 = (value[name] = new Dictionary<int, T>()); } int key = AccessTools.CombinedHashCode(arguments); if (!value2.TryGetValue(key, out var value3)) { value3 = (value2[key] = fetcher()); } return value3; } } internal FieldInfo GetFieldInfo(Type type, string name, MemberType memberType = MemberType.Any, bool declaredOnly = false) { FieldInfo fieldInfo = Get(declaredFields, type, name, () => type.GetField(name, declaredOnlyBindingFlags[memberType])); if ((object)fieldInfo == null && !declaredOnly) { fieldInfo = Get(inheritedFields, type, name, () => AccessTools.FindIncludingBaseTypes(type, (Type t) => t.GetField(name, AccessTools.all))); } return fieldInfo; } internal PropertyInfo GetPropertyInfo(Type type, string name, MemberType memberType = MemberType.Any, bool declaredOnly = false) { PropertyInfo propertyInfo = Get(declaredProperties, type, name, () => type.GetProperty(name, declaredOnlyBindingFlags[memberType])); if ((object)propertyInfo == null && !declaredOnly) { propertyInfo = Get(inheritedProperties, type, name, () => AccessTools.FindIncludingBaseTypes(type, (Type t) => t.GetProperty(name, AccessTools.all))); } return propertyInfo; } internal MethodBase GetMethodInfo(Type type, string name, Type[] arguments, MemberType memberType = MemberType.Any, bool declaredOnly = false) { MethodBase methodBase = Get(declaredMethods, type, name, arguments, () => type.GetMethod(name, declaredOnlyBindingFlags[memberType], null, arguments, null)); if ((object)methodBase == null && !declaredOnly) { methodBase = Get(inheritedMethods, type, name, arguments, () => AccessTools.Method(type, name, arguments)); } return methodBase; } } internal static class PatchArgumentExtensions { private static IEnumerable<HarmonyArgument> AllHarmonyArguments(object[] attributes) { return attributes.Select((object attr) => (attr.GetType().Name != "HarmonyArgument") ? null : AccessTools.MakeDeepCopy<HarmonyArgument>(attr)).OfType<HarmonyArgument>(); } internal static HarmonyArgument GetArgumentAttribute(this ParameterInfo parameter) { object[] customAttributes = parameter.GetCustomAttributes(inherit: true); return AllHarmonyArguments(customAttributes).FirstOrDefault(); } internal static IEnumerable<HarmonyArgument> GetArgumentAttributes(this MethodInfo method) { object[] customAttributes = method.GetCustomAttributes(inherit: true); return AllHarmonyArguments(customAttributes); } internal static IEnumerable<HarmonyArgument> GetArgumentAttributes(this Type type) { object[] customAttributes = type.GetCustomAttributes(inherit: true); return AllHarmonyArguments(customAttributes); } internal static string GetRealName(this IEnumerable<HarmonyArgument> attributes, string name, string[] originalParameterNames) { HarmonyArgument harmonyArgument = attributes.FirstOrDefault((HarmonyArgument p) => p.OriginalName == name); if (harmonyArgument == null) { return null; } if (!string.IsNullOrEmpty(harmonyArgument.NewName)) { return harmonyArgument.NewName; } if (originalParameterNames != null && harmonyArgument.Index >= 0 && harmonyArgument.Index < originalParameterNames.Length) { return originalParameterNames[harmonyArgument.Index]; } return null; } private static string GetRealParameterName(this MethodInfo method, string[] originalParameterNames, string name) { if ((object)method == null || method is DynamicMethod) { return name; } string realName = method.GetArgumentAttributes().GetRealName(name, originalParameterNames); if (realName != null) { return realName; } Type declaringType = method.DeclaringType; if ((object)declaringType != null) { realName = declaringType.GetArgumentAttributes().GetRealName(name, originalParameterNames); if (realName != null) { return realName; } } return name; } private static string GetRealParameterName(this ParameterInfo parameter, string[] originalParameterNames) { HarmonyArgument argumentAttribute = parameter.GetArgumentAttribute(); if (argumentAttribute == null) { return null; } if (!string.IsNullOrEmpty(argumentAttribute.OriginalName)) { return argumentAttribute.OriginalName; } if (argumentAttribute.Index >= 0 && argumentAttribute.Index < originalParameterNames.Length) { return originalParameterNames[argumentAttribute.Index]; } return null; } internal static int GetArgumentIndex(this MethodInfo patch, string[] originalParameterNames, ParameterInfo patchParam) { if (patch is DynamicMethod) { return Array.IndexOf<string>(originalParameterNames, patchParam.Name); } string realParameterName = patchParam.GetRealParameterName(originalParameterNames); if (realParameterName != null) { return Array.IndexOf(originalParameterNames, realParameterName); } realParameterName = patch.GetRealParameterName(originalParameterNames, patchParam.Name); if (realParameterName != null) { return Array.IndexOf(originalParameterNames, realParameterName); } return -1; } } internal static class PatchFunctions { internal static List<MethodInfo> GetSortedPatchMethods(MethodBase original, Patch[] patches, bool debug) { return new PatchSorter(patches, debug).Sort(original); } internal static Patch[] GetSortedPatchMethodsAsPatches(MethodBase original, Patch[] patches, bool debug) { return new PatchSorter(patches, debug).SortAsPatches(original); } internal static MethodInfo UpdateWrapper(MethodBase original, PatchInfo patchInfo) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown MethodPatcher methodPatcher = original.GetMethodPatcher(); DynamicMethodDefinition val = methodPatcher.PrepareOriginal(); if (val != null) { ILContext ctx = new ILContext(val.Definition); HarmonyManipulator.Manipulate(original, patchInfo, ctx); } try { return methodPatcher.DetourTo((val != null) ? val.Generate() : null) as MethodInfo; } catch (Exception ex) { object body; if (val == null) { body = null; } else { MethodDefinition definition = val.Definition; body = ((definition != null) ? definition.Body : null); } throw HarmonyException.Create(ex, (MethodBody)body); } } internal static MethodInfo ReversePatch(HarmonyMethod standin, MethodBase original, MethodInfo postTranspiler, MethodInfo postManipulator) { //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown if (standin == null) { throw new ArgumentNullException("standin"); } if ((object)standin.method == null) { throw new ArgumentNullException("standin", "standin.method is NULL"); } if (!standin.method.IsStatic) { throw new ArgumentException("standin", "standin.method is not static"); } bool debug = standin.debug == true; List<MethodInfo> transpilers = new List<MethodInfo>(); List<MethodInfo> ilmanipulators = new List<MethodInfo>(); if (standin.reversePatchType == HarmonyReversePatchType.Snapshot) { Patches patchInfo = Harmony.GetPatchInfo(original); transpilers.AddRange(GetSortedPatchMethods(original, patchInfo.Transpilers.ToArray(), debug)); ilmanipulators.AddRange(GetSortedPatchMethods(original, patchInfo.ILManipulators.ToArray(), debug)); } if ((object)postTranspiler != null) { transpilers.Add(postTranspiler); } if ((object)postManipulator != null) { ilmanipulators.Add(postManipulator); } Logger.Log(Logger.LogChannel.Info, delegate { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Reverse patching " + standin.method.FullDescription() + " with " + original.FullDescription()); PrintInfo(stringBuilder, transpilers, "Transpiler"); PrintInfo(stringBuilder, ilmanipulators, "Manipulators"); return stringBuilder.ToString(); }, debug); MethodBody patchBody = null; ILHook val = new ILHook((MethodBase)standin.method, (Manipulator)delegate(ILContext ctx) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) if (original is MethodInfo methodInfo2) { patchBody = ctx.Body; MethodPatcher methodPatcher = methodInfo2.GetMethodPatcher(); DynamicMethodDefinition val2 = methodPatcher.CopyOriginal(); if (val2 == null) { throw new NullReferenceException($"Cannot reverse patch {methodInfo2.FullDescription()}: method patcher ({methodPatcher.GetType().FullDescription()}) can't copy original method body"); } ILManipulator iLManipulator = new ILManipulator(val2.Definition.Body, debug); ctx.Body.Variables.Clear(); Enumerator<VariableDefinition> enumerator = iLManipulator.Body.Variables.GetEnumerator(); try { while (enumerator.MoveNext()) { VariableDefinition current = enumerator.Current; ctx.Body.Variables.Add(new VariableDefinition(ctx.Module.ImportReference(((VariableReference)current).VariableType))); } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } foreach (MethodInfo item in transpilers) { iLManipulator.AddTranspiler(item); } iLManipulator.WriteTo(ctx.Body, standin.method); HarmonyManipulator.ApplyManipulators(ctx, original, ilmanipulators, null); StackTraceFixes.FixStackTrace(ctx); Instruction val3 = null; foreach (Instruction item2 in ((IEnumerable<Instruction>)ctx.Instrs).Where((Instruction i) => i.OpCode == OpCodes.Ret)) { if (val3 == null) { val3 = ctx.IL.Create(OpCodes.Ret); } item2.OpCode = OpCodes.Br; item2.Operand = val3; } if (val3 != null) { ctx.IL.Append(val3); } Logger.Log(Logger.LogChannel.IL, () => "Generated reverse patcher (" + ((MemberReference)ctx.Method).FullName + "):\n" + ctx.Body.ToILDasmString(), debug); } }, false); try { val.Apply(); } catch (Exception ex) { throw HarmonyException.Create(ex, patchBody); } MethodInfo methodInfo = val.Method as MethodInfo; PatchTools.RememberObject(standin.method, (methodInfo, val)); return methodInfo; static void PrintInfo(StringBuilder sb, ICollection<MethodInfo> methods, string name) { if (methods.Count <= 0) { return; } sb.AppendLine(name + ":"); foreach (MethodInfo method in methods) { sb.AppendLine(" * " + method.FullDescription()); } } } internal static IEnumerable<CodeInstruction> ApplyTranspilers(MethodBase methodBase, ILGenerator generator, int maxTranspilers = 0) { MethodPatcher methodPatcher = methodBase.GetMethodPatcher(); DynamicMethodDefinition val = methodPatcher.CopyOriginal(); if (val == null) { throw new NullReferenceException($"Cannot reverse patch {methodBase.FullDescription()}: method patcher ({methodPatcher.GetType().FullDescription()}) can't copy original method body"); } ILManipulator iLManipulator = new ILManipulator(val.Definition.Body, debug: false); PatchInfo patchInfo = methodBase.GetPatchInfo(); if (patchInfo != null) { List<MethodInfo> sortedPatchMethods = GetSortedPatchMethods(methodBase, patchInfo.transpilers, debug: false); for (int i = 0; i < maxTranspilers && i < sortedPatchMethods.Count; i++) { iLManipulator.AddTranspiler(sortedPatchMethods[i]); } } return iLManipulator.GetInstructions(generator, methodBase); } internal static void UnpatchConditional(Func<Patch, bool> executionCondition) { List<MethodBase> list = PatchProcessor.GetAllPatchedMethods().ToList(); foreach (MethodBase item in list) { Patches patchInfo = PatchProcessor.GetPatchInfo(item); PatchProcessor patchProcessor = new PatchProcessor(null, item); patchInfo.Postfixes.DoIf(executionCondition, delegate(Patch patch) { patchProcessor.Unpatch(patch.PatchMethod); }); patchInfo.Prefixes.DoIf(executionCondition, delegate(Patch patch) { patchProcessor.Unpatch(patch.PatchMethod); }); patchInfo.ILManipulators.DoIf(executionCondition, delegate(Patch patch) { patchProcessor.Unpatch(patch.PatchMethod); }); patchInfo.Transpilers.DoIf(executionCondition, delegate(Patch patch) { patchProcessor.Unpatch(patch.PatchMethod); }); patchInfo.Finalizers.DoIf(executionCondition, delegate(Patch patch) { patchProcessor.Unpatch(patch.PatchMethod); }); } } } internal class PatchJobs<T> { internal class Job { internal MethodBase original; internal T replacement; internal List<HarmonyMethod> prefixes = new List<HarmonyMethod>(); internal List<HarmonyMethod> postfixes = new List<HarmonyMethod>(); internal List<HarmonyMethod> transpilers = new List<HarmonyMethod>(); internal List<HarmonyMethod> finalizers = new List<HarmonyMethod>(); internal List<HarmonyMethod> ilmanipulators = new List<HarmonyMethod>(); internal void AddPatch(AttributePatch patch) { HarmonyPatchType? type = patch.type; if (type.HasValue) { switch (type.GetValueOrDefault()) { case HarmonyPatchType.Prefix: prefixes.Add(patch.info); break; case HarmonyPatchType.Postfix: postfixes.Add(patch.info); break; case HarmonyPatchType.Transpiler: transpilers.Add(patch.info); break; case HarmonyPatchType.Finalizer: finalizers.Add(patch.info); break; case HarmonyPatchType.ILManipulator: ilmanipulators.Add(patch.info); break; case HarmonyPatchType.ReversePatch: break; } } } } internal Dictionary<MethodBase, Job> state = new Dictionary<MethodBase, Job>(); internal Job GetJob(MethodBase method) { if ((object)method == null) { return null; } if (!state.TryGetValue(method, out var value)) { value = new Job { original = method }; state[method] = value; } return value; } internal List<Job> GetJobs() { return state.Values.Where((Job job) => job.prefixes.Count + job.postfixes.Count + job.transpilers.Count + job.finalizers.Count + job.ilmanipulators.Count > 0).ToList(); } internal List<T> GetReplacements() { return state.Values.Select((Job job) => job.replacement).ToList(); } } internal class AttributePatch { private static readonly HarmonyPatchType[] allPatchTypes = new HarmonyPatchType[6] { HarmonyPatchType.Prefix, HarmonyPatchType.Postfix, HarmonyPatchType.Transpiler, HarmonyPatchType.Finalizer, HarmonyPatchType.ReversePatch, HarmonyPatchType.ILManipulator }; internal HarmonyMethod info; internal HarmonyPatchType? type; internal static IEnumerable<AttributePatch> Create(MethodInfo patch, bool collectIncomplete = false) { if ((object)patch == null) { throw new NullReferenceException("Patch method cannot be null"); } object[] customAttributes = patch.GetCustomAttributes(inherit: true); string name = patch.Name; HarmonyPatchType? type = GetPatchType(name, customAttributes); if (!type.HasValue) { return Enumerable.Empty<AttributePatch>(); } if (type != HarmonyPatchType.ReversePatch && !patch.IsStatic) { throw new ArgumentException("Patch method " + patch.FullDescription() + " must be static"); } List<HarmonyMethod> list = customAttributes.Where((object attr) => attr.GetType().BaseType.FullName == PatchTools.harmonyAttributeFullName).Select(delegate(object attr) { FieldInfo fieldInfo = AccessTools.Field(attr.GetType(), "info"); return fieldInfo.GetValue(attr); }).Select(AccessTools.MakeDeepCopy<HarmonyMethod>) .ToList(); List<HarmonyMethod> list2 = new List<HarmonyMethod>(); ILookup<bool, HarmonyMethod> lookup = list.ToLookup((HarmonyMethod m) => IsComplete(m, collectIncomplete)); List<HarmonyMethod> incomplete = lookup[false].ToList(); HarmonyMethod info = HarmonyMethod.Merge(incomplete); List<HarmonyMethod> list3 = lookup[true].Where((HarmonyMethod m) => !Same(m, info)).ToList(); if (list3.Count > 1) { list2.AddRange(list3.Select((HarmonyMethod m) => HarmonyMethod.Merge(incomplete.AddItem(m)))); } else { list2.Add(HarmonyMethod.Merge(list)); } foreach (HarmonyMethod item in list2) { item.method = patch; } return list2.Select((HarmonyMethod i) => new AttributePatch { info = i, type = type }).ToList(); static bool IsComplete(HarmonyMethod m, bool flag) { if (flag || m.declaringType != null) { return m.methodName != null; } return false; } static bool Same(HarmonyMethod m1, HarmonyMethod m2) { if (m1.declaringType == m2.declaringType && m1.methodName == m2.methodName) { return m1.GetArgumentList().SequenceEqual(m2.GetArgumentList()); } return false; } } private static HarmonyPatchType? GetPatchType(string methodName, object[] allAttributes) { HashSet<string> hashSet = new HashSet<string>(from attr in allAttributes select attr.GetType().FullName into name where name.StartsWith("Harmony") select name); HarmonyPatchType? result = null; HarmonyPatchType[] array = allPatchTypes; for (int num = 0; num < array.Length; num++) { HarmonyPatchType value = array[num]; string text = value.ToString(); if (text == methodName || hashSet.Contains("HarmonyLib.Harmony" + text)) { result = value; break; } } return result; } } internal class PatchSorter { private class PatchSortingWrapper : IComparable { internal readonly HashSet<PatchSortingWrapper> after; internal readonly HashSet<PatchSortingWrapper> before; internal readonly Patch innerPatch; internal PatchSortingWrapper(Patch patch) { innerPatch = patch; before = new HashSet<PatchSortingWrapper>(); after = new HashSet<PatchSortingWrapper>(); } public int CompareTo(object obj) { return PatchInfoSerialization.PriorityComparer((obj is PatchSortingWrapper patchSortingWrapper) ? patchSortingWrapper.innerPatch : null, innerPatch.index, innerPatch.priority); } public override bool Equals(object obj) { if (obj is PatchSortingWrapper patchSortingWrapper) { return innerPatch.PatchMethod == patchSortingWrapper.innerPatch.PatchMethod; } return false; } public override int GetHashCode() { return innerPatch.PatchMethod.GetHashCode(); } internal void AddBeforeDependency(IEnumerable<PatchSortingWrapper> dependencies) { foreach (PatchSortingWrapper dependency in dependencies) { before.Add(dependency); dependency.after.Add(this); } } internal void AddAfterDependency(IEnumerable<PatchSortingWrapper> dependencies) { foreach (PatchSortingWrapper dependency in dependencies) { after.Add(dependency); dependency.before.Add(this); } } internal void RemoveAfterDependency(PatchSortingWrapper afterNode) { after.Remove(afterNode); afterNode.before.Remove(this); } internal void RemoveBeforeDependency(PatchSortingWrapper beforeNode) { before.Remove(beforeNode); beforeNode.after.Remove(this); } } internal class PatchDetailedComparer : IEqualityComparer<Patch> { public bool Equals(Patch x, Patch y) { if (y != null && x != null && x.owner == y.owner && x.PatchMethod == y.PatchMethod && x.index == y.index && x.priority == y.priority && x.before.Length == y.before.Length && x.after.Length == y.after.Length && x.before.All(((IEnumerable<string>)y.before).Contains<string>)) { return x.after.All(((IEnumerable<string>)y.after).Contains<string>); } return false; } public int GetHashCode(Patch obj) { return obj.GetHashCode(); } } private List<PatchSortingWrapper> patches; private HashSet<PatchSortingWrapper> handledPatches; private List<PatchSortingWrapper> result; private List<PatchSortingWrapper> waitingList; internal Patch[] sortedPatchArray; private readonly bool debug; internal PatchSorter(Patch[] patches, bool debug = false) { this.patches = patches.Select((Patch x) => new PatchSortingWrapper(x)).ToList(); this.debug = debug; foreach (PatchSortingWrapper node in this.patches) { node.AddBeforeDependency(this.patches.Where((PatchSortingWrapper x) => node.innerPatch.before.Contains(x.innerPatch.owner))); node.AddAfterDependency(this.patches.Where((PatchSortingWrapper x) => node.innerPatch.after.Contains(x.innerPatch.owner))); } this.patches.Sort(); } internal List<MethodInfo> Sort(MethodBase original) { return (from x in SortAsPatches(original) select x.GetMethod(original)).ToList(); } internal Patch[] SortAsPatches(MethodBase original) { if (sortedPatchArray != null) { return sortedPatchArray; } handledPatches = new HashSet<PatchSortingWrapper>(); waitingList = new List<PatchSortingWrapper>(); result = new List<PatchSortingWrapper>(patches.Count); Queue<PatchSortingWrapper> queue = new Queue<PatchSortingWrapper>(patches); while (queue.Count != 0) { foreach (PatchSortingWrapper item in queue) { if (item.after.All((PatchSortingWrapper x) => handledPatches.Contains(x))) { AddNodeToResult(item); if (item.before.Count != 0) { ProcessWaitingList(); } } else { waitingList.Add(item); } } CullDependency(); queue = new Queue<PatchSortingWrapper>(waitingList); waitingList.Clear(); } sortedPatchArray = result.Select((PatchSortingWrapper x) => x.innerPatch).ToArray(); handledPatches = null; waitingList = null; patches = null; return sortedPatchArray; } internal bool ComparePatchLists(Patch[] patches) { if (sortedPatchArray == null) { Sort(null); } if (patches != null && sortedPatchArray.Length == patches.Length) { return sortedPatchArray.All((Patch x) => patches.Contains(x, new PatchDetailedComparer())); } return false; } private void CullDependency() { for (int i = waitingList.Count - 1; i >= 0; i--) { foreach (PatchSortingWrapper afterNode in waitingList[i].after) { if (!handledPatches.Contains(afterNode)) { waitingList[i].RemoveAfterDependency(afterNode); Logger.Log(Logger.LogChannel.Debug, delegate { string text = afterNode.innerPatch.PatchMethod.FullDescription(); string text2 = waitingList[i].innerPatch.PatchMethod.FullDescription(); return "Breaking dependence between " + text + " and " + text2; }, debug); return; } } } } private void ProcessWaitingList() { int num = waitingList.Count; int num2 = 0; while (num2 < num) { PatchSortingWrapper patchSortingWrapper = waitingList[num2]; if (patchSortingWrapper.after.All(handledPatches.Contains)) { waitingList.Remove(patchSortingWrapper); AddNodeToResult(patchSortingWrapper); num--; num2 = 0; } else { num2++; } } } private void AddNodeToResult(PatchSortingWrapper node) { result.Add(node); handledPatches.Add(node); } } internal static class PatchTools { internal static readonly string harmonyMethodFullName = typeof(HarmonyMethod).FullName; internal static readonly string harmonyAttributeFullName = typeof(HarmonyAttribute).FullName; internal static readonly string harmonyPatchAllFullName = typeof(HarmonyPatchAll).FullName; private static readonly Dictionary<object, object> objectReferences = new Dictionary<object, object>(); internal static void RememberObject(object key, object value) { lock (objectReferences) { objectReferences[key] = value; } } public static MethodInfo CreateMethod(string name, Type returnType, List<KeyValuePair<string, Type>> parameters, Action<ILGenerator> generator) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown Type[] array = parameters.Select((KeyValuePair<string, Type> p) => p.Value).ToArray(); if (AccessTools.IsMonoRuntime && !ReflectionTools.isWindows) { AssemblyName name2 = new AssemblyName("TempAssembly"); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(name2, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("TempModule"); TypeBuilder typeBuilder = moduleBuilder.DefineType("TempType", TypeAttributes.Public); MethodBuilder methodBuilder = typeBuilder.DefineMethod(name, MethodAttributes.Public | MethodAttributes.Static, returnType, array); for (int num = 0; num < parameters.Count; num++) { methodBuilder.DefineParameter(num + 1, ParameterAttributes.None, parameters[num].Key); } generator(methodBuilder.GetILGenerator()); Type type = typeBuilder.CreateTypeInfo().AsType(); return type.GetMethod(name, BindingFlags.Static | BindingFlags.Public); } DynamicMethodDefinition val = new DynamicMethodDefinition(name, returnType, array); for (int num2 = 0; num2 < parameters.Count; num2++) { ((ParameterReference)((MethodReference)val.Definition).Parameters[num2]).Name = parameters[num2].Key; } generator(val.GetILGenerator()); return val.Generate(); } internal static MethodInfo GetPatchMethod(Type patchType, string attributeName) { MethodInfo methodInfo = patchType.GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.GetCustomAttributes(inherit: true).Any((object a) => a.GetType().FullName == attributeName)); if ((object)methodInfo == null) { string name = attributeName.Replace("HarmonyLib.Harmony", ""); methodInfo = patchType.GetMethod(name, AccessTools.all); } return methodInfo; } internal static AssemblyBuilder DefineDynamicAssembly(string name) { AssemblyName name2 = new AssemblyName(name); return AssemblyBuilder.DefineDynamicAssembly(name2, AssemblyBuilderAccess.Run); } internal static List<AttributePatch> GetPatchMethods(Type type, bool collectIncomplete = false) { return (from attributePatch in AccessTools.GetDeclaredMethods(type).SelectMany((MethodInfo method) => AttributePatch.Create(method, collectIncomplete)) where attributePatch != null select attributePatch).ToList(); } internal static MethodBase GetOriginalMethod(this HarmonyMethod attr) { try { MethodType? methodType = attr.methodType; if (methodType.HasValue) { switch (methodType.GetValueOrDefault()) { case MethodType.Normal: if (string.IsNullOrEmpty(attr.methodName)) { return null; } return AccessTools.DeclaredMethod(attr.declaringType, attr.methodName, attr.argumentTypes); case MethodType.Getter: if (string.IsNullOrEmpty(attr.methodName)) { return AccessTools.DeclaredIndexerGetter(attr.declaringType, attr.argumentTypes); } return AccessTools.DeclaredPropertyGetter(attr.declaringType, attr.methodName); case MethodType.Setter: if (string.IsNullOrEmpty(attr.methodName)) { return AccessTools.DeclaredIndexerSetter(attr.declaringType, attr.argumentTypes); } return AccessTools.DeclaredPropertySetter(attr.declaringType, attr.methodName); case MethodType.Constructor: return AccessTools.DeclaredConstructor(attr.declaringType, attr.argumentTypes); case MethodType.StaticConstructor: return AccessTools.GetDeclaredConstructors(attr.declaringType).FirstOrDefault((ConstructorInfo c) => c.IsStatic); case MethodType.Enumerator: if (string.IsNullOrEmpty(attr.methodName)) { return null; } return AccessTools.EnumeratorMoveNext(AccessTools.DeclaredMethod(attr.declaringType, attr.methodName, attr.argumentTypes)); case MethodType.Async: if (string.IsNullOrEmpty(attr.methodName)) { return null; } return AccessTools.AsyncMoveNext(AccessTools.DeclaredMethod(attr.declaringType, attr.methodName, attr.argumentTypes)); } } } catch (AmbiguousMatchException ex) { throw new HarmonyException("Ambiguous match for HarmonyMethod[" + attr.Description() + "]", ex.InnerException ?? ex); } return null; } } public enum MethodType { Normal, Getter, Setter, Constructor, StaticConstructor, Enumerator, Async } public enum ArgumentType { Normal, Ref, Out, Pointer } public enum HarmonyPatchType { All, Prefix, Postfix, Transpiler, Finalizer, ReversePatch, ILManipulator } public enum HarmonyReversePatchType { Original, Snapshot } public enum MethodDispatchType { VirtualCall, Call } [MeansImplicitUse] public class HarmonyAttribute : Attribute { public HarmonyMethod info = new HarmonyMethod(); } [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class HarmonyPatchCategory : HarmonyAttribute { public HarmonyPatchCategory(string category) { info.category = category; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Delegate, AllowMultiple = true)] public class HarmonyPatch : HarmonyAttribute { public HarmonyPatch() { } public HarmonyPatch(Type declaringType) { info.declaringType = declaringType; } public HarmonyPatch(Type declaringType, Type[] argumentTypes) { info.declaringType = declaringType; info.argumentTypes = argumentTypes; } public HarmonyPatch(Type declaringType, string methodName) { info.declaringType = declaringType; info.methodName = methodName; } public HarmonyPatch(Type declaringType, string methodName, params Type[] argumentTypes) { info.declaringType = declaringType; info.methodName = methodName; info.argumentTypes = argumentTypes; } public HarmonyPatch(Type declaringType, string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations) { info.declaringType = declaringType; info.methodName = methodName; ParseSpecialArguments(argumentTypes, argumentVariations); } public HarmonyPatch(string typeName, string methodName) { info.declaringType = AccessTools.TypeByName(typeName); info.methodName = methodName; } public HarmonyPatch(string typeName, string methodName, MethodType methodType, Type[] argumentTypes = null, ArgumentType[] argumentVariations = null) { info.declaringType = AccessTools.TypeByName(typeName); info.methodName = methodName; info.methodType = methodType; if (argumentTypes != null) { ParseSpecialArguments(argumentTypes, argumentVariations); } } public HarmonyPatch(Type declaringType, MethodType methodType) { info.declaringType = declaringType; info.methodType = methodType; } public HarmonyPatch(Type declaringType, MethodType methodType, params Type[] argumentTypes) { info.declaringType = declaringType; info.methodType = methodType; info.argumentTypes = argumentTypes; } public HarmonyPatch(Type declaringType, MethodType methodType, Type[] argumentTypes, ArgumentType[] argumentVariations) { info.declaringType = declaringType; info.methodType = methodType; ParseSpecialArguments(argumentTypes, argumentVariations); } public HarmonyPatch(Type declaringType, string methodName, MethodType methodType) { info.declaringType = declaringType; info.methodName = methodName; info.methodType = methodType; } public HarmonyPatch(string methodName) { info.methodName = methodName; } public HarmonyPatch(string methodName, params Type[] argumentTypes) { info.methodName = methodName; info.argumentTypes = argumentTypes; } public HarmonyPatch(string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations) { info.methodName = methodName; ParseSpecialArguments(argumentTypes, argumentVariations); } public HarmonyPatch(string methodName, MethodType methodType) { info.methodName = methodName; info.methodType = methodType; } public HarmonyPatch(MethodType methodType) { info.methodType = methodType; } public HarmonyPatch(MethodType methodType, params Type[] argumentTypes) { info.methodType = methodType; info.argumentTypes = argumentTypes; } public HarmonyPatch(MethodType methodType, Type[] argumentTypes, ArgumentType[] argumentVariations) { info.methodType = methodType; ParseSpecialArguments(argumentTypes, argumentVariations); } public HarmonyPatch(Type[] argumentTypes) { info.argumentTypes = argumentTypes; } public HarmonyPatch(Type[] argumentTypes, ArgumentType[] argumentVariations) { ParseSpecialArguments(argumentTypes, argumentVariations); } public HarmonyPatch(string typeName, string methodName, MethodType methodType = MethodType.Normal) { info.declaringType = AccessTools.TypeByName(typeName); info.methodName = methodName; info.methodType = methodType; } private void ParseSpecialArguments(Type[] argumentTypes, ArgumentType[] argumentVariations) { if (argumentVariations == null || argumentVariations.Length == 0) { info.argumentTypes = argumentTypes; return; } if (argumentTypes.Length < argumentVariations.Length) { throw new ArgumentException("argumentVariations contains more elements than argumentTypes", "argumentVariations"); } List<Type> list = new List<Type>(); for (int i = 0; i < argumentTypes.Length; i++) { Type type = argumentTypes[i]; switch (argumentVariations[i]) { case ArgumentType.Ref: case ArgumentType.Out: type = type.MakeByRefType(); break; case ArgumentType.Pointer: type = type.MakePointerType(); break; } list.Add(type); } info.argumentTypes = list.ToArray(); } } [AttributeUsage(AttributeTargets.Delegate, AllowMultiple = true)] public class HarmonyDelegate : HarmonyPatch { public HarmonyDelegate(Type declaringType) : base(declaringType) { } public HarmonyDelegate(Type declaringType, Type[] argumentTypes) : base(declaringType, argumentTypes) { } public HarmonyDelegate(Type declaringType, string methodName) : base(declaringType, methodName) { } public HarmonyDelegate(Type declaringType, string methodName, params Type[] argumentTypes) : base(declaringType, methodName, argumentTypes) { } public HarmonyDelegate(Type declaringType, string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations) : base(declaringType, methodName, argumentTypes, argumentVariations) { } public HarmonyDelegate(Type declaringType, MethodDispatchType methodDispatchType) : base(declaringType, MethodType.Normal) { info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call; } public HarmonyDelegate(Type declaringType, MethodDispatchType methodDispatchType, params Type[] argumentTypes) : base(declaringType, MethodType.Normal, argumentTypes) { info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call; } public HarmonyDelegate(Type declaringType, MethodDispatchType methodDispatchType, Type[] argumentTypes, ArgumentType[] argumentVariations) : base(declaringType, MethodType.Normal, argumentTypes, argumentVariations) { info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call; } public HarmonyDelegate(Type declaringType, string methodName, MethodDispatchType methodDispatchType) : base(declaringType, methodName, MethodType.Normal) { info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call; } public HarmonyDelegate(string methodName) : base(methodName) { } public HarmonyDelegate(string methodName, params Type[] argumentTypes) : base(methodName, argumentTypes) { } public HarmonyDelegate(string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations) : base(methodName, argumentTypes, argumentVariations) { } public HarmonyDelegate(string methodName, MethodDispatchType methodDispatchType) : base(methodName, MethodType.Normal) { info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call; } public HarmonyDelegate(MethodDispatchType methodDispatchType) { info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call; } public HarmonyDelegate(MethodDispatchType methodDispatchType, params Type[] argumentTypes) : base(MethodType.Normal, argumentTypes) { info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call; } public HarmonyDelegate(MethodDispatchType methodDispatchType, Type[] argumentTypes, ArgumentType[] argumentVariations) : base(MethodType.Normal, argumentTypes, argumentVariations) { info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call; } public HarmonyDelegate(Type[] argumentTypes) : base(argumentTypes) { } public HarmonyDelegate(Type[] argumentTypes, ArgumentType[] argumentVariations) : base(argumentTypes, argumentVariations) { } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] public class HarmonyReversePatch : HarmonyAttribute { public HarmonyReversePatch(HarmonyReversePatchType type = HarmonyReversePatchType.Original) { info.reversePatchType = type; } } [AttributeUsage(AttributeTargets.Class)] public class HarmonyPatchAll : HarmonyAttribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class HarmonyPriority : HarmonyAttribute { public HarmonyPriority(int priority) { info.priority = priority; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class HarmonyBefore : HarmonyAttribute { public HarmonyBefore(params string[] before) { info.before = before; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class HarmonyAfter : HarmonyAttribute { public HarmonyAfter(params string[] after) { info.after = after; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class HarmonyDebug : HarmonyAttribute { public HarmonyDebug() { info.debug = true; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class HarmonyEmitIL : HarmonyAttribute { public HarmonyEmitIL() { info.debugEmitPath = "./"; } public HarmonyEmitIL(string dir) { info.debugEmitPath = dir; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class HarmonyWrapSafe : HarmonyAttribute { public HarmonyWrapSafe() { info.wrapTryCatch = true; } } [AttributeUsage(AttributeTargets.Method)] public class HarmonyPrepare : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class HarmonyCleanup : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class HarmonyTargetMethod : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class HarmonyTargetMethods : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class HarmonyPrefix : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class HarmonyPostfix : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class HarmonyTranspiler : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class HarmonyILManipulator : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class HarmonyFinalizer : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Parameter, AllowMultiple = true)] public class HarmonyArgument : Attribute { public string OriginalName { get; private set; } public int Index { get; private set; } public string NewName { get; private set; } public HarmonyArgument(string originalName) : this(originalName, null) { } public HarmonyArgument(int index) : this(index, null) { } public HarmonyArgument(string originalName, string newName) { OriginalName = originalName; Index = -1; NewName = newName; } public HarmonyArgument(int index, string name) { OriginalName = null; Index = index; NewName = name; } } [AttributeUsage(AttributeTargets.Method)] public class HarmonyOptional : HarmonyAttribute { public HarmonyOptional() { info.optional = true; } } public class CodeInstruction { public OpCode opcode; public object operand; public List<Label> labels = new List<Label>(); public List<ExceptionBlock> blocks = new List<ExceptionBlock>(); internal CodeInstruction() { } public CodeInstruction(OpCode opcode, object operand = null) { this.opcode = opcode; this.operand = operand; } public CodeInstruction(CodeInstruction instruction) { opcode = instruction.opcode; operand = instruction.operand; labels = instruction.labels.ToList(); blocks = instruction.blocks.ToList(); } public CodeInstruction Clone() { return new CodeInstruction(this) { labels = new List<Label>(), blocks = new List<ExceptionBlock>() }; } public CodeInstruction Clone(OpCode opcode) { CodeInstruction codeInstruction = Clone(); codeInstruction.opcode = opcode; return codeInstruction; } public CodeInstruction Clone(object operand) { CodeInstruction codeInstruction = Clone(); codeInstruction.operand = operand; return codeInstruction; } public static CodeInstruction Call(Type type, string name, Type[] parameters = null, Type[] generics = null) { MethodInfo methodInfo = AccessTools.Method(type, name, parameters, generics); if ((object)methodInfo == null) { throw new ArgumentException($"No method found for type={type}, name={name}, parameters={parameters.Description()}, generics={generics.Description()}"); } return new CodeInstruction(OpCodes.Call, methodInfo); } public static CodeInstruction Call(string typeColonMethodname, Type[] parameters = null, Type[] generics = null) { MethodInfo methodInfo = AccessTools.Method(typeColonMethodname, parameters, generics); if ((object)methodInfo == null) { throw new ArgumentException($"No method found for {typeColonMethodname}, parameters={parameters.Description()}, generics={generics.Description()}"); } return new CodeInstruction(OpCodes.Call, methodInfo); } public static CodeInstruction Call(Expression<Action> expression) { return new CodeInstruction(OpCodes.Call, SymbolExtensions.GetMethodInfo(expression)); } public static CodeInstruction Call<T>(Expression<Action<T>> expression) { return new CodeInstruction(OpCodes.Call, SymbolExtensions.GetMethodInfo(expression)); } public static CodeInstruction Call<T, TResult>(Expression<Func<T, TResult>> expression) { return new CodeInstruction(OpCodes.Call, SymbolExtensions.GetMethodInfo(expression)); } public static CodeInstruction Call(LambdaExpression expression) { return new CodeInstruction(OpCodes.Call, SymbolExtensions.GetMethodInfo(expression)); } public static CodeInstruction CallClosure<T>(T closure) where T : Delegate { return Transpilers.EmitDelegate(closure); } public static CodeInstruction LoadField(Type type, string name, bool useAddress = false) { FieldInfo fieldInfo = AccessTools.Field(type, name); if ((object)fieldInfo == null) { throw new ArgumentException($"No field found for {type} and {name}"); } return new CodeInstruction((!useAddress) ? (fieldInfo.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld) : (fieldInfo.IsStatic ? OpCodes.Ldsflda : OpCodes.Ldflda), fieldInfo); } public static CodeInstruction StoreField(Type type, string name) { FieldInfo fieldInfo = AccessTools.Field(type, name); if ((object)fieldInfo == null) { throw new ArgumentException($"No field found for {type} and {name}"); } return new CodeInstruction(fieldInfo.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fieldInfo); } public static CodeInstruction LoadLocal(int index, bool useAddress = false) { if (useAddress) { if (index < 256) { return new CodeInstruction(OpCodes.Ldloca_S, Convert.ToByte(index)); } return new CodeInstruction(OpCodes.Ldloca, index); } if (index == 0) { return new CodeInstruction(OpCodes.Ldloc_0); } if (index == 1) { return new CodeInstruction(OpCodes.Ldloc_1); } if (index == 2) { return new CodeInstruction(OpCodes.Ldloc_2); } if (index == 3) { return new CodeInstruction(OpCodes.Ldloc_3); } if (index < 256) { return new CodeInstruction(OpCodes.Ldloc_S, Convert.ToByte(index)); } return new CodeInstruction(OpCodes.Ldloc, index); } public static CodeInstruction StoreLocal(int index) { if (index == 0) { return new CodeInstruction(OpCodes.Stloc_0); } if (index == 1) { return new CodeInstruction(OpCodes.Stloc_1); } if (index == 2) { return new CodeInstruction(OpCodes.Stloc_2); } if (index == 3) { return new CodeInstruction(OpCodes.Stloc_3); } if (index < 256) { return new CodeInstruction(OpCodes.Stloc_S, Convert.ToByte(index)); } return new CodeInstruction(OpCodes.Stloc, index); } public static CodeInstruction LoadArgument(int index, bool useAddress = false) { if (useAddress) { if (index < 256) { return new CodeInstruction(OpCodes.Ldarga_S, Convert.ToByte(index)); } return new CodeInstruction(OpCodes.Ldarga, index); } if (index == 0) { return new CodeInstruction(OpCodes.Ldarg_0); } if (index == 1) { return new CodeInstruction(OpCodes.Ldarg_1); } if (index == 2) { return new CodeInstruction(OpCodes.Ldarg_2); } if (index == 3) { return new CodeInstruction(OpCodes.Ldarg_3); } if (index < 256) { return new CodeInstruction(OpCodes.Ldarg_S, Convert.ToByte(index)); } return new CodeInstruction(OpCodes.Ldarg, index); } public static CodeInstruction StoreArgument(int index) { if (index < 256) { return new CodeInstruction(OpCodes.Starg_S, Convert.ToByte(index)); } return new CodeInstruction(OpCodes.Starg, index); } public override string ToString() { List<string> list = new List<string>(); foreach (Label label in labels) { list.Add($"Label{label.GetHashCode()}"); } foreach (ExceptionBlock block in blocks) { list.Add("EX_" + block.blockType.ToString().Replace("Block", "")); } string text = ((list.Count > 0) ? (" [" + string.Join(", ", list.ToArray()) + "]") : ""); string text2 = FormatArgument(operand); if (text2.Length > 0) { text2 = " " + text2; } OpCode opCode = opcode; return opCode.ToString() + text2 + text; } internal static string FormatArgument(object argument, string extra = null) { if (argument == null) { return "NULL"; } Type type = argument.GetType(); if (argument is MethodBase member) { return member.FullDescription() + ((extra != null) ? (" " + extra) : ""); } if (argument is FieldInfo fieldInfo) { return $"{fieldInfo.FieldType.FullDescription()} {fieldInfo.DeclaringType.FullDescription()}::{fieldInfo.Name}"; } if (type == typeof(Label)) { return $"Label{((Label)argument/*cast due to .constrained prefix*/).GetHashCode()}"; } if (type == typeof(Label[])) { return "Labels" + string.Join(",", ((Label[])argument).Select((Label l) => l.GetHashCode().ToString()).ToArray()); } if (type == typeof(LocalBuilder)) { return $"{((LocalBuilder)argument).LocalIndex} ({((LocalBuilder)argument).LocalType})"; } if (type == typeof(string)) { return argument.ToString().ToLiteral(); } return argument.ToString().Trim(); } } public enum ExceptionBlockType { BeginExceptionBlock, BeginCatchBlock, BeginExceptFilterBlock, BeginFaultBlock, BeginFinallyBlock, EndExceptionBlock } public class ExceptionBlock { public ExceptionBlockType blockType; public Type catchType; public ExceptionBlock(ExceptionBlockType blockType, Type catchType = null) { this.blockType = blockType; this.catchType = catchType ?? typeof(object); base..ctor(); } } public class InvalidHarmonyPatchArgumentException : Exception { public MethodBase Original { get; } public MethodInfo Patch { get; } public override string Message => "(" + Patch.FullDescription() + "): " + base.Message; public InvalidHarmonyPatchArgumentException(string message, MethodBase original, MethodInfo patch) : base(message) { Original = original; Patch = patch; } } public class MemberNotFoundException : Exception { public MemberNotFoundException(string message) : base(message) { } } public class Harmony : IDisposable { [Obsolete("Use HarmonyFileLog.Enabled instead")] public static bool DEBUG; private static int _autoGuidCounter; public string Id { get; } static Harmony() { _autoGuidCounter = 100; StackTraceFixes.Install(); } public Harmony(string id) { if (string.IsNullOrEmpty(id)) { throw new ArgumentException("id cannot be null or empty"); } try { string environmentVariable = Environment.GetEnvironmentVariable("HARMONY_DEBUG"); if (environmentVariable != null && environmentVariable.Length > 0) { environmentVariable = environmentVariable.Trim(); DEBUG = environmentVariable == "1" || bool.Parse(environmentVariable); } } catch { } if (DEBUG) { HarmonyFileLog.Enabled = true; } MethodBase callingMethod = (Logger.IsEnabledFor(Logger.LogChannel.Info) ? AccessTools.GetOutsideCaller() : null); Logger.Log(Logger.LogChannel.Info, delegate { StringBuilder stringBuilder = new StringBuilder(); Assembly assembly = typeof(Harmony).Assembly; Version version = assembly.GetName().Version; string location = assembly.Location; string value = Environment.Version.ToString(); string value2 = Environment.OSVersion.Platform.ToString(); int size = IntPtr.Size; stringBuilder.AppendLine($"### Harmony id={id}, version={version}, location={location}, env/clr={value}, platform={value2}, ptrsize:runtime={size}"); if ((object)callingMethod?.DeclaringType != null) { Assembly assembly2 = callingMethod.DeclaringType.Assembly; location = assembly2.Location; stringBuilder.AppendLine("### Started from " + callingMethod.FullDescription() + ", location " + location); stringBuilder.Append($"### At {DateTime.Now:yyyy-MM-dd hh.mm.ss}"); } return stringBuilder.ToString(); }); Id = id; } public void PatchAll() { MethodBase method = new StackTrace().GetFrame(1).GetMethod(); Assembly assembly = method.ReflectedType.Assembly; PatchAll(assembly); } public PatchProcessor CreateProcessor(MethodBase original) { return new PatchProcessor(this, original); } public PatchClassProcessor CreateClassProcessor(Type type) { return new PatchClassProcessor(this, type); } public PatchClassProcessor CreateClassProcessor(Type type, bool allowUnannotatedType) { return new PatchClassProcessor(this, type, allowUnannotatedType); } public ReversePatcher CreateReversePatcher(MethodBase original, HarmonyMethod standin) { return new ReversePatcher(this, original, standin); } public void PatchAll(Assembly assembly) { AccessTools.GetTypesFromAssembly(assembly).Do(delegate(Type type) { CreateClassProcessor(type).Patch(); }); } public void PatchAll(Type type) { CreateClassProcessor(type, allowUnannotatedType: true).Patch(); } public void PatchAllUncategorized() { MethodBase method = new StackTrace().GetFrame(1).GetMethod(); Assembly assembly = method.ReflectedType.Assembly; PatchAllUncategorized(assembly); } public void PatchAllUncategorized(Assembly assembly) { PatchClassProcessor[] sequence = AccessTools.GetTypesFromAssembly(assembly).Select(CreateClassProcessor).ToArray(); sequence.DoIf((PatchClassProcessor patchClass) => string.IsNullOrEmpty(patchClass.Category), delegate(PatchClassProcessor patchClass) { patchClass.Patch(); }); } public void PatchCategory(string category) { MethodBase method = new StackTrace().GetFrame(1).GetMethod(); Assembly assembly = method.ReflectedType.Assembly; PatchCategory(assembly, category); } public void PatchCategory(Assembly assembly, string category) { AccessTools.GetTypesFromAssembly(assembly).Where(delegate(Type type) { List<HarmonyMethod> fromType = HarmonyMethodExtensions.GetFromType(type); HarmonyMethod harmonyMethod = HarmonyMethod.Merge(fromType); return harmonyMethod.category == category; }).Do(delegate(Type type) { CreateClassProcessor(type).Patch(); }); } public MethodInfo Patch(MethodBase original, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null, HarmonyMethod ilmanipulator = null) { PatchProcessor patchProcessor = CreateProcessor(original); patchProcessor.AddPrefix(prefix); patchProcessor.AddPostfix(postfix); patchProcessor.AddTranspiler(transpiler); patchProcessor.AddFinalizer(finalizer); patchProcessor.AddILManipulator(ilmanipulator); return patchProcessor.Patch(); } [Obsolete("Use newer Patch() instead", true)] public MethodInfo Patch(MethodBase original, HarmonyMethod prefix, HarmonyMethod postfix, HarmonyMethod transpiler, HarmonyMethod finalizer) { return Patch(original, prefix, postfix, transpiler, finalizer, null); } public static MethodInfo ReversePatch(MethodBase original, HarmonyMethod standin, MethodInfo transpiler = null, MethodInfo ilmanipulator = null) { return PatchFunctions.ReversePatch(standin, original, transpiler, ilmanipulator); } [Obsolete("Use newer ReversePatch() instead", true)] public static MethodInfo ReversePatch(MethodBase original, HarmonyMethod standin, MethodInfo transpiler) { return PatchFunctions.ReversePatch(standin, original, transpiler, null); } public static void UnpatchID(string harmonyID) { if (string.IsNullOrEmpty(harmonyID)) { throw new ArgumentNullException("harmonyID", "UnpatchID was called with a null or empty harmonyID."); } PatchFunctions.UnpatchConditional((Patch patchInfo) => patchInfo.owner == harmonyID); } void IDisposable.Dispose() { UnpatchSelf(); } public void UnpatchSelf() { UnpatchID(Id); } public static void UnpatchAll() { Logger.Log(Logger.LogChannel.Warn, () => "UnpatchAll has been called - This will remove ALL HARMONY PATCHES."); PatchFunctions.UnpatchConditional((Patch _) => true); } [Obsolete("Use UnpatchSelf() to unpatch the current instance. The functionality to unpatch either other ids or EVERYTHING has been moved the static methods UnpatchID() and UnpatchAll() respectively", true)] public void UnpatchAll(string harmonyID = null) { if (harmonyID == null) { if (HarmonyGlobalSettings.DisallowLegacyGlobalUnpatchAll) { Logger.Log(Logger.LogChannel.Warn, () => "Legacy UnpatchAll has been called AND DisallowLegacyGlobalUnpatchAll=true. Skipping execution of UnpatchAll"); } else { UnpatchAll(); } } else if (harmonyID.Length == 0) { Logger.Log(Logger.LogChannel.Warn, () => "Legacy UnpatchAll was called with harmonyID=\"\" which is an invalid id. Skipping execution of UnpatchAll"); } else { UnpatchID(harmonyID); } } public void Unpatch(MethodBase original, HarmonyPatchType type, string harmonyID = "*") { PatchProcessor patchProcessor = CreateProcessor(original); patchProcessor.Unpatch(type, harmonyID); } public void Unpatch(MethodBase original, MethodInfo patch) { PatchProcessor patchProcessor = CreateProcessor(original); patchProcessor.Unpatch(patch); } public void UnpatchCategory(string category) { MethodBase method = new StackTrace().GetFrame(1).GetMethod(); Assembly assembly = method.ReflectedType.Assembly; UnpatchCategory(assembly, category); } public void UnpatchCategory(Assembly assembly, string category) { AccessTools.GetTypesFromAssembly(assembly).Where(delegate(Type type) { List<HarmonyMethod> fromType = HarmonyMethodExtensions.GetFromType(type); HarmonyMethod harmonyMethod = HarmonyMethod.Merge(fromType); return harmonyMethod.category == category; }).Do(delegate(Type type) { CreateClassProcessor(type).Unpatch(); }); } public static bool HasAnyPatches(string harmonyID) { return GetAllPatchedMethods().Select(GetPatchInfo).Any((Patches info) => info.Owners.Contains(harmonyID)); } public static Patches GetPatchInfo(MethodBase method) { return PatchProcessor.GetPatchInfo(method); } public IEnumerable<MethodBase> GetPatchedMethods() { return from original in GetAllPatchedMethods() where GetPatchInfo(original).Owners.Contains(Id) select original; } public static IEnumerable<MethodBase> GetAllPatchedMethods() { return PatchProcessor.GetAllPatchedMethods(); } public static MethodBase GetOriginalMethod(MethodInfo replacement) { if (replacement == null) { throw new ArgumentNullException("replacement"); } return PatchManager.GetRealMethod(replacement, useReplacement: false); } public static MethodBase GetMethodFromStackframe(StackFrame frame) { if (frame == null) { throw new ArgumentNullException("frame"); } return PatchManager.GetStackFrameMethod(frame, useReplacement: true); } public static MethodBase GetOriginalMethodFromStackframe(StackFrame frame) { if (frame == null) { throw new ArgumentNullException("frame"); } return PatchManager.GetStackFrameMethod(frame, useReplacement: false); } public static Dictionary<string, Version> VersionInfo(out Version currentVersion) { return PatchProcessor.VersionInfo(out currentVersion); } public static Harmony CreateAndPatchAll(Type type, string harmonyInstanceId = null) { if (type == null) { throw new ArgumentNullException("type"); } Harmony harmony = new Harmony(harmonyInstanceId ?? $"harmony-auto-{Interlocked.Increment(ref _autoGuidCounter)}-{type.Assembly.GetName().Name}-{type.FullName}"); harmony.PatchAll(type); return harmony; } public static Harmony CreateAndPatchAll(Assembly assembly, string harmonyInstanceId = null) { if (assembly == null) { throw new ArgumentNullException("assembly"); } Harmony harmony = new Harmony(harmonyInstanceId ?? $"harmony-auto-{Interlocked.Increment(ref _autoGuidCounter)}-{assembly.GetName().Name}"); harmony.PatchAll(assembly); return harmony; } } [Serializable] public class HarmonyException : Exception { private Dictionary<int, CodeInstruction> instructions = new Dictionary<int, CodeInstruction>(); private int errorOffset = -1; internal HarmonyException() { } internal HarmonyException(string message) : base(message) { } internal HarmonyException(string message, Exception innerException) : base(message, innerException) { } protected HarmonyException(SerializationInfo serializationInfo, StreamingContext streamingContext) { throw new NotImplementedException(); } internal HarmonyException(Exception innerException, Dictionary<int, CodeInstruction> instructions, int errorOffset) : base("IL Compile Error", innerException) { this.instructions = instructions; this.errorOffset = errorOffset; } internal static Exception Create(Exception ex, MethodBody body) { if (ex is HarmonyException { instructions: { Count: >0 }, errorOffset: >=0 }) { return ex; } Match match = Regex.Match(ex.Message.TrimEnd(Array.Empty<char>()), "(?:Reason: )?Invalid IL code in.+: IL_(\\d{4}): (.+)$"); if (!match.Success) { return new HarmonyException("IL Compile Error (unknown location)", ex); } Dictionary<int, CodeInstruction> dictionary2 = ILManipulator.GetInstructions(body) ?? new Dictionary<int, CodeInstruction>(); int num = int.Parse(match.Groups[1].Value, NumberStyles.HexNumber); Regex.Replace(match.Groups[2].Value, " {2,}", " "); if (ex is HarmonyException ex3) { if (dictionary2.Count != 0) { ex3.instructions = dictionary2; ex3.errorOffset = num; } return ex3; } return new HarmonyException(ex, dictionary2, num); } public List<KeyValuePair<int, CodeInstruction>> GetInstructionsWithOffsets() { return instructions.OrderBy((KeyValuePair<int, CodeInstruction> ins) => ins.Key).ToList(); } public List<CodeInstruction> GetInstructions() { return (from ins in instructions orderby ins.Key select ins.Value).ToList(); } public int GetErrorOffset() { return errorOffset; } public int GetErrorIndex() { if (instructions.TryGetValue(errorOffset, out var value)) { return GetInstructions().IndexOf(value); } return -1; } } public static class HarmonyGlobalSettings { public static bool DisallowLegacyGlobalUnpatchAll { get; set; } } public class HarmonyMethod { public MethodInfo method; public string category; public Type declaringType; public string methodName; public MethodType? methodType; public Type[] argumentTypes; public int priority = -1; public string[] before; public string[] after; public HarmonyReversePatchType? reversePatchType; public bool? debug; public string debugEmitPath; public bool nonVirtualDelegate; public bool? wrapTryCatch; public bool? optional; public HarmonyMethod() { } private void ImportMethod(MethodInfo theMethod) { if ((object)theMethod == null) { throw new ArgumentNullException("theMethod", "Harmony method is null (did you target a wrong or missing method?)"); } if (!theMethod.IsStatic) { throw new ArgumentException("Harmony method must be static", "theMethod"); } method = theMethod; List<HarmonyMethod> fromMethod = HarmonyMethodExtensions.GetFromMethod(method); if (fromMethod != null) { Merge(fromMethod).CopyTo(this); } } public HarmonyMethod(MethodInfo method) { if ((object)method == null) { throw new ArgumentNullException("method"); } ImportMethod(method); } public HarmonyMethod(Delegate @delegate) : this(@delegate.Method) { } public HarmonyMethod(MethodInfo method, int priority = -1, string[] before = null, string[] after = null, bool? debug = null) { if ((object)method == null) { throw new ArgumentNullException("method"); } ImportMethod(method); this.priority = priority; this.before = before; this.after = after; this.debug = debug; } public HarmonyMethod(Delegate @delegate, int priority = -1, string[] before = null, string[] after = null, bool? debug = null) : this(@delegate.Method, priority, before, after, debug) { } public HarmonyMethod(Type methodType, string methodName, Type[] argumentTypes = null) { MethodInfo methodInfo = AccessTools.Method(methodType, methodName, argumentTypes); if ((object)methodInfo == null) { throw new ArgumentException($"Cannot not find method for type {methodType} and name {methodName} and parameters {argumentTypes?.Description()}"); } ImportMethod(methodInfo); } public static List<string> HarmonyFields() { return (from s in AccessTools.GetFieldNames(typeof(HarmonyMethod)) where s != "method" select s).ToList(); } public static HarmonyMethod Merge(List<HarmonyMethod> attributes) { if (attributes == null || attributes.Count == 0) { return new HarmonyMethod(); } return Merge((IEnumerable<HarmonyMethod>)attributes); } internal static HarmonyMethod Merge(IEnumerable<HarmonyMethod> attributes) { HarmonyMethod harmonyMethod = new HarmonyMethod(); if (attributes == null) { return harmonyMethod; } Traverse resultTrv = Traverse.Create(harmonyMethod); attributes.Do(delegate(HarmonyMethod attribute) { Traverse trv = Traverse.Create(attribute); HarmonyFields().ForEach(delegate(string f) { object value = trv.Field(f).GetValue(); if (value != null && (f != "priority" || (int)value != -1)) { HarmonyMethodExtensions.SetValue(resultTrv, f, value); } }); }); return harmonyMethod; } public override string ToString() { string result = ""; Traverse trv = Traverse.Create(this); HarmonyFields().ForEach(delegate(string f) { if (result.Length > 0) { result += ", "; } result += $"{f}={trv.Field(f).GetValue()}"; }); return "HarmonyMethod[" + result + "]"; } internal string Description() { string value = (((object)declaringType != null) ? declaringType.FullDescription() : "undefined"); string value2 = methodName ?? "undefined"; string value3 = (methodType.HasValue ? methodType.Value.ToString() : "undefined"); string value4 = ((argumentTypes != null) ? argumentTypes.Description() : "undefined"); return $"(class={value}, methodname={value2}, type={value3}, args={value4})"; } internal Type[] GetArgumentList() { return argumentTypes ?? Type.EmptyTypes; } public static implicit operator HarmonyMethod(MethodInfo method) { return new HarmonyMethod(method); } public static implicit operator HarmonyMethod(Delegate @delegate) { return new HarmonyMethod(@delegate); } } public static class HarmonyMethodExtensions { internal static void SetValue(Traverse trv, string name, object val) { if (val != null) { Traverse traverse = trv.Field(name); if (name == "methodType" || name == "reversePatchType") { Type underlyingType = Nullable.GetUnderlyingType(traverse.GetValueType()); val = Enum.ToObject(underlyingType, (int)val); } traverse.SetValue(val); } } public static void CopyTo(this HarmonyMethod from, HarmonyMethod to) { if (to == null) { return; } Traverse fromTrv = Traverse.Create(from); Traverse toTrv = Traverse.Create(to); HarmonyMethod.HarmonyFields().ForEach(delegate(string f) { object value = fromTrv.Field(f).GetValue(); if (value != null) { SetValue(toTrv, f, value); } }); } public static HarmonyMethod Clone(this HarmonyMethod original) { HarmonyMethod harmonyMethod = new HarmonyMethod(); original.CopyTo(harmonyMethod); return harmonyMethod; } public static HarmonyMethod Merge(this HarmonyMethod master, HarmonyMethod detail) { if (detail == null) { return master; } HarmonyMethod harmonyMethod = new HarmonyMethod(); Traverse resultTrv = Traverse.Create(harmonyMethod); Traverse masterTrv = Traverse.Create(master); Traverse detailTrv = Traverse.Create(detail); HarmonyMethod.HarmonyFields().ForEach(delegate(string f) { object value = masterTrv.Field(f).GetValue(); object value2 = detailTrv.Field(f).GetValue(); if (f != "priority") { SetValue(resultTrv, f, value2 ?? value); } else { int num = (int)value; int num2 = (int)value2; int num3 = Math.Max(num, num2); if (num == -1 && num2 != -1) { num3 = num2; } if (num != -1 && num2 == -1) { num3 = num; } SetValue(resultTrv, f, num3); } }); return harmonyMethod; } private static HarmonyMethod GetHarmonyMethodInfo(object attribute) { FieldInfo field = attribute.GetType().GetField("info", AccessTools.all); if ((object)field == null) { return null; } if (field.FieldType.FullName != PatchTools.harmonyMethodFullName) { return null; } object value = field.GetValue(attribute); return AccessTools.MakeDeepCopy<HarmonyMethod>(value); } public static List<HarmonyMethod> GetFromType(Type type) { return (from info in type.GetCustomAttributes(inherit: true).Select(GetHarmonyMethodInfo) where info != null select info).ToList(); } public static HarmonyMethod GetMergedFromType(Type type) { return HarmonyMethod.Merge(GetFromType(type)); } public static List<HarmonyMethod> GetFromMethod(MethodBase method) { return (from info in method.GetCustomAttributes(inherit: true).Select(GetHarmonyMethodInfo) where info != null select info).ToList(); } public static HarmonyMethod GetMergedFromMethod(MethodBase method) { return HarmonyMethod.Merge(GetFromMethod(method)); } } internal static class PatchInfoSerialization { private class Binder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { Type[] array = new Type[3] { typeof(PatchInfo), typeof(Patch[]), typeof(Patch) }; Type[] array2 = array; foreach (Type type in array2) { if (typeName == type.FullName) { return type; } } return Type.GetType($"{typeName}, {assemblyName}"); } } private static readonly JsonSerializerOptions serializerOptions = new JsonSerializerOptions { IncludeFields = true }; internal static bool? useBinaryFormatter = null; internal static readonly BinaryFormatter binaryFormatter = new BinaryFormatter { Binder = new Binder() }; internal static bool UseBinaryFormatter { get { if (!useBinaryFormatter.HasValue) { if (AppContext.TryGetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", out var isEnabled)) { useBinaryFormatter = isEnabled; } else { useBinaryFormatter = true; } } return useBinaryFormatter.Value; } } internal static byte[] Serialize(this PatchInfo patchInfo) { if (UseBinaryFormatter) { using (MemoryStream memoryStream = new MemoryStream()) { binaryFormatter.Serialize(memoryStream, patchInfo); return memoryStream.GetBuffer(); } } return JsonSerializer.SerializeToUtf8Bytes(patchInfo); } internal static PatchInfo Deserialize(byte[] bytes) { if (UseBinaryFormatter) { using (MemoryStream ser
BepInExPack/BepInEx/core/BepInEx.Core.dll
Decompiled a day 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.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.ConsoleUtil; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using HarmonyLib; using HarmonyLib.Tools; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Collections.Generic; using MonoMod.Utils; using SemanticVersioning; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("BepInEx.Preloader.Core")] [assembly: InternalsVisibleTo("BepInEx.NET.CoreCLR")] [assembly: InternalsVisibleTo("BepInExTests")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("BepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2022 BepInEx Team")] [assembly: AssemblyDescription("BepInEx Core library")] [assembly: AssemblyFileVersion("6.0.0.0")] [assembly: AssemblyInformationalVersion("6.0.0+802b84c947c2b8ab870be453776f7ab895d8cf09")] [assembly: AssemblyProduct("BepInEx.Core")] [assembly: AssemblyTitle("BepInEx.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ibox233/BepinEx-6-CoreCLR-For-Romestead")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter)] 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; } } } namespace BepInEx { public static class ConsoleManager { public enum ConsoleOutRedirectType { [Description("Auto")] Auto, [Description("Console Out")] ConsoleOut, [Description("Standard Out")] StandardOut } private const uint SHIFT_JIS_CP = 932u; private const string ENABLE_CONSOLE_ARG = "--enable-console"; public static readonly ConfigEntry<bool> ConfigConsoleEnabled; public static readonly ConfigEntry<bool> ConfigPreventClose; public static readonly ConfigEntry<bool> ConfigConsoleShiftJis; public static readonly ConfigEntry<ConsoleOutRedirectType> ConfigConsoleOutRedirectType; private static readonly bool? EnableConsoleArgOverride; public static bool ConsoleEnabled => EnableConsoleArgOverride ?? ConfigConsoleEnabled.Value; internal static IConsoleDriver Driver { get; set; } public static bool ConsoleActive => Driver?.ConsoleActive ?? false; public static TextWriter StandardOutStream => Driver?.StandardOut; public static TextWriter ConsoleStream => Driver?.ConsoleOut; static ConsoleManager() { ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind("Logging.Console", "Enabled", defaultValue: true, "Enables showing a console for log output."); ConfigPreventClose = ConfigFile.CoreConfig.Bind("Logging.Console", "PreventClose", defaultValue: false, "If enabled, will prevent closing the console (either by deleting the close button or in other platform-specific way)."); ConfigConsoleShiftJis = ConfigFile.CoreConfig.Bind("Logging.Console", "ShiftJisEncoding", defaultValue: false, "If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding."); ConfigConsoleOutRedirectType = ConfigFile.CoreConfig.Bind("Logging.Console", "StandardOutType", ConsoleOutRedirectType.Auto, new StringBuilder().AppendLine("Hints console manager on what handle to assign as StandardOut. Possible values:").AppendLine("Auto - lets BepInEx decide how to redirect console output").AppendLine("ConsoleOut - prefer redirecting to console output; if possible, closes original standard output") .AppendLine("StandardOut - prefer redirecting to standard output; if possible, closes console out") .ToString()); try { string[] commandLineArgs = Environment.GetCommandLineArgs(); for (int i = 0; i < commandLineArgs.Length; i++) { if (commandLineArgs[i] == "--enable-console" && i + 1 < commandLineArgs.Length && bool.TryParse(commandLineArgs[i + 1], out var result)) { EnableConsoleArgOverride = result; } } } catch (Exception) { } } public static void Initialize(bool alreadyActive, bool useManagedEncoder) { IConsoleDriver driver; if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { IConsoleDriver consoleDriver = new UnixConsoleDriver(); driver = consoleDriver; } else { IConsoleDriver consoleDriver = new WindowsConsoleDriver(); driver = consoleDriver; } Driver = driver; Driver.Initialize(alreadyActive, useManagedEncoder); } private static void DriverCheck() { if (Driver == null) { throw new InvalidOperationException("Driver has not been initialized"); } } public static void CreateConsole() { if (!ConsoleActive) { DriverCheck(); uint codepage = (ConfigConsoleShiftJis.Value ? 932u : ((uint)Encoding.UTF8.CodePage)); Driver.CreateConsole(codepage); if (ConfigPreventClose.Value) { Driver.PreventClose(); } } } public static void DetachConsole() { if (ConsoleActive) { DriverCheck(); Driver.DetachConsole(); } } public static void SetConsoleTitle(string title) { DriverCheck(); Driver.SetConsoleTitle(title); } public static void SetConsoleColor(ConsoleColor color) { DriverCheck(); Driver.SetConsoleColor(color); } } internal interface IConsoleDriver { TextWriter StandardOut { get; } TextWriter ConsoleOut { get; } bool ConsoleActive { get; } bool ConsoleIsExternal { get; } void PreventClose(); void Initialize(bool alreadyActive, bool useManagedEncoder); void CreateConsole(uint codepage); void DetachConsole(); void SetConsoleColor(ConsoleColor color); void SetConsoleTitle(string title); } internal class UnixConsoleDriver : IConsoleDriver { public TextWriter StandardOut { get; private set; } public TextWriter ConsoleOut { get; private set; } public bool ConsoleActive { get; private set; } public bool ConsoleIsExternal => false; public void Initialize(bool alreadyActive, bool useManagedEncoder) { StandardOut = Console.Out; ConsoleOut = Console.Out; ConsoleActive = alreadyActive; } public void CreateConsole(uint codepage) { StandardOut = Console.Out; ConsoleOut = Console.Out; ConsoleActive = true; } public void PreventClose() { } public void DetachConsole() { ConsoleOut = TextWriter.Null; ConsoleActive = false; } public void SetConsoleColor(ConsoleColor color) { try { Console.ForegroundColor = color; } catch { } } public void SetConsoleTitle(string title) { try { Console.Title = title; } catch { } } } internal class WindowsConsoleDriver : IConsoleDriver { private readonly Func<int> getWindowHeight; private readonly Func<int> getWindowWidth; private bool useManagedEncoder; private int ConsoleWidth { get { try { return getWindowWidth?.Invoke() ?? 0; } catch (IOException) { return 0; } } } private int ConsoleHeight { get { try { return getWindowHeight?.Invoke() ?? 0; } catch (IOException) { return 0; } } } public TextWriter StandardOut { get; private set; } public TextWriter ConsoleOut { get; private set; } public bool ConsoleActive { get; private set; } public bool ConsoleIsExternal => true; public void Initialize(bool alreadyActive, bool useManagedEncoder) { ConsoleActive = alreadyActive; this.useManagedEncoder = useManagedEncoder; if (ConsoleActive) { ConsoleOut = Console.Out; StandardOut = new StreamWriter(Console.OpenStandardOutput()); } else { StandardOut = Console.Out; } } public void CreateConsole(uint codepage) { ConsoleWindow.Attach(); ConsoleEncoding.ConsoleCodePage = codepage; IntPtr outHandle = GetOutHandle(); if (outHandle == IntPtr.Zero) { StandardOut = TextWriter.Null; ConsoleOut = TextWriter.Null; return; } Stream stream = OpenFileStream(outHandle); StandardOut = new StreamWriter(stream, Utility.UTF8NoBom) { AutoFlush = true }; Stream stream2 = OpenFileStream(ConsoleWindow.ConsoleOutHandle); ConsoleOut = new StreamWriter(stream2, GetConsoleOutputEncoding(codepage)) { AutoFlush = true }; ConsoleActive = true; } public void PreventClose() { ConsoleWindow.PreventClose(); } public void DetachConsole() { ConsoleWindow.Detach(); ConsoleOut.Close(); ConsoleOut = null; ConsoleActive = false; } public void SetConsoleColor(ConsoleColor color) { SafeConsole.ForegroundColor = color; Kon.ForegroundColor = color; } public void SetConsoleTitle(string title) { ConsoleWindow.Title = title; } private Encoding GetConsoleOutputEncoding(uint codepage) { if (useManagedEncoder && codepage == Utility.UTF8NoBom.CodePage) { return Utility.UTF8NoBom; } return ConsoleEncoding.GetEncoding(codepage); } private static Stream OpenFileStream(IntPtr handle) { return (Stream)AccessTools.Constructor(Type.GetType("System.ConsolePal+WindowsConsoleStream, System.Console", throwOnError: true), new Type[3] { typeof(IntPtr), typeof(FileAccess), typeof(bool) }, false).Invoke(new object[3] { handle, FileAccess.Write, true }); } private IntPtr GetOutHandle() { switch (ConsoleManager.ConfigConsoleOutRedirectType.Value) { case ConsoleManager.ConsoleOutRedirectType.ConsoleOut: return ConsoleWindow.ConsoleOutHandle; case ConsoleManager.ConsoleOutRedirectType.StandardOut: return ConsoleWindow.OriginalStdoutHandle; default: if (!(ConsoleWindow.OriginalStdoutHandle != IntPtr.Zero)) { return ConsoleWindow.ConsoleOutHandle; } return ConsoleWindow.OriginalStdoutHandle; } } public WindowsConsoleDriver() { MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(Console), "WindowHeight"); getWindowHeight = (((object)methodInfo != null) ? Extensions.CreateDelegate<Func<int>>((MethodBase)methodInfo) : null); MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(Console), "WindowWidth"); getWindowWidth = (((object)methodInfo2 != null) ? Extensions.CreateDelegate<Func<int>>((MethodBase)methodInfo2) : null); base..ctor(); } } [AttributeUsage(AttributeTargets.Class)] public class BepInPlugin : Attribute { public string GUID { get; protected set; } public string Name { get; protected set; } public Version Version { get; protected set; } public BepInPlugin(string GUID, string Name, string Version) { this.GUID = GUID; this.Name = Name; this.Version = TryParseLongVersion(Version); } private static Version TryParseLongVersion(string version) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown Version result = default(Version); if (Version.TryParse(version, ref result)) { return result; } try { Version version2 = new Version(version); return new Version(version2.Major, version2.Minor, (version2.Build != -1) ? version2.Build : 0, (string)null, (string)null); } catch { } return null; } internal static BepInPlugin FromCecilType(TypeDefinition td) { //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_0032: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) CustomAttribute val = MetadataHelper.GetCustomAttributes<BepInPlugin>(td, inherit: false).FirstOrDefault(); if (val == null) { return null; } CustomAttributeArgument val2 = val.ConstructorArguments[0]; string gUID = (string)((CustomAttributeArgument)(ref val2)).Value; val2 = val.ConstructorArguments[1]; string name = (string)((CustomAttributeArgument)(ref val2)).Value; val2 = val.ConstructorArguments[2]; return new BepInPlugin(gUID, name, (string)((CustomAttributeArgument)(ref val2)).Value); } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class BepInDependency : Attribute, ICacheable { [Flags] public enum DependencyFlags { HardDependency = 1, SoftDependency = 2 } public string DependencyGUID { get; protected set; } public DependencyFlags Flags { get; protected set; } public Range VersionRange { get; protected set; } public BepInDependency(string DependencyGUID, DependencyFlags Flags = DependencyFlags.HardDependency) { this.DependencyGUID = DependencyGUID; this.Flags = Flags; VersionRange = null; } public BepInDependency(string guid, string version) : this(guid) { VersionRange = Range.Parse(version, false); } void ICacheable.Save(BinaryWriter bw) { bw.Write(DependencyGUID); bw.Write((int)Flags); bw.Write(((object)VersionRange)?.ToString() ?? string.Empty); } void ICacheable.Load(BinaryReader br) { DependencyGUID = br.ReadString(); Flags = (DependencyFlags)br.ReadInt32(); string text = br.ReadString(); VersionRange = ((text == string.Empty) ? null : Range.Parse(text, false)); } internal static IEnumerable<BepInDependency> FromCecilType(TypeDefinition td) { return MetadataHelper.GetCustomAttributes<BepInDependency>(td, inherit: true).Select(delegate(CustomAttribute customAttribute) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) CustomAttributeArgument val = customAttribute.ConstructorArguments[0]; string text = (string)((CustomAttributeArgument)(ref val)).Value; val = customAttribute.ConstructorArguments[1]; object value = ((CustomAttributeArgument)(ref val)).Value; return (value is string version) ? new BepInDependency(text, version) : new BepInDependency(text, (DependencyFlags)value); }).ToList(); } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class BepInIncompatibility : Attribute, ICacheable { public string IncompatibilityGUID { get; protected set; } public BepInIncompatibility(string IncompatibilityGUID) { this.IncompatibilityGUID = IncompatibilityGUID; } void ICacheable.Save(BinaryWriter bw) { bw.Write(IncompatibilityGUID); } void ICacheable.Load(BinaryReader br) { IncompatibilityGUID = br.ReadString(); } internal static IEnumerable<BepInIncompatibility> FromCecilType(TypeDefinition td) { return MetadataHelper.GetCustomAttributes<BepInIncompatibility>(td, inherit: true).Select(delegate(CustomAttribute customAttribute) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) CustomAttributeArgument val = customAttribute.ConstructorArguments[0]; return new BepInIncompatibility((string)((CustomAttributeArgument)(ref val)).Value); }).ToList(); } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class BepInProcess : Attribute { public string ProcessName { get; protected set; } public BepInProcess(string ProcessName) { this.ProcessName = ProcessName; } internal static List<BepInProcess> FromCecilType(TypeDefinition td) { return MetadataHelper.GetCustomAttributes<BepInProcess>(td, inherit: true).Select(delegate(CustomAttribute customAttribute) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) CustomAttributeArgument val = customAttribute.ConstructorArguments[0]; return new BepInProcess((string)((CustomAttributeArgument)(ref val)).Value); }).ToList(); } } public static class MetadataHelper { internal static IEnumerable<CustomAttribute> GetCustomAttributes<T>(TypeDefinition td, bool inherit) where T : Attribute { List<CustomAttribute> list = new List<CustomAttribute>(); Type type = typeof(T); TypeDefinition val = td; do { list.AddRange(((IEnumerable<CustomAttribute>)val.CustomAttributes).Where((CustomAttribute ca) => ((MemberReference)ca.AttributeType).FullName == type.FullName)); TypeReference baseType = val.BaseType; val = ((baseType != null) ? baseType.Resolve() : null); } while (inherit && ((val != null) ? ((MemberReference)val).FullName : null) != "System.Object"); return list; } public static BepInPlugin GetMetadata(Type pluginType) { object[] customAttributes = pluginType.GetCustomAttributes(typeof(BepInPlugin), inherit: false); if (customAttributes.Length == 0) { return null; } return (BepInPlugin)customAttributes[0]; } public static BepInPlugin GetMetadata(object plugin) { return GetMetadata(plugin.GetType()); } public static T[] GetAttributes<T>(Type pluginType) where T : Attribute { return (T[])pluginType.GetCustomAttributes(typeof(T), inherit: true); } public static T[] GetAttributes<T>(Assembly assembly) where T : Attribute { return (T[])assembly.GetCustomAttributes(typeof(T), inherit: true); } public static IEnumerable<T> GetAttributes<T>(object plugin) where T : Attribute { return GetAttributes<T>(plugin.GetType()); } public static T[] GetAttributes<T>(MemberInfo member) where T : Attribute { return (T[])member.GetCustomAttributes(typeof(T), inherit: true); } public static IEnumerable<BepInDependency> GetDependencies(Type plugin) { return plugin.GetCustomAttributes(typeof(BepInDependency), inherit: true).Cast<BepInDependency>(); } } public class PluginInfo : ICacheable { public BepInPlugin Metadata { get; internal set; } public IEnumerable<BepInProcess> Processes { get; internal set; } public IEnumerable<BepInDependency> Dependencies { get; internal set; } public IEnumerable<BepInIncompatibility> Incompatibilities { get; internal set; } public string Location { get; internal set; } public object Instance { get; internal set; } public string TypeName { get; internal set; } internal Version TargettedBepInExVersion { get; set; } void ICacheable.Save(BinaryWriter bw) { bw.Write(TypeName); bw.Write(Location); bw.Write(Metadata.GUID); bw.Write(Metadata.Name); bw.Write(((object)Metadata.Version).ToString()); List<BepInProcess> list = Processes.ToList(); bw.Write(list.Count); foreach (BepInProcess item in list) { bw.Write(item.ProcessName); } List<BepInDependency> list2 = Dependencies.ToList(); bw.Write(list2.Count); foreach (BepInDependency item2 in list2) { ((ICacheable)item2).Save(bw); } List<BepInIncompatibility> list3 = Incompatibilities.ToList(); bw.Write(list3.Count); foreach (BepInIncompatibility item3 in list3) { ((ICacheable)item3).Save(bw); } bw.Write(TargettedBepInExVersion.ToString(4)); } void ICacheable.Load(BinaryReader br) { TypeName = br.ReadString(); Location = br.ReadString(); Metadata = new BepInPlugin(br.ReadString(), br.ReadString(), br.ReadString()); int num = br.ReadInt32(); List<BepInProcess> list = new List<BepInProcess>(num); for (int i = 0; i < num; i++) { list.Add(new BepInProcess(br.ReadString())); } Processes = list; int num2 = br.ReadInt32(); List<BepInDependency> list2 = new List<BepInDependency>(num2); for (int j = 0; j < num2; j++) { BepInDependency bepInDependency = new BepInDependency(""); ((ICacheable)bepInDependency).Load(br); list2.Add(bepInDependency); } Dependencies = list2; int num3 = br.ReadInt32(); List<BepInIncompatibility> list3 = new List<BepInIncompatibility>(num3); for (int k = 0; k < num3; k++) { BepInIncompatibility bepInIncompatibility = new BepInIncompatibility(""); ((ICacheable)bepInIncompatibility).Load(br); list3.Add(bepInIncompatibility); } Incompatibilities = list3; TargettedBepInExVersion = new Version(br.ReadString()); } public override string ToString() { return $"{Metadata?.Name} {Metadata?.Version}"; } } public static class Paths { public static Version BepInExVersion { get; } = Version.Parse(MetadataHelper.GetAttributes<AssemblyInformationalVersionAttribute>(typeof(Paths).Assembly)[0].InformationalVersion, false); public static string ManagedPath { get; private set; } public static string BepInExAssemblyDirectory { get; private set; } public static string BepInExAssemblyPath { get; private set; } public static string BepInExRootPath { get; private set; } public static string ExecutablePath { get; private set; } public static string GameRootPath { get; private set; } public static string ConfigPath { get; private set; } public static string BepInExConfigPath { get; private set; } public static string CachePath { get; private set; } public static string PatcherPluginPath { get; private set; } public static string PluginPath { get; private set; } public static string ProcessName { get; private set; } public static void SetDotNetGamePath(string entrypointAssemblyPath, string bepinRootPath = null) { ExecutablePath = entrypointAssemblyPath; ProcessName = Path.GetFileNameWithoutExtension(entrypointAssemblyPath); GameRootPath = Path.GetDirectoryName(entrypointAssemblyPath); ManagedPath = GameRootPath; BepInExRootPath = bepinRootPath ?? Path.Combine(GameRootPath, "BepInEx"); ConfigPath = Path.Combine(BepInExRootPath, "config"); BepInExConfigPath = Path.Combine(ConfigPath, "BepInEx.cfg"); PluginPath = Path.Combine(BepInExRootPath, "plugins"); PatcherPluginPath = Path.Combine(BepInExRootPath, "patchers"); BepInExAssemblyDirectory = Path.Combine(BepInExRootPath, "core"); BepInExAssemblyPath = Path.Combine(BepInExAssemblyDirectory, Assembly.GetExecutingAssembly().GetName().Name + ".dll"); CachePath = Path.Combine(BepInExRootPath, "cache"); } internal static void SetPluginPath(string pluginPath) { PluginPath = Utility.CombinePaths(BepInExRootPath, pluginPath); } } public static class Utility { private const string TRUSTED_PLATFORM_ASSEMBLIES = "TRUSTED_PLATFORM_ASSEMBLIES"; private static bool? sreEnabled; public static bool CLRSupportsDynamicAssemblies => CheckSRE(); public static Encoding UTF8NoBom { get; } = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); private static bool CheckSRE() { try { if (sreEnabled.HasValue) { return sreEnabled.Value; } new CustomAttributeBuilder(null, new object[0]); } catch (PlatformNotSupportedException) { sreEnabled = false; return sreEnabled.Value; } catch (ArgumentNullException) { } sreEnabled = true; return sreEnabled.Value; } public static bool TryDo(Action action, out Exception exception) { exception = null; try { action(); return true; } catch (Exception ex) { exception = ex; return false; } } public static string CombinePaths(params string[] parts) { return parts.Aggregate(Path.Combine); } public static string ParentDirectory(string path, int levels = 1) { for (int i = 0; i < levels; i++) { path = Path.GetDirectoryName(path); } return path; } public static bool SafeParseBool(string input, bool defaultValue = false) { if (!bool.TryParse(input, out var result)) { return defaultValue; } return result; } public static bool IsNullOrWhiteSpace(this string self) { return self?.All(char.IsWhiteSpace) ?? true; } public static IEnumerable<TNode> TopologicalSort<TNode>(IEnumerable<TNode> nodes, Func<TNode, IEnumerable<TNode>> dependencySelector) { List<TNode> sorted_list = new List<TNode>(); HashSet<TNode> visited = new HashSet<TNode>(); HashSet<TNode> sorted = new HashSet<TNode>(); foreach (TNode node in nodes) { Stack<TNode> stack = new Stack<TNode>(); if (!Visit(node, stack)) { throw new Exception("Cyclic Dependency:\r\n" + stack.Select((TNode x) => $" - {x}").Aggregate((string a, string b) => a + "\r\n" + b)); } } return sorted_list; bool Visit(TNode node, Stack<TNode> stack2) { if (visited.Contains(node)) { if (!sorted.Contains(node)) { return false; } } else { visited.Add(node); stack2.Push(node); if (dependencySelector(node).Any((TNode dep) => !Visit(dep, stack2))) { return false; } sorted.Add(node); sorted_list.Add(node); stack2.Pop(); } return true; } } public static bool TryResolveDllAssembly<T>(AssemblyName assemblyName, string directory, Func<string, T> loader, out T assembly) where T : class { assembly = null; List<string> list = new List<string> { directory }; if (!Directory.Exists(directory)) { return false; } list.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories)); foreach (string item in list) { string[] array = new string[2] { assemblyName.Name + ".dll", assemblyName.Name + ".exe" }; foreach (string path in array) { string text = Path.Combine(item, path); if (File.Exists(text)) { try { assembly = loader(text); } catch (Exception) { continue; } return true; } } } return false; } public static bool IsSubtypeOf(this TypeDefinition self, Type td) { if (((MemberReference)self).FullName == td.FullName) { return true; } if (((MemberReference)self).FullName != "System.Object") { TypeReference baseType = self.BaseType; return ((baseType == null) ? ((bool?)null) : baseType.Resolve()?.IsSubtypeOf(td)) == true; } return false; } public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly) { return TryResolveDllAssembly(assemblyName, directory, (Func<string, Assembly>)Assembly.LoadFrom, out assembly); } public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, ReaderParameters readerParameters, out AssemblyDefinition assembly) { return TryResolveDllAssembly(assemblyName, directory, (Func<string, AssemblyDefinition>)((string s) => AssemblyDefinition.ReadAssembly(s, readerParameters)), out assembly); } public static bool TryOpenFileStream(string path, FileMode mode, out FileStream fileStream, FileAccess access = FileAccess.ReadWrite, FileShare share = FileShare.Read) { try { fileStream = new FileStream(path, mode, access, share); return true; } catch (IOException) { fileStream = null; return false; } } public static IEnumerable<MethodDefinition> EnumerateAllMethods(this TypeDefinition type) { TypeDefinition currentType = type; while (currentType != null) { Enumerator<MethodDefinition> enumerator = currentType.Methods.GetEnumerator(); try { while (enumerator.MoveNext()) { yield return enumerator.Current; } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } TypeReference baseType = currentType.BaseType; currentType = ((baseType != null) ? baseType.Resolve() : null); } } public static string HashStream(Stream stream) { using MD5 mD = MD5.Create(); byte[] array = new byte[4096]; int inputCount; while ((inputCount = stream.Read(array, 0, array.Length)) > 0) { mD.TransformBlock(array, 0, inputCount, array, 0); } mD.TransformFinalBlock(new byte[0], 0, 0); return ByteArrayToString(mD.Hash); } public static string HashStrings(params string[] strings) { using MD5 mD = MD5.Create(); foreach (string s in strings) { byte[] bytes = Encoding.UTF8.GetBytes(s); mD.TransformBlock(bytes, 0, bytes.Length, null, 0); } mD.TransformFinalBlock(new byte[0], 0, 0); return ByteArrayToString(mD.Hash); } public static string ByteArrayToString(byte[] data) { StringBuilder stringBuilder = new StringBuilder(data.Length * 2); foreach (byte b in data) { stringBuilder.AppendFormat("{0:x2}", b); } return stringBuilder.ToString(); } public static string GetCommandLineArgValue(string arg) { string[] commandLineArgs = Environment.GetCommandLineArgs(); for (int i = 1; i < commandLineArgs.Length; i++) { if (commandLineArgs[i] == arg && i + 1 < commandLineArgs.Length) { return commandLineArgs[i + 1]; } } return null; } public static bool TryParseAssemblyName(string fullName, out AssemblyName assemblyName) { try { assemblyName = new AssemblyName(fullName); return true; } catch (Exception) { assemblyName = null; return false; } } internal static void AddCecilPlatformAssemblies(this AppDomain appDomain, string assemblyDir) { if (Directory.Exists(assemblyDir)) { string text = appDomain.GetData("TRUSTED_PLATFORM_ASSEMBLIES") as string; char pathSeparator = Path.PathSeparator; string text2 = string.Join(pathSeparator.ToString(), Directory.GetFiles(assemblyDir, "*.dll", SearchOption.TopDirectoryOnly)); string data = ((text == null) ? text2 : $"{text}{Path.PathSeparator}{text2}"); appDomain.SetData("TRUSTED_PLATFORM_ASSEMBLIES", data); } } public static IEnumerable<string> GetUniqueFilesInDirectories(IEnumerable<string> directories, string pattern = "*") { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); foreach (string directory in directories) { if (!Directory.Exists(directory)) { LogLevel logLevel = LogLevel.Warning; bool isEnabled; BepInExLogInterpolatedStringHandler bepInExLogInterpolatedStringHandler = new BepInExLogInterpolatedStringHandler(47, 1, logLevel, out isEnabled); if (isEnabled) { bepInExLogInterpolatedStringHandler.AppendLiteral("Skipping search directory that does not exist: "); bepInExLogInterpolatedStringHandler.AppendFormatted(directory); } Logger.Log(logLevel, bepInExLogInterpolatedStringHandler); continue; } string[] files = Directory.GetFiles(directory, pattern); foreach (string text in files) { string fileName = Path.GetFileName(text); if (!dictionary.ContainsKey(fileName)) { dictionary[fileName] = text; } } } return dictionary.Values; } } } namespace BepInEx.Logging { public class ConsoleLogListener : ILogListener, IDisposable { protected static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind("Logging.Console", "LogLevels", LogLevel.Fatal | LogLevel.Error | LogLevel.Warning | LogLevel.Message | LogLevel.Info, "Only displays the specified log levels in the console output."); public LogLevel LogLevelFilter => ConfigConsoleDisplayedLevel.Value; public void LogEvent(object sender, LogEventArgs eventArgs) { ConsoleManager.SetConsoleColor(eventArgs.Level.GetConsoleColor()); ConsoleManager.ConsoleStream?.Write(eventArgs.ToStringLine()); ConsoleManager.SetConsoleColor(ConsoleColor.Gray); } public void Dispose() { } } public class DiskLogListener : ILogListener, IDisposable { public static HashSet<string> BlacklistedSources = new HashSet<string>(); public LogLevel DisplayedLogLevel { get; } public TextWriter LogWriter { get; protected set; } private Timer FlushTimer { get; } private bool InstantFlushing { get; } public LogLevel LogLevelFilter => DisplayedLogLevel; public DiskLogListener(string localPath, LogLevel displayedLogLevel = LogLevel.Info, bool appendLog = false, bool delayedFlushing = true, int fileLimit = 5) { DisplayedLogLevel = displayedLogLevel; int num = 1; FileStream fileStream; while (!Utility.TryOpenFileStream(Path.Combine(Paths.BepInExRootPath, localPath), appendLog ? FileMode.Append : FileMode.Create, out fileStream, FileAccess.Write)) { if (num == fileLimit) { Logger.Log(LogLevel.Error, "Couldn't open a log file for writing. Skipping log file creation"); return; } LogLevel logLevel = LogLevel.Warning; bool isEnabled; BepInExLogInterpolatedStringHandler bepInExLogInterpolatedStringHandler = new BepInExLogInterpolatedStringHandler(56, 1, logLevel, out isEnabled); if (isEnabled) { bepInExLogInterpolatedStringHandler.AppendLiteral("Couldn't open log file '"); bepInExLogInterpolatedStringHandler.AppendFormatted(localPath); bepInExLogInterpolatedStringHandler.AppendLiteral("' for writing, trying another..."); } Logger.Log(logLevel, bepInExLogInterpolatedStringHandler); localPath = $"LogOutput.{num++}.log"; } LogWriter = TextWriter.Synchronized(new StreamWriter(fileStream, Utility.UTF8NoBom)); if (delayedFlushing) { FlushTimer = new Timer(delegate { LogWriter?.Flush(); }, null, 2000, 2000); } InstantFlushing = !delayedFlushing; } public void LogEvent(object sender, LogEventArgs eventArgs) { if (LogWriter != null && !BlacklistedSources.Contains(eventArgs.Source.SourceName)) { LogWriter.WriteLine(eventArgs.ToString()); if (InstantFlushing) { LogWriter.Flush(); } } } public void Dispose() { FlushTimer?.Dispose(); try { LogWriter?.Flush(); LogWriter?.Dispose(); } catch (ObjectDisposedException) { } } ~DiskLogListener() { Dispose(); } } public class HarmonyLogSource : ILogSource, IDisposable { private static readonly ConfigEntry<LogChannel> LogChannels = ConfigFile.CoreConfig.Bind<LogChannel>("Harmony.Logger", "LogChannels", (LogChannel)24, "Specifies which Harmony log channels to listen to.\nNOTE: IL channel dumps the whole patch methods, use only when needed!"); private static readonly Dictionary<LogChannel, LogLevel> LevelMap = new Dictionary<LogChannel, LogLevel> { [(LogChannel)2] = LogLevel.Info, [(LogChannel)8] = LogLevel.Warning, [(LogChannel)16] = LogLevel.Error, [(LogChannel)4] = LogLevel.Debug }; public string SourceName { get; } = "HarmonyX"; public event EventHandler<LogEventArgs> LogEvent; public HarmonyLogSource() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Logger.ChannelFilter = LogChannels.Value; Logger.MessageReceived += HandleHarmonyMessage; } public void Dispose() { Logger.MessageReceived -= HandleHarmonyMessage; } private void HandleHarmonyMessage(object sender, LogEventArgs e) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (LevelMap.TryGetValue(e.LogChannel, out var value)) { this.LogEvent?.Invoke(this, new LogEventArgs(e.Message, value, this)); } } } public interface ILogListener : IDisposable { LogLevel LogLevelFilter { get; } void LogEvent(object sender, LogEventArgs eventArgs); } public interface ILogSource : IDisposable { string SourceName { get; } event EventHandler<LogEventArgs> LogEvent; } public class LogEventArgs : EventArgs { public object Data { get; } public LogLevel Level { get; } public ILogSource Source { get; } public LogEventArgs(object data, LogLevel level, ILogSource source) { Data = data; Level = level; Source = source; } public override string ToString() { return $"[{Level,-7}:{Source.SourceName,10}] {Data}"; } public string ToStringLine() { return $"[{Level,-7}:{Source.SourceName,10}] {Data}{Environment.NewLine}"; } } public static class Logger { private class LogListenerCollection : ThreadSafeCollection<ILogListener> { internal LogLevel ActiveLogLevels; internal void SendLogEvent(object sender, LogEventArgs eventArgs) { List<ILogListener> baseList = BaseList; for (int i = 0; i < baseList.Count; i++) { if ((eventArgs.Level & baseList[i].LogLevelFilter) != LogLevel.None) { baseList[i].LogEvent(sender, eventArgs); } } } public override void Add(ILogListener item) { if (item == null) { throw new ArgumentNullException("item"); } lock (SpinLock) { ActiveLogLevels |= item.LogLevelFilter; base.Add(item); } } public override void Clear() { lock (SpinLock) { ActiveLogLevels = LogLevel.None; base.Clear(); } } public override bool Remove(ILogListener item) { if (item == null || !base.Remove(item)) { return false; } lock (SpinLock) { ActiveLogLevels = LogLevel.None; using (IEnumerator<ILogListener> enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { ILogListener current = enumerator.Current; ActiveLogLevels |= current.LogLevelFilter; } } return true; } } } private class LogSourceCollection : ThreadSafeCollection<ILogSource> { public override void Add(ILogSource item) { if (item == null) { throw new ArgumentNullException("item", "Log sources cannot be null when added to the source list."); } lock (SpinLock) { item.LogEvent += InternalLogEvent; base.Add(item); List<ILogSource> list = new List<ILogSource>(BaseList.Count + 1); list.AddRange(BaseList); list.Add(item); BaseList = list; } } public override void Clear() { if (base.Count == 0) { return; } lock (SpinLock) { for (int i = 0; i < BaseList.Count; i++) { BaseList[i].LogEvent -= InternalLogEvent; } BaseList = new List<ILogSource>(); } } public override bool Remove(ILogSource item) { if (item == null) { return false; } lock (SpinLock) { bool num = base.Remove(item); if (num) { item.LogEvent -= InternalLogEvent; } return num; } } } private class ThreadSafeCollection<T> : ICollection<T>, IEnumerable<T>, IEnumerable where T : class { protected readonly object SpinLock = new object(); protected List<T> BaseList = new List<T>(); public int Count => BaseList.Count; public bool IsReadOnly => false; public IEnumerator<T> GetEnumerator() { return BaseList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return BaseList.GetEnumerator(); } public virtual void Add(T item) { if (item == null) { throw new ArgumentNullException("item", "item can't be null"); } lock (SpinLock) { List<T> list = new List<T>(BaseList.Count + 1); list.AddRange(BaseList); list.Add(item); BaseList = list; } } public virtual void Clear() { if (Count == 0) { return; } lock (SpinLock) { BaseList = new List<T>(); } } public bool Contains(T item) { return BaseList.Contains(item); } public void CopyTo(T[] array, int arrayIndex) { BaseList.CopyTo(array, arrayIndex); } public virtual bool Remove(T item) { if (item == null) { return false; } lock (SpinLock) { List<T> list = new List<T>(BaseList.Count); bool result = false; for (int i = 0; i < BaseList.Count; i++) { T val = BaseList[i]; if (val.Equals(item)) { result = true; } else { list.Add(val); } } BaseList = list; return result; } } } private static readonly ManualLogSource InternalLogSource; private static readonly LogListenerCollection listeners; public static LogLevel ListenedLogLevels => listeners.ActiveLogLevels; public static ICollection<ILogListener> Listeners => listeners; public static ICollection<ILogSource> Sources { get; } static Logger() { Sources = new LogSourceCollection(); listeners = new LogListenerCollection(); InternalLogSource = CreateLogSource("BepInEx"); } internal static void InternalLogEvent(object sender, LogEventArgs eventArgs) { listeners.SendLogEvent(sender, eventArgs); } internal static void Log(LogLevel level, object data) { InternalLogSource.Log(level, data); } internal static void Log(LogLevel level, [InterpolatedStringHandlerArgument("level")] BepInExLogInterpolatedStringHandler logHandler) { InternalLogSource.Log(level, logHandler); } public static ManualLogSource CreateLogSource(string sourceName) { ManualLogSource manualLogSource = new ManualLogSource(sourceName); Sources.Add(manualLogSource); return manualLogSource; } } [Flags] public enum LogLevel { None = 0, Fatal = 1, Error = 2, Warning = 4, Message = 8, Info = 0x10, Debug = 0x20, All = 0x3F } public static class LogLevelExtensions { public static LogLevel GetHighestLevel(this LogLevel levels) { Array values = Enum.GetValues(typeof(LogLevel)); Array.Sort(values); foreach (LogLevel item in values) { if ((levels & item) != LogLevel.None) { return item; } } return LogLevel.None; } public static ConsoleColor GetConsoleColor(this LogLevel level) { level = level.GetHighestLevel(); return level switch { LogLevel.Fatal => ConsoleColor.Red, LogLevel.Error => ConsoleColor.DarkRed, LogLevel.Warning => ConsoleColor.Yellow, LogLevel.Message => ConsoleColor.White, LogLevel.Info => ConsoleColor.DarkGray, LogLevel.Debug => ConsoleColor.DarkGray, _ => ConsoleColor.Gray, }; } } public class ManualLogSource : ILogSource, IDisposable { public string SourceName { get; } public event EventHandler<LogEventArgs> LogEvent; public ManualLogSource(string sourceName) { SourceName = sourceName; } public void Dispose() { } public void Log(LogLevel level, object data) { this.LogEvent?.Invoke(this, new LogEventArgs(data, level, this)); } public void Log(LogLevel level, [InterpolatedStringHandlerArgument("level")] BepInExLogInterpolatedStringHandler logHandler) { if (logHandler.Enabled) { this.LogEvent?.Invoke(this, new LogEventArgs(logHandler.ToString(), level, this)); } } public void LogFatal(object data) { Log(LogLevel.Fatal, data); } public void LogFatal(BepInExFatalLogInterpolatedStringHandler logHandler) { Log(LogLevel.Fatal, logHandler); } public void LogError(object data) { Log(LogLevel.Error, data); } public void LogError(BepInExErrorLogInterpolatedStringHandler logHandler) { Log(LogLevel.Error, logHandler); } public void LogWarning(object data) { Log(LogLevel.Warning, data); } public void LogWarning(BepInExWarningLogInterpolatedStringHandler logHandler) { Log(LogLevel.Warning, logHandler); } public void LogMessage(object data) { Log(LogLevel.Message, data); } public void LogMessage(BepInExMessageLogInterpolatedStringHandler logHandler) { Log(LogLevel.Message, logHandler); } public void LogInfo(object data) { Log(LogLevel.Info, data); } public void LogInfo(BepInExInfoLogInterpolatedStringHandler logHandler) { Log(LogLevel.Info, logHandler); } public void LogDebug(object data) { Log(LogLevel.Debug, data); } public void LogDebug(BepInExDebugLogInterpolatedStringHandler logHandler) { Log(LogLevel.Debug, logHandler); } } public class TraceLogSource : TraceListener { private static TraceLogSource traceListener; public static bool IsListening { get; private set; } protected ManualLogSource LogSource { get; } protected TraceLogSource() { LogSource = new ManualLogSource("Trace"); } public static ILogSource CreateSource() { if (traceListener == null) { traceListener = new TraceLogSource(); Trace.Listeners.Add(traceListener); IsListening = true; } return traceListener.LogSource; } public override void Write(string message) { LogSource.Log(LogLevel.Info, message); } public override void WriteLine(string message) { LogSource.Log(LogLevel.Info, message); } public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) { TraceEvent(eventCache, source, eventType, id, string.Format(format, args)); } public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) { LogSource.Log(eventType switch { TraceEventType.Critical => LogLevel.Fatal, TraceEventType.Error => LogLevel.Error, TraceEventType.Warning => LogLevel.Warning, TraceEventType.Information => LogLevel.Info, _ => LogLevel.Debug, }, (message ?? "").Trim()); } } } namespace BepInEx.Core.Logging.Interpolation { [InterpolatedStringHandler] public class BepInExLogInterpolatedStringHandler { private const int GUESSED_LENGTH_PER_HOLE = 11; private readonly StringBuilder sb; public bool Enabled { get; } public BepInExLogInterpolatedStringHandler(int literalLength, int formattedCount, LogLevel logLevel, out bool isEnabled) { Enabled = (logLevel & Logger.ListenedLogLevels) != 0; isEnabled = Enabled; sb = (Enabled ? new StringBuilder(literalLength + formattedCount * 11) : null); } public void AppendLiteral(string s) { if (Enabled) { sb.Append(s); } } public void AppendFormatted<T>(T t) { if (Enabled) { sb.Append(t); } } public void AppendFormatted<T>(T t, string format) where T : IFormattable { if (Enabled) { sb.Append(t?.ToString(format, null)); } } public void AppendFormatted(IntPtr t, string format) { if (Enabled) { sb.Append(t.ToString(format)); } } public override string ToString() { return sb?.ToString() ?? string.Empty; } } [InterpolatedStringHandler] public class BepInExFatalLogInterpolatedStringHandler : BepInExLogInterpolatedStringHandler { public BepInExFatalLogInterpolatedStringHandler(int literalLength, int formattedCount, out bool isEnabled) : base(literalLength, formattedCount, LogLevel.Fatal, out isEnabled) { } } [InterpolatedStringHandler] public class BepInExErrorLogInterpolatedStringHandler : BepInExLogInterpolatedStringHandler { public BepInExErrorLogInterpolatedStringHandler(int literalLength, int formattedCount, out bool isEnabled) : base(literalLength, formattedCount, LogLevel.Error, out isEnabled) { } } [InterpolatedStringHandler] public class BepInExWarningLogInterpolatedStringHandler : BepInExLogInterpolatedStringHandler { public BepInExWarningLogInterpolatedStringHandler(int literalLength, int formattedCount, out bool isEnabled) : base(literalLength, formattedCount, LogLevel.Warning, out isEnabled) { } } [InterpolatedStringHandler] public class BepInExMessageLogInterpolatedStringHandler : BepInExLogInterpolatedStringHandler { public BepInExMessageLogInterpolatedStringHandler(int literalLength, int formattedCount, out bool isEnabled) : base(literalLength, formattedCount, LogLevel.Message, out isEnabled) { } } [InterpolatedStringHandler] public class BepInExInfoLogInterpolatedStringHandler : BepInExLogInterpolatedStringHandler { public BepInExInfoLogInterpolatedStringHandler(int literalLength, int formattedCount, out bool isEnabled) : base(literalLength, formattedCount, LogLevel.Info, out isEnabled) { } } [InterpolatedStringHandler] public class BepInExDebugLogInterpolatedStringHandler : BepInExLogInterpolatedStringHandler { public BepInExDebugLogInterpolatedStringHandler(int literalLength, int formattedCount, out bool isEnabled) : base(literalLength, formattedCount, LogLevel.Debug, out isEnabled) { } } } namespace BepInEx.ConsoleUtil { internal static class SafeConsole { private delegate ConsoleColor GetColorDelegate(); private delegate void SetColorDelegate(ConsoleColor value); private delegate string GetStringDelegate(); private delegate void SetStringDelegate(string value); private static GetColorDelegate _getBackgroundColor; private static SetColorDelegate _setBackgroundColor; private static GetColorDelegate _getForegroundColor; private static SetColorDelegate _setForegroundColor; private static GetStringDelegate _getTitle; private static SetStringDelegate _setTitle; public static bool BackgroundColorExists { get; private set; } public static ConsoleColor BackgroundColor { get { return _getBackgroundColor(); } set { _setBackgroundColor(value); } } public static bool ForegroundColorExists { get; private set; } public static ConsoleColor ForegroundColor { get { return _getForegroundColor(); } set { _setForegroundColor(value); } } public static bool TitleExists { get; private set; } public static string Title { get { return _getTitle(); } set { _setTitle(value); } } static SafeConsole() { InitColors(typeof(Console)); } private static void InitColors(Type tConsole) { MethodInfo method = tConsole.GetMethod("get_ForegroundColor", BindingFlags.Static | BindingFlags.Public); MethodInfo method2 = tConsole.GetMethod("set_ForegroundColor", BindingFlags.Static | BindingFlags.Public); MethodInfo method3 = tConsole.GetMethod("get_BackgroundColor", BindingFlags.Static | BindingFlags.Public); MethodInfo method4 = tConsole.GetMethod("set_BackgroundColor", BindingFlags.Static | BindingFlags.Public); MethodInfo method5 = tConsole.GetMethod("get_Title", BindingFlags.Static | BindingFlags.Public); MethodInfo method6 = tConsole.GetMethod("set_Title", BindingFlags.Static | BindingFlags.Public); _setForegroundColor = ((method2 != null) ? ((SetColorDelegate)Delegate.CreateDelegate(typeof(SetColorDelegate), method2)) : ((SetColorDelegate)delegate { })); _setBackgroundColor = ((method4 != null) ? ((SetColorDelegate)Delegate.CreateDelegate(typeof(SetColorDelegate), method4)) : ((SetColorDelegate)delegate { })); _getForegroundColor = ((method != null) ? ((GetColorDelegate)Delegate.CreateDelegate(typeof(GetColorDelegate), method)) : ((GetColorDelegate)(() => ConsoleColor.Gray))); _getBackgroundColor = ((method3 != null) ? ((GetColorDelegate)Delegate.CreateDelegate(typeof(GetColorDelegate), method3)) : ((GetColorDelegate)(() => ConsoleColor.Black))); _getTitle = ((method5 != null) ? ((GetStringDelegate)Delegate.CreateDelegate(typeof(GetStringDelegate), method5)) : ((GetStringDelegate)(() => string.Empty))); _setTitle = ((method6 != null) ? ((SetStringDelegate)Delegate.CreateDelegate(typeof(SetStringDelegate), method6)) : ((SetStringDelegate)delegate { })); BackgroundColorExists = _setBackgroundColor != null && _getBackgroundColor != null; ForegroundColorExists = _setForegroundColor != null && _getForegroundColor != null; TitleExists = _setTitle != null && _getTitle != null; } } internal class ConsoleEncoding : Encoding { private readonly byte[] _zeroByte = new byte[0]; private readonly char[] _zeroChar = new char[0]; private byte[] _byteBuffer = new byte[256]; private char[] _charBuffer = new char[256]; private readonly uint _codePage; public override int CodePage => (int)_codePage; public static Encoding OutputEncoding => new ConsoleEncoding(ConsoleCodePage); public static uint ConsoleCodePage { get { return GetConsoleOutputCP(); } set { SetConsoleOutputCP(value); } } private void ExpandByteBuffer(int count) { if (_byteBuffer.Length < count) { _byteBuffer = new byte[count]; } } private void ExpandCharBuffer(int count) { if (_charBuffer.Length < count) { _charBuffer = new char[count]; } } private void ReadByteBuffer(byte[] bytes, int index, int count) { for (int i = 0; i < count; i++) { bytes[index + i] = _byteBuffer[i]; } } private void ReadCharBuffer(char[] chars, int index, int count) { for (int i = 0; i < count; i++) { chars[index + i] = _charBuffer[i]; } } private void WriteByteBuffer(byte[] bytes, int index, int count) { ExpandByteBuffer(count); for (int i = 0; i < count; i++) { _byteBuffer[i] = bytes[index + i]; } } private void WriteCharBuffer(char[] chars, int index, int count) { ExpandCharBuffer(count); for (int i = 0; i < count; i++) { _charBuffer[i] = chars[index + i]; } } private ConsoleEncoding(uint codePage) { _codePage = codePage; } public static uint GetActiveCodePage() { return GetACP(); } public static ConsoleEncoding GetEncoding(uint codePage) { return new ConsoleEncoding(codePage); } public override int GetByteCount(char[] chars, int index, int count) { WriteCharBuffer(chars, index, count); return WideCharToMultiByte(_codePage, 0u, _charBuffer, count, _zeroByte, 0, IntPtr.Zero, IntPtr.Zero); } public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { int byteCount = GetByteCount(chars, charIndex, charCount); WriteCharBuffer(chars, charIndex, charCount); ExpandByteBuffer(byteCount); WideCharToMultiByte(_codePage, 0u, _charBuffer, charCount, _byteBuffer, byteCount, IntPtr.Zero, IntPtr.Zero); int num = Math.Min(bytes.Length, byteCount); ReadByteBuffer(bytes, byteIndex, num); return num; } public override int GetCharCount(byte[] bytes, int index, int count) { WriteByteBuffer(bytes, index, count); return MultiByteToWideChar(_codePage, 0u, _byteBuffer, count, _zeroChar, 0); } public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { int charCount = GetCharCount(bytes, byteIndex, byteCount); WriteByteBuffer(bytes, byteIndex, byteCount); ExpandCharBuffer(charCount); MultiByteToWideChar(_codePage, 0u, _byteBuffer, byteCount, _charBuffer, charCount); int num = Math.Min(chars.Length, charCount); ReadCharBuffer(chars, charIndex, num); return num; } public override int GetMaxByteCount(int charCount) { return charCount * 4; } public override int GetMaxCharCount(int byteCount) { return byteCount; } [DllImport("kernel32.dll")] private static extern uint GetConsoleOutputCP(); [DllImport("kernel32.dll")] private static extern uint GetACP(); [DllImport("kernel32.dll", SetLastError = true)] private static extern int MultiByteToWideChar(uint codePage, uint dwFlags, [In][MarshalAs(UnmanagedType.LPArray)] byte[] lpMultiByteStr, int cbMultiByte, [Out][MarshalAs(UnmanagedType.LPWStr)] char[] lpWideCharStr, int cchWideChar); [DllImport("kernel32.dll")] private static extern IntPtr SetConsoleOutputCP(uint codepage); [DllImport("kernel32.dll", SetLastError = true)] private static extern int WideCharToMultiByte(uint codePage, uint dwFlags, [In][MarshalAs(UnmanagedType.LPWStr)] char[] lpWideCharStr, int cchWideChar, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] lpMultiByteStr, int cbMultiByte, IntPtr lpDefaultChar, IntPtr lpUsedDefaultChar); } internal class ConsoleWindow { [UnmanagedFunctionPointer(CallingConvention.Winapi)] [return: MarshalAs(UnmanagedType.Bool)] private delegate bool SetForegroundWindowDelegate(IntPtr hWnd); [UnmanagedFunctionPointer(CallingConvention.Winapi)] private delegate IntPtr GetForegroundWindowDelegate(); [UnmanagedFunctionPointer(CallingConvention.Winapi)] private delegate IntPtr GetSystemMenuDelegate(IntPtr hwnd, bool bRevert); [UnmanagedFunctionPointer(CallingConvention.Winapi)] private delegate bool DeleteMenuDelegate(IntPtr hMenu, uint uPosition, uint uFlags); private const int STD_OUTPUT_HANDLE = -11; private const uint SC_CLOSE = 61536u; private const uint MF_BYCOMMAND = 0u; private const uint LOAD_LIBRARY_SEARCH_SYSTEM32 = 2048u; public static IntPtr ConsoleOutHandle; public static IntPtr OriginalStdoutHandle; private static bool methodsInited; private static SetForegroundWindowDelegate setForeground; private static GetForegroundWindowDelegate getForeground; private static GetSystemMenuDelegate getSystemMenu; private static DeleteMenuDelegate deleteMenu; public static bool IsAttached { get; private set; } public static string Title { set { if (IsAttached) { if (value == null) { throw new ArgumentNullException("value"); } if (value.Length > 24500) { throw new InvalidOperationException("Console title too long"); } if (!SetConsoleTitle(value)) { throw new InvalidOperationException("Console title invalid"); } } } } public static void Attach() { if (IsAttached) { return; } Initialize(); if (OriginalStdoutHandle == IntPtr.Zero) { OriginalStdoutHandle = GetStdHandle(-11); } if (GetConsoleWindow() == IntPtr.Zero) { IntPtr hWnd = getForeground(); if (!AllocConsole() && Marshal.GetLastWin32Error() != 5) { throw new Win32Exception("AllocConsole() failed"); } setForeground(hWnd); } ConsoleOutHandle = CreateFile("CONOUT$", 3221225472u, 2, IntPtr.Zero, 3, 0, IntPtr.Zero); Kon.conOut = ConsoleOutHandle; if (!SetStdHandle(-11, ConsoleOutHandle)) { throw new Win32Exception("SetStdHandle() failed"); } if (OriginalStdoutHandle != IntPtr.Zero && ConsoleManager.ConfigConsoleOutRedirectType.Value == ConsoleManager.ConsoleOutRedirectType.ConsoleOut) { CloseHandle(OriginalStdoutHandle); } IsAttached = true; } public static void PreventClose() { if (IsAttached) { Initialize(); IntPtr consoleWindow = GetConsoleWindow(); IntPtr intPtr = getSystemMenu(consoleWindow, bRevert: false); if (intPtr != IntPtr.Zero) { deleteMenu(intPtr, 61536u, 0u); } } } public static void Detach() { if (IsAttached) { if (!CloseHandle(ConsoleOutHandle)) { throw new Win32Exception("CloseHandle() failed"); } ConsoleOutHandle = IntPtr.Zero; if (!FreeConsole()) { throw new Win32Exception("FreeConsole() failed"); } if (!SetStdHandle(-11, OriginalStdoutHandle)) { throw new Win32Exception("SetStdHandle() failed"); } IsAttached = false; } } private static void Initialize() { if (!methodsInited) { methodsInited = true; IntPtr hModule = LoadLibraryEx("user32.dll", IntPtr.Zero, 2048u); setForeground = Marshal.GetDelegateForFunctionPointer<SetForegroundWindowDelegate>(GetProcAddress(hModule, "SetForegroundWindow")); getForeground = Marshal.GetDelegateForFunctionPointer<GetForegroundWindowDelegate>(GetProcAddress(hModule, "GetForegroundWindow")); getSystemMenu = Marshal.GetDelegateForFunctionPointer<GetSystemMenuDelegate>(GetProcAddress(hModule, "GetSystemMenu")); deleteMenu = Marshal.GetDelegateForFunctionPointer<DeleteMenuDelegate>(GetProcAddress(hModule, "DeleteMenu")); } } [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool AllocConsole(); [DllImport("kernel32.dll")] private static extern IntPtr GetConsoleWindow(); [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)] private static extern bool CloseHandle(IntPtr handle); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CreateFile(string fileName, uint desiredAccess, int shareMode, IntPtr securityAttributes, int creationDisposition, int flagsAndAttributes, IntPtr templateFile); [DllImport("kernel32.dll")] private static extern bool FreeConsole(); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput); [DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Auto, SetLastError = true)] private static extern bool SetConsoleTitle(string title); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr LoadLibraryEx(string lpLibFileName, IntPtr hFile, uint dwFlags); } internal class Kon { private struct CONSOLE_SCREEN_BUFFER_INFO { internal COORD dwSize; internal COORD dwCursorPosition; internal short wAttributes; internal SMALL_RECT srWindow; internal COORD dwMaximumWindowSize; } private struct COORD { internal short X; internal short Y; } private struct SMALL_RECT { internal short Left; internal short Top; internal short Right; internal short Bottom; } private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); internal static IntPtr conOut = IntPtr.Zero; public static ConsoleColor ForegroundColor { get { return GetConsoleColor(isBackground: false); } set { SetConsoleColor(isBackground: false, value); } } public static ConsoleColor BackgroundColor { get { return GetConsoleColor(isBackground: true); } set { SetConsoleColor(isBackground: true, value); } } [DllImport("kernel32.dll", SetLastError = true)] private static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetConsoleTextAttribute(IntPtr hConsoleOutput, short attributes); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetStdHandle(int nStdHandle); private static short ConsoleColorToColorAttribute(short color, bool isBackground) { if ((color & -16) != 0) { throw new ArgumentException("Arg_InvalidConsoleColor"); } if (isBackground) { color <<= 4; } return color; } private static CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo(bool throwOnNoConsole, out bool succeeded) { succeeded = false; if (!(conOut == INVALID_HANDLE_VALUE)) { if (!GetConsoleScreenBufferInfo(conOut, out var lpConsoleScreenBufferInfo)) { bool consoleScreenBufferInfo = GetConsoleScreenBufferInfo(GetStdHandle(-12), out lpConsoleScreenBufferInfo); if (!consoleScreenBufferInfo) { consoleScreenBufferInfo = GetConsoleScreenBufferInfo(GetStdHandle(-10), out lpConsoleScreenBufferInfo); } if (!consoleScreenBufferInfo && Marshal.GetLastWin32Error() == 6 && !throwOnNoConsole) { return default(CONSOLE_SCREEN_BUFFER_INFO); } } succeeded = true; return lpConsoleScreenBufferInfo; } if (!throwOnNoConsole) { return default(CONSOLE_SCREEN_BUFFER_INFO); } throw new Exception("IO.IO_NoConsole"); } private static void SetConsoleColor(bool isBackground, ConsoleColor c) { short num = ConsoleColorToColorAttribute((short)c, isBackground); bool succeeded; CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo(throwOnNoConsole: false, out succeeded); if (succeeded) { short wAttributes = bufferInfo.wAttributes; wAttributes &= (short)(isBackground ? (-241) : (-16)); wAttributes = (short)((ushort)wAttributes | (ushort)num); SetConsoleTextAttribute(conOut, wAttributes); } } private static ConsoleColor GetConsoleColor(bool isBackground) { bool succeeded; CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo(throwOnNoConsole: false, out succeeded); if (!succeeded) { if (!isBackground) { return ConsoleColor.Gray; } return ConsoleColor.Black; } return ColorAttributeToConsoleColor((short)(bufferInfo.wAttributes & 0xF0)); } private static ConsoleColor ColorAttributeToConsoleColor(short c) { if ((short)(c & 0xFF) != 0) { c >>= 4; } return (ConsoleColor)c; } public static void ResetConsoleColor() { SetConsoleColor(isBackground: true, ConsoleColor.Black); SetConsoleColor(isBackground: false, ConsoleColor.Gray); } } } namespace BepInEx.Configuration { public abstract class AcceptableValueBase { public Type ValueType { get; } protected AcceptableValueBase(Type valueType) { ValueType = valueType; } public abstract object Clamp(object value); public abstract bool IsValid(object value); public abstract string ToDescriptionString(); } public class AcceptableValueList<T> : AcceptableValueBase where T : IEquatable<T> { public virtual T[] AcceptableValues { get; } public AcceptableValueList(params T[] acceptableValues) : base(typeof(T)) { if (acceptableValues == null) { throw new ArgumentNullException("acceptableValues"); } if (acceptableValues.Length == 0) { throw new ArgumentException("At least one acceptable value is needed", "acceptableValues"); } AcceptableValues = acceptableValues; } public override object Clamp(object value) { if (IsValid(value)) { return value; } return AcceptableValues[0]; } public override bool IsValid(object value) { if (value is T) { T v = (T)value; return AcceptableValues.Any((T x) => x.Equals(v)); } return false; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", AcceptableValues.Select((T x) => x.ToString()).ToArray()); } } public class AcceptableValueRange<T> : AcceptableValueBase where T : IComparable { public virtual T MinValue { get; } public virtual T MaxValue { get; } public AcceptableValueRange(T minValue, T maxValue) : base(typeof(T)) { if (maxValue == null) { throw new ArgumentNullException("maxValue"); } if (minValue == null) { throw new ArgumentNullException("minValue"); } if (minValue.CompareTo(maxValue) >= 0) { throw new ArgumentException("minValue has to be lower than maxValue"); } MinValue = minValue; MaxValue = maxValue; } public override object Clamp(object value) { if (MinValue.CompareTo(value) > 0) { return MinValue; } if (MaxValue.CompareTo(value) < 0) { return MaxValue; } return value; } public override bool IsValid(object value) { if (MinValue.CompareTo(value) <= 0) { return MaxValue.CompareTo(value) >= 0; } return false; } public override string ToDescriptionString() { return $"# Acceptable value range: From {MinValue} to {MaxValue}"; } } public class ConfigDefinition : IEquatable<ConfigDefinition> { private static readonly char[] _invalidConfigChars = new char[8] { '=', '\n', '\t', '\\', '"', '\'', '[', ']' }; public string Section { get; } public string Key { get; } public ConfigDefinition(string section, string key) { CheckInvalidConfigChars(section, "section"); CheckInvalidConfigChars(key, "key"); Key = key; Section = section; } [Obsolete("description argument is no longer used, put it in a ConfigDescription instead")] public ConfigDefinition(string section, string key, string description) { Key = key ?? ""; Section = section ?? ""; } public bool Equals(ConfigDefinition other) { if (other == null) { return false; } if (string.Equals(Key, other.Key)) { return string.Equals(Section, other.Section); } return false; } private static void CheckInvalidConfigChars(string val, string name) { if (val == null) { throw new ArgumentNullException(name); } if (val != val.Trim()) { throw new ArgumentException("Cannot use whitespace characters at start or end of section and key names", name); } if (val.Any((char c) => _invalidConfigChars.Contains(c))) { throw new ArgumentException("Cannot use any of the following characters in section and key names: = \\n \\t \\ \" ' [ ]", name); } } public override bool Equals(object obj) { if (obj == null) { return false; } if (this == obj) { return true; } return Equals(obj as ConfigDefinition); } public override int GetHashCode() { return (((Key != null) ? Key.GetHashCode() : 0) * 397) ^ ((Section != null) ? Section.GetHashCode() : 0); } public static bool operator ==(ConfigDefinition left, ConfigDefinition right) { return object.Equals(left, right); } public static bool operator !=(ConfigDefinition left, ConfigDefinition right) { return !object.Equals(left, right); } public override string ToString() { return Section + "." + Key; } } public class ConfigDescription { public string Description { get; } public AcceptableValueBase AcceptableValues { get; } public object[] Tags { get; } public static ConfigDescription Empty { get; } = new ConfigDescription("", null); public ConfigDescription(string description, AcceptableValueBase acceptableValues = null, params object[] tags) { AcceptableValues = acceptableValues; Tags = tags; Description = description ?? throw new ArgumentNullException("description"); } } public sealed class ConfigEntry<T> : ConfigEntryBase { private T _typedValue; public T Value { get { return _typedValue; } set { value = ClampValue(value); if (!object.Equals(_typedValue, value)) { _typedValue = value; OnSettingChanged(this); } } } public override object BoxedValue { get { return Value; } set { Value = (T)value; } } public event EventHandler SettingChanged; internal ConfigEntry(ConfigFile configFile, ConfigDefinition definition, T defaultValue, ConfigDescription configDescription) : base(configFile, definition, typeof(T), defaultValue, configDescription) { configFile.SettingChanged += delegate(object sender, SettingChangedEventArgs args) { if (args.ChangedSetting == this) { this.SettingChanged?.Invoke(sender, args); } }; } } public abstract class ConfigEntryBase { public ConfigFile ConfigFile { get; } public ConfigDefinition Definition { get; } public ConfigDescription Description { get; } public Type SettingType { get; } public object DefaultValue { get; } public abstract object BoxedValue { get; set; } protected internal ConfigEntryBase(ConfigFile configFile, ConfigDefinition definition, Type settingType, object defaultValue, ConfigDescription configDescription) { ConfigFile = configFile ?? throw new ArgumentNullException("configFile"); Definition = definition ?? throw new ArgumentNullException("definition"); SettingType = settingType ?? throw new ArgumentNullException("settingType"); Description = configDescription ?? ConfigDescription.Empty; if (Description.AcceptableValues != null && !SettingType.IsAssignableFrom(Description.AcceptableValues.ValueType)) { throw new ArgumentException("configDescription.AcceptableValues is for a different type than the type of this setting"); } DefaultValue = defaultValue; BoxedValue = defaultValue; } public string GetSerializedValue() { return TomlTypeConverter.ConvertToString(BoxedValue, SettingType); } public void SetSerializedValue(string value) { try { object boxedValue = TomlTypeConverter.ConvertToValue(value, SettingType); BoxedValue = boxedValue; } catch (Exception ex) { LogLevel logLevel = LogLevel.Warning; bool isEnabled; BepInExLogInterpolatedStringHandler bepInExLogInterpolatedStringHandler = new BepInExLogInterpolatedStringHandler(85, 3, logLevel, out isEnabled); if (isEnabled) { bepInExLogInterpolatedStringHandler.AppendLiteral("Config value of setting \""); bepInExLogInterpolatedStringHandler.AppendFormatted(Definition); bepInExLogInterpolatedStringHandler.AppendLiteral("\" could not be parsed and will be ignored. Reason: "); bepInExLogInterpolatedStringHandler.AppendFormatted(ex.Message); bepInExLogInterpolatedStringHandler.AppendLiteral("; Value: "); bepInExLogInterpolatedStringHandler.AppendFormatted(value); } Logger.Log(logLevel, bepInExLogInterpolatedStringHandler); } } protected T ClampValue<T>(T value) { if (Description.AcceptableValues != null) { return (T)Description.AcceptableValues.Clamp(value); } return value; } protected void OnSettingChanged(object sender) { ConfigFile.OnSettingChanged(sender, this); } public void WriteDescription(StreamWriter writer) { if (!string.IsNullOrEmpty(Description.Description)) { writer.WriteLine("## " + Description.Description.Replace("\n", "\n## ")); } writer.WriteLine("# Setting type: " + SettingType.Name); writer.WriteLine("# Default value: " + TomlTypeConverter.ConvertToString(DefaultValue, SettingType)); if (Description.AcceptableValues != null) { writer.WriteLine(Description.AcceptableValues.ToDescriptionString()); } else if (SettingType.IsEnum) { writer.WriteLine("# Acceptable values: " + string.Join(", ", Enum.GetNames(SettingType))); if (SettingType.GetCustomAttributes(typeof(FlagsAttribute), inherit: true).Any()) { writer.WriteLine("# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)"); } } } } public class ConfigFile : IDictionary<ConfigDefinition, ConfigEntryBase>, ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>, IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>, IEnumerable { private readonly BepInPlugin _ownerMetadata; private readonly object _ioLock = new object(); public static ConfigFile CoreConfig { get; } = new ConfigFile(Paths.BepInExConfigPath, saveOnInit: true); protected Dictionary<ConfigDefinition, ConfigEntryBase> Entries { get; } = new Dictionary<ConfigDefinition, ConfigEntryBase>(); private Dictionary<ConfigDefinition, string> OrphanedEntries { get; } = new Dictionary<ConfigDefinition, string>(); [Obsolete("Use Keys instead")] public ReadOnlyCollection<ConfigDefinition> ConfigDefinitions { get { lock (_ioLock) { return Entries.Keys.ToList().AsReadOnly(); } } } public string ConfigFilePath { get; } public bool SaveOnConfigSet { get; set; } = true; public ConfigEntryBase this[ConfigDefinition key] { get { lock (_ioLock) { return Entries[key]; } } } public ConfigEntryBase this[string section, string key] => this[new ConfigDefinition(section, key)]; public int Count { get { lock (_ioLock) { return Entries.Count; } } } public bool IsReadOnly => false; ConfigEntryBase IDictionary<ConfigDefinition, ConfigEntryBase>.this[ConfigDefinition key] { get { lock (_ioLock) { return Entries[key]; } } set { throw new InvalidOperationException("Directly setting a config entry is not supported"); } } public ICollection<ConfigDefinition> Keys { get { lock (_ioLock) { return Entries.Keys.ToArray(); } } } public ICollection<ConfigEntryBase> Values { get { lock (_ioLock) { return Entries.Values.ToArray(); } } } public bool GenerateSettingDescriptions { get; set; } = true; public event EventHandler ConfigReloaded; public event EventHandler<SettingChangedEventArgs> SettingChanged; public ConfigFile(string configPath, bool saveOnInit) : this(configPath, saveOnInit, null) { } public ConfigFile(string configPath, bool saveOnInit, BepInPlugin ownerMetadata) { _ownerMetadata = ownerMetadata; if (configPath == null) { throw new ArgumentNullException("configPath"); } configPath = Path.GetFullPath(configPath); ConfigFilePath = configPath; if (File.Exists(ConfigFilePath)) { Reload(); } else if (saveOnInit) { TrySave(); } } public IEnumerator<KeyValuePair<ConfigDefinition, ConfigEntryBase>> GetEnumerator() { lock (_ioLock) { return Entries.ToList().GetEnumerator(); } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } void ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>.Add(KeyValuePair<ConfigDefinition, ConfigEntryBase> item) { lock (_ioLock) { Entries.Add(item.Key, item.Value); } } public bool Contains(KeyValuePair<ConfigDefinition, ConfigEntryBase> item) { lock (_ioLock) { return ((ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)Entries).Contains(item); } } void ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>.CopyTo(KeyValuePair<ConfigDefinition, ConfigEntryBase>[] array, int arrayIndex) { lock (_ioLock) { ((ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)Entries).CopyTo(array, arrayIndex); } } bool ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>.Remove(KeyValuePair<ConfigDefinition, ConfigEntryBase> item) { lock (_ioLock) { return Entries.Remove(item.Key); } } public bool ContainsKey(ConfigDefinition key) { lock (_ioLock) { return Entries.ContainsKey(key); } } public void Add(ConfigDefinition key, ConfigEntryBase value) { throw new InvalidOperationException("Directly adding a config entry is not supported"); } public bool Remove(ConfigDefinition key) { lock (_ioLock) { return Entries.Remove(key); } } public void Clear() { lock (_ioLock) { Entries.Clear(); } } bool IDictionary<ConfigDefinition, ConfigEntryBase>.TryGetValue(ConfigDefinition key, out ConfigEntryBase value) { lock (_ioLock) { return Entries.TryGetValue(key, out value); } } [Obsolete("Use Values instead")] public ConfigEntryBase[] GetConfigEntries() { lock (_ioLock) { return Entries.Values.ToArray(); } } public void Reload() { lock (_ioLock) { OrphanedEntries.Clear(); string section = string.Empty; string[] array = File.ReadAllLines(ConfigFilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.StartsWith("#")) { continue; } if (text.StartsWith("[") && text.EndsWith("]")) { section = text.Substring(1, text.Length - 2); continue; } string[] array2 = text.Split(new char[1] { '=' }, 2); if (array2.Length == 2) { string key = array2[0].Trim(); string text2 = array2[1].Trim(); ConfigDefinition key2 = new ConfigDefinition(section, key); Entries.TryGetValue(key2, out var value); if (value != null) { value.SetSerializedValue(text2); } else { OrphanedEntries[key2] = text2; } } } } OnConfigReloaded(); } public void Save() { lock (_ioLock) { string directoryName = Path.GetDirectoryName(ConfigFilePath); if (directoryName != null) { Directory.CreateDirectory(directoryName); } using StreamWriter streamWriter = new StreamWriter(ConfigFilePath, append: false, Utility.UTF8NoBom); if (_ownerMetadata != null) { streamWriter.WriteLine($"## Settings file was created by plugin {_ownerMetadata.Name} v{_ownerMetadata.Version}"); streamWriter.WriteLine("## Plugin GUID: " + _ownerMetadata.GUID); streamWriter.WriteLine(); } foreach (var item in from x in Entries.Select((KeyValuePair<ConfigDefinition, ConfigEntryBase> x) => new { Key = x.Key, entry = x.Value, value = x.Value.GetSerializedValue() }).Concat(OrphanedEntries.Select((KeyValuePair<ConfigDefinition, string> x) => new { Key = x.Key, entry = (ConfigEntryBase)null, value = x.Value })) group x by x.Key.Section into x orderby x.Key select x) { streamWriter.WriteLine("[" + item.Key + "]"); foreach (var item2 in item) { if (GenerateSettingDescriptions) { streamWriter.WriteLine(); item2.entry?.WriteDescription(streamWriter); } streamWriter.WriteLine(item2.Key.Key + " = " + item2.value); } streamWriter.WriteLine(); } } } private void TrySave() { try { Save(); } catch (Exception ex) when (((ex is IOException || ex is UnauthorizedAccessException) ? 1 : 0) != 0) { LogLevel logLevel = LogLevel.Warning; bool isEnabled; BepInExLogInterpolatedStringHandler bepInExLogInterpolatedStringHandler = new BepInExLogInterpolatedStringHandler(76, 2, logLevel, out isEnabled); if (isEnabled) { bepInExLogInterpolatedStringHandler.AppendLiteral("Could not write config file "); bepInExLogInterpolatedStringHandler.AppendFormatted(ConfigFilePath); bepInExLogInterpolatedStringHandler.AppendLiteral(": "); bepInExLogInterpolatedStringHandler.AppendFormatted(ex.Message); bepInExLogInterpolatedStringHandler.AppendLiteral(". Continuing with the in-memory configuration."); } Logger.Log(logLevel, bepInExLogInterpolatedStringHandler); } } [Obsolete("Use ConfigFile[key] or TryGetEntry instead")] public ConfigEntry<T> GetSetting<T>(ConfigDefinition configDefinition) { if (!TryGetEntry(configDefinition, out ConfigEntry<T> entry)) { return null; } return entry; } [Obsolete("Use ConfigFile[key] or TryGetEntry instead")] public ConfigEntry<T> GetSetting<T>(string section, string key) { if (!TryGetEntry(section, key, out ConfigEntry<T> entry)) { return null; } return entry; } public bool TryGetEntry<T>(ConfigDefinition configDefinition, out ConfigEntry<T> entry) { lock (_ioLock) { if (Entries.TryGetValue(configDefinition, out var value)) { entry = (ConfigEntry<T>)value; return true; } entry = null; return false; } } public bool TryGetEntry<T>(string section, string key, out ConfigEntry<T> entry) { return TryGetEntry(new ConfigDefinition(section, key), out entry); } public ConfigEntry<T> Bind<T>(ConfigDefinition configDefinition, T defaultValue, ConfigDescription configDescription = null) { if (!TomlTypeConverter.CanConvert(typeof(T))) { throw new ArgumentException($"Type {typeof(T)} is not supported by the config system. Supported types: {string.Join(", ", (from x in TomlTypeConverter.GetSupportedTypes() select x.Name).ToArray())}"); } lock (_ioLock) { if (Entries.TryGetValue(configDefinition, out var value)) { return (ConfigEntry<T>)value; } ConfigEntry<T> configEntry = new ConfigEntry<T>(this, configDefinition, defaultValue, configDescription); Entries[configDefinition] = configEntry; if (OrphanedEntries.TryGetValue(configDefinition, out var value2)) { configEntry.SetSerializedValue(value2); OrphanedEntries.Remove(configDefinition); } if (SaveOnConfigSet) { TrySave(); } return configEntry; } } public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, ConfigDescription configDescription = null) { return Bind(new ConfigDefinition(section, key), defaultValue, configDescription); } public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description) { return Bind(new ConfigDefinition(section, key), defaultValue, new ConfigDescription(description, null)); } [Obsolete("Use Bind instead")] public ConfigEntry<T> AddSetting<T>(ConfigDefinition configDefinition, T defaultValue, ConfigDescription configDescription = null) { return Bind(configDefinition, defaultValue, configDescription); } [Obsolete("Use Bind instead")] public ConfigEntry<T> AddSetting<T>(string section, string key, T defaultValue, ConfigDescription configDescription = null) { return Bind(new ConfigDefinition(section, key), defaultValue, configDescription); } [Obsolete("Use Bind instead")] public ConfigEntry<T> AddSetting<T>(string section, string key, T defaultValue, string description) { return Bind(new ConfigDefinition(section, key), defaultValue, new ConfigDescription(description, null)); } [Obsolete("Use Bind instead")] public ConfigWrapper<T> Wrap<T>(string section, string key, string description = null, T defaultValue = default(T)) { lock (_ioLock) { ConfigDefinition configDefinition = new ConfigDefinition(section, key, description); return new ConfigWrapper<T>(Bind(configDefinition, defaultValue, string.IsNullOrEmpty(description) ? null : new ConfigDescription(description, null))); } } [Obsolete("Use Bind instead")] public ConfigWrapper<T> Wrap<T>(ConfigDefinition configDefinition, T defaultValue = default(T)) { return Wrap(configDefinition.Section, configDefinition.Key, null, defaultValue); } internal void OnSettingChanged(object sender, ConfigEntryBase changedEntryBase) { if (changedEntryBase == null) { throw new ArgumentNullException("changedEntryBase"); } if (SaveOnConfigSet) { Save(); } EventHandler<SettingChangedEventArgs> eventHandler = this.SettingChanged; if (eventHandler == null) { return; } SettingChangedEventArgs e = new SettingChangedEventArgs(changedEntryBase); Delegate[] invocationList = eventHandler.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { EventHandler<SettingChangedEventArgs> eventHandler2 = (EventHandler<SettingChangedEventArgs>)invocationList[i]; try { eventHandler2(sender, e); } catch (Exception data) { Logger.Log(LogLevel.Error, data); } } } private void OnConfigReloaded() { EventHandler eventHandler = this.ConfigReloaded; if (eventHandler == null) { return; } Delegate[] invocationList = eventHandler.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { EventHandler eventHandler2 = (EventHandler)invocationList[i]; try { eventHandler2(this, EventArgs.Empty); } catch (Exception data) { Logger.Log(LogLevel.Error, data); } } } } [Obsolete("Use ConfigFile from new Bind overloads instead")] public sealed class ConfigWrapper<T> { public ConfigEntry<T> ConfigEntry { get; } public ConfigDefinition Definition => ConfigEntry.Definition; public ConfigFile ConfigFile => ConfigEntry.ConfigFile; public T Value { get { return ConfigEntry.Value; } set { ConfigEntry.Value = value; } } public event EventHandler SettingChanged; internal ConfigWrapper(ConfigEntry<T> configEntry) { ConfigWrapper<T> configWrapper = this; ConfigEntry = configEntry ?? throw new ArgumentNullException("configEntry"); configEntry.ConfigFile.SettingChanged += delegate(object sender, SettingChangedEventArgs args) { if (args.ChangedSetting == configEntry) { configWrapper.SettingChanged?.Invoke(sender, args); } }; } } public sealed class SettingChangedEventArgs : EventArgs { public ConfigEntryBase ChangedSetting { get; } public SettingChangedEventArgs(ConfigEntryBase changedSetting) { ChangedSetting = changedSetting; } } public static class TomlTypeConverter { private static Dictionary<Type, TypeConverter> TypeConverters { get; } = new Dictionary<Type, TypeConverter> { [typeof(string)] = new TypeConverter { ConvertToString = (object obj, Type type) => ((string)obj).Escape(), ConvertToObject = (string str, Type type) => Regex.IsMatch(str, "^\"?\\w:\\\\(?!\\\\)(?!.+\\\\\\\\)") ? str : str.Unescape() }, [typeof(bool)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString().ToLowerInvariant(), ConvertToObject = (string str, Type type) => bool.Parse(str) }, [typeof(sbyte)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => sbyte.Parse(str) }, [typeof(byte)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => byte.Parse(str) }, [typeof(short)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => short.Parse(str) }, [typeof(ushort)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => ushort.Parse(str) }, [typeof(int)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => int.Parse(str) }, [typeof(uint)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => uint.Parse(str) }, [typeof(long)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => long.Parse(str) }, [typeof(ulong)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => ulong.Parse(str) }, [typeof(float)] = new TypeConverter { ConvertToString = (object obj, Type type) => ((float)obj).ToString(NumberFormatInfo.InvariantInfo), ConvertToObject = (string str, Type type) => float.Parse(str, NumberFormatInfo.InvariantInfo) }, [typeof(double)] = new TypeConverter { ConvertToString = (object obj, Type type) => ((double)obj).ToString(NumberFormatInfo.InvariantInfo), ConvertToObject = (string str, Type type) => double.Parse(str, NumberFormatInfo.InvariantInfo) }, [typeof(decimal)] = new TypeConverter { ConvertToString = (object obj, Type type) => ((decimal)obj).ToString(NumberFormatInfo.InvariantInfo), ConvertToObject = (string str, Type type) => decimal.Parse(str, NumberFormatInfo.InvariantInfo) }, [typeof(Enum)] = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => Enum.Parse(type, str, ignoreCase: true) } }; public static string ConvertToString(object value, Type valueType) { return (GetConverter(valueType) ?? throw new InvalidOperationException($"Cannot convert from type {valueType}")).ConvertToString(value, valueType); } public static T ConvertToValue<T>(string value) { return (T)ConvertToValue(value, typeof(T)); } public static object ConvertToValue(string value, Type valueType) { return (GetConverter(valueType) ?? throw new InvalidOperationException("Cannot convert to type " + valueType.Name)).ConvertToObject(value, valueType); } public static TypeConverter GetConverter(Type valueType) { if (valueType == null) { throw new ArgumentNullException("valueType"); } if (valueType.IsEnum) { return TypeConverters[typeof(Enum)]; } TypeConverters.TryGetValue(valueType, out var value); return value; } public static bool AddConverter(Type type, TypeConverter converter) { if (type == null) { throw new ArgumentNullException("type"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (CanConvert(type)) { Logger.Log(LogLevel.Warning, "Tried to add a TomlConverter when one already exists for type " + type.FullName); return false; } TypeConverters.Add(type, converter); return true; } public static bool CanConvert(Type type) { return GetConverter(type) != null; } public static IEnumerable<Type> GetSupportedTypes() { return TypeConverters.Keys; } private static string Escape(this string txt) { if (string.IsNullOrEmpty(txt)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(txt.Length + 2); foreach (char c in txt) { switch (c) { case '\0': stringBuilder.Append("\\0"); break; case '\a': stringBuilder.Append("\\a"); break; case '\b': stringBuilder.Append("\\b"); break; case '\t': stringBuilder.Append("\\t"); break; case '\n': stringBuilder.Append("\\n"); break; case '\v': stringBuilder.Append("\\v"); break; case '\f': stringBuilder.Append("\\f"); break; case '\r': stringBuilder.Append("\\r"); break; case '\'': stringBuilder.Append("\\'"); break; case '\\': stringBuilder.Append("\\"); break; case '"': stringBuilder.Append("\\\""); break; default: stringBuilder.Append(c); break; } } return stringBuilder.ToString(); } private static string Unescape(this string txt) { if (string.IsNullOrEmpty(txt)) { return txt; } StringBuilder stringBuilder = new StringBuilder(txt.Length); int num = 0; while (num < txt.Length) { int num2 = txt.IndexOf('\\', num); if (num2 < 0 || num2 == txt.Length - 1) { num2 = txt.Length; } stringBuilder.Append(txt, num, num2 - num); if (num2 >= txt.Length) { break; } char c = txt[num2 + 1]; switch (c) { case '0': stringBuilder.Append('\0'); break; case 'a': stringBuilder.Append('\a'); break; case 'b': stringBuilder.Append('\b'); break; case 't': stringBuilder.Append('\t'); break; case 'n': stringBuilder.Append('\n'); break; case 'v': stringBuilder.Append('\v'); break; case 'f': stringBuilder.Append('\f'); break; case 'r': stringBuilder.Append('\r'); break; case '\'': stringBuilder.Append('\''); break; case '"': stringBuilder.Append('"'); break; case '\\': stringBuilder.Append('\\'); break; default: stringBuilder.Append('\\').Append(c); break; } num = num2 + 2; } return stringBuilder.ToString(); } } public class TypeConverter { public Func<object, Type, string> ConvertToString { get; set; } public Func<string, Type, object> ConvertToObject { get; set; } } } namespace BepInEx.Bootstrap { public abstract class BaseChainloader<TPlugin> { protected static readonly string CurrentAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; protected static readonly Version CurrentAssemblyVersion = Assembly.GetExecutingAssembly().GetName().Version; private bool _initialized; private static readonly ConfigEntry<bool> ConfigDiskAppend = ConfigFile.CoreConfig.Bind("Logging.Disk", "AppendLog", defaultValue: false, "Appends to the log file instead of overwriting, on game startup."); private static readonly ConfigEntry<bool> ConfigDiskLogging = ConfigFile.CoreConfig.Bind("Logging.Disk", "Enabled", defaultValue: true, "Enables writing log messages to disk."); private static readonly ConfigEntry<LogLevel> ConfigDiskLoggingDisplayedLevel = ConfigFile.CoreConfig.Bind("Logging.Disk", "LogLevels", LogLevel.Fatal | LogLevel.Error | LogLevel.Warning | LogLevel.Message | LogLevel.Info, "Only displays the specified log levels in the disk log output."); private static readonly ConfigEntry<bool> ConfigDiskLoggingInstantFlushing = ConfigFile.CoreConfig.Bind("Logging.Disk", "InstantFlushing", defaultValue: false, new StringBuilder().AppendLine("If true, instantly writes any received log entries to disk.").AppendLine("This incurs a major performance hit if a lot of log messages are being written, however it is really useful for debugging crashes.").ToString()); private static readonly ConfigEntry<int> ConfigDiskLoggingFileLimit = ConfigFile.CoreConfig.Bind("Logging.Disk", "ConcurrentFileLimit", 5, new StringBuilder().AppendLine("The maximum amount of concurrent log files that will be written to disk.").AppendLine("As one log file is used per open game instance, you may find it necessary to increase this limit when debugging multiple instances at the same time.").ToString()); private static Regex allowedGuidRegex { get; } = new Regex("^[a-zA-Z0-9\\._\\-]+$"); private static string ConsoleTitle => $"BepInEx {Paths.BepInExVersion} - {Paths.ProcessName}"; public Dictionary<string, PluginInfo> Plugins { get; } = new Dictionary<string, PluginInfo>(); public List<string> DependencyErrors { get; } = new List<string>(); public event Action<PluginInfo> PluginLoaded; public event Action Finished; public static PluginInfo ToPluginInfo(TypeDefinition type, string assemblyLocation) { if (type.IsInterface || type.IsAbstract) { return null; } try { if (!type.IsSubtypeOf(typeof(TPlugin))) { return null; } } catch (AssemblyResolutionException) { return null; } BepInPlugin bepInPlugin = BepInPlugin.FromCecilType(type); bool isEnabled; if (bepInPlugin == null) { LogLevel logLevel = LogLevel.Warning; LogLevel level = logLevel; BepInExLogInterpolatedStringHandler bepInExLogInterpolatedStringHandler = new BepInExLogInterpolatedStringHandler(59, 1, logLevel, out isEnabled); if (isEnabled) { bepInExLogInterpolatedStringHandler.AppendLiteral("Skipping over type ["); bepInExLogInterpolatedStringHandler.AppendFormatted(((MemberReference)type).FullName); bepInExLogInterpolatedStringHandler.AppendLiteral("] as no metadata attribute is specified"); } Logger.Log(level, bepInExLogInterpolatedStringHandler); return null; } if (string.IsNullOrEmpty(bepInPlugin.GUID) || !allowedGuidRegex.IsMatch(bepInPlugin.GUID)) { LogLevel logLevel = LogLevel.Warning; LogLevel level2 = logLevel; BepInExLogInterpolatedStringHandler bepInExLogInterpolatedStringHandler = new BepInExLogInterpolatedStringHandler(61, 2, logLevel, out isEnabled); if (isEnabled) { bepInExLogInterpolatedStringHandler.AppendLiteral("Skipping type ["); bepInExLogInterpolatedStringHandler.AppendFormatted(((MemberReference)type).FullName); bepInExLogInterpolatedStringHandler.AppendLiteral("] because its GUID ["); bepInExLogInterpolatedStringHandler.AppendFormatted(bepInPlugin.GUID); bepInExLogInterpolatedStringHandler.AppendLiteral("] is of an illegal format."); } Logger.Log(level2, bepInExLogInterpolatedStringHandler); return null; } if (bepInPlugin.Version == (Version)null) { LogLevel logLevel = LogLevel.Warning; LogLevel level3 = logLevel; BepInExLogInterpolatedStringHandler bepInExLogInterpolatedStringHandler = new BepInExLogInterpolatedStringHandler(48, 1, logLevel, out isEnabled); if (isEnabled) { bepInExLogInterpolatedStringHandler.AppendLiteral("Skipping type ["); bepInExLogInterpolatedStringHandler.AppendFormatted(((MemberReference)type).FullName); bepInExLogInterpolatedStringHandler.AppendLiteral("] because its version is invalid."); } Logger.Log(level3, bepInExLogInterpolatedStringHandler); return null; } if (bepInPlugin.Name == null) { LogLevel logLevel = LogLevel.Warning; LogLevel level4 = logLevel; BepInExLogInterpolatedStringHandler bepInExLogInterpolatedStringHandler = new BepInExLogInterpolatedStringHandler(42, 1, logLevel, out isEnabled); if (isEnabled) { bepInExLogInterpolatedStringHandler.AppendLiteral("Skipping type ["); bepInExLogInterpolatedStringHandler.AppendFormatted(((MemberReference)type).FullName); bepInExLogInterpolatedStringHandler.AppendLiteral("] because its name is null."); } Logger.Log(level4, bepInExLogInterpolatedStringHandler); return null; } List<BepInProcess> processes = BepInProcess.FromCecilType(type); IEnumerable<BepInDependency> dependencies = BepInDependency.FromCecilType(type); IEnumerable<BepInIncompatibility> incompatibilities = BepInIncompatibility.FromCecilType(type); AssemblyNameReference? obj = ((IEnumerable<AssemblyNameReference>)((MemberReference)type).Module.AssemblyReferences).FirstOrDefault((Func<AssemblyNam
BepInExPack/BepInEx/core/BepInEx.NET.Common.dll
Decompiled a day agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Preloader.Core.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2022 BepInEx Team")] [assembly: AssemblyDescription("BepInEx common code for .NET-based games")] [assembly: AssemblyFileVersion("6.0.0.0")] [assembly: AssemblyInformationalVersion("6.0.0+802b84c947c2b8ab870be453776f7ab895d8cf09")] [assembly: AssemblyProduct("BepInEx.NET.Common")] [assembly: AssemblyTitle("BepInEx.NET.Common")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ibox233/BepinEx-6-CoreCLR-For-Romestead")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx.NET.Common { public abstract class BasePlugin { public ManualLogSource Log { get; } public ConfigFile Config { get; } public Harmony HarmonyInstance { get; set; } protected BasePlugin() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown BepInPlugin metadata = MetadataHelper.GetMetadata((object)this); HarmonyInstance = new Harmony("BepInEx.Plugin." + metadata.GUID); Log = Logger.CreateLogSource(metadata.Name); Config = new ConfigFile(Utility.CombinePaths(new string[2] { Paths.ConfigPath, metadata.GUID + ".cfg" }), false, metadata); } public abstract void Load(); public virtual bool Unload() { return false; } } public class NetChainloader : BaseChainloader<BasePlugin> { public static NetChainloader Instance { get; set; } public override void Initialize() { Instance = this; base.Initialize(); } public override BasePlugin LoadPlugin(PluginInfo pluginInfo, Assembly pluginAssembly) { BasePlugin obj = (BasePlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginInfo.TypeName)); obj.Load(); return obj; } protected override void InitializeLoggers() { base.InitializeLoggers(); ChainloaderLogHelper.RewritePreloaderLogs(); } } }
BepInExPack/BepInEx/core/BepInEx.NET.CoreCLR.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx.Bootstrap; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.NET.Common; using BepInEx.NET.CoreCLR; using BepInEx.NET.Shared; using BepInEx.Preloader.Core; using BepInEx.Preloader.Core.Logging; using BepInEx.Preloader.Core.Patching; using Mono.Cecil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] [assembly: AssemblyCompany("BepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2022 BepInEx Team")] [assembly: AssemblyDescription("BepInEx support library for CoreCLR games")] [assembly: AssemblyFileVersion("6.0.0.0")] [assembly: AssemblyInformationalVersion("6.0.0+802b84c947c2b8ab870be453776f7ab895d8cf09")] [assembly: AssemblyProduct("BepInEx.NET.CoreCLR")] [assembly: AssemblyTitle("BepInEx.NET.CoreCLR")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ibox233/BepinEx-6-CoreCLR-For-Romestead")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class StartupHook { public static List<string> ResolveDirectories = new List<string>(); public static string DoesNotExistPath = "_doesnotexist_.exe"; private static int initialized; private static Mutex initializationMutex; private const string AppDomainInitializedKey = "Romestead.BepInEx.NET.CoreCLR.StartupHook.Initialized"; public static void Initialize() { if (!TryBeginInitialize()) { return; } string text = $"bepinex_preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log"; try { string fileName = Process.GetCurrentProcess().MainModule.FileName; string text2 = TryDetermineAssemblyNameFromDotnet(fileName) ?? TryDetermineAssemblyNameFromStubExecutable(fileName) ?? TryDetermineAssemblyNameFromCurrentAssembly(fileName); string text3 = null; if (text2 != null) { text3 = Path.GetDirectoryName(text2); } string text4 = TryDetermineBepInExRootFromDoorstopTarget() ?? TryDetermineBepInExRootFromCurrentAssembly() ?? TryDetermineBepInExRootFromGameDirectory(text3); string text5 = null; if (text4 != null) { text5 = Path.Combine(text4, "core"); } if (text2 == null || text3 == null || !Directory.Exists(text5)) { throw new Exception("Could not determine game location, or BepInEx install location"); } text = Path.Combine(text3, text); ResolveDirectories.Add(text5); AppDomain.CurrentDomain.AssemblyResolve += SharedEntrypoint.RemoteResolve(ResolveDirectories); NetCorePreloaderRunner.OuterMain(text2, text4); } catch (Exception value) { string text6 = null; string text7 = null; try { text6 = Process.GetCurrentProcess().MainModule?.FileName; text7 = string.Join(' ', Environment.GetCommandLineArgs()); } catch { } string contents = $"Unhandled fatal exception\r\nExecutable location: {text6 ?? "<null>"}\r\nArguments: {text7 ?? "<null>"}\r\n{value}"; File.WriteAllText(text, contents); Console.WriteLine("Unhandled exception"); Console.WriteLine("Executable location: " + (text6 ?? "<null>")); Console.WriteLine("Arguments: " + (text7 ?? "<null>")); Console.WriteLine(value); } } private static bool TryBeginInitialize() { if (Interlocked.Exchange(ref initialized, 1) == 1) { return false; } if (AppDomain.CurrentDomain.GetData("Romestead.BepInEx.NET.CoreCLR.StartupHook.Initialized") != null) { return false; } try { string name = $"Romestead.BepInEx.NET.CoreCLR.StartupHook.{Environment.ProcessId}"; initializationMutex = new Mutex(initiallyOwned: true, name, out var createdNew); if (!createdNew) { return false; } } catch { } AppDomain.CurrentDomain.SetData("Romestead.BepInEx.NET.CoreCLR.StartupHook.Initialized", true); return true; } private static string TryDetermineAssemblyNameFromDotnet(string executableFilename) { if (Path.GetFileNameWithoutExtension(executableFilename) == "dotnet") { string[] commandLineArgs = Environment.GetCommandLineArgs(); foreach (string text in commandLineArgs) { if ((text.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || text.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) && File.Exists(text)) { return Path.GetFullPath(text); } } } return null; } private static string TryDetermineAssemblyNameFromStubExecutable(string executableFilename) { string text = Path.ChangeExtension(executableFilename, ".dll"); if (File.Exists(text)) { return text; } return null; } private static string TryDetermineAssemblyNameFromCurrentAssembly(string executableFilename) { string directoryName = Path.GetDirectoryName(typeof(StartupHook).Assembly.Location.Replace('/', Path.DirectorySeparatorChar)); if (directoryName == null) { return null; } string directoryName2 = Path.GetDirectoryName(Path.GetDirectoryName(directoryName)); if (directoryName2 == null) { return null; } return Path.Combine(directoryName2, DoesNotExistPath); } private static string TryDetermineBepInExRootFromDoorstopTarget() { string text = GetCommandLineArgValue("--doorstop-target") ?? GetCommandLineArgValue("--doorstop-target-assembly") ?? GetCommandLineArgValue("--doorstop_target_assembly"); if (string.IsNullOrWhiteSpace(text)) { return null; } return TryDetermineBepInExRootFromTargetAssembly(text); } private static string TryDetermineBepInExRootFromTargetAssembly(string targetAssembly) { string fullPath; try { fullPath = Path.GetFullPath(targetAssembly); } catch { return null; } if (!File.Exists(fullPath)) { return null; } if (!string.Equals(Path.GetFileName(fullPath), "BepInEx.NET.CoreCLR.dll", StringComparison.OrdinalIgnoreCase)) { return null; } string directoryName = Path.GetDirectoryName(fullPath); if (directoryName == null) { return null; } if (string.Equals(Path.GetFileName(directoryName), "core", StringComparison.OrdinalIgnoreCase)) { string text = ParentDirectory(fullPath, 2); if (HasBepInExCoreDirectory(text)) { return text; } } return TryDetermineBepInExRootFromGameDirectory(directoryName); } private static string TryDetermineBepInExRootFromCurrentAssembly() { return TryDetermineBepInExRootFromTargetAssembly(typeof(StartupHook).Assembly.Location.Replace('/', Path.DirectorySeparatorChar)); } private static string TryDetermineBepInExRootFromGameDirectory(string gameDirectory) { if (string.IsNullOrWhiteSpace(gameDirectory)) { return null; } string text = Path.Combine(gameDirectory, "BepInEx"); if (!HasBepInExCoreDirectory(text)) { return null; } return text; } private static bool HasBepInExCoreDirectory(string bepinexRoot) { if (!string.IsNullOrWhiteSpace(bepinexRoot)) { return Directory.Exists(Path.Combine(bepinexRoot, "core")); } return false; } private static string GetCommandLineArgValue(string name) { string[] commandLineArgs = Environment.GetCommandLineArgs(); for (int i = 1; i < commandLineArgs.Length - 1; i++) { if (string.Equals(commandLineArgs[i], name, StringComparison.OrdinalIgnoreCase)) { return commandLineArgs[i + 1]; } } return null; } private static string ParentDirectory(string path, int levels) { for (int i = 0; i < levels; i++) { path = Path.GetDirectoryName(path); } return path; } } namespace BepInEx.NET.Shared { internal static class SharedEntrypoint { public static ResolveEventHandler RemoteResolve(List<string> resolveDirectories) { return (object? sender, ResolveEventArgs args) => RemoteResolveInternal(sender, args, resolveDirectories); } private static Assembly RemoteResolveInternal(object sender, ResolveEventArgs reference, List<string> resolveDirectories) { AssemblyName assemblyName = new AssemblyName(reference.Name); foreach (string resolveDirectory in resolveDirectories) { if (!Directory.Exists(resolveDirectory)) { continue; } List<string> list = new List<string> { resolveDirectory }; list.AddRange(Directory.GetDirectories(resolveDirectory, "*", SearchOption.AllDirectories)); foreach (string item in list.Select((string x) => Path.Combine(x, assemblyName.Name + ".dll")).Concat(list.Select((string x) => Path.Combine(x, assemblyName.Name + ".exe")))) { if (File.Exists(item)) { Assembly assembly; try { assembly = Assembly.LoadFrom(item); } catch (Exception) { continue; } if (assembly.GetName().Name == assemblyName.Name) { return assembly; } } } } return null; } public static Assembly LocalResolve(object sender, ResolveEventArgs args) { AssemblyName assemblyName = new AssemblyName(args.Name); Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => x.GetName().Name == assemblyName.Name); if (assembly != null) { return assembly; } if (LocalUtility.TryResolveDllAssembly(assemblyName, Paths.BepInExAssemblyDirectory, out assembly) || LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PatcherPluginPath, out assembly) || LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PluginPath, out assembly)) { return assembly; } return null; } } internal static class LocalUtility { private static bool TryResolveDllAssembly<T>(AssemblyName assemblyName, string directory, Func<string, T> loader, out T assembly) where T : class { assembly = null; if (!Directory.Exists(directory)) { return false; } List<string> list = new List<string>(); list.Add(directory); list.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories)); foreach (string item in list) { string text = Path.Combine(item, assemblyName.Name + ".dll"); if (File.Exists(text)) { try { assembly = loader(text); } catch (Exception) { continue; } return true; } } return false; } public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly) { return TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFrom, out assembly); } } } namespace BepInEx.NET.CoreCLR { internal static class NetCorePreloaderRunner { internal static void PreloaderMain() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown ConsoleManager.Initialize(false, true); if (ConsoleManager.ConsoleEnabled) { ConsoleManager.CreateConsole(); Logger.Listeners.Add((ILogListener)new ConsoleLogListener()); } try { NetCorePreloader.Start(); } catch (Exception ex) { PreloaderLogger.Log.Log((LogLevel)1, (object)"Unhandled exception"); PreloaderLogger.Log.Log((LogLevel)1, (object)ex); } } internal static void OuterMain(string filename, string bepinexRootPath) { PlatformUtils.SetPlatform(); Paths.SetDotNetGamePath(filename, bepinexRootPath); AppDomain.CurrentDomain.AssemblyResolve += SharedEntrypoint.LocalResolve; PreloaderMain(); } } public static class NativeEntrypoint { public static int Initialize(nint args, int sizeBytes) { StartupHook.Initialize(); return 0; } } internal class NetCorePreloader { private static readonly ManualLogSource Log = PreloaderLogger.Log; public static void Start() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Expected O, but got Unknown //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Expected O, but got Unknown //IL_02ac: Expected O, but got Unknown PreloaderConsoleListener item = new PreloaderConsoleListener(); Logger.Listeners.Add((ILogListener)(object)item); string text = ((!Paths.ExecutablePath.EndsWith(StartupHook.DoesNotExistPath)) ? Paths.ExecutablePath : null); TypeLoader.SearchDirectories.Add(Paths.GameRootPath); Logger.Sources.Add(TraceLogSource.CreateSource()); ChainloaderLogHelper.PrintLogInfo(Log); bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CLR runtime version: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Version>(Environment.Version); } Log.LogInfo(val); val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Current executable: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Process.GetCurrentProcess().MainModule.FileName); } Log.LogInfo(val); val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Entrypoint assembly: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text ?? "<does not exist>"); } Log.LogInfo(val); val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Launch arguments: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(' ', Environment.GetCommandLineArgs())); } Log.LogInfo(val); if (text != null) { AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(text); AssemblyBuildInfo val3; try { val3 = AssemblyBuildInfo.DetermineInfo(val2); } finally { ((IDisposable)val2)?.Dispose(); } val = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Game executable build architecture: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<AssemblyBuildInfo>(val3); } Log.LogInfo(val); } else { Log.LogWarning((object)"Game assembly is unknown, can't determine build architecture"); } Log.LogMessage((object)"Preloader started"); AssemblyPatcher val4 = new AssemblyPatcher((Func<byte[], string, Assembly>)((byte[] data, string _) => Assembly.Load(data))); try { val4.AddPatchersFromDirectory(Paths.PatcherPluginPath); val = new BepInExInfoLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(val4.PatcherContext.PatchDefinitions.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" patcher definition(s) loaded"); } Log.LogInfo(val); val4.LoadAssemblyDirectories((IEnumerable<string>)new string[1] { Paths.GameRootPath }, (IEnumerable<string>)new string[2] { "dll", "exe" }); val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(val4.PatcherContext.AvailableAssemblies.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" assemblies discovered"); } Log.LogInfo(val); val4.PatchAndLoad(); } finally { ((IDisposable)val4)?.Dispose(); } Log.LogMessage((object)"Preloader finished"); Logger.Listeners.Remove((ILogListener)(object)item); NetChainloader val5 = new NetChainloader(); ((BaseChainloader<BasePlugin>)val5).Initialize(); ((BaseChainloader<BasePlugin>)val5).Execute(); } } }
BepInExPack/BepInEx/core/BepInEx.Preloader.Core.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Mono.Cecil; using SemanticVersioning; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("BepInEx.NET.CoreCLR")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("BepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2022 BepInEx Team")] [assembly: AssemblyDescription("Core classes and utilities for BepInEx Preloader")] [assembly: AssemblyFileVersion("6.0.0.0")] [assembly: AssemblyInformationalVersion("6.0.0+802b84c947c2b8ab870be453776f7ab895d8cf09")] [assembly: AssemblyProduct("BepInEx.Preloader.Core")] [assembly: AssemblyTitle("BepInEx.Preloader.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ibox233/BepinEx-6-CoreCLR-For-Romestead")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx.Preloader.RuntimeFixes { public static class ConsoleSetOutFix { private static LoggedTextWriter loggedTextWriter; internal static ManualLogSource ConsoleLogSource = Logger.CreateLogSource("Console"); public static void Apply() { loggedTextWriter = new LoggedTextWriter { Parent = Console.Out }; Console.SetOut(loggedTextWriter); Harmony.CreateAndPatchAll(typeof(ConsoleSetOutFix), (string)null); } [HarmonyPatch(typeof(Console), "SetOut")] [HarmonyPrefix] private static bool OnSetOut(TextWriter newOut) { loggedTextWriter.Parent = newOut; return false; } } internal class LoggedTextWriter : TextWriter { public override Encoding Encoding { get; } = Encoding.UTF8; public TextWriter Parent { get; set; } public override void Flush() { Parent.Flush(); } public override void Write(string value) { ConsoleSetOutFix.ConsoleLogSource.Log((LogLevel)16, (object)value); Parent.Write(value); } public override void WriteLine(string value) { ConsoleSetOutFix.ConsoleLogSource.Log((LogLevel)16, (object)value); Parent.WriteLine(value); } } public static class HarmonyBackendFix { private enum MonoModBackend { [Description("Auto")] auto, [Description("DynamicMethod")] dynamicmethod, [Description("MethodBuilder")] methodbuilder, [Description("Cecil")] cecil } private static readonly ConfigEntry<MonoModBackend> ConfigHarmonyBackend = ConfigFile.CoreConfig.Bind<MonoModBackend>("Preloader", "HarmonyBackend", MonoModBackend.auto, "Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.\nThis setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting."); public static void Initialize() { switch (ConfigHarmonyBackend.Value) { case MonoModBackend.dynamicmethod: case MonoModBackend.methodbuilder: case MonoModBackend.cecil: Environment.SetEnvironmentVariable("MONOMOD_DMD_TYPE", ConfigHarmonyBackend.Value.ToString()); break; default: throw new ArgumentOutOfRangeException("ConfigHarmonyBackend", ConfigHarmonyBackend.Value, "Unknown backend"); case MonoModBackend.auto: break; } } } } namespace BepInEx.Preloader.Core { public class AssemblyBuildInfo { public enum FrameworkType { Unknown, NetFramework, NetStandard, NetCore } public Version NetFrameworkVersion { get; private set; } public bool IsAnyCpu { get; set; } public bool Is64Bit { get; set; } public FrameworkType AssemblyFrameworkType { get; set; } private void SetNet4Version(AssemblyDefinition assemblyDefinition) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0084: Unknown result type (might be due to invalid IL or missing references) NetFrameworkVersion = new Version(0, 0); AssemblyFrameworkType = FrameworkType.Unknown; CustomAttribute val = ((IEnumerable<CustomAttribute>)assemblyDefinition.CustomAttributes).FirstOrDefault((Func<CustomAttribute, bool>)((CustomAttribute x) => ((MemberReference)x.AttributeType).FullName == "System.Runtime.Versioning.TargetFrameworkAttribute")); if (val == null || val.ConstructorArguments.Count < 1) { return; } CustomAttributeArgument val2 = val.ConstructorArguments[0]; if (((MemberReference)((CustomAttributeArgument)(ref val2)).Type).Name != "String") { return; } val2 = val.ConstructorArguments[0]; string[] array = ((string)((CustomAttributeArgument)(ref val2)).Value).Split(new char[1] { ',' }); foreach (string text in array) { if (text.StartsWith(".NET")) { AssemblyFrameworkType = text switch { ".NETFramework" => FrameworkType.NetFramework, ".NETCoreApp" => FrameworkType.NetCore, ".NETStandard" => FrameworkType.NetStandard, _ => FrameworkType.Unknown, }; } else if (text.StartsWith("Version=v")) { try { NetFrameworkVersion = new Version(text.Substring("Version=v".Length)); } catch { } } } } public static AssemblyBuildInfo DetermineInfo(AssemblyDefinition assemblyDefinition) { //IL_000c: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) AssemblyBuildInfo assemblyBuildInfo = new AssemblyBuildInfo(); TargetRuntime runtime = assemblyDefinition.MainModule.Runtime; if ((int)runtime == 0) { assemblyBuildInfo.NetFrameworkVersion = new Version(1, 0); assemblyBuildInfo.AssemblyFrameworkType = FrameworkType.NetFramework; } else if ((int)runtime == 1) { assemblyBuildInfo.NetFrameworkVersion = new Version(1, 1); assemblyBuildInfo.AssemblyFrameworkType = FrameworkType.NetFramework; } else if ((int)runtime == 2) { assemblyBuildInfo.NetFrameworkVersion = new Version(3, 5); assemblyBuildInfo.AssemblyFrameworkType = FrameworkType.NetFramework; } else { assemblyBuildInfo.SetNet4Version(assemblyDefinition); } TargetArchitecture architecture = assemblyDefinition.MainModule.Architecture; ModuleAttributes attributes = assemblyDefinition.MainModule.Attributes; if ((int)architecture == 34404) { assemblyBuildInfo.Is64Bit = true; assemblyBuildInfo.IsAnyCpu = false; } else if ((int)architecture == 332 && HasFlag(attributes, (ModuleAttributes)131074)) { assemblyBuildInfo.Is64Bit = false; assemblyBuildInfo.IsAnyCpu = true; } else if ((int)architecture == 332 && HasFlag(attributes, (ModuleAttributes)2)) { assemblyBuildInfo.Is64Bit = false; assemblyBuildInfo.IsAnyCpu = false; } else { if ((int)architecture != 332) { throw new Exception("Unable to determine assembly architecture"); } assemblyBuildInfo.Is64Bit = true; assemblyBuildInfo.IsAnyCpu = true; } return assemblyBuildInfo; } private static bool HasFlag(ModuleAttributes value, ModuleAttributes flag) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (ModuleAttributes)(value & flag) == flag; } public override string ToString() { string value = AssemblyFrameworkType switch { FrameworkType.NetFramework => "Framework", FrameworkType.NetStandard => "Standard", FrameworkType.NetCore => "Core", FrameworkType.Unknown => "Unknown", _ => throw new ArgumentOutOfRangeException(), }; if (!IsAnyCpu) { return $".NET {value} {NetFrameworkVersion}, {(Is64Bit ? "x64" : "x86")}"; } return $".NET {value} {NetFrameworkVersion}, AnyCPU ({(Is64Bit ? "64" : "32")}-bit preferred)"; } } public static class PreloaderLogger { public static ManualLogSource Log { get; } = Logger.CreateLogSource("Preloader"); } internal static class PlatformUtils { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.LPStr)] private delegate string GetWineVersionDelegate(); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] public struct WindowsOSVersionInfoExW { public uint dwOSVersionInfoSize; public uint dwMajorVersion; public uint dwMinorVersion; public uint dwBuildNumber; public uint dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szCSDVersion; public ushort wServicePackMajor; public ushort wServicePackMinor; public ushort wSuiteMask; public byte wProductType; public byte wReserved; public WindowsOSVersionInfoExW() { dwOSVersionInfoSize = (uint)Marshal.SizeOf(typeof(WindowsOSVersionInfoExW)); dwMajorVersion = 0u; dwMinorVersion = 0u; dwBuildNumber = 0u; dwPlatformId = 0u; szCSDVersion = null; wServicePackMajor = 0; wServicePackMinor = 0; wSuiteMask = 0; wProductType = 0; wReserved = 0; } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct utsname_osx { private const int osx_utslen = 256; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string sysname; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string nodename; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string release; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string version; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string machine; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct utsname_linux { private const int linux_utslen = 65; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string sysname; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string nodename; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string release; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string version; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string machine; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string domainname; } public static readonly bool ProcessIs64Bit = IntPtr.Size >= 8; public static Version WindowsVersion { get; set; } public static string WineVersion { get; set; } public static string LinuxArchitecture { get; set; } public static string LinuxKernelVersion { get; set; } public static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); public static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux); public static bool IsMacOS => RuntimeInformation.IsOSPlatform(OSPlatform.OSX); public static bool IsWine => !string.IsNullOrEmpty(WineVersion); public static string Architecture => RuntimeInformation.ProcessArchitecture.ToString(); [DllImport("libc.so.6", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "uname")] private static extern IntPtr uname_linux(ref utsname_linux utsname); [DllImport("/usr/lib/libSystem.dylib", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "uname")] private static extern IntPtr uname_osx(ref utsname_osx utsname); [DllImport("ntdll.dll", SetLastError = true)] private static extern bool RtlGetVersion(ref WindowsOSVersionInfoExW versionInfo); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr LoadLibrary(string libraryName); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); public static void SetPlatform() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { WindowsOSVersionInfoExW versionInfo = new WindowsOSVersionInfoExW(); RtlGetVersion(ref versionInfo); WindowsVersion = new Version((int)versionInfo.dwMajorVersion, (int)versionInfo.dwMinorVersion, (int)versionInfo.dwBuildNumber); IntPtr intPtr = LoadLibrary("ntdll.dll"); if (intPtr != IntPtr.Zero) { IntPtr procAddress = GetProcAddress(intPtr, "wine_get_version"); if (procAddress != IntPtr.Zero) { WineVersion = (Marshal.GetDelegateForFunctionPointer(procAddress, typeof(GetWineVersionDelegate)) as GetWineVersionDelegate)(); } } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { utsname_linux utsname = default(utsname_linux); if (uname_linux(ref utsname) == IntPtr.Zero) { LinuxArchitecture = utsname.machine; LinuxKernelVersion = utsname.version; } } } } } namespace BepInEx.Preloader.Core.Patching { public class AssemblyPatcher : IDisposable { private static readonly string CurrentAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; private Func<byte[], string, Assembly> assemblyLoader; private static readonly ConfigEntry<bool> ConfigDumpAssemblies = ConfigFile.CoreConfig.Bind<bool>("Preloader", "DumpAssemblies", false, "If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.\nThis can be used by developers to inspect and debug preloader patchers."); private static readonly ConfigEntry<bool> ConfigLoadDumpedAssemblies = ConfigFile.CoreConfig.Bind<bool>("Preloader", "LoadDumpedAssemblies", false, "If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.\nThis can be used to be able to load patched assemblies into debuggers like dnSpy.\nIf set to true, will override DumpAssemblies."); private static readonly ConfigEntry<bool> ConfigBreakBeforeLoadAssemblies = ConfigFile.CoreConfig.Bind<bool>("Preloader", "BreakBeforeLoadAssemblies", false, "If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.\nThis can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded."); public PatcherContext PatcherContext { get; } = new PatcherContext { DumpedAssembliesPath = Utility.CombinePaths(new string[3] { Paths.BepInExRootPath, "DumpedAssemblies", Paths.ProcessName }) }; private IEnumerable<BasePatcher> PatcherPluginsSafe => PatcherContext.PatcherPlugins.ToList(); private ManualLogSource Logger { get; } = Logger.CreateLogSource("AssemblyPatcher"); private static Regex allowedGuidRegex { get; } = new Regex("^[a-zA-Z0-9\\._\\-]+$"); public AssemblyPatcher(Func<byte[], string, Assembly> assemblyLoader) { this.assemblyLoader = assemblyLoader; } public void Dispose() { foreach (KeyValuePair<string, AssemblyDefinition> availableAssembly in PatcherContext.AvailableAssemblies) { availableAssembly.Value.Dispose(); } PatcherContext.AvailableAssemblies.Clear(); PatcherContext.AvailableAssembliesPaths.Clear(); PatcherContext.PatcherPlugins.Clear(); } private PatcherPluginMetadata ToPatcherPlugin(TypeDefinition type, string assemblyPath) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //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_0055: 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_005f: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if (type.IsInterface || (type.IsAbstract && !type.IsSealed)) { return null; } try { if (!Utility.IsSubtypeOf(type, typeof(BasePatcher))) { return null; } } catch (AssemblyResolutionException) { return null; } PatcherPluginInfoAttribute patcherPluginInfoAttribute = PatcherPluginInfoAttribute.FromCecilType(type); bool flag = default(bool); if (patcherPluginInfoAttribute == null) { ManualLogSource logger = Logger; LogLevel val = (LogLevel)4; LogLevel val2 = val; BepInExLogInterpolatedStringHandler val3 = new BepInExLogInterpolatedStringHandler(59, 1, val, ref flag); if (flag) { val3.AppendLiteral("Skipping over type ["); val3.AppendFormatted<string>(((MemberReference)type).FullName); val3.AppendLiteral("] as no metadata attribute is specified"); } logger.Log(val2, val3); return null; } if (string.IsNullOrEmpty(patcherPluginInfoAttribute.GUID) || !allowedGuidRegex.IsMatch(patcherPluginInfoAttribute.GUID)) { ManualLogSource logger2 = Logger; LogLevel val2 = (LogLevel)4; LogLevel val = val2; BepInExLogInterpolatedStringHandler val3 = new BepInExLogInterpolatedStringHandler(60, 2, val2, ref flag); if (flag) { val3.AppendLiteral("Skipping type ["); val3.AppendFormatted<string>(((MemberReference)type).FullName); val3.AppendLiteral("] because its GUID ["); val3.AppendFormatted<string>(patcherPluginInfoAttribute.GUID); val3.AppendLiteral("] is of an illegal format"); } logger2.Log(val, val3); return null; } if (patcherPluginInfoAttribute.Version == (Version)null) { ManualLogSource logger3 = Logger; LogLevel val = (LogLevel)4; LogLevel val2 = val; BepInExLogInterpolatedStringHandler val3 = new BepInExLogInterpolatedStringHandler(47, 1, val, ref flag); if (flag) { val3.AppendLiteral("Skipping type ["); val3.AppendFormatted<string>(((MemberReference)type).FullName); val3.AppendLiteral("] because its version is invalid"); } logger3.Log(val2, val3); return null; } if (patcherPluginInfoAttribute.Name == null) { ManualLogSource logger4 = Logger; LogLevel val2 = (LogLevel)4; LogLevel val = val2; BepInExLogInterpolatedStringHandler val3 = new BepInExLogInterpolatedStringHandler(41, 1, val2, ref flag); if (flag) { val3.AppendLiteral("Skipping type ["); val3.AppendFormatted<string>(((MemberReference)type).FullName); val3.AppendLiteral("] because its name is null"); } logger4.Log(val, val3); return null; } return new PatcherPluginMetadata { TypeName = ((MemberReference)type).FullName }; } private bool HasPatcherPlugins(AssemblyDefinition ass) { if (((IEnumerable<AssemblyNameReference>)ass.MainModule.AssemblyReferences).All((AssemblyNameReference r) => r.Name != CurrentAssemblyName) && ((AssemblyNameReference)ass.Name).Name != CurrentAssemblyName) { return false; } if (ass.MainModule.GetTypeReferences().All((TypeReference r) => ((MemberReference)r).FullName != typeof(BasePatcher).FullName)) { return false; } return true; } public void AddPatchersFromDirectory(string directory) { //IL_0295: 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_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Expected O, but got Unknown //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) if (!Directory.Exists(directory)) { return; } List<PatchDefinition> sortedPatchers = new List<PatchDefinition>(); bool flag = default(bool); foreach (KeyValuePair<string, List<PatcherPluginMetadata>> item in TypeLoader.FindPluginTypes<PatcherPluginMetadata>(directory, (Func<TypeDefinition, string, PatcherPluginMetadata>)ToPatcherPlugin, (Func<AssemblyDefinition, bool>)HasPatcherPlugins, (string)null)) { string key = item.Key; List<PatcherPluginMetadata> value = item.Value; if (value.Count == 0) { continue; } Assembly assembly = Assembly.LoadFrom(key); LogLevel val; LogLevel val2; BepInExLogInterpolatedStringHandler val3; foreach (PatcherPluginMetadata item2 in value) { try { Type? type = assembly.GetType(item2.TypeName); BasePatcher basePatcher = (BasePatcher)Activator.CreateInstance(type); basePatcher.Context = PatcherContext; PatcherContext.PatcherPlugins.Add(basePatcher); MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { TargetAssemblyAttribute[] attributes = MetadataHelper.GetAttributes<TargetAssemblyAttribute>((MemberInfo)methodInfo); TargetTypeAttribute[] attributes2 = MetadataHelper.GetAttributes<TargetTypeAttribute>((MemberInfo)methodInfo); if (attributes.Length == 0 && attributes2.Length == 0) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length < 1 || parameters.Length > 2 || (!(parameters[0].ParameterType == typeof(AssemblyDefinition)) && (!(parameters[0].ParameterType == typeof(AssemblyDefinition).MakeByRefType()) || attributes2.Length != 0) && (!(parameters[0].ParameterType == typeof(TypeDefinition)) || attributes.Length != 0)) || (parameters.Length == 2 && parameters[1].ParameterType != typeof(string)) || (methodInfo.ReturnType != typeof(void) && methodInfo.ReturnType != typeof(bool))) { ManualLogSource logger = Logger; val = (LogLevel)4; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(54, 1, val, ref flag); if (flag) { val3.AppendLiteral("Skipping method ["); val3.AppendFormatted<string>(GeneralExtensions.FullDescription((MethodBase)methodInfo)); val3.AppendLiteral("] as it is not a valid patcher method"); } logger.Log(val2, val3); } else { TargetAssemblyAttribute[] array = attributes; foreach (TargetAssemblyAttribute targetAssembly in array) { AddDefinition(new PatchDefinition(targetAssembly, basePatcher, methodInfo)); } TargetTypeAttribute[] array2 = attributes2; foreach (TargetTypeAttribute targetType in array2) { AddDefinition(new PatchDefinition(targetType, basePatcher, methodInfo)); } } } } catch (Exception ex) { ManualLogSource logger2 = Logger; val2 = (LogLevel)2; val = val2; val3 = new BepInExLogInterpolatedStringHandler(38, 2, val2, ref flag); if (flag) { val3.AppendLiteral("Failed to load patchers from type ["); val3.AppendFormatted<string>(item2.TypeName); val3.AppendLiteral("]: "); val3.AppendFormatted<string>((ex is ReflectionTypeLoadException ex2) ? TypeLoader.TypeLoadExceptionToString(ex2) : ex.ToString()); } logger2.Log(val, val3); } } AssemblyName name = assembly.GetName(); ManualLogSource logger3 = Logger; val = (LogLevel)(value.Any() ? 16 : 32); val2 = val; val3 = new BepInExLogInterpolatedStringHandler(29, 4, val, ref flag); if (flag) { val3.AppendLiteral("Loaded "); val3.AppendFormatted<int>(value.Count); val3.AppendLiteral(" patcher type"); val3.AppendFormatted<string>((value.Count == 1) ? "" : "s"); val3.AppendLiteral(" from ["); val3.AppendFormatted<string>(name.Name); val3.AppendLiteral(" "); val3.AppendFormatted<Version>(name.Version); val3.AppendLiteral("]"); } logger3.Log(val2, val3); } PatcherContext.PatchDefinitions.AddRange(sortedPatchers); void AddDefinition(PatchDefinition definition) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) ManualLogSource logger4 = Logger; LogLevel val4 = (LogLevel)32; LogLevel val5 = val4; bool flag2 = default(bool); BepInExLogInterpolatedStringHandler val6 = new BepInExLogInterpolatedStringHandler(19, 1, val4, ref flag2); if (flag2) { val6.AppendLiteral("Discovered patch ["); val6.AppendFormatted<string>(definition.FullName); val6.AppendLiteral("]"); } logger4.Log(val5, val6); sortedPatchers.Add(definition); } } public void LoadAssemblyDirectories(params string[] directories) { LoadAssemblyDirectories(directories, new string[1] { "dll" }); } public void LoadAssemblyDirectories(IEnumerable<string> directories, IEnumerable<string> assemblyExtensions) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown bool flag = default(bool); foreach (string item in assemblyExtensions.SelectMany((string ext) => Utility.GetUniqueFilesInDirectories(directories, "*." + ext))) { if (!TryLoadAssembly(item, out var assembly)) { continue; } if (((AssemblyNameReference)assembly.Name).Name == "System" || ((AssemblyNameReference)assembly.Name).Name == "mscorlib") { assembly.Dispose(); continue; } string fileName = Path.GetFileName(item); PatcherContext.AvailableAssemblies.Add(fileName, assembly); PatcherContext.AvailableAssembliesPaths.Add(fileName, item); ManualLogSource logger = Logger; BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(17, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Assembly loaded: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Path.GetFileName(item)); } logger.LogDebug(val); } } public static bool TryLoadAssembly(string path, out AssemblyDefinition assembly) { try { assembly = AssemblyDefinition.ReadAssembly(path, TypeLoader.ReaderParameters); return true; } catch (BadImageFormatException) { assembly = null; return false; } } public void PatchAndLoad() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0708: Unknown result type (might be due to invalid IL or missing references) //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_070c: Unknown result type (might be due to invalid IL or missing references) //IL_0711: Unknown result type (might be due to invalid IL or missing references) //IL_0715: Unknown result type (might be due to invalid IL or missing references) //IL_071c: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0754: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_050f: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Unknown result type (might be due to invalid IL or missing references) //IL_0513: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Expected O, but got Unknown //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_0569: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Unknown result type (might be due to invalid IL or missing references) //IL_0574: Expected O, but got Unknown //IL_0596: Unknown result type (might be due to invalid IL or missing references) //IL_0674: Unknown result type (might be due to invalid IL or missing references) //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Unknown result type (might be due to invalid IL or missing references) //IL_0688: Expected O, but got Unknown //IL_06b2: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, AssemblyDefinition> dictionary = new Dictionary<string, AssemblyDefinition>(PatcherContext.AvailableAssemblies, StringComparer.InvariantCultureIgnoreCase); bool flag = default(bool); LogLevel val2; LogLevel val; BepInExLogInterpolatedStringHandler val3; foreach (BasePatcher item in PatcherPluginsSafe) { try { item.Initialize(); } catch (Exception ex) { ManualLogSource logger = Logger; val = (LogLevel)2; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(31, 2, val, ref flag); if (flag) { val3.AppendLiteral("Failed to run initializer of "); val3.AppendFormatted<string>(item.Info.GUID); val3.AppendLiteral(": "); val3.AppendFormatted<Exception>(ex); } logger.Log(val2, val3); } } HashSet<string> patchedAssemblies = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); Dictionary<string, string> dictionary2 = new Dictionary<string, string>(); HashSet<string> invalidAssemblies = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); ManualLogSource logger2 = Logger; val2 = (LogLevel)8; val = val2; val3 = new BepInExLogInterpolatedStringHandler(20, 1, val2, ref flag); if (flag) { val3.AppendLiteral("Executing "); val3.AppendFormatted<int>(PatcherContext.PatchDefinitions.Count); val3.AppendLiteral(" patch(es)"); } logger2.Log(val, val3); AssemblyName assemblyName = default(AssemblyName); foreach (PatchDefinition item2 in PatcherContext.PatchDefinitions.ToList()) { PatchDefinition patchDefinition = item2; string text = patchDefinition.TargetAssembly?.TargetAssembly ?? patchDefinition.TargetType.TargetAssembly; bool isAssemblyPatch = patchDefinition.TargetAssembly != null; if (text == "_all") { foreach (KeyValuePair<string, AssemblyDefinition> item3 in PatcherContext.AvailableAssemblies.ToList()) { if (!invalidAssemblies.Contains(item3.Key)) { RunPatcher(item3.Value, item3.Key); } } } else { if (!PatcherContext.AvailableAssemblies.TryGetValue(text, out var value) || invalidAssemblies.Contains(text)) { continue; } RunPatcher(value, text); } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { string key = (Utility.TryParseAssemblyName(assembly.FullName, ref assemblyName) ? assemblyName.Name : assembly.FullName); if (!dictionary2.ContainsKey(key)) { dictionary2[key] = patchDefinition.MethodInfo.DeclaringType.ToString(); } } bool RunPatcher(AssemblyDefinition val5, string targetDll) { //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_01fc: 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_005e: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown try { object[] array = new object[patchDefinition.MethodInfo.GetParameters().Length]; if (!isAssemblyPatch) { TypeDefinition val4 = ((IEnumerable<TypeDefinition>)val5.MainModule.Types).FirstOrDefault((Func<TypeDefinition, bool>)((TypeDefinition x) => ((MemberReference)x).FullName == patchDefinition.TargetType.TargetType)); if (val4 == null) { ManualLogSource logger7 = Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val6 = new BepInExWarningLogInterpolatedStringHandler(52, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Unable to find type ["); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(patchDefinition.TargetType.TargetType); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("] defined in "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(patchDefinition.MethodInfo.Name); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(". Skipping patcher"); } logger7.LogWarning(val6); return false; } array[0] = val4; } else { array[0] = val5; } if (array.Length > 1) { array[1] = targetDll; } object obj = patchDefinition.MethodInfo.Invoke(patchDefinition.Instance, array); if (patchDefinition.MethodInfo.ReturnType == typeof(void) || (patchDefinition.MethodInfo.ReturnType == typeof(bool) && (bool)obj)) { if (isAssemblyPatch) { val5 = (AssemblyDefinition)array[0]; PatcherContext.AvailableAssemblies[targetDll] = val5; } patchedAssemblies.Add(targetDll); } return true; } catch (Exception ex3) { ManualLogSource logger8 = Logger; LogLevel val7 = (LogLevel)2; LogLevel val8 = val7; bool flag3 = default(bool); BepInExLogInterpolatedStringHandler val9 = new BepInExLogInterpolatedStringHandler(77, 3, val7, ref flag3); if (flag3) { val9.AppendLiteral("Failed to run ["); val9.AppendFormatted<string>(patchDefinition.FullName); val9.AppendLiteral("] when patching ["); val9.AppendFormatted<string>(((AssemblyNameReference)val5.Name).Name); val9.AppendLiteral("]. This assembly will not be patched. Error: "); val9.AppendFormatted<Exception>(ex3); } logger8.Log(val8, val9); patchedAssemblies.Remove(targetDll); invalidAssemblies.Add(targetDll); return false; } } } HashSet<string> patchedAssemblyNames = new HashSet<string>(from kv in dictionary where patchedAssemblies.Contains(kv.Key) select ((AssemblyNameReference)kv.Value.Name).Name, StringComparer.InvariantCultureIgnoreCase); List<KeyValuePair<string, string>> list = dictionary2.Where((KeyValuePair<string, string> kv) => patchedAssemblyNames.Contains(kv.Key)).ToList(); if (list.Count != 0) { Logger.Log((LogLevel)4, (object)new StringBuilder().AppendLine("The following assemblies have been loaded too early and will not be patched by preloader:").AppendLine(string.Join(Environment.NewLine, list.Select((KeyValuePair<string, string> kv) => $"* [{kv.Key}] (first loaded by [{kv.Value}])").ToArray())).AppendLine("Expect unexpected behavior and issues with plugins and patchers not being loaded.") .ToString()); } Dictionary<string, string> dictionary3 = new Dictionary<string, string>(); if (ConfigDumpAssemblies.Value || ConfigLoadDumpedAssemblies.Value) { if (!Directory.Exists(PatcherContext.DumpedAssembliesPath)) { Directory.CreateDirectory(PatcherContext.DumpedAssembliesPath); } FileStream fileStream = default(FileStream); foreach (KeyValuePair<string, AssemblyDefinition> item4 in dictionary) { string key2 = item4.Key; string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(key2); string extension = Path.GetExtension(key2); AssemblyDefinition value2 = item4.Value; if (!patchedAssemblies.Contains(key2)) { continue; } int num = 0; string text3; while (true) { string text2 = ((num > 0) ? $"_{num}" : ""); text3 = Path.Combine(PatcherContext.DumpedAssembliesPath, fileNameWithoutExtension + text2 + extension); if (Utility.TryOpenFileStream(text3, FileMode.Create, ref fileStream, FileAccess.ReadWrite, FileShare.Read)) { break; } num++; } value2.Write((Stream)fileStream); fileStream.Dispose(); dictionary3[key2] = text3; } } if (ConfigBreakBeforeLoadAssemblies.Value) { ManualLogSource logger3 = Logger; val = (LogLevel)16; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(48, 1, val, ref flag); if (flag) { val3.AppendLiteral("BepInEx is about load the following assemblies:\n"); val3.AppendFormatted<string>(string.Join("\n", patchedAssemblies.ToArray())); } logger3.Log(val2, val3); ManualLogSource logger4 = Logger; val2 = (LogLevel)16; val = val2; val3 = new BepInExLogInterpolatedStringHandler(32, 1, val2, ref flag); if (flag) { val3.AppendLiteral("The assemblies were dumped into "); val3.AppendFormatted<string>(PatcherContext.DumpedAssembliesPath); } logger4.Log(val, val3); Logger.Log((LogLevel)16, (object)"Load any assemblies into the debugger, set breakpoints and continue execution."); Debugger.Break(); } foreach (KeyValuePair<string, AssemblyDefinition> item5 in dictionary) { string key3 = item5.Key; AssemblyDefinition value3 = item5.Value; if (patchedAssemblies.Contains(key3)) { Assembly value5; if (ConfigLoadDumpedAssemblies.Value && dictionary3.TryGetValue(key3, out var value4)) { value5 = Assembly.LoadFrom(value4); } else { using MemoryStream memoryStream = new MemoryStream(); value3.Write((Stream)memoryStream); value5 = assemblyLoader(memoryStream.ToArray(), PatcherContext.AvailableAssembliesPaths[key3]); } PatcherContext.LoadedAssemblies.Add(key3, value5); ManualLogSource logger5 = Logger; val = (LogLevel)32; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(21, 1, val, ref flag); if (flag) { val3.AppendLiteral("Loaded '"); val3.AppendFormatted<string>(value3.FullName); val3.AppendLiteral("' into memory"); } logger5.Log(val2, val3); } value3.Dispose(); } foreach (BasePatcher item6 in PatcherPluginsSafe) { try { item6.Finalizer(); } catch (Exception ex2) { ManualLogSource logger6 = Logger; val2 = (LogLevel)2; val = val2; val3 = new BepInExLogInterpolatedStringHandler(29, 2, val2, ref flag); if (flag) { val3.AppendLiteral("Failed to run finalizer of "); val3.AppendFormatted<string>(item6.Info.GUID); val3.AppendLiteral(": "); val3.AppendFormatted<Exception>(ex2); } logger6.Log(val, val3); } } } } [AttributeUsage(AttributeTargets.Class)] public class PatcherPluginInfoAttribute : Attribute { public string GUID { get; protected set; } public string Name { get; protected set; } public Version Version { get; protected set; } public PatcherPluginInfoAttribute(string GUID, string Name, string Version) { this.GUID = GUID; this.Name = Name; this.Version = TryParseLongVersion(Version); } private static Version TryParseLongVersion(string version) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown Version result = default(Version); if (Version.TryParse(version, ref result)) { return result; } try { Version version2 = new Version(version); return new Version(version2.Major, version2.Minor, (version2.Build != -1) ? version2.Build : 0, (string)null, (string)null); } catch { } return null; } internal static PatcherPluginInfoAttribute FromCecilType(TypeDefinition td) { //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_0032: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) CustomAttribute val = MetadataHelper.GetCustomAttributes<PatcherPluginInfoAttribute>(td, false).FirstOrDefault(); if (val == null) { return null; } CustomAttributeArgument val2 = val.ConstructorArguments[0]; string gUID = (string)((CustomAttributeArgument)(ref val2)).Value; val2 = val.ConstructorArguments[1]; string name = (string)((CustomAttributeArgument)(ref val2)).Value; val2 = val.ConstructorArguments[2]; return new PatcherPluginInfoAttribute(gUID, name, (string)((CustomAttributeArgument)(ref val2)).Value); } internal static PatcherPluginInfoAttribute FromType(Type type) { object[] customAttributes = type.GetCustomAttributes(typeof(PatcherPluginInfoAttribute), inherit: false); if (customAttributes.Length == 0) { return null; } return (PatcherPluginInfoAttribute)customAttributes[0]; } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public class TargetAssemblyAttribute : Attribute { public const string AllAssemblies = "_all"; public string TargetAssembly { get; } public TargetAssemblyAttribute(string targetAssembly) { TargetAssembly = targetAssembly; } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public class TargetTypeAttribute : Attribute { public string TargetAssembly { get; } public string TargetType { get; } public TargetTypeAttribute(string targetAssembly, string targetType) { TargetAssembly = targetAssembly; TargetType = targetType; } } public abstract class BasePatcher { public ManualLogSource Log { get; } public ConfigFile Config { get; } public PatcherPluginInfoAttribute Info { get; } public PatcherContext Context { get; set; } protected BasePatcher() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown Info = PatcherPluginInfoAttribute.FromType(GetType()); Log = Logger.CreateLogSource(Info.Name); Config = new ConfigFile(Utility.CombinePaths(new string[2] { Paths.ConfigPath, Info.GUID + ".cfg" }), false, new BepInPlugin(Info.GUID, Info.Name, ((object)Info.Version).ToString())); } public virtual void Initialize() { } public virtual void Finalizer() { } } public class PatchDefinition { public TargetAssemblyAttribute TargetAssembly { get; } public TargetTypeAttribute TargetType { get; } public BasePatcher Instance { get; } public MethodInfo MethodInfo { get; } public string FullName { get; } public PatchDefinition(TargetAssemblyAttribute targetAssembly, BasePatcher instance, MethodInfo methodInfo) { TargetAssembly = targetAssembly; Instance = instance; MethodInfo = methodInfo; FullName = $"{MethodInfo.DeclaringType.FullName}/{MethodInfo.Name} -> {TargetAssembly.TargetAssembly}"; } public PatchDefinition(TargetTypeAttribute targetType, BasePatcher instance, MethodInfo methodInfo) { TargetType = targetType; Instance = instance; MethodInfo = methodInfo; FullName = $"{MethodInfo.DeclaringType.FullName}/{MethodInfo.Name} -> {TargetType.TargetAssembly}/{TargetType.TargetType}"; } } public class PatcherContext { public Dictionary<string, AssemblyDefinition> AvailableAssemblies { get; } = new Dictionary<string, AssemblyDefinition>(); public Dictionary<string, string> AvailableAssembliesPaths { get; } = new Dictionary<string, string>(); public Dictionary<string, Assembly> LoadedAssemblies { get; } = new Dictionary<string, Assembly>(); public List<BasePatcher> PatcherPlugins { get; } = new List<BasePatcher>(); public List<PatchDefinition> PatchDefinitions { get; } = new List<PatchDefinition>(); public string DumpedAssembliesPath { get; internal set; } } internal class PatcherPluginMetadata : ICacheable { public string TypeName { get; set; } = string.Empty; public void Save(BinaryWriter bw) { bw.Write(TypeName); } public void Load(BinaryReader br) { TypeName = br.ReadString(); } } } namespace BepInEx.Preloader.Core.Logging { public static class ChainloaderLogHelper { private static Dictionary<string, string> MacOSVersions { get; } = new Dictionary<string, string> { ["16.0.0"] = "10.12", ["16.5.0"] = "10.12.4", ["16.6.0"] = "10.12.6", ["17.5.0"] = "10.13.4", ["17.6.0"] = "10.13.5", ["17.7.0"] = "10.13.6", ["18.2.0"] = "10.14.1", ["19.2.0"] = "10.15.2", ["19.3.0"] = "10.15.3", ["19.5.0"] = "10.15.5.1", ["20.1.0"] = "11.0", ["20.2.0"] = "11.1", ["20.3.0"] = "11.2", ["20.4.0"] = "11.3", ["20.5.0"] = "11.4", ["21.0.1"] = "12.0", ["21.1.0"] = "12.0.1", ["21.2.0"] = "12.1" }; public static void PrintLogInfo(ManualLogSource log) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0065: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_0145: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) Version bepInExVersion = Paths.BepInExVersion; Version value = new Version(bepInExVersion.Major, bepInExVersion.Minor, bepInExVersion.Patch, bepInExVersion.PreRelease, (string)null); string text = $"BepInEx {value} - {Paths.ProcessName}"; LogLevel val = (LogLevel)8; LogLevel val2 = val; bool flag = default(bool); BepInExLogInterpolatedStringHandler val3 = new BepInExLogInterpolatedStringHandler(3, 2, val, ref flag); if (flag) { val3.AppendFormatted<string>(text); val3.AppendLiteral(" ("); val3.AppendFormatted<DateTime>(File.GetLastWriteTime(Paths.ExecutablePath)); val3.AppendLiteral(")"); } log.Log(val2, val3); if (ConsoleManager.ConsoleActive) { ConsoleManager.SetConsoleTitle(text); } if (!string.IsNullOrEmpty(bepInExVersion.Build)) { val2 = (LogLevel)8; val = val2; val3 = new BepInExLogInterpolatedStringHandler(18, 1, val2, ref flag); if (flag) { val3.AppendLiteral("Built from commit "); val3.AppendFormatted<string>(bepInExVersion.Build); } log.Log(val, val3); } val = (LogLevel)16; LogLevel val4 = val; val3 = new BepInExLogInterpolatedStringHandler(17, 1, val, ref flag); if (flag) { val3.AppendLiteral("System platform: "); val3.AppendFormatted<string>(GetPlatformString()); } Logger.Log(val4, val3); val = (LogLevel)16; LogLevel val5 = val; val3 = new BepInExLogInterpolatedStringHandler(17, 1, val, ref flag); if (flag) { val3.AppendLiteral("Process bitness: "); val3.AppendFormatted<string>(PlatformUtils.ProcessIs64Bit ? "64-bit (x64)" : "32-bit (x86)"); } Logger.Log(val5, val3); } private static string GetPlatformString() { StringBuilder stringBuilder = new StringBuilder(); Version version = Environment.OSVersion.Version; if (PlatformUtils.IsWindows) { version = PlatformUtils.WindowsVersion; stringBuilder.Append("Windows "); if (version.Major >= 10 && version.Build >= 22000) { stringBuilder.Append("11"); } else if (version.Major >= 10) { stringBuilder.Append("10"); } else if (version.Major == 6 && version.Minor == 3) { stringBuilder.Append("8.1"); } else if (version.Major == 6 && version.Minor == 2) { stringBuilder.Append("8"); } else if (version.Major == 6 && version.Minor == 1) { stringBuilder.Append("7"); } else if (version.Major == 6 && version.Minor == 0) { stringBuilder.Append("Vista"); } else if (version.Major <= 5) { stringBuilder.Append("XP"); } if (PlatformUtils.IsWine) { stringBuilder.AppendFormat(" (Wine {0})", PlatformUtils.WineVersion); } } else if (PlatformUtils.IsMacOS) { stringBuilder.Append("macOS "); string key = version.ToString(3); if (MacOSVersions.TryGetValue(key, out var value)) { stringBuilder.Append(value); } else { stringBuilder.AppendFormat("Unknown (kernel {0})", version); } } else if (PlatformUtils.IsLinux) { stringBuilder.Append("Linux"); if (PlatformUtils.LinuxKernelVersion != null) { stringBuilder.AppendFormat(" (kernel {0})", PlatformUtils.LinuxKernelVersion); } } stringBuilder.Append(PlatformUtils.ProcessIs64Bit ? " 64-bit" : " 32-bit"); stringBuilder.AppendFormat(" ({0})", PlatformUtils.Architecture); return stringBuilder.ToString(); } public static void RewritePreloaderLogs() { if (PreloaderConsoleListener.LogEvents == null || PreloaderConsoleListener.LogEvents.Count == 0) { return; } ILogListener val = ((IEnumerable<ILogListener>)Logger.Listeners).FirstOrDefault((Func<ILogListener, bool>)((ILogListener logger) => logger is ConsoleLogListener)); if (val != null) { Logger.Listeners.Remove(val); } foreach (LogEventArgs logEvent in PreloaderConsoleListener.LogEvents) { Logger.InternalLogEvent((object)PreloaderLogger.Log, logEvent); } if (val != null) { Logger.Listeners.Add(val); } } } public class PreloaderConsoleListener : ILogListener, IDisposable { private static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind<LogLevel>("Logging.Console", "LogLevels", (LogLevel)31, "Which log levels to show in the console output."); public static List<LogEventArgs> LogEvents { get; } = new List<LogEventArgs>(); public LogLevel LogLevelFilter => ConfigConsoleDisplayedLevel.Value; public void LogEvent(object sender, LogEventArgs eventArgs) { LogEvents.Add(eventArgs); } public void Dispose() { } } }
BepInExPack/BepInEx/core/Mono.Cecil.dll
Decompiled a day 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.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Threading; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Metadata; using Mono.Cecil.PE; using Mono.Collections.Generic; using Mono.Security.Cryptography; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyProduct("Mono.Cecil")] [assembly: AssemblyCopyright("Copyright © 2008 - 2018 Jb Evain")] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("0.11.6.0")] [assembly: AssemblyInformationalVersion("0.11.6.0")] [assembly: AssemblyTitle("Mono.Cecil")] [assembly: Guid("fd225bb4-fa53-44b2-a6db-85f5e48dcb54")] [assembly: InternalsVisibleTo("Mono.Cecil.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf")] [assembly: InternalsVisibleTo("Mono.Cecil.Pdb, PublicKey=00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf")] [assembly: InternalsVisibleTo("Mono.Cecil.Mdb, PublicKey=00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf")] [assembly: InternalsVisibleTo("Mono.Cecil.Rocks, PublicKey=00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyVersion("0.11.6.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } internal static class Consts { public const string AssemblyName = "Mono.Cecil"; public const string PublicKey = "00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf"; } namespace Mono { internal static class Disposable { public static Disposable<T> Owned<T>(T value) where T : class, IDisposable { return new Disposable<T>(value, owned: true); } public static Disposable<T> NotOwned<T>(T value) where T : class, IDisposable { return new Disposable<T>(value, owned: false); } } internal struct Disposable<T> : IDisposable where T : class, IDisposable { internal readonly T value; private readonly bool owned; public Disposable(T value, bool owned) { this.value = value; this.owned = owned; } public void Dispose() { if (value != null && owned) { value.Dispose(); } } } internal static class Empty<T> { public static readonly T[] Array = new T[0]; } internal class ArgumentNullOrEmptyException : ArgumentException { public ArgumentNullOrEmptyException(string paramName) : base("Argument null or empty", paramName) { } } internal class MergeSort<T> { private readonly T[] elements; private readonly T[] buffer; private readonly IComparer<T> comparer; private MergeSort(T[] elements, IComparer<T> comparer) { this.elements = elements; buffer = new T[elements.Length]; Array.Copy(this.elements, buffer, elements.Length); this.comparer = comparer; } public static void Sort(T[] source, IComparer<T> comparer) { Sort(source, 0, source.Length, comparer); } public static void Sort(T[] source, int start, int length, IComparer<T> comparer) { new MergeSort<T>(source, comparer).Sort(start, length); } private void Sort(int start, int length) { TopDownSplitMerge(buffer, elements, start, length); } private void TopDownSplitMerge(T[] a, T[] b, int start, int end) { if (end - start >= 2) { int num = (end + start) / 2; TopDownSplitMerge(b, a, start, num); TopDownSplitMerge(b, a, num, end); TopDownMerge(a, b, start, num, end); } } private void TopDownMerge(T[] a, T[] b, int start, int middle, int end) { int num = start; int num2 = middle; for (int i = start; i < end; i++) { if (num < middle && (num2 >= end || comparer.Compare(a[num], a[num2]) <= 0)) { b[i] = a[num++]; } else { b[i] = a[num2++]; } } } } } namespace Mono.Security.Cryptography { internal static class CryptoConvert { private static int ToInt32LE(byte[] bytes, int offset) { return (bytes[offset + 3] << 24) | (bytes[offset + 2] << 16) | (bytes[offset + 1] << 8) | bytes[offset]; } private static uint ToUInt32LE(byte[] bytes, int offset) { return (uint)((bytes[offset + 3] << 24) | (bytes[offset + 2] << 16) | (bytes[offset + 1] << 8) | bytes[offset]); } private static byte[] GetBytesLE(int val) { return new byte[4] { (byte)((uint)val & 0xFFu), (byte)((uint)(val >> 8) & 0xFFu), (byte)((uint)(val >> 16) & 0xFFu), (byte)((uint)(val >> 24) & 0xFFu) }; } private static byte[] Trim(byte[] array) { for (int i = 0; i < array.Length; i++) { if (array[i] != 0) { byte[] array2 = new byte[array.Length - i]; Buffer.BlockCopy(array, i, array2, 0, array2.Length); return array2; } } return null; } private static RSA FromCapiPrivateKeyBlob(byte[] blob, int offset) { RSAParameters parameters = default(RSAParameters); try { if (blob[offset] != 7 || blob[offset + 1] != 2 || blob[offset + 2] != 0 || blob[offset + 3] != 0 || ToUInt32LE(blob, offset + 8) != 843141970) { throw new CryptographicException("Invalid blob header"); } int num = ToInt32LE(blob, offset + 12); byte[] array = new byte[4]; Buffer.BlockCopy(blob, offset + 16, array, 0, 4); Array.Reverse((Array)array); parameters.Exponent = Trim(array); int num2 = offset + 20; int num3 = num >> 3; parameters.Modulus = new byte[num3]; Buffer.BlockCopy(blob, num2, parameters.Modulus, 0, num3); Array.Reverse((Array)parameters.Modulus); num2 += num3; int num4 = num3 >> 1; parameters.P = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.P, 0, num4); Array.Reverse((Array)parameters.P); num2 += num4; parameters.Q = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.Q, 0, num4); Array.Reverse((Array)parameters.Q); num2 += num4; parameters.DP = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.DP, 0, num4); Array.Reverse((Array)parameters.DP); num2 += num4; parameters.DQ = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.DQ, 0, num4); Array.Reverse((Array)parameters.DQ); num2 += num4; parameters.InverseQ = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.InverseQ, 0, num4); Array.Reverse((Array)parameters.InverseQ); num2 += num4; parameters.D = new byte[num3]; if (num2 + num3 + offset <= blob.Length) { Buffer.BlockCopy(blob, num2, parameters.D, 0, num3); Array.Reverse((Array)parameters.D); } } catch (Exception inner) { throw new CryptographicException("Invalid blob.", inner); } RSA rSA = null; try { rSA = RSA.Create(); rSA.ImportParameters(parameters); } catch (CryptographicException) { bool flag = false; try { rSA = new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore }); rSA.ImportParameters(parameters); } catch { flag = true; } if (flag) { throw; } } return rSA; } private static RSA FromCapiPublicKeyBlob(byte[] blob, int offset) { try { if (blob[offset] != 6 || blob[offset + 1] != 2 || blob[offset + 2] != 0 || blob[offset + 3] != 0 || ToUInt32LE(blob, offset + 8) != 826364754) { throw new CryptographicException("Invalid blob header"); } int num = ToInt32LE(blob, offset + 12); RSAParameters parameters = new RSAParameters { Exponent = new byte[3] }; parameters.Exponent[0] = blob[offset + 18]; parameters.Exponent[1] = blob[offset + 17]; parameters.Exponent[2] = blob[offset + 16]; int srcOffset = offset + 20; int num2 = num >> 3; parameters.Modulus = new byte[num2]; Buffer.BlockCopy(blob, srcOffset, parameters.Modulus, 0, num2); Array.Reverse((Array)parameters.Modulus); RSA rSA = null; try { rSA = RSA.Create(); rSA.ImportParameters(parameters); } catch (CryptographicException) { rSA = new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore }); rSA.ImportParameters(parameters); } return rSA; } catch (Exception inner) { throw new CryptographicException("Invalid blob.", inner); } } public static RSA FromCapiKeyBlob(byte[] blob) { return FromCapiKeyBlob(blob, 0); } public static RSA FromCapiKeyBlob(byte[] blob, int offset) { if (blob == null) { throw new ArgumentNullException("blob"); } if (offset >= blob.Length) { throw new ArgumentException("blob is too small."); } switch (blob[offset]) { case 0: if (blob[offset + 12] == 6) { return FromCapiPublicKeyBlob(blob, offset + 12); } break; case 6: return FromCapiPublicKeyBlob(blob, offset); case 7: return FromCapiPrivateKeyBlob(blob, offset); } throw new CryptographicException("Unknown blob format."); } public static byte[] ToCapiPublicKeyBlob(RSA rsa) { RSAParameters rSAParameters = rsa.ExportParameters(includePrivateParameters: false); int num = rSAParameters.Modulus.Length; byte[] array = new byte[20 + num]; array[0] = 6; array[1] = 2; array[5] = 36; array[8] = 82; array[9] = 83; array[10] = 65; array[11] = 49; byte[] bytesLE = GetBytesLE(num << 3); array[12] = bytesLE[0]; array[13] = bytesLE[1]; array[14] = bytesLE[2]; array[15] = bytesLE[3]; int num2 = 16; int num3 = rSAParameters.Exponent.Length; while (num3 > 0) { array[num2++] = rSAParameters.Exponent[--num3]; } num2 = 20; byte[]? modulus = rSAParameters.Modulus; int num4 = modulus.Length; Array.Reverse((Array)modulus, 0, num4); Buffer.BlockCopy(modulus, 0, array, num2, num4); num2 += num4; return array; } } } namespace Mono.Collections.Generic { public class Collection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection { public struct Enumerator : IEnumerator<T>, IEnumerator, IDisposable { private Collection<T> collection; private T current; private int next; private readonly int version; public T Current => current; object IEnumerator.Current { get { CheckState(); if (next <= 0) { throw new InvalidOperationException(); } return current; } } internal Enumerator(Collection<T> collection) { this = default(Enumerator); this.collection = collection; version = collection.version; } public bool MoveNext() { CheckState(); if (next < 0) { return false; } if (next < collection.size) { current = collection.items[next++]; return true; } next = -1; return false; } public void Reset() { CheckState(); next = 0; } private void CheckState() { if (collection == null) { throw new ObjectDisposedException(GetType().FullName); } if (version != collection.version) { throw new InvalidOperationException(); } } public void Dispose() { collection = null; } } internal T[] items; internal int size; private int version; public int Count => size; public T this[int index] { get { if (index >= size) { throw new ArgumentOutOfRangeException(); } return items[index]; } set { CheckIndex(index); if (index == size) { throw new ArgumentOutOfRangeException(); } OnSet(value, index); items[index] = value; } } public int Capacity { get { return items.Length; } set { if (value < 0 || value < size) { throw new ArgumentOutOfRangeException(); } Resize(value); } } bool ICollection<T>.IsReadOnly => false; bool IList.IsFixedSize => false; bool IList.IsReadOnly => false; object IList.this[int index] { get { return this[index]; } set { CheckIndex(index); try { this[index] = (T)value; return; } catch (InvalidCastException) { } catch (NullReferenceException) { } throw new ArgumentException(); } } int ICollection.Count => Count; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; public Collection() { items = Empty<T>.Array; } public Collection(int capacity) { if (capacity < 0) { throw new ArgumentOutOfRangeException(); } items = ((capacity == 0) ? Empty<T>.Array : new T[capacity]); } public Collection(ICollection<T> items) { if (items == null) { throw new ArgumentNullException("items"); } this.items = new T[items.Count]; items.CopyTo(this.items, 0); size = this.items.Length; } public void Add(T item) { if (size == items.Length) { Grow(1); } OnAdd(item, size); items[size++] = item; version++; } public bool Contains(T item) { return IndexOf(item) != -1; } public int IndexOf(T item) { return Array.IndexOf(items, item, 0, size); } public void Insert(int index, T item) { CheckIndex(index); if (size == items.Length) { Grow(1); } OnInsert(item, index); Shift(index, 1); items[index] = item; version++; } public void RemoveAt(int index) { if (index < 0 || index >= size) { throw new ArgumentOutOfRangeException(); } T item = items[index]; OnRemove(item, index); Shift(index, -1); version++; } public bool Remove(T item) { int num = IndexOf(item); if (num == -1) { return false; } OnRemove(item, num); Shift(num, -1); version++; return true; } public void Clear() { OnClear(); Array.Clear(items, 0, size); size = 0; version++; } public void CopyTo(T[] array, int arrayIndex) { Array.Copy(items, 0, array, arrayIndex, size); } public T[] ToArray() { T[] array = new T[size]; Array.Copy(items, 0, array, 0, size); return array; } private void CheckIndex(int index) { if (index < 0 || index > size) { throw new ArgumentOutOfRangeException(); } } private void Shift(int start, int delta) { if (delta < 0) { start -= delta; } if (start < size) { Array.Copy(items, start, items, start + delta, size - start); } size += delta; if (delta < 0) { Array.Clear(items, size, -delta); } } protected virtual void OnAdd(T item, int index) { } protected virtual void OnInsert(T item, int index) { } protected virtual void OnSet(T item, int index) { } protected virtual void OnRemove(T item, int index) { } protected virtual void OnClear() { } internal virtual void Grow(int desired) { int num = size + desired; if (num > items.Length) { num = Math.Max(Math.Max(items.Length * 2, 4), num); Resize(num); } } protected void Resize(int new_size) { if (new_size != size) { if (new_size < size) { throw new ArgumentOutOfRangeException(); } items = items.Resize(new_size); } } int IList.Add(object value) { try { Add((T)value); return size - 1; } catch (InvalidCastException) { } catch (NullReferenceException) { } throw new ArgumentException(); } void IList.Clear() { Clear(); } bool IList.Contains(object value) { return ((IList)this).IndexOf(value) > -1; } int IList.IndexOf(object value) { try { return IndexOf((T)value); } catch (InvalidCastException) { } catch (NullReferenceException) { } return -1; } void IList.Insert(int index, object value) { CheckIndex(index); try { Insert(index, (T)value); return; } catch (InvalidCastException) { } catch (NullReferenceException) { } throw new ArgumentException(); } void IList.Remove(object value) { try { Remove((T)value); } catch (InvalidCastException) { } catch (NullReferenceException) { } } void IList.RemoveAt(int index) { RemoveAt(index); } void ICollection.CopyTo(Array array, int index) { Array.Copy(items, 0, array, index, size); } public Enumerator GetEnumerator() { return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(this); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(this); } } public sealed class ReadOnlyCollection<T> : Collection<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection { private static ReadOnlyCollection<T> empty; public static ReadOnlyCollection<T> Empty { get { if (empty != null) { return empty; } Interlocked.CompareExchange(ref empty, new ReadOnlyCollection<T>(), null); return empty; } } bool ICollection<T>.IsReadOnly => true; bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; private ReadOnlyCollection() { } public ReadOnlyCollection(T[] array) { if (array == null) { throw new ArgumentNullException(); } Initialize(array, array.Length); } public ReadOnlyCollection(Collection<T> collection) { if (collection == null) { throw new ArgumentNullException(); } Initialize(collection.items, collection.size); } private void Initialize(T[] items, int size) { base.items = new T[size]; Array.Copy(items, 0, base.items, 0, size); base.size = size; } internal override void Grow(int desired) { throw new InvalidOperationException(); } protected override void OnAdd(T item, int index) { throw new InvalidOperationException(); } protected override void OnClear() { throw new InvalidOperationException(); } protected override void OnInsert(T item, int index) { throw new InvalidOperationException(); } protected override void OnRemove(T item, int index) { throw new InvalidOperationException(); } protected override void OnSet(T item, int index) { throw new InvalidOperationException(); } } } namespace Mono.Cecil { internal static class Mixin { public enum Argument { name, fileName, fullName, stream, type, method, field, parameters, module, modifierType, eventType, fieldType, declaringType, returnType, propertyType, interfaceType, constraintType } public static Version ZeroVersion = new Version(0, 0, 0, 0); public const int NotResolvedMarker = -2; public const int NoDataMarker = -1; internal static object NoValue = new object(); internal static object NotResolved = new object(); public const string mscorlib = "mscorlib"; public const string system_runtime = "System.Runtime"; public const string system_private_corelib = "System.Private.CoreLib"; public const string netstandard = "netstandard"; public const int TableCount = 58; public const int CodedIndexCount = 14; public static bool IsNullOrEmpty<T>(this T[] self) { if (self != null) { return self.Length == 0; } return true; } public static bool IsNullOrEmpty<T>(this Collection<T> self) { if (self != null) { return self.size == 0; } return true; } public static T[] Resize<T>(this T[] self, int length) { Array.Resize(ref self, length); return self; } public static T[] Add<T>(this T[] self, T item) { if (self == null) { self = new T[1] { item }; return self; } self = self.Resize(self.Length + 1); self[^1] = item; return self; } public static Version CheckVersion(Version version) { if (version == null) { return ZeroVersion; } if (version.Build == -1) { return new Version(version.Major, version.Minor, 0, 0); } if (version.Revision == -1) { return new Version(version.Major, version.Minor, version.Build, 0); } return version; } public static bool TryGetUniqueDocument(this MethodDebugInformation info, out Document document) { document = info.SequencePoints[0].Document; for (int i = 1; i < info.SequencePoints.Count; i++) { if (info.SequencePoints[i].Document != document) { return false; } } return true; } public static void ResolveConstant(this IConstantProvider self, ref object constant, ModuleDefinition module) { if (module == null) { constant = NoValue; return; } lock (module.SyncRoot) { if (constant != NotResolved) { return; } if (module.HasImage()) { constant = module.Read(self, (IConstantProvider provider, MetadataReader reader) => reader.ReadConstant(provider)); } else { constant = NoValue; } } } public static bool GetHasCustomAttributes(this ICustomAttributeProvider self, ModuleDefinition module) { if (module.HasImage()) { return module.Read(self, (ICustomAttributeProvider provider, MetadataReader reader) => reader.HasCustomAttributes(provider)); } return false; } public static Collection<CustomAttribute> GetCustomAttributes(this ICustomAttributeProvider self, ref Collection<CustomAttribute> variable, ModuleDefinition module) { if (module.HasImage()) { return module.Read(ref variable, self, (ICustomAttributeProvider provider, MetadataReader reader) => reader.ReadCustomAttributes(provider)); } Interlocked.CompareExchange(ref variable, new Collection<CustomAttribute>(), null); return variable; } public static bool ContainsGenericParameter(this IGenericInstance self) { Collection<TypeReference> genericArguments = self.GenericArguments; for (int i = 0; i < genericArguments.Count; i++) { if (genericArguments[i].ContainsGenericParameter) { return true; } } return false; } public static void GenericInstanceFullName(this IGenericInstance self, StringBuilder builder) { builder.Append("<"); Collection<TypeReference> genericArguments = self.GenericArguments; for (int i = 0; i < genericArguments.Count; i++) { if (i > 0) { builder.Append(","); } builder.Append(genericArguments[i].FullName); } builder.Append(">"); } public static bool GetHasGenericParameters(this IGenericParameterProvider self, ModuleDefinition module) { if (module.HasImage()) { return module.Read(self, (IGenericParameterProvider provider, MetadataReader reader) => reader.HasGenericParameters(provider)); } return false; } public static Collection<GenericParameter> GetGenericParameters(this IGenericParameterProvider self, ref Collection<GenericParameter> collection, ModuleDefinition module) { if (module.HasImage()) { return module.Read(ref collection, self, (IGenericParameterProvider provider, MetadataReader reader) => reader.ReadGenericParameters(provider)); } Interlocked.CompareExchange(ref collection, new GenericParameterCollection(self), null); return collection; } public static bool GetHasMarshalInfo(this IMarshalInfoProvider self, ModuleDefinition module) { if (module.HasImage()) { return module.Read(self, (IMarshalInfoProvider provider, MetadataReader reader) => reader.HasMarshalInfo(provider)); } return false; } public static MarshalInfo GetMarshalInfo(this IMarshalInfoProvider self, ref MarshalInfo variable, ModuleDefinition module) { if (!module.HasImage()) { return null; } return module.Read(ref variable, self, (IMarshalInfoProvider provider, MetadataReader reader) => reader.ReadMarshalInfo(provider)); } public static bool GetAttributes(this uint self, uint attributes) { return (self & attributes) != 0; } public static uint SetAttributes(this uint self, uint attributes, bool value) { if (value) { return self | attributes; } return self & ~attributes; } public static bool GetMaskedAttributes(this uint self, uint mask, uint attributes) { return (self & mask) == attributes; } public static uint SetMaskedAttributes(this uint self, uint mask, uint attributes, bool value) { if (value) { self &= ~mask; return self | attributes; } return self & ~(mask & attributes); } public static bool GetAttributes(this ushort self, ushort attributes) { return (self & attributes) != 0; } public static ushort SetAttributes(this ushort self, ushort attributes, bool value) { if (value) { return (ushort)(self | attributes); } return (ushort)(self & ~attributes); } public static bool GetMaskedAttributes(this ushort self, ushort mask, uint attributes) { return (self & mask) == attributes; } public static ushort SetMaskedAttributes(this ushort self, ushort mask, uint attributes, bool value) { if (value) { self = (ushort)(self & ~mask); return (ushort)(self | attributes); } return (ushort)(self & ~(mask & attributes)); } public static bool HasImplicitThis(this IMethodSignature self) { if (self.HasThis) { return !self.ExplicitThis; } return false; } public static void MethodSignatureFullName(this IMethodSignature self, StringBuilder builder) { builder.Append("("); if (self.HasParameters) { Collection<ParameterDefinition> parameters = self.Parameters; for (int i = 0; i < parameters.Count; i++) { ParameterDefinition parameterDefinition = parameters[i]; if (i > 0) { builder.Append(","); } if (parameterDefinition.ParameterType.IsSentinel) { builder.Append("...,"); } builder.Append(parameterDefinition.ParameterType.FullName); } } builder.Append(")"); } public static void CheckModule(ModuleDefinition module) { if (module == null) { throw new ArgumentNullException(Argument.module.ToString()); } } public static bool TryGetAssemblyNameReference(this ModuleDefinition module, AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference) { Collection<AssemblyNameReference> assemblyReferences = module.AssemblyReferences; for (int i = 0; i < assemblyReferences.Count; i++) { AssemblyNameReference assemblyNameReference = assemblyReferences[i]; if (Equals(name_reference, assemblyNameReference)) { assembly_reference = assemblyNameReference; return true; } } assembly_reference = null; return false; } private static bool Equals(byte[] a, byte[] b) { if (a == b) { return true; } if (a == null) { return false; } if (a.Length != b.Length) { return false; } for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) { return false; } } return true; } private static bool Equals<T>(T a, T b) where T : class, IEquatable<T> { if (a == b) { return true; } return a?.Equals(b) ?? false; } private static bool Equals(AssemblyNameReference a, AssemblyNameReference b) { if (a == b) { return true; } if (a.Name != b.Name) { return false; } if (!Equals(a.Version, b.Version)) { return false; } if (a.Culture != b.Culture) { return false; } if (!Equals(a.PublicKeyToken, b.PublicKeyToken)) { return false; } return true; } public static ParameterDefinition GetParameter(this Mono.Cecil.Cil.MethodBody self, int index) { MethodDefinition method = self.method; if (method.HasThis) { if (index == 0) { return self.ThisParameter; } index--; } Collection<ParameterDefinition> parameters = method.Parameters; if (index < 0 || index >= parameters.size) { return null; } return parameters[index]; } public static VariableDefinition GetVariable(this Mono.Cecil.Cil.MethodBody self, int index) { Collection<VariableDefinition> variables = self.Variables; if (index < 0 || index >= variables.size) { return null; } return variables[index]; } public static bool GetSemantics(this MethodDefinition self, MethodSemanticsAttributes semantics) { return (self.SemanticsAttributes & semantics) != 0; } public static void SetSemantics(this MethodDefinition self, MethodSemanticsAttributes semantics, bool value) { if (value) { self.SemanticsAttributes |= semantics; } else { self.SemanticsAttributes &= (MethodSemanticsAttributes)(ushort)(~(int)semantics); } } public static bool IsVarArg(this IMethodSignature self) { return self.CallingConvention == MethodCallingConvention.VarArg; } public static int GetSentinelPosition(this IMethodSignature self) { if (!self.HasParameters) { return -1; } Collection<ParameterDefinition> parameters = self.Parameters; for (int i = 0; i < parameters.Count; i++) { if (parameters[i].ParameterType.IsSentinel) { return i; } } return -1; } public static void CheckName(object name) { if (name == null) { throw new ArgumentNullException(Argument.name.ToString()); } } public static void CheckName(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullOrEmptyException(Argument.name.ToString()); } } public static void CheckFileName(string fileName) { if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullOrEmptyException(Argument.fileName.ToString()); } } public static void CheckFullName(string fullName) { if (string.IsNullOrEmpty(fullName)) { throw new ArgumentNullOrEmptyException(Argument.fullName.ToString()); } } public static void CheckStream(object stream) { if (stream == null) { throw new ArgumentNullException(Argument.stream.ToString()); } } public static void CheckWriteSeek(Stream stream) { if (!stream.CanWrite || !stream.CanSeek) { throw new ArgumentException("Stream must be writable and seekable."); } } public static void CheckReadSeek(Stream stream) { if (!stream.CanRead || !stream.CanSeek) { throw new ArgumentException("Stream must be readable and seekable."); } } public static void CheckType(object type) { if (type == null) { throw new ArgumentNullException(Argument.type.ToString()); } } public static void CheckType(object type, Argument argument) { if (type == null) { throw new ArgumentNullException(argument.ToString()); } } public static void CheckField(object field) { if (field == null) { throw new ArgumentNullException(Argument.field.ToString()); } } public static void CheckMethod(object method) { if (method == null) { throw new ArgumentNullException(Argument.method.ToString()); } } public static void CheckParameters(object parameters) { if (parameters == null) { throw new ArgumentNullException(Argument.parameters.ToString()); } } public static uint GetTimestamp() { return (uint)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; } public static bool HasImage(this ModuleDefinition self) { return self?.HasImage ?? false; } public static string GetFileName(this Stream self) { if (!(self is FileStream fileStream)) { return string.Empty; } return Path.GetFullPath(fileStream.Name); } public static TargetRuntime ParseRuntime(this string self) { if (string.IsNullOrEmpty(self)) { return TargetRuntime.Net_4_0; } switch (self[1]) { case '1': if (self[3] != '0') { return TargetRuntime.Net_1_1; } return TargetRuntime.Net_1_0; case '2': return TargetRuntime.Net_2_0; default: return TargetRuntime.Net_4_0; } } public static string RuntimeVersionString(this TargetRuntime runtime) { return runtime switch { TargetRuntime.Net_1_0 => "v1.0.3705", TargetRuntime.Net_1_1 => "v1.1.4322", TargetRuntime.Net_2_0 => "v2.0.50727", _ => "v4.0.30319", }; } public static bool IsWindowsMetadata(this ModuleDefinition module) { return module.MetadataKind != MetadataKind.Ecma335; } public static byte[] ReadAll(this Stream self) { MemoryStream memoryStream = new MemoryStream((int)self.Length); byte[] array = new byte[1024]; int count; while ((count = self.Read(array, 0, array.Length)) != 0) { memoryStream.Write(array, 0, count); } return memoryStream.ToArray(); } public static void Read(object o) { } public static bool GetHasSecurityDeclarations(this ISecurityDeclarationProvider self, ModuleDefinition module) { if (module.HasImage()) { return module.Read(self, (ISecurityDeclarationProvider provider, MetadataReader reader) => reader.HasSecurityDeclarations(provider)); } return false; } public static Collection<SecurityDeclaration> GetSecurityDeclarations(this ISecurityDeclarationProvider self, ref Collection<SecurityDeclaration> variable, ModuleDefinition module) { if (module.HasImage) { return module.Read(ref variable, self, (ISecurityDeclarationProvider provider, MetadataReader reader) => reader.ReadSecurityDeclarations(provider)); } Interlocked.CompareExchange(ref variable, new Collection<SecurityDeclaration>(), null); return variable; } public static TypeReference GetEnumUnderlyingType(this TypeDefinition self) { Collection<FieldDefinition> fields = self.Fields; for (int i = 0; i < fields.Count; i++) { FieldDefinition fieldDefinition = fields[i]; if (!fieldDefinition.IsStatic) { return fieldDefinition.FieldType; } } throw new ArgumentException(); } public static TypeDefinition GetNestedType(this TypeDefinition self, string fullname) { if (!self.HasNestedTypes) { return null; } Collection<TypeDefinition> nestedTypes = self.NestedTypes; for (int i = 0; i < nestedTypes.Count; i++) { TypeDefinition typeDefinition = nestedTypes[i]; if (typeDefinition.TypeFullName() == fullname) { return typeDefinition; } } return null; } public static bool IsPrimitive(this ElementType self) { if (self - 2 <= ElementType.U8 || self - 24 <= ElementType.Void) { return true; } return false; } public static string TypeFullName(this TypeReference self) { if (!string.IsNullOrEmpty(self.Namespace)) { return self.Namespace + "." + self.Name; } return self.Name; } public static bool IsTypeOf(this TypeReference self, string @namespace, string name) { if (self.Name == name) { return self.Namespace == @namespace; } return false; } public static bool IsTypeSpecification(this TypeReference type) { switch (type.etype) { case ElementType.Ptr: case ElementType.ByRef: case ElementType.Var: case ElementType.Array: case ElementType.GenericInst: case ElementType.FnPtr: case ElementType.SzArray: case ElementType.MVar: case ElementType.CModReqD: case ElementType.CModOpt: case ElementType.Sentinel: case ElementType.Pinned: return true; default: return false; } } public static TypeDefinition CheckedResolve(this TypeReference self) { return self.Resolve() ?? throw new ResolutionException(self); } public static bool TryGetCoreLibraryReference(this ModuleDefinition module, out AssemblyNameReference reference) { Collection<AssemblyNameReference> assemblyReferences = module.AssemblyReferences; for (int i = 0; i < assemblyReferences.Count; i++) { reference = assemblyReferences[i]; if (IsCoreLibrary(reference)) { return true; } } reference = null; return false; } public static bool IsCoreLibrary(this ModuleDefinition module) { if (module.Assembly == null) { return false; } if (!IsCoreLibrary(module.Assembly.Name)) { return false; } if (module.HasImage && module.Read(module, (ModuleDefinition m, MetadataReader reader) => reader.image.GetTableLength(Table.AssemblyRef) > 0)) { return false; } return true; } public static void KnownValueType(this TypeReference type) { if (!type.IsDefinition) { type.IsValueType = true; } } private static bool IsCoreLibrary(AssemblyNameReference reference) { string name = reference.Name; switch (name) { default: return name == "netstandard"; case "mscorlib": case "System.Runtime": case "System.Private.CoreLib": return true; } } public static ImageDebugHeaderEntry GetCodeViewEntry(this ImageDebugHeader header) { return header.GetEntry(ImageDebugType.CodeView); } public static ImageDebugHeaderEntry GetDeterministicEntry(this ImageDebugHeader header) { return header.GetEntry(ImageDebugType.Deterministic); } public static ImageDebugHeader AddDeterministicEntry(this ImageDebugHeader header) { ImageDebugDirectory directory = default(ImageDebugDirectory); directory.Type = ImageDebugType.Deterministic; ImageDebugHeaderEntry imageDebugHeaderEntry = new ImageDebugHeaderEntry(directory, Empty<byte>.Array); if (header == null) { return new ImageDebugHeader(imageDebugHeaderEntry); } ImageDebugHeaderEntry[] array = new ImageDebugHeaderEntry[header.Entries.Length + 1]; Array.Copy(header.Entries, array, header.Entries.Length); array[^1] = imageDebugHeaderEntry; return new ImageDebugHeader(array); } public static ImageDebugHeaderEntry GetEmbeddedPortablePdbEntry(this ImageDebugHeader header) { return header.GetEntry(ImageDebugType.EmbeddedPortablePdb); } public static ImageDebugHeaderEntry GetPdbChecksumEntry(this ImageDebugHeader header) { return header.GetEntry(ImageDebugType.PdbChecksum); } private static ImageDebugHeaderEntry GetEntry(this ImageDebugHeader header, ImageDebugType type) { if (!header.HasEntries) { return null; } for (int i = 0; i < header.Entries.Length; i++) { ImageDebugHeaderEntry imageDebugHeaderEntry = header.Entries[i]; if (imageDebugHeaderEntry.Directory.Type == type) { return imageDebugHeaderEntry; } } return null; } public static string GetPdbFileName(string assemblyFileName) { return Path.ChangeExtension(assemblyFileName, ".pdb"); } public static string GetMdbFileName(string assemblyFileName) { return assemblyFileName + ".mdb"; } public static bool IsPortablePdb(string fileName) { using FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); return IsPortablePdb(stream); } public static bool IsPortablePdb(Stream stream) { if (stream.Length < 4) { return false; } long position = stream.Position; try { return new BinaryReader(stream).ReadUInt32() == 1112167234; } finally { stream.Position = position; } } public static bool GetHasCustomDebugInformations(this ICustomDebugInformationProvider self, ref Collection<CustomDebugInformation> collection, ModuleDefinition module) { if (module.HasImage()) { module.Read(ref collection, self, (ICustomDebugInformationProvider provider, MetadataReader reader) => reader.module.symbol_reader?.Read(provider)); } return !collection.IsNullOrEmpty(); } public static Collection<CustomDebugInformation> GetCustomDebugInformations(this ICustomDebugInformationProvider self, ref Collection<CustomDebugInformation> collection, ModuleDefinition module) { if (module.HasImage()) { module.Read(ref collection, self, (ICustomDebugInformationProvider provider, MetadataReader reader) => reader.module.symbol_reader?.Read(provider)); } Interlocked.CompareExchange(ref collection, new Collection<CustomDebugInformation>(), null); return collection; } public static uint ReadCompressedUInt32(this byte[] data, ref int position) { uint result; if ((data[position] & 0x80) == 0) { result = data[position]; position++; } else if ((data[position] & 0x40) == 0) { result = (uint)((data[position] & -129) << 8); result |= data[position + 1]; position += 2; } else { result = (uint)((data[position] & -193) << 24); result |= (uint)(data[position + 1] << 16); result |= (uint)(data[position + 2] << 8); result |= data[position + 3]; position += 4; } return result; } public static MetadataToken GetMetadataToken(this CodedIndex self, uint data) { uint rid; TokenType type; switch (self) { case CodedIndex.TypeDefOrRef: rid = data >> 2; switch (data & 3) { case 0u: break; case 1u: goto IL_006d; case 2u: goto IL_0078; default: goto end_IL_0001; } type = TokenType.TypeDef; goto IL_05b3; case CodedIndex.HasConstant: rid = data >> 2; switch (data & 3) { case 0u: break; case 1u: goto IL_00ad; case 2u: goto IL_00b8; default: goto end_IL_0001; } type = TokenType.Field; goto IL_05b3; case CodedIndex.HasCustomAttribute: rid = data >> 5; switch (data & 0x1F) { case 0u: break; case 1u: goto IL_013a; case 2u: goto IL_0145; case 3u: goto IL_0150; case 4u: goto IL_015b; case 5u: goto IL_0166; case 6u: goto IL_0171; case 7u: goto IL_017c; case 8u: goto IL_0183; case 9u: goto IL_018e; case 10u: goto IL_0199; case 11u: goto IL_01a4; case 12u: goto IL_01af; case 13u: goto IL_01ba; case 14u: goto IL_01c5; case 15u: goto IL_01d0; case 16u: goto IL_01db; case 17u: goto IL_01e6; case 18u: goto IL_01f1; case 19u: goto IL_01fc; case 20u: goto IL_0207; case 21u: goto IL_0212; default: goto end_IL_0001; } type = TokenType.Method; goto IL_05b3; case CodedIndex.HasFieldMarshal: { rid = data >> 1; uint num = data & 1u; if (num != 0) { if (num != 1) { break; } type = TokenType.Param; } else { type = TokenType.Field; } goto IL_05b3; } case CodedIndex.HasDeclSecurity: rid = data >> 2; switch (data & 3) { case 0u: break; case 1u: goto IL_0271; case 2u: goto IL_027c; default: goto end_IL_0001; } type = TokenType.TypeDef; goto IL_05b3; case CodedIndex.MemberRefParent: rid = data >> 3; switch (data & 7) { case 0u: break; case 1u: goto IL_02b9; case 2u: goto IL_02c4; case 3u: goto IL_02cf; case 4u: goto IL_02da; default: goto end_IL_0001; } type = TokenType.TypeDef; goto IL_05b3; case CodedIndex.HasSemantics: { rid = data >> 1; uint num = data & 1u; if (num != 0) { if (num != 1) { break; } type = TokenType.Property; } else { type = TokenType.Event; } goto IL_05b3; } case CodedIndex.MethodDefOrRef: { rid = data >> 1; uint num = data & 1u; if (num != 0) { if (num != 1) { break; } type = TokenType.MemberRef; } else { type = TokenType.Method; } goto IL_05b3; } case CodedIndex.MemberForwarded: { rid = data >> 1; uint num = data & 1u; if (num != 0) { if (num != 1) { break; } type = TokenType.Method; } else { type = TokenType.Field; } goto IL_05b3; } case CodedIndex.Implementation: rid = data >> 2; switch (data & 3) { case 0u: break; case 1u: goto IL_038d; case 2u: goto IL_0398; default: goto end_IL_0001; } type = TokenType.File; goto IL_05b3; case CodedIndex.CustomAttributeType: { rid = data >> 3; uint num = data & 7u; if (num != 2) { if (num != 3) { break; } type = TokenType.MemberRef; } else { type = TokenType.Method; } goto IL_05b3; } case CodedIndex.ResolutionScope: rid = data >> 2; switch (data & 3) { case 0u: break; case 1u: goto IL_03f8; case 2u: goto IL_0403; case 3u: goto IL_040e; default: goto end_IL_0001; } type = TokenType.Module; goto IL_05b3; case CodedIndex.TypeOrMethodDef: { rid = data >> 1; uint num = data & 1u; if (num != 0) { if (num != 1) { break; } type = TokenType.Method; } else { type = TokenType.TypeDef; } goto IL_05b3; } case CodedIndex.HasCustomDebugInformation: { rid = data >> 5; switch (data & 0x1F) { case 0u: break; case 1u: goto IL_04ce; case 2u: goto IL_04d9; case 3u: goto IL_04e4; case 4u: goto IL_04ef; case 5u: goto IL_04fa; case 6u: goto IL_0505; case 7u: goto IL_0510; case 8u: goto IL_0517; case 9u: goto IL_0522; case 10u: goto IL_052d; case 11u: goto IL_0535; case 12u: goto IL_053d; case 13u: goto IL_0545; case 14u: goto IL_054d; case 15u: goto IL_0555; case 16u: goto IL_055d; case 17u: goto IL_0565; case 18u: goto IL_056d; case 19u: goto IL_0575; case 20u: goto IL_057d; case 21u: goto IL_0585; case 22u: goto IL_058d; case 23u: goto IL_0595; case 24u: goto IL_059d; case 25u: goto IL_05a5; case 26u: goto IL_05ad; default: goto end_IL_0001; } type = TokenType.Method; goto IL_05b3; } IL_05ad: type = TokenType.ImportScope; goto IL_05b3; IL_05a5: type = TokenType.LocalConstant; goto IL_05b3; IL_059d: type = TokenType.LocalVariable; goto IL_05b3; IL_0595: type = TokenType.LocalScope; goto IL_05b3; IL_058d: type = TokenType.Document; goto IL_05b3; IL_0585: type = TokenType.MethodSpec; goto IL_05b3; IL_057d: type = TokenType.GenericParamConstraint; goto IL_05b3; IL_0575: type = TokenType.GenericParam; goto IL_05b3; IL_056d: type = TokenType.ManifestResource; goto IL_05b3; IL_0565: type = TokenType.ExportedType; goto IL_05b3; IL_055d: type = TokenType.File; goto IL_05b3; IL_0555: type = TokenType.AssemblyRef; goto IL_05b3; IL_054d: type = TokenType.Assembly; goto IL_05b3; IL_0545: type = TokenType.TypeSpec; goto IL_05b3; IL_053d: type = TokenType.ModuleRef; goto IL_05b3; IL_0535: type = TokenType.Signature; goto IL_05b3; IL_052d: type = TokenType.Event; goto IL_05b3; IL_0522: type = TokenType.Property; goto IL_05b3; IL_0517: type = TokenType.Permission; goto IL_05b3; IL_0510: type = TokenType.Module; goto IL_05b3; IL_0505: type = TokenType.MemberRef; goto IL_05b3; IL_04fa: type = TokenType.InterfaceImpl; goto IL_05b3; IL_04ef: type = TokenType.Param; goto IL_05b3; IL_04e4: type = TokenType.TypeDef; goto IL_05b3; IL_04d9: type = TokenType.TypeRef; goto IL_05b3; IL_04ce: type = TokenType.Field; goto IL_05b3; IL_01db: type = TokenType.File; goto IL_05b3; IL_01d0: type = TokenType.AssemblyRef; goto IL_05b3; IL_01ba: type = TokenType.TypeSpec; goto IL_05b3; IL_01c5: type = TokenType.Assembly; goto IL_05b3; IL_040e: type = TokenType.TypeRef; goto IL_05b3; IL_0403: type = TokenType.AssemblyRef; goto IL_05b3; IL_03f8: type = TokenType.ModuleRef; goto IL_05b3; IL_01af: type = TokenType.ModuleRef; goto IL_05b3; IL_01a4: type = TokenType.Signature; goto IL_05b3; IL_018e: type = TokenType.Property; goto IL_05b3; IL_0199: type = TokenType.Event; goto IL_05b3; IL_0398: type = TokenType.ExportedType; goto IL_05b3; IL_038d: type = TokenType.AssemblyRef; goto IL_05b3; IL_0183: type = TokenType.Permission; goto IL_05b3; IL_017c: type = TokenType.Module; goto IL_05b3; IL_0166: type = TokenType.InterfaceImpl; goto IL_05b3; IL_0171: type = TokenType.MemberRef; goto IL_05b3; IL_015b: type = TokenType.Param; goto IL_05b3; IL_0145: type = TokenType.TypeRef; goto IL_05b3; IL_0150: type = TokenType.TypeDef; goto IL_05b3; IL_013a: type = TokenType.Field; goto IL_05b3; IL_006d: type = TokenType.TypeRef; goto IL_05b3; IL_02da: type = TokenType.TypeSpec; goto IL_05b3; IL_02cf: type = TokenType.Method; goto IL_05b3; IL_02c4: type = TokenType.ModuleRef; goto IL_05b3; IL_02b9: type = TokenType.TypeRef; goto IL_05b3; IL_00b8: type = TokenType.Property; goto IL_05b3; IL_027c: type = TokenType.Assembly; goto IL_05b3; IL_0271: type = TokenType.Method; goto IL_05b3; IL_00ad: type = TokenType.Param; goto IL_05b3; IL_05b3: return new MetadataToken(type, rid); IL_0078: type = TokenType.TypeSpec; goto IL_05b3; IL_0212: type = TokenType.MethodSpec; goto IL_05b3; IL_0207: type = TokenType.GenericParamConstraint; goto IL_05b3; IL_01fc: type = TokenType.GenericParam; goto IL_05b3; IL_01f1: type = TokenType.ManifestResource; goto IL_05b3; IL_01e6: type = TokenType.ExportedType; goto IL_05b3; end_IL_0001: break; } return MetadataToken.Zero; } public static uint CompressMetadataToken(this CodedIndex self, MetadataToken token) { uint result = 0u; if (token.RID == 0) { return result; } switch (self) { case CodedIndex.TypeDefOrRef: result = token.RID << 2; switch (token.TokenType) { case TokenType.TypeDef: return result | 0u; case TokenType.TypeRef: return result | 1u; case TokenType.TypeSpec: return result | 2u; } break; case CodedIndex.HasConstant: result = token.RID << 2; switch (token.TokenType) { case TokenType.Field: return result | 0u; case TokenType.Param: return result | 1u; case TokenType.Property: return result | 2u; } break; case CodedIndex.HasCustomAttribute: result = token.RID << 5; switch (token.TokenType) { case TokenType.Method: return result | 0u; case TokenType.Field: return result | 1u; case TokenType.TypeRef: return result | 2u; case TokenType.TypeDef: return result | 3u; case TokenType.Param: return result | 4u; case TokenType.InterfaceImpl: return result | 5u; case TokenType.MemberRef: return result | 6u; case TokenType.Module: return result | 7u; case TokenType.Permission: return result | 8u; case TokenType.Property: return result | 9u; case TokenType.Event: return result | 0xAu; case TokenType.Signature: return result | 0xBu; case TokenType.ModuleRef: return result | 0xCu; case TokenType.TypeSpec: return result | 0xDu; case TokenType.Assembly: return result | 0xEu; case TokenType.AssemblyRef: return result | 0xFu; case TokenType.File: return result | 0x10u; case TokenType.ExportedType: return result | 0x11u; case TokenType.ManifestResource: return result | 0x12u; case TokenType.GenericParam: return result | 0x13u; case TokenType.GenericParamConstraint: return result | 0x14u; case TokenType.MethodSpec: return result | 0x15u; } break; case CodedIndex.HasFieldMarshal: result = token.RID << 1; switch (token.TokenType) { case TokenType.Field: return result | 0u; case TokenType.Param: return result | 1u; } break; case CodedIndex.HasDeclSecurity: result = token.RID << 2; switch (token.TokenType) { case TokenType.TypeDef: return result | 0u; case TokenType.Method: return result | 1u; case TokenType.Assembly: return result | 2u; } break; case CodedIndex.MemberRefParent: result = token.RID << 3; switch (token.TokenType) { case TokenType.TypeDef: return result | 0u; case TokenType.TypeRef: return result | 1u; case TokenType.ModuleRef: return result | 2u; case TokenType.Method: return result | 3u; case TokenType.TypeSpec: return result | 4u; } break; case CodedIndex.HasSemantics: result = token.RID << 1; switch (token.TokenType) { case TokenType.Event: return result | 0u; case TokenType.Property: return result | 1u; } break; case CodedIndex.MethodDefOrRef: result = token.RID << 1; switch (token.TokenType) { case TokenType.Method: return result | 0u; case TokenType.MemberRef: return result | 1u; } break; case CodedIndex.MemberForwarded: result = token.RID << 1; switch (token.TokenType) { case TokenType.Field: return result | 0u; case TokenType.Method: return result | 1u; } break; case CodedIndex.Implementation: result = token.RID << 2; switch (token.TokenType) { case TokenType.File: return result | 0u; case TokenType.AssemblyRef: return result | 1u; case TokenType.ExportedType: return result | 2u; } break; case CodedIndex.CustomAttributeType: result = token.RID << 3; switch (token.TokenType) { case TokenType.Method: return result | 2u; case TokenType.MemberRef: return result | 3u; } break; case CodedIndex.ResolutionScope: result = token.RID << 2; switch (token.TokenType) { case TokenType.Module: return result | 0u; case TokenType.ModuleRef: return result | 1u; case TokenType.AssemblyRef: return result | 2u; case TokenType.TypeRef: return result | 3u; } break; case CodedIndex.TypeOrMethodDef: result = token.RID << 1; switch (token.TokenType) { case TokenType.TypeDef: return result | 0u; case TokenType.Method: return result | 1u; } break; case CodedIndex.HasCustomDebugInformation: result = token.RID << 5; switch (token.TokenType) { case TokenType.Method: return result | 0u; case TokenType.Field: return result | 1u; case TokenType.TypeRef: return result | 2u; case TokenType.TypeDef: return result | 3u; case TokenType.Param: return result | 4u; case TokenType.InterfaceImpl: return result | 5u; case TokenType.MemberRef: return result | 6u; case TokenType.Module: return result | 7u; case TokenType.Permission: return result | 8u; case TokenType.Property: return result | 9u; case TokenType.Event: return result | 0xAu; case TokenType.Signature: return result | 0xBu; case TokenType.ModuleRef: return result | 0xCu; case TokenType.TypeSpec: return result | 0xDu; case TokenType.Assembly: return result | 0xEu; case TokenType.AssemblyRef: return result | 0xFu; case TokenType.File: return result | 0x10u; case TokenType.ExportedType: return result | 0x11u; case TokenType.ManifestResource: return result | 0x12u; case TokenType.GenericParam: return result | 0x13u; case TokenType.GenericParamConstraint: return result | 0x14u; case TokenType.MethodSpec: return result | 0x15u; case TokenType.Document: return result | 0x16u; case TokenType.LocalScope: return result | 0x17u; case TokenType.LocalVariable: return result | 0x18u; case TokenType.LocalConstant: return result | 0x19u; case TokenType.ImportScope: return result | 0x1Au; } break; } throw new ArgumentException(); } public static int GetSize(this CodedIndex self, Func<Table, int> counter) { int num; Table[] array; switch (self) { case CodedIndex.TypeDefOrRef: num = 2; array = new Table[3] { Table.TypeDef, Table.TypeRef, Table.TypeSpec }; break; case CodedIndex.HasConstant: num = 2; array = new Table[3] { Table.Field, Table.Param, Table.Property }; break; case CodedIndex.HasCustomAttribute: num = 5; array = new Table[22] { Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, Table.Param, Table.InterfaceImpl, Table.MemberRef, Table.Module, Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, Table.ModuleRef, Table.TypeSpec, Table.Assembly, Table.AssemblyRef, Table.File, Table.ExportedType, Table.ManifestResource, Table.GenericParam, Table.GenericParamConstraint, Table.MethodSpec }; break; case CodedIndex.HasFieldMarshal: num = 1; array = new Table[2] { Table.Field, Table.Param }; break; case CodedIndex.HasDeclSecurity: num = 2; array = new Table[3] { Table.TypeDef, Table.Method, Table.Assembly }; break; case CodedIndex.MemberRefParent: num = 3; array = new Table[5] { Table.TypeDef, Table.TypeRef, Table.ModuleRef, Table.Method, Table.TypeSpec }; break; case CodedIndex.HasSemantics: num = 1; array = new Table[2] { Table.Event, Table.Property }; break; case CodedIndex.MethodDefOrRef: num = 1; array = new Table[2] { Table.Method, Table.MemberRef }; break; case CodedIndex.MemberForwarded: num = 1; array = new Table[2] { Table.Field, Table.Method }; break; case CodedIndex.Implementation: num = 2; array = new Table[3] { Table.File, Table.AssemblyRef, Table.ExportedType }; break; case CodedIndex.CustomAttributeType: num = 3; array = new Table[2] { Table.Method, Table.MemberRef }; break; case CodedIndex.ResolutionScope: num = 2; array = new Table[4] { Table.Module, Table.ModuleRef, Table.AssemblyRef, Table.TypeRef }; break; case CodedIndex.TypeOrMethodDef: num = 1; array = new Table[2] { Table.TypeDef, Table.Method }; break; case CodedIndex.HasCustomDebugInformation: num = 5; array = new Table[27] { Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, Table.Param, Table.InterfaceImpl, Table.MemberRef, Table.Module, Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, Table.ModuleRef, Table.TypeSpec, Table.Assembly, Table.AssemblyRef, Table.File, Table.ExportedType, Table.ManifestResource, Table.GenericParam, Table.GenericParamConstraint, Table.MethodSpec, Table.Document, Table.LocalScope, Table.LocalVariable, Table.LocalConstant, Table.ImportScope }; break; default: throw new ArgumentException(); } int num2 = 0; for (int i = 0; i < array.Length; i++) { num2 = Math.Max(counter(array[i]), num2); } if (num2 >= 1 << 16 - num) { return 4; } return 2; } public static RSA CreateRSA(this WriterParameters writer_parameters) { if (writer_parameters.StrongNameKeyBlob != null) { return CryptoConvert.FromCapiKeyBlob(writer_parameters.StrongNameKeyBlob); } string key_container; byte[] key; if (writer_parameters.StrongNameKeyContainer != null) { key_container = writer_parameters.StrongNameKeyContainer; } else if (!TryGetKeyContainer(writer_parameters.StrongNameKeyPair, out key, out key_container)) { return CryptoConvert.FromCapiKeyBlob(key); } return new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore, KeyContainerName = key_container, KeyNumber = 2 }); } private static bool TryGetKeyContainer(ISerializable key_pair, out byte[] key, out string key_container) { SerializationInfo serializationInfo = new SerializationInfo(typeof(StrongNameKeyPair), new FormatterConverter()); key_pair.GetObjectData(serializationInfo, default(StreamingContext)); key = (byte[])serializationInfo.GetValue("_keyPairArray", typeof(byte[])); key_container = serializationInfo.GetString("_keyPairContainer"); return key_container != null; } } public struct ArrayDimension { private int? lower_bound; private int? upper_bound; public int? LowerBound { get { return lower_bound; } set { lower_bound = value; } } public int? UpperBound { get { return upper_bound; } set { upper_bound = value; } } public bool IsSized { get { if (!lower_bound.HasValue) { return upper_bound.HasValue; } return true; } } public ArrayDimension(int? lowerBound, int? upperBound) { lower_bound = lowerBound; upper_bound = upperBound; } public override string ToString() { if (IsSized) { int? num = lower_bound; string? text = num.ToString(); num = upper_bound; return text + "..." + num; } return string.Empty; } } public sealed class ArrayType : TypeSpecification { private Collection<ArrayDimension> dimensions; public Collection<ArrayDimension> Dimensions { get { if (dimensions != null) { return dimensions; } Collection<ArrayDimension> collection = new Collection<ArrayDimension>(); collection.Add(default(ArrayDimension)); Interlocked.CompareExchange(ref dimensions, collection, null); return dimensions; } } public int Rank { get { if (dimensions != null) { return dimensions.Count; } return 1; } } public bool IsVector { get { if (dimensions == null) { return true; } if (dimensions.Count > 1) { return false; } return !dimensions[0].IsSized; } } public override bool IsValueType { get { return false; } set { throw new InvalidOperationException(); } } public override string Name => base.Name + Suffix; public override string FullName => base.FullName + Suffix; private string Suffix { get { if (IsVector) { return "[]"; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("["); for (int i = 0; i < dimensions.Count; i++) { if (i > 0) { stringBuilder.Append(","); } stringBuilder.Append(dimensions[i].ToString()); } stringBuilder.Append("]"); return stringBuilder.ToString(); } } public override bool IsArray => true; public ArrayType(TypeReference type) : base(type) { Mixin.CheckType(type); etype = Mono.Cecil.Metadata.ElementType.Array; } public ArrayType(TypeReference type, int rank) : this(type) { Mixin.CheckType(type); if (rank != 1) { dimensions = new Collection<ArrayDimension>(rank); for (int i = 0; i < rank; i++) { dimensions.Add(default(ArrayDimension)); } etype = Mono.Cecil.Metadata.ElementType.Array; } } } public sealed class AssemblyDefinition : ICustomAttributeProvider, IMetadataTokenProvider, ISecurityDeclarationProvider, IDisposable { private AssemblyNameDefinition name; internal ModuleDefinition main_module; private Collection<ModuleDefinition> modules; private Collection<CustomAttribute> custom_attributes; private Collection<SecurityDeclaration> security_declarations; public AssemblyNameDefinition Name { get { return name; } set { name = value; } } public string FullName { get { if (name == null) { return string.Empty; } return name.FullName; } } public MetadataToken MetadataToken { get { return new MetadataToken(TokenType.Assembly, 1); } set { } } public Collection<ModuleDefinition> Modules { get { if (modules != null) { return modules; } if (main_module.HasImage) { return main_module.Read(ref modules, this, (AssemblyDefinition _, MetadataReader reader) => reader.ReadModules()); } Interlocked.CompareExchange(ref modules, new Collection<ModuleDefinition>(1) { main_module }, null); return modules; } } public ModuleDefinition MainModule => main_module; public MethodDefinition EntryPoint { get { return main_module.EntryPoint; } set { main_module.EntryPoint = value; } } public bool HasCustomAttributes { get { if (custom_attributes != null) { return custom_attributes.Count > 0; } return this.GetHasCustomAttributes(main_module); } } public Collection<CustomAttribute> CustomAttributes => custom_attributes ?? this.GetCustomAttributes(ref custom_attributes, main_module); public bool HasSecurityDeclarations { get { if (security_declarations != null) { return security_declarations.Count > 0; } return this.GetHasSecurityDeclarations(main_module); } } public Collection<SecurityDeclaration> SecurityDeclarations => security_declarations ?? this.GetSecurityDeclarations(ref security_declarations, main_module); internal AssemblyDefinition() { } public void Dispose() { if (modules == null) { main_module.Dispose(); return; } Collection<ModuleDefinition> collection = Modules; for (int i = 0; i < collection.Count; i++) { collection[i].Dispose(); } } public static AssemblyDefinition CreateAssembly(AssemblyNameDefinition assemblyName, string moduleName, ModuleKind kind) { return CreateAssembly(assemblyName, moduleName, new ModuleParameters { Kind = kind }); } public static AssemblyDefinition CreateAssembly(AssemblyNameDefinition assemblyName, string moduleName, ModuleParameters parameters) { if (assemblyName == null) { throw new ArgumentNullException("assemblyName"); } if (moduleName == null) { throw new ArgumentNullException("moduleName"); } Mixin.CheckParameters(parameters); if (parameters.Kind == ModuleKind.NetModule) { throw new ArgumentException("kind"); } AssemblyDefinition assembly = ModuleDefinition.CreateModule(moduleName, parameters).Assembly; assembly.Name = assemblyName; return assembly; } public static AssemblyDefinition ReadAssembly(string fileName) { return ReadAssembly(ModuleDefinition.ReadModule(fileName)); } public static AssemblyDefinition ReadAssembly(string fileName, ReaderParameters parameters) { return ReadAssembly(ModuleDefinition.ReadModule(fileName, parameters)); } public static AssemblyDefinition ReadAssembly(Stream stream) { return ReadAssembly(ModuleDefinition.ReadModule(stream)); } public static AssemblyDefinition ReadAssembly(Stream stream, ReaderParameters parameters) { return ReadAssembly(ModuleDefinition.ReadModule(stream, parameters)); } private static AssemblyDefinition ReadAssembly(ModuleDefinition module) { return module.Assembly ?? throw new ArgumentException(); } public void Write(string fileName) { Write(fileName, new WriterParameters()); } public void Write(string fileName, WriterParameters parameters) { main_module.Write(fileName, parameters); } public void Write() { main_module.Write(); } public void Write(WriterParameters parameters) { main_module.Write(parameters); } public void Write(Stream stream) { Write(stream, new WriterParameters()); } public void Write(Stream stream, WriterParameters parameters) { main_module.Write(stream, parameters); } public override string ToString() { return FullName; } } [Flags] public enum AssemblyAttributes : uint { PublicKey = 1u, SideBySideCompatible = 0u, Retargetable = 0x100u, WindowsRuntime = 0x200u, DisableJITCompileOptimizer = 0x4000u, EnableJITCompileTracking = 0x8000u } public enum AssemblyHashAlgorithm : uint { None = 0u, MD5 = 32771u, SHA1 = 32772u, SHA256 = 32780u, SHA384 = 32781u, SHA512 = 32782u, Reserved = 32771u } public sealed class AssemblyLinkedResource : Resource { private AssemblyNameReference reference; public AssemblyNameReference Assembly { get { return reference; } set { reference = value; } } public override ResourceType ResourceType => ResourceType.AssemblyLinked; public AssemblyLinkedResource(string name, ManifestResourceAttributes flags) : base(name, flags) { } public AssemblyLinkedResource(string name, ManifestResourceAttributes flags, AssemblyNameReference reference) : base(name, flags) { this.reference = reference; } } public sealed class AssemblyNameDefinition : AssemblyNameReference { public override byte[] Hash => Empty<byte>.Array; internal AssemblyNameDefinition() { token = new MetadataToken(TokenType.Assembly, 1); } public AssemblyNameDefinition(string name, Version version) : base(name, version) { token = new MetadataToken(TokenType.Assembly, 1); } } public class AssemblyNameReference : IMetadataScope, IMetadataTokenProvider { private string name; private string culture; private Version version; private uint attributes; private byte[] public_key; private byte[] public_key_token; private AssemblyHashAlgorithm hash_algorithm; private byte[] hash; internal MetadataToken token; private string full_name; public string Name { get { return name; } set { name = value; full_name = null; } } public string Culture { get { return culture; } set { culture = value; full_name = null; } } public Version Version { get { return version; } set { version = Mixin.CheckVersion(value); full_name = null; } } public AssemblyAttributes Attributes { get { return (AssemblyAttributes)attributes; } set { attributes = (uint)value; } } public bool HasPublicKey { get { return attributes.GetAttributes(1u); } set { attributes = attributes.SetAttributes(1u, value); } } public bool IsSideBySideCompatible { get { return attributes.GetAttributes(0u); } set { attributes = attributes.SetAttributes(0u, value); } } public bool IsRetargetable { get { return attributes.GetAttributes(256u); } set { attributes = attributes.SetAttributes(256u, value); } } public bool IsWindowsRuntime { get { return attributes.GetAttributes(512u); } set { attributes = attributes.SetAttributes(512u, value); } } public byte[] PublicKey { get { return public_key ?? Empty<byte>.Array; } set { public_key = value; HasPublicKey = !public_key.IsNullOrEmpty(); public_key_token = null; full_name = null; } } public byte[] PublicKeyToken { get { if (public_key_token == null && !public_key.IsNullOrEmpty()) { byte[] array = HashPublicKey(); byte[] array2 = new byte[8]; Array.Copy(array, array.Length - 8, array2, 0, 8); Array.Reverse((Array)array2, 0, 8); Interlocked.CompareExchange(ref public_key_token, array2, null); } return public_key_token ?? Empty<byte>.Array; } set { public_key_token = value; full_name = null; } } public virtual MetadataScopeType MetadataScopeType => MetadataScopeType.AssemblyNameReference; public string FullName { get { if (full_name != null) { return full_name; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(name); stringBuilder.Append(", "); stringBuilder.Append("Version="); stringBuilder.Append(version.ToString(4)); stringBuilder.Append(", "); stringBuilder.Append("Culture="); stringBuilder.Append(string.IsNullOrEmpty(culture) ? "neutral" : culture); stringBuilder.Append(", "); stringBuilder.Append("PublicKeyToken="); byte[] publicKeyToken = PublicKeyToken; if (!publicKeyToken.IsNullOrEmpty() && publicKeyToken.Length != 0) { for (int i = 0; i < publicKeyToken.Length; i++) { stringBuilder.Append(publicKeyToken[i].ToString("x2")); } } else { stringBuilder.Append("null"); } if (IsRetargetable) { stringBuilder.Append(", "); stringBuilder.Append("Retargetable=Yes"); } Interlocked.CompareExchange(ref full_name, stringBuilder.ToString(), null); return full_name; } } public AssemblyHashAlgorithm HashAlgorithm { get { return hash_algorithm; } set { hash_algorithm = value; } } public virtual byte[] Hash { get { return hash; } set { hash = value; } } public MetadataToken MetadataToken { get { return token; } set { token = value; } } private byte[] HashPublicKey() { HashAlgorithm hashAlgorithm = ((hash_algorithm != AssemblyHashAlgorithm.MD5) ? ((HashAlgorithm)SHA1.Create()) : ((HashAlgorithm)MD5.Create())); using (hashAlgorithm) { return hashAlgorithm.ComputeHash(public_key); } } public static AssemblyNameReference Parse(string fullName) { if (fullName == null) { throw new ArgumentNullException("fullName"); } if (fullName.Length == 0) { throw new ArgumentException("Name can not be empty"); } AssemblyNameReference assemblyNameReference = new AssemblyNameReference(); string[] array = fullName.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (i == 0) { assemblyNameReference.Name = text; continue; } string[] array2 = text.Split(new char[1] { '=' }); if (array2.Length != 2) { throw new ArgumentException("Malformed name"); } switch (array2[0].ToLowerInvariant()) { case "version": assemblyNameReference.Version = new Version(array2[1]); break; case "culture": assemblyNameReference.Culture = ((array2[1] == "neutral") ? "" : array2[1]); break; case "publickeytoken": { string text2 = array2[1]; if (!(text2 == "null")) { assemblyNameReference.PublicKeyToken = new byte[text2.Length / 2]; for (int j = 0; j < assemblyNameReference.PublicKeyToken.Length; j++) { assemblyNameReference.PublicKeyToken[j] = byte.Parse(text2.Substring(j * 2, 2), NumberStyles.HexNumber); } } break; } } } return assemblyNameReference; } internal AssemblyNameReference() { version = Mixin.ZeroVersion; token = new MetadataToken(TokenType.AssemblyRef); } public AssemblyNameReference(string name, Version version) { Mixin.CheckName(name); this.name = name; this.version = Mixin.CheckVersion(version); hash_algorithm = AssemblyHashAlgorithm.None; token = new MetadataToken(TokenType.AssemblyRef); } public override string ToString() { return FullName; } } internal abstract class ModuleReader { protected readonly ModuleDefinition module; protected ModuleReader(Image image, ReadingMode mode) { module = new ModuleDefinition(image); module.ReadingMode = mode; } protected abstract void ReadModule(); public abstract void ReadSymbols(ModuleDefinition module); protected void ReadModuleManifest(MetadataReader reader) { reader.Populate(module); ReadAssembly(reader); } private void ReadAssembly(MetadataReader reader) { AssemblyNameDefinition assemblyNameDefinition = reader.ReadAssemblyNameDefinition(); if (assemblyNameDefinition == null) { module.kind = ModuleKind.NetModule; return; } AssemblyDefinition assemblyDefinition = new AssemblyDefinition(); assemblyDefinition.Name = assemblyNameDefinition; module.assembly = assemblyDefinition; assemblyDefinition.main_module = module; } public static ModuleDefinition CreateModule(Image image, ReaderParameters parameters) { ModuleReader moduleReader = CreateModuleReader(image, parameters.ReadingMode); ModuleDefinition moduleDefinition = moduleReader.module; if (parameters.assembly_resolver != null) { moduleDefinition.assembly_resolver = Disposable.NotOwned(parameters.assembly_resolver); } if (parameters.metadata_resolver != null) { moduleDefinition.metadata_resolver = parameters.metadata_resolver; } if (parameters.metadata_importer_provider != null) { moduleDefinition.metadata_importer = parameters.metadata_importer_provider.GetMetadataImporter(moduleDefinition); } if (parameters.reflection_importer_provider != null) { moduleDefinition.reflection_importer = parameters.reflection_importer_provider.GetReflectionImporter(moduleDefinition); } GetMetadataKind(moduleDefinition, parameters); moduleReader.ReadModule(); ReadSymbols(moduleDefinition, parameters); moduleReader.ReadSymbols(moduleDefinition); if (parameters.ReadingMode == ReadingMode.Immediate) { moduleDefinition.MetadataSystem.Clear(); } return moduleDefinition; } private static void ReadSymbols(ModuleDefinition module, ReaderParameters parameters) { ISymbolReaderProvider symbolReaderProvider = parameters.SymbolReaderProvider; if (symbolReaderProvider == null && parameters.ReadSymbols) { symbolReaderProvider = new DefaultSymbolReaderProvider(); } if (symbolReaderProvider != null) { module.SymbolReaderProvider = symbolReaderProvider; ISymbolReader symbolReader = ((parameters.SymbolStream != null) ? symbolReaderProvider.GetSymbolReader(module, parameters.SymbolStream) : symbolReaderProvider.GetSymbolReader(module, module.FileName)); if (symbolReader != null) { try { module.ReadSymbols(symbolReader, parameters.ThrowIfSymbolsAreNotMatching); } catch (Exception) { symbolReader.Dispose(); throw; } } } if (module.Image.HasDebugTables()) { module.ReadSymbols(new PortablePdbReader(module.Image, module)); } } private static void GetMetadataKind(ModuleDefinition module, ReaderParameters parameters) { if (!parameters.ApplyWindowsRuntimeProjections) { module.MetadataKind = MetadataKind.Ecma335; return; } string runtimeVersion = module.RuntimeVersion; if (!runtimeVersion.Contains("WindowsRuntime")) { module.MetadataKind = MetadataKind.Ecma335; } else if (runtimeVersion.Contains("CLR")) { module.MetadataKind = MetadataKind.ManagedWindowsMetadata; } else { module.MetadataKind = MetadataKind.WindowsMetadata; } } private static ModuleReader CreateModuleReader(Image image, ReadingMode mode) { return mode switch { ReadingMode.Immediate => new ImmediateModuleReader(image), ReadingMode.Deferred => new DeferredModuleReader(image), _ => throw new ArgumentException(), }; } } internal sealed class ImmediateModuleReader : ModuleReader { private bool resolve_attributes; public ImmediateModuleReader(Image image) : base(image, ReadingMode.Immediate) { } protected override void ReadModule() { module.Read(module, delegate(ModuleDefinition module, MetadataReader reader) { ReadModuleManifest(reader); ReadModule(module, resolve_attributes: true); }); } public void ReadModule(ModuleDefinition module, bool resolve_attributes) { this.resolve_attributes = resolve_attributes; if (module.HasAssemblyReferences) { Mixin.Read(module.AssemblyReferences); } if (module.HasResources) { Mixin.Read(module.Resources); } if (module.HasModuleReferences) { Mixin.Read(module.ModuleReferences); } if (module.HasTypes) { ReadTypes(module.Types); } if (module.HasExportedTypes) { Mixin.Read(module.ExportedTypes); } ReadCustomAttributes(module); AssemblyDefinition assembly = module.Assembly; if (module.kind != ModuleKind.NetModule && assembly != null) { ReadCustomAttributes(assembly); ReadSecurityDeclarations(assembly); } } private void ReadTypes(Collection<TypeDefinition> types) { for (int i = 0; i < types.Count; i++) { ReadType(types[i]); } } private void ReadType(TypeDefinition type) { ReadGenericParameters(type); if (type.HasInterfaces) { ReadInterfaces(type); } if (type.HasNestedTypes) { ReadTypes(type.NestedTypes); } if (type.HasLayoutInfo) { Mixin.Read(type.ClassSize); } if (type.HasFields) { ReadFields(type); } if (type.HasMethods) { ReadMethods(type); } if (type.HasProperties) { ReadProperties(type); } if (type.HasEvents) { ReadEvents(type); } ReadSecurityDeclarations(type); ReadCustomAttributes(type); } private void ReadInterfaces(TypeDefinition type) { Collection<InterfaceImplementation> interfaces = type.Interfaces; for (int i = 0; i < interfaces.Count; i++) { ReadCustomAttributes(interfaces[i]); } } private void ReadGenericParameters(IGenericParameterProvider provider) { if (!provider.HasGenericParameters) { return; } Collection<GenericParameter> genericParameters = provider.GenericParameters; for (int i = 0; i < genericParameters.Count; i++) { GenericParameter genericParameter = genericParameters[i]; if (genericParameter.HasConstraints) { ReadGenericParameterConstraints(genericParameter); } ReadCustomAttributes(genericParameter); } } private void ReadGenericParameterConstraints(GenericParameter parameter) { Collection<GenericParameterConstraint> constraints = parameter.Constraints; for (int i = 0; i < constraints.Count; i++) { ReadCustomAttributes(constraints[i]); } } private void ReadSecurityDeclarations(ISecurityDeclarationProvider provider) { if (!provider.HasSecurityDeclarations) { return; } Collection<SecurityDeclaration> securityDeclarations = provider.SecurityDeclarations; if (resolve_attributes) { for (int i = 0; i < securityDeclarations.Count; i++) { Mixin.Read(securityDeclarations[i].SecurityAttributes); } } } private void ReadCustomAttributes(ICustomAttributeProvider provider) { if (!provider.HasCustomAttributes) { return; } Collection<CustomAttribute> customAttributes = provider.CustomAttributes; if (resolve_attributes) { for (int i = 0; i < customAttributes.Count; i++) { Mixin.Read(customAttributes[i].ConstructorArguments); } } } private void ReadFields(TypeDefinition type) { Collection<FieldDefinition> fields = type.Fields; for (int i = 0; i < fields.Count; i++) { FieldDefinition fieldDefinition = fields[i]; if (fieldDefinition.HasConstant) { Mixin.Read(fieldDefinition.Constant); } if (fieldDefinition.HasLayoutInfo) { Mixin.Read(fieldDefinition.Offset); } if (fieldDefinition.RVA > 0) { Mixin.Read(fieldDefinition.InitialValue); } if (fieldDefinition.HasMarshalInfo) { Mixin.Read(fieldDefinition.MarshalInfo); } ReadCustomAttributes(fieldDefinition); } } private void ReadMethods(TypeDefinition type) { Collection<MethodDefinition> methods = type.Methods; for (int i = 0; i < methods.Count; i++) { MethodDefinition methodDefinition = methods[i]; ReadGenericParameters(methodDefinition); if (methodDefinition.HasParameters) { ReadParameters(methodDefinition); } if (methodDefinition.HasOverrides) { Mixin.Read(methodDefinition.Overrides); } if (methodDefinition.IsPInvokeImpl) { Mixin.Read(methodDefinition.PInvokeInfo); } ReadSecurityDeclarations(methodDefinition); ReadCustomAttributes(methodDefinition); MethodReturnType methodReturnType = methodDefinition.MethodReturnType; if (methodReturnType.HasConstant) { Mixin.Read(methodReturnType.Constant); } if (methodReturnType.HasMarshalInfo) { Mixin.Read(methodReturnType.MarshalInfo); } ReadCustomAttributes(methodReturnType); } } private void ReadParameters(MethodDefinition method) { Collection<ParameterDefinition> parameters = method.Parameters; for (int i = 0; i < parameters.Count; i++) { ParameterDefinition parameterDefinition = parameters[i]; if (parameterDefinition.HasConstant) { Mixin.Read(parameterDefinition.Constant); } if (parameterDefinition.HasMarshalInfo) { Mixin.Read(parameterDefinition.MarshalInfo); } ReadCustomAttributes(parameterDefinition); } } private void ReadProperties(TypeDefinition type) { Collection<PropertyDefinition> properties = type.Properties; for (int i = 0; i < properties.Count; i++) { PropertyDefinition propertyDefinition = properties[i]; Mixin.Read(propertyDefinition.GetMethod); if (propertyDefinition.HasConstant) { Mixin.Read(propertyDefinition.Constant); } ReadCustomAttributes(propertyDefinition); } } private void ReadEvents(TypeDefinition type) { Collection<EventDefinition> events = type.Events; for (int i = 0; i < events.Count; i++) { EventDefinition eventDefinition = events[i]; Mixin.Read(eventDefinition.AddMethod); ReadCustomAttributes(eventDefinition); } } public override void ReadSymbols(ModuleDefinition module) { if (module.symbol_reader != null) { ReadTypesSymbols(module.Types, module.symbol_reader); } } private void ReadTypesSymbols(Collection<TypeDefinition> types, ISymbolReader symbol_reader) { for (int i = 0; i < types.Count; i++) { TypeDefinition typeDefinition = types[i]; typeDefinition.custom_infos = symbol_reader.Read(typeDefinition); if (typeDefinition.HasNestedTypes) { ReadTypesSymbols(typeDefinition.NestedTypes, symbol_reader); } if (typeDefinition.HasMethods) { ReadMethodsSymbols(typeDefinition, symbol_reader); } } } private void ReadMethodsSymbols(TypeDefinition type, ISymbolReader symbol_reader) { Collection<MethodDefinition> methods = type.Methods; for (int i = 0; i < methods.Count; i++) { MethodDefinition methodDefinition = methods[i]; if (methodDefinition.HasBody && methodDefinition.token.RID != 0 && methodDefinition.debug_info == null) { methodDefinition.debug_info = symbol_reader.Read(methodDefinition); } } } } internal sealed class DeferredModuleReader : ModuleReader { public DeferredModuleReader(Image image) : base(image, ReadingMode.Deferred) { } protected override void ReadModule() { module.Read(module, delegate(ModuleDefinition _, MetadataReader reader) { ReadModuleManifest(reader); }); } public override void ReadSymbols(ModuleDefinition module) { } } internal sealed class MetadataReader : ByteBuffer { internal readonly Image image; internal readonly ModuleDefinition module; internal readonly MetadataSystem metadata; internal CodeReader code; internal IGenericContext context; private readonly MetadataReader metadata_reader; public MetadataReader(ModuleDefinition module) : base(module.Image.TableHeap.data) { image = module.Image; this.module = module; metadata = module.MetadataSystem; code = new CodeReader(this); } public MetadataReader(Image image, ModuleDefinition module, MetadataReader metadata_reader) : base(image.TableHeap.data) { this.image = image; this.module = module; metadata = module.MetadataSystem; this.metadata_reader = metadata_reader; } private int GetCodedIndexSize(CodedIndex index) { return image.GetCodedIndexSize(index); } private uint ReadByIndexSize(int size) { if (size == 4) { return ReadUInt32(); } return ReadUInt16(); } private byte[] ReadBlob() { BlobHeap blobHeap = image.BlobHeap; if (blobHeap == null) { position += 2; return Empty<byte>.Array; } return blobHeap.Read(ReadBlobIndex()); } private byte[] ReadBlob(uint signature) { BlobHeap blobHeap = image.BlobHeap; if (blobHeap == null) { return Empty<byte>.Array; } return blobHeap.Read(signature); } private uint ReadBlobIndex() { return ReadByIndexSize(image.BlobHeap?.IndexSize ?? 2); } private void GetBlobView(uint signature, out byte[] blob, out int index, out int count) { BlobHeap blobHeap = image.BlobHeap; if (blobHeap == null) { blob = null; index = (count = 0); } else { blobHeap.GetView(signature, out blob, out index, out count); } } private string ReadString() { return image.StringHeap.Read(ReadByIndexSize(image.StringHeap.IndexSize)); } private uint ReadStringIndex() { return ReadByIndexSize(image.StringHeap.IndexSize); } private Guid ReadGuid() { return image.GuidHeap.Read(ReadByIndexSize(image.GuidHeap.IndexSize)); } private uint ReadTableIndex(Table table) { return ReadByIndexSize(image.GetTableIndexSize(table)); } private MetadataToken ReadMetadataToken(CodedIndex index) { return index.GetMetadataToken(ReadByIndexSize(GetCodedIndexSize(index))); } private int MoveTo(Table table) { TableInformation tableInformation = image.TableHeap[table]; if (tableInformation.Length != 0) { position = (int)tableInformation.Offset; } return (int)tableInformation.Length; } private bool MoveTo(Table table, uint row) { TableInformation tableInformation = image.TableHeap[table]; uint num = tableInformation.Length; if (num == 0 || row > num) { return false; } position = (int)(tableInformation.Offset + tableInformation.RowSize * (row - 1)); return true; } public AssemblyNameDefinition ReadAssemblyNameDefinition() { if (MoveTo(Table.Assembly) == 0) { return null; } AssemblyNameDefinition assemblyNameDefinition = new AssemblyNameDefinition(); assemblyNameDefinition.HashAlgorithm = (AssemblyHashAlgorithm)ReadUInt32(); PopulateVersionAndFlags(assemblyNameDefinition); assemblyNameDefinition.PublicKey = ReadBlob(); PopulateNameAndCulture(assemblyNameDefinition); return assemblyNameDefinition; } public ModuleDefinition Populate(ModuleDefinition module) { if (MoveTo(Table.Module) == 0) { return module; } Advance(2); module.Name = ReadString(); module.Mvid = ReadGuid(); return module; } private void InitializeAssemblyReferences() { if (metadata.AssemblyReferences != null) { return; } int num = MoveTo(Table.AssemblyRef); AssemblyNameReference[] array = (metadata.AssemblyReferences = new AssemblyNameReference[num]); for (uint num2 = 0u; num2 < num; num2++) { AssemblyNameReference assemblyNameReference = new AssemblyNameReference(); assemblyNameReference.token = new MetadataToken(TokenType.AssemblyRef, num2 + 1); PopulateVersionAndFlags(assemblyNameReference); byte[] array2 = ReadBlob(); if (assemblyNameReference.HasPublicKey) { assemblyNameReference.PublicKey = array2; } else { assemblyNameReference.PublicKeyToken = array2; } PopulateNameAndCulture(assemblyNameReference); assemblyNameReference.Hash = ReadBlob(); array[num2] = assemblyNameReference; } } public Collection<AssemblyNameReference> ReadAssemblyReferences() { InitializeAssemblyReferences(); Collection<AssemblyNameReference> collection = new Collection<AssemblyNameReference>(metadata.AssemblyReferences); if (module.IsWindowsMetadata()) { module.Projections.AddVirtualReferences(collection); } return collection; } public MethodDefinition ReadEntryPoint() { if (module.Image.EntryPointToken == 0) { return null; } return GetMethodDefinition(new MetadataToken(module.Image.EntryPointToken).RID); } public Collection<ModuleDefinition> ReadModules() { Collection<ModuleDefinition> collection = new Collection<ModuleDefinition>(1); collection.Add(module); int num = MoveTo(Table.File); for (uint num2 = 1u; num2 <= num; num2++) { uint num3 = ReadUInt32(); string name = ReadString(); ReadBlobIndex(); if (num3 == 0) { ReaderParameters parameters = new ReaderParameters { ReadingMode = module.ReadingMode, SymbolReaderProvider = module.SymbolReaderProvider, AssemblyResolver = module.AssemblyResolver }; ModuleDefinition moduleDefinition = ModuleDefinition.ReadModule(GetModuleFileName(name), parameters); moduleDefinition.assembly = module.assembly; collection.Add(moduleDefinition); } } return collection; } private string GetModuleFileName(string name) { if (module.FileName == null) { throw new NotSupportedException(); } return Path.Combine(Path.GetDirectoryName(module.FileName), name); } private void InitializeModuleReferences() { if (metadata.ModuleReferences == null) { int num = MoveTo(Table.ModuleRef); ModuleReference[] array = (metadata.ModuleReferences = new ModuleReference[num]); for (uint num2 = 0u; num2 < num; num2++) { ModuleReference moduleReference = new ModuleReference(ReadString()); moduleReference.token = new MetadataToken(TokenType.ModuleRef, num2 + 1); array[num2] = moduleReference; } } } public Collection<ModuleReference> ReadModuleReferences() { InitializeModuleReferences(); return new Collection<ModuleReference>(metadata.ModuleReferences); } public bool HasFileResource() { int num = MoveTo(Table.File); if (num == 0) { return false; } for (uint num2 = 1u; num2 <= num; num2++) { if (ReadFileRecord(num2).Col1 == FileAttributes.ContainsNoMetaData) { return true; } } return false; } public Collection<Resource> ReadResources() { int num = MoveTo(Table.ManifestResource); Collection<Resource> collection = new Collection<Resource>(num); for (int i = 1; i <= num; i++) { uint offset = ReadUInt32(); ManifestResourceAttributes manifestResourceAttributes = (ManifestResourceAttributes)ReadUInt32(); string name = ReadString(); MetadataToken scope = ReadMetadataToken(CodedIndex.Implementation); Resource item; if (scope.RID == 0) { item = new EmbeddedResource(name, manifestResourceAttributes, offset, this); } else if (scope.TokenType == TokenType.AssemblyRef) { item = new AssemblyLinkedResource(name, manifestResourceAttributes) { Assembly = (AssemblyNameReference)GetTypeReferenceScope(scope) }; } else { if (scope.TokenType != TokenType.File) { continue; } Row<FileAttributes, string, uint> row = ReadFileRecord(scope.RID); item = new LinkedResource(name, manifestResourceAttributes) { File = row.Col2, hash = ReadBlob(row.Col3) }; } collection.Add(item); } return collection; } private Row<FileAttributes, string, uint> ReadFileRecord(uint rid) { int num = position; if (!MoveTo(Table.File, rid)) { throw new ArgumentException(); } Row<FileAttributes, string, uint> result = new Row<FileAttributes, string, uint>((FileAttributes)ReadUInt32(), ReadString(), ReadBlobIndex()); position = num; return result; } public byte[] GetManagedResource(uint offset) { return image.GetReaderAt(image.Resources.VirtualAddress, offset, delegate(uint o, BinaryStreamReader reader) { reader.Advance((int)o); return reader.ReadBytes(reader.ReadInt32()); }) ?? Empty<byte>.Array; } private void PopulateVersionAndFlags(AssemblyNameReference name) { name.Version = new Version(ReadUInt16(), ReadUInt16(), ReadUInt16(), ReadUInt16()); name.Attributes = (AssemblyAttributes)ReadUInt32(); } private void PopulateNameAndCulture(AssemblyNameReference name) { name.Name = ReadString(); name.Culture = ReadString(); } public TypeDefinitionCollection ReadTypes() { InitializeTypeDefinitions(); TypeDefinition[] types = metadata.Types; int capacity = types.Length - metadata.NestedTypes.Count; TypeDefinitionCollection typeDefinitionCollection = new TypeDefinitionCollection(module, capacity); foreach (TypeDefinition typeDefinition in types) { if (!IsNested(typeDefinition.Attributes)) { typeDefinitionCollection.Add(typeDefinition); } } if (image.HasTable(Table.MethodPtr) || image.HasTable(Table.FieldPtr)) { CompleteTypes(); } return typeDefinitionCollection; } private void CompleteTypes() { TypeDefinition[] types = metadata.Types; foreach (TypeDefinition obj in types) { Mixin.Read(obj.Fields); Mixin.Read(obj.Methods); } } private void InitializeTypeDefinitions() { if (metadata.Types != null) { return; } InitializeNestedTypes(); InitializeFields(); InitializeMethods(); int num = MoveTo(Table.TypeDef); TypeDefinition[] array = (metadata.Types = new TypeDefinition[num]); for (uint num2 = 0u; num2 < num; num2++) { if (array[num2] == null) { array[num2] = ReadType(num2 + 1); } } if (module.IsWindowsMetadata()) { for (uint num3 = 0u; num3 < num; num3++) { WindowsRuntimeProjections.Project(array[num3]); } } } private static bool IsNested(TypeAttributes attributes) { TypeAttributes typeAttributes = attributes & TypeAttributes.VisibilityMask; if (typeAttributes - 2 <= TypeAttributes.NestedAssembly) { return true; } return false; } public bool HasNestedTypes(TypeDefinition type) { InitializeNestedTypes(); if (!metadata.TryGetNestedTypeMapping(type, out var mapping)) { return false; } return mapping.Count > 0; } public Collection<TypeDefinition> ReadNestedTypes(TypeDefinition type) { InitializeNestedTypes(); if (!metadata.TryGetNestedTypeMapping(type, out var mapping)) { return new MemberDefinitionCollection<TypeDefinition>(type); } MemberDefinitionCollection<TypeDefinition> memberDefinitionCollection = new MemberDefinitionCollection<TypeDefinition>(type, mapping.Count); for (int i = 0; i < mapping.Count; i++) { TypeDefinition typeDefinition = GetTypeDefinition(mapping[i]); if (typeDefinition != null) { memberDefinitionCollection.Add(typeDefinition); } } return memberDefinitionCollection; } private void InitializeNestedTypes() { if (metadata.NestedTypes != null) { return; } int num = MoveTo(Table.NestedClass); metadata.NestedTypes = new Dictionary<uint, Collection<uint>>(num); metadata.ReverseNestedTypes = new Dictionary<uint, uint>(num); if (num != 0) { for (int i = 1; i <= num; i++) { uint nested = ReadTableIndex(Table.TypeDef); uint declaring = ReadTableIndex(Table.TypeDef); AddNestedMapping(declaring, nested); } } } private void AddNestedMapping(uint declaring, uint nested) { metadata.SetNestedTypeMapping(declaring, AddMapping(metadata.NestedTypes, declaring, nested)
BepInExPack/BepInEx/core/Mono.Cecil.Mdb.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using Mono.Collections.Generic; using Mono.CompilerServices.SymbolWriter; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyProduct("Mono.Cecil")] [assembly: AssemblyCopyright("Copyright © 2008 - 2018 Jb Evain")] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("0.11.6.0")] [assembly: AssemblyInformationalVersion("0.11.6.0")] [assembly: AssemblyTitle("Mono.Cecil.Mdb")] [assembly: CLSCompliant(false)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyVersion("0.11.6.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Mono.CompilerServices.SymbolWriter { public class MonoSymbolFileException : Exception { public MonoSymbolFileException() { } public MonoSymbolFileException(string message, params object[] args) : base(string.Format(message, args)) { } public MonoSymbolFileException(string message, Exception innerException) : base(message, innerException) { } } internal sealed class MyBinaryWriter : BinaryWriter { public MyBinaryWriter(Stream stream) : base(stream) { } public void WriteLeb128(int value) { Write7BitEncodedInt(value); } } internal class MyBinaryReader : BinaryReader { public MyBinaryReader(Stream stream) : base(stream) { } public int ReadLeb128() { return Read7BitEncodedInt(); } public string ReadString(int offset) { long position = BaseStream.Position; BaseStream.Position = offset; string result = ReadString(); BaseStream.Position = position; return result; } } public interface ISourceFile { SourceFileEntry Entry { get; } } public interface ICompileUnit { CompileUnitEntry Entry { get; } } public interface IMethodDef { string Name { get; } int Token { get; } } public class MonoSymbolFile : IDisposable { private List<MethodEntry> methods = new List<MethodEntry>(); private List<SourceFileEntry> sources = new List<SourceFileEntry>(); private List<CompileUnitEntry> comp_units = new List<CompileUnitEntry>(); private Dictionary<int, AnonymousScopeEntry> anonymous_scopes; private OffsetTable ot; private int last_type_index; private int last_method_index; private int last_namespace_index; public readonly int MajorVersion = 50; public readonly int MinorVersion; public int NumLineNumbers; private MyBinaryReader reader; private Dictionary<int, SourceFileEntry> source_file_hash; private Dictionary<int, CompileUnitEntry> compile_unit_hash; private List<MethodEntry> method_list; private Dictionary<int, MethodEntry> method_token_hash; private Dictionary<string, int> source_name_hash; private Guid guid; internal int LineNumberCount; internal int LocalCount; internal int StringSize; internal int LineNumberSize; internal int ExtendedLineNumberSize; public int CompileUnitCount => ot.CompileUnitCount; public int SourceCount => ot.SourceCount; public int MethodCount => ot.MethodCount; public int TypeCount => ot.TypeCount; public int AnonymousScopeCount => ot.AnonymousScopeCount; public int NamespaceCount => last_namespace_index; public Guid Guid => guid; public OffsetTable OffsetTable => ot; public SourceFileEntry[] Sources { get { if (reader == null) { throw new InvalidOperationException(); } SourceFileEntry[] array = new SourceFileEntry[SourceCount]; for (int i = 0; i < SourceCount; i++) { array[i] = GetSourceFile(i + 1); } return array; } } public CompileUnitEntry[] CompileUnits { get { if (reader == null) { throw new InvalidOperationException(); } CompileUnitEntry[] array = new CompileUnitEntry[CompileUnitCount]; for (int i = 0; i < CompileUnitCount; i++) { array[i] = GetCompileUnit(i + 1); } return array; } } public MethodEntry[] Methods { get { if (reader == null) { throw new InvalidOperationException(); } lock (this) { read_methods(); MethodEntry[] array = new MethodEntry[MethodCount]; method_list.CopyTo(array, 0); return array; } } } internal MyBinaryReader BinaryReader { get { if (reader == null) { throw new InvalidOperationException(); } return reader; } } public MonoSymbolFile() { ot = new OffsetTable(); } public int AddSource(SourceFileEntry source) { sources.Add(source); return sources.Count; } public int AddCompileUnit(CompileUnitEntry entry) { comp_units.Add(entry); return comp_units.Count; } public void AddMethod(MethodEntry entry) { methods.Add(entry); } public MethodEntry DefineMethod(CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id) { if (reader != null) { throw new InvalidOperationException(); } MethodEntry methodEntry = new MethodEntry(this, comp_unit, token, scope_vars, locals, lines, code_blocks, real_name, flags, namespace_id); AddMethod(methodEntry); return methodEntry; } internal void DefineAnonymousScope(int id) { if (reader != null) { throw new InvalidOperationException(); } if (anonymous_scopes == null) { anonymous_scopes = new Dictionary<int, AnonymousScopeEntry>(); } anonymous_scopes.Add(id, new AnonymousScopeEntry(id)); } internal void DefineCapturedVariable(int scope_id, string name, string captured_name, CapturedVariable.CapturedKind kind) { if (reader != null) { throw new InvalidOperationException(); } anonymous_scopes[scope_id].AddCapturedVariable(name, captured_name, kind); } internal void DefineCapturedScope(int scope_id, int id, string captured_name) { if (reader != null) { throw new InvalidOperationException(); } anonymous_scopes[scope_id].AddCapturedScope(id, captured_name); } internal int GetNextTypeIndex() { return ++last_type_index; } internal int GetNextMethodIndex() { return ++last_method_index; } internal int GetNextNamespaceIndex() { return ++last_namespace_index; } private void Write(MyBinaryWriter bw, Guid guid) { bw.Write(5037318119232611860L); bw.Write(MajorVersion); bw.Write(MinorVersion); bw.Write(guid.ToByteArray()); long position = bw.BaseStream.Position; ot.Write(bw, MajorVersion, MinorVersion); methods.Sort(); for (int i = 0; i < methods.Count; i++) { methods[i].Index = i + 1; } ot.DataSectionOffset = (int)bw.BaseStream.Position; foreach (SourceFileEntry source in sources) { source.WriteData(bw); } foreach (CompileUnitEntry comp_unit in comp_units) { comp_unit.WriteData(bw); } foreach (MethodEntry method in methods) { method.WriteData(this, bw); } ot.DataSectionSize = (int)bw.BaseStream.Position - ot.DataSectionOffset; ot.MethodTableOffset = (int)bw.BaseStream.Position; for (int j = 0; j < methods.Count; j++) { methods[j].Write(bw); } ot.MethodTableSize = (int)bw.BaseStream.Position - ot.MethodTableOffset; ot.SourceTableOffset = (int)bw.BaseStream.Position; for (int k = 0; k < sources.Count; k++) { sources[k].Write(bw); } ot.SourceTableSize = (int)bw.BaseStream.Position - ot.SourceTableOffset; ot.CompileUnitTableOffset = (int)bw.BaseStream.Position; for (int l = 0; l < comp_units.Count; l++) { comp_units[l].Write(bw); } ot.CompileUnitTableSize = (int)bw.BaseStream.Position - ot.CompileUnitTableOffset; ot.AnonymousScopeCount = ((anonymous_scopes != null) ? anonymous_scopes.Count : 0); ot.AnonymousScopeTableOffset = (int)bw.BaseStream.Position; if (anonymous_scopes != null) { foreach (AnonymousScopeEntry value in anonymous_scopes.Values) { value.Write(bw); } } ot.AnonymousScopeTableSize = (int)bw.BaseStream.Position - ot.AnonymousScopeTableOffset; ot.TypeCount = last_type_index; ot.MethodCount = methods.Count; ot.SourceCount = sources.Count; ot.CompileUnitCount = comp_units.Count; ot.TotalFileSize = (int)bw.BaseStream.Position; bw.Seek((int)position, SeekOrigin.Begin); ot.Write(bw, MajorVersion, MinorVersion); bw.Seek(0, SeekOrigin.End); } public void CreateSymbolFile(Guid guid, FileStream fs) { if (reader != null) { throw new InvalidOperationException(); } Write(new MyBinaryWriter(fs), guid); } private MonoSymbolFile(Stream stream) { reader = new MyBinaryReader(stream); try { long num = reader.ReadInt64(); int num2 = reader.ReadInt32(); int num3 = reader.ReadInt32(); if (num != 5037318119232611860L) { throw new MonoSymbolFileException("Symbol file is not a valid"); } if (num2 != 50) { throw new MonoSymbolFileException("Symbol file has version {0} but expected {1}", num2, 50); } if (num3 != 0) { throw new MonoSymbolFileException("Symbol file has version {0}.{1} but expected {2}.{3}", num2, num3, 50, 0); } MajorVersion = num2; MinorVersion = num3; guid = new Guid(reader.ReadBytes(16)); ot = new OffsetTable(reader, num2, num3); } catch (Exception innerException) { throw new MonoSymbolFileException("Cannot read symbol file", innerException); } source_file_hash = new Dictionary<int, SourceFileEntry>(); compile_unit_hash = new Dictionary<int, CompileUnitEntry>(); } public static MonoSymbolFile ReadSymbolFile(string mdbFilename) { return ReadSymbolFile(new FileStream(mdbFilename, FileMode.Open, FileAccess.Read)); } public static MonoSymbolFile ReadSymbolFile(string mdbFilename, Guid assemblyGuid) { MonoSymbolFile monoSymbolFile = ReadSymbolFile(mdbFilename); if (assemblyGuid != monoSymbolFile.guid) { throw new MonoSymbolFileException("Symbol file `{0}' does not match assembly", mdbFilename); } return monoSymbolFile; } public static MonoSymbolFile ReadSymbolFile(Stream stream) { return new MonoSymbolFile(stream); } public SourceFileEntry GetSourceFile(int index) { if (index < 1 || index > ot.SourceCount) { throw new ArgumentException(); } if (reader == null) { throw new InvalidOperationException(); } lock (this) { if (source_file_hash.TryGetValue(index, out var value)) { return value; } long position = reader.BaseStream.Position; reader.BaseStream.Position = ot.SourceTableOffset + SourceFileEntry.Size * (index - 1); value = new SourceFileEntry(this, reader); source_file_hash.Add(index, value); reader.BaseStream.Position = position; return value; } } public CompileUnitEntry GetCompileUnit(int index) { if (index < 1 || index > ot.CompileUnitCount) { throw new ArgumentException(); } if (reader == null) { throw new InvalidOperationException(); } lock (this) { if (compile_unit_hash.TryGetValue(index, out var value)) { return value; } long position = reader.BaseStream.Position; reader.BaseStream.Position = ot.CompileUnitTableOffset + CompileUnitEntry.Size * (index - 1); value = new CompileUnitEntry(this, reader); compile_unit_hash.Add(index, value); reader.BaseStream.Position = position; return value; } } private void read_methods() { lock (this) { if (method_token_hash == null) { method_token_hash = new Dictionary<int, MethodEntry>(); method_list = new List<MethodEntry>(); long position = reader.BaseStream.Position; reader.BaseStream.Position = ot.MethodTableOffset; for (int i = 0; i < MethodCount; i++) { MethodEntry methodEntry = new MethodEntry(this, reader, i + 1); method_token_hash.Add(methodEntry.Token, methodEntry); method_list.Add(methodEntry); } reader.BaseStream.Position = position; } } } public MethodEntry GetMethodByToken(int token) { if (reader == null) { throw new InvalidOperationException(); } lock (this) { read_methods(); method_token_hash.TryGetValue(token, out var value); return value; } } public MethodEntry GetMethod(int index) { if (index < 1 || index > ot.MethodCount) { throw new ArgumentException(); } if (reader == null) { throw new InvalidOperationException(); } lock (this) { read_methods(); return method_list[index - 1]; } } public int FindSource(string file_name) { if (reader == null) { throw new InvalidOperationException(); } lock (this) { if (source_name_hash == null) { source_name_hash = new Dictionary<string, int>(); for (int i = 0; i < ot.SourceCount; i++) { SourceFileEntry sourceFile = GetSourceFile(i + 1); source_name_hash.Add(sourceFile.FileName, i); } } if (!source_name_hash.TryGetValue(file_name, out var value)) { return -1; } return value; } } public AnonymousScopeEntry GetAnonymousScope(int id) { if (reader == null) { throw new InvalidOperationException(); } lock (this) { if (anonymous_scopes != null) { anonymous_scopes.TryGetValue(id, out var value); return value; } anonymous_scopes = new Dictionary<int, AnonymousScopeEntry>(); reader.BaseStream.Position = ot.AnonymousScopeTableOffset; for (int i = 0; i < ot.AnonymousScopeCount; i++) { AnonymousScopeEntry value = new AnonymousScopeEntry(reader); anonymous_scopes.Add(value.ID, value); } return anonymous_scopes[id]; } } public void Dispose() { Dispose(disposing: true); } protected virtual void Dispose(bool disposing) { if (disposing && reader != null) { reader.Dispose(); reader = null; } } } public class OffsetTable { [Flags] public enum Flags { IsAspxSource = 1, WindowsFileNames = 2 } public const int MajorVersion = 50; public const int MinorVersion = 0; public const long Magic = 5037318119232611860L; public int TotalFileSize; public int DataSectionOffset; public int DataSectionSize; public int CompileUnitCount; public int CompileUnitTableOffset; public int CompileUnitTableSize; public int SourceCount; public int SourceTableOffset; public int SourceTableSize; public int MethodCount; public int MethodTableOffset; public int MethodTableSize; public int TypeCount; public int AnonymousScopeCount; public int AnonymousScopeTableOffset; public int AnonymousScopeTableSize; public Flags FileFlags; public int LineNumberTable_LineBase = -1; public int LineNumberTable_LineRange = 8; public int LineNumberTable_OpcodeBase = 9; internal OffsetTable() { } internal OffsetTable(BinaryReader reader, int major_version, int minor_version) { TotalFileSize = reader.ReadInt32(); DataSectionOffset = reader.ReadInt32(); DataSectionSize = reader.ReadInt32(); CompileUnitCount = reader.ReadInt32(); CompileUnitTableOffset = reader.ReadInt32(); CompileUnitTableSize = reader.ReadInt32(); SourceCount = reader.ReadInt32(); SourceTableOffset = reader.ReadInt32(); SourceTableSize = reader.ReadInt32(); MethodCount = reader.ReadInt32(); MethodTableOffset = reader.ReadInt32(); MethodTableSize = reader.ReadInt32(); TypeCount = reader.ReadInt32(); AnonymousScopeCount = reader.ReadInt32(); AnonymousScopeTableOffset = reader.ReadInt32(); AnonymousScopeTableSize = reader.ReadInt32(); LineNumberTable_LineBase = reader.ReadInt32(); LineNumberTable_LineRange = reader.ReadInt32(); LineNumberTable_OpcodeBase = reader.ReadInt32(); FileFlags = (Flags)reader.ReadInt32(); } internal void Write(BinaryWriter bw, int major_version, int minor_version) { bw.Write(TotalFileSize); bw.Write(DataSectionOffset); bw.Write(DataSectionSize); bw.Write(CompileUnitCount); bw.Write(CompileUnitTableOffset); bw.Write(CompileUnitTableSize); bw.Write(SourceCount); bw.Write(SourceTableOffset); bw.Write(SourceTableSize); bw.Write(MethodCount); bw.Write(MethodTableOffset); bw.Write(MethodTableSize); bw.Write(TypeCount); bw.Write(AnonymousScopeCount); bw.Write(AnonymousScopeTableOffset); bw.Write(AnonymousScopeTableSize); bw.Write(LineNumberTable_LineBase); bw.Write(LineNumberTable_LineRange); bw.Write(LineNumberTable_OpcodeBase); bw.Write((int)FileFlags); } public override string ToString() { return $"OffsetTable [{TotalFileSize} - {DataSectionOffset}:{DataSectionSize} - {SourceCount}:{SourceTableOffset}:{SourceTableSize} - {MethodCount}:{MethodTableOffset}:{MethodTableSize} - {TypeCount}]"; } } public class LineNumberEntry { public sealed class LocationComparer : IComparer<LineNumberEntry> { public static readonly LocationComparer Default = new LocationComparer(); public int Compare(LineNumberEntry l1, LineNumberEntry l2) { if (l1.Row != l2.Row) { int row = l1.Row; return row.CompareTo(l2.Row); } return l1.Column.CompareTo(l2.Column); } } public readonly int Row; public int Column; public int EndRow; public int EndColumn; public readonly int File; public readonly int Offset; public readonly bool IsHidden; public static readonly LineNumberEntry Null = new LineNumberEntry(0, 0, 0, 0); public LineNumberEntry(int file, int row, int column, int offset) : this(file, row, column, offset, is_hidden: false) { } public LineNumberEntry(int file, int row, int offset) : this(file, row, -1, offset, is_hidden: false) { } public LineNumberEntry(int file, int row, int column, int offset, bool is_hidden) : this(file, row, column, -1, -1, offset, is_hidden) { } public LineNumberEntry(int file, int row, int column, int end_row, int end_column, int offset, bool is_hidden) { File = file; Row = row; Column = column; EndRow = end_row; EndColumn = end_column; Offset = offset; IsHidden = is_hidden; } public override string ToString() { return $"[Line {File}:{Row},{Column}-{EndRow},{EndColumn}:{Offset}]"; } } public class CodeBlockEntry { public enum Type { Lexical = 1, CompilerGenerated, IteratorBody, IteratorDispatcher } public int Index; public int Parent; public Type BlockType; public int StartOffset; public int EndOffset; public CodeBlockEntry(int index, int parent, Type type, int start_offset) { Index = index; Parent = parent; BlockType = type; StartOffset = start_offset; } internal CodeBlockEntry(int index, MyBinaryReader reader) { Index = index; int num = reader.ReadLeb128(); BlockType = (Type)(num & 0x3F); Parent = reader.ReadLeb128(); StartOffset = reader.ReadLeb128(); EndOffset = reader.ReadLeb128(); if (((uint)num & 0x40u) != 0) { int num2 = reader.ReadInt16(); reader.BaseStream.Position += num2; } } public void Close(int end_offset) { EndOffset = end_offset; } internal void Write(MyBinaryWriter bw) { bw.WriteLeb128((int)BlockType); bw.WriteLeb128(Parent); bw.WriteLeb128(StartOffset); bw.WriteLeb128(EndOffset); } public override string ToString() { return $"[CodeBlock {Index}:{Parent}:{BlockType}:{StartOffset}:{EndOffset}]"; } } public struct LocalVariableEntry { public readonly int Index; public readonly string Name; public readonly int BlockIndex; public LocalVariableEntry(int index, string name, int block) { Index = index; Name = name; BlockIndex = block; } internal LocalVariableEntry(MonoSymbolFile file, MyBinaryReader reader) { Index = reader.ReadLeb128(); Name = reader.ReadString(); BlockIndex = reader.ReadLeb128(); } internal void Write(MonoSymbolFile file, MyBinaryWriter bw) { bw.WriteLeb128(Index); bw.Write(Name); bw.WriteLeb128(BlockIndex); } public override string ToString() { return $"[LocalVariable {Name}:{Index}:{BlockIndex - 1}]"; } } public struct CapturedVariable { public enum CapturedKind : byte { Local, Parameter, This } public readonly string Name; public readonly string CapturedName; public readonly CapturedKind Kind; public CapturedVariable(string name, string captured_name, CapturedKind kind) { Name = name; CapturedName = captured_name; Kind = kind; } internal CapturedVariable(MyBinaryReader reader) { Name = reader.ReadString(); CapturedName = reader.ReadString(); Kind = (CapturedKind)reader.ReadByte(); } internal void Write(MyBinaryWriter bw) { bw.Write(Name); bw.Write(CapturedName); bw.Write((byte)Kind); } public override string ToString() { return $"[CapturedVariable {Name}:{CapturedName}:{Kind}]"; } } public struct CapturedScope { public readonly int Scope; public readonly string CapturedName; public CapturedScope(int scope, string captured_name) { Scope = scope; CapturedName = captured_name; } internal CapturedScope(MyBinaryReader reader) { Scope = reader.ReadLeb128(); CapturedName = reader.ReadString(); } internal void Write(MyBinaryWriter bw) { bw.WriteLeb128(Scope); bw.Write(CapturedName); } public override string ToString() { return $"[CapturedScope {Scope}:{CapturedName}]"; } } public struct ScopeVariable { public readonly int Scope; public readonly int Index; public ScopeVariable(int scope, int index) { Scope = scope; Index = index; } internal ScopeVariable(MyBinaryReader reader) { Scope = reader.ReadLeb128(); Index = reader.ReadLeb128(); } internal void Write(MyBinaryWriter bw) { bw.WriteLeb128(Scope); bw.WriteLeb128(Index); } public override string ToString() { return $"[ScopeVariable {Scope}:{Index}]"; } } public class AnonymousScopeEntry { public readonly int ID; private List<CapturedVariable> captured_vars = new List<CapturedVariable>(); private List<CapturedScope> captured_scopes = new List<CapturedScope>(); public CapturedVariable[] CapturedVariables { get { CapturedVariable[] array = new CapturedVariable[captured_vars.Count]; captured_vars.CopyTo(array, 0); return array; } } public CapturedScope[] CapturedScopes { get { CapturedScope[] array = new CapturedScope[captured_scopes.Count]; captured_scopes.CopyTo(array, 0); return array; } } public AnonymousScopeEntry(int id) { ID = id; } internal AnonymousScopeEntry(MyBinaryReader reader) { ID = reader.ReadLeb128(); int num = reader.ReadLeb128(); for (int i = 0; i < num; i++) { captured_vars.Add(new CapturedVariable(reader)); } int num2 = reader.ReadLeb128(); for (int j = 0; j < num2; j++) { captured_scopes.Add(new CapturedScope(reader)); } } internal void AddCapturedVariable(string name, string captured_name, CapturedVariable.CapturedKind kind) { captured_vars.Add(new CapturedVariable(name, captured_name, kind)); } internal void AddCapturedScope(int scope, string captured_name) { captured_scopes.Add(new CapturedScope(scope, captured_name)); } internal void Write(MyBinaryWriter bw) { bw.WriteLeb128(ID); bw.WriteLeb128(captured_vars.Count); foreach (CapturedVariable captured_var in captured_vars) { captured_var.Write(bw); } bw.WriteLeb128(captured_scopes.Count); foreach (CapturedScope captured_scope in captured_scopes) { captured_scope.Write(bw); } } public override string ToString() { return $"[AnonymousScope {ID}]"; } } public class CompileUnitEntry : ICompileUnit { public readonly int Index; private int DataOffset; private MonoSymbolFile file; private SourceFileEntry source; private List<SourceFileEntry> include_files; private List<NamespaceEntry> namespaces; private bool creating; public static int Size => 8; CompileUnitEntry ICompileUnit.Entry => this; public SourceFileEntry SourceFile { get { if (creating) { return source; } ReadData(); return source; } } public NamespaceEntry[] Namespaces { get { ReadData(); NamespaceEntry[] array = new NamespaceEntry[namespaces.Count]; namespaces.CopyTo(array, 0); return array; } } public SourceFileEntry[] IncludeFiles { get { ReadData(); if (include_files == null) { return new SourceFileEntry[0]; } SourceFileEntry[] array = new SourceFileEntry[include_files.Count]; include_files.CopyTo(array, 0); return array; } } public CompileUnitEntry(MonoSymbolFile file, SourceFileEntry source) { this.file = file; this.source = source; Index = file.AddCompileUnit(this); creating = true; namespaces = new List<NamespaceEntry>(); } public void AddFile(SourceFileEntry file) { if (!creating) { throw new InvalidOperationException(); } if (include_files == null) { include_files = new List<SourceFileEntry>(); } include_files.Add(file); } public int DefineNamespace(string name, string[] using_clauses, int parent) { if (!creating) { throw new InvalidOperationException(); } int nextNamespaceIndex = file.GetNextNamespaceIndex(); NamespaceEntry item = new NamespaceEntry(name, nextNamespaceIndex, using_clauses, parent); namespaces.Add(item); return nextNamespaceIndex; } internal void WriteData(MyBinaryWriter bw) { DataOffset = (int)bw.BaseStream.Position; bw.WriteLeb128(source.Index); int value = ((include_files != null) ? include_files.Count : 0); bw.WriteLeb128(value); if (include_files != null) { foreach (SourceFileEntry include_file in include_files) { bw.WriteLeb128(include_file.Index); } } bw.WriteLeb128(namespaces.Count); foreach (NamespaceEntry @namespace in namespaces) { @namespace.Write(file, bw); } } internal void Write(BinaryWriter bw) { bw.Write(Index); bw.Write(DataOffset); } internal CompileUnitEntry(MonoSymbolFile file, MyBinaryReader reader) { this.file = file; Index = reader.ReadInt32(); DataOffset = reader.ReadInt32(); } public void ReadAll() { ReadData(); } private void ReadData() { if (creating) { throw new InvalidOperationException(); } lock (file) { if (namespaces != null) { return; } MyBinaryReader binaryReader = file.BinaryReader; int num = (int)binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = DataOffset; int index = binaryReader.ReadLeb128(); source = file.GetSourceFile(index); int num2 = binaryReader.ReadLeb128(); if (num2 > 0) { include_files = new List<SourceFileEntry>(); for (int i = 0; i < num2; i++) { include_files.Add(file.GetSourceFile(binaryReader.ReadLeb128())); } } int num3 = binaryReader.ReadLeb128(); namespaces = new List<NamespaceEntry>(); for (int j = 0; j < num3; j++) { namespaces.Add(new NamespaceEntry(file, binaryReader)); } binaryReader.BaseStream.Position = num; } } } public class SourceFileEntry { public readonly int Index; private int DataOffset; private MonoSymbolFile file; private string file_name; private byte[] guid; private byte[] hash; private bool creating; private bool auto_generated; private readonly string sourceFile; public static int Size => 8; public byte[] Checksum => hash; public string FileName { get { return file_name; } set { file_name = value; } } public bool AutoGenerated => auto_generated; public SourceFileEntry(MonoSymbolFile file, string file_name) { this.file = file; this.file_name = file_name; Index = file.AddSource(this); creating = true; } public SourceFileEntry(MonoSymbolFile file, string sourceFile, byte[] guid, byte[] checksum) : this(file, sourceFile, sourceFile, guid, checksum) { } public SourceFileEntry(MonoSymbolFile file, string fileName, string sourceFile, byte[] guid, byte[] checksum) : this(file, fileName) { this.guid = guid; hash = checksum; this.sourceFile = sourceFile; } internal void WriteData(MyBinaryWriter bw) { DataOffset = (int)bw.BaseStream.Position; bw.Write(file_name); if (guid == null) { guid = new byte[16]; } if (hash == null) { try { using FileStream inputStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read); MD5 mD = MD5.Create(); hash = mD.ComputeHash(inputStream); } catch { hash = new byte[16]; } } bw.Write(guid); bw.Write(hash); bw.Write(auto_generated ? ((byte)1) : ((byte)0)); } internal void Write(BinaryWriter bw) { bw.Write(Index); bw.Write(DataOffset); } internal SourceFileEntry(MonoSymbolFile file, MyBinaryReader reader) { this.file = file; Index = reader.ReadInt32(); DataOffset = reader.ReadInt32(); int num = (int)reader.BaseStream.Position; reader.BaseStream.Position = DataOffset; sourceFile = (file_name = reader.ReadString()); guid = reader.ReadBytes(16); hash = reader.ReadBytes(16); auto_generated = reader.ReadByte() == 1; reader.BaseStream.Position = num; } public void SetAutoGenerated() { if (!creating) { throw new InvalidOperationException(); } auto_generated = true; file.OffsetTable.FileFlags |= OffsetTable.Flags.IsAspxSource; } public bool CheckChecksum() { try { using FileStream inputStream = new FileStream(sourceFile, FileMode.Open); byte[] array = MD5.Create().ComputeHash(inputStream); for (int i = 0; i < 16; i++) { if (array[i] != hash[i]) { return false; } } return true; } catch { return false; } } public override string ToString() { return $"SourceFileEntry ({Index}:{DataOffset})"; } } public class LineNumberTable { protected LineNumberEntry[] _line_numbers; public readonly int LineBase; public readonly int LineRange; public readonly byte OpcodeBase; public readonly int MaxAddressIncrement; public const int Default_LineBase = -1; public const int Default_LineRange = 8; public const byte Default_OpcodeBase = 9; public const byte DW_LNS_copy = 1; public const byte DW_LNS_advance_pc = 2; public const byte DW_LNS_advance_line = 3; public const byte DW_LNS_set_file = 4; public const byte DW_LNS_const_add_pc = 8; public const byte DW_LNE_end_sequence = 1; public const byte DW_LNE_MONO_negate_is_hidden = 64; internal const byte DW_LNE_MONO__extensions_start = 64; internal const byte DW_LNE_MONO__extensions_end = 127; public LineNumberEntry[] LineNumbers => _line_numbers; protected LineNumberTable(MonoSymbolFile file) { LineBase = file.OffsetTable.LineNumberTable_LineBase; LineRange = file.OffsetTable.LineNumberTable_LineRange; OpcodeBase = (byte)file.OffsetTable.LineNumberTable_OpcodeBase; MaxAddressIncrement = (255 - OpcodeBase) / LineRange; } internal LineNumberTable(MonoSymbolFile file, LineNumberEntry[] lines) : this(file) { _line_numbers = lines; } internal void Write(MonoSymbolFile file, MyBinaryWriter bw, bool hasColumnsInfo, bool hasEndInfo) { int num = (int)bw.BaseStream.Position; bool flag = false; int num2 = 1; int num3 = 0; int num4 = 1; for (int i = 0; i < LineNumbers.Length; i++) { int num5 = LineNumbers[i].Row - num2; int num6 = LineNumbers[i].Offset - num3; if (LineNumbers[i].File != num4) { bw.Write((byte)4); bw.WriteLeb128(LineNumbers[i].File); num4 = LineNumbers[i].File; } if (LineNumbers[i].IsHidden != flag) { bw.Write((byte)0); bw.Write((byte)1); bw.Write((byte)64); flag = LineNumbers[i].IsHidden; } if (num6 >= MaxAddressIncrement) { if (num6 < 2 * MaxAddressIncrement) { bw.Write((byte)8); num6 -= MaxAddressIncrement; } else { bw.Write((byte)2); bw.WriteLeb128(num6); num6 = 0; } } if (num5 < LineBase || num5 >= LineBase + LineRange) { bw.Write((byte)3); bw.WriteLeb128(num5); if (num6 != 0) { bw.Write((byte)2); bw.WriteLeb128(num6); } bw.Write((byte)1); } else { byte value = (byte)(num5 - LineBase + LineRange * num6 + OpcodeBase); bw.Write(value); } num2 = LineNumbers[i].Row; num3 = LineNumbers[i].Offset; } bw.Write((byte)0); bw.Write((byte)1); bw.Write((byte)1); if (hasColumnsInfo) { for (int j = 0; j < LineNumbers.Length; j++) { LineNumberEntry lineNumberEntry = LineNumbers[j]; if (lineNumberEntry.Row >= 0) { bw.WriteLeb128(lineNumberEntry.Column); } } } if (hasEndInfo) { for (int k = 0; k < LineNumbers.Length; k++) { LineNumberEntry lineNumberEntry2 = LineNumbers[k]; if (lineNumberEntry2.EndRow == -1 || lineNumberEntry2.EndColumn == -1 || lineNumberEntry2.Row > lineNumberEntry2.EndRow) { bw.WriteLeb128(16777215); continue; } bw.WriteLeb128(lineNumberEntry2.EndRow - lineNumberEntry2.Row); bw.WriteLeb128(lineNumberEntry2.EndColumn); } } file.ExtendedLineNumberSize += (int)bw.BaseStream.Position - num; } internal static LineNumberTable Read(MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo, bool readEndInfo) { LineNumberTable lineNumberTable = new LineNumberTable(file); lineNumberTable.DoRead(file, br, readColumnsInfo, readEndInfo); return lineNumberTable; } private void DoRead(MonoSymbolFile file, MyBinaryReader br, bool includesColumns, bool includesEnds) { List<LineNumberEntry> list = new List<LineNumberEntry>(); bool flag = false; bool flag2 = false; int num = 1; int num2 = 0; int file2 = 1; while (true) { byte b = br.ReadByte(); if (b == 0) { byte b2 = br.ReadByte(); long position = br.BaseStream.Position + b2; b = br.ReadByte(); switch (b) { case 1: { if (flag2) { list.Add(new LineNumberEntry(file2, num, -1, num2, flag)); } _line_numbers = list.ToArray(); if (includesColumns) { for (int i = 0; i < _line_numbers.Length; i++) { LineNumberEntry lineNumberEntry = _line_numbers[i]; if (lineNumberEntry.Row >= 0) { lineNumberEntry.Column = br.ReadLeb128(); } } } if (!includesEnds) { return; } for (int j = 0; j < _line_numbers.Length; j++) { LineNumberEntry lineNumberEntry2 = _line_numbers[j]; int num3 = br.ReadLeb128(); if (num3 == 16777215) { lineNumberEntry2.EndRow = -1; lineNumberEntry2.EndColumn = -1; } else { lineNumberEntry2.EndRow = lineNumberEntry2.Row + num3; lineNumberEntry2.EndColumn = br.ReadLeb128(); } } return; } case 64: flag = !flag; flag2 = true; break; default: throw new MonoSymbolFileException("Unknown extended opcode {0:x}", b); case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: case 98: case 99: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 109: case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127: break; } br.BaseStream.Position = position; } else if (b < OpcodeBase) { switch (b) { case 1: list.Add(new LineNumberEntry(file2, num, -1, num2, flag)); flag2 = false; break; case 2: num2 += br.ReadLeb128(); flag2 = true; break; case 3: num += br.ReadLeb128(); flag2 = true; break; case 4: file2 = br.ReadLeb128(); flag2 = true; break; case 8: num2 += MaxAddressIncrement; flag2 = true; break; default: throw new MonoSymbolFileException("Unknown standard opcode {0:x} in LNT", b); } } else { b -= OpcodeBase; num2 += b / LineRange; num += LineBase + b % LineRange; list.Add(new LineNumberEntry(file2, num, -1, num2, flag)); flag2 = false; } } } public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end) { if (_line_numbers.Length > 1) { start = _line_numbers[0]; end = _line_numbers[_line_numbers.Length - 1]; return true; } start = LineNumberEntry.Null; end = LineNumberEntry.Null; return false; } } public class MethodEntry : IComparable { [Flags] public enum Flags { LocalNamesAmbiguous = 1, ColumnsInfoIncluded = 2, EndInfoIncluded = 4 } public readonly int CompileUnitIndex; public readonly int Token; public readonly int NamespaceID; private int DataOffset; private int LocalVariableTableOffset; private int LineNumberTableOffset; private int CodeBlockTableOffset; private int ScopeVariableTableOffset; private int RealNameOffset; private Flags flags; private int index; public readonly CompileUnitEntry CompileUnit; private LocalVariableEntry[] locals; private CodeBlockEntry[] code_blocks; private ScopeVariable[] scope_vars; private LineNumberTable lnt; private string real_name; public readonly MonoSymbolFile SymbolFile; public const int Size = 12; public Flags MethodFlags => flags; public int Index { get { return index; } set { index = value; } } internal MethodEntry(MonoSymbolFile file, MyBinaryReader reader, int index) { SymbolFile = file; this.index = index; Token = reader.ReadInt32(); DataOffset = reader.ReadInt32(); LineNumberTableOffset = reader.ReadInt32(); long position = reader.BaseStream.Position; reader.BaseStream.Position = DataOffset; CompileUnitIndex = reader.ReadLeb128(); LocalVariableTableOffset = reader.ReadLeb128(); NamespaceID = reader.ReadLeb128(); CodeBlockTableOffset = reader.ReadLeb128(); ScopeVariableTableOffset = reader.ReadLeb128(); RealNameOffset = reader.ReadLeb128(); flags = (Flags)reader.ReadLeb128(); reader.BaseStream.Position = position; CompileUnit = file.GetCompileUnit(CompileUnitIndex); } internal MethodEntry(MonoSymbolFile file, CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, Flags flags, int namespace_id) { SymbolFile = file; this.real_name = real_name; this.locals = locals; this.code_blocks = code_blocks; this.scope_vars = scope_vars; this.flags = flags; index = -1; Token = token; CompileUnitIndex = comp_unit.Index; CompileUnit = comp_unit; NamespaceID = namespace_id; CheckLineNumberTable(lines); lnt = new LineNumberTable(file, lines); file.NumLineNumbers += lines.Length; int num = ((locals != null) ? locals.Length : 0); if (num <= 32) { for (int i = 0; i < num; i++) { string name = locals[i].Name; for (int j = i + 1; j < num; j++) { if (locals[j].Name == name) { flags |= Flags.LocalNamesAmbiguous; return; } } } return; } Dictionary<string, LocalVariableEntry> dictionary = new Dictionary<string, LocalVariableEntry>(); for (int k = 0; k < locals.Length; k++) { LocalVariableEntry value = locals[k]; if (dictionary.ContainsKey(value.Name)) { flags |= Flags.LocalNamesAmbiguous; break; } dictionary.Add(value.Name, value); } } private static void CheckLineNumberTable(LineNumberEntry[] line_numbers) { int num = -1; int num2 = -1; if (line_numbers == null) { return; } foreach (LineNumberEntry lineNumberEntry in line_numbers) { if (lineNumberEntry.Equals(LineNumberEntry.Null)) { throw new MonoSymbolFileException(); } if (lineNumberEntry.Offset < num) { throw new MonoSymbolFileException(); } if (lineNumberEntry.Offset > num) { num2 = lineNumberEntry.Row; num = lineNumberEntry.Offset; } else if (lineNumberEntry.Row > num2) { num2 = lineNumberEntry.Row; } } } internal void Write(MyBinaryWriter bw) { if (index <= 0 || DataOffset == 0) { throw new InvalidOperationException(); } bw.Write(Token); bw.Write(DataOffset); bw.Write(LineNumberTableOffset); } internal void WriteData(MonoSymbolFile file, MyBinaryWriter bw) { if (index <= 0) { throw new InvalidOperationException(); } LocalVariableTableOffset = (int)bw.BaseStream.Position; int num = ((locals != null) ? locals.Length : 0); bw.WriteLeb128(num); for (int i = 0; i < num; i++) { locals[i].Write(file, bw); } file.LocalCount += num; CodeBlockTableOffset = (int)bw.BaseStream.Position; int num2 = ((code_blocks != null) ? code_blocks.Length : 0); bw.WriteLeb128(num2); for (int j = 0; j < num2; j++) { code_blocks[j].Write(bw); } ScopeVariableTableOffset = (int)bw.BaseStream.Position; int num3 = ((scope_vars != null) ? scope_vars.Length : 0); bw.WriteLeb128(num3); for (int k = 0; k < num3; k++) { scope_vars[k].Write(bw); } if (real_name != null) { RealNameOffset = (int)bw.BaseStream.Position; bw.Write(real_name); } LineNumberEntry[] lineNumbers = lnt.LineNumbers; foreach (LineNumberEntry lineNumberEntry in lineNumbers) { if (lineNumberEntry.EndRow != -1 || lineNumberEntry.EndColumn != -1) { flags |= Flags.EndInfoIncluded; } } LineNumberTableOffset = (int)bw.BaseStream.Position; lnt.Write(file, bw, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); DataOffset = (int)bw.BaseStream.Position; bw.WriteLeb128(CompileUnitIndex); bw.WriteLeb128(LocalVariableTableOffset); bw.WriteLeb128(NamespaceID); bw.WriteLeb128(CodeBlockTableOffset); bw.WriteLeb128(ScopeVariableTableOffset); bw.WriteLeb128(RealNameOffset); bw.WriteLeb128((int)flags); } public void ReadAll() { GetLineNumberTable(); GetLocals(); GetCodeBlocks(); GetScopeVariables(); GetRealName(); } public LineNumberTable GetLineNumberTable() { lock (SymbolFile) { if (lnt != null) { return lnt; } if (LineNumberTableOffset == 0) { return null; } MyBinaryReader binaryReader = SymbolFile.BinaryReader; long position = binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = LineNumberTableOffset; lnt = LineNumberTable.Read(SymbolFile, binaryReader, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); binaryReader.BaseStream.Position = position; return lnt; } } public LocalVariableEntry[] GetLocals() { lock (SymbolFile) { if (locals != null) { return locals; } if (LocalVariableTableOffset == 0) { return null; } MyBinaryReader binaryReader = SymbolFile.BinaryReader; long position = binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = LocalVariableTableOffset; int num = binaryReader.ReadLeb128(); locals = new LocalVariableEntry[num]; for (int i = 0; i < num; i++) { locals[i] = new LocalVariableEntry(SymbolFile, binaryReader); } binaryReader.BaseStream.Position = position; return locals; } } public CodeBlockEntry[] GetCodeBlocks() { lock (SymbolFile) { if (code_blocks != null) { return code_blocks; } if (CodeBlockTableOffset == 0) { return null; } MyBinaryReader binaryReader = SymbolFile.BinaryReader; long position = binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = CodeBlockTableOffset; int num = binaryReader.ReadLeb128(); code_blocks = new CodeBlockEntry[num]; for (int i = 0; i < num; i++) { code_blocks[i] = new CodeBlockEntry(i, binaryReader); } binaryReader.BaseStream.Position = position; return code_blocks; } } public ScopeVariable[] GetScopeVariables() { lock (SymbolFile) { if (scope_vars != null) { return scope_vars; } if (ScopeVariableTableOffset == 0) { return null; } MyBinaryReader binaryReader = SymbolFile.BinaryReader; long position = binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = ScopeVariableTableOffset; int num = binaryReader.ReadLeb128(); scope_vars = new ScopeVariable[num]; for (int i = 0; i < num; i++) { scope_vars[i] = new ScopeVariable(binaryReader); } binaryReader.BaseStream.Position = position; return scope_vars; } } public string GetRealName() { lock (SymbolFile) { if (real_name != null) { return real_name; } if (RealNameOffset == 0) { return null; } real_name = SymbolFile.BinaryReader.ReadString(RealNameOffset); return real_name; } } public int CompareTo(object obj) { MethodEntry methodEntry = (MethodEntry)obj; if (methodEntry.Token < Token) { return 1; } if (methodEntry.Token > Token) { return -1; } return 0; } public override string ToString() { return $"[Method {index}:{Token:x}:{CompileUnitIndex}:{CompileUnit}]"; } } public struct NamespaceEntry { public readonly string Name; public readonly int Index; public readonly int Parent; public readonly string[] UsingClauses; public NamespaceEntry(string name, int index, string[] using_clauses, int parent) { Name = name; Index = index; Parent = parent; UsingClauses = ((using_clauses != null) ? using_clauses : new string[0]); } internal NamespaceEntry(MonoSymbolFile file, MyBinaryReader reader) { Name = reader.ReadString(); Index = reader.ReadLeb128(); Parent = reader.ReadLeb128(); int num = reader.ReadLeb128(); UsingClauses = new string[num]; for (int i = 0; i < num; i++) { UsingClauses[i] = reader.ReadString(); } } internal void Write(MonoSymbolFile file, MyBinaryWriter bw) { bw.Write(Name); bw.WriteLeb128(Index); bw.WriteLeb128(Parent); bw.WriteLeb128(UsingClauses.Length); string[] usingClauses = UsingClauses; foreach (string value in usingClauses) { bw.Write(value); } } public override string ToString() { return $"[Namespace {Name}:{Index}:{Parent}]"; } } public class MonoSymbolWriter { private List<SourceMethodBuilder> methods; private List<SourceFileEntry> sources; private List<CompileUnitEntry> comp_units; protected readonly MonoSymbolFile file; private string filename; private SourceMethodBuilder current_method; private Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder>(); public MonoSymbolFile SymbolFile => file; public MonoSymbolWriter(string filename) { methods = new List<SourceMethodBuilder>(); sources = new List<SourceFileEntry>(); comp_units = new List<CompileUnitEntry>(); file = new MonoSymbolFile(); this.filename = filename + ".mdb"; } public void CloseNamespace() { } public void DefineLocalVariable(int index, string name) { if (current_method != null) { current_method.AddLocal(index, name); } } public void DefineCapturedLocal(int scope_id, string name, string captured_name) { file.DefineCapturedVariable(scope_id, name, captured_name, CapturedVariable.CapturedKind.Local); } public void DefineCapturedParameter(int scope_id, string name, string captured_name) { file.DefineCapturedVariable(scope_id, name, captured_name, CapturedVariable.CapturedKind.Parameter); } public void DefineCapturedThis(int scope_id, string captured_name) { file.DefineCapturedVariable(scope_id, "this", captured_name, CapturedVariable.CapturedKind.This); } public void DefineCapturedScope(int scope_id, int id, string captured_name) { file.DefineCapturedScope(scope_id, id, captured_name); } public void DefineScopeVariable(int scope, int index) { if (current_method != null) { current_method.AddScopeVariable(scope, index); } } public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden) { if (current_method != null) { current_method.MarkSequencePoint(offset, file, line, column, is_hidden); } } public SourceMethodBuilder OpenMethod(ICompileUnit file, int ns_id, IMethodDef method) { SourceMethodBuilder result = new SourceMethodBuilder(file, ns_id, method); current_method_stack.Push(current_method); current_method = result; methods.Add(current_method); return result; } public void CloseMethod() { current_method = current_method_stack.Pop(); } public SourceFileEntry DefineDocument(string url) { SourceFileEntry sourceFileEntry = new SourceFileEntry(file, url); sources.Add(sourceFileEntry); return sourceFileEntry; } public SourceFileEntry DefineDocument(string url, byte[] guid, byte[] checksum) { SourceFileEntry sourceFileEntry = new SourceFileEntry(file, url, guid, checksum); sources.Add(sourceFileEntry); return sourceFileEntry; } public CompileUnitEntry DefineCompilationUnit(SourceFileEntry source) { CompileUnitEntry compileUnitEntry = new CompileUnitEntry(file, source); comp_units.Add(compileUnitEntry); return compileUnitEntry; } public int DefineNamespace(string name, CompileUnitEntry unit, string[] using_clauses, int parent) { if (unit == null || using_clauses == null) { throw new NullReferenceException(); } return unit.DefineNamespace(name, using_clauses, parent); } public int OpenScope(int start_offset) { if (current_method == null) { return 0; } current_method.StartBlock(CodeBlockEntry.Type.Lexical, start_offset); return 0; } public void CloseScope(int end_offset) { if (current_method != null) { current_method.EndBlock(end_offset); } } public void OpenCompilerGeneratedBlock(int start_offset) { if (current_method != null) { current_method.StartBlock(CodeBlockEntry.Type.CompilerGenerated, start_offset); } } public void CloseCompilerGeneratedBlock(int end_offset) { if (current_method != null) { current_method.EndBlock(end_offset); } } public void StartIteratorBody(int start_offset) { current_method.StartBlock(CodeBlockEntry.Type.IteratorBody, start_offset); } public void EndIteratorBody(int end_offset) { current_method.EndBlock(end_offset); } public void StartIteratorDispatcher(int start_offset) { current_method.StartBlock(CodeBlockEntry.Type.IteratorDispatcher, start_offset); } public void EndIteratorDispatcher(int end_offset) { current_method.EndBlock(end_offset); } public void DefineAnonymousScope(int id) { file.DefineAnonymousScope(id); } public void WriteSymbolFile(Guid guid) { foreach (SourceMethodBuilder method in methods) { method.DefineMethod(file); } try { File.Delete(filename); } catch { } using FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write); file.CreateSymbolFile(guid, fs); } } public class SourceMethodBuilder { private List<LocalVariableEntry> _locals; private List<CodeBlockEntry> _blocks; private List<ScopeVariable> _scope_vars; private Stack<CodeBlockEntry> _block_stack; private readonly List<LineNumberEntry> method_lines; private readonly ICompileUnit _comp_unit; private readonly int ns_id; private readonly IMethodDef method; public CodeBlockEntry[] Blocks { get { if (_blocks == null) { return new CodeBlockEntry[0]; } CodeBlockEntry[] array = new CodeBlockEntry[_blocks.Count]; _blocks.CopyTo(array, 0); return array; } } public CodeBlockEntry CurrentBlock { get { if (_block_stack != null && _block_stack.Count > 0) { return _block_stack.Peek(); } return null; } } public LocalVariableEntry[] Locals { get { if (_locals == null) { return new LocalVariableEntry[0]; } return _locals.ToArray(); } } public ICompileUnit SourceFile => _comp_unit; public ScopeVariable[] ScopeVariables { get { if (_scope_vars == null) { return new ScopeVariable[0]; } return _scope_vars.ToArray(); } } public SourceMethodBuilder(ICompileUnit comp_unit) { _comp_unit = comp_unit; method_lines = new List<LineNumberEntry>(); } public SourceMethodBuilder(ICompileUnit comp_unit, int ns_id, IMethodDef method) : this(comp_unit) { this.ns_id = ns_id; this.method = method; } public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden) { MarkSequencePoint(offset, file, line, column, -1, -1, is_hidden); } public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, int end_line, int end_column, bool is_hidden) { LineNumberEntry lineNumberEntry = new LineNumberEntry(file?.Index ?? 0, line, column, end_line, end_column, offset, is_hidden); if (method_lines.Count > 0) { LineNumberEntry lineNumberEntry2 = method_lines[method_lines.Count - 1]; if (lineNumberEntry2.Offset == offset) { if (LineNumberEntry.LocationComparer.Default.Compare(lineNumberEntry, lineNumberEntry2) > 0) { method_lines[method_lines.Count - 1] = lineNumberEntry; } return; } } method_lines.Add(lineNumberEntry); } public void StartBlock(CodeBlockEntry.Type type, int start_offset) { StartBlock(type, start_offset, (_blocks == null) ? 1 : (_blocks.Count + 1)); } public void StartBlock(CodeBlockEntry.Type type, int start_offset, int scopeIndex) { if (_block_stack == null) { _block_stack = new Stack<CodeBlockEntry>(); } if (_blocks == null) { _blocks = new List<CodeBlockEntry>(); } int parent = ((CurrentBlock != null) ? CurrentBlock.Index : (-1)); CodeBlockEntry item = new CodeBlockEntry(scopeIndex, parent, type, start_offset); _block_stack.Push(item); _blocks.Add(item); } public void EndBlock(int end_offset) { _block_stack.Pop().Close(end_offset); } public void AddLocal(int index, string name) { if (_locals == null) { _locals = new List<LocalVariableEntry>(); } int block = ((CurrentBlock != null) ? CurrentBlock.Index : 0); _locals.Add(new LocalVariableEntry(index, name, block)); } public void AddScopeVariable(int scope, int index) { if (_scope_vars == null) { _scope_vars = new List<ScopeVariable>(); } _scope_vars.Add(new ScopeVariable(scope, index)); } public void DefineMethod(MonoSymbolFile file) { DefineMethod(file, method.Token); } public void DefineMethod(MonoSymbolFile file, int token) { CodeBlockEntry[] array = Blocks; if (array.Length != 0) { List<CodeBlockEntry> list = new List<CodeBlockEntry>(array.Length); int num = 0; for (int i = 0; i < array.Length; i++) { num = Math.Max(num, array[i].Index); } for (int j = 0; j < num; j++) { int num2 = j + 1; if (j < array.Length && array[j].Index == num2) { list.Add(array[j]); continue; } bool flag = false; for (int k = 0; k < array.Length; k++) { if (array[k].Index == num2) { list.Add(array[k]); flag = true; break; } } if (!flag) { list.Add(new CodeBlockEntry(num2, -1, CodeBlockEntry.Type.CompilerGenerated, 0)); } } array = list.ToArray(); } MethodEntry entry = new MethodEntry(file, _comp_unit.Entry, token, ScopeVariables, Locals, method_lines.ToArray(), array, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id); file.AddMethod(entry); } } } namespace Mono.Cecil.Mdb { public sealed class MdbReaderProvider : ISymbolReaderProvider { public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName) { Mixin.CheckModule(module); Mixin.CheckFileName(fileName); return (ISymbolReader)(object)new MdbReader(module, MonoSymbolFile.ReadSymbolFile(Mixin.GetMdbFileName(fileName))); } public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) { Mixin.CheckModule(module); Mixin.CheckStream((object)symbolStream); return (ISymbolReader)(object)new MdbReader(module, MonoSymbolFile.ReadSymbolFile(symbolStream)); } } public sealed class MdbReader : ISymbolReader, IDisposable { private readonly ModuleDefinition module; private readonly MonoSymbolFile symbol_file; private readonly Dictionary<string, Document> documents; public MdbReader(ModuleDefinition module, MonoSymbolFile symFile) { this.module = module; symbol_file = symFile; documents = new Dictionary<string, Document>(); } public ISymbolWriterProvider GetWriterProvider() { return (ISymbolWriterProvider)(object)new MdbWriterProvider(); } public bool ProcessDebugHeader(ImageDebugHeader header) { return symbol_file.Guid == module.Mvid; } public MethodDebugInformation Read(MethodDefinition method) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0026: Expected O, but got Unknown MetadataToken metadataToken = ((MemberReference)method).MetadataToken; MethodEntry methodByToken = symbol_file.GetMethodByToken(((MetadataToken)(ref metadataToken)).ToInt32()); if (methodByToken == null) { return null; } MethodDebugInformation val = new MethodDebugInformation(method); val.code_size = ReadCodeSize(method); ScopeDebugInformation[] scopes = ReadScopes(methodByToken, val); ReadLineNumbers(methodByToken, val); ReadLocalVariables(methodByToken, scopes); return val; } private static int ReadCodeSize(MethodDefinition method) { return ((MemberReference)method).Module.Read<MethodDefinition, int>(method, (Func<MethodDefinition, MetadataReader, int>)((MethodDefinition m, MetadataReader reader) => reader.ReadCodeSize(m))); } private static void ReadLocalVariables(MethodEntry entry, ScopeDebugInformation[] scopes) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown LocalVariableEntry[] locals = entry.GetLocals(); for (int i = 0; i < locals.Length; i++) { LocalVariableEntry localVariableEntry = locals[i]; VariableDebugInformation val = new VariableDebugInformation(localVariableEntry.Index, localVariableEntry.Name); int blockIndex = localVariableEntry.BlockIndex; if (blockIndex >= 0 && blockIndex < scopes.Length) { ScopeDebugInformation val2 = scopes[blockIndex]; if (val2 != null) { val2.Variables.Add(val); } } } } private void ReadLineNumbers(MethodEntry entry, MethodDebugInformation info) { LineNumberTable lineNumberTable = entry.GetLineNumberTable(); info.sequence_points = new Collection<SequencePoint>(lineNumberTable.LineNumbers.Length); for (int i = 0; i < lineNumberTable.LineNumbers.Length; i++) { LineNumberEntry lineNumberEntry = lineNumberTable.LineNumbers[i]; if (i <= 0 || lineNumberTable.LineNumbers[i - 1].Offset != lineNumberEntry.Offset) { info.sequence_points.Add(LineToSequencePoint(lineNumberEntry)); } } } private Document GetDocument(SourceFileEntry file) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown string fileName = file.FileName; if (documents.TryGetValue(fileName, out var value)) { return value; } value = new Document(fileName) { Hash = file.Checksum }; documents.Add(fileName, value); return value; } private static ScopeDebugInformation[] ReadScopes(MethodEntry entry, MethodDebugInformation info) { //IL_0014: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0039: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_006d: 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) CodeBlockEntry[] codeBlocks = entry.GetCodeBlocks(); ScopeDebugInformation[] array = (ScopeDebugInformation[])(object)new ScopeDebugInformation[codeBlocks.Length + 1]; ScopeDebugInformation val = new ScopeDebugInformation { Start = new InstructionOffset(0), End = new InstructionOffset(info.code_size) }; ScopeDebugInformation scope = val; array[0] = val; info.scope = scope; CodeBlockEntry[] array2 = codeBlocks; foreach (CodeBlockEntry codeBlockEntry in array2) { if (codeBlockEntry.BlockType == CodeBlockEntry.Type.Lexical || codeBlockEntry.BlockType == CodeBlockEntry.Type.CompilerGenerated) { ScopeDebugInformation val2 = new ScopeDebugInformation(); val2.Start = new InstructionOffset(codeBlockEntry.StartOffset); val2.End = new InstructionOffset(codeBlockEntry.EndOffset); array[codeBlockEntry.Index + 1] = val2; if (!AddScope(info.scope.Scopes, val2)) { info.scope.Scopes.Add(val2); } } } return array; } private static bool AddScope(Collection<ScopeDebugInformation> scopes, ScopeDebugInformation scope) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_005d: Unknown result type (might be due to invalid IL or missing references) Enumerator<ScopeDebugInformation> enumerator = scopes.GetEnumerator(); try { while (enumerator.MoveNext()) { ScopeDebugInformation current = enumerator.Current; if (current.HasScopes && AddScope(current.Scopes, scope)) { return true; } InstructionOffset val = scope.Start; int offset = ((InstructionOffset)(ref val)).Offset; val = current.Start; if (offset >= ((InstructionOffset)(ref val)).Offset) { val = scope.End; int offset2 = ((InstructionOffset)(ref val)).Offset; val = current.End; if (offset2 <= ((InstructionOffset)(ref val)).Offset) { current.Scopes.Add(scope); return true; } } } } finally { ((IDisposable)enumerator).Dispose(); } return false; } private SequencePoint LineToSequencePoint(LineNumberEntry line) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown SourceFileEntry sourceFile = symbol_file.GetSourceFile(line.File); return new SequencePoint(line.Offset, GetDocument(sourceFile)) { StartLine = line.Row, EndLine = line.EndRow, StartColumn = line.Column, EndColumn = line.EndColumn }; } public Collection<CustomDebugInformation> Read(ICustomDebugInformationProvider provider) { return new Collection<CustomDebugInformation>(); } public void Dispose() { symbol_file.Dispose(); } } internal static class MethodEntryExtensions { public static bool HasColumnInfo(this MethodEntry entry) { return (entry.MethodFlags & MethodEntry.Flags.ColumnsInfoIncluded) != 0; } public static bool HasEndInfo(this MethodEntry entry) { return (entry.MethodFlags & MethodEntry.Flags.EndInfoIncluded) != 0; } } public sealed class MdbWriterProvider : ISymbolWriterProvider { public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName) { Mixin.CheckModule(module); Mixin.CheckFileName(fileName); return (ISymbolWriter)(object)new MdbWriter(module, fileName); } public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream) { throw new NotImplementedException(); } } public sealed class MdbWriter : ISymbolWriter, IDisposable { private class SourceFile : ISourceFile { private readonly CompileUnitEntry compilation_unit; private readonly SourceFileEntry entry; public SourceFileEntry Entry => entry; public CompileUnitEntry CompilationUnit => compilation_unit; public SourceFile(CompileUnitEntry comp_unit, SourceFileEntry entry) { compilation_unit = comp_unit; this.entry = entry; } } private class SourceMethod : IMethodDef { private readonly MethodDefinition method; public string Name => ((MemberReference)method).Name; public int Token { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) MetadataToken metadataToken = ((MemberReference)method).MetadataToken; return ((MetadataToken)(ref metadataToken)).ToInt32(); } } public SourceMethod(MethodDefinition method) { this.method = method; } } private readonly ModuleDefinition module; private readonly MonoSymbolWriter writer; private readonly Dictionary<string, SourceFile> source_files; public MdbWriter(ModuleDefinition module, string assembly) { this.module = module; writer = new MonoSymbolWriter(assembly); source_files = new Dictionary<string, SourceFile>(); } public ISymbolReaderProvider GetReaderProvider() { return (ISymbolReaderProvider)(object)new MdbReaderProvider(); } private SourceFile GetSourceFile(Document document) { string url = document.Url; if (source_files.TryGetValue(url, out var value)) { return value; } SourceFileEntry sourceFileEntry = writer.DefineDocument(url, null, (document.Hash != null && document.Hash.Length == 16) ? document.Hash : null); value = new SourceFile(writer.DefineCompilationUnit(sourceFileEntry), sourceFileEntry); source_files.Add(url, value); return value; } private void Populate(Collection<SequencePoint> sequencePoints, int[] offsets, int[] startRows, int[] endRows, int[] startCols, int[] endCols, out SourceFile file) { SourceFile sourceFile = null; for (int i = 0; i < sequencePoints.Count; i++) { SequencePoint val = sequencePoints[i]; offsets[i] = val.Offset; if (sourceFile == null) { sourceFile = GetSourceFile(val.Document); } startRows[i] = val.StartLine; endRows[i] = val.EndLine; startCols[i] = val.StartColumn; endCols[i] = val.EndColumn; } file = sourceFile; } public void Write(MethodDebugInformation info) { SourceMethod method = new SourceMethod(info.method); Collection<SequencePoint> sequencePoints = info.SequencePoints; int count = sequencePoints.Count; if (count != 0) { int[] array = new int[count]; int[] array2 = new int[count]; int[] array3 = new int[count]; int[] array4 = new int[count]; int[] array5 = new int[count]; Populate(sequencePoints, array, array2, array3, array4, array5, out var file); SourceMethodBuilder sourceMethodBuilder = writer.OpenMethod(file.CompilationUnit, 0, method); for (int i = 0; i < count; i++) { sourceMethodBuilder.MarkSequencePoint(array[i], file.CompilationUnit.SourceFile, array2[i], array4[i], array3[i], array5[i], is_hidden: false); } if (info.scope != null) { WriteRootScope(info.scope, info); } writer.CloseMethod(); } } private void WriteRootScope(ScopeDebugInformation scope, MethodDebugInformation info) { WriteScopeVariables(scope); if (scope.HasScopes) { WriteScopes(scope.Scopes, info); } } private void WriteScope(ScopeDebugInformation scope, MethodDebugInformation info) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) MonoSymbolWriter monoSymbolWriter = writer; InstructionOffset val = scope.Start; monoSymbolWriter.OpenScope(((InstructionOffset)(ref val)).Offset); WriteScopeVariables(scope); if (scope.HasScopes) { WriteScopes(scope.Scopes, info); } MonoSymbolWriter monoSymbolWriter2 = writer; val = scope.End; int end_offset; if (!((InstructionOffset)(ref val)).IsEndOfMethod) { val = scope.End; end_offset = ((InstructionOffset)(ref val)).Offset; } else { end_offset = info.code_size; } monoSymbolWriter2.CloseScope(end_offset); } private void WriteScopes(Collection<ScopeDebugInformation> scopes, MethodDebugInformation info) { for (int i = 0; i < scopes.Count; i++) { WriteScope(scopes[i], info); } } private void WriteScopeVariables(ScopeDebugInformation scope) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!scope.HasVariables) { return; } Enumerator<VariableDebugInformation> enumerator = scope.variables.GetEnumerator(); try { while (enumerator.MoveNext()) { VariableDebugInformation current = enumerator.Current; if (!string.IsNullOrEmpty(current.Name)) { writer.DefineLocalVariable(current.Index, current.Name); } } } finally { ((IDisposable)enumerator).Dispose(); } } public ImageDebugHeader GetDebugHeader() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown return new ImageDebugHeader(); } public void Write() { } public void Write(ICustomDebugInformationProvider provider) { } public void Dispose() { writer.WriteSymbolFile(module.Mvid); } } }
BepInExPack/BepInEx/core/Mono.Cecil.Pdb.dll
Decompiled a day 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.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using Microsoft.Cci.Pdb; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using Mono.Cecil.PE; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyProduct("Mono.Cecil")] [assembly: AssemblyCopyright("Copyright © 2008 - 2018 Jb Evain")] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("0.11.6.0")] [assembly: AssemblyInformationalVersion("0.11.6.0")] [assembly: AssemblyTitle("Mono.Cecil.Pdb")] [assembly: CLSCompliant(false)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.11.6.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 Mono.Cecil.Pdb { [ComImport] [Guid("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface ISymUnmanagedDocumentWriter { void SetSource(uint sourceSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] source); void SetCheckSum(Guid algorithmId, uint checkSumSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] checkSum); } [ComImport] [Guid("0B97726E-9E6D-4f05-9A26-424022093CAA")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface ISymUnmanagedWriter2 { void DefineDocument([In][MarshalAs(UnmanagedType.LPWStr)] string url, [In] ref Guid langauge, [In] ref Guid languageVendor, [In] ref Guid documentType, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedDocumentWriter pRetVal); void SetUserEntryPoint([In] int methodToken); void OpenMethod([In] int methodToken); void CloseMethod(); void OpenScope([In] int startOffset, out int pRetVal); void CloseScope([In] int endOffset); void SetScopeRange_Placeholder(); void DefineLocalVariable_Placeholder(); void DefineParameter_Placeholder(); void DefineField_Placeholder(); void DefineGlobalVariable_Placeholder(); void Close(); void SetSymAttribute(uint parent, string name, uint data, IntPtr signature); void OpenNamespace([In][MarshalAs(UnmanagedType.LPWStr)] string name); void CloseNamespace(); void UsingNamespace([In][MarshalAs(UnmanagedType.LPWStr)] string fullName); void SetMethodSourceRange_Placeholder(); void Initialize([In][MarshalAs(UnmanagedType.IUnknown)] object emitter, [In][MarshalAs(UnmanagedType.LPWStr)] string filename, [In] IStream pIStream, [In] bool fFullBuild); void GetDebugInfo(out ImageDebugDirectory pIDD, [In] int cData, out int pcData, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data); void DefineSequencePoints([In][MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter document, [In] int spCount, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] offsets, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] lines, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] columns, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endLines, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endColumns); void RemapToken_Placeholder(); void Initialize2_Placeholder(); void DefineConstant_Placeholder(); void Abort_Placeholder(); void DefineLocalVariable2([In][MarshalAs(UnmanagedType.LPWStr)] string name, [In] int attributes, [In] int sigToken, [In] int addrKind, [In] int addr1, [In] int addr2, [In] int addr3, [In] int startOffset, [In] int endOffset); void DefineGlobalVariable2_Placeholder(); void DefineConstant2([In][MarshalAs(UnmanagedType.LPWStr)] string name, [In][MarshalAs(UnmanagedType.Struct)] object variant, [In] int sigToken); } [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("BA3FEE4C-ECB9-4e41-83B7-183FA41CD859")] internal interface IMetaDataEmit { void SetModuleProps(string szName); void Save(string szFile, uint dwSaveFlags); void SaveToStream(IntPtr pIStream, uint dwSaveFlags); uint GetSaveSize(uint fSave); uint DefineTypeDef(IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements); uint DefineNestedType(IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements, uint tdEncloser); void SetHandler([In][MarshalAs(UnmanagedType.IUnknown)] object pUnk); uint DefineMethod(uint td, IntPtr zName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags); void DefineMethodImpl(uint td, uint tkBody, uint tkDecl); uint DefineTypeRefByName(uint tkResolutionScope, IntPtr szName); uint DefineImportType(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint tdImport, IntPtr pAssemEmit); uint DefineMemberRef(uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob); uint DefineImportMember(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent); uint DefineEvent(uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods); void SetClassLayout(uint td, uint dwPackSize, IntPtr rFieldOffsets, uint ulClassSize); void DeleteClassLayout(uint td); void SetFieldMarshal(uint tk, IntPtr pvNativeType, uint cbNativeType); void DeleteFieldMarshal(uint tk); uint DefinePermissionSet(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission); void SetRVA(uint md, uint ulRVA); uint GetTokenFromSig(IntPtr pvSig, uint cbSig); uint DefineModuleRef(string szName); void SetParent(uint mr, uint tk); uint GetTokenFromTypeSpec(IntPtr pvSig, uint cbSig); void SaveToMemory(IntPtr pbData, uint cbData); uint DefineUserString(string szString, uint cchString); void DeleteToken(uint tkObj); void SetMethodProps(uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags); void SetTypeDefProps(uint td, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements); void SetEventProps(uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods); uint SetPermissionSetProps(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission); void DefinePinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL); void SetPinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL); void DeletePinvokeMap(uint tk); uint DefineCustomAttribute(uint tkObj, uint tkType, IntPtr pCustomAttribute, uint cbCustomAttribute); void SetCustomAttributeValue(uint pcv, IntPtr pCustomAttribute, uint cbCustomAttribute); uint DefineField(uint td, string szName, uint dwFieldFlags, IntPtr pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue); uint DefineProperty(uint td, string szProperty, uint dwPropFlags, IntPtr pvSig, uint cbSig, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods); uint DefineParam(uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue); void SetFieldProps(uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue); void SetPropertyProps(uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods); void SetParamProps(uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue); uint DefineSecurityAttributeSet(uint tkObj, IntPtr rSecAttrs, uint cSecAttrs); void ApplyEditAndContinue([MarshalAs(UnmanagedType.IUnknown)] object pImport); uint TranslateSigWithScope(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport import, IntPtr pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr pvTranslatedSig, uint cbTranslatedSigMax); void SetMethodImplFlags(uint md, uint dwImplFlags); void SetFieldRVA(uint fd, uint ulRVA); void Merge(IMetaDataImport pImport, IntPtr pHostMapToken, [MarshalAs(UnmanagedType.IUnknown)] object pHandler); void MergeEnd(); } [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44")] internal interface IMetaDataImport { [PreserveSig] void CloseEnum(uint hEnum); uint CountEnum(uint hEnum); void ResetEnum(uint hEnum, uint ulPos); uint EnumTypeDefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeDefs, uint cMax); uint EnumInterfaceImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rImpls, uint cMax); uint EnumTypeRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeRefs, uint cMax); uint FindTypeDefByName(string szTypeDef, uint tkEnclosingClass); Guid GetScopeProps(StringBuilder szName, uint cchName, out uint pchName); uint GetModuleFromScope(); [PreserveSig] unsafe uint GetTypeDefProps(uint td, char* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends); uint GetInterfaceImplProps(uint iiImpl, out uint pClass); uint GetTypeRefProps(uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName); uint ResolveTypeRef(uint tr, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppIScope); uint EnumMembers(ref uint phEnum, uint cl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMembers, uint cMax); uint EnumMembersWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMembers, uint cMax); uint EnumMethods(ref uint phEnum, uint cl, IntPtr rMethods, uint cMax); uint EnumMethodsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethods, uint cMax); uint EnumFields(ref uint phEnum, uint cl, IntPtr rFields, uint cMax); uint EnumFieldsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rFields, uint cMax); uint EnumParams(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rParams, uint cMax); uint EnumMemberRefs(ref uint phEnum, uint tkParent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMemberRefs, uint cMax); uint EnumMethodImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodBody, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodDecl, uint cMax); uint EnumPermissionSets(ref uint phEnum, uint tk, uint dwActions, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rPermission, uint cMax); uint FindMember(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob); uint FindMethod(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob); uint FindField(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob); uint FindMemberRef(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob); [PreserveSig] unsafe uint GetMethodProps(uint mb, uint* pClass, char* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, uint* pulCodeRVA, uint* pdwImplFlags); uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob); uint EnumProperties(ref uint phEnum, uint td, IntPtr rProperties, uint cMax); uint EnumEvents(ref uint phEnum, uint td, IntPtr rEvents, uint cMax); uint GetEventProps(uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)] uint[] rmdOtherMethod, uint cMax); uint EnumMethodSemantics(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rEventProp, uint cMax); uint GetMethodSemantics(uint mb, uint tkEventProp); uint GetClassLayout(uint td, out uint pdwPackSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset); uint GetFieldMarshal(uint tk, out IntPtr ppvNativeType); uint GetRVA(uint tk, out uint pulCodeRVA); uint GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission); uint GetSigFromToken(uint mdSig, out IntPtr ppvSig); uint GetModuleRefProps(uint mur, StringBuilder szName, uint cchName); uint EnumModuleRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rModuleRefs, uint cmax); uint GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig); uint GetNameFromToken(uint tk); uint EnumUnresolvedMethods(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rMethods, uint cMax); uint GetUserString(uint stk, StringBuilder szString, uint cchString); uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName); uint EnumSignatures(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rSignatures, uint cmax); uint EnumTypeSpecs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeSpecs, uint cmax); uint EnumUserStrings(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rStrings, uint cmax); [PreserveSig] int GetParamForMethodIndex(uint md, uint ulParamSeq, out uint pParam); uint EnumCustomAttributes(ref uint phEnum, uint tk, uint tkType, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rCustomAttributes, uint cMax); uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob); uint FindTypeRef(uint tkResolutionScope, string szName); uint GetMemberProps(uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue); uint GetFieldProps(uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue); uint GetPropertyProps(uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 14)] uint[] rmdOtherMethod, uint cMax); uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue); uint GetCustomAttributeByName(uint tkObj, string szName, out IntPtr ppData); [PreserveSig] [return: MarshalAs(UnmanagedType.Bool)] bool IsValidToken(uint tk); [PreserveSig] unsafe uint GetNestedClassProps(uint tdNestedClass, uint* ptdEnclosingClass); uint GetNativeCallConvFromSig(IntPtr pvSig, uint cbSig); int IsGlobal(uint pd); } internal class ModuleMetadata : IMetaDataEmit, IMetaDataImport { private readonly ModuleDefinition module; private Dictionary<uint, TypeDefinition> types; private Dictionary<uint, MethodDefinition> methods; private const uint S_OK = 0u; private const uint E_FAIL = 2147500037u; public ModuleMetadata(ModuleDefinition module) { this.module = module; } private bool TryGetType(uint token, out TypeDefinition type) { if (types == null) { InitializeMetadata(module); } return types.TryGetValue(token, out type); } private bool TryGetMethod(uint token, out MethodDefinition method) { if (methods == null) { InitializeMetadata(module); } return methods.TryGetValue(token, out method); } private void InitializeMetadata(ModuleDefinition module) { //IL_0032: 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) types = new Dictionary<uint, TypeDefinition>(); methods = new Dictionary<uint, MethodDefinition>(); foreach (TypeDefinition type in module.GetTypes()) { Dictionary<uint, TypeDefinition> dictionary = types; MetadataToken metadataToken = ((MemberReference)type).MetadataToken; dictionary.Add(((MetadataToken)(ref metadataToken)).ToUInt32(), type); InitializeMethods(type); } } private void InitializeMethods(TypeDefinition type) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0022: Unknown result type (might be due to invalid IL or missing references) Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator(); try { while (enumerator.MoveNext()) { MethodDefinition current = enumerator.Current; Dictionary<uint, MethodDefinition> dictionary = methods; MetadataToken metadataToken = ((MemberReference)current).MetadataToken; dictionary.Add(((MetadataToken)(ref metadataToken)).ToUInt32(), current); } } finally { ((IDisposable)enumerator).Dispose(); } } public void SetModuleProps(string szName) { throw new NotImplementedException(); } public void Save(string szFile, uint dwSaveFlags) { throw new NotImplementedException(); } public void SaveToStream(IntPtr pIStream, uint dwSaveFlags) { throw new NotImplementedException(); } public uint GetSaveSize(uint fSave) { throw new NotImplementedException(); } public uint DefineTypeDef(IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements) { throw new NotImplementedException(); } public uint DefineNestedType(IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements, uint tdEncloser) { throw new NotImplementedException(); } public void SetHandler(object pUnk) { throw new NotImplementedException(); } public uint DefineMethod(uint td, IntPtr zName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags) { throw new NotImplementedException(); } public void DefineMethodImpl(uint td, uint tkBody, uint tkDecl) { throw new NotImplementedException(); } public uint DefineTypeRefByName(uint tkResolutionScope, IntPtr szName) { throw new NotImplementedException(); } public uint DefineImportType(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint tdImport, IntPtr pAssemEmit) { throw new NotImplementedException(); } public uint DefineMemberRef(uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob) { throw new NotImplementedException(); } public uint DefineImportMember(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent) { throw new NotImplementedException(); } public uint DefineEvent(uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods) { throw new NotImplementedException(); } public void SetClassLayout(uint td, uint dwPackSize, IntPtr rFieldOffsets, uint ulClassSize) { throw new NotImplementedException(); } public void DeleteClassLayout(uint td) { throw new NotImplementedException(); } public void SetFieldMarshal(uint tk, IntPtr pvNativeType, uint cbNativeType) { throw new NotImplementedException(); } public void DeleteFieldMarshal(uint tk) { throw new NotImplementedException(); } public uint DefinePermissionSet(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission) { throw new NotImplementedException(); } public void SetRVA(uint md, uint ulRVA) { throw new NotImplementedException(); } public uint GetTokenFromSig(IntPtr pvSig, uint cbSig) { throw new NotImplementedException(); } public uint DefineModuleRef(string szName) { throw new NotImplementedException(); } public void SetParent(uint mr, uint tk) { throw new NotImplementedException(); } public uint GetTokenFromTypeSpec(IntPtr pvSig, uint cbSig) { throw new NotImplementedException(); } public void SaveToMemory(IntPtr pbData, uint cbData) { throw new NotImplementedException(); } public uint DefineUserString(string szString, uint cchString) { throw new NotImplementedException(); } public void DeleteToken(uint tkObj) { throw new NotImplementedException(); } public void SetMethodProps(uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags) { throw new NotImplementedException(); } public void SetTypeDefProps(uint td, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements) { throw new NotImplementedException(); } public void SetEventProps(uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods) { throw new NotImplementedException(); } public uint SetPermissionSetProps(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission) { throw new NotImplementedException(); } public void DefinePinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL) { throw new NotImplementedException(); } public void SetPinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL) { throw new NotImplementedException(); } public void DeletePinvokeMap(uint tk) { throw new NotImplementedException(); } public uint DefineCustomAttribute(uint tkObj, uint tkType, IntPtr pCustomAttribute, uint cbCustomAttribute) { throw new NotImplementedException(); } public void SetCustomAttributeValue(uint pcv, IntPtr pCustomAttribute, uint cbCustomAttribute) { throw new NotImplementedException(); } public uint DefineField(uint td, string szName, uint dwFieldFlags, IntPtr pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) { throw new NotImplementedException(); } public uint DefineProperty(uint td, string szProperty, uint dwPropFlags, IntPtr pvSig, uint cbSig, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods) { throw new NotImplementedException(); } public uint DefineParam(uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) { throw new NotImplementedException(); } public void SetFieldProps(uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) { throw new NotImplementedException(); } public void SetPropertyProps(uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods) { throw new NotImplementedException(); } public void SetParamProps(uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) { throw new NotImplementedException(); } public uint DefineSecurityAttributeSet(uint tkObj, IntPtr rSecAttrs, uint cSecAttrs) { throw new NotImplementedException(); } public void ApplyEditAndContinue(object pImport) { throw new NotImplementedException(); } public uint TranslateSigWithScope(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport import, IntPtr pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr pvTranslatedSig, uint cbTranslatedSigMax) { throw new NotImplementedException(); } public void SetMethodImplFlags(uint md, uint dwImplFlags) { throw new NotImplementedException(); } public void SetFieldRVA(uint fd, uint ulRVA) { throw new NotImplementedException(); } public void Merge(IMetaDataImport pImport, IntPtr pHostMapToken, object pHandler) { throw new NotImplementedException(); } public void MergeEnd() { throw new NotImplementedException(); } public void CloseEnum(uint hEnum) { throw new NotImplementedException(); } public uint CountEnum(uint hEnum) { throw new NotImplementedException(); } public void ResetEnum(uint hEnum, uint ulPos) { throw new NotImplementedException(); } public uint EnumTypeDefs(ref uint phEnum, uint[] rTypeDefs, uint cMax) { throw new NotImplementedException(); } public uint EnumInterfaceImpls(ref uint phEnum, uint td, uint[] rImpls, uint cMax) { throw new NotImplementedException(); } public uint EnumTypeRefs(ref uint phEnum, uint[] rTypeRefs, uint cMax) { throw new NotImplementedException(); } public uint FindTypeDefByName(string szTypeDef, uint tkEnclosingClass) { throw new NotImplementedException(); } public Guid GetScopeProps(StringBuilder szName, uint cchName, out uint pchName) { throw new NotImplementedException(); } public uint GetModuleFromScope() { throw new NotImplementedException(); } public unsafe uint GetTypeDefProps(uint td, char* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!TryGetType(td, out var type)) { return 2147500037u; } WriteNameBuffer(((TypeReference)type).IsNested ? ((MemberReference)type).Name : ((MemberReference)type).FullName, szTypeDef, cchTypeDef, pchTypeDef); if (pdwTypeDefFlags != null) { *pdwTypeDefFlags = (uint)(int)type.Attributes; } if (ptkExtends != null) { int num; if (type.BaseType == null) { num = 0; } else { MetadataToken metadataToken = ((MemberReference)type.BaseType).MetadataToken; num = (int)((MetadataToken)(ref metadataToken)).ToUInt32(); } *ptkExtends = (uint)num; } return 0u; } public uint GetInterfaceImplProps(uint iiImpl, out uint pClass) { throw new NotImplementedException(); } public uint GetTypeRefProps(uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName) { throw new NotImplementedException(); } public uint ResolveTypeRef(uint tr, ref Guid riid, out object ppIScope) { throw new NotImplementedException(); } public uint EnumMembers(ref uint phEnum, uint cl, uint[] rMembers, uint cMax) { throw new NotImplementedException(); } public uint EnumMembersWithName(ref uint phEnum, uint cl, string szName, uint[] rMembers, uint cMax) { throw new NotImplementedException(); } public uint EnumMethods(ref uint phEnum, uint cl, IntPtr rMethods, uint cMax) { throw new NotImplementedException(); } public uint EnumMethodsWithName(ref uint phEnum, uint cl, string szName, uint[] rMethods, uint cMax) { throw new NotImplementedException(); } public uint EnumFields(ref uint phEnum, uint cl, IntPtr rFields, uint cMax) { throw new NotImplementedException(); } public uint EnumFieldsWithName(ref uint phEnum, uint cl, string szName, uint[] rFields, uint cMax) { throw new NotImplementedException(); } public uint EnumParams(ref uint phEnum, uint mb, uint[] rParams, uint cMax) { throw new NotImplementedException(); } public uint EnumMemberRefs(ref uint phEnum, uint tkParent, uint[] rMemberRefs, uint cMax) { throw new NotImplementedException(); } public uint EnumMethodImpls(ref uint phEnum, uint td, uint[] rMethodBody, uint[] rMethodDecl, uint cMax) { throw new NotImplementedException(); } public uint EnumPermissionSets(ref uint phEnum, uint tk, uint dwActions, uint[] rPermission, uint cMax) { throw new NotImplementedException(); } public uint FindMember(uint td, string szName, byte[] pvSigBlob, uint cbSigBlob) { throw new NotImplementedException(); } public uint FindMethod(uint td, string szName, byte[] pvSigBlob, uint cbSigBlob) { throw new NotImplementedException(); } public uint FindField(uint td, string szName, byte[] pvSigBlob, uint cbSigBlob) { throw new NotImplementedException(); } public uint FindMemberRef(uint td, string szName, byte[] pvSigBlob, uint cbSigBlob) { throw new NotImplementedException(); } public unsafe uint GetMethodProps(uint mb, uint* pClass, char* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, uint* pulCodeRVA, uint* pdwImplFlags) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected I4, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected I4, but got Unknown if (!TryGetMethod(mb, out var method)) { return 2147500037u; } if (pClass != null) { MetadataToken metadataToken = ((MemberReference)method.DeclaringType).MetadataToken; *pClass = ((MetadataToken)(ref metadataToken)).ToUInt32(); } WriteNameBuffer(((MemberReference)method).Name, szMethod, cchMethod, pchMethod); if (pdwAttr != null) { *pdwAttr = (uint)(int)method.Attributes; } if (pulCodeRVA != null) { *pulCodeRVA = (uint)method.RVA; } if (pdwImplFlags != null) { *pdwImplFlags = (uint)(int)method.ImplAttributes; } return 0u; } private unsafe static void WriteNameBuffer(string name, char* buffer, uint bufferLength, uint* actualLength) { long num = Math.Min(name.Length, bufferLength - 1); if (actualLength != null) { *actualLength = (uint)num; } if (buffer != null && bufferLength != 0) { for (int i = 0; i < num; i++) { buffer[i] = name[i]; } buffer[num + 1] = '\0'; } } public uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob) { throw new NotImplementedException(); } public uint EnumProperties(ref uint phEnum, uint td, IntPtr rProperties, uint cMax) { throw new NotImplementedException(); } public uint EnumEvents(ref uint phEnum, uint td, IntPtr rEvents, uint cMax) { throw new NotImplementedException(); } public uint GetEventProps(uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, uint[] rmdOtherMethod, uint cMax) { throw new NotImplementedException(); } public uint EnumMethodSemantics(ref uint phEnum, uint mb, uint[] rEventProp, uint cMax) { throw new NotImplementedException(); } public uint GetMethodSemantics(uint mb, uint tkEventProp) { throw new NotImplementedException(); } public uint GetClassLayout(uint td, out uint pdwPackSize, IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset) { throw new NotImplementedException(); } public uint GetFieldMarshal(uint tk, out IntPtr ppvNativeType) { throw new NotImplementedException(); } public uint GetRVA(uint tk, out uint pulCodeRVA) { throw new NotImplementedException(); } public uint GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission) { throw new NotImplementedException(); } public uint GetSigFromToken(uint mdSig, out IntPtr ppvSig) { throw new NotImplementedException(); } public uint GetModuleRefProps(uint mur, StringBuilder szName, uint cchName) { throw new NotImplementedException(); } public uint EnumModuleRefs(ref uint phEnum, uint[] rModuleRefs, uint cmax) { throw new NotImplementedException(); } public uint GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig) { throw new NotImplementedException(); } public uint GetNameFromToken(uint tk) { throw new NotImplementedException(); } public uint EnumUnresolvedMethods(ref uint phEnum, uint[] rMethods, uint cMax) { throw new NotImplementedException(); } public uint GetUserString(uint stk, StringBuilder szString, uint cchString) { throw new NotImplementedException(); } public uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName) { throw new NotImplementedException(); } public uint EnumSignatures(ref uint phEnum, uint[] rSignatures, uint cmax) { throw new NotImplementedException(); } public uint EnumTypeSpecs(ref uint phEnum, uint[] rTypeSpecs, uint cmax) { throw new NotImplementedException(); } public uint EnumUserStrings(ref uint phEnum, uint[] rStrings, uint cmax) { throw new NotImplementedException(); } public int GetParamForMethodIndex(uint md, uint ulParamSeq, out uint pParam) { throw new NotImplementedException(); } public uint EnumCustomAttributes(ref uint phEnum, uint tk, uint tkType, uint[] rCustomAttributes, uint cMax) { throw new NotImplementedException(); } public uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob) { throw new NotImplementedException(); } public uint FindTypeRef(uint tkResolutionScope, string szName) { throw new NotImplementedException(); } public uint GetMemberProps(uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue) { throw new NotImplementedException(); } public uint GetFieldProps(uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue) { throw new NotImplementedException(); } public uint GetPropertyProps(uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, uint[] rmdOtherMethod, uint cMax) { throw new NotImplementedException(); } public uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue) { throw new NotImplementedException(); } public uint GetCustomAttributeByName(uint tkObj, string szName, out IntPtr ppData) { throw new NotImplementedException(); } public bool IsValidToken(uint tk) { throw new NotImplementedException(); } public unsafe uint GetNestedClassProps(uint tdNestedClass, uint* ptdEnclosingClass) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!TryGetType(tdNestedClass, out var type)) { return 2147500037u; } if (ptdEnclosingClass != null) { int num; if (!((TypeReference)type).IsNested) { num = 0; } else { MetadataToken metadataToken = ((MemberReference)type.DeclaringType).MetadataToken; num = (int)((MetadataToken)(ref metadataToken)).ToUInt32(); } *ptdEnclosingClass = (uint)num; } return 0u; } public uint GetNativeCallConvFromSig(IntPtr pvSig, uint cbSig) { throw new NotImplementedException(); } public int IsGlobal(uint pd) { throw new NotImplementedException(); } } public class NativePdbReader : ISymbolReader, IDisposable { private readonly Disposable<Stream> pdb_file; private readonly Dictionary<string, Document> documents = new Dictionary<string, Document>(); private readonly Dictionary<uint, PdbFunction> functions = new Dictionary<uint, PdbFunction>(); private readonly Dictionary<PdbScope, ImportDebugInformation> imports = new Dictionary<PdbScope, ImportDebugInformation>(); internal NativePdbReader(Disposable<Stream> file) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) pdb_file = file; } public ISymbolWriterProvider GetWriterProvider() { return (ISymbolWriterProvider)(object)new NativePdbWriterProvider(); } public bool ProcessDebugHeader(ImageDebugHeader header) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!header.HasEntries) { return false; } Disposable<Stream> val = pdb_file; try { PdbInfo pdbInfo = PdbFile.LoadFunctions(pdb_file.value); ImageDebugHeaderEntry[] entries = header.Entries; foreach (ImageDebugHeaderEntry entry in entries) { if (IsMatchingEntry(pdbInfo, entry)) { PdbFunction[] array = pdbInfo.Functions; foreach (PdbFunction pdbFunction in array) { functions.Add(pdbFunction.token, pdbFunction); } return true; } } } finally { ((IDisposable)val).Dispose(); } return false; } private static bool IsMatchingEntry(PdbInfo info, ImageDebugHeaderEntry entry) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if ((int)entry.Directory.Type != 2) { return false; } byte[] data = entry.Data; if (data.Length < 24) { return false; } if (ReadInt32(data, 0) != 1396986706) { return false; } byte[] array = new byte[16]; Buffer.BlockCopy(data, 4, array, 0, 16); return info.Guid == new Guid(array); } private static int ReadInt32(byte[] bytes, int start) { return bytes[start] | (bytes[start + 1] << 8) | (bytes[start + 2] << 16) | (bytes[start + 3] << 24); } public MethodDebugInformation Read(MethodDefinition method) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0026: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01db: 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_022e: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown MetadataToken metadataToken = ((MemberReference)method).MetadataToken; if (!functions.TryGetValue(((MetadataToken)(ref metadataToken)).ToUInt32(), out var value)) { return null; } MethodDebugInformation val = new MethodDebugInformation(method); ReadSequencePoints(value, val); val.scope = (ScopeDebugInformation)((!Mixin.IsNullOrEmpty<PdbScope>(value.scopes)) ? ((object)ReadScopeAndLocals(value.scopes[0], val)) : ((object)new ScopeDebugInformation { Start = new InstructionOffset(0), End = new InstructionOffset((int)value.length) })); uint tokenOfMethodWhoseUsingInfoAppliesToThisMethod = value.tokenOfMethodWhoseUsingInfoAppliesToThisMethod; MetadataToken metadataToken2 = ((MemberReference)method).MetadataToken; if (tokenOfMethodWhoseUsingInfoAppliesToThisMethod != ((MetadataToken)(ref metadataToken2)).ToUInt32() && value.tokenOfMethodWhoseUsingInfoAppliesToThisMethod != 0) { val.scope.import = GetImport(value.tokenOfMethodWhoseUsingInfoAppliesToThisMethod, ((MemberReference)method).Module); } if (value.scopes.Length > 1) { for (int i = 1; i < value.scopes.Length; i++) { ScopeDebugInformation val2 = ReadScopeAndLocals(value.scopes[i], val); if (!AddScope(val.scope.Scopes, val2)) { val.scope.Scopes.Add(val2); } } } if (value.iteratorScopes != null) { StateMachineScopeDebugInformation val3 = new StateMachineScopeDebugInformation(); foreach (ILocalScope iteratorScope in value.iteratorScopes) { val3.Scopes.Add(new StateMachineScope((int)iteratorScope.Offset, (int)(iteratorScope.Offset + iteratorScope.Length + 1))); } ((DebugInformation)val).CustomDebugInformations.Add((CustomDebugInformation)(object)val3); } if (value.synchronizationInformation != null) { AsyncMethodBodyDebugInformation val4 = new AsyncMethodBodyDebugInformation((int)value.synchronizationInformation.GeneratedCatchHandlerOffset); PdbSynchronizationPoint[] synchronizationPoints = value.synchronizationInformation.synchronizationPoints; foreach (PdbSynchronizationPoint pdbSynchronizationPoint in synchronizationPoints) { val4.Yields.Add(new InstructionOffset((int)pdbSynchronizationPoint.SynchronizeOffset)); val4.Resumes.Add(new InstructionOffset((int)pdbSynchronizationPoint.ContinuationOffset)); val4.ResumeMethods.Add(method); } ((DebugInformation)val).CustomDebugInformations.Add((CustomDebugInformation)(object)val4); val.StateMachineKickOffMethod = (MethodDefinition)((MemberReference)method).Module.LookupToken((int)value.synchronizationInformation.kickoffMethodToken); } return val; } private Collection<ScopeDebugInformation> ReadScopeAndLocals(PdbScope[] scopes, MethodDebugInformation info) { Collection<ScopeDebugInformation> val = new Collection<ScopeDebugInformation>(scopes.Length); foreach (PdbScope pdbScope in scopes) { if (pdbScope != null) { val.Add(ReadScopeAndLocals(pdbScope, info)); } } return val; } private ScopeDebugInformation ReadScopeAndLocals(PdbScope scope, MethodDebugInformation info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown ScopeDebugInformation val = new ScopeDebugInformation(); val.Start = new InstructionOffset((int)scope.offset); val.End = new InstructionOffset((int)(scope.offset + scope.length)); if (!Mixin.IsNullOrEmpty<PdbSlot>(scope.slots)) { val.variables = new Collection<VariableDebugInformation>(scope.slots.Length); PdbSlot[] slots = scope.slots; foreach (PdbSlot pdbSlot in slots) { if ((pdbSlot.flags & 1) == 0) { VariableDebugInformation val2 = new VariableDebugInformation((int)pdbSlot.slot, pdbSlot.name); if ((pdbSlot.flags & 4u) != 0) { val2.IsDebuggerHidden = true; } val.variables.Add(val2); } } } if (!Mixin.IsNullOrEmpty<PdbConstant>(scope.constants)) { val.constants = new Collection<ConstantDebugInformation>(scope.constants.Length); PdbConstant[] constants = scope.constants; foreach (PdbConstant pdbConstant in constants) { TypeReference val3 = ((MemberReference)info.Method).Module.Read<PdbConstant, TypeReference>(pdbConstant, (Func<PdbConstant, MetadataReader, TypeReference>)((PdbConstant c, MetadataReader r) => r.ReadConstantSignature(new MetadataToken(c.token)))); object obj = pdbConstant.value; if (val3 != null && !val3.IsValueType && obj is int && (int)obj == 0) { obj = null; } val.constants.Add(new ConstantDebugInformation(pdbConstant.name, val3, obj)); } } if (!Mixin.IsNullOrEmpty<string>(scope.usedNamespaces)) { if (imports.TryGetValue(scope, out var value)) { val.import = value; } else { value = GetImport(scope, ((MemberReference)info.Method).Module); imports.Add(scope, value); val.import = value; } } val.scopes = ReadScopeAndLocals(scope.scopes, info); return val; } private static bool AddScope(Collection<ScopeDebugInformation> scopes, ScopeDebugInformation scope) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_005d: Unknown result type (might be due to invalid IL or missing references) Enumerator<ScopeDebugInformation> enumerator = scopes.GetEnumerator(); try { while (enumerator.MoveNext()) { ScopeDebugInformation current = enumerator.Current; if (current.HasScopes && AddScope(current.Scopes, scope)) { return true; } InstructionOffset val = scope.Start; int offset = ((InstructionOffset)(ref val)).Offset; val = current.Start; if (offset >= ((InstructionOffset)(ref val)).Offset) { val = scope.End; int offset2 = ((InstructionOffset)(ref val)).Offset; val = current.End; if (offset2 <= ((InstructionOffset)(ref val)).Offset) { current.Scopes.Add(scope); return true; } } } } finally { ((IDisposable)enumerator).Dispose(); } return false; } private ImportDebugInformation GetImport(uint token, ModuleDefinition module) { if (!functions.TryGetValue(token, out var value)) { return null; } if (value.scopes.Length != 1) { return null; } PdbScope pdbScope = value.scopes[0]; if (imports.TryGetValue(pdbScope, out var value2)) { return value2; } value2 = GetImport(pdbScope, module); imports.Add(pdbScope, value2); return value2; } private static ImportDebugInformation GetImport(PdbScope scope, ModuleDefinition module) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown //IL_00c5: 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_00d3: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_007a: 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_0089: Expected O, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown if (Mixin.IsNullOrEmpty<string>(scope.usedNamespaces)) { return null; } ImportDebugInformation val = new ImportDebugInformation(); string[] usedNamespaces = scope.usedNamespaces; foreach (string text in usedNamespaces) { if (string.IsNullOrEmpty(text)) { continue; } ImportTarget val2 = null; string text2 = text.Substring(1); switch (text[0]) { case 'U': val2 = new ImportTarget((ImportTargetKind)1) { @namespace = text2 }; break; case 'T': { TypeReference val4 = TypeParser.ParseType(module, text2, false); if (val4 != null) { val2 = new ImportTarget((ImportTargetKind)3) { type = val4 }; } break; } case 'A': { int num = text.IndexOf(' '); if (num < 0) { val2 = new ImportTarget((ImportTargetKind)1) { @namespace = text }; break; } string alias = text.Substring(1, num - 1); string text3 = text.Substring(num + 2); switch (text[num + 1]) { case 'U': val2 = new ImportTarget((ImportTargetKind)7) { alias = alias, @namespace = text3 }; break; case 'T': { TypeReference val3 = TypeParser.ParseType(module, text3, false); if (val3 != null) { val2 = new ImportTarget((ImportTargetKind)9) { alias = alias, type = val3 }; } break; } } break; } case '*': val2 = new ImportTarget((ImportTargetKind)1) { @namespace = text2 }; break; case '@': if (!text2.StartsWith("P:")) { continue; } val2 = new ImportTarget((ImportTargetKind)1) { @namespace = text2.Substring(2) }; break; } if (val2 != null) { val.Targets.Add(val2); } } return val; } private void ReadSequencePoints(PdbFunction function, MethodDebugInformation info) { if (function.lines != null) { info.sequence_points = new Collection<SequencePoint>(); PdbLines[] lines = function.lines; foreach (PdbLines lines2 in lines) { ReadLines(lines2, info); } } } private void ReadLines(PdbLines lines, MethodDebugInformation info) { Document document = GetDocument(lines.file); PdbLine[] lines2 = lines.lines; for (int i = 0; i < lines2.Length; i++) { ReadLine(lines2[i], document, info); } } private static void ReadLine(PdbLine line, Document document, MethodDebugInformation info) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown SequencePoint val = new SequencePoint((int)line.offset, document); val.StartLine = (int)line.lineBegin; val.StartColumn = line.colBegin; val.EndLine = (int)line.lineEnd; val.EndColumn = line.colEnd; info.sequence_points.Add(val); } private Document GetDocument(PdbSource source) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown string name = source.name; if (documents.TryGetValue(name, out var value)) { return value; } value = new Document(name) { LanguageGuid = source.language, LanguageVendorGuid = source.vendor, TypeGuid = source.doctype, HashAlgorithmGuid = source.checksumAlgorithm, Hash = source.checksum }; documents.Add(name, value); return value; } public Collection<CustomDebugInformation> Read(ICustomDebugInformationProvider provider) { return new Collection<CustomDebugInformation>(); } public void Dispose() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) pdb_file.Dispose(); } } public class NativePdbWriter : ISymbolWriter, IDisposable { private readonly ModuleDefinition module; private readonly MetadataBuilder metadata; private readonly SymWriter writer; private readonly Dictionary<string, SymDocumentWriter> documents; private readonly Dictionary<ImportDebugInformation, MetadataToken> import_info_to_parent; private ImageDebugDirectory debug_directory; private byte[] debug_info; internal NativePdbWriter(ModuleDefinition module, SymWriter writer) { this.module = module; metadata = module.metadata_builder; this.writer = writer; documents = new Dictionary<string, SymDocumentWriter>(); import_info_to_parent = new Dictionary<ImportDebugInformation, MetadataToken>(); } public ISymbolReaderProvider GetReaderProvider() { return (ISymbolReaderProvider)(object)new NativePdbReaderProvider(); } public ImageDebugHeader GetDebugHeader() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return new ImageDebugHeader(new ImageDebugHeaderEntry(debug_directory, debug_info)); } public void Write(MethodDebugInformation info) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) MetadataToken metadataToken = ((MemberReference)info.method).MetadataToken; int methodToken = ((MetadataToken)(ref metadataToken)).ToInt32(); if (info.HasSequencePoints || info.scope != null || ((DebugInformation)info).HasCustomDebugInformations || info.StateMachineKickOffMethod != null) { writer.OpenMethod(methodToken); if (!Mixin.IsNullOrEmpty<SequencePoint>(info.sequence_points)) { DefineSequencePoints(info.sequence_points); } MetadataToken import_parent = default(MetadataToken); if (info.scope != null) { DefineScope(info.scope, info, out import_parent); } DefineCustomMetadata(info, import_parent); writer.CloseMethod(); } } private void DefineCustomMetadata(MethodDebugInformation info, MetadataToken import_parent) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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) CustomMetadataWriter customMetadataWriter = new CustomMetadataWriter(writer); if (((MetadataToken)(ref import_parent)).RID != 0) { customMetadataWriter.WriteForwardInfo(import_parent); } else if (info.scope != null && info.scope.Import != null && info.scope.Import.HasTargets) { customMetadataWriter.WriteUsingInfo(info.scope.Import); } if (info.Method.HasCustomAttributes) { Enumerator<CustomAttribute> enumerator = info.Method.CustomAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttribute current = enumerator.Current; TypeReference attributeType = current.AttributeType; if (Mixin.IsTypeOf(attributeType, "System.Runtime.CompilerServices", "IteratorStateMachineAttribute") || Mixin.IsTypeOf(attributeType, "System.Runtime.CompilerServices", "AsyncStateMachineAttribute")) { CustomAttributeArgument val = current.ConstructorArguments[0]; object value = ((CustomAttributeArgument)(ref val)).Value; TypeReference val2 = (TypeReference)((value is TypeReference) ? value : null); if (val2 != null) { customMetadataWriter.WriteForwardIterator(val2); } } } } finally { ((IDisposable)enumerator).Dispose(); } } if (((DebugInformation)info).HasCustomDebugInformations) { CustomDebugInformation? obj = ((IEnumerable<CustomDebugInformation>)((DebugInformation)info).CustomDebugInformations).FirstOrDefault((Func<CustomDebugInformation, bool>)((CustomDebugInformation cdi) => (int)cdi.Kind == 1)); StateMachineScopeDebugInformation val3 = (StateMachineScopeDebugInformation)(object)((obj is StateMachineScopeDebugInformation) ? obj : null); if (val3 != null) { customMetadataWriter.WriteIteratorScopes(val3, info); } } customMetadataWriter.WriteCustomMetadata(); DefineAsyncCustomMetadata(info); } private void DefineAsyncCustomMetadata(MethodDebugInformation info) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_004c: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) if (!((DebugInformation)info).HasCustomDebugInformations) { return; } Enumerator<CustomDebugInformation> enumerator = ((DebugInformation)info).CustomDebugInformations.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomDebugInformation current = enumerator.Current; AsyncMethodBodyDebugInformation val = (AsyncMethodBodyDebugInformation)(object)((current is AsyncMethodBodyDebugInformation) ? current : null); if (val == null) { continue; } using MemoryStream memoryStream = new MemoryStream(); BinaryStreamWriter val2 = new BinaryStreamWriter((Stream)memoryStream); int num; MetadataToken metadataToken; if (info.StateMachineKickOffMethod == null) { num = 0; } else { metadataToken = ((MemberReference)info.StateMachineKickOffMethod).MetadataToken; num = (int)((MetadataToken)(ref metadataToken)).ToUInt32(); } val2.WriteUInt32((uint)num); InstructionOffset val3 = val.CatchHandler; val2.WriteUInt32((uint)((InstructionOffset)(ref val3)).Offset); val2.WriteUInt32((uint)val.Resumes.Count); for (int i = 0; i < val.Resumes.Count; i++) { val3 = val.Yields[i]; val2.WriteUInt32((uint)((InstructionOffset)(ref val3)).Offset); metadataToken = ((MemberReference)val.resume_methods[i]).MetadataToken; val2.WriteUInt32(((MetadataToken)(ref metadataToken)).ToUInt32()); val3 = val.Resumes[i]; val2.WriteUInt32((uint)((InstructionOffset)(ref val3)).Offset); } writer.DefineCustomMetadata("asyncMethodInfo", memoryStream.ToArray()); } } finally { ((IDisposable)enumerator).Dispose(); } } private void DefineScope(ScopeDebugInformation scope, MethodDebugInformation info, out MetadataToken import_parent) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Invalid comparison between Unknown and I4 //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Invalid comparison between Unknown and I4 InstructionOffset val = scope.Start; int offset = ((InstructionOffset)(ref val)).Offset; val = scope.End; int num; if (!((InstructionOffset)(ref val)).IsEndOfMethod) { val = scope.End; num = ((InstructionOffset)(ref val)).Offset; } else { num = info.code_size; } int num2 = num; import_parent = new MetadataToken(0u); writer.OpenScope(offset); if (scope.Import != null && scope.Import.HasTargets && !import_info_to_parent.TryGetValue(info.scope.Import, out import_parent)) { Enumerator<ImportTarget> enumerator = scope.Import.Targets.GetEnumerator(); try { while (enumerator.MoveNext()) { ImportTarget current = enumerator.Current; ImportTargetKind kind = current.Kind; if ((int)kind <= 3) { if ((int)kind != 1) { if ((int)kind == 3) { writer.UsingNamespace("T" + TypeParser.ToParseable(current.type, true)); } } else { writer.UsingNamespace("U" + current.@namespace); } } else if ((int)kind != 7) { if ((int)kind == 9) { writer.UsingNamespace("A" + current.Alias + " T" + TypeParser.ToParseable(current.type, true)); } } else { writer.UsingNamespace("A" + current.Alias + " U" + current.@namespace); } } } finally { ((IDisposable)enumerator).Dispose(); } import_info_to_parent.Add(info.scope.Import, ((MemberReference)info.method).MetadataToken); } int local_var_token = ((MetadataToken)(ref info.local_var_token)).ToInt32(); if (!Mixin.IsNullOrEmpty<VariableDebugInformation>(scope.variables)) { for (int i = 0; i < scope.variables.Count; i++) { VariableDebugInformation variable = scope.variables[i]; DefineLocalVariable(variable, local_var_token, offset, num2); } } if (!Mixin.IsNullOrEmpty<ConstantDebugInformation>(scope.constants)) { for (int j = 0; j < scope.constants.Count; j++) { ConstantDebugInformation constant = scope.constants[j]; DefineConstant(constant); } } if (!Mixin.IsNullOrEmpty<ScopeDebugInformation>(scope.scopes)) { for (int k = 0; k < scope.scopes.Count; k++) { DefineScope(scope.scopes[k], info, out var _); } } writer.CloseScope(num2); } private void DefineSequencePoints(Collection<SequencePoint> sequence_points) { for (int i = 0; i < sequence_points.Count; i++) { SequencePoint val = sequence_points[i]; writer.DefineSequencePoints(GetDocument(val.Document), new int[1] { val.Offset }, new int[1] { val.StartLine }, new int[1] { val.StartColumn }, new int[1] { val.EndLine }, new int[1] { val.EndColumn }); } } private void DefineLocalVariable(VariableDebugInformation variable, int local_var_token, int start_offset, int end_offset) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) writer.DefineLocalVariable2(variable.Name, variable.Attributes, local_var_token, variable.Index, 0, 0, start_offset, end_offset); } private void DefineConstant(ConstantDebugInformation constant) { uint num = metadata.AddStandAloneSignature(metadata.GetConstantTypeBlobIndex(constant.ConstantType)); MetadataToken val = default(MetadataToken); ((MetadataToken)(ref val))..ctor((TokenType)285212672, num); writer.DefineConstant2(constant.Name, constant.Value, ((MetadataToken)(ref val)).ToInt32()); } private SymDocumentWriter GetDocument(Document document) { if (document == null) { return null; } if (documents.TryGetValue(document.Url, out var value)) { return value; } value = writer.DefineDocument(document.Url, document.LanguageGuid, document.LanguageVendorGuid, document.TypeGuid); if (!Mixin.IsNullOrEmpty<byte>(document.Hash)) { value.SetCheckSum(document.HashAlgorithmGuid, document.Hash); } documents[document.Url] = value; return value; } public void Write() { //IL_0016: 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) MethodDefinition entryPoint = module.EntryPoint; if (entryPoint != null) { SymWriter symWriter = writer; MetadataToken metadataToken = ((MemberReference)entryPoint).MetadataToken; symWriter.SetUserEntryPoint(((MetadataToken)(ref metadataToken)).ToInt32()); } debug_info = writer.GetDebugInfo(out debug_directory); debug_directory.TimeDateStamp = (int)module.timestamp; writer.Close(); } public void Write(ICustomDebugInformationProvider provider) { } public void Dispose() { writer.Close(); } } internal enum CustomMetadataType : byte { UsingInfo = 0, ForwardInfo = 1, IteratorScopes = 3, ForwardIterator = 4 } internal class CustomMetadataWriter : IDisposable { private readonly SymWriter sym_writer; private readonly MemoryStream stream; private readonly BinaryStreamWriter writer; private int count; private const byte version = 4; public CustomMetadataWriter(SymWriter sym_writer) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown this.sym_writer = sym_writer; stream = new MemoryStream(); writer = new BinaryStreamWriter((Stream)stream); writer.WriteByte((byte)4); writer.WriteByte((byte)0); writer.Align(4); } public void WriteUsingInfo(ImportDebugInformation import_info) { Write(CustomMetadataType.UsingInfo, delegate { writer.WriteUInt16((ushort)1); writer.WriteUInt16((ushort)import_info.Targets.Count); }); } public void WriteForwardInfo(MetadataToken import_parent) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Write(CustomMetadataType.ForwardInfo, delegate { writer.WriteUInt32(((MetadataToken)(ref import_parent)).ToUInt32()); }); } public void WriteIteratorScopes(StateMachineScopeDebugInformation state_machine, MethodDebugInformation debug_info) { Write(CustomMetadataType.IteratorScopes, delegate { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) Collection<StateMachineScope> scopes = state_machine.Scopes; writer.WriteInt32(scopes.Count); Enumerator<StateMachineScope> enumerator = scopes.GetEnumerator(); try { while (enumerator.MoveNext()) { StateMachineScope current = enumerator.Current; InstructionOffset val = current.Start; int offset = ((InstructionOffset)(ref val)).Offset; val = current.End; int num; if (!((InstructionOffset)(ref val)).IsEndOfMethod) { val = current.End; num = ((InstructionOffset)(ref val)).Offset; } else { num = debug_info.code_size; } int num2 = num; writer.WriteInt32(offset); writer.WriteInt32(num2 - 1); } } finally { ((IDisposable)enumerator).Dispose(); } }); } public void WriteForwardIterator(TypeReference type) { Write(CustomMetadataType.ForwardIterator, delegate { writer.WriteBytes(Encoding.Unicode.GetBytes(((MemberReference)type).Name)); }); } private void Write(CustomMetadataType type, Action write) { count++; writer.WriteByte((byte)4); writer.WriteByte((byte)type); writer.Align(4); int position = writer.Position; writer.WriteUInt32(0u); write(); writer.Align(4); int position2 = writer.Position; int num = position2 - position + 4; writer.Position = position; writer.WriteInt32(num); writer.Position = position2; } public void WriteCustomMetadata() { if (count != 0) { ((BinaryWriter)(object)writer).BaseStream.Position = 1L; writer.WriteByte((byte)count); ((BinaryWriter)(object)writer).Flush(); sym_writer.DefineCustomMetadata("MD2", stream.ToArray()); } } public void Dispose() { stream.Dispose(); } } public sealed class NativePdbReaderProvider : ISymbolReaderProvider { public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) Mixin.CheckModule(module); Mixin.CheckFileName(fileName); return (ISymbolReader)(object)new NativePdbReader(Disposable.Owned<Stream>((Stream)File.OpenRead(Mixin.GetPdbFileName(fileName)))); } public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) Mixin.CheckModule(module); Mixin.CheckStream((object)symbolStream); return (ISymbolReader)(object)new NativePdbReader(Disposable.NotOwned<Stream>(symbolStream)); } } public sealed class PdbReaderProvider : ISymbolReaderProvider { public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName) { //IL_0048: 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) Mixin.CheckModule(module); if (module.HasDebugHeader && Mixin.GetEmbeddedPortablePdbEntry(module.GetDebugHeader()) != null) { return new EmbeddedPortablePdbReaderProvider().GetSymbolReader(module, fileName); } Mixin.CheckFileName(fileName); if (!Mixin.IsPortablePdb(Mixin.GetPdbFileName(fileName))) { return new NativePdbReaderProvider().GetSymbolReader(module, fileName); } return new PortablePdbReaderProvider().GetSymbolReader(module, fileName); } public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) Mixin.CheckModule(module); Mixin.CheckStream((object)symbolStream); Mixin.CheckReadSeek(symbolStream); if (!Mixin.IsPortablePdb(symbolStream)) { return new NativePdbReaderProvider().GetSymbolReader(module, symbolStream); } return new PortablePdbReaderProvider().GetSymbolReader(module, symbolStream); } } public sealed class NativePdbWriterProvider : ISymbolWriterProvider { public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName) { Mixin.CheckModule(module); Mixin.CheckFileName(fileName); return (ISymbolWriter)(object)new NativePdbWriter(module, CreateWriter(module, Mixin.GetPdbFileName(fileName))); } private static SymWriter CreateWriter(ModuleDefinition module, string pdb) { SymWriter symWriter = new SymWriter(); if (File.Exists(pdb)) { File.Delete(pdb); } symWriter.Initialize(new ModuleMetadata(module), pdb, fFullBuild: true); return symWriter; } public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream) { throw new NotImplementedException(); } } public sealed class PdbWriterProvider : ISymbolWriterProvider { public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) Mixin.CheckModule(module); Mixin.CheckFileName(fileName); if (HasPortablePdbSymbols(module)) { return new PortablePdbWriterProvider().GetSymbolWriter(module, fileName); } return new NativePdbWriterProvider().GetSymbolWriter(module, fileName); } private static bool HasPortablePdbSymbols(ModuleDefinition module) { if (module.symbol_reader != null) { return module.symbol_reader is PortablePdbReader; } return false; } public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) Mixin.CheckModule(module); Mixin.CheckStream((object)symbolStream); Mixin.CheckReadSeek(symbolStream); if (HasPortablePdbSymbols(module)) { return new PortablePdbWriterProvider().GetSymbolWriter(module, symbolStream); } return new NativePdbWriterProvider().GetSymbolWriter(module, symbolStream); } } internal class SymDocumentWriter { private readonly ISymUnmanagedDocumentWriter writer; public ISymUnmanagedDocumentWriter Writer => writer; public SymDocumentWriter(ISymUnmanagedDocumentWriter writer) { this.writer = writer; } public void SetSource(byte[] source) { writer.SetSource((uint)source.Length, source); } public void SetCheckSum(Guid hashAlgo, byte[] checkSum) { writer.SetCheckSum(hashAlgo, (uint)checkSum.Length, checkSum); } } internal class SymWriter { private static Guid s_symUnmangedWriterIID = new Guid("0b97726e-9e6d-4f05-9a26-424022093caa"); private static Guid s_CorSymWriter_SxS_ClassID = new Guid("108296c1-281e-11d3-bd22-0000f80849bd"); private readonly ISymUnmanagedWriter2 writer; private readonly Collection<ISymUnmanagedDocumentWriter> documents; private bool closed; [DllImport("ole32.dll")] private static extern int CoCreateInstance([In] ref Guid rclsid, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, [In] uint dwClsContext, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppv); public SymWriter() { CoCreateInstance(ref s_CorSymWriter_SxS_ClassID, null, 1u, ref s_symUnmangedWriterIID, out var ppv); writer = (ISymUnmanagedWriter2)ppv; documents = new Collection<ISymUnmanagedDocumentWriter>(); } public byte[] GetDebugInfo(out ImageDebugDirectory idd) { writer.GetDebugInfo(out idd, 0, out var pcData, null); byte[] array = new byte[pcData]; writer.GetDebugInfo(out idd, pcData, out pcData, array); return array; } public void DefineLocalVariable2(string name, VariableAttributes attributes, int sigToken, int addr1, int addr2, int addr3, int startOffset, int endOffset) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected I4, but got Unknown writer.DefineLocalVariable2(name, (int)attributes, sigToken, 1, addr1, addr2, addr3, startOffset, endOffset); } public void DefineConstant2(string name, object value, int sigToken) { if (value == null) { writer.DefineConstant2(name, 0, sigToken); } else { writer.DefineConstant2(name, value, sigToken); } } public void Close() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (closed) { return; } closed = true; writer.Close(); Marshal.ReleaseComObject(writer); Enumerator<ISymUnmanagedDocumentWriter> enumerator = documents.GetEnumerator(); try { while (enumerator.MoveNext()) { Marshal.ReleaseComObject(enumerator.Current); } } finally { ((IDisposable)enumerator).Dispose(); } } public void CloseMethod() { writer.CloseMethod(); } public void CloseNamespace() { writer.CloseNamespace(); } public void CloseScope(int endOffset) { writer.CloseScope(endOffset); } public SymDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) { writer.DefineDocument(url, ref language, ref languageVendor, ref documentType, out var pRetVal); documents.Add(pRetVal); return new SymDocumentWriter(pRetVal); } public void DefineSequencePoints(SymDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) { writer.DefineSequencePoints(document.Writer, offsets.Length, offsets, lines, columns, endLines, endColumns); } public void Initialize(object emitter, string filename, bool fFullBuild) { writer.Initialize(emitter, filename, null, fFullBuild); } public void SetUserEntryPoint(int methodToken) { writer.SetUserEntryPoint(methodToken); } public void OpenMethod(int methodToken) { writer.OpenMethod(methodToken); } public void OpenNamespace(string name) { writer.OpenNamespace(name); } public int OpenScope(int startOffset) { writer.OpenScope(startOffset, out var pRetVal); return pRetVal; } public void UsingNamespace(string fullName) { writer.UsingNamespace(fullName); } public void DefineCustomMetadata(string name, byte[] metadata) { GCHandle gCHandle = GCHandle.Alloc(metadata, GCHandleType.Pinned); writer.SetSymAttribute(0u, name, (uint)metadata.Length, gCHandle.AddrOfPinnedObject()); gCHandle.Free(); } } } namespace Microsoft.Cci.Pdb { internal class BitAccess { private byte[] buffer; private int offset; internal byte[] Buffer => buffer; internal int Position { get { return offset; } set { offset = value; } } internal BitAccess(int capacity) { buffer = new byte[capacity]; } internal BitAccess(byte[] buffer) { this.buffer = buffer; offset = 0; } internal void FillBuffer(Stream stream, int capacity) { MinCapacity(capacity); stream.Read(buffer, 0, capacity); offset = 0; } internal void Append(Stream stream, int count) { int num = offset + count; if (buffer.Length < num) { byte[] destinationArray = new byte[num]; Array.Copy(buffer, destinationArray, buffer.Length); buffer = destinationArray; } stream.Read(buffer, offset, count); offset += count; } internal void MinCapacity(int capacity) { if (buffer.Length < capacity) { buffer = new byte[capacity]; } offset = 0; } internal void Align(int alignment) { while (offset % alignment != 0) { offset++; } } internal void ReadInt16(out short value) { value = (short)((buffer[offset] & 0xFF) | (buffer[offset + 1] << 8)); offset += 2; } internal void ReadInt8(out sbyte value) { value = (sbyte)buffer[offset]; offset++; } internal void ReadInt32(out int value) { value = (buffer[offset] & 0xFF) | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24); offset += 4; } internal void ReadInt64(out long value) { value = ((long)buffer[offset] & 0xFFL) | (long)((ulong)buffer[offset + 1] << 8) | (long)((ulong)buffer[offset + 2] << 16) | (long)((ulong)buffer[offset + 3] << 24) | (long)((ulong)buffer[offset + 4] << 32) | (long)((ulong)buffer[offset + 5] << 40) | (long)((ulong)buffer[offset + 6] << 48) | (long)((ulong)buffer[offset + 7] << 56); offset += 8; } internal void ReadUInt16(out ushort value) { value = (ushort)((buffer[offset] & 0xFFu) | (uint)(buffer[offset + 1] << 8)); offset += 2; } internal void ReadUInt8(out byte value) { value = (byte)(buffer[offset] & 0xFFu); offset++; } internal void ReadUInt32(out uint value) { value = (buffer[offset] & 0xFFu) | (uint)(buffer[offset + 1] << 8) | (uint)(buffer[offset + 2] << 16) | (uint)(buffer[offset + 3] << 24); offset += 4; } internal void ReadUInt64(out ulong value) { value = ((ulong)buffer[offset] & 0xFFuL) | ((ulong)buffer[offset + 1] << 8) | ((ulong)buffer[offset + 2] << 16) | ((ulong)buffer[offset + 3] << 24) | ((ulong)buffer[offset + 4] << 32) | ((ulong)buffer[offset + 5] << 40) | ((ulong)buffer[offset + 6] << 48) | ((ulong)buffer[offset + 7] << 56); offset += 8; } internal void ReadInt32(int[] values) { for (int i = 0; i < values.Length; i++) { ReadInt32(out values[i]); } } internal void ReadUInt32(uint[] values) { for (int i = 0; i < values.Length; i++) { ReadUInt32(out values[i]); } } internal void ReadBytes(byte[] bytes) { for (int i = 0; i < bytes.Length; i++) { bytes[i] = buffer[offset++]; } } internal float ReadFloat() { float result = BitConverter.ToSingle(buffer, offset); offset += 4; return result; } internal double ReadDouble() { double result = BitConverter.ToDouble(buffer, offset); offset += 8; return result; } internal decimal ReadDecimal() { int[] array = new int[4]; ReadInt32(array); return new decimal(array[2], array[3], array[1], array[0] < 0, (byte)((array[0] & 0xFF0000) >> 16)); } internal void ReadBString(out string value) { ReadUInt16(out var value2); value = Encoding.UTF8.GetString(buffer, offset, value2); offset += value2; } internal string ReadBString(int len) { string @string = Encoding.UTF8.GetString(buffer, offset, len); offset += len; return @string; } internal void ReadCString(out string value) { int i; for (i = 0; offset + i < buffer.Length && buffer[offset + i] != 0; i++) { } value = Encoding.UTF8.GetString(buffer, offset, i); offset += i + 1; } internal void SkipCString(out string value) { int i; for (i = 0; offset + i < buffer.Length && buffer[offset + i] != 0; i++) { } offset += i + 1; value = null; } internal void ReadGuid(out Guid guid) { ReadUInt32(out var value); ReadUInt16(out var value2); ReadUInt16(out var value3); ReadUInt8(out var value4); ReadUInt8(out var value5); ReadUInt8(out var value6); ReadUInt8(out var value7); ReadUInt8(out var value8); ReadUInt8(out var value9); ReadUInt8(out var value10); ReadUInt8(out var value11); guid = new Guid(value, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11); } internal string ReadString() { int i; for (i = 0; offset + i < buffer.Length && buffer[offset + i] != 0; i += 2) { } string @string = Encoding.Unicode.GetString(buffer, offset, i); offset += i + 2; return @string; } } internal struct BitSet { private int size; private uint[] words; internal bool IsEmpty => size == 0; internal BitSet(BitAccess bits) { bits.ReadInt32(out size); words = new uint[size]; bits.ReadUInt32(words); } internal bool IsSet(int index) { int num = index / 32; if (num >= size) { return false; } return (words[num] & GetBit(index)) != 0; } private static uint GetBit(int index) { return (uint)(1 << index % 32); } } internal struct FLOAT10 { internal byte Data_0; internal byte Data_1; internal byte Data_2; internal byte Data_3; internal byte Data_4; internal byte Data_5; internal byte Data_6; internal byte Data_7; internal byte Data_8; internal byte Data_9; } internal enum CV_SIGNATURE { C6 = 0, C7 = 1, C11 = 2, C13 = 4, RESERVERD = 5 } internal enum CV_prmode { CV_TM_DIRECT = 0, CV_TM_NPTR32 = 4, CV_TM_NPTR64 = 6, CV_TM_NPTR128 = 7 } internal enum CV_type { CV_SPECIAL = 0, CV_SIGNED = 1, CV_UNSIGNED = 2, CV_BOOLEAN = 3, CV_REAL = 4, CV_COMPLEX = 5, CV_SPECIAL2 = 6, CV_INT = 7, CV_CVRESERVED = 15 } internal enum CV_special { CV_SP_NOTYPE, CV_SP_ABS, CV_SP_SEGMENT, CV_SP_VOID, CV_SP_CURRENCY, CV_SP_NBASICSTR, CV_SP_FBASICSTR, CV_SP_NOTTRANS, CV_SP_HRESULT } internal enum CV_special2 { CV_S2_BIT, CV_S2_PASCHAR } internal enum CV_integral { CV_IN_1BYTE, CV_IN_2BYTE, CV_IN_4BYTE, CV_IN_8BYTE, CV_IN_16BYTE } internal enum CV_real { CV_RC_REAL32, CV_RC_REAL64, CV_RC_REAL80, CV_RC_REAL128 } internal enum CV_int { CV_RI_CHAR = 0, CV_RI_INT1 = 0, CV_RI_WCHAR = 1, CV_RI_UINT1 = 1, CV_RI_INT2 = 2, CV_RI_UINT2 = 3, CV_RI_INT4 = 4, CV_RI_UINT4 = 5, CV_RI_INT8 = 6, CV_RI_UINT8 = 7, CV_RI_INT16 = 8, CV_RI_UINT16 = 9 } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct CV_PRIMITIVE_TYPE { private const uint CV_MMASK = 1792u; private const uint CV_TMASK = 240u; private const uint CV_SMASK = 15u; private const int CV_MSHIFT = 8; private const int CV_TSHIFT = 4; private const int CV_SSHIFT = 0; private const uint CV_FIRST_NONPRIM = 4096u; } internal enum TYPE_ENUM { T_NOTYPE = 0, T_ABS = 1, T_SEGMENT = 2, T_VOID = 3, T_HRESULT = 8, T_32PHRESULT = 1032, T_64PHRESULT = 1544, T_PVOID = 259, T_PFVOID = 515, T_PHVOID = 771, T_32PVOID = 1027, T_64PVOID = 1539, T_CURRENCY = 4, T_NOTTRANS = 7, T_BIT = 96, T_PASCHAR = 97, T_CHAR = 16, T_32PCHAR = 1040, T_64PCHAR = 1552, T_UCHAR = 32, T_32PUCHAR = 1056, T_64PUCHAR = 1568, T_RCHAR = 112, T_32PRCHAR = 1136, T_64PRCHAR = 1648, T_WCHAR = 113, T_32PWCHAR = 1137, T_64PWCHAR = 1649, T_INT1 = 104, T_32PINT1 = 1128, T_64PINT1 = 1640, T_UINT1 = 105, T_32PUINT1 = 1129, T_64PUINT1 = 1641, T_SHORT = 17, T_32PSHORT = 1041, T_64PSHORT = 1553, T_USHORT = 33, T_32PUSHORT = 1057, T_64PUSHORT = 1569, T_INT2 = 114, T_32PINT2 = 1138, T_64PINT2 = 1650, T_UINT2 = 115, T_32PUINT2 = 1139, T_64PUINT2 = 1651, T_LONG = 18, T_ULONG = 34, T_32PLONG = 1042, T_32PULONG = 1058, T_64PLONG = 1554, T_64PULONG = 1570, T_INT4 = 116, T_32PINT4 = 1140, T_64PINT4 = 1652, T_UINT4 = 117, T_32PUINT4 = 1141, T_64PUINT4 = 1653, T_QUAD = 19, T_32PQUAD = 1043, T_64PQUAD = 1555, T_UQUAD = 35, T_32PUQUAD = 1059, T_64PUQUAD = 1571, T_INT8 = 118, T_32PINT8 = 1142, T_64PINT8 = 1654, T_UINT8 = 119, T_32PUINT8 = 1143, T_64PUINT8 = 1655, T_OCT = 20, T_32POCT = 1044, T_64POCT = 1556, T_UOCT = 36, T_32PUOCT = 1060, T_64PUOCT = 1572, T_INT16 = 120, T_32PINT16 = 1144, T_64PINT16 = 1656, T_UINT16 = 121, T_32PUINT16 = 1145, T_64PUINT16 = 1657, T_REAL32 = 64, T_32PREAL32 = 1088, T_64PREAL32 = 1600, T_REAL64 = 65, T_32PREAL64 = 1089, T_64PREAL64 = 1601, T_REAL80 = 66, T_32PREAL80 = 1090, T_64PREAL80 = 1602, T_REAL128 = 67, T_32PREAL128 = 1091, T_64PREAL128 = 1603, T_CPLX32 = 80, T_32PCPLX32 = 1104, T_64PCPLX32 = 1616, T_CPLX64 = 81, T_32PCPLX64 = 1105, T_64PCPLX64 = 1617, T_CPLX80 = 82, T_32PCPLX80 = 1106, T_64PCPLX80 = 1618, T_CPLX128 = 83, T_32PCPLX128 = 1107, T_64PCPLX128 = 1619, T_BOOL08 = 48, T_32PBOOL08 = 1072, T_64PBOOL08 = 1584, T_BOOL16 = 49, T_32PBOOL16 = 1073, T_64PBOOL16 = 1585, T_BOOL32 = 50, T_32PBOOL32 = 1074, T_64PBOOL32 = 1586, T_BOOL64 = 51, T_32PBOOL64 = 1075, T_64PBOOL64 = 1587 } internal enum LEAF { LF_VTSHAPE = 10, LF_COBOL1 = 12, LF_LABEL = 14, LF_NULL = 15, LF_NOTTRAN = 16, LF_ENDPRECOMP = 20, LF_TYPESERVER_ST = 22, LF_LIST = 515, LF_REFSYM = 524, LF_ENUMERATE_ST = 1027, LF_TI16_MAX = 4096, LF_MODIFIER = 4097, LF_POINTER = 4098, LF_ARRAY_ST = 4099, LF_CLASS_ST = 4100, LF_STRUCTURE_ST = 4101, LF_UNION_ST = 4102, LF_ENUM_ST = 4103, LF_PROCEDURE = 4104, LF_MFUNCTION = 4105, LF_COBOL0 = 4106, LF_BARRAY = 4107, LF_DIMARRAY_ST = 4108, LF_VFTPATH = 4109, LF_PRECOMP_ST = 4110, LF_OEM = 4111, LF_ALIAS_ST = 4112, LF_OEM2 = 4113, LF_SKIP = 4608, LF_ARGLIST = 4609, LF_DEFARG_ST = 4610, LF_FIELDLIST = 4611, LF_DERIVED = 4612, LF_BITFIELD = 4613, LF_METHODLIST = 4614, LF_DIMCONU = 4615, LF_DIMCONLU = 4616, LF_DIMVARU = 4617, LF_DIMVARLU = 4618, LF_BCLASS = 5120, LF_VBCLASS = 5121, LF_IVBCLASS = 5122, LF_FRIENDFCN_ST = 5123, LF_INDEX = 5124, LF_MEMBER_ST = 5125, LF_STMEMBER_ST = 5126, LF_METHOD_ST = 5127, LF_NESTTYPE_ST = 5128, LF_VFUNCTAB = 5129, LF_FRIENDCLS = 5130, LF_ONEMETHOD_ST = 5131, LF_VFUNCOFF = 5132, LF_NESTTYPEEX_ST = 5133, LF_MEMBERMODIFY_ST = 5134, LF_MANAGED_ST = 5135, LF_ST_MAX = 5376, LF_TYPESERVER = 5377, LF_ENUMERATE = 5378, LF_ARRAY = 5379, LF_CLASS = 5380, LF_STRUCTURE = 5381, LF_UNION = 5382, LF_ENUM = 5383, LF_DIMARRAY = 5384, LF_PRECOMP = 5385, LF_ALIAS = 5386, LF_DEFARG = 5387, LF_FRIENDFCN = 5388, LF_MEMBER = 5389, LF_STMEMBER = 5390, LF_METHOD = 5391, LF_NESTTYPE = 5392, LF_ONEMETHOD = 5393, LF_NESTTYPEEX = 5394, LF_MEMBERMODIFY = 5395, LF_MANAGED = 5396, LF_TYPESERVER2 = 5397, LF_NUMERIC = 32768, LF_CHAR = 32768, LF_SHORT = 32769, LF_USHORT = 32770, LF_LONG = 32771, LF_ULONG = 32772, LF_REAL32 = 32773, LF_REAL64 = 32774, LF_REAL80 = 32775, LF_REAL128 = 32776, LF_QUADWORD = 32777, LF_UQUADWORD = 32778, LF_COMPLEX32 = 32780, LF_COMPLEX64 = 32781, LF_COMPLEX80 = 32782, LF_COMPLEX128 = 32783, LF_VARSTRING = 32784, LF_OCTWORD = 32791, LF_UOCTWORD = 32792, LF_DECIMAL = 32793, LF_DATE = 32794, LF_UTF8STRING = 32795, LF_PAD0 = 240, LF_PAD1 = 241, LF_PAD2 = 242, LF_PAD3 = 243, LF_PAD4 = 244, LF_PAD5 = 245, LF_PAD6 = 246, LF_PAD7 = 247, LF_PAD8 = 248, LF_PAD9 = 249, LF_PAD10 = 250, LF_PAD11 = 251, LF_PAD12 = 252, LF_PAD13 = 253, LF_PAD14 = 254, LF_PAD15 = 255 } internal enum CV_ptrtype { CV_PTR_BASE_SEG = 3, CV_PTR_BASE_VAL = 4, CV_PTR_BASE_SEGVAL = 5, CV_PTR_BASE_ADDR = 6, CV_PTR_BASE_SEGADDR = 7, CV_PTR_BASE_TYPE = 8, CV_PTR_BASE_SELF = 9, CV_PTR_NEAR32 = 10, CV_PTR_64 = 12, CV_PTR_UNUSEDPTR = 13 } internal enum CV_ptrmode { CV_PTR_MODE_PTR, CV_PTR_MODE_REF, CV_PTR_MODE_PMEM, CV_PTR_MODE_PMFUNC, CV_PTR_MODE_RESERVED } internal enum CV_pmtype { CV_PMTYPE_Undef, CV_PMTYPE_D_Single, CV_PMTYPE_D_Multiple, CV_PMTYPE_D_Virtual, CV_PMTYPE_D_General, CV_PMTYPE_F_Single, CV_PMTYPE_F_Multiple, CV_PMTYPE_F_Virtual, CV_PMTYPE_F_General } internal enum CV_methodprop { CV_MTvanilla, CV_MTvirtual, CV_MTstatic, CV_MTfriend, CV_MTintro, CV_MTpurevirt, CV_MTpureintro } internal enum CV_VTS_desc { CV_VTS_near, CV_VTS_far, CV_VTS_thin, CV_VTS_outer, CV_VTS_meta, CV_VTS_near32, CV_VTS_far32, CV_VTS_unused } internal enum CV_LABEL_TYPE { CV_LABEL_NEAR = 0, CV_LABEL_FAR = 4 } [Flags] internal enum CV_modifier : ushort { MOD_const = 1, MOD_volatile = 2, MOD_unaligned = 4 } [Flags] internal enum CV_prop : ushort { packed = 1, ctor = 2, ovlops = 4, isnested = 8, cnested = 0x10, opassign = 0x20, opcast = 0x40, fwdref = 0x80, scoped = 0x100 } [Flags] internal enum CV_fldattr { access = 3, mprop = 0x1C, pseudo = 0x20, noinherit = 0x40, noconstruct = 0x80, compgenx = 0x100 } internal struct TYPTYPE { internal ushort len; internal ushort leaf; } internal struct CV_PDMR32_NVVFCN { internal int mdisp; } internal struct CV_PDMR32_VBASE { internal int mdisp; internal int pdisp; internal int vdisp; } internal struct CV_PMFR32_NVSA { internal uint off; } internal struct CV_PMFR32_NVMA { internal uint off; internal int disp; } internal struct CV_PMFR32_VBASE { internal uint off; internal int mdisp; internal int pdisp; internal int vdisp; } internal struct LeafModifier { internal uint type; internal CV_modifier attr; } [Flags] internal enum LeafPointerAttr : uint { ptrtype = 0x1Fu, ptrmode = 0xE0u, isflat32 = 0x100u, isvolatile = 0x200u, isconst = 0x400u, isunaligned = 0x800u, isrestrict = 0x1000u } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct LeafPointer { internal struct LeafPointerBody { internal uint utype; internal LeafPointerAttr attr; } } internal struct LeafArray { internal uint elemtype; internal uint idxtype; internal byte[] data; internal string name; } internal struct LeafClass { internal ushort count; internal ushort property; internal uint field; internal uint derived; internal uint vshape; internal byte[] data; internal string name; } internal struct LeafUnion { internal ushort count; internal ushort property; internal uint field; internal byte[] data; internal string name; } internal struct LeafAlias { internal uint utype; internal string name; } internal struct LeafManaged { internal string name; } internal struct LeafEnum { internal ushort count; internal ushort property; internal uint utype; internal uint field; internal string name; } internal struct LeafProc { internal uint rvtype; internal byte calltype; internal byte reserved; internal ushort parmcount; internal uint arglist; } internal struct LeafMFunc { internal uint rvtype; internal uint classtype; internal uint thistype; internal byte calltype; internal byte reserved; internal ushort parmcount; internal uint arglist; internal int thisadjust; } internal struct LeafVTShape { internal ushort count; internal byte[] desc; } internal struct LeafCobol0 { internal uint type; internal byte[] data; } internal struct LeafCobol1 { internal byte[] data; } internal struct LeafBArray { internal uint utype; } internal struct LeafLabel { internal ushort mode; } internal struct LeafDimArray { internal uint utype; internal uint diminfo; internal string name; } internal struct LeafVFTPath { internal uint count; internal uint[] bases; } internal struct LeafPreComp { internal uint start; internal uint count; internal uint signature; internal string name; } internal struct LeafEndPreComp { internal uint signature; } internal struct LeafOEM { internal ushort cvOEM; internal ushort recOEM; internal uint count; internal uint[] index; } internal enum OEM_ID { OEM_MS_FORTRAN90 = 61584, OEM_ODI = 16, OEM_THOMSON_SOFTWARE = 21587, OEM_ODI_REC_BASELIST = 0 } internal struct LeafOEM2 { internal Guid idOem; internal uint count; internal uint[] index; } internal struct LeafTypeServer { internal uint signature; internal uint age; internal string name; } internal struct LeafTypeServer2 { internal Guid sig70; internal uint age; internal string name; } internal struct LeafSkip { internal uint type; internal byte[] data; } internal struct LeafArgList { internal uint count; internal uint[] arg; } internal struct LeafDerived { internal uint count; internal uint[] drvdcls; } internal struct LeafDefArg { internal uint type; internal byte[] expr; } internal struct LeafList { internal byte[] data; } internal struct LeafFieldList { internal char[] data; } internal struct mlMethod { internal ushort attr; internal ushort pad0; internal uint index; internal uint[] vbaseoff; } internal struct LeafMethodList { internal byte[] mList; } internal struct LeafBitfield { internal uint type; internal byte length; internal byte position; } internal struct LeafDimCon { internal uint typ; internal ushort rank; internal byte[] dim; } internal struct LeafDimVar { internal uint rank; internal uint typ; internal uint[] dim; } internal struct LeafRefSym { internal byte[] Sym; } internal struct LeafChar { internal sbyte val; } internal struct LeafShort { internal short val; } internal struct LeafUShort { internal ushort val; } internal struct LeafLong { internal int val; } internal struct LeafULong { internal uint val; } internal struct LeafQuad { internal long val; } internal struct LeafUQuad { internal ulong val; } internal struct LeafOct { internal ulong val0; internal ulong val1; } internal struct LeafUOct { internal ulong val0; internal ulong val1; } internal struct LeafReal32 { internal float val; } internal struct LeafReal64 { internal double val; } internal struct LeafReal80 { internal FLOAT10 val; } internal struct LeafReal128 { internal ulong val0; internal ulong val1; } internal struct LeafCmplx32 { internal float val_real; internal float val_imag; } internal struct LeafCmplx64 { internal double val_real; internal double val_imag; } internal struct LeafCmplx80 { internal FLOAT10 val_real; internal FLOAT10 val_imag; } internal struct LeafCmplx128 { internal ulong val0_real; internal ulong val1_real; internal ulong val0_imag; internal ulong val1_imag; } internal struct LeafVarString { internal ushort len; internal byte[] value; } internal struct LeafIndex { internal ushort pad0; internal uint index; } internal struct LeafBClass { internal ushort attr; internal uint index; internal byte[] offset; } internal struct LeafVBClass { internal ushort attr; internal uint index; internal uint vbptr; internal byte[] vbpoff; } internal struct LeafFriendCls { internal ushort pad0;
BepInExPack/BepInEx/core/Mono.Cecil.Rocks.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using Mono.Cecil.PE; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyProduct("Mono.Cecil")] [assembly: AssemblyCopyright("Copyright © 2008 - 2018 Jb Evain")] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("0.11.6.0")] [assembly: AssemblyInformationalVersion("0.11.6.0")] [assembly: AssemblyTitle("Mono.Cecil.Rocks")] [assembly: CLSCompliant(false)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyVersion("0.11.6.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Mono.Cecil.Rocks { public class DocCommentId { private class GenericTypeOptions { public bool IsArgument { get; set; } public bool IsNestedType { get; set; } public IList<TypeReference> Arguments { get; set; } public int ArgumentIndex { get; set; } public static GenericTypeOptions Empty() { return new GenericTypeOptions(); } } private IMemberDefinition commentMember; private StringBuilder id; private DocCommentId(IMemberDefinition member) { commentMember = member; id = new StringBuilder(); } private void WriteField(FieldDefinition field) { WriteDefinition('F', (IMemberDefinition)(object)field); } private void WriteEvent(EventDefinition @event) { WriteDefinition('E', (IMemberDefinition)(object)@event); } private void WriteType(TypeDefinition type) { id.Append('T').Append(':'); WriteTypeFullName((TypeReference)(object)type); } private void WriteMethod(MethodDefinition method) { WriteDefinition('M', (IMemberDefinition)(object)method); if (((MethodReference)method).HasGenericParameters) { id.Append('`').Append('`'); id.Append(((MethodReference)method).GenericParameters.Count); } if (((MethodReference)method).HasParameters) { WriteParameters((IList<ParameterDefinition>)((MethodReference)method).Parameters); } if (IsConversionOperator(method)) { WriteReturnType(method); } } private static bool IsConversionOperator(MethodDefinition self) { if (self == null) { throw new ArgumentNullException("self"); } if (self.IsSpecialName) { if (!(((MemberReference)self).Name == "op_Explicit")) { return ((MemberReference)self).Name == "op_Implicit"; } return true; } return false; } private void WriteReturnType(MethodDefinition method) { id.Append('~'); WriteTypeSignature(((MethodReference)method).ReturnType); } private void WriteProperty(PropertyDefinition property) { WriteDefinition('P', (IMemberDefinition)(object)property); if (property.HasParameters) { WriteParameters((IList<ParameterDefinition>)((PropertyReference)property).Parameters); } } private void WriteParameters(IList<ParameterDefinition> parameters) { id.Append('('); WriteList(parameters, delegate(ParameterDefinition p) { WriteTypeSignature(((ParameterReference)p).ParameterType); }); id.Append(')'); } private void WriteTypeSignature(TypeReference type) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_000a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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) //IL_005e: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected I4, but got Unknown //IL_00c5: 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_008b: Expected O, but got Unknown //IL_00f2: 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_0120: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown MetadataType metadataType = type.MetadataType; switch (metadataType - 15) { default: switch (metadataType - 27) { case 0: WriteFunctionPointerTypeSignature((FunctionPointerType)type); return; case 3: id.Append('`').Append('`'); id.Append(((GenericParameter)type).Position); return; case 5: WriteModiferTypeSignature((IModifierType)(OptionalModifierType)type, '!'); return; case 4: WriteModiferTypeSignature((IModifierType)(RequiredModifierType)type, '|'); return; } break; case 5: WriteArrayTypeSignature((ArrayType)type); return; case 1: WriteTypeSignature(((TypeSpecification)(ByReferenceType)type).ElementType); id.Append('@'); return; case 6: WriteGenericInstanceTypeSignature((GenericInstanceType)type); return; case 4: if (IsGenericMethodTypeParameter(type)) { id.Append('`'); } id.Append('`'); id.Append(((GenericParameter)type).Position); return; case 0: WriteTypeSignature(((TypeSpecification)(PointerType)type).ElementType); id.Append('*'); return; case 2: case 3: break; } WriteTypeFullName(type); } private bool IsGenericMethodTypeParameter(TypeReference type) { IMemberDefinition obj = commentMember; MethodDefinition val = (MethodDefinition)(object)((obj is MethodDefinition) ? obj : null); if (val != null) { GenericParameter genericParameter = (GenericParameter)(object)((type is GenericParameter) ? type : null); if (genericParameter != null) { return ((IEnumerable<GenericParameter>)((MethodReference)val).GenericParameters).Any((GenericParameter i) => ((MemberReference)i).Name == ((MemberReference)genericParameter).Name); } } return false; } private void WriteGenericInstanceTypeSignature(GenericInstanceType type) { if (Mixin.IsTypeSpecification(((TypeSpecification)type).ElementType)) { throw new NotSupportedException(); } GenericTypeOptions options = new GenericTypeOptions { IsArgument = true, IsNestedType = ((TypeReference)type).IsNested, Arguments = (IList<TypeReference>)type.GenericArguments }; WriteTypeFullName(((TypeSpecification)type).ElementType, options); } private void WriteList<T>(IList<T> list, Action<T> action) { for (int i = 0; i < list.Count; i++) { if (i > 0) { id.Append(','); } action(list[i]); } } private void WriteModiferTypeSignature(IModifierType type, char id) { WriteTypeSignature(type.ElementType); this.id.Append(id); WriteTypeSignature(type.ModifierType); } private void WriteFunctionPointerTypeSignature(FunctionPointerType type) { id.Append("=FUNC:"); WriteTypeSignature(type.ReturnType); if (type.HasParameters) { WriteParameters((IList<ParameterDefinition>)type.Parameters); } } private void WriteArrayTypeSignature(ArrayType type) { WriteTypeSignature(((TypeSpecification)type).ElementType); if (type.IsVector) { id.Append("[]"); return; } id.Append("["); WriteList((IList<ArrayDimension>)type.Dimensions, delegate(ArrayDimension dimension) { if (((ArrayDimension)(ref dimension)).LowerBound.HasValue) { id.Append(((ArrayDimension)(ref dimension)).LowerBound.Value); } id.Append(':'); if (((ArrayDimension)(ref dimension)).UpperBound.HasValue) { id.Append(((ArrayDimension)(ref dimension)).UpperBound.Value - (((ArrayDimension)(ref dimension)).LowerBound.GetValueOrDefault() + 1)); } }); id.Append("]"); } private void WriteDefinition(char id, IMemberDefinition member) { this.id.Append(id).Append(':'); WriteTypeFullName((TypeReference)(object)member.DeclaringType); this.id.Append('.'); WriteItemName(member.Name); } private void WriteTypeFullName(TypeReference type) { WriteTypeFullName(type, GenericTypeOptions.Empty()); } private void WriteTypeFullName(TypeReference type, GenericTypeOptions options) { if (((MemberReference)type).DeclaringType != null) { WriteTypeFullName(((MemberReference)type).DeclaringType, options); id.Append('.'); } if (!string.IsNullOrEmpty(type.Namespace)) { id.Append(type.Namespace); id.Append('.'); } string text = ((MemberReference)type).Name; if (options.IsArgument) { int num = text.LastIndexOf('`'); if (num > 0) { text = text.Substring(0, num); } } id.Append(text); WriteGenericTypeParameters(type, options); } private void WriteGenericTypeParameters(TypeReference type, GenericTypeOptions options) { if (options.IsArgument && IsGenericType(type)) { id.Append('{'); WriteList(GetGenericTypeArguments(type, options), WriteTypeSignature); id.Append('}'); } } private static bool IsGenericType(TypeReference type) { if (type.HasGenericParameters) { string text = string.Empty; int num = ((MemberReference)type).Name.LastIndexOf('`'); if (num >= 0) { text = ((MemberReference)type).Name.Substring(0, num); } return ((MemberReference)type).Name.LastIndexOf('`') == text.Length; } return false; } private IList<TypeReference> GetGenericTypeArguments(TypeReference type, GenericTypeOptions options) { if (options.IsNestedType) { int count = type.GenericParameters.Count; List<TypeReference> result = options.Arguments.Skip(options.ArgumentIndex).Take(count).ToList(); options.ArgumentIndex += count; return result; } return options.Arguments; } private void WriteItemName(string name) { id.Append(name.Replace('.', '#').Replace('<', '{').Replace('>', '}')); } public override string ToString() { return id.ToString(); } public static string GetDocCommentId(IMemberDefinition member) { //IL_0016: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown if (member == null) { throw new ArgumentNullException("member"); } DocCommentId docCommentId = new DocCommentId(member); MetadataToken metadataToken = ((IMetadataTokenProvider)member).MetadataToken; TokenType tokenType = ((MetadataToken)(ref metadataToken)).TokenType; if ((int)tokenType <= 67108864) { if ((int)tokenType != 33554432) { if ((int)tokenType != 67108864) { goto IL_009e; } docCommentId.WriteField((FieldDefinition)member); } else { docCommentId.WriteType((TypeDefinition)member); } } else if ((int)tokenType != 100663296) { if ((int)tokenType != 335544320) { if ((int)tokenType != 385875968) { goto IL_009e; } docCommentId.WriteProperty((PropertyDefinition)member); } else { docCommentId.WriteEvent((EventDefinition)member); } } else { docCommentId.WriteMethod((MethodDefinition)member); } return docCommentId.ToString(); IL_009e: throw new NotSupportedException(member.FullName); } } internal static class Functional { public static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f) { Func<A, R> g = null; g = f((A a) => g(a)); return g; } public static IEnumerable<TSource> Prepend<TSource>(this IEnumerable<TSource> source, TSource element) { if (source == null) { throw new ArgumentNullException("source"); } return PrependIterator(source, element); } private static IEnumerable<TSource> PrependIterator<TSource>(IEnumerable<TSource> source, TSource element) { yield return element; foreach (TSource item in source) { yield return item; } } } public interface IILVisitor { void OnInlineNone(OpCode opcode); void OnInlineSByte(OpCode opcode, sbyte value); void OnInlineByte(OpCode opcode, byte value); void OnInlineInt32(OpCode opcode, int value); void OnInlineInt64(OpCode opcode, long value); void OnInlineSingle(OpCode opcode, float value); void OnInlineDouble(OpCode opcode, double value); void OnInlineString(OpCode opcode, string value); void OnInlineBranch(OpCode opcode, int offset); void OnInlineSwitch(OpCode opcode, int[] offsets); void OnInlineVariable(OpCode opcode, VariableDefinition variable); void OnInlineArgument(OpCode opcode, ParameterDefinition parameter); void OnInlineSignature(OpCode opcode, CallSite callSite); void OnInlineType(OpCode opcode, TypeReference type); void OnInlineField(OpCode opcode, FieldReference field); void OnInlineMethod(OpCode opcode, MethodReference method); } public static class ILParser { private class ParseContext { public CodeReader Code { get; set; } public int Position { get; set; } public MetadataReader Metadata { get; set; } public Collection<VariableDefinition> Variables { get; set; } public IILVisitor Visitor { get; set; } } public static void Parse(MethodDefinition method, IILVisitor visitor) { if (method == null) { throw new ArgumentNullException("method"); } if (visitor == null) { throw new ArgumentNullException("visitor"); } if (!method.HasBody || !((MemberReference)method).HasImage) { throw new ArgumentException(); } ((MemberReference)method).Module.Read<MethodDefinition, bool>(method, (Func<MethodDefinition, MetadataReader, bool>)delegate(MethodDefinition m, MetadataReader _) { ParseMethod(m, visitor); return true; }); } private static void ParseMethod(MethodDefinition method, IILVisitor visitor) { ParseContext parseContext = CreateContext(method, visitor); CodeReader code = parseContext.Code; byte b = ((BinaryReader)(object)code).ReadByte(); switch (b & 3) { case 2: ParseCode(b >> 2, parseContext); break; case 3: ((BinaryStreamReader)code).Advance(-1); ParseFatMethod(parseContext); break; default: throw new NotSupportedException(); } code.MoveBackTo(parseContext.Position); } private static ParseContext CreateContext(MethodDefinition method, IILVisitor visitor) { CodeReader val = ((MemberReference)method).Module.Read<MethodDefinition, CodeReader>(method, (Func<MethodDefinition, MetadataReader, CodeReader>)((MethodDefinition _, MetadataReader reader) => reader.code)); int position = val.MoveTo(method); return new ParseContext { Code = val, Position = position, Metadata = val.reader, Visitor = visitor }; } private static void ParseFatMethod(ParseContext context) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_002a: Unknown result type (might be due to invalid IL or missing references) CodeReader code = context.Code; ((BinaryStreamReader)code).Advance(4); int code_size = ((BinaryReader)(object)code).ReadInt32(); MetadataToken val = code.ReadToken(); if (val != MetadataToken.Zero) { context.Variables = (Collection<VariableDefinition>)(object)code.ReadVariables(val); } ParseCode(code_size, context); } private static void ParseCode(int code_size, ParseContext context) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected I4, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Invalid comparison between Unknown and I4 //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: 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_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Invalid comparison between Unknown and I4 //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Invalid comparison between Unknown and I4 //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Invalid comparison between Unknown and I4 //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Invalid comparison between Unknown and I4 //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Invalid comparison between Unknown and I4 //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Invalid comparison between Unknown and I4 //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Expected O, but got Unknown //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Invalid comparison between Unknown and I4 //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Invalid comparison between Unknown and I4 //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Expected O, but got Unknown //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) CodeReader code = context.Code; MetadataReader metadata = context.Metadata; IILVisitor visitor = context.Visitor; int num = ((BinaryStreamReader)code).Position + code_size; while (((BinaryStreamReader)code).Position < num) { byte b = ((BinaryReader)(object)code).ReadByte(); OpCode val = ((b != 254) ? OpCodes.OneByteOpCode[b] : OpCodes.TwoBytesOpCode[((BinaryReader)(object)code).ReadByte()]); OperandType operandType = ((OpCode)(ref val)).OperandType; IMetadataTokenProvider val2; switch ((int)operandType) { case 5: visitor.OnInlineNone(val); break; case 10: { int num2 = ((BinaryReader)(object)code).ReadInt32(); int[] array = new int[num2]; for (int i = 0; i < num2; i++) { array[i] = ((BinaryReader)(object)code).ReadInt32(); } visitor.OnInlineSwitch(val, array); break; } case 15: visitor.OnInlineBranch(val, ((BinaryReader)(object)code).ReadSByte()); break; case 0: visitor.OnInlineBranch(val, ((BinaryReader)(object)code).ReadInt32()); break; case 16: if (val == OpCodes.Ldc_I4_S) { visitor.OnInlineSByte(val, ((BinaryReader)(object)code).ReadSByte()); } else { visitor.OnInlineByte(val, ((BinaryReader)(object)code).ReadByte()); } break; case 2: visitor.OnInlineInt32(val, ((BinaryReader)(object)code).ReadInt32()); break; case 3: visitor.OnInlineInt64(val, ((BinaryReader)(object)code).ReadInt64()); break; case 17: visitor.OnInlineSingle(val, ((BinaryReader)(object)code).ReadSingle()); break; case 7: visitor.OnInlineDouble(val, ((BinaryReader)(object)code).ReadDouble()); break; case 8: visitor.OnInlineSignature(val, code.GetCallSite(code.ReadToken())); break; case 9: visitor.OnInlineString(val, code.GetString(code.ReadToken())); break; case 19: visitor.OnInlineArgument(val, code.GetParameter((int)((BinaryReader)(object)code).ReadByte())); break; case 14: visitor.OnInlineArgument(val, code.GetParameter((int)((BinaryReader)(object)code).ReadInt16())); break; case 18: visitor.OnInlineVariable(val, GetVariable(context, ((BinaryReader)(object)code).ReadByte())); break; case 13: visitor.OnInlineVariable(val, GetVariable(context, ((BinaryReader)(object)code).ReadInt16())); break; case 1: case 4: case 11: case 12: { val2 = metadata.LookupToken(code.ReadToken()); MetadataToken metadataToken = val2.MetadataToken; TokenType tokenType = ((MetadataToken)(ref metadataToken)).TokenType; if ((int)tokenType <= 67108864) { if ((int)tokenType != 16777216 && (int)tokenType != 33554432) { if ((int)tokenType == 67108864) { visitor.OnInlineField(val, (FieldReference)val2); } break; } goto IL_02b8; } if ((int)tokenType <= 167772160) { if ((int)tokenType != 100663296) { if ((int)tokenType != 167772160) { break; } FieldReference val3 = (FieldReference)(object)((val2 is FieldReference) ? val2 : null); if (val3 != null) { visitor.OnInlineField(val, val3); break; } MethodReference val4 = (MethodReference)(object)((val2 is MethodReference) ? val2 : null); if (val4 != null) { visitor.OnInlineMethod(val, val4); break; } throw new InvalidOperationException(); } } else { if ((int)tokenType == 452984832) { goto IL_02b8; } if ((int)tokenType != 721420288) { break; } } visitor.OnInlineMethod(val, (MethodReference)val2); break; } IL_02b8: visitor.OnInlineType(val, (TypeReference)val2); break; } } } private static VariableDefinition GetVariable(ParseContext context, int index) { return context.Variables[index]; } } public static class MethodBodyRocks { public static void SimplifyMacros(this MethodBody self) { //IL_0014: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected I4, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0203: 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_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Invalid comparison between Unknown and I4 //IL_0484: Unknown result type (might be due to invalid IL or missing references) if (self == null) { throw new ArgumentNullException("self"); } Enumerator<Instruction> enumerator = self.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; OpCode opCode = current.OpCode; if ((int)((OpCode)(ref opCode)).OpCodeType != 1) { continue; } opCode = current.OpCode; Code code = ((OpCode)(ref opCode)).Code; switch (code - 2) { case 0: ExpandMacro(current, OpCodes.Ldarg, Mixin.GetParameter(self, 0)); continue; case 1: ExpandMacro(current, OpCodes.Ldarg, Mixin.GetParameter(self, 1)); continue; case 2: ExpandMacro(current, OpCodes.Ldarg, Mixin.GetParameter(self, 2)); continue; case 3: ExpandMacro(current, OpCodes.Ldarg, Mixin.GetParameter(self, 3)); continue; case 4: ExpandMacro(current, OpCodes.Ldloc, self.Variables[0]); continue; case 5: ExpandMacro(current, OpCodes.Ldloc, self.Variables[1]); continue; case 6: ExpandMacro(current, OpCodes.Ldloc, self.Variables[2]); continue; case 7: ExpandMacro(current, OpCodes.Ldloc, self.Variables[3]); continue; case 8: ExpandMacro(current, OpCodes.Stloc, self.Variables[0]); continue; case 9: ExpandMacro(current, OpCodes.Stloc, self.Variables[1]); continue; case 10: ExpandMacro(current, OpCodes.Stloc, self.Variables[2]); continue; case 11: ExpandMacro(current, OpCodes.Stloc, self.Variables[3]); continue; case 12: current.OpCode = OpCodes.Ldarg; continue; case 13: current.OpCode = OpCodes.Ldarga; continue; case 14: current.OpCode = OpCodes.Starg; continue; case 15: current.OpCode = OpCodes.Ldloc; continue; case 16: current.OpCode = OpCodes.Ldloca; continue; case 17: current.OpCode = OpCodes.Stloc; continue; case 19: ExpandMacro(current, OpCodes.Ldc_I4, -1); continue; case 20: ExpandMacro(current, OpCodes.Ldc_I4, 0); continue; case 21: ExpandMacro(current, OpCodes.Ldc_I4, 1); continue; case 22: ExpandMacro(current, OpCodes.Ldc_I4, 2); continue; case 23: ExpandMacro(current, OpCodes.Ldc_I4, 3); continue; case 24: ExpandMacro(current, OpCodes.Ldc_I4, 4); continue; case 25: ExpandMacro(current, OpCodes.Ldc_I4, 5); continue; case 26: ExpandMacro(current, OpCodes.Ldc_I4, 6); continue; case 27: ExpandMacro(current, OpCodes.Ldc_I4, 7); continue; case 28: ExpandMacro(current, OpCodes.Ldc_I4, 8); continue; case 29: ExpandMacro(current, OpCodes.Ldc_I4, (int)(sbyte)current.Operand); continue; case 40: current.OpCode = OpCodes.Br; continue; case 41: current.OpCode = OpCodes.Brfalse; continue; case 42: current.OpCode = OpCodes.Brtrue; continue; case 43: current.OpCode = OpCodes.Beq; continue; case 44: current.OpCode = OpCodes.Bge; continue; case 45: current.OpCode = OpCodes.Bgt; continue; case 46: current.OpCode = OpCodes.Ble; continue; case 47: current.OpCode = OpCodes.Blt; continue; case 48: current.OpCode = OpCodes.Bne_Un; continue; case 49: current.OpCode = OpCodes.Bge_Un; continue; case 50: current.OpCode = OpCodes.Bgt_Un; continue; case 51: current.OpCode = OpCodes.Ble_Un; continue; case 52: current.OpCode = OpCodes.Blt_Un; continue; case 18: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: continue; } if ((int)code == 188) { current.OpCode = OpCodes.Leave; } } } finally { ((IDisposable)enumerator).Dispose(); } } private static void ExpandMacro(Instruction instruction, OpCode opcode, object operand) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) instruction.OpCode = opcode; instruction.Operand = operand; } private static void MakeMacro(Instruction instruction, OpCode opcode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) instruction.OpCode = opcode; instruction.Operand = null; } public static void Optimize(this MethodBody self) { if (self == null) { throw new ArgumentNullException("self"); } self.OptimizeLongs(); self.OptimizeMacros(); } private static void OptimizeLongs(this MethodBody self) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < self.Instructions.Count; i++) { Instruction val = self.Instructions[i]; OpCode opCode = val.OpCode; if ((int)((OpCode)(ref opCode)).Code == 33) { long num = (long)val.Operand; if (num < int.MaxValue && num > int.MinValue) { ExpandMacro(val, OpCodes.Ldc_I4, (int)num); self.Instructions.Insert(++i, Instruction.Create(OpCodes.Conv_I8)); } } } } public static void OptimizeMacros(this MethodBody self) { //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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected I4, but got Unknown //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0238: 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_028c: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0271: 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) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if (self == null) { throw new ArgumentNullException("self"); } MethodDefinition method = self.Method; Enumerator<Instruction> enumerator = self.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; OpCode opCode = current.OpCode; Code code = ((OpCode)(ref opCode)).Code; if ((int)code != 32) { switch (code - 199) { case 0: { int index = ((ParameterReference)(ParameterDefinition)current.Operand).Index; if (index == -1 && current.Operand == self.ThisParameter) { index = 0; } else if (((MethodReference)method).HasThis) { index++; } switch (index) { case 0: MakeMacro(current, OpCodes.Ldarg_0); break; case 1: MakeMacro(current, OpCodes.Ldarg_1); break; case 2: MakeMacro(current, OpCodes.Ldarg_2); break; case 3: MakeMacro(current, OpCodes.Ldarg_3); break; default: if (index < 256) { ExpandMacro(current, OpCodes.Ldarg_S, current.Operand); } break; } break; } case 3: { int index = ((VariableReference)(VariableDefinition)current.Operand).Index; switch (index) { case 0: MakeMacro(current, OpCodes.Ldloc_0); break; case 1: MakeMacro(current, OpCodes.Ldloc_1); break; case 2: MakeMacro(current, OpCodes.Ldloc_2); break; case 3: MakeMacro(current, OpCodes.Ldloc_3); break; default: if (index < 256) { ExpandMacro(current, OpCodes.Ldloc_S, current.Operand); } break; } break; } case 5: { int index = ((VariableReference)(VariableDefinition)current.Operand).Index; switch (index) { case 0: MakeMacro(current, OpCodes.Stloc_0); break; case 1: MakeMacro(current, OpCodes.Stloc_1); break; case 2: MakeMacro(current, OpCodes.Stloc_2); break; case 3: MakeMacro(current, OpCodes.Stloc_3); break; default: if (index < 256) { ExpandMacro(current, OpCodes.Stloc_S, current.Operand); } break; } break; } case 1: { int index = ((ParameterReference)(ParameterDefinition)current.Operand).Index; if (index == -1 && current.Operand == self.ThisParameter) { index = 0; } else if (((MethodReference)method).HasThis) { index++; } if (index < 256) { ExpandMacro(current, OpCodes.Ldarga_S, current.Operand); } break; } case 4: if (((VariableReference)(VariableDefinition)current.Operand).Index < 256) { ExpandMacro(current, OpCodes.Ldloca_S, current.Operand); } break; } continue; } int num = (int)current.Operand; switch (num) { case -1: MakeMacro(current, OpCodes.Ldc_I4_M1); continue; case 0: MakeMacro(current, OpCodes.Ldc_I4_0); continue; case 1: MakeMacro(current, OpCodes.Ldc_I4_1); continue; case 2: MakeMacro(current, OpCodes.Ldc_I4_2); continue; case 3: MakeMacro(current, OpCodes.Ldc_I4_3); continue; case 4: MakeMacro(current, OpCodes.Ldc_I4_4); continue; case 5: MakeMacro(current, OpCodes.Ldc_I4_5); continue; case 6: MakeMacro(current, OpCodes.Ldc_I4_6); continue; case 7: MakeMacro(current, OpCodes.Ldc_I4_7); continue; case 8: MakeMacro(current, OpCodes.Ldc_I4_8); continue; } if (num >= -128 && num < 128) { ExpandMacro(current, OpCodes.Ldc_I4_S, (sbyte)num); } } } finally { ((IDisposable)enumerator).Dispose(); } OptimizeBranches(self); } private static void OptimizeBranches(MethodBody body) { //IL_000c: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) ComputeOffsets(body); Enumerator<Instruction> enumerator = body.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; OpCode opCode = current.OpCode; if ((int)((OpCode)(ref opCode)).OperandType == 0 && OptimizeBranch(current)) { ComputeOffsets(body); } } } finally { ((IDisposable)enumerator).Dispose(); } } private static bool OptimizeBranch(Instruction instruction) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected I4, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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: Invalid comparison between Unknown and I4 //IL_0147: Unknown result type (might be due to invalid IL or missing references) int offset = ((Instruction)instruction.Operand).Offset; int offset2 = instruction.Offset; OpCode opCode = instruction.OpCode; int num = offset - (offset2 + ((OpCode)(ref opCode)).Size + 4); if (num < -128 || num > 127) { return false; } opCode = instruction.OpCode; Code code = ((OpCode)(ref opCode)).Code; switch (code - 55) { default: if ((int)code == 187) { instruction.OpCode = OpCodes.Leave_S; } break; case 0: instruction.OpCode = OpCodes.Br_S; break; case 1: instruction.OpCode = OpCodes.Brfalse_S; break; case 2: instruction.OpCode = OpCodes.Brtrue_S; break; case 3: instruction.OpCode = OpCodes.Beq_S; break; case 4: instruction.OpCode = OpCodes.Bge_S; break; case 5: instruction.OpCode = OpCodes.Bgt_S; break; case 6: instruction.OpCode = OpCodes.Ble_S; break; case 7: instruction.OpCode = OpCodes.Blt_S; break; case 8: instruction.OpCode = OpCodes.Bne_Un_S; break; case 9: instruction.OpCode = OpCodes.Bge_Un_S; break; case 10: instruction.OpCode = OpCodes.Bgt_Un_S; break; case 11: instruction.OpCode = OpCodes.Ble_Un_S; break; case 12: instruction.OpCode = OpCodes.Blt_Un_S; break; } return true; } private static void ComputeOffsets(MethodBody body) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) int num = 0; Enumerator<Instruction> enumerator = body.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; current.Offset = num; num += current.GetSize(); } } finally { ((IDisposable)enumerator).Dispose(); } } } public static class MethodDefinitionRocks { public static MethodDefinition GetBaseMethod(this MethodDefinition self) { if (self == null) { throw new ArgumentNullException("self"); } if (!self.IsVirtual) { return self; } if (self.IsNewSlot) { return self; } for (TypeDefinition val = ResolveBaseType(self.DeclaringType); val != null; val = ResolveBaseType(val)) { MethodDefinition matchingMethod = GetMatchingMethod(val, self); if (matchingMethod != null) { return matchingMethod; } } return self; } public static MethodDefinition GetOriginalBaseMethod(this MethodDefinition self) { if (self == null) { throw new ArgumentNullException("self"); } while (true) { MethodDefinition baseMethod = self.GetBaseMethod(); if (baseMethod == self) { break; } self = baseMethod; } return self; } private static TypeDefinition ResolveBaseType(TypeDefinition type) { if (type == null) { return null; } TypeReference baseType = type.BaseType; if (baseType == null) { return null; } return baseType.Resolve(); } private static MethodDefinition GetMatchingMethod(TypeDefinition type, MethodDefinition method) { return MetadataResolver.GetMethod(type.Methods, (MethodReference)(object)method); } } public static class ModuleDefinitionRocks { public static IEnumerable<TypeDefinition> GetAllTypes(this ModuleDefinition self) { if (self == null) { throw new ArgumentNullException("self"); } return ((IEnumerable<TypeDefinition>)self.Types).SelectMany(Functional.Y((Func<TypeDefinition, IEnumerable<TypeDefinition>> f) => (TypeDefinition type) => ((IEnumerable<TypeDefinition>)type.NestedTypes).SelectMany(f).Prepend(type))); } } public static class ParameterReferenceRocks { public static int GetSequence(this ParameterReference self) { return self.Index + 1; } } public static class TypeDefinitionRocks { public static IEnumerable<MethodDefinition> GetConstructors(this TypeDefinition self) { if (self == null) { throw new ArgumentNullException("self"); } if (!self.HasMethods) { return Empty<MethodDefinition>.Array; } return ((IEnumerable<MethodDefinition>)self.Methods).Where((MethodDefinition method) => method.IsConstructor); } public static MethodDefinition GetStaticConstructor(this TypeDefinition self) { if (self == null) { throw new ArgumentNullException("self"); } if (!self.HasMethods) { return null; } return self.GetConstructors().FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition ctor) => ctor.IsStatic)); } public static IEnumerable<MethodDefinition> GetMethods(this TypeDefinition self) { if (self == null) { throw new ArgumentNullException("self"); } if (!self.HasMethods) { return Empty<MethodDefinition>.Array; } return ((IEnumerable<MethodDefinition>)self.Methods).Where((MethodDefinition method) => !method.IsConstructor); } public static TypeReference GetEnumUnderlyingType(this TypeDefinition self) { if (self == null) { throw new ArgumentNullException("self"); } if (!self.IsEnum) { throw new ArgumentException(); } return Mixin.GetEnumUnderlyingType(self); } } public static class TypeReferenceRocks { public static ArrayType MakeArrayType(this TypeReference self) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown return new ArrayType(self); } public static ArrayType MakeArrayType(this TypeReference self, int rank) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (rank == 0) { throw new ArgumentOutOfRangeException("rank"); } ArrayType val = new ArrayType(self); for (int i = 1; i < rank; i++) { val.Dimensions.Add(default(ArrayDimension)); } return val; } public static PointerType MakePointerType(this TypeReference self) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown return new PointerType(self); } public static ByReferenceType MakeByReferenceType(this TypeReference self) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown return new ByReferenceType(self); } public static OptionalModifierType MakeOptionalModifierType(this TypeReference self, TypeReference modifierType) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown return new OptionalModifierType(modifierType, self); } public static RequiredModifierType MakeRequiredModifierType(this TypeReference self, TypeReference modifierType) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown return new RequiredModifierType(modifierType, self); } public static GenericInstanceType MakeGenericInstanceType(this TypeReference self, params TypeReference[] arguments) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown if (self == null) { throw new ArgumentNullException("self"); } if (arguments == null) { throw new ArgumentNullException("arguments"); } if (arguments.Length == 0) { throw new ArgumentException(); } if (self.GenericParameters.Count != arguments.Length) { throw new ArgumentException(); } GenericInstanceType val = new GenericInstanceType(self, arguments.Length); foreach (TypeReference val2 in arguments) { val.GenericArguments.Add(val2); } return val; } public static PinnedType MakePinnedType(this TypeReference self) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown return new PinnedType(self); } public static SentinelType MakeSentinelType(this TypeReference self) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown return new SentinelType(self); } } }
BepInExPack/BepInEx/core/MonoMod.Backports.dll
Decompiled a day agousing System; using System.Buffers; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Reflection; using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(/*Could not decode attribute arguments.*/)] [assembly: CLSCompliant(true)] [assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] [assembly: AssemblyCompany("0x0ade, DaNike")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2024 0x0ade, DaNike")] [assembly: AssemblyDescription("A set of backports of new BCL features to all frameworks which MonoMod supports.")] [assembly: AssemblyFileVersion("1.1.2.0")] [assembly: AssemblyInformationalVersion("1.1.2+a1b82852b")] [assembly: AssemblyProduct("MonoMod.Backports")] [assembly: AssemblyTitle("MonoMod.Backports")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoMod/MonoMod.git")] [assembly: SecurityPermission(8, SkipVerification = true)] [assembly: AssemblyVersion("1.1.2.0")] [assembly: TypeForwardedTo(typeof(ArrayPool<>))] [assembly: TypeForwardedTo(typeof(BuffersExtensions))] [assembly: TypeForwardedTo(typeof(IBufferWriter<>))] [assembly: TypeForwardedTo(typeof(IMemoryOwner<>))] [assembly: TypeForwardedTo(typeof(IPinnable))] [assembly: TypeForwardedTo(typeof(MemoryHandle))] [assembly: TypeForwardedTo(typeof(MemoryManager<>))] [assembly: TypeForwardedTo(typeof(ReadOnlySequence<>))] [assembly: TypeForwardedTo(typeof(ReadOnlySequenceSegment<>))] [assembly: TypeForwardedTo(typeof(StandardFormat))] [assembly: TypeForwardedTo(typeof(ConcurrentBag<>))] [assembly: TypeForwardedTo(typeof(ConcurrentDictionary<, >))] [assembly: TypeForwardedTo(typeof(ConcurrentQueue<>))] [assembly: TypeForwardedTo(typeof(ConcurrentStack<>))] [assembly: TypeForwardedTo(typeof(EnumerablePartitionerOptions))] [assembly: TypeForwardedTo(typeof(IProducerConsumerCollection<>))] [assembly: TypeForwardedTo(typeof(OrderablePartitioner<>))] [assembly: TypeForwardedTo(typeof(Partitioner))] [assembly: TypeForwardedTo(typeof(Partitioner<>))] [assembly: TypeForwardedTo(typeof(IReadOnlyCollection<>))] [assembly: TypeForwardedTo(typeof(IReadOnlyList<>))] [assembly: TypeForwardedTo(typeof(IStructuralComparable))] [assembly: TypeForwardedTo(typeof(IStructuralEquatable))] [assembly: TypeForwardedTo(typeof(DynamicallyAccessedMembersAttribute))] [assembly: TypeForwardedTo(typeof(DynamicallyAccessedMemberTypes))] [assembly: TypeForwardedTo(typeof(UnscopedRefAttribute))] [assembly: TypeForwardedTo(typeof(HashCode))] [assembly: TypeForwardedTo(typeof(Memory<>))] [assembly: TypeForwardedTo(typeof(MemoryExtensions))] [assembly: TypeForwardedTo(typeof(BitOperations))] [assembly: TypeForwardedTo(typeof(ReadOnlyMemory<>))] [assembly: TypeForwardedTo(typeof(ReadOnlySpan<>))] [assembly: TypeForwardedTo(typeof(IntrospectionExtensions))] [assembly: TypeForwardedTo(typeof(IReflectableType))] [assembly: TypeForwardedTo(typeof(TypeDelegator))] [assembly: TypeForwardedTo(typeof(TypeInfo))] [assembly: TypeForwardedTo(typeof(CallerArgumentExpressionAttribute))] [assembly: TypeForwardedTo(typeof(CallerFilePathAttribute))] [assembly: TypeForwardedTo(typeof(CallerLineNumberAttribute))] [assembly: TypeForwardedTo(typeof(CallerMemberNameAttribute))] [assembly: TypeForwardedTo(typeof(ConditionalWeakTable<, >))] [assembly: TypeForwardedTo(typeof(DefaultInterpolatedStringHandler))] [assembly: TypeForwardedTo(typeof(DisableRuntimeMarshallingAttribute))] [assembly: TypeForwardedTo(typeof(InterpolatedStringHandlerArgumentAttribute))] [assembly: TypeForwardedTo(typeof(InterpolatedStringHandlerAttribute))] [assembly: TypeForwardedTo(typeof(ModuleInitializerAttribute))] [assembly: TypeForwardedTo(typeof(TupleElementNamesAttribute))] [assembly: TypeForwardedTo(typeof(Unsafe))] [assembly: TypeForwardedTo(typeof(DependentHandle))] [assembly: TypeForwardedTo(typeof(DefaultDllImportSearchPathsAttribute))] [assembly: TypeForwardedTo(typeof(DllImportSearchPath))] [assembly: TypeForwardedTo(typeof(MemoryMarshal))] [assembly: TypeForwardedTo(typeof(SequenceMarshal))] [assembly: TypeForwardedTo(typeof(SequencePosition))] [assembly: TypeForwardedTo(typeof(Span<>))] [assembly: TypeForwardedTo(typeof(SpinLock))] [assembly: TypeForwardedTo(typeof(SpinWait))] [assembly: TypeForwardedTo(typeof(ThreadLocal<>))] [assembly: TypeForwardedTo(typeof(Volatile))] [assembly: TypeForwardedTo(typeof(Tuple))] [assembly: TypeForwardedTo(typeof(Tuple<>))] [assembly: TypeForwardedTo(typeof(Tuple<, >))] [assembly: TypeForwardedTo(typeof(Tuple<, , >))] [assembly: TypeForwardedTo(typeof(Tuple<, , , >))] [assembly: TypeForwardedTo(typeof(Tuple<, , , , >))] [assembly: TypeForwardedTo(typeof(Tuple<, , , , , >))] [assembly: TypeForwardedTo(typeof(Tuple<, , , , , , >))] [assembly: TypeForwardedTo(typeof(Tuple<, , , , , , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple))] [assembly: TypeForwardedTo(typeof(ValueTuple<>))] [assembly: TypeForwardedTo(typeof(ValueTuple<, >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , , >))] [assembly: TypeForwardedTo(typeof(ValueTuple<, , , , , , , >))] [assembly: TypeForwardedTo(typeof(WeakReference<>))] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal static class AssemblyInfo { public const string AssemblyName = "MonoMod.Backports"; public const string AssemblyVersion = "1.1.2"; } namespace MonoMod.SourceGen.Attributes { [AttributeUsage(/*Could not decode attribute arguments.*/)] internal sealed class EmitILOverloadsAttribute : System.Attribute { public EmitILOverloadsAttribute(string filename, string kind) { } } internal static class ILOverloadKind { public const string Cursor = "ILCursor"; public const string Matcher = "ILMatcher"; } } namespace MonoMod.Backports { public static class MethodImplOptionsEx { public const MethodImplOptions Unmanaged = 4; public const MethodImplOptions NoInlining = 8; public const MethodImplOptions ForwardRef = 16; public const MethodImplOptions Synchronized = 32; public const MethodImplOptions NoOptimization = 64; public const MethodImplOptions PreserveSig = 128; public const MethodImplOptions AggressiveInlining = 256; public const MethodImplOptions AggressiveOptimization = 512; public const MethodImplOptions InternalCall = 4096; } } namespace MonoMod.Backports.ILHelpers { [CLSCompliant(false)] public static class UnsafeRaw { [MethodImpl(256)] [NonVersionable] public unsafe static T Read<T>(void* source) { return System.Runtime.CompilerServices.Unsafe.Read<T>(source); } [MethodImpl(256)] [NonVersionable] public unsafe static T ReadUnaligned<T>(void* source) { return System.Runtime.CompilerServices.Unsafe.ReadUnaligned<T>(source); } [MethodImpl(256)] [NonVersionable] public static T ReadUnaligned<T>(ref byte source) { return System.Runtime.CompilerServices.Unsafe.ReadUnaligned<T>(ref source); } [MethodImpl(256)] [NonVersionable] public unsafe static void Write<T>(void* destination, T value) { System.Runtime.CompilerServices.Unsafe.Write<T>(destination, value); } [MethodImpl(256)] [NonVersionable] public unsafe static void WriteUnaligned<T>(void* destination, T value) { System.Runtime.CompilerServices.Unsafe.WriteUnaligned<T>(destination, value); } [MethodImpl(256)] [NonVersionable] public static void WriteUnaligned<T>(ref byte destination, T value) { System.Runtime.CompilerServices.Unsafe.WriteUnaligned<T>(ref destination, value); } [MethodImpl(256)] [NonVersionable] public unsafe static void Copy<T>(void* destination, ref T source) { System.Runtime.CompilerServices.Unsafe.Copy<T>(destination, ref source); } [MethodImpl(256)] [NonVersionable] public unsafe static void Copy<T>(ref T destination, void* source) { System.Runtime.CompilerServices.Unsafe.Copy<T>(ref destination, source); } [MethodImpl(256)] [NonVersionable] public unsafe static void* AsPointer<T>(ref T value) { return System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref value); } [MethodImpl(256)] [NonVersionable] public static void SkipInit<T>(out T value) { System.Runtime.CompilerServices.Unsafe.SkipInit<T>(ref value); } [MethodImpl(256)] [NonVersionable] public unsafe static void CopyBlock(void* destination, void* source, uint byteCount) { System.Runtime.CompilerServices.Unsafe.CopyBlock(destination, source, byteCount); } [MethodImpl(256)] [NonVersionable] public static void CopyBlock(ref byte destination, ref byte source, uint byteCount) { System.Runtime.CompilerServices.Unsafe.CopyBlock(ref destination, ref source, byteCount); } [MethodImpl(256)] [NonVersionable] public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(destination, source, byteCount); } [MethodImpl(256)] [NonVersionable] public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount) { System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount); } [MethodImpl(256)] [NonVersionable] public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { System.Runtime.CompilerServices.Unsafe.InitBlock(startAddress, value, byteCount); } [MethodImpl(256)] [NonVersionable] public static void InitBlock(ref byte startAddress, byte value, uint byteCount) { System.Runtime.CompilerServices.Unsafe.InitBlock(ref startAddress, value, byteCount); } [MethodImpl(256)] [NonVersionable] public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(startAddress, value, byteCount); } [MethodImpl(256)] [NonVersionable] public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount); } [MethodImpl(256)] [NonVersionable] public static T As<T>(object o) where T : class { return System.Runtime.CompilerServices.Unsafe.As<T>(o); } [MethodImpl(256)] [NonVersionable] public unsafe static ref T AsRef<T>(void* source) { return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(source); } [MethodImpl(256)] [NonVersionable] public static ref T AsRef<T>(in T source) { return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(ref source); } [MethodImpl(256)] [NonVersionable] public static ref TTo As<TFrom, TTo>(ref TFrom source) { return ref System.Runtime.CompilerServices.Unsafe.As<TFrom, TTo>(ref source); } [MethodImpl(256)] [NonVersionable] public static ref T Unbox<T>(object box) where T : struct { return ref System.Runtime.CompilerServices.Unsafe.Unbox<T>(box); } [MethodImpl(256)] [NonVersionable] public static ref T AddByteOffset<T>(ref T source, nint byteOffset) { return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref source, (System.IntPtr)byteOffset); } [MethodImpl(256)] [NonVersionable] public static ref T AddByteOffset<T>(ref T source, nuint byteOffset) { return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref source, (System.UIntPtr)byteOffset); } [MethodImpl(256)] [NonVersionable] public static ref T SubtractByteOffset<T>(ref T source, nint byteOffset) { return ref System.Runtime.CompilerServices.Unsafe.SubtractByteOffset<T>(ref source, (System.IntPtr)byteOffset); } [MethodImpl(256)] [NonVersionable] public static ref T SubtractByteOffset<T>(ref T source, nuint byteOffset) { return ref System.Runtime.CompilerServices.Unsafe.SubtractByteOffset<T>(ref source, (System.UIntPtr)byteOffset); } [MethodImpl(256)] [NonVersionable] public static nint ByteOffset<T>(ref T origin, ref T target) { return System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref origin, ref target); } [MethodImpl(256)] [NonVersionable] public static bool AreSame<T>(ref T left, ref T right) { return System.Runtime.CompilerServices.Unsafe.AreSame<T>(ref left, ref right); } [MethodImpl(256)] [NonVersionable] public static bool IsAddressGreaterThan<T>(ref T left, ref T right) { return System.Runtime.CompilerServices.Unsafe.IsAddressGreaterThan<T>(ref left, ref right); } [MethodImpl(256)] [NonVersionable] public static bool IsAddressLessThan<T>(ref T left, ref T right) { return System.Runtime.CompilerServices.Unsafe.IsAddressLessThan<T>(ref left, ref right); } [MethodImpl(256)] [NonVersionable] public static bool IsNullRef<T>(ref T source) { return System.Runtime.CompilerServices.Unsafe.IsNullRef<T>(ref source); } [MethodImpl(256)] [NonVersionable] public static ref T NullRef<T>() { return ref System.Runtime.CompilerServices.Unsafe.NullRef<T>(); } [MethodImpl(256)] [NonVersionable] public static int SizeOf<T>() { return System.Runtime.CompilerServices.Unsafe.SizeOf<T>(); } [MethodImpl(256)] [NonVersionable] public static ref T Add<T>(ref T source, int elementOffset) { return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref source, elementOffset); } [MethodImpl(256)] [NonVersionable] public unsafe static void* Add<T>(void* source, int elementOffset) { return System.Runtime.CompilerServices.Unsafe.Add<T>(source, elementOffset); } [MethodImpl(256)] [NonVersionable] public static ref T Add<T>(ref T source, nint elementOffset) { return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref source, (System.IntPtr)elementOffset); } [MethodImpl(256)] [NonVersionable] public static ref T Add<T>(ref T source, nuint elementOffset) { return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref source, (System.UIntPtr)elementOffset); } [MethodImpl(256)] [NonVersionable] public static ref T Subtract<T>(ref T source, int elementOffset) { return ref System.Runtime.CompilerServices.Unsafe.Subtract<T>(ref source, elementOffset); } [MethodImpl(256)] [NonVersionable] public unsafe static void* Subtract<T>(void* source, int elementOffset) { return System.Runtime.CompilerServices.Unsafe.Subtract<T>(source, elementOffset); } [MethodImpl(256)] [NonVersionable] public static ref T Subtract<T>(ref T source, nint elementOffset) { return ref System.Runtime.CompilerServices.Unsafe.Subtract<T>(ref source, (System.IntPtr)elementOffset); } [MethodImpl(256)] [NonVersionable] public static ref T Subtract<T>(ref T source, nuint elementOffset) { return ref System.Runtime.CompilerServices.Unsafe.Subtract<T>(ref source, (System.UIntPtr)elementOffset); } } } namespace System { public static class ArrayEx { public static int MaxLength => System.Array.MaxLength; [MethodImpl(256)] public static T[] Empty<T>() { return System.Array.Empty<T>(); } } public static class EnvironmentEx { public static int CurrentManagedThreadId => Environment.CurrentManagedThreadId; } public sealed class Gen2GcCallback : CriticalFinalizerObject { private readonly Func<bool>? _callback0; private readonly Func<object, bool>? _callback1; private GCHandle _weakTargetObj; private Gen2GcCallback(Func<bool> callback) { _callback0 = callback; } private Gen2GcCallback(Func<object, bool> callback, object targetObj) { //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) _callback1 = callback; _weakTargetObj = GCHandle.Alloc(targetObj, (GCHandleType)0); } public static void Register(Func<bool> callback) { new Gen2GcCallback(callback); } public static void Register(Func<object, bool> callback, object targetObj) { new Gen2GcCallback(callback, targetObj); } ~Gen2GcCallback() { try { if (((GCHandle)(ref _weakTargetObj)).IsAllocated) { object target = ((GCHandle)(ref _weakTargetObj)).Target; if (target == null) { ((GCHandle)(ref _weakTargetObj)).Free(); return; } try { if (!_callback1.Invoke(target)) { ((GCHandle)(ref _weakTargetObj)).Free(); return; } } catch { } } else { try { if (!_callback0.Invoke()) { return; } } catch { } } GC.ReRegisterForFinalize((object)this); } finally { ((CriticalFinalizerObject)this).Finalize(); } } } public static class MathEx { [MethodImpl(256)] public static byte Clamp(byte value, byte min, byte max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] public static decimal Clamp(decimal value, decimal min, decimal max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] public static double Clamp(double value, double min, double max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] public static short Clamp(short value, short min, short max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] public static int Clamp(int value, int min, int max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] public static long Clamp(long value, long min, long max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] public static nint Clamp(nint value, nint min, nint max) { return Math.Clamp((System.IntPtr)value, (System.IntPtr)min, (System.IntPtr)max); } [MethodImpl(256)] [CLSCompliant(false)] public static sbyte Clamp(sbyte value, sbyte min, sbyte max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] public static float Clamp(float value, float min, float max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] [CLSCompliant(false)] public static ushort Clamp(ushort value, ushort min, ushort max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] [CLSCompliant(false)] public static uint Clamp(uint value, uint min, uint max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] [CLSCompliant(false)] public static ulong Clamp(ulong value, ulong min, ulong max) { return Math.Clamp(value, min, max); } [MethodImpl(256)] [CLSCompliant(false)] public static nuint Clamp(nuint value, nuint min, nuint max) { return Math.Clamp((System.UIntPtr)value, (System.UIntPtr)min, (System.UIntPtr)max); } } [AttributeUsage(/*Could not decode attribute arguments.*/)] internal sealed class NonVersionableAttribute : System.Attribute { } public static class StringComparerEx { [MethodImpl(256)] public static StringComparer FromComparison(StringComparison comparisonType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return StringComparer.FromComparison(comparisonType); } } public static class StringExtensions { [MethodImpl(256)] public static string Replace(this string self, string oldValue, string newValue, StringComparison comparison) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) ThrowHelper.ThrowIfArgumentNull(self, ExceptionArgument.self); ThrowHelper.ThrowIfArgumentNull(oldValue, ExceptionArgument.oldValue); ThrowHelper.ThrowIfArgumentNull(newValue, ExceptionArgument.newValue); return self.Replace(oldValue, newValue, comparison); } [MethodImpl(256)] public static bool Contains(this string self, string value, StringComparison comparison) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) ThrowHelper.ThrowIfArgumentNull(self, ExceptionArgument.self); ThrowHelper.ThrowIfArgumentNull(value, ExceptionArgument.value); return self.Contains(value, comparison); } [MethodImpl(256)] public static bool Contains(this string self, char value, StringComparison comparison) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) ThrowHelper.ThrowIfArgumentNull(self, ExceptionArgument.self); return self.Contains(value, comparison); } [MethodImpl(256)] public static int GetHashCode(this string self, StringComparison comparison) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) ThrowHelper.ThrowIfArgumentNull(self, ExceptionArgument.self); return self.GetHashCode(comparison); } [MethodImpl(256)] public static int IndexOf(this string self, char value, StringComparison comparison) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) ThrowHelper.ThrowIfArgumentNull(self, ExceptionArgument.self); return self.IndexOf(value, comparison); } } internal static class ThrowHelper { [MethodImpl(256)] internal static void ThrowIfArgumentNull([NotNull] object? obj, ExceptionArgument argument) { if (obj == null) { ThrowArgumentNullException(argument); } } [MethodImpl(256)] internal static void ThrowIfArgumentNull([NotNull] object? obj, string argument, string? message = null) { if (obj == null) { ThrowArgumentNullException(argument, message); } } [DoesNotReturn] internal static void ThrowArgumentNullException(ExceptionArgument argument) { throw CreateArgumentNullException(argument); } [DoesNotReturn] internal static void ThrowArgumentNullException(string argument, string? message = null) { throw CreateArgumentNullException(argument, message); } [MethodImpl(8)] private static System.Exception CreateArgumentNullException(ExceptionArgument argument) { return CreateArgumentNullException(((object)argument).ToString()); } [MethodImpl(8)] private static System.Exception CreateArgumentNullException(string argument, string? message = null) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown return (System.Exception)new ArgumentNullException(argument, message); } [DoesNotReturn] internal static void ThrowArrayTypeMismatchException() { throw CreateArrayTypeMismatchException(); } [MethodImpl(8)] private static System.Exception CreateArrayTypeMismatchException() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown return (System.Exception)new ArrayTypeMismatchException(); } [DoesNotReturn] internal static void ThrowArgumentException_InvalidTypeWithPointersNotSupported(System.Type type) { throw CreateArgumentException_InvalidTypeWithPointersNotSupported(type); } [MethodImpl(8)] private static System.Exception CreateArgumentException_InvalidTypeWithPointersNotSupported(System.Type type) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown return (System.Exception)new ArgumentException($"Type {type} with managed pointers cannot be used in a Span"); } [DoesNotReturn] internal static void ThrowArgumentException_DestinationTooShort() { throw CreateArgumentException_DestinationTooShort(); } [MethodImpl(8)] private static System.Exception CreateArgumentException_DestinationTooShort() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new ArgumentException("Destination too short"); } [DoesNotReturn] internal static void ThrowArgumentException(string message, string? argument = null) { throw CreateArgumentException(message, argument); } [MethodImpl(8)] private static System.Exception CreateArgumentException(string message, string? argument) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown return (System.Exception)new ArgumentException(message, argument ?? ""); } [DoesNotReturn] internal static void ThrowIndexOutOfRangeException() { throw CreateIndexOutOfRangeException(); } [MethodImpl(8)] private static System.Exception CreateIndexOutOfRangeException() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown return (System.Exception)new IndexOutOfRangeException(); } [DoesNotReturn] internal static void ThrowArgumentOutOfRangeException() { throw CreateArgumentOutOfRangeException(); } [MethodImpl(8)] private static System.Exception CreateArgumentOutOfRangeException() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown return (System.Exception)new ArgumentOutOfRangeException(); } [DoesNotReturn] internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument) { throw CreateArgumentOutOfRangeException(argument); } [MethodImpl(8)] private static System.Exception CreateArgumentOutOfRangeException(ExceptionArgument argument) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown return (System.Exception)new ArgumentOutOfRangeException(((object)argument).ToString()); } [DoesNotReturn] internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge() { throw CreateArgumentOutOfRangeException_PrecisionTooLarge(); } [MethodImpl(8)] private static System.Exception CreateArgumentOutOfRangeException_PrecisionTooLarge() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown return (System.Exception)new ArgumentOutOfRangeException("precision", $"Precision too large (max: {99})"); } [DoesNotReturn] internal static void ThrowArgumentOutOfRangeException_SymbolDoesNotFit() { throw CreateArgumentOutOfRangeException_SymbolDoesNotFit(); } [MethodImpl(8)] private static System.Exception CreateArgumentOutOfRangeException_SymbolDoesNotFit() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown return (System.Exception)new ArgumentOutOfRangeException("symbol", "Bad format specifier"); } [DoesNotReturn] internal static void ThrowInvalidOperationException() { throw CreateInvalidOperationException(); } [MethodImpl(8)] private static System.Exception CreateInvalidOperationException() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown return (System.Exception)new InvalidOperationException(); } [DoesNotReturn] internal static void ThrowInvalidOperationException_OutstandingReferences() { throw CreateInvalidOperationException_OutstandingReferences(); } [MethodImpl(8)] private static System.Exception CreateInvalidOperationException_OutstandingReferences() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new InvalidOperationException("Outstanding references"); } [DoesNotReturn] internal static void ThrowInvalidOperationException_UnexpectedSegmentType() { throw CreateInvalidOperationException_UnexpectedSegmentType(); } [MethodImpl(8)] private static System.Exception CreateInvalidOperationException_UnexpectedSegmentType() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new InvalidOperationException("Unexpected segment type"); } [DoesNotReturn] internal static void ThrowInvalidOperationException_EndPositionNotReached() { throw CreateInvalidOperationException_EndPositionNotReached(); } [MethodImpl(8)] private static System.Exception CreateInvalidOperationException_EndPositionNotReached() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new InvalidOperationException("End position not reached"); } [DoesNotReturn] internal static void ThrowArgumentOutOfRangeException_PositionOutOfRange() { throw CreateArgumentOutOfRangeException_PositionOutOfRange(); } [MethodImpl(8)] private static System.Exception CreateArgumentOutOfRangeException_PositionOutOfRange() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new ArgumentOutOfRangeException("position"); } [DoesNotReturn] internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange() { throw CreateArgumentOutOfRangeException_OffsetOutOfRange(); } [MethodImpl(8)] private static System.Exception CreateArgumentOutOfRangeException_OffsetOutOfRange() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new ArgumentOutOfRangeException("offset"); } [DoesNotReturn] internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer() { throw CreateObjectDisposedException_ArrayMemoryPoolBuffer(); } [MethodImpl(8)] private static System.Exception CreateObjectDisposedException_ArrayMemoryPoolBuffer() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new ObjectDisposedException("ArrayMemoryPoolBuffer"); } [DoesNotReturn] internal static void ThrowFormatException_BadFormatSpecifier() { throw CreateFormatException_BadFormatSpecifier(); } [MethodImpl(8)] private static System.Exception CreateFormatException_BadFormatSpecifier() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new FormatException("Bad format specifier"); } [DoesNotReturn] internal static void ThrowArgumentException_OverlapAlignmentMismatch() { throw CreateArgumentException_OverlapAlignmentMismatch(); } [MethodImpl(8)] private static System.Exception CreateArgumentException_OverlapAlignmentMismatch() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new ArgumentException("Overlap alignment mismatch"); } [DoesNotReturn] internal static void ThrowNotSupportedException(string? msg = null) { throw CreateThrowNotSupportedException(msg); } [MethodImpl(8)] private static System.Exception CreateThrowNotSupportedException(string? msg) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown return (System.Exception)new NotSupportedException(); } [DoesNotReturn] internal static void ThrowKeyNullException() { ThrowArgumentNullException(ExceptionArgument.key); } [DoesNotReturn] internal static void ThrowValueNullException() { throw CreateThrowValueNullException(); } [MethodImpl(8)] private static System.Exception CreateThrowValueNullException() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown return (System.Exception)new ArgumentException("Value is null"); } [DoesNotReturn] internal static void ThrowOutOfMemoryException() { throw CreateOutOfMemoryException(); } [MethodImpl(8)] private static System.Exception CreateOutOfMemoryException() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown return (System.Exception)new OutOfMemoryException(); } public static bool TryFormatThrowFormatException(out int bytesWritten) { bytesWritten = 0; ThrowFormatException_BadFormatSpecifier(); return false; } public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed) { value = default(T); bytesConsumed = 0; ThrowFormatException_BadFormatSpecifier(); return false; } [DoesNotReturn] public static void ThrowArgumentValidationException<T>(ReadOnlySequenceSegment<T>? startSegment, int startIndex, ReadOnlySequenceSegment<T>? endSegment) { throw CreateArgumentValidationException<T>(startSegment, startIndex, endSegment); } private static System.Exception CreateArgumentValidationException<T>(ReadOnlySequenceSegment<T>? startSegment, int startIndex, ReadOnlySequenceSegment<T>? endSegment) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (startSegment == null) { return CreateArgumentNullException(ExceptionArgument.startSegment); } if (endSegment == null) { return CreateArgumentNullException(ExceptionArgument.endSegment); } if (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex) { return CreateArgumentOutOfRangeException(ExceptionArgument.endSegment); } if ((uint)startSegment.Memory.Length < (uint)startIndex) { return CreateArgumentOutOfRangeException(ExceptionArgument.startIndex); } return CreateArgumentOutOfRangeException(ExceptionArgument.endIndex); } [DoesNotReturn] public static void ThrowArgumentValidationException(System.Array? array, int start) { throw CreateArgumentValidationException(array, start); } private static System.Exception CreateArgumentValidationException(System.Array? array, int start) { if (array == null) { return CreateArgumentNullException(ExceptionArgument.array); } if ((uint)start > (uint)array.Length) { return CreateArgumentOutOfRangeException(ExceptionArgument.start); } return CreateArgumentOutOfRangeException(ExceptionArgument.length); } [DoesNotReturn] internal static void ThrowArgumentException_TupleIncorrectType(object other) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) throw new ArgumentException($"Value tuple of incorrect type (found {other.GetType()})", "other"); } [DoesNotReturn] public static void ThrowStartOrEndArgumentValidationException(long start) { throw CreateStartOrEndArgumentValidationException(start); } private static System.Exception CreateStartOrEndArgumentValidationException(long start) { if (start < 0) { return CreateArgumentOutOfRangeException(ExceptionArgument.start); } return CreateArgumentOutOfRangeException(ExceptionArgument.length); } } internal enum ExceptionArgument { length, start, bufferSize, minimumBufferSize, elementIndex, comparable, comparer, destination, offset, startSegment, endSegment, startIndex, endIndex, array, culture, manager, key, collection, index, type, self, value, oldValue, newValue } public static class TypeExtensions { public static bool IsByRefLike(this System.Type type) { ThrowHelper.ThrowIfArgumentNull(type, ExceptionArgument.type); if (type == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.type); } return type.IsByRefLike; } } } namespace System.Threading { public static class MonitorEx { [MethodImpl(256)] public static void Enter(object obj, ref bool lockTaken) { Monitor.Enter(obj, ref lockTaken); } } } namespace System.Text { public static class StringBuilderExtensions { [MethodImpl(256)] public static StringBuilder Clear(this StringBuilder builder) { ThrowHelper.ThrowIfArgumentNull(builder, "builder"); return builder.Clear(); } } } namespace System.Numerics { public static class BitOperationsEx { [MethodImpl(256)] public static bool IsPow2(int value) { return BitOperations.IsPow2(value); } [MethodImpl(256)] [CLSCompliant(false)] public static bool IsPow2(uint value) { return BitOperations.IsPow2(value); } [MethodImpl(256)] public static bool IsPow2(long value) { return BitOperations.IsPow2(value); } [MethodImpl(256)] [CLSCompliant(false)] public static bool IsPow2(ulong value) { return BitOperations.IsPow2(value); } [MethodImpl(256)] public static bool IsPow2(nint value) { return BitOperations.IsPow2((System.IntPtr)value); } [MethodImpl(256)] [CLSCompliant(false)] public static bool IsPow2(nuint value) { return BitOperations.IsPow2((System.UIntPtr)value); } [MethodImpl(256)] [CLSCompliant(false)] public static uint RoundUpToPowerOf2(uint value) { return BitOperations.RoundUpToPowerOf2(value); } [MethodImpl(256)] [CLSCompliant(false)] public static ulong RoundUpToPowerOf2(ulong value) { return BitOperations.RoundUpToPowerOf2(value); } [MethodImpl(256)] [CLSCompliant(false)] public static nuint RoundUpToPowerOf2(nuint value) { return BitOperations.RoundUpToPowerOf2((System.UIntPtr)value); } [MethodImpl(256)] [CLSCompliant(false)] public static int LeadingZeroCount(uint value) { return BitOperations.LeadingZeroCount(value); } [MethodImpl(256)] [CLSCompliant(false)] public static int LeadingZeroCount(ulong value) { return BitOperations.LeadingZeroCount(value); } [MethodImpl(256)] [CLSCompliant(false)] public static int LeadingZeroCount(nuint value) { return BitOperations.LeadingZeroCount((System.UIntPtr)value); } [MethodImpl(256)] [CLSCompliant(false)] public static int Log2(uint value) { return BitOperations.Log2(value); } [MethodImpl(256)] [CLSCompliant(false)] public static int Log2(ulong value) { return BitOperations.Log2(value); } [MethodImpl(256)] [CLSCompliant(false)] public static int Log2(nuint value) { return BitOperations.LeadingZeroCount((System.UIntPtr)value); } [MethodImpl(256)] [CLSCompliant(false)] public static int PopCount(uint value) { return BitOperations.PopCount(value); } [MethodImpl(256)] [CLSCompliant(false)] public static int PopCount(ulong value) { return BitOperations.PopCount(value); } [MethodImpl(256)] [CLSCompliant(false)] public static int PopCount(nuint value) { return BitOperations.PopCount((System.UIntPtr)value); } [MethodImpl(256)] public static int TrailingZeroCount(int value) { return BitOperations.TrailingZeroCount(value); } [MethodImpl(256)] [CLSCompliant(false)] public static int TrailingZeroCount(uint value) { return BitOperations.TrailingZeroCount(value); } [MethodImpl(256)] public static int TrailingZeroCount(long value) { return BitOperations.TrailingZeroCount(value); } [MethodImpl(256)] [CLSCompliant(false)] public static int TrailingZeroCount(ulong value) { return BitOperations.TrailingZeroCount(value); } [MethodImpl(256)] public static int TrailingZeroCount(nint value) { return BitOperations.TrailingZeroCount((System.IntPtr)value); } [MethodImpl(256)] [CLSCompliant(false)] public static int TrailingZeroCount(nuint value) { return BitOperations.TrailingZeroCount((System.UIntPtr)value); } [MethodImpl(256)] [CLSCompliant(false)] public static uint RotateLeft(uint value, int offset) { return BitOperations.RotateLeft(value, offset); } [MethodImpl(256)] [CLSCompliant(false)] public static ulong RotateLeft(ulong value, int offset) { return BitOperations.RotateLeft(value, offset); } [MethodImpl(256)] [CLSCompliant(false)] public static nuint RotateLeft(nuint value, int offset) { return BitOperations.RotateLeft((System.UIntPtr)value, offset); } [MethodImpl(256)] [CLSCompliant(false)] public static uint RotateRight(uint value, int offset) { return BitOperations.RotateRight(value, offset); } [MethodImpl(256)] [CLSCompliant(false)] public static ulong RotateRight(ulong value, int offset) { return BitOperations.RotateRight(value, offset); } [MethodImpl(256)] [CLSCompliant(false)] public static nuint RotateRight(nuint value, int offset) { return BitOperations.RotateLeft((System.UIntPtr)value, offset); } } } namespace System.IO { public static class StreamExtensions { public static void CopyTo(this Stream src, Stream destination) { ThrowHelper.ThrowIfArgumentNull(src, "src"); src.CopyTo(destination); } public static void CopyTo(this Stream src, Stream destination, int bufferSize) { ThrowHelper.ThrowIfArgumentNull(src, "src"); src.CopyTo(destination, bufferSize); } } } namespace System.Diagnostics.CodeAnalysis { public static class ExtraDynamicallyAccessedMemberTypes { public const DynamicallyAccessedMemberTypes Interfaces = 8192; } } namespace System.Collections { internal static class HashHelpers { public const uint HashCollisionThreshold = 100u; public const int MaxPrimeArrayLength = 2147483587; public const int HashPrime = 101; private static readonly int[] s_primes; public static bool IsPrime(int candidate) { if (((uint)candidate & (true ? 1u : 0u)) != 0) { int num = (int)Math.Sqrt((double)candidate); for (int i = 3; i <= num; i += 2) { if (candidate % i == 0) { return false; } } return true; } return candidate == 2; } public static int GetPrime(int min) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (min < 0) { throw new ArgumentException("Prime minimum cannot be less than zero"); } int[] array = s_primes; foreach (int num in array) { if (num >= min) { return num; } } for (int j = min | 1; j < 2147483647; j += 2) { if (IsPrime(j) && (j - 1) % 101 != 0) { return j; } } return min; } public static int ExpandPrime(int oldSize) { int num = 2 * oldSize; if ((uint)num > 2147483587u && 2147483587 > oldSize) { return 2147483587; } return GetPrime(num); } public static ulong GetFastModMultiplier(uint divisor) { return 18446744073709551615uL / (ulong)divisor + 1; } [MethodImpl(256)] public static uint FastMod(uint value, uint divisor, ulong multiplier) { return (uint)(((multiplier * value >> 32) + 1) * divisor >> 32); } static HashHelpers() { int[] array = new int[72]; RuntimeHelpers.InitializeArray((System.Array)array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); s_primes = array; } } } namespace System.Collections.Concurrent { public static class ConcurrentExtensions { public static void Clear<T>(this ConcurrentBag<T> bag) { ThrowHelper.ThrowIfArgumentNull(bag, "bag"); bag.Clear(); } public static void Clear<T>(this ConcurrentQueue<T> queue) { ThrowHelper.ThrowIfArgumentNull(queue, "queue"); queue.Clear(); } public static TValue AddOrUpdate<TKey, TValue, TArg>(this ConcurrentDictionary<TKey, TValue> dict, TKey key, Func<TKey, TArg, TValue> addValueFactory, Func<TKey, TValue, TArg, TValue> updateValueFactory, TArg factoryArgument) where TKey : notnull { ThrowHelper.ThrowIfArgumentNull(dict, "dict"); return ((ConcurrentDictionary<TArg, ?>)(object)dict).AddOrUpdate<TArg>((TArg)key, (Func<TArg, TArg, ?>)(object)addValueFactory, (Func<TArg, ?, TArg, ?>)(object)updateValueFactory, factoryArgument); } public static TValue GetOrAdd<TKey, TValue, TArg>(this ConcurrentDictionary<TKey, TValue> dict, TKey key, Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument) where TKey : notnull { ThrowHelper.ThrowIfArgumentNull(dict, "dict"); return ((ConcurrentDictionary<TArg, ?>)(object)dict).GetOrAdd<TArg>((TArg)key, (Func<TArg, TArg, ?>)(object)valueFactory, factoryArgument); } public static bool TryRemove<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dict, KeyValuePair<TKey, TValue> item) where TKey : notnull { //IL_000d: Unknown result type (might be due to invalid IL or missing references) ThrowHelper.ThrowIfArgumentNull(dict, "dict"); return dict.TryRemove(item); } } } namespace System.Runtime.InteropServices { public static class MarshalEx { [MethodImpl(256)] public static int GetLastPInvokeError() { return Marshal.GetLastPInvokeError(); } [MethodImpl(256)] public static void SetLastPInvokeError(int error) { Marshal.SetLastPInvokeError(error); } } } namespace System.Runtime.CompilerServices { [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal static class IsExternalInit { } internal interface ICWTEnumerable<T> { System.Collections.Generic.IEnumerable<T> SelfEnumerable { get; } System.Collections.Generic.IEnumerator<T> GetEnumerator(); } internal sealed class CWTEnumerable<TKey, TValue> : System.Collections.Generic.IEnumerable<KeyValuePair<TKey, TValue>>, System.Collections.IEnumerable where TKey : class where TValue : class? { private readonly ConditionalWeakTable<TKey, TValue> cwt; public CWTEnumerable(ConditionalWeakTable<TKey, TValue> table) { cwt = table; } public System.Collections.Generic.IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return cwt.GetEnumerator<TKey, TValue>(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return (System.Collections.IEnumerator)GetEnumerator(); } } public static class ConditionalWeakTableExtensions { public static System.Collections.Generic.IEnumerable<KeyValuePair<TKey, TValue>> AsEnumerable<TKey, TValue>(this ConditionalWeakTable<TKey, TValue> self) where TKey : class where TValue : class? { ThrowHelper.ThrowIfArgumentNull(self, "self"); if (self != null) { return (System.Collections.Generic.IEnumerable<KeyValuePair<TKey, TValue>>)self; } if (self is ICWTEnumerable<KeyValuePair<TKey, TValue>> iCWTEnumerable) { return iCWTEnumerable.SelfEnumerable; } return new CWTEnumerable<TKey, TValue>(self); } public static System.Collections.Generic.IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator<TKey, TValue>(this ConditionalWeakTable<TKey, TValue> self) where TKey : class where TValue : class? { //IL_002e: Unknown result type (might be due to invalid IL or missing references) ThrowHelper.ThrowIfArgumentNull(self, "self"); if (self != null) { return ((System.Collections.Generic.IEnumerable<KeyValuePair<TKey, TValue>>)self).GetEnumerator(); } if (self is ICWTEnumerable<KeyValuePair<TKey, TValue>> iCWTEnumerable) { return iCWTEnumerable.GetEnumerator(); } throw new PlatformNotSupportedException("This version of MonoMod.Backports was built targeting a version of the framework where ConditionalWeakTable is enumerable, but it isn't!"); } public static void Clear<TKey, TValue>(this ConditionalWeakTable<TKey, TValue> self) where TKey : class where TValue : class? { ThrowHelper.ThrowIfArgumentNull(self, "self"); self.Clear(); } public static bool TryAdd<TKey, TValue>(this ConditionalWeakTable<TKey, TValue> self, TKey key, TValue value) where TKey : class where TValue : class? { ThrowHelper.ThrowIfArgumentNull(self, "self"); return self.TryAdd(key, value); } } [DefaultMember("Item")] internal interface ITuple { int Length { get; } object? this[int index] { get; } } }
BepInExPack/BepInEx/core/MonoMod.Core.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Numerics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using Iced.Intel; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod; using MonoMod.Core.Interop; using MonoMod.Core.Interop.Attributes; using MonoMod.Core.Platforms; using MonoMod.Core.Platforms.Architectures; using MonoMod.Core.Platforms.Architectures.AltEntryFactories; using MonoMod.Core.Platforms.Memory; using MonoMod.Core.Platforms.Runtimes; using MonoMod.Core.Platforms.Systems; using MonoMod.Core.Utils; using MonoMod.Logs; using MonoMod.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)] [assembly: DisableRuntimeMarshalling] [assembly: CLSCompliant(false)] [assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] [assembly: AssemblyCompany("0x0ade, DaNike")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2026 0x0ade, DaNike")] [assembly: AssemblyDescription("The code functionality for runtime detouring. Use `DetourFactory.Current` to get a DetourFactory capable of installing unique method detours.\n \n WARNING: THIS IS A LOW-LEVEL LIBRARY THAT IS DIFFICULT TO USE ON ITS OWN. If possible, use MonoMod.RuntimeDetour instead.")] [assembly: AssemblyFileVersion("1.3.4.0")] [assembly: AssemblyInformationalVersion("1.3.4+69fdc9deb")] [assembly: AssemblyProduct("MonoMod.Core")] [assembly: AssemblyTitle("MonoMod.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoMod/MonoMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { MMDbgLog.LogVersion(); } } [CompilerGenerated] internal unsafe delegate CoreCLR.CorJitResult <>f__AnonymousDelegate0(nint arg1, nint arg2, CoreCLR.V21.CORINFO_METHOD_INFO* arg3, uint arg4, byte** arg5, uint* arg6); [CompilerGenerated] internal unsafe delegate CoreCLR.CorJitResult <>f__AnonymousDelegate1(nint arg1, nint arg2, CoreCLR.V21.CORINFO_METHOD_INFO* arg3, uint arg4, byte** arg5, uint* arg6, CoreCLR.CorJitResult arg7, CoreCLR.V60.AllocMemArgs* arg8); [CompilerGenerated] internal unsafe delegate void <>f__AnonymousDelegate2(nint arg1, CoreCLR.V60.AllocMemArgs* arg2); namespace MonoMod { internal static class MMDbgLog { [InterpolatedStringHandler] internal ref struct DebugLogSpamStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogSpamStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)0, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogTraceStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogTraceStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)1, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogInfoStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogInfoStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)2, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogWarningStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogWarningStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)3, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogErrorStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogErrorStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)4, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } public static bool IsWritingLog => DebugLog.IsWritingLog; [ModuleInitializer] internal static void LogVersion() { Info("Version 1.3.4"); } public static void Log(LogLevel level, string message) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) DebugLog.Log("MonoMod.Core", level, message); } public static void Log(LogLevel level, [InterpolatedStringHandlerArgument("level")] ref DebugLogInterpolatedStringHandler message) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) DebugLog.Log("MonoMod.Core", level, ref message); } public static void Spam(string message) { Log((LogLevel)0, message); } public static void Spam(ref DebugLogSpamStringHandler message) { Log((LogLevel)0, ref message.handler); } public static void Trace(string message) { Log((LogLevel)1, message); } public static void Trace(ref DebugLogTraceStringHandler message) { Log((LogLevel)1, ref message.handler); } public static void Info(string message) { Log((LogLevel)2, message); } public static void Info(ref DebugLogInfoStringHandler message) { Log((LogLevel)2, ref message.handler); } public static void Warning(string message) { Log((LogLevel)3, message); } public static void Warning(ref DebugLogWarningStringHandler message) { Log((LogLevel)3, ref message.handler); } public static void Error(string message) { Log((LogLevel)4, message); } public static void Error(ref DebugLogErrorStringHandler message) { Log((LogLevel)4, ref message.handler); } } internal static class MultiTargetShims { public static TypeReference GetConstraintType(this GenericParameterConstraint constraint) { return constraint.ConstraintType; } } } namespace MonoMod.SourceGen.Attributes { [AttributeUsage(AttributeTargets.Class)] internal sealed class EmitILOverloadsAttribute : Attribute { public EmitILOverloadsAttribute(string filename, string kind) { } } internal static class ILOverloadKind { public const string Cursor = "ILCursor"; public const string Matcher = "ILMatcher"; } } namespace MonoMod.Core { [CLSCompliant(true)] public interface ICoreDetour : ICoreDetourBase, IDisposable { MethodBase Source { get; } MethodBase Target { get; } } public interface ICoreDetourWithClone : ICoreDetour, ICoreDetourBase, IDisposable { MethodInfo? SourceMethodClone { get; } DynamicMethodDefinition? SourceMethodCloneIL { get; } } public interface ICoreDetourBase : IDisposable { bool IsApplied { get; } void Apply(); void Undo(); } public interface ICoreNativeDetour : ICoreDetourBase, IDisposable { nint Source { get; } nint Target { get; } bool HasOrigEntrypoint { get; } nint OrigEntrypoint { get; } } [CLSCompliant(true)] public interface IDetourFactory { bool SupportsNativeDetourOrigEntrypoint { get; } ICoreDetour CreateDetour(CreateDetourRequest request); ICoreNativeDetour CreateNativeDetour(CreateNativeDetourRequest request); } [CLSCompliant(true)] public readonly record struct CreateDetourRequest { public MethodBase Source { get; init; } public MethodBase Target { get; init; } public bool ApplyByDefault { get; init; } public bool CreateSourceCloneIfNotILClone { get; init; } public CreateDetourRequest(MethodBase Source, MethodBase Target) { CreateSourceCloneIfNotILClone = false; this.Source = Source; this.Target = Target; ApplyByDefault = true; } [CompilerGenerated] public void Deconstruct(out MethodBase Source, out MethodBase Target) { Source = this.Source; Target = this.Target; } } [CLSCompliant(true)] public readonly record struct CreateNativeDetourRequest(nint Source, nint Target) { public bool ApplyByDefault { get; init; } = true; } [CLSCompliant(true)] public static class DetourFactory { private static object currentLock = new object(); private static IDetourFactory? lazyDefault; private static IDetourFactory? lazyCurrent; public unsafe static IDetourFactory Default => Helpers.GetOrInitWithLock<IDetourFactory>(ref lazyDefault, currentLock, (delegate*<IDetourFactory>)(&CreateDefault)); public unsafe static IDetourFactory Current => Helpers.GetOrInitWithLock<IDetourFactory>(ref lazyCurrent, currentLock, (delegate*<IDetourFactory>)(&CreateCurrent)); private static IDetourFactory CreateDefault() { return new PlatformTripleDetourFactory(PlatformTriple.Current); } private static IDetourFactory CreateCurrent() { return Default; } [EditorBrowsable(EditorBrowsableState.Never)] public static void SetCurrentFactory(Func<IDetourFactory, IDetourFactory> creator) { Helpers.ThrowIfArgumentNull<Func<IDetourFactory, IDetourFactory>>(creator, "creator"); lock (currentLock) { lazyCurrent = creator(Current); } } public static ICoreDetour CreateDetour(this IDetourFactory factory, MethodBase source, MethodBase target, bool applyByDefault = true) { Helpers.ThrowIfArgumentNull<IDetourFactory>(factory, "factory"); return factory.CreateDetour(new CreateDetourRequest(source, target) { ApplyByDefault = applyByDefault }); } public static ICoreNativeDetour CreateNativeDetour(this IDetourFactory factory, nint source, nint target, bool applyByDefault = true) { Helpers.ThrowIfArgumentNull<IDetourFactory>(factory, "factory"); return factory.CreateNativeDetour(new CreateNativeDetourRequest(source, target) { ApplyByDefault = applyByDefault }); } } internal static class AssemblyInfo { public const string AssemblyName = "MonoMod.Core"; public const string AssemblyVersion = "1.3.4"; } } namespace MonoMod.Core.Utils { [Flags] public enum AddressKind { Rel32 = 0, Rel64 = 2, Abs32 = 1, Abs64 = 3, PrecodeFixupThunkRel32 = 4, PrecodeFixupThunkRel64 = 6, PrecodeFixupThunkAbs32 = 5, PrecodeFixupThunkAbs64 = 7, Indirect = 8, ConstantAddr = 0x10 } public static class AddressKindExtensions { public const AddressKind IsAbsoluteField = AddressKind.Abs32; public const AddressKind Is64BitField = AddressKind.Rel64; public const AddressKind IsPrecodeFixupField = AddressKind.PrecodeFixupThunkRel32; public const AddressKind IsIndirectField = AddressKind.Indirect; public const AddressKind IsConstantField = AddressKind.ConstantAddr; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsRelative(this AddressKind value) { return (value & AddressKind.Abs32) == 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsAbsolute(this AddressKind value) { return !value.IsRelative(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is32Bit(this AddressKind value) { return (value & AddressKind.Rel64) == 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is64Bit(this AddressKind value) { return !value.Is32Bit(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsPrecodeFixup(this AddressKind value) { return (value & AddressKind.PrecodeFixupThunkRel32) != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsIndirect(this AddressKind value) { return (value & AddressKind.Indirect) != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsConstant(this AddressKind value) { return (value & AddressKind.ConstantAddr) != 0; } public static void Validate(this AddressKind value, [CallerArgumentExpression("value")] string argName = "") { if ((value & ~(AddressKind.PrecodeFixupThunkAbs64 | AddressKind.Indirect | AddressKind.ConstantAddr)) != AddressKind.Rel32) { throw new ArgumentOutOfRangeException(argName); } } public static string FastToString(this AddressKind value) { FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val))..ctor(0, 4); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted(value.IsPrecodeFixup() ? "PrecodeFixupThunk" : ""); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted(value.IsRelative() ? "Rel" : "Abs"); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted(value.Is32Bit() ? "32" : "64"); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted(value.IsIndirect() ? "Indirect" : ""); return DebugFormatter.Format(ref val); } } public readonly struct AddressMeaning : IEquatable<AddressMeaning> { public AddressKind Kind { get; } public int RelativeToOffset { get; } public ulong ConstantValue { get; } public AddressMeaning(AddressKind kind) { ConstantValue = 0uL; kind.Validate("kind"); if (!kind.IsAbsolute()) { throw new ArgumentOutOfRangeException("kind"); } Kind = kind; RelativeToOffset = 0; } public AddressMeaning(AddressKind kind, int relativeOffset) { ConstantValue = 0uL; kind.Validate("kind"); if (!kind.IsRelative()) { throw new ArgumentOutOfRangeException("kind"); } if (relativeOffset < 0) { throw new ArgumentOutOfRangeException("relativeOffset"); } Kind = kind; RelativeToOffset = relativeOffset; } public AddressMeaning(AddressKind kind, int relativeOffset, ulong constantValue) { kind.Validate("kind"); if (!kind.IsRelative()) { throw new ArgumentOutOfRangeException("kind"); } if (relativeOffset < 0) { throw new ArgumentOutOfRangeException("relativeOffset"); } Kind = kind; RelativeToOffset = relativeOffset; ConstantValue = constantValue; } private unsafe static nint DoProcessAddress(AddressKind kind, nint basePtr, int offset, ulong constantValue, ulong address) { if (kind.IsConstant()) { address = constantValue; } nint num; if (kind.IsAbsolute()) { num = (nint)address; } else { long num2 = (kind.Is32Bit() ? Unsafe.As<ulong, int>(ref address) : Unsafe.As<ulong, long>(ref address)); num = (nint)(basePtr + offset + num2); } if (kind.IsIndirect()) { num = *(nint*)num; } return num; } public nint ProcessAddress(nint basePtr, int offset, ulong address) { return DoProcessAddress(Kind, basePtr, offset + RelativeToOffset, ConstantValue, address); } public override bool Equals(object? obj) { if (obj is AddressMeaning other) { return Equals(other); } return false; } public bool Equals(AddressMeaning other) { if (Kind == other.Kind && RelativeToOffset == other.RelativeToOffset) { return ConstantValue == other.ConstantValue; } return false; } public override string ToString() { FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val))..ctor(38, 3); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral("AddressMeaning("); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted(Kind.FastToString()); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(", offset: "); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<int>(RelativeToOffset); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(", constant: "); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<ulong>(ConstantValue); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(")"); return DebugFormatter.Format(ref val); } public override int GetHashCode() { return HashCode.Combine(Kind, RelativeToOffset, ConstantValue); } public static bool operator ==(AddressMeaning left, AddressMeaning right) { return left.Equals(right); } public static bool operator !=(AddressMeaning left, AddressMeaning right) { return !(left == right); } } public sealed class BytePattern { private enum SegmentKind { Literal, MaskedLiteral, Any, AnyRepeating, Address } private record struct PatternSegment(int Start, int Length, SegmentKind Kind) { public ReadOnlySpan<T> SliceOf<T>(ReadOnlySpan<T> span) { return span.Slice(Start, Length); } public ReadOnlyMemory<T> SliceOf<T>(ReadOnlyMemory<T> mem) { return mem.Slice(Start, Length); } } private readonly record struct ComputeSegmentsResult(PatternSegment[] Segments, int MinLen, int AddrBytes); private const ushort MaskMask = 65280; public const byte BAnyValue = 0; public const ushort SAnyValue = 65280; public const byte BAnyRepeatingValue = 1; public const ushort SAnyRepeatingValue = 65281; public const byte BAddressValue = 2; public const ushort SAddressValue = 65282; private readonly ReadOnlyMemory<byte> pattern; private readonly ReadOnlyMemory<byte> bitmask; private readonly PatternSegment[] segments; private (ReadOnlyMemory<byte> Bytes, int Offset)? lazyFirstLiteralSegment; public int AddressBytes { get; } public int MinLength { get; } public AddressMeaning AddressMeaning { get; } public bool MustMatchAtStart { get; } public (ReadOnlyMemory<byte> Bytes, int Offset) FirstLiteralSegment { get { (ReadOnlyMemory<byte>, int) valueOrDefault = lazyFirstLiteralSegment.GetValueOrDefault(); if (!lazyFirstLiteralSegment.HasValue) { valueOrDefault = GetFirstLiteralSegment(); lazyFirstLiteralSegment = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } public BytePattern(AddressMeaning meaning, params ushort[] pattern) : this(meaning, mustMatchAtStart: false, pattern.AsMemory()) { } public BytePattern(AddressMeaning meaning, bool mustMatchAtStart, params ushort[] pattern) : this(meaning, mustMatchAtStart, pattern.AsMemory()) { } public BytePattern(AddressMeaning meaning, ReadOnlyMemory<ushort> pattern) : this(meaning, mustMatchAtStart: false, pattern) { } public BytePattern(AddressMeaning meaning, bool mustMatchAtStart, ReadOnlyMemory<ushort> pattern) { AddressMeaning = meaning; MustMatchAtStart = mustMatchAtStart; ComputeSegmentsFromShort(pattern).Deconstruct(out PatternSegment[] Segments, out int MinLen, out int AddrBytes); segments = Segments; MinLength = MinLen; AddressBytes = AddrBytes; Memory<byte> memory = new byte[pattern.Length * 2].AsMemory(); Memory<byte> memory2 = memory.Slice(0, pattern.Length); Memory<byte> memory3 = memory.Slice(pattern.Length); for (int i = 0; i < pattern.Length; i++) { ushort num = pattern.Span[i]; byte b = (byte)((num & 0xFF00) >> 8); byte b2 = (byte)(num & -65281); if ((b == 0 || b == byte.MaxValue) ? true : false) { b = (byte)(~b); } memory2.Span[i] = (byte)(b2 & b); memory3.Span[i] = b; } this.pattern = memory2; bitmask = memory3; } public BytePattern(AddressMeaning meaning, ReadOnlyMemory<byte> mask, ReadOnlyMemory<byte> pattern) : this(meaning, mustMatchAtStart: false, mask, pattern) { } public BytePattern(AddressMeaning meaning, bool mustMatchAtStart, ReadOnlyMemory<byte> mask, ReadOnlyMemory<byte> pattern) { AddressMeaning = meaning; MustMatchAtStart = mustMatchAtStart; ComputeSegmentsFromMaskPattern(mask, pattern).Deconstruct(out PatternSegment[] Segments, out int MinLen, out int AddrBytes); segments = Segments; MinLength = MinLen; AddressBytes = AddrBytes; this.pattern = pattern; bitmask = mask; } private unsafe static ComputeSegmentsResult ComputeSegmentsFromShort(ReadOnlyMemory<ushort> pattern) { return ComputeSegmentsCore((delegate*<ReadOnlyMemory<ushort>, int, SegmentKind>)(&KindForShort), pattern.Length, pattern); static SegmentKind KindForShort(ReadOnlyMemory<ushort> readOnlyMemory, int idx) { ushort num = readOnlyMemory.Span[idx]; switch (num & 0xFF00) { case 0: return SegmentKind.Literal; case 65280: { int num2 = num & 0xFF; return num2 switch { 0 => SegmentKind.Any, 1 => SegmentKind.AnyRepeating, 2 => SegmentKind.Address, _ => throw new ArgumentException($"Pattern contained unknown special value {num2:x2}", "pattern"), }; } default: return SegmentKind.MaskedLiteral; } } } private unsafe static ComputeSegmentsResult ComputeSegmentsFromMaskPattern(ReadOnlyMemory<byte> mask, ReadOnlyMemory<byte> pattern) { if (mask.Length < pattern.Length) { throw new ArgumentException("Mask buffer shorter than pattern", "mask"); } return ComputeSegmentsCore((delegate*<(ReadOnlyMemory<byte>, ReadOnlyMemory<byte>), int, SegmentKind>)(&KindForIdx), pattern.Length, (mask, pattern)); static SegmentKind KindForIdx((ReadOnlyMemory<byte> mask, ReadOnlyMemory<byte> pattern) t, int idx) { switch (t.mask.Span[idx]) { case 0: { byte b = t.pattern.Span[idx]; return b switch { 0 => SegmentKind.Any, 1 => SegmentKind.AnyRepeating, 2 => SegmentKind.Address, _ => throw new ArgumentException($"Pattern contained unknown special value {b:x2}", "pattern"), }; } case byte.MaxValue: return SegmentKind.Literal; default: return SegmentKind.MaskedLiteral; } } } private unsafe static ComputeSegmentsResult ComputeSegmentsCore<TPattern>(delegate*<TPattern, int, SegmentKind> kindForIdx, int patternLength, TPattern pattern) { if (patternLength == 0) { throw new ArgumentException("Pattern cannot be empty", "pattern"); } int num = 0; SegmentKind segmentKind = SegmentKind.AnyRepeating; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = -1; for (int i = 0; i < patternLength; i++) { SegmentKind segmentKind2 = kindForIdx(pattern, i); int num6 = num4; num4 = num6 + segmentKind2 switch { SegmentKind.Literal => 1, SegmentKind.MaskedLiteral => 1, SegmentKind.Any => 1, SegmentKind.AnyRepeating => 0, SegmentKind.Address => 1, _ => 0, }; if (segmentKind2 != segmentKind) { if (num5 < 0) { num5 = i; } num++; num2 = 1; } else { num2++; } if (segmentKind2 == SegmentKind.Address) { num3++; } segmentKind = segmentKind2; } if (num > 0 && segmentKind == SegmentKind.AnyRepeating) { num--; } if (num == 0 || num4 <= 0) { throw new ArgumentException("Pattern has no meaningful segments", "pattern"); } PatternSegment[] array = new PatternSegment[num]; num = 0; segmentKind = SegmentKind.AnyRepeating; num2 = 0; for (int j = num5; j < patternLength; j++) { if (num > array.Length) { break; } SegmentKind num7 = kindForIdx(pattern, j); if (num7 != segmentKind) { if (num > 0) { array[num - 1] = new PatternSegment(j - num2, num2, segmentKind); if (num > 1 && segmentKind == SegmentKind.Any && array[num - 2].Kind == SegmentKind.AnyRepeating) { Helpers.Swap<PatternSegment>(ref array[num - 2], ref array[num - 1]); } } num++; num2 = 1; } else { num2++; } segmentKind = num7; } if (segmentKind != SegmentKind.AnyRepeating && num > 0) { array[num - 1] = new PatternSegment(patternLength - num2, num2, segmentKind); } return new ComputeSegmentsResult(array, num4, num3); } public bool TryMatchAt(ReadOnlySpan<byte> data, out ulong address, out int length) { if (data.Length < MinLength) { length = 0; address = 0uL; return false; } ReadOnlySpan<byte> span = pattern.Span; Span<byte> addrBuf = stackalloc byte[8]; bool result = TryMatchAtImpl(span, data, addrBuf, out length, 0); address = Unsafe.ReadUnaligned<ulong>(in addrBuf[0]); return result; } public bool TryMatchAt(ReadOnlySpan<byte> data, Span<byte> addrBuf, out int length) { if (data.Length < MinLength) { length = 0; return false; } ReadOnlySpan<byte> span = pattern.Span; return TryMatchAtImpl(span, data, addrBuf, out length, 0); } private bool TryMatchAtImpl(ReadOnlySpan<byte> patternSpan, ReadOnlySpan<byte> data, Span<byte> addrBuf, out int length, int startAtSegment) { int num = 0; int num2 = startAtSegment; while (true) { if (num2 < segments.Length) { PatternSegment patternSegment = segments[num2]; switch (patternSegment.Kind) { case SegmentKind.Literal: if (data.Length - num >= patternSegment.Length) { ReadOnlySpan<byte> span = patternSegment.SliceOf(patternSpan); if (span.SequenceEqual(data.Slice(num, span.Length))) { num += patternSegment.Length; goto IL_0192; } } break; case SegmentKind.MaskedLiteral: if (data.Length - num >= patternSegment.Length) { ReadOnlySpan<byte> readOnlySpan2 = patternSegment.SliceOf(patternSpan); ReadOnlySpan<byte> readOnlySpan3 = patternSegment.SliceOf(bitmask.Span); if (Helpers.MaskedSequenceEqual(readOnlySpan2, data.Slice(num, readOnlySpan2.Length), readOnlySpan3)) { num += patternSegment.Length; goto IL_0192; } } break; case SegmentKind.Any: if (data.Length - num >= patternSegment.Length) { num += patternSegment.Length; goto IL_0192; } break; case SegmentKind.Address: if (data.Length - num >= patternSegment.Length) { ReadOnlySpan<byte> readOnlySpan = data.Slice(num, Math.Min(patternSegment.Length, addrBuf.Length)); readOnlySpan.CopyTo(addrBuf); addrBuf = addrBuf.Slice(Math.Min(addrBuf.Length, readOnlySpan.Length)); num += patternSegment.Length; goto IL_0192; } break; case SegmentKind.AnyRepeating: { int offset; int length2; bool result = ScanForNextLiteral(patternSpan, data.Slice(num), addrBuf, out offset, out length2, num2); length = num + offset + length2; return result; } default: throw new InvalidOperationException(); } break; } length = num; return true; IL_0192: num2++; } length = 0; return false; } public bool TryFindMatch(ReadOnlySpan<byte> data, out ulong address, out int offset, out int length) { if (data.Length < MinLength) { length = (offset = 0); address = 0uL; return false; } ReadOnlySpan<byte> span = pattern.Span; Span<byte> addrBuf = stackalloc byte[8]; bool result; if (MustMatchAtStart) { offset = 0; result = TryMatchAtImpl(span, data, addrBuf, out length, 0); } else { result = ScanForNextLiteral(span, data, addrBuf, out offset, out length, 0); } address = Unsafe.ReadUnaligned<ulong>(in addrBuf[0]); return result; } public bool TryFindMatch(ReadOnlySpan<byte> data, Span<byte> addrBuf, out int offset, out int length) { if (data.Length < MinLength) { length = (offset = 0); return false; } ReadOnlySpan<byte> span = pattern.Span; if (MustMatchAtStart) { offset = 0; return TryMatchAtImpl(span, data, addrBuf, out length, 0); } return ScanForNextLiteral(span, data, addrBuf, out offset, out length, 0); } private bool ScanForNextLiteral(ReadOnlySpan<byte> patternSpan, ReadOnlySpan<byte> data, Span<byte> addrBuf, out int offset, out int length, int segmentIndex) { var (patternSegment, num) = GetNextLiteralSegment(segmentIndex); if (num + patternSegment.Length > data.Length) { offset = (length = 0); return false; } int num2 = 0; while (true) { int num3 = data.Slice(num + num2).IndexOf(patternSegment.SliceOf(patternSpan)); if (num3 < 0) { offset = (length = 0); return false; } if (TryMatchAtImpl(patternSpan, data.Slice(offset = num2 + num3), addrBuf, out length, segmentIndex)) { break; } num2 += num3 + 1; } return true; } private (ReadOnlyMemory<byte> Bytes, int Offset) GetFirstLiteralSegment() { var (patternSegment, item) = GetNextLiteralSegment(0); return (Bytes: patternSegment.SliceOf(pattern), Offset: item); } private (PatternSegment Segment, int LiteralOffset) GetNextLiteralSegment(int segmentIndexId) { if (segmentIndexId < 0 || segmentIndexId >= segments.Length) { throw new ArgumentOutOfRangeException("segmentIndexId"); } int num = 0; while (segmentIndexId < segments.Length) { PatternSegment item = segments[segmentIndexId]; if (item.Kind == SegmentKind.Literal) { return (Segment: item, LiteralOffset: num); } SegmentKind kind = item.Kind; if (((uint)(kind - 1) <= 1u || kind == SegmentKind.Address) ? true : false) { num += item.Length; } else if (item.Kind != SegmentKind.AnyRepeating) { throw new InvalidOperationException("Unknown segment kind"); } segmentIndexId++; } return (Segment: default(PatternSegment), LiteralOffset: num); } } public sealed class BytePatternCollection : IEnumerable<BytePattern>, IEnumerable { private struct HomogenousPatternCollection { public BytePattern[]?[] Lut; public readonly int Offset; public int MinLength; public HomogenousPatternCollection(int offs) { Offset = offs; Lut = null; MinLength = int.MaxValue; } public void AddFirstBytes(ref FirstByteCollection bytes) { for (int i = 0; i < Lut.Length; i++) { if (Lut[i] != null) { bytes.Add((byte)i); } } } } private ref struct FirstByteCollection { private Span<byte> firstByteStore; private Span<byte> byteIndicies; private int firstBytesRecorded; public const int SingleAllocationSize = 512; public ReadOnlySpan<byte> FirstBytes => firstByteStore.Slice(0, firstBytesRecorded); public FirstByteCollection(Span<byte> store) : this(store.Slice(0, 256), store.Slice(256, 256)) { } public FirstByteCollection(Span<byte> store, Span<byte> indicies) { firstByteStore = store; byteIndicies = indicies; firstBytesRecorded = 0; byteIndicies.Fill(byte.MaxValue); } public void Add(byte value) { ref byte reference = ref byteIndicies[value]; if (reference == byte.MaxValue) { reference = (byte)firstBytesRecorded; firstByteStore[reference] = value; firstBytesRecorded = Math.Min(firstBytesRecorded + 1, 256); } } } private readonly HomogenousPatternCollection[] patternCollections; private readonly BytePattern[]? emptyPatterns; private ReadOnlyMemory<byte>? lazyPossibleFirstBytes; public int MinLength { get; } public int MaxMinLength { get; } public int MaxAddressLength { get; } private ReadOnlyMemory<byte> PossibleFirstBytes { get { ReadOnlyMemory<byte> valueOrDefault = lazyPossibleFirstBytes.GetValueOrDefault(); if (!lazyPossibleFirstBytes.HasValue) { valueOrDefault = GetPossibleFirstBytes(); lazyPossibleFirstBytes = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } public BytePatternCollection(ReadOnlyMemory<BytePattern?> patterns) { int minLength; int maxMinLength; int maxAddrLength; (HomogenousPatternCollection[], BytePattern[]) tuple = ComputeLut(patterns, out minLength, out maxMinLength, out maxAddrLength); patternCollections = tuple.Item1; emptyPatterns = tuple.Item2; MinLength = minLength; MaxMinLength = maxMinLength; MaxAddressLength = maxAddrLength; Helpers.Assert(MinLength > 0, (string)null, "MinLength > 0"); } public BytePatternCollection(params BytePattern?[] patterns) : this(patterns.AsMemory()) { } public IEnumerator<BytePattern> GetEnumerator() { for (int i = 0; i < patternCollections.Length; i++) { BytePattern[]?[] coll = patternCollections[i].Lut; for (int j = 0; j < coll.Length; j++) { if (coll[j] != null) { BytePattern[] array = coll[j]; for (int k = 0; k < array.Length; k++) { yield return array[k]; } } } } if (emptyPatterns != null) { BytePattern[] array = emptyPatterns; for (int i = 0; i < array.Length; i++) { yield return array[i]; } } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private static (HomogenousPatternCollection[], BytePattern[]?) ComputeLut(ReadOnlyMemory<BytePattern?> patterns, out int minLength, out int maxMinLength, out int maxAddrLength) { if (patterns.Length == 0) { minLength = 0; maxMinLength = 0; maxAddrLength = 0; return (ArrayEx.Empty<HomogenousPatternCollection>(), null); } Span<int> span = stackalloc int[256]; minLength = int.MaxValue; maxMinLength = int.MinValue; maxAddrLength = 0; int[][] array = null; int num = 0; int num2 = 0; for (int i = 0; i < patterns.Length; i++) { BytePattern bytePattern = patterns.Span[i]; if (bytePattern == null) { continue; } if (bytePattern.MinLength < minLength) { minLength = bytePattern.MinLength; } if (bytePattern.MinLength > maxMinLength) { maxMinLength = bytePattern.MinLength; } if (bytePattern.AddressBytes > maxAddrLength) { maxAddrLength = bytePattern.AddressBytes; } var (readOnlyMemory, num3) = bytePattern.FirstLiteralSegment; if (readOnlyMemory.Length == 0) { num++; continue; } num2 = 1; if (num3 == 0) { span[readOnlyMemory.Span[0]]++; continue; } if (array == null || array.Length < num3) { Array.Resize(ref array, num3); } ref int[] reference = ref array[num3 - 1]; if (reference == null) { reference = new int[256]; } reference[readOnlyMemory.Span[0]]++; } if (array != null) { int[][] array2 = array; for (int j = 0; j < array2.Length; j++) { if (array2[j] != null) { num2++; } } } BytePattern[] array3 = ((num > 0) ? new BytePattern[num] : null); int num4 = 0; HomogenousPatternCollection[] array4 = new HomogenousPatternCollection[num2]; int num5 = 1; array4[0] = new HomogenousPatternCollection(0); for (int k = 0; k < patterns.Length; k++) { BytePattern bytePattern2 = patterns.Span[k]; if (bytePattern2 == null) { continue; } var (readOnlyMemory2, num6) = bytePattern2.FirstLiteralSegment; if (readOnlyMemory2.Length == 0) { array3[num4++] = bytePattern2; continue; } int num7 = -1; for (int l = 0; l < array4.Length; l++) { if (array4[l].Offset == num6) { num7 = l; break; } } if (num7 == -1) { num7 = num5++; array4[num7] = new HomogenousPatternCollection(num6); } ReadOnlySpan<int> arrayCounts = ((num6 == 0) ? span : array[num6 - 1].AsSpan()); AddToPatternCollection(ref array4[num7], arrayCounts, bytePattern2); if (num7 > 0 && array4[num7 - 1].Offset > array4[num7].Offset) { Helpers.Swap<HomogenousPatternCollection>(ref array4[num7 - 1], ref array4[num7]); } } return (array4, array3); static void AddToPatternCollection(ref HomogenousPatternCollection collection, ReadOnlySpan<int> readOnlySpan, BytePattern pattern) { ReadOnlyMemory<byte> item = pattern.FirstLiteralSegment.Bytes; if (collection.Lut == null) { BytePattern[][] array5 = new BytePattern[256][]; for (int m = 0; m < readOnlySpan.Length; m++) { if (readOnlySpan[m] > 0) { array5[m] = new BytePattern[readOnlySpan[m]]; } } collection.Lut = array5; } BytePattern[]? obj = collection.Lut[item.Span[0]]; int num8 = Array.IndexOf(obj, null); obj[num8] = pattern; if (pattern.MinLength < collection.MinLength) { collection.MinLength = pattern.MinLength; } } } public bool TryMatchAt(ReadOnlySpan<byte> data, out ulong address, [MaybeNullWhen(false)] out BytePattern matchingPattern, out int length) { if (data.Length < MinLength) { length = 0; address = 0uL; matchingPattern = null; return false; } Span<byte> addrBuf = stackalloc byte[8]; bool result = TryMatchAt(data, addrBuf, out matchingPattern, out length); address = Unsafe.ReadUnaligned<ulong>(in addrBuf[0]); return result; } public bool TryMatchAt(ReadOnlySpan<byte> data, Span<byte> addrBuf, [MaybeNullWhen(false)] out BytePattern matchingPattern, out int length) { if (data.Length < MinLength) { length = 0; matchingPattern = null; return false; } for (int i = 0; i < patternCollections.Length; i++) { ref HomogenousPatternCollection reference = ref patternCollections[i]; if (data.Length < reference.Offset + reference.MinLength) { continue; } byte b = data[reference.Offset]; BytePattern[] array = reference.Lut[b]; if (array == null) { continue; } BytePattern[] array2 = array; foreach (BytePattern bytePattern in array2) { if (bytePattern.TryMatchAt(data, addrBuf, out length)) { matchingPattern = bytePattern; return true; } } } if (emptyPatterns != null) { BytePattern[] array2 = emptyPatterns; foreach (BytePattern bytePattern2 in array2) { if (bytePattern2.TryMatchAt(data, addrBuf, out length)) { matchingPattern = bytePattern2; return true; } } } matchingPattern = null; length = 0; return false; } public bool TryFindMatch(ReadOnlySpan<byte> data, out ulong address, [MaybeNullWhen(false)] out BytePattern matchingPattern, out int offset, out int length) { if (data.Length < MinLength) { length = (offset = 0); address = 0uL; matchingPattern = null; return false; } Span<byte> addrBuf = stackalloc byte[8]; bool result = TryFindMatch(data, addrBuf, out matchingPattern, out offset, out length); address = Unsafe.ReadUnaligned<ulong>(in addrBuf[0]); return result; } public bool TryFindMatch(ReadOnlySpan<byte> data, Span<byte> addrBuf, [MaybeNullWhen(false)] out BytePattern matchingPattern, out int offset, out int length) { if (data.Length < MinLength) { length = (offset = 0); matchingPattern = null; return false; } ReadOnlySpan<byte> span = PossibleFirstBytes.Span; int num = 0; while (true) { int num2 = data.Slice(num).IndexOfAny(span); if (num2 < 0) { break; } offset = num + num2; byte b = data[offset]; for (int i = 0; i < patternCollections.Length; i++) { ref HomogenousPatternCollection reference = ref patternCollections[i]; if (offset < reference.Offset || data.Length < offset + reference.MinLength) { continue; } BytePattern[] array = reference.Lut[b]; if (array == null) { continue; } BytePattern[] array2 = array; foreach (BytePattern bytePattern in array2) { if ((offset == 0 || !bytePattern.MustMatchAtStart) && bytePattern.TryMatchAt(data.Slice(offset - reference.Offset), addrBuf, out length)) { offset -= reference.Offset; matchingPattern = bytePattern; return true; } } } num = offset + 1; } if (emptyPatterns != null) { BytePattern[] array2 = emptyPatterns; foreach (BytePattern bytePattern2 in array2) { if (bytePattern2.TryFindMatch(data, addrBuf, out offset, out length)) { matchingPattern = bytePattern2; return true; } } } matchingPattern = null; offset = 0; length = 0; return false; } private ReadOnlyMemory<byte> GetPossibleFirstBytes() { Memory<byte> memory = new byte[512].AsMemory(); FirstByteCollection bytes = new FirstByteCollection(memory.Span); for (int i = 0; i < patternCollections.Length; i++) { patternCollections[i].AddFirstBytes(ref bytes); } return memory.Slice(0, bytes.FirstBytes.Length); } } internal static class IcedExtensions { [Obsolete("This method is not supported.", true)] public static string FormatInsns(this IList<Instruction> insns) { throw new NotSupportedException(); } [Obsolete("This method is not supported.", true)] public static string FormatInsns(this InstructionList insns) { throw new NotSupportedException(); } } public interface IInitialize { void Initialize(); } public interface IInitialize<T> { void Initialize(T value); } internal struct StringParser { internal delegate T ParseRawFunc<T>(string buffer, ref int startIndex, ref int endIndex); private readonly string _buffer; private readonly char _separator; private readonly bool _skipEmpty; private int _startIndex; private int _endIndex; public StringParser(string buffer, char separator, bool skipEmpty = false) { _buffer = Helpers.ThrowIfNull<string>(buffer, "buffer"); _separator = separator; _skipEmpty = skipEmpty; _startIndex = -1; _endIndex = -1; } public bool MoveNext() { if (_buffer == null) { throw new InvalidOperationException(); } do { if (_endIndex >= _buffer.Length) { _startIndex = _endIndex; return false; } int num = _buffer.IndexOf(_separator, _endIndex + 1); _startIndex = _endIndex + 1; _endIndex = ((num >= 0) ? num : _buffer.Length); } while (_skipEmpty && _endIndex < _startIndex + 1); return true; } public void MoveNextOrFail() { if (!MoveNext()) { ThrowForInvalidData(); } } public string MoveAndExtractNext() { MoveNextOrFail(); return _buffer.Substring(_startIndex, _endIndex - _startIndex); } public string MoveAndExtractNextInOuterParens() { MoveNextOrFail(); if (_buffer[_startIndex] != '(') { ThrowForInvalidData(); } int num = _buffer.LastIndexOf(')'); if (num == -1 || num < _startIndex) { ThrowForInvalidData(); } string result = _buffer.Substring(_startIndex + 1, num - _startIndex - 1); _endIndex = num + 1; return result; } public string ExtractCurrent() { if (_buffer == null || _startIndex == -1) { throw new InvalidOperationException(); } return _buffer.Substring(_startIndex, _endIndex - _startIndex); } public unsafe int ParseNextInt32() { MoveNextOrFail(); bool flag = false; int num = 0; fixed (char* ptr = _buffer.AsSpan()) { char* ptr2 = ptr + _startIndex; char* ptr3 = ptr + _endIndex; if (ptr2 == ptr3) { ThrowForInvalidData(); } if (*ptr2 == '-') { flag = true; ptr2++; if (ptr2 == ptr3) { ThrowForInvalidData(); } } for (; ptr2 != ptr3; ptr2++) { int num2 = *ptr2 - 48; if (num2 < 0 || num2 > 9) { ThrowForInvalidData(); } num = checked(flag ? (num * 10 - num2) : (num * 10 + num2)); } } return num; } public unsafe long ParseNextInt64() { MoveNextOrFail(); bool flag = false; long num = 0L; fixed (char* ptr = _buffer.AsSpan()) { char* ptr2 = ptr + _startIndex; char* ptr3 = ptr + _endIndex; if (ptr2 == ptr3) { ThrowForInvalidData(); } if (*ptr2 == '-') { flag = true; ptr2++; if (ptr2 == ptr3) { ThrowForInvalidData(); } } for (; ptr2 != ptr3; ptr2++) { int num2 = *ptr2 - 48; if (num2 < 0 || num2 > 9) { ThrowForInvalidData(); } num = checked(flag ? (num * 10 - num2) : (num * 10 + num2)); } } return num; } public unsafe uint ParseNextUInt32() { MoveNextOrFail(); if (_startIndex == _endIndex) { ThrowForInvalidData(); } uint num = 0u; fixed (char* ptr = _buffer.AsSpan()) { char* ptr2 = ptr + _startIndex; for (char* ptr3 = ptr + _endIndex; ptr2 != ptr3; ptr2++) { int num2 = *ptr2 - 48; if (num2 < 0 || num2 > 9) { ThrowForInvalidData(); } num = (uint)checked(num * 10 + num2); } } return num; } public unsafe ulong ParseNextUInt64() { MoveNextOrFail(); ulong num = 0uL; fixed (char* ptr = _buffer.AsSpan()) { char* ptr2 = ptr + _startIndex; for (char* ptr3 = ptr + _endIndex; ptr2 != ptr3; ptr2++) { int num2 = *ptr2 - 48; if (num2 < 0 || num2 > 9) { ThrowForInvalidData(); } num = checked(num * 10 + (ulong)num2); } } return num; } public char ParseNextChar() { MoveNextOrFail(); if (_endIndex - _startIndex != 1) { ThrowForInvalidData(); } return _buffer[_startIndex]; } internal T ParseRaw<T>(ParseRawFunc<T> selector) { MoveNextOrFail(); return selector(_buffer, ref _startIndex, ref _endIndex); } public string ExtractCurrentToEnd() { if (_buffer == null || _startIndex == -1) { throw new InvalidOperationException(); } return _buffer.Substring(_startIndex); } private static void ThrowForInvalidData() { throw new FormatException(); } } } namespace MonoMod.Core.Platforms { public enum TypeClassification { InRegister, ByReference, OnStack } public delegate TypeClassification Classifier(Type type, bool isReturn); public enum SpecialArgumentKind { ThisPointer, ReturnBuffer, GenericContext, UserArguments } public readonly record struct Abi(ReadOnlyMemory<SpecialArgumentKind> ArgumentOrder, Classifier Classifier, bool ReturnsReturnBuffer) { public TypeClassification Classify(Type type, bool isReturn) { Helpers.ThrowIfArgumentNull<Type>(type, "type"); if (type == typeof(void)) { return TypeClassification.InRegister; } if (!type.IsValueType) { return TypeClassification.InRegister; } if (type.IsPointer) { return TypeClassification.InRegister; } if (type.IsByRef) { return TypeClassification.InRegister; } return Classifier(type, isReturn); } } [Flags] public enum ArchitectureFeature { None = 0, FixedInstructionSize = 1, Immediate64 = 2, CreateAltEntryPoint = 4 } public readonly struct FeatureFlags : IEquatable<FeatureFlags> { public ArchitectureFeature Architecture { get; } public SystemFeature System { get; } public RuntimeFeature Runtime { get; } public FeatureFlags(ArchitectureFeature archFlags, SystemFeature sysFlags, RuntimeFeature runtimeFlags) { Runtime = runtimeFlags; Architecture = archFlags; System = sysFlags; } public bool Has(RuntimeFeature feature) { return (Runtime & feature) == feature; } public bool Has(ArchitectureFeature feature) { return (Architecture & feature) == feature; } public bool Has(SystemFeature feature) { return (System & feature) == feature; } public override bool Equals(object? obj) { if (obj is FeatureFlags other) { return Equals(other); } return false; } public bool Equals(FeatureFlags other) { if (Runtime == other.Runtime && Architecture == other.Architecture) { return System == other.System; } return false; } public override int GetHashCode() { return HashCode.Combine(Runtime, Architecture, System); } public override string ToString() { return $"({Architecture})({System})({Runtime})"; } public static bool operator ==(FeatureFlags left, FeatureFlags right) { return left.Equals(right); } public static bool operator !=(FeatureFlags left, FeatureFlags right) { return !(left == right); } } public interface IAltEntryFactory { nint CreateAlternateEntrypoint(nint entrypoint, int minLength, out IDisposable? handle); } public interface IArchitecture { ArchitectureKind Target { get; } ArchitectureFeature Features { get; } BytePatternCollection KnownMethodThunks { get; } IAltEntryFactory AltEntryFactory { get; } NativeDetourInfo ComputeDetourInfo(nint from, nint target, int maxSizeHint = -1); int GetDetourBytes(NativeDetourInfo info, Span<byte> buffer, out IDisposable? allocationHandle); NativeDetourInfo ComputeRetargetInfo(NativeDetourInfo detour, nint target, int maxSizeHint = -1); int GetRetargetBytes(NativeDetourInfo original, NativeDetourInfo retarget, Span<byte> buffer, out IDisposable? allocationHandle, out bool needsRepatch, out bool disposeOldAlloc); ReadOnlyMemory<IAllocatedMemory> CreateNativeVtableProxyStubs(nint vtableBase, int vtableSize); IAllocatedMemory CreateSpecialEntryStub(nint target, nint argument); } public interface INativeDetourKind { int Size { get; } } public readonly record struct NativeDetourInfo(nint From, nint To, INativeDetourKind InternalKind, IDisposable? InternalData) { public int Size => InternalKind.Size; } public interface IControlFlowGuard { bool IsSupported { get; } int TargetAlignmentRequirement { get; } unsafe void RegisterValidIndirectCallTargets(void* memoryRegionStart, nint memoryRegionLength, ReadOnlySpan<nint> validTargetsInMemoryRegion); } public interface IMemoryAllocator { int MaxSize { get; } bool TryAllocate(AllocationRequest request, [MaybeNullWhen(false)] out IAllocatedMemory allocated); bool TryAllocateInRange(PositionedAllocationRequest request, [MaybeNullWhen(false)] out IAllocatedMemory allocated); } public readonly record struct AllocationRequest { public int Size { get; init; } public int Alignment { get; init; } public bool Executable { get; init; } public AllocationRequest(int Size) { Executable = false; this.Size = Size; Alignment = 8; } [CompilerGenerated] public void Deconstruct(out int Size) { Size = this.Size; } } public readonly record struct PositionedAllocationRequest(nint Target, nint LowBound, nint HighBound, AllocationRequest Base); public interface IAllocatedMemory : IDisposable { bool IsExecutable { get; } nint BaseAddress { get; } int Size { get; } Span<byte> Memory { get; } } public interface INativeExceptionHelper { GetExceptionSlot GetExceptionSlot { get; } nint CreateNativeToManagedHelper(nint target, out IDisposable? handle); nint CreateManagedToNativeHelper(nint target, out IDisposable? handle); } public unsafe delegate nint* GetExceptionSlot(); public interface IRuntime { RuntimeKind Target { get; } RuntimeFeature Features { get; } Abi Abi { get; } event OnMethodCompiledCallback? OnMethodCompiled; MethodBase GetIdentifiable(MethodBase method); RuntimeMethodHandle GetMethodHandle(MethodBase method); bool RequiresGenericContext(MethodBase method); void DisableInlining(MethodBase method); IDisposable? PinMethodIfNeeded(MethodBase method); nint GetMethodEntryPoint(MethodBase method); void Compile(MethodBase method); } public delegate void OnMethodCompiledCallback(RuntimeMethodHandle methodHandle, MethodBase? method, nint codeStart, nint codeRw, ulong codeSize); public interface ISystem { OSKind Target { get; } SystemFeature Features { get; } Abi? DefaultAbi { get; } IMemoryAllocator MemoryAllocator { get; } INativeExceptionHelper? NativeExceptionHelper { get; } IEnumerable<LoadedModule> EnumerateLoadedModules(); IEnumerable<string?> EnumerateLoadedModuleFiles(); nint GetSizeOfReadableMemory(nint start, nint guess); void PatchData(PatchTargetKind targetKind, nint patchTarget, ReadOnlySpan<byte> data, Span<byte> backup); nint GetNativeJitHookConfig(int runtimeMajMin); } public enum PatchTargetKind { Executable, ReadOnly } public readonly record struct LoadedModule(ulong? BaseAddress, string? FileName, ulong? Size); public sealed class PlatformTriple { public record struct NativeDetour(SimpleNativeDetour Simple, nint AltEntry, IDisposable? AltHandle) { public bool HasAltEntry => AltEntry != IntPtr.Zero; } private static object lazyCurrentLock = new object(); private static PlatformTriple? lazyCurrent; private static readonly Func<PlatformTriple> createCurrentFunc = CreateCurrent; private nint ThePreStub = IntPtr.Zero; public IArchitecture Architecture { get; } public ISystem System { get; } public IRuntime Runtime { get; } public static PlatformTriple Current => Helpers.GetOrInitWithLock<PlatformTriple>(ref lazyCurrent, lazyCurrentLock, createCurrentFunc); public (ArchitectureKind Arch, OSKind OS, RuntimeKind Runtime) HostTriple => (Arch: Architecture.Target, OS: System.Target, Runtime: Runtime.Target); public FeatureFlags SupportedFeatures { get; } public Abi Abi { get; } [EditorBrowsable(EditorBrowsableState.Advanced)] public static IRuntime CreateCurrentRuntime(ISystem system, IArchitecture arch) { //IL_0016: 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_001c: 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_0030: Expected I4, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) Helpers.ThrowIfArgumentNull<ISystem>(system, "system"); Helpers.ThrowIfArgumentNull<IArchitecture>(arch, "arch"); RuntimeKind runtime = PlatformDetection.Runtime; return (runtime - 1) switch { 0 => FxBaseRuntime.CreateForVersion(PlatformDetection.RuntimeVersion, system), 1 => CoreBaseRuntime.CreateForVersion(PlatformDetection.RuntimeVersion, system, arch), 2 => new MonoRuntime(system), _ => throw new PlatformNotSupportedException($"Runtime kind {runtime} not supported"), }; } [EditorBrowsable(EditorBrowsableState.Advanced)] public static IArchitecture CreateCurrentArchitecture(ISystem system) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected I4, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) Helpers.ThrowIfArgumentNull<ISystem>(system, "system"); ArchitectureKind architecture = PlatformDetection.Architecture; return (architecture - 2) switch { 0 => new x86Arch(system), 1 => new x86_64Arch(system), 2 => throw new NotImplementedException(), 3 => new Arm64Arch(system), _ => throw new PlatformNotSupportedException($"Architecture kind {architecture} not supported"), }; } [EditorBrowsable(EditorBrowsableState.Advanced)] public static ISystem CreateCurrentSystem() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected I4, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 OSKind oS = PlatformDetection.OS; if ((int)oS <= 17) { switch (oS - 1) { case 0: throw new NotImplementedException(); case 4: return new MacOSSystem(); case 1: goto IL_006c; case 2: case 3: goto IL_0074; } if ((int)oS == 9) { return new LinuxSystem(); } if ((int)oS == 17) { throw new NotImplementedException(); } } else { if ((int)oS == 34) { goto IL_006c; } if ((int)oS == 37) { throw new NotImplementedException(); } if ((int)oS == 41) { throw new NotImplementedException(); } } goto IL_0074; IL_006c: return new WindowsSystem(); IL_0074: throw new PlatformNotSupportedException($"OS kind {oS} not supported"); } private static PlatformTriple CreateCurrent() { ISystem system = CreateCurrentSystem(); IArchitecture architecture = CreateCurrentArchitecture(system); IRuntime runtime = CreateCurrentRuntime(system, architecture); return new PlatformTriple(architecture, system, runtime); } [EditorBrowsable(EditorBrowsableState.Advanced)] public static void SetPlatformTriple(PlatformTriple triple) { Helpers.ThrowIfArgumentNull<PlatformTriple>(triple, "triple"); if (lazyCurrent != null) { ThrowTripleAlreadyExists(); } lock (lazyCurrentLock) { if (lazyCurrent != null) { ThrowTripleAlreadyExists(); } lazyCurrent = triple; } } [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowTripleAlreadyExists() { throw new InvalidOperationException("The platform triple has already been initialized; cannot set a new one"); } [EditorBrowsable(EditorBrowsableState.Advanced)] public PlatformTriple(IArchitecture architecture, ISystem system, IRuntime runtime) { Helpers.ThrowIfArgumentNull<IArchitecture>(architecture, "architecture"); Helpers.ThrowIfArgumentNull<ISystem>(system, "system"); Helpers.ThrowIfArgumentNull<IRuntime>(runtime, "runtime"); Architecture = architecture; System = system; Runtime = runtime; SupportedFeatures = new FeatureFlags(Architecture.Features, System.Features, Runtime.Features); InitIfNeeded(Architecture); InitIfNeeded(System); InitIfNeeded(Runtime); Abi = Runtime.Abi; } private void InitIfNeeded(object obj) { (obj as IInitialize<ISystem>)?.Initialize(System); (obj as IInitialize<IArchitecture>)?.Initialize(Architecture); (obj as IInitialize<IRuntime>)?.Initialize(Runtime); (obj as IInitialize<PlatformTriple>)?.Initialize(this); (obj as IInitialize)?.Initialize(); } public void Compile(MethodBase method) { Helpers.ThrowIfArgumentNull<MethodBase>(method, "method"); if (method.IsGenericMethodDefinition) { throw new ArgumentException("Cannot prepare generic method definition", "method"); } method = GetIdentifiable(method); if (SupportedFeatures.Has(RuntimeFeature.RequiresCustomMethodCompile)) { Runtime.Compile(method); return; } RuntimeMethodHandle methodHandle = Runtime.GetMethodHandle(method); if (method.IsGenericMethod) { Type[] genericArguments = method.GetGenericArguments(); RuntimeTypeHandle[] array = new RuntimeTypeHandle[genericArguments.Length]; for (int i = 0; i < genericArguments.Length; i++) { array[i] = genericArguments[i].TypeHandle; } RuntimeHelpers.PrepareMethod(methodHandle, array); } else { RuntimeHelpers.PrepareMethod(methodHandle); } } public MethodBase GetIdentifiable(MethodBase method) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) Helpers.ThrowIfArgumentNull<MethodBase>(method, "method"); if (SupportedFeatures.Has(RuntimeFeature.RequiresMethodIdentification)) { method = Runtime.GetIdentifiable(method); } if (method.ReflectedType != method.DeclaringType) { ParameterInfo[] parameters = method.GetParameters(); Type[] array = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = parameters[i].ParameterType; } bool flag2 = default(bool); if ((object)method.DeclaringType == null) { MethodInfo? method2 = method.Module.GetMethod(method.Name, (BindingFlags)(-1), null, method.CallingConvention, array, null); bool flag = (object)method2 != null; bool num = flag; AssertionInterpolatedStringHandler val = new AssertionInterpolatedStringHandler(16, 2, flag, ref flag2); if (flag2) { ((AssertionInterpolatedStringHandler)(ref val)).AppendLiteral("orig: "); ((AssertionInterpolatedStringHandler)(ref val)).AppendFormatted<MethodBase>(method); ((AssertionInterpolatedStringHandler)(ref val)).AppendLiteral(", module: "); ((AssertionInterpolatedStringHandler)(ref val)).AppendFormatted<Module>(method.Module); } Helpers.Assert(num, ref val, "got is not null"); method = method2; } else if (method.IsConstructor) { ConstructorInfo? constructor = method.DeclaringType.GetConstructor((BindingFlags)(-1), null, method.CallingConvention, array, null); flag2 = (object)constructor != null; bool num2 = flag2; bool flag = default(bool); AssertionInterpolatedStringHandler val2 = new AssertionInterpolatedStringHandler(6, 1, flag2, ref flag); if (flag) { ((AssertionInterpolatedStringHandler)(ref val2)).AppendLiteral("orig: "); ((AssertionInterpolatedStringHandler)(ref val2)).AppendFormatted<MethodBase>(method); } Helpers.Assert(num2, ref val2, "got is not null"); method = constructor; } else { MethodInfo? method3 = method.DeclaringType.GetMethod(method.Name, (BindingFlags)(-1), null, method.CallingConvention, array, null); bool flag = (object)method3 != null; bool num3 = flag; AssertionInterpolatedStringHandler val3 = new AssertionInterpolatedStringHandler(6, 1, flag, ref flag2); if (flag2) { ((AssertionInterpolatedStringHandler)(ref val3)).AppendLiteral("orig: "); ((AssertionInterpolatedStringHandler)(ref val3)).AppendFormatted<MethodBase>(method); } Helpers.Assert(num3, ref val3, "got is not null"); method = method3; } } return method; } public IDisposable? PinMethodIfNeeded(MethodBase method) { if (SupportedFeatures.Has(RuntimeFeature.RequiresMethodPinning)) { return Runtime.PinMethodIfNeeded(method); } return null; } public bool TryDisableInlining(MethodBase method) { if (SupportedFeatures.Has(RuntimeFeature.DisableInlining)) { Runtime.DisableInlining(method); return true; } return false; } public SimpleNativeDetour CreateSimpleDetour(nint from, nint to, int detourMaxSize = -1, nint fromRw = 0) { //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) if (fromRw == 0) { fromRw = from; } bool flag = from != to; bool isEnabled = default(bool); AssertionInterpolatedStringHandler val = new AssertionInterpolatedStringHandler(48, 2, flag, ref isEnabled); if (isEnabled) { ((AssertionInterpolatedStringHandler)(ref val)).AppendLiteral("Cannot detour a method to itself! (from: "); ((AssertionInterpolatedStringHandler)(ref val)).AppendFormatted<nint>(from); ((AssertionInterpolatedStringHandler)(ref val)).AppendLiteral(", to: "); ((AssertionInterpolatedStringHandler)(ref val)).AppendFormatted<nint>(to); ((AssertionInterpolatedStringHandler)(ref val)).AppendLiteral(")"); } Helpers.Assert(flag, ref val, "from != to"); MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(31, 2, out isEnabled); if (isEnabled) { message.AppendLiteral("Creating simple detour 0x"); message.AppendFormatted(from, "x16"); message.AppendLiteral(" => 0x"); message.AppendFormatted(to, "x16"); } MMDbgLog.Trace(ref message); NativeDetourInfo nativeDetourInfo = Architecture.ComputeDetourInfo(from, to, detourMaxSize); Span<byte> span = stackalloc byte[nativeDetourInfo.Size]; Architecture.GetDetourBytes(nativeDetourInfo, span, out IDisposable allocationHandle); byte[] array = new byte[nativeDetourInfo.Size]; System.PatchData(PatchTargetKind.Executable, fromRw, span, array); return new SimpleNativeDetour(this, nativeDetourInfo, array, allocationHandle); } public NativeDetour CreateNativeDetour(nint from, nint to, int detourMaxSize = -1, nint fromRw = 0) { //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) if (fromRw == 0) { fromRw = from; } bool flag = from != to; bool isEnabled = default(bool); AssertionInterpolatedStringHandler val = new AssertionInterpolatedStringHandler(48, 2, flag, ref isEnabled); if (isEnabled) { ((AssertionInterpolatedStringHandler)(ref val)).AppendLiteral("Cannot detour a method to itself! (from: "); ((AssertionInterpolatedStringHandler)(ref val)).AppendFormatted<nint>(from); ((AssertionInterpolatedStringHandler)(ref val)).AppendLiteral(", to: "); ((AssertionInterpolatedStringHandler)(ref val)).AppendFormatted<nint>(to); ((AssertionInterpolatedStringHandler)(ref val)).AppendLiteral(")"); } Helpers.Assert(flag, ref val, "from != to"); MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(31, 2, out isEnabled); if (isEnabled) { message.AppendLiteral("Creating simple detour 0x"); message.AppendFormatted(from, "x16"); message.AppendLiteral(" => 0x"); message.AppendFormatted(to, "x16"); } MMDbgLog.Trace(ref message); NativeDetourInfo nativeDetourInfo = Architecture.ComputeDetourInfo(from, to, detourMaxSize); Span<byte> span = stackalloc byte[nativeDetourInfo.Size]; IDisposable allocationHandle; int detourBytes = Architecture.GetDetourBytes(nativeDetourInfo, span, out allocationHandle); nint altEntry = IntPtr.Zero; IDisposable handle = null; if (SupportedFeatures.Has(ArchitectureFeature.CreateAltEntryPoint)) { altEntry = Architecture.AltEntryFactory.CreateAlternateEntrypoint(from, detourBytes, out handle); } else { MMDbgLog.DebugLogWarningStringHandler message2 = new MMDbgLog.DebugLogWarningStringHandler(67, 2, out isEnabled); if (isEnabled) { message2.AppendLiteral("Cannot create alternate entry point for native detour (from: "); message2.AppendFormatted(from, "x16"); message2.AppendLiteral(", to: "); message2.AppendFormatted(to, "x16"); } MMDbgLog.Warning(ref message2); } byte[] array = new byte[nativeDetourInfo.Size]; System.PatchData(PatchTargetKind.Executable, fromRw, span, array); return new NativeDetour(new SimpleNativeDetour(this, nativeDetourInfo, array, allocationHandle), altEntry, handle); } public nint GetNativeMethodBody(MethodBase method) { if (SupportedFeatures.Has(RuntimeFeature.RequiresBodyThunkWalking)) { return GetNativeMethodBodyWalk(method, reloadPtr: true); } return GetNativeMethodBodyDirect(method); } private unsafe nint GetNativeMethodBodyWalk(MethodBase method, bool reloadPtr) { bool flag = false; bool flag2 = false; int value = 0; BytePatternCollection knownMethodThunks = Architecture.KnownMethodThunks; bool isEnabled; MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(32, 1, out isEnabled); if (isEnabled) { message.AppendLiteral("Performing method body walk for "); message.AppendFormatted(method); } MMDbgLog.Trace(ref message); nint num = -1; FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); while (true) { nint num2 = Runtime.GetMethodEntryPoint(method); MMDbgLog.DebugLogTraceStringHandler message2 = new MMDbgLog.DebugLogTraceStringHandler(25, 1, out isEnabled); if (isEnabled) { message2.AppendLiteral("Starting entry point = 0x"); message2.AppendFormatted(num2, "x16"); } MMDbgLog.Trace(ref message2); while (true) { if (value++ > 20) { MMDbgLog.DebugLogErrorStringHandler message3 = new MMDbgLog.DebugLogErrorStringHandler(70, 4, out isEnabled); if (isEnabled) { message3.AppendLiteral("Could not get entry point for "); message3.AppendFormatted(method); message3.AppendLiteral("! (tried "); message3.AppendFormatted(value); message3.AppendLiteral(" times) entry: 0x"); message3.AppendFormatted(num2, "x16"); message3.AppendLiteral(" prevEntry: 0x"); message3.AppendFormatted(num, "x16"); } MMDbgLog.Error(ref message3); ((FormatInterpolatedStringHandler)(ref val))..ctor(47, 1); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral("Could not get entrypoint for "); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<MethodBase>(method); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(" (stuck in a loop)"); throw new NotSupportedException(DebugFormatter.Format(ref val)); } if (flag2 || num != num2) { num = num2; nint sizeOfReadableMemory = System.GetSizeOfReadableMemory(num2, knownMethodThunks.MaxMinLength); if (sizeOfReadableMemory <= 0) { MMDbgLog.DebugLogWarningStringHandler message4 = new MMDbgLog.DebugLogWarningStringHandler(43, 2, out isEnabled); if (isEnabled) { message4.AppendLiteral("Got zero or negative readable length "); message4.AppendFormatted(sizeOfReadableMemory); message4.AppendLiteral(" at 0x"); message4.AppendFormatted(num2, "x16"); } MMDbgLog.Warning(ref message4); } ReadOnlySpan<byte> data = new ReadOnlySpan<byte>((void*)num2, Math.Min((int)sizeOfReadableMemory, knownMethodThunks.MaxMinLength)); if (knownMethodThunks.TryFindMatch(data, out ulong address, out BytePattern matchingPattern, out int offset, out int _)) { nint ptrGot = num2; flag2 = false; AddressMeaning addressMeaning = matchingPattern.AddressMeaning; MMDbgLog.DebugLogTraceStringHandler message5 = new MMDbgLog.DebugLogTraceStringHandler(46, 4, out isEnabled); if (isEnabled) { message5.AppendLiteral("Matched thunk with "); message5.AppendFormatted(addressMeaning); message5.AppendLiteral(" at 0x"); message5.AppendFormatted(num2, "x16"); message5.AppendLiteral(" (addr: 0x"); message5.AppendFormatted(address, "x8"); message5.AppendLiteral(", offset: "); message5.AppendFormatted(offset); message5.AppendLiteral(")"); } MMDbgLog.Trace(ref message5); if (addressMeaning.Kind.IsPrecodeFixup() && !flag) { nint num3 = addressMeaning.ProcessAddress(num2, offset, address); if (reloadPtr) { MMDbgLog.DebugLogTraceStringHandler message6 = new MMDbgLog.DebugLogTraceStringHandler(56, 1, out isEnabled); if (isEnabled) { message6.AppendLiteral("Method thunk reset; regenerating (PrecodeFixupThunk: 0x"); message6.AppendFormatted(num3, "X16"); message6.AppendLiteral(")"); } MMDbgLog.Trace(ref message6); Compile(method); flag2 = true; break; } num2 = num3; } else { num2 = addressMeaning.ProcessAddress(num2, offset, address); } MMDbgLog.DebugLogTraceStringHandler message7 = new MMDbgLog.DebugLogTraceStringHandler(23, 1, out isEnabled); if (isEnabled) { message7.AppendLiteral("Got next entry point 0x"); message7.AppendFormatted(num2, "x16"); } MMDbgLog.Trace(ref message7); num2 = NotThePreStub(ptrGot, num2, out var wasPreStub); if (wasPreStub && reloadPtr) { MMDbgLog.Trace("Matched ThePreStub"); Compile(method); break; } continue; } } return num2; } } } private nint GetNativeMethodBodyDirect(MethodBase method) { return Runtime.GetMethodEntryPoint(method); } private nint NotThePreStub(nint ptrGot, nint ptrParsed, out bool wasPreStub) { if (ThePreStub == IntPtr.Zero) { ThePreStub = -2; nint thePreStub = (from m in typeof(HttpWebRequest).Assembly.GetType("System.Net.Connection")?.GetMethods() group m by GetNativeMethodBodyWalk(m, reloadPtr: false)).First((IGrouping<nint, MethodInfo> g) => g.Count() > 1).Key ?? (-1); ThePreStub = thePreStub; bool isEnabled; MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(14, 1, out isEnabled); if (isEnabled) { message.AppendLiteral("ThePreStub: 0x"); message.AppendFormatted(ThePreStub, "X16"); } MMDbgLog.Trace(ref message); } wasPreStub = ptrParsed == ThePreStub; if (!wasPreStub) { return ptrParsed; } return ptrGot; } public MethodBase GetRealDetourTarget(MethodBase from, MethodBase to) { //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Expected O, but got Unknown //IL_0266: 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_029c: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) Helpers.ThrowIfArgumentNull<MethodBase>(from, "from"); Helpers.ThrowIfArgumentNull<MethodBase>(to, "to"); to = GetIdentifiable(to); if (!(from is MethodInfo methodInfo) || !(to is MethodInfo methodInfo2)) { return to; } bool flag = false; ReadOnlyMemory<SpecialArgumentKind> argumentOrder = Abi.ArgumentOrder; ReadOnlySpan<SpecialArgumentKind> span = argumentOrder.Span; for (int i = 0; i < span.Length; i++) { if (span[i] == SpecialArgumentKind.ReturnBuffer) { flag = true; break; } } Type returnType = methodInfo.ReturnType; bool flag2 = Abi.Classify(returnType, isReturn: true) == TypeClassification.ByReference; bool flag3 = !methodInfo.IsStatic; bool num = flag3 && methodInfo2.IsStatic && flag2 && flag; bool flag4 = HasGenericContext(Abi) && Runtime.RequiresGenericContext(methodInfo); if (!num && !flag4) { return to; } Type type = (flag2 ? returnType.MakeByRefType() : returnType); Type type2 = ((flag2 && !Abi.ReturnsReturnBuffer) ? typeof(void) : type); int num2 = -1; int num3 = -1; int num4 = -1; ParameterInfo[] parameters = from.GetParameters(); List<Type> list = new List<Type>(parameters.Length + 3); argumentOrder = Abi.ArgumentOrder; ReadOnlySpan<SpecialArgumentKind> span2 = argumentOrder.Span; for (int j = 0; j < span2.Length; j++) { switch (span2[j]) { case SpecialArgumentKind.ThisPointer: if (flag3) { num2 = list.Count; list.Add(Extensions.GetThisParamType(from)); } break; case SpecialArgumentKind.ReturnBuffer: if (flag2) { num3 = list.Count; list.Add(type); } break; case SpecialArgumentKind.GenericContext: if (flag4) { list.Add(typeof(nint)); } break; case SpecialArgumentKind.UserArguments: num4 = list.Count; list.AddRange(parameters.Select((ParameterInfo p) => p.ParameterType)); break; } } FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val))..ctor(16, 2); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral("Glue:AbiFixup<"); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<MethodBase>(from); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(","); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<MethodBase>(to); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(">"); DynamicMethodDefinition val2 = new DynamicMethodDefinition(DebugFormatter.Format(ref val), type2, list.ToArray()); try { MethodDefinition definition = val2.Definition; definition.ImplAttributes = (MethodImplAttributes)(definition.ImplAttributes | 0x208); ILProcessor iLProcessor = val2.GetILProcessor(); if (flag2 && num3 >= 0) { iLProcessor.Emit(OpCodes.Ldarg, num3); } if (flag3) { iLProcessor.Emit(OpCodes.Ldarg, num2); } for (int num5 = 0; num5 < parameters.Length; num5++) { iLProcessor.Emit(OpCodes.Ldarg, num5 + num4); } iLProcessor.Emit(OpCodes.Call, ((MemberReference)iLProcessor.Body.Method).Module.ImportReference(to)); if (flag2 && num3 >= 0) { iLProcessor.Emit(OpCodes.Stobj, ((MemberReference)iLProcessor.Body.Method).Module.ImportReference(returnType)); } if (flag2 && Abi.ReturnsReturnBuffer) { iLProcessor.Emit(OpCodes.Ldarg, num3); } iLProcessor.Emit(OpCodes.Ret); return val2.Generate(); } finally { ((IDisposable)val2)?.Dispose(); } } private static bool HasGenericContext(Abi abi) { ReadOnlySpan<SpecialArgumentKind> span = abi.ArgumentOrder.Span; for (int i = 0; i < span.Length; i++) { if (span[i] == SpecialArgumentKind.GenericContext) { return true; } } return false; } } internal sealed class PlatformTripleDetourFactory : IDetourFactory { private abstract class DetourBase : ICoreDetourBase, IDisposable { protected abstract class DetourBoxBase { public SimpleNativeDetour? Detour; public readonly List<SimpleNativeDetour> OldDetours = new List<SimpleNativeDetour>(); protected readonly PlatformTriple Triple; protected readonly object Sync = new object(); private bool applyDetours; private bool isApplying; public bool IsApplied { get { return Volatile.Read(in applyDetours); } set { Volatile.Write(ref applyDetours, value); Thread.MemoryBarrier(); } } public bool IsApplying { get { return Volatile.Read(in isApplying); } set { Volatile.Write(ref isApplying, value); Thread.MemoryBarrier(); } } protected DetourBoxBase(PlatformTriple triple) { Triple = triple; applyDetours = false; isApplying = false; } public void ClearOldDetours() { foreach (SimpleNativeDetour oldDetour in OldDetours) { oldDetour.Dispose(); } OldDetours.Clear(); } } protected readonly PlatformTriple Triple; protected DetourBoxBase DetourBox; private bool disposedValue; public bool IsApplied => DetourBox.IsApplied; protected DetourBase(PlatformTriple triple) { Triple = triple; DetourBox = null; } protected TBox GetDetourBox<TBox>() where TBox : DetourBoxBase { return Unsafe.As<TBox>(DetourBox); } protected static void ReplaceDetourInLock(DetourBoxBase nativeDetour, SimpleNativeDetour? newDetour, out SimpleNativeDetour? oldDetour) { Thread.MemoryBarrier(); oldDetour = Interlocked.Exchange(ref nativeDetour.Detour, newDetour); if (oldDetour != null) { nativeDetour.OldDetours.Add(oldDetour); } } protected abstract SimpleNativeDetour CreateDetour(); public void Apply() { lock (DetourBox) { if (IsApplied) { throw new InvalidOperationException("Cannot apply a detour which is already applied"); } try { DetourBox.IsApplying = true; DetourBox.IsApplied = true; ReplaceDetourInLock(DetourBox, CreateDetour(), out SimpleNativeDetour _); } catch { DetourBox.IsApplied = false; throw; } finally { DetourBox.IsApplying = false; } } } protected abstract void BeforeUndo(); protected abstract void AfterUndo(); public void Undo() { lock (DetourBox) { if (!IsApplied) { throw new InvalidOperationException("Cannot undo a detour which is not applied"); } try { DetourBox.IsApplying = true; UndoCore(out SimpleNativeDetour _); DetourBox.ClearOldDetours(); } finally { DetourBox.IsApplying = false; } } } private void UndoCore(out SimpleNativeDetour? oldDetour) { BeforeUndo(); DetourBox.IsApplied = false; ReplaceDetourInLock(DetourBox, null, out oldDetour); AfterUndo(); } protected abstract void BeforeDispose(); private void Dispose(bool disposing) { if (!disposedValue) { BeforeDispose(); lock (DetourBox) { UndoCore(out SimpleNativeDetour _); DetourBox.ClearOldDetours(); } disposedValue = true; } } ~DetourBase() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } } private sealed class Detour : DetourBase, ICoreDetour, ICoreDetourBase, IDisposable { private sealed class ManagedDetourBox : DetourBoxBase { private readonly MethodBase src; private readonly MethodBase target; public ManagedDetourBox(PlatformTriple triple, MethodBase src, MethodBase target) : base(triple) { this.src = src; this.target = target; Detour = null; } public void SubscribeCompileMethod() { AddRelatedDetour(src, this); } public void UnsubscribeCompileMethod() { RemoveRelatedDetour(src, this); } public void OnMethodCompiled(MethodBase method, nint codeStart, nint codeStartRw, ulong codeSize) { if (!base.IsApplied) { return; } method = Triple.GetIdentifiable(method); lock (Sync) { if (!base.IsApplied || base.IsApplying) { return; } bool isEnabled; MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(43, 4, out isEnabled); if (isEnabled) { message.AppendLiteral("Updating detour from "); message.AppendFormatted(src); message.AppendLiteral(" to "); message.AppendFormatted(target); message.AppendLiteral(" (recompiled "); message.AppendFormatted(method); message.AppendLiteral(" to "); message.AppendFormatted(codeStart, "x16"); message.AppendLiteral(")"); } MMDbgLog.Trace(ref message); try { base.IsApplying = true; SimpleNativeDetour detour = Detour; nint to; nint num; nint fromRw; if (detour != null) { _ = detour.Source; to = detour.Destination; num = codeStart; fromRw = codeStartRw; } else { num = codeStart; fromRw = codeStartRw; to = Triple.Runtime.GetMethodHandle(target).GetFunctionPointer(); } SimpleNativeDetour newDetour = Triple.CreateSimpleDetour(num, to, (int)codeSize, fromRw); DetourBase.ReplaceDetourInLock(this, newDetour, out SimpleNativeDetour _); } finally { base.IsApplying = false; } } } } private sealed class RelatedDetourBag { public readonly MethodBase Method; public readonly List<ManagedDetourBox> RelatedDetours = new List<ManagedDetourBox>(); public bool IsValid = true; public RelatedDetourBag(MethodBase method) { Method = method; } } private readonly MethodBase realTarget; private static readonly object subLock = new object(); private static bool hasSubscribed; private static readonly ConcurrentDictionary<MethodBase, RelatedDetourBag> relatedDetours = new ConcurrentDictionary<MethodBase, RelatedDetourBag>(); private IDisposable? srcPin; private IDisposable? dstPin; private new ManagedDetourBox DetourBox => GetDetourBox<ManagedDetourBox>(); public MethodBase Source { get; } public MethodBase Target { get; } public Detour(PlatformTriple triple, MethodBase src, MethodBase dst) : base(triple) { Source = triple.GetIdentifiable(src); Target = dst; realTarget = triple.GetRealDetourTarget(src, dst); base.DetourBox = new ManagedDetourBox(triple, Source, realTarget); if (triple.SupportedFeatures.Has(RuntimeFeature.CompileMethodHook)) { EnsureSubscribed(triple); DetourBox.SubscribeCompileMethod(); } } private static void EnsureSubscribed(PlatformTriple triple) { if (Volatile.Read(in hasSubscribed)) { return; } lock (subLock) { if (!Volatile.Read(in hasSubscribed)) { Volatile.Write(ref hasSubscribed, value: true); triple.Runtime.OnMethodCompiled += OnMethodCompiled; } } } private static void AddRelatedDetour(MethodBase m, ManagedDetourBox cmh) { while (true) { RelatedDetourBag orAdd = relatedDetours.GetOrAdd(m, (MethodBase method) => new RelatedDetourBag(method)); lock (orAdd) { if (!orAdd.IsValid) { continue; } orAdd.RelatedDetours.Add(cmh); if (orAdd.RelatedDetours.Count > 1) { bool isEnabled; MMDbgLog.DebugLogWarningStringHandler message = new MMDbgLog.DebugLogWarningStringHandler(115, 1, out isEnabled); if (isEnabled) { message.AppendLiteral("Multiple related detours for method "); message.AppendFormatted(m); message.AppendLiteral("! This means that the method has been detoured twice. Detour cleanup will fail."); } MMDbgLog.Warning(ref message); } break; } } } private static void RemoveRelatedDetour(MethodBase m, ManagedDetourBox cmh) { if (relatedDetours.TryGetValue(m, out RelatedDetourBag value)) { lock (value) { value.RelatedDetours.Remove(cmh); if (value.RelatedDetours.Count == 0) { value.IsValid = false; Helpers.Assert(relatedDetours.TryRemove(value.Method, out RelatedDetourBag _), (string)null, "relatedDetours.TryRemove(related.Method, out _)"); } return; } } bool isEnabled; MMDbgLog.DebugLogWarningStringHandler message = new MMDbgLog.DebugLogWarningStringHandler(79, 1, out isEnabled); if (isEnabled) { message.AppendLiteral("Attempted to remove a related detour from method "); message.AppendFormatted(m); message.AppendLiteral(" which has no RelatedDetourBag"); } MMDbgLog.Warning(ref message); } private static void OnMethodCompiled(RuntimeMethodHandle methodHandle, MethodBase? method, nint codeStart, nint codeStartRw, ulong codeSize) { if ((object)method == null) { return; } method = PlatformTriple.Current.GetIdentifiable(method); if (!relatedDetours.TryGetValue(method, out RelatedDetourBag value)) { return; } lock (value) { foreach (ManagedDetourBox relatedDetour in value.RelatedDetours) { relatedDetour.OnMethodCompiled(method, codeStart, codeStartRw, codeSize); } } } protected override SimpleNativeDetour CreateDetour() { bool isEnabled; MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(33, 2, out isEnabled); if (isEnabled) { message.AppendLiteral("Applying managed detour from "); message.AppendFormatted(Source); message.AppendLiteral(" to "); message.AppendFormatted(realTarget); } MMDbgLog.Trace(ref message); srcPin = Triple.PinMethodIfNeeded(Source); dstPin = Triple.PinMethodIfNeeded(realTarget); Triple.Compile(Source); nint nativeMethodBody = Triple.GetNativeMethodBody(Source); Triple.Compile(realTarget); nint functionPointer = Triple.Runtime.GetMethodHandle(realTarget).GetFunctionPointer(); return Triple.CreateSimpleDetour(nativeMethodBody, functionPointer); } protected override void BeforeUndo() { bool isEnabled; MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringH
BepInExPack/BepInEx/core/MonoMod.Iced.dll
Decompiled a day 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.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Iced.Intel.BlockEncoderInternal; using Iced.Intel.DecoderInternal; using Iced.Intel.EncoderInternal; using Iced.Intel.Internal; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("Iced.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d94ac07d6edc1ac1f306b60544bb88927664f05037602c5e994ea52ca5b0aadc4a242d90522f46730c11af657acc3ff5aadfe19a3030e7dbd67b481635eecd7d738950a7de6a78c92715b797dde11e87d967109da659672957fabe3524cd5f90557cd8ab4927333a0dbd32e7e7246ee18a43327806c6721283fc619acca3f2cb")] [assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] [assembly: AssemblyCompany("iced project and contributors <https://github.com/icedland>")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (C) 2018-present iced project and contributors")] [assembly: AssemblyDescription("x86/x64 disassembler, assembler, instruction decoder")] [assembly: AssemblyFileVersion("1.21.0.0")] [assembly: AssemblyInformationalVersion("1.21.0+69fdc9deb")] [assembly: AssemblyProduct("Iced")] [assembly: AssemblyTitle("MonoMod.Iced")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoMod/MonoMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.21.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NullablePublicOnly(true)] namespace MonoMod.SourceGen.Attributes { [AttributeUsage(AttributeTargets.Class)] internal sealed class EmitILOverloadsAttribute : Attribute { public EmitILOverloadsAttribute(string filename, string kind) { } } internal static class ILOverloadKind { public const string Cursor = "ILCursor"; public const string Matcher = "ILMatcher"; } } namespace iced { internal static class AssemblyInfo { public const string AssemblyName = "MonoMod.Iced"; public const string AssemblyVersion = "1.21.0"; } } namespace Iced.Intel { public enum RelocKind { Offset64 } public readonly struct RelocInfo { public readonly ulong Address; public readonly RelocKind Kind; public RelocInfo(RelocKind kind, ulong address) { Kind = kind; Address = address; } } public readonly struct InstructionBlock { public readonly CodeWriter CodeWriter; public readonly IList<Instruction> Instructions; public readonly ulong RIP; public InstructionBlock(CodeWriter codeWriter, IList<Instruction> instructions, ulong rip) { CodeWriter = codeWriter ?? throw new ArgumentNullException("codeWriter"); Instructions = instructions ?? throw new ArgumentNullException("instructions"); RIP = rip; } } public readonly struct BlockEncoderResult { public readonly ulong RIP; public readonly List<RelocInfo>? RelocInfos; public readonly uint[] NewInstructionOffsets; public readonly ConstantOffsets[] ConstantOffsets; internal BlockEncoderResult(ulong rip, List<RelocInfo>? relocInfos, uint[]? newInstructionOffsets, ConstantOffsets[]? constantOffsets) { RIP = rip; RelocInfos = relocInfos; NewInstructionOffsets = newInstructionOffsets ?? Array2.Empty<uint>(); ConstantOffsets = constantOffsets ?? Array2.Empty<ConstantOffsets>(); } } [Flags] public enum BlockEncoderOptions { None = 0, DontFixBranches = 1, ReturnRelocInfos = 2, ReturnNewInstructionOffsets = 4, ReturnConstantOffsets = 8 } public sealed class BlockEncoder { private sealed class NullCodeWriter : CodeWriter { public static readonly NullCodeWriter Instance = new NullCodeWriter(); private NullCodeWriter() { } public override void WriteByte(byte value) { } } private readonly int bitness; private readonly BlockEncoderOptions options; private readonly Block[] blocks; private readonly Encoder nullEncoder; private readonly Dictionary<ulong, Instr> toInstr; internal int Bitness => bitness; internal bool FixBranches => (options & BlockEncoderOptions.DontFixBranches) == 0; private bool ReturnRelocInfos => (options & BlockEncoderOptions.ReturnRelocInfos) != 0; private bool ReturnNewInstructionOffsets => (options & BlockEncoderOptions.ReturnNewInstructionOffsets) != 0; private bool ReturnConstantOffsets => (options & BlockEncoderOptions.ReturnConstantOffsets) != 0; private BlockEncoder(int bitness, InstructionBlock[] instrBlocks, BlockEncoderOptions options) { if (bitness != 16 && bitness != 32 && bitness != 64) { throw new ArgumentOutOfRangeException("bitness"); } if (instrBlocks == null) { throw new ArgumentNullException("instrBlocks"); } this.bitness = bitness; nullEncoder = Encoder.Create(bitness, NullCodeWriter.Instance); this.options = options; blocks = new Block[instrBlocks.Length]; int num = 0; for (int i = 0; i < instrBlocks.Length; i++) { IList<Instruction> instructions = instrBlocks[i].Instructions; if (instructions == null) { throw new ArgumentException(); } Block block = new Block(this, instrBlocks[i].CodeWriter, instrBlocks[i].RIP, ReturnRelocInfos ? new List<RelocInfo>() : null); blocks[i] = block; Instr[] array = new Instr[instructions.Count]; ulong num2 = instrBlocks[i].RIP; for (int j = 0; j < array.Length; j++) { Instr instr = Instr.Create(this, block, instructions[j]); instr.IP = num2; array[j] = instr; num++; num2 += instr.Size; } block.SetInstructions(array); } Array.Sort(blocks, (Block a, Block b) => a.RIP.CompareTo(b.RIP)); Dictionary<ulong, Instr> dictionary = (toInstr = new Dictionary<ulong, Instr>(num)); bool flag = false; Block[] array2 = blocks; for (int num3 = 0; num3 < array2.Length; num3++) { Instr[] instructions2 = array2[num3].Instructions; foreach (Instr instr2 in instructions2) { ulong origIP = instr2.OrigIP; if (dictionary.TryGetValue(origIP, out var _)) { if (origIP != 0L) { throw new ArgumentException($"Multiple instructions with the same IP: 0x{origIP:X}"); } flag = true; } else { dictionary[origIP] = instr2; } } } if (flag) { dictionary.Remove(0uL); } array2 = blocks; foreach (Block obj in array2) { ulong num5 = obj.RIP; Instr[] instructions2 = obj.Instructions; foreach (Instr instr3 in instructions2) { instr3.IP = num5; if (!instr3.Done) { instr3.Initialize(this); } num5 += instr3.Size; } } } public static bool TryEncode(int bitness, InstructionBlock block, [NotNullWhen(false)] out string? errorMessage, out BlockEncoderResult result, BlockEncoderOptions options = BlockEncoderOptions.None) { if (TryEncode(bitness, new InstructionBlock[1] { block }, out errorMessage, out BlockEncoderResult[] result2, options)) { result = result2[0]; return true; } result = default(BlockEncoderResult); return false; } public static bool TryEncode(int bitness, InstructionBlock[] blocks, [NotNullWhen(false)] out string? errorMessage, [NotNullWhen(true)] out BlockEncoderResult[]? result, BlockEncoderOptions options = BlockEncoderOptions.None) { return new BlockEncoder(bitness, blocks, options).Encode(out errorMessage, out result); } private bool Encode([NotNullWhen(false)] out string errorMessage, [NotNullWhen(true)] out BlockEncoderResult[] result) { Block[] array; for (int i = 0; i < 5; i++) { bool flag = false; array = blocks; foreach (Block obj in array) { ulong num = obj.RIP; ulong num2 = 0uL; Instr[] instructions = obj.Instructions; foreach (Instr instr in instructions) { instr.IP = num; if (!instr.Done) { uint size = instr.Size; if (instr.Optimize(num2)) { if (instr.Size > size) { errorMessage = "Internal error: new size > old size"; result = null; return false; } if (instr.Size < size) { num2 += size - instr.Size; flag = true; } } else if (instr.Size != size) { errorMessage = "Internal error: new size != old size"; result = null; return false; } } num += instr.Size; } } if (!flag) { break; } } array = blocks; for (int j = 0; j < array.Length; j++) { array[j].InitializeData(); } BlockEncoderResult[] array2 = new BlockEncoderResult[blocks.Length]; for (int l = 0; l < blocks.Length; l++) { Block block = blocks[l]; Encoder encoder = Encoder.Create(bitness, block.CodeWriter); ulong num3 = block.RIP; uint[] array3 = (ReturnNewInstructionOffsets ? new uint[block.Instructions.Length] : null); ConstantOffsets[] array4 = (ReturnConstantOffsets ? new ConstantOffsets[block.Instructions.Length] : null); Instr[] instructions2 = block.Instructions; for (int m = 0; m < instructions2.Length; m++) { Instr instr2 = instructions2[m]; uint bytesWritten = block.CodeWriter.BytesWritten; bool isOriginalInstruction; if (array4 != null) { errorMessage = instr2.TryEncode(encoder, out array4[m], out isOriginalInstruction); } else { errorMessage = instr2.TryEncode(encoder, out var _, out isOriginalInstruction); } if (errorMessage != null) { result = null; return false; } uint num4 = block.CodeWriter.BytesWritten - bytesWritten; if (num4 != instr2.Size) { errorMessage = "Internal error: didn't write all bytes"; result = null; return false; } if (array3 != null) { if (isOriginalInstruction) { array3[m] = (uint)(num3 - block.RIP); } else { array3[m] = uint.MaxValue; } } num3 += num4; } array2[l] = new BlockEncoderResult(block.RIP, block.relocInfos, array3, array4); block.WriteData(); } errorMessage = null; result = array2; return true; } internal TargetInstr GetTarget(ulong address) { if (toInstr.TryGetValue(address, out var value)) { return new TargetInstr(value); } return new TargetInstr(address); } internal uint GetInstructionSize(in Instruction instruction, ulong ip) { if (!nullEncoder.TryEncode(in instruction, ip, out uint encodedLength, out string _)) { return 15u; } return encodedLength; } } public sealed class ByteArrayCodeReader : CodeReader { private readonly byte[] data; private int currentPosition; private readonly int startPosition; private readonly int endPosition; public int Position { get { return currentPosition - startPosition; } set { if ((uint)value > (uint)Count) { ThrowHelper.ThrowArgumentOutOfRangeException_value(); } currentPosition = startPosition + value; } } public int Count => endPosition - startPosition; public bool CanReadByte => currentPosition < endPosition; public ByteArrayCodeReader(string hexData) : this(HexUtils.ToByteArray(hexData)) { } public ByteArrayCodeReader(byte[] data) { if (data == null) { ThrowHelper.ThrowArgumentNullException_data(); } this.data = data; currentPosition = 0; startPosition = 0; endPosition = data.Length; } public ByteArrayCodeReader(byte[] data, int index, int count) { if (data == null) { ThrowHelper.ThrowArgumentNullException_data(); } this.data = data; if (index < 0) { ThrowHelper.ThrowArgumentOutOfRangeException_index(); } if (count < 0) { ThrowHelper.ThrowArgumentOutOfRangeException_count(); } if ((uint)(index + count) > (uint)data.Length) { ThrowHelper.ThrowArgumentOutOfRangeException_count(); } currentPosition = index; startPosition = index; endPosition = index + count; } public ByteArrayCodeReader(ArraySegment<byte> data) { if (data.Array == null) { ThrowHelper.ThrowArgumentException(); } this.data = data.Array; endPosition = (startPosition = (currentPosition = data.Offset)) + data.Count; } public override int ReadByte() { if (currentPosition >= endPosition) { return -1; } return data[currentPosition++]; } } public enum Code { INVALID, DeclareByte, DeclareWord, DeclareDword, DeclareQword, Add_rm8_r8, Add_rm16_r16, Add_rm32_r32, Add_rm64_r64, Add_r8_rm8, Add_r16_rm16, Add_r32_rm32, Add_r64_rm64, Add_AL_imm8, Add_AX_imm16, Add_EAX_imm32, Add_RAX_imm32, Pushw_ES, Pushd_ES, Popw_ES, Popd_ES, Or_rm8_r8, Or_rm16_r16, Or_rm32_r32, Or_rm64_r64, Or_r8_rm8, Or_r16_rm16, Or_r32_rm32, Or_r64_rm64, Or_AL_imm8, Or_AX_imm16, Or_EAX_imm32, Or_RAX_imm32, Pushw_CS, Pushd_CS, Popw_CS, Adc_rm8_r8, Adc_rm16_r16, Adc_rm32_r32, Adc_rm64_r64, Adc_r8_rm8, Adc_r16_rm16, Adc_r32_rm32, Adc_r64_rm64, Adc_AL_imm8, Adc_AX_imm16, Adc_EAX_imm32, Adc_RAX_imm32, Pushw_SS, Pushd_SS, Popw_SS, Popd_SS, Sbb_rm8_r8, Sbb_rm16_r16, Sbb_rm32_r32, Sbb_rm64_r64, Sbb_r8_rm8, Sbb_r16_rm16, Sbb_r32_rm32, Sbb_r64_rm64, Sbb_AL_imm8, Sbb_AX_imm16, Sbb_EAX_imm32, Sbb_RAX_imm32, Pushw_DS, Pushd_DS, Popw_DS, Popd_DS, And_rm8_r8, And_rm16_r16, And_rm32_r32, And_rm64_r64, And_r8_rm8, And_r16_rm16, And_r32_rm32, And_r64_rm64, And_AL_imm8, And_AX_imm16, And_EAX_imm32, And_RAX_imm32, Daa, Sub_rm8_r8, Sub_rm16_r16, Sub_rm32_r32, Sub_rm64_r64, Sub_r8_rm8, Sub_r16_rm16, Sub_r32_rm32, Sub_r64_rm64, Sub_AL_imm8, Sub_AX_imm16, Sub_EAX_imm32, Sub_RAX_imm32, Das, Xor_rm8_r8, Xor_rm16_r16, Xor_rm32_r32, Xor_rm64_r64, Xor_r8_rm8, Xor_r16_rm16, Xor_r32_rm32, Xor_r64_rm64, Xor_AL_imm8, Xor_AX_imm16, Xor_EAX_imm32, Xor_RAX_imm32, Aaa, Cmp_rm8_r8, Cmp_rm16_r16, Cmp_rm32_r32, Cmp_rm64_r64, Cmp_r8_rm8, Cmp_r16_rm16, Cmp_r32_rm32, Cmp_r64_rm64, Cmp_AL_imm8, Cmp_AX_imm16, Cmp_EAX_imm32, Cmp_RAX_imm32, Aas, Inc_r16, Inc_r32, Dec_r16, Dec_r32, Push_r16, Push_r32, Push_r64, Pop_r16, Pop_r32, Pop_r64, Pushaw, Pushad, Popaw, Popad, Bound_r16_m1616, Bound_r32_m3232, Arpl_rm16_r16, Arpl_r32m16_r32, Movsxd_r16_rm16, Movsxd_r32_rm32, Movsxd_r64_rm32, Push_imm16, Pushd_imm32, Pushq_imm32, Imul_r16_rm16_imm16, Imul_r32_rm32_imm32, Imul_r64_rm64_imm32, Pushw_imm8, Pushd_imm8, Pushq_imm8, Imul_r16_rm16_imm8, Imul_r32_rm32_imm8, Imul_r64_rm64_imm8, Insb_m8_DX, Insw_m16_DX, Insd_m32_DX, Outsb_DX_m8, Outsw_DX_m16, Outsd_DX_m32, Jo_rel8_16, Jo_rel8_32, Jo_rel8_64, Jno_rel8_16, Jno_rel8_32, Jno_rel8_64, Jb_rel8_16, Jb_rel8_32, Jb_rel8_64, Jae_rel8_16, Jae_rel8_32, Jae_rel8_64, Je_rel8_16, Je_rel8_32, Je_rel8_64, Jne_rel8_16, Jne_rel8_32, Jne_rel8_64, Jbe_rel8_16, Jbe_rel8_32, Jbe_rel8_64, Ja_rel8_16, Ja_rel8_32, Ja_rel8_64, Js_rel8_16, Js_rel8_32, Js_rel8_64, Jns_rel8_16, Jns_rel8_32, Jns_rel8_64, Jp_rel8_16, Jp_rel8_32, Jp_rel8_64, Jnp_rel8_16, Jnp_rel8_32, Jnp_rel8_64, Jl_rel8_16, Jl_rel8_32, Jl_rel8_64, Jge_rel8_16, Jge_rel8_32, Jge_rel8_64, Jle_rel8_16, Jle_rel8_32, Jle_rel8_64, Jg_rel8_16, Jg_rel8_32, Jg_rel8_64, Add_rm8_imm8, Or_rm8_imm8, Adc_rm8_imm8, Sbb_rm8_imm8, And_rm8_imm8, Sub_rm8_imm8, Xor_rm8_imm8, Cmp_rm8_imm8, Add_rm16_imm16, Add_rm32_imm32, Add_rm64_imm32, Or_rm16_imm16, Or_rm32_imm32, Or_rm64_imm32, Adc_rm16_imm16, Adc_rm32_imm32, Adc_rm64_imm32, Sbb_rm16_imm16, Sbb_rm32_imm32, Sbb_rm64_imm32, And_rm16_imm16, And_rm32_imm32, And_rm64_imm32, Sub_rm16_imm16, Sub_rm32_imm32, Sub_rm64_imm32, Xor_rm16_imm16, Xor_rm32_imm32, Xor_rm64_imm32, Cmp_rm16_imm16, Cmp_rm32_imm32, Cmp_rm64_imm32, Add_rm8_imm8_82, Or_rm8_imm8_82, Adc_rm8_imm8_82, Sbb_rm8_imm8_82, And_rm8_imm8_82, Sub_rm8_imm8_82, Xor_rm8_imm8_82, Cmp_rm8_imm8_82, Add_rm16_imm8, Add_rm32_imm8, Add_rm64_imm8, Or_rm16_imm8, Or_rm32_imm8, Or_rm64_imm8, Adc_rm16_imm8, Adc_rm32_imm8, Adc_rm64_imm8, Sbb_rm16_imm8, Sbb_rm32_imm8, Sbb_rm64_imm8, And_rm16_imm8, And_rm32_imm8, And_rm64_imm8, Sub_rm16_imm8, Sub_rm32_imm8, Sub_rm64_imm8, Xor_rm16_imm8, Xor_rm32_imm8, Xor_rm64_imm8, Cmp_rm16_imm8, Cmp_rm32_imm8, Cmp_rm64_imm8, Test_rm8_r8, Test_rm16_r16, Test_rm32_r32, Test_rm64_r64, Xchg_rm8_r8, Xchg_rm16_r16, Xchg_rm32_r32, Xchg_rm64_r64, Mov_rm8_r8, Mov_rm16_r16, Mov_rm32_r32, Mov_rm64_r64, Mov_r8_rm8, Mov_r16_rm16, Mov_r32_rm32, Mov_r64_rm64, Mov_rm16_Sreg, Mov_r32m16_Sreg, Mov_r64m16_Sreg, Lea_r16_m, Lea_r32_m, Lea_r64_m, Mov_Sreg_rm16, Mov_Sreg_r32m16, Mov_Sreg_r64m16, Pop_rm16, Pop_rm32, Pop_rm64, Nopw, Nopd, Nopq, Xchg_r16_AX, Xchg_r32_EAX, Xchg_r64_RAX, Pause, Cbw, Cwde, Cdqe, Cwd, Cdq, Cqo, Call_ptr1616, Call_ptr1632, Wait, Pushfw, Pushfd, Pushfq, Popfw, Popfd, Popfq, Sahf, Lahf, Mov_AL_moffs8, Mov_AX_moffs16, Mov_EAX_moffs32, Mov_RAX_moffs64, Mov_moffs8_AL, Mov_moffs16_AX, Mov_moffs32_EAX, Mov_moffs64_RAX, Movsb_m8_m8, Movsw_m16_m16, Movsd_m32_m32, Movsq_m64_m64, Cmpsb_m8_m8, Cmpsw_m16_m16, Cmpsd_m32_m32, Cmpsq_m64_m64, Test_AL_imm8, Test_AX_imm16, Test_EAX_imm32, Test_RAX_imm32, Stosb_m8_AL, Stosw_m16_AX, Stosd_m32_EAX, Stosq_m64_RAX, Lodsb_AL_m8, Lodsw_AX_m16, Lodsd_EAX_m32, Lodsq_RAX_m64, Scasb_AL_m8, Scasw_AX_m16, Scasd_EAX_m32, Scasq_RAX_m64, Mov_r8_imm8, Mov_r16_imm16, Mov_r32_imm32, Mov_r64_imm64, Rol_rm8_imm8, Ror_rm8_imm8, Rcl_rm8_imm8, Rcr_rm8_imm8, Shl_rm8_imm8, Shr_rm8_imm8, Sal_rm8_imm8, Sar_rm8_imm8, Rol_rm16_imm8, Rol_rm32_imm8, Rol_rm64_imm8, Ror_rm16_imm8, Ror_rm32_imm8, Ror_rm64_imm8, Rcl_rm16_imm8, Rcl_rm32_imm8, Rcl_rm64_imm8, Rcr_rm16_imm8, Rcr_rm32_imm8, Rcr_rm64_imm8, Shl_rm16_imm8, Shl_rm32_imm8, Shl_rm64_imm8, Shr_rm16_imm8, Shr_rm32_imm8, Shr_rm64_imm8, Sal_rm16_imm8, Sal_rm32_imm8, Sal_rm64_imm8, Sar_rm16_imm8, Sar_rm32_imm8, Sar_rm64_imm8, Retnw_imm16, Retnd_imm16, Retnq_imm16, Retnw, Retnd, Retnq, Les_r16_m1616, Les_r32_m1632, Lds_r16_m1616, Lds_r32_m1632, Mov_rm8_imm8, Xabort_imm8, Mov_rm16_imm16, Mov_rm32_imm32, Mov_rm64_imm32, Xbegin_rel16, Xbegin_rel32, Enterw_imm16_imm8, Enterd_imm16_imm8, Enterq_imm16_imm8, Leavew, Leaved, Leaveq, Retfw_imm16, Retfd_imm16, Retfq_imm16, Retfw, Retfd, Retfq, Int3, Int_imm8, Into, Iretw, Iretd, Iretq, Rol_rm8_1, Ror_rm8_1, Rcl_rm8_1, Rcr_rm8_1, Shl_rm8_1, Shr_rm8_1, Sal_rm8_1, Sar_rm8_1, Rol_rm16_1, Rol_rm32_1, Rol_rm64_1, Ror_rm16_1, Ror_rm32_1, Ror_rm64_1, Rcl_rm16_1, Rcl_rm32_1, Rcl_rm64_1, Rcr_rm16_1, Rcr_rm32_1, Rcr_rm64_1, Shl_rm16_1, Shl_rm32_1, Shl_rm64_1, Shr_rm16_1, Shr_rm32_1, Shr_rm64_1, Sal_rm16_1, Sal_rm32_1, Sal_rm64_1, Sar_rm16_1, Sar_rm32_1, Sar_rm64_1, Rol_rm8_CL, Ror_rm8_CL, Rcl_rm8_CL, Rcr_rm8_CL, Shl_rm8_CL, Shr_rm8_CL, Sal_rm8_CL, Sar_rm8_CL, Rol_rm16_CL, Rol_rm32_CL, Rol_rm64_CL, Ror_rm16_CL, Ror_rm32_CL, Ror_rm64_CL, Rcl_rm16_CL, Rcl_rm32_CL, Rcl_rm64_CL, Rcr_rm16_CL, Rcr_rm32_CL, Rcr_rm64_CL, Shl_rm16_CL, Shl_rm32_CL, Shl_rm64_CL, Shr_rm16_CL, Shr_rm32_CL, Shr_rm64_CL, Sal_rm16_CL, Sal_rm32_CL, Sal_rm64_CL, Sar_rm16_CL, Sar_rm32_CL, Sar_rm64_CL, Aam_imm8, Aad_imm8, Salc, Xlat_m8, Fadd_m32fp, Fmul_m32fp, Fcom_m32fp, Fcomp_m32fp, Fsub_m32fp, Fsubr_m32fp, Fdiv_m32fp, Fdivr_m32fp, Fadd_st0_sti, Fmul_st0_sti, Fcom_st0_sti, Fcomp_st0_sti, Fsub_st0_sti, Fsubr_st0_sti, Fdiv_st0_sti, Fdivr_st0_sti, Fld_m32fp, Fst_m32fp, Fstp_m32fp, Fldenv_m14byte, Fldenv_m28byte, Fldcw_m2byte, Fnstenv_m14byte, Fstenv_m14byte, Fnstenv_m28byte, Fstenv_m28byte, Fnstcw_m2byte, Fstcw_m2byte, Fld_sti, Fxch_st0_sti, Fnop, Fstpnce_sti, Fchs, Fabs, Ftst, Fxam, Fld1, Fldl2t, Fldl2e, Fldpi, Fldlg2, Fldln2, Fldz, F2xm1, Fyl2x, Fptan, Fpatan, Fxtract, Fprem1, Fdecstp, Fincstp, Fprem, Fyl2xp1, Fsqrt, Fsincos, Frndint, Fscale, Fsin, Fcos, Fiadd_m32int, Fimul_m32int, Ficom_m32int, Ficomp_m32int, Fisub_m32int, Fisubr_m32int, Fidiv_m32int, Fidivr_m32int, Fcmovb_st0_sti, Fcmove_st0_sti, Fcmovbe_st0_sti, Fcmovu_st0_sti, Fucompp, Fild_m32int, Fisttp_m32int, Fist_m32int, Fistp_m32int, Fld_m80fp, Fstp_m80fp, Fcmovnb_st0_sti, Fcmovne_st0_sti, Fcmovnbe_st0_sti, Fcmovnu_st0_sti, Fneni, Feni, Fndisi, Fdisi, Fnclex, Fclex, Fninit, Finit, Fnsetpm, Fsetpm, Frstpm, Fucomi_st0_sti, Fcomi_st0_sti, Fadd_m64fp, Fmul_m64fp, Fcom_m64fp, Fcomp_m64fp, Fsub_m64fp, Fsubr_m64fp, Fdiv_m64fp, Fdivr_m64fp, Fadd_sti_st0, Fmul_sti_st0, Fcom_st0_sti_DCD0, Fcomp_st0_sti_DCD8, Fsubr_sti_st0, Fsub_sti_st0, Fdivr_sti_st0, Fdiv_sti_st0, Fld_m64fp, Fisttp_m64int, Fst_m64fp, Fstp_m64fp, Frstor_m94byte, Frstor_m108byte, Fnsave_m94byte, Fsave_m94byte, Fnsave_m108byte, Fsave_m108byte, Fnstsw_m2byte, Fstsw_m2byte, Ffree_sti, Fxch_st0_sti_DDC8, Fst_sti, Fstp_sti, Fucom_st0_sti, Fucomp_st0_sti, Fiadd_m16int, Fimul_m16int, Ficom_m16int, Ficomp_m16int, Fisub_m16int, Fisubr_m16int, Fidiv_m16int, Fidivr_m16int, Faddp_sti_st0, Fmulp_sti_st0, Fcomp_st0_sti_DED0, Fcompp, Fsubrp_sti_st0, Fsubp_sti_st0, Fdivrp_sti_st0, Fdivp_sti_st0, Fild_m16int, Fisttp_m16int, Fist_m16int, Fistp_m16int, Fbld_m80bcd, Fild_m64int, Fbstp_m80bcd, Fistp_m64int, Ffreep_sti, Fxch_st0_sti_DFC8, Fstp_sti_DFD0, Fstp_sti_DFD8, Fnstsw_AX, Fstsw_AX, Fstdw_AX, Fstsg_AX, Fucomip_st0_sti, Fcomip_st0_sti, Loopne_rel8_16_CX, Loopne_rel8_32_CX, Loopne_rel8_16_ECX, Loopne_rel8_32_ECX, Loopne_rel8_64_ECX, Loopne_rel8_16_RCX, Loopne_rel8_64_RCX, Loope_rel8_16_CX, Loope_rel8_32_CX, Loope_rel8_16_ECX, Loope_rel8_32_ECX, Loope_rel8_64_ECX, Loope_rel8_16_RCX, Loope_rel8_64_RCX, Loop_rel8_16_CX, Loop_rel8_32_CX, Loop_rel8_16_ECX, Loop_rel8_32_ECX, Loop_rel8_64_ECX, Loop_rel8_16_RCX, Loop_rel8_64_RCX, Jcxz_rel8_16, Jcxz_rel8_32, Jecxz_rel8_16, Jecxz_rel8_32, Jecxz_rel8_64, Jrcxz_rel8_16, Jrcxz_rel8_64, In_AL_imm8, In_AX_imm8, In_EAX_imm8, Out_imm8_AL, Out_imm8_AX, Out_imm8_EAX, Call_rel16, Call_rel32_32, Call_rel32_64, Jmp_rel16, Jmp_rel32_32, Jmp_rel32_64, Jmp_ptr1616, Jmp_ptr1632, Jmp_rel8_16, Jmp_rel8_32, Jmp_rel8_64, In_AL_DX, In_AX_DX, In_EAX_DX, Out_DX_AL, Out_DX_AX, Out_DX_EAX, Int1, Hlt, Cmc, Test_rm8_imm8, Test_rm8_imm8_F6r1, Not_rm8, Neg_rm8, Mul_rm8, Imul_rm8, Div_rm8, Idiv_rm8, Test_rm16_imm16, Test_rm32_imm32, Test_rm64_imm32, Test_rm16_imm16_F7r1, Test_rm32_imm32_F7r1, Test_rm64_imm32_F7r1, Not_rm16, Not_rm32, Not_rm64, Neg_rm16, Neg_rm32, Neg_rm64, Mul_rm16, Mul_rm32, Mul_rm64, Imul_rm16, Imul_rm32, Imul_rm64, Div_rm16, Div_rm32, Div_rm64, Idiv_rm16, Idiv_rm32, Idiv_rm64, Clc, Stc, Cli, Sti, Cld, Std, Inc_rm8, Dec_rm8, Inc_rm16, Inc_rm32, Inc_rm64, Dec_rm16, Dec_rm32, Dec_rm64, Call_rm16, Call_rm32, Call_rm64, Call_m1616, Call_m1632, Call_m1664, Jmp_rm16, Jmp_rm32, Jmp_rm64, Jmp_m1616, Jmp_m1632, Jmp_m1664, Push_rm16, Push_rm32, Push_rm64, Sldt_rm16, Sldt_r32m16, Sldt_r64m16, Str_rm16, Str_r32m16, Str_r64m16, Lldt_rm16, Lldt_r32m16, Lldt_r64m16, Ltr_rm16, Ltr_r32m16, Ltr_r64m16, Verr_rm16, Verr_r32m16, Verr_r64m16, Verw_rm16, Verw_r32m16, Verw_r64m16, Jmpe_rm16, Jmpe_rm32, Sgdt_m1632_16, Sgdt_m1632, Sgdt_m1664, Sidt_m1632_16, Sidt_m1632, Sidt_m1664, Lgdt_m1632_16, Lgdt_m1632, Lgdt_m1664, Lidt_m1632_16, Lidt_m1632, Lidt_m1664, Smsw_rm16, Smsw_r32m16, Smsw_r64m16, Rstorssp_m64, Lmsw_rm16, Lmsw_r32m16, Lmsw_r64m16, Invlpg_m, Enclv, Vmcall, Vmlaunch, Vmresume, Vmxoff, Pconfig, Monitorw, Monitord, Monitorq, Mwait, Clac, Stac, Encls, Xgetbv, Xsetbv, Vmfunc, Xend, Xtest, Enclu, Vmrunw, Vmrund, Vmrunq, Vmmcall, Vmloadw, Vmloadd, Vmloadq, Vmsavew, Vmsaved, Vmsaveq, Stgi, Clgi, Skinit, Invlpgaw, Invlpgad, Invlpgaq, Setssbsy, Saveprevssp, Rdpkru, Wrpkru, Swapgs, Rdtscp, Monitorxw, Monitorxd, Monitorxq, Mcommit, Mwaitx, Clzerow, Clzerod, Clzeroq, Rdpru, Lar_r16_rm16, Lar_r32_r32m16, Lar_r64_r64m16, Lsl_r16_rm16, Lsl_r32_r32m16, Lsl_r64_r64m16, Storeall, Loadall286, Syscall, Clts, Loadall386, Sysretd, Sysretq, Invd, Wbinvd, Wbnoinvd, Cl1invmb, Ud2, Reservednop_rm16_r16_0F0D, Reservednop_rm32_r32_0F0D, Reservednop_rm64_r64_0F0D, Prefetch_m8, Prefetchw_m8, Prefetchwt1_m8, Femms, Umov_rm8_r8, Umov_rm16_r16, Umov_rm32_r32, Umov_r8_rm8, Umov_r16_rm16, Umov_r32_rm32, Movups_xmm_xmmm128, VEX_Vmovups_xmm_xmmm128, VEX_Vmovups_ymm_ymmm256, EVEX_Vmovups_xmm_k1z_xmmm128, EVEX_Vmovups_ymm_k1z_ymmm256, EVEX_Vmovups_zmm_k1z_zmmm512, Movupd_xmm_xmmm128, VEX_Vmovupd_xmm_xmmm128, VEX_Vmovupd_ymm_ymmm256, EVEX_Vmovupd_xmm_k1z_xmmm128, EVEX_Vmovupd_ymm_k1z_ymmm256, EVEX_Vmovupd_zmm_k1z_zmmm512, Movss_xmm_xmmm32, VEX_Vmovss_xmm_xmm_xmm, VEX_Vmovss_xmm_m32, EVEX_Vmovss_xmm_k1z_xmm_xmm, EVEX_Vmovss_xmm_k1z_m32, Movsd_xmm_xmmm64, VEX_Vmovsd_xmm_xmm_xmm, VEX_Vmovsd_xmm_m64, EVEX_Vmovsd_xmm_k1z_xmm_xmm, EVEX_Vmovsd_xmm_k1z_m64, Movups_xmmm128_xmm, VEX_Vmovups_xmmm128_xmm, VEX_Vmovups_ymmm256_ymm, EVEX_Vmovups_xmmm128_k1z_xmm, EVEX_Vmovups_ymmm256_k1z_ymm, EVEX_Vmovups_zmmm512_k1z_zmm, Movupd_xmmm128_xmm, VEX_Vmovupd_xmmm128_xmm, VEX_Vmovupd_ymmm256_ymm, EVEX_Vmovupd_xmmm128_k1z_xmm, EVEX_Vmovupd_ymmm256_k1z_ymm, EVEX_Vmovupd_zmmm512_k1z_zmm, Movss_xmmm32_xmm, VEX_Vmovss_xmm_xmm_xmm_0F11, VEX_Vmovss_m32_xmm, EVEX_Vmovss_xmm_k1z_xmm_xmm_0F11, EVEX_Vmovss_m32_k1_xmm, Movsd_xmmm64_xmm, VEX_Vmovsd_xmm_xmm_xmm_0F11, VEX_Vmovsd_m64_xmm, EVEX_Vmovsd_xmm_k1z_xmm_xmm_0F11, EVEX_Vmovsd_m64_k1_xmm, Movhlps_xmm_xmm, Movlps_xmm_m64, VEX_Vmovhlps_xmm_xmm_xmm, VEX_Vmovlps_xmm_xmm_m64, EVEX_Vmovhlps_xmm_xmm_xmm, EVEX_Vmovlps_xmm_xmm_m64, Movlpd_xmm_m64, VEX_Vmovlpd_xmm_xmm_m64, EVEX_Vmovlpd_xmm_xmm_m64, Movsldup_xmm_xmmm128, VEX_Vmovsldup_xmm_xmmm128, VEX_Vmovsldup_ymm_ymmm256, EVEX_Vmovsldup_xmm_k1z_xmmm128, EVEX_Vmovsldup_ymm_k1z_ymmm256, EVEX_Vmovsldup_zmm_k1z_zmmm512, Movddup_xmm_xmmm64, VEX_Vmovddup_xmm_xmmm64, VEX_Vmovddup_ymm_ymmm256, EVEX_Vmovddup_xmm_k1z_xmmm64, EVEX_Vmovddup_ymm_k1z_ymmm256, EVEX_Vmovddup_zmm_k1z_zmmm512, Movlps_m64_xmm, VEX_Vmovlps_m64_xmm, EVEX_Vmovlps_m64_xmm, Movlpd_m64_xmm, VEX_Vmovlpd_m64_xmm, EVEX_Vmovlpd_m64_xmm, Unpcklps_xmm_xmmm128, VEX_Vunpcklps_xmm_xmm_xmmm128, VEX_Vunpcklps_ymm_ymm_ymmm256, EVEX_Vunpcklps_xmm_k1z_xmm_xmmm128b32, EVEX_Vunpcklps_ymm_k1z_ymm_ymmm256b32, EVEX_Vunpcklps_zmm_k1z_zmm_zmmm512b32, Unpcklpd_xmm_xmmm128, VEX_Vunpcklpd_xmm_xmm_xmmm128, VEX_Vunpcklpd_ymm_ymm_ymmm256, EVEX_Vunpcklpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vunpcklpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vunpcklpd_zmm_k1z_zmm_zmmm512b64, Unpckhps_xmm_xmmm128, VEX_Vunpckhps_xmm_xmm_xmmm128, VEX_Vunpckhps_ymm_ymm_ymmm256, EVEX_Vunpckhps_xmm_k1z_xmm_xmmm128b32, EVEX_Vunpckhps_ymm_k1z_ymm_ymmm256b32, EVEX_Vunpckhps_zmm_k1z_zmm_zmmm512b32, Unpckhpd_xmm_xmmm128, VEX_Vunpckhpd_xmm_xmm_xmmm128, VEX_Vunpckhpd_ymm_ymm_ymmm256, EVEX_Vunpckhpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vunpckhpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vunpckhpd_zmm_k1z_zmm_zmmm512b64, Movlhps_xmm_xmm, VEX_Vmovlhps_xmm_xmm_xmm, EVEX_Vmovlhps_xmm_xmm_xmm, Movhps_xmm_m64, VEX_Vmovhps_xmm_xmm_m64, EVEX_Vmovhps_xmm_xmm_m64, Movhpd_xmm_m64, VEX_Vmovhpd_xmm_xmm_m64, EVEX_Vmovhpd_xmm_xmm_m64, Movshdup_xmm_xmmm128, VEX_Vmovshdup_xmm_xmmm128, VEX_Vmovshdup_ymm_ymmm256, EVEX_Vmovshdup_xmm_k1z_xmmm128, EVEX_Vmovshdup_ymm_k1z_ymmm256, EVEX_Vmovshdup_zmm_k1z_zmmm512, Movhps_m64_xmm, VEX_Vmovhps_m64_xmm, EVEX_Vmovhps_m64_xmm, Movhpd_m64_xmm, VEX_Vmovhpd_m64_xmm, EVEX_Vmovhpd_m64_xmm, Reservednop_rm16_r16_0F18, Reservednop_rm32_r32_0F18, Reservednop_rm64_r64_0F18, Reservednop_rm16_r16_0F19, Reservednop_rm32_r32_0F19, Reservednop_rm64_r64_0F19, Reservednop_rm16_r16_0F1A, Reservednop_rm32_r32_0F1A, Reservednop_rm64_r64_0F1A, Reservednop_rm16_r16_0F1B, Reservednop_rm32_r32_0F1B, Reservednop_rm64_r64_0F1B, Reservednop_rm16_r16_0F1C, Reservednop_rm32_r32_0F1C, Reservednop_rm64_r64_0F1C, Reservednop_rm16_r16_0F1D, Reservednop_rm32_r32_0F1D, Reservednop_rm64_r64_0F1D, Reservednop_rm16_r16_0F1E, Reservednop_rm32_r32_0F1E, Reservednop_rm64_r64_0F1E, Reservednop_rm16_r16_0F1F, Reservednop_rm32_r32_0F1F, Reservednop_rm64_r64_0F1F, Prefetchnta_m8, Prefetcht0_m8, Prefetcht1_m8, Prefetcht2_m8, Bndldx_bnd_mib, Bndmov_bnd_bndm64, Bndmov_bnd_bndm128, Bndcl_bnd_rm32, Bndcl_bnd_rm64, Bndcu_bnd_rm32, Bndcu_bnd_rm64, Bndstx_mib_bnd, Bndmov_bndm64_bnd, Bndmov_bndm128_bnd, Bndmk_bnd_m32, Bndmk_bnd_m64, Bndcn_bnd_rm32, Bndcn_bnd_rm64, Cldemote_m8, Rdsspd_r32, Rdsspq_r64, Endbr64, Endbr32, Nop_rm16, Nop_rm32, Nop_rm64, Mov_r32_cr, Mov_r64_cr, Mov_r32_dr, Mov_r64_dr, Mov_cr_r32, Mov_cr_r64, Mov_dr_r32, Mov_dr_r64, Mov_r32_tr, Mov_tr_r32, Movaps_xmm_xmmm128, VEX_Vmovaps_xmm_xmmm128, VEX_Vmovaps_ymm_ymmm256, EVEX_Vmovaps_xmm_k1z_xmmm128, EVEX_Vmovaps_ymm_k1z_ymmm256, EVEX_Vmovaps_zmm_k1z_zmmm512, Movapd_xmm_xmmm128, VEX_Vmovapd_xmm_xmmm128, VEX_Vmovapd_ymm_ymmm256, EVEX_Vmovapd_xmm_k1z_xmmm128, EVEX_Vmovapd_ymm_k1z_ymmm256, EVEX_Vmovapd_zmm_k1z_zmmm512, Movaps_xmmm128_xmm, VEX_Vmovaps_xmmm128_xmm, VEX_Vmovaps_ymmm256_ymm, EVEX_Vmovaps_xmmm128_k1z_xmm, EVEX_Vmovaps_ymmm256_k1z_ymm, EVEX_Vmovaps_zmmm512_k1z_zmm, Movapd_xmmm128_xmm, VEX_Vmovapd_xmmm128_xmm, VEX_Vmovapd_ymmm256_ymm, EVEX_Vmovapd_xmmm128_k1z_xmm, EVEX_Vmovapd_ymmm256_k1z_ymm, EVEX_Vmovapd_zmmm512_k1z_zmm, Cvtpi2ps_xmm_mmm64, Cvtpi2pd_xmm_mmm64, Cvtsi2ss_xmm_rm32, Cvtsi2ss_xmm_rm64, VEX_Vcvtsi2ss_xmm_xmm_rm32, VEX_Vcvtsi2ss_xmm_xmm_rm64, EVEX_Vcvtsi2ss_xmm_xmm_rm32_er, EVEX_Vcvtsi2ss_xmm_xmm_rm64_er, Cvtsi2sd_xmm_rm32, Cvtsi2sd_xmm_rm64, VEX_Vcvtsi2sd_xmm_xmm_rm32, VEX_Vcvtsi2sd_xmm_xmm_rm64, EVEX_Vcvtsi2sd_xmm_xmm_rm32_er, EVEX_Vcvtsi2sd_xmm_xmm_rm64_er, Movntps_m128_xmm, VEX_Vmovntps_m128_xmm, VEX_Vmovntps_m256_ymm, EVEX_Vmovntps_m128_xmm, EVEX_Vmovntps_m256_ymm, EVEX_Vmovntps_m512_zmm, Movntpd_m128_xmm, VEX_Vmovntpd_m128_xmm, VEX_Vmovntpd_m256_ymm, EVEX_Vmovntpd_m128_xmm, EVEX_Vmovntpd_m256_ymm, EVEX_Vmovntpd_m512_zmm, Movntss_m32_xmm, Movntsd_m64_xmm, Cvttps2pi_mm_xmmm64, Cvttpd2pi_mm_xmmm128, Cvttss2si_r32_xmmm32, Cvttss2si_r64_xmmm32, VEX_Vcvttss2si_r32_xmmm32, VEX_Vcvttss2si_r64_xmmm32, EVEX_Vcvttss2si_r32_xmmm32_sae, EVEX_Vcvttss2si_r64_xmmm32_sae, Cvttsd2si_r32_xmmm64, Cvttsd2si_r64_xmmm64, VEX_Vcvttsd2si_r32_xmmm64, VEX_Vcvttsd2si_r64_xmmm64, EVEX_Vcvttsd2si_r32_xmmm64_sae, EVEX_Vcvttsd2si_r64_xmmm64_sae, Cvtps2pi_mm_xmmm64, Cvtpd2pi_mm_xmmm128, Cvtss2si_r32_xmmm32, Cvtss2si_r64_xmmm32, VEX_Vcvtss2si_r32_xmmm32, VEX_Vcvtss2si_r64_xmmm32, EVEX_Vcvtss2si_r32_xmmm32_er, EVEX_Vcvtss2si_r64_xmmm32_er, Cvtsd2si_r32_xmmm64, Cvtsd2si_r64_xmmm64, VEX_Vcvtsd2si_r32_xmmm64, VEX_Vcvtsd2si_r64_xmmm64, EVEX_Vcvtsd2si_r32_xmmm64_er, EVEX_Vcvtsd2si_r64_xmmm64_er, Ucomiss_xmm_xmmm32, VEX_Vucomiss_xmm_xmmm32, EVEX_Vucomiss_xmm_xmmm32_sae, Ucomisd_xmm_xmmm64, VEX_Vucomisd_xmm_xmmm64, EVEX_Vucomisd_xmm_xmmm64_sae, Comiss_xmm_xmmm32, Comisd_xmm_xmmm64, VEX_Vcomiss_xmm_xmmm32, VEX_Vcomisd_xmm_xmmm64, EVEX_Vcomiss_xmm_xmmm32_sae, EVEX_Vcomisd_xmm_xmmm64_sae, Wrmsr, Rdtsc, Rdmsr, Rdpmc, Sysenter, Sysexitd, Sysexitq, Getsecd, Cmovo_r16_rm16, Cmovo_r32_rm32, Cmovo_r64_rm64, Cmovno_r16_rm16, Cmovno_r32_rm32, Cmovno_r64_rm64, Cmovb_r16_rm16, Cmovb_r32_rm32, Cmovb_r64_rm64, Cmovae_r16_rm16, Cmovae_r32_rm32, Cmovae_r64_rm64, Cmove_r16_rm16, Cmove_r32_rm32, Cmove_r64_rm64, Cmovne_r16_rm16, Cmovne_r32_rm32, Cmovne_r64_rm64, Cmovbe_r16_rm16, Cmovbe_r32_rm32, Cmovbe_r64_rm64, Cmova_r16_rm16, Cmova_r32_rm32, Cmova_r64_rm64, Cmovs_r16_rm16, Cmovs_r32_rm32, Cmovs_r64_rm64, Cmovns_r16_rm16, Cmovns_r32_rm32, Cmovns_r64_rm64, Cmovp_r16_rm16, Cmovp_r32_rm32, Cmovp_r64_rm64, Cmovnp_r16_rm16, Cmovnp_r32_rm32, Cmovnp_r64_rm64, Cmovl_r16_rm16, Cmovl_r32_rm32, Cmovl_r64_rm64, Cmovge_r16_rm16, Cmovge_r32_rm32, Cmovge_r64_rm64, Cmovle_r16_rm16, Cmovle_r32_rm32, Cmovle_r64_rm64, Cmovg_r16_rm16, Cmovg_r32_rm32, Cmovg_r64_rm64, VEX_Kandw_kr_kr_kr, VEX_Kandq_kr_kr_kr, VEX_Kandb_kr_kr_kr, VEX_Kandd_kr_kr_kr, VEX_Kandnw_kr_kr_kr, VEX_Kandnq_kr_kr_kr, VEX_Kandnb_kr_kr_kr, VEX_Kandnd_kr_kr_kr, VEX_Knotw_kr_kr, VEX_Knotq_kr_kr, VEX_Knotb_kr_kr, VEX_Knotd_kr_kr, VEX_Korw_kr_kr_kr, VEX_Korq_kr_kr_kr, VEX_Korb_kr_kr_kr, VEX_Kord_kr_kr_kr, VEX_Kxnorw_kr_kr_kr, VEX_Kxnorq_kr_kr_kr, VEX_Kxnorb_kr_kr_kr, VEX_Kxnord_kr_kr_kr, VEX_Kxorw_kr_kr_kr, VEX_Kxorq_kr_kr_kr, VEX_Kxorb_kr_kr_kr, VEX_Kxord_kr_kr_kr, VEX_Kaddw_kr_kr_kr, VEX_Kaddq_kr_kr_kr, VEX_Kaddb_kr_kr_kr, VEX_Kaddd_kr_kr_kr, VEX_Kunpckwd_kr_kr_kr, VEX_Kunpckdq_kr_kr_kr, VEX_Kunpckbw_kr_kr_kr, Movmskps_r32_xmm, Movmskps_r64_xmm, VEX_Vmovmskps_r32_xmm, VEX_Vmovmskps_r64_xmm, VEX_Vmovmskps_r32_ymm, VEX_Vmovmskps_r64_ymm, Movmskpd_r32_xmm, Movmskpd_r64_xmm, VEX_Vmovmskpd_r32_xmm, VEX_Vmovmskpd_r64_xmm, VEX_Vmovmskpd_r32_ymm, VEX_Vmovmskpd_r64_ymm, Sqrtps_xmm_xmmm128, VEX_Vsqrtps_xmm_xmmm128, VEX_Vsqrtps_ymm_ymmm256, EVEX_Vsqrtps_xmm_k1z_xmmm128b32, EVEX_Vsqrtps_ymm_k1z_ymmm256b32, EVEX_Vsqrtps_zmm_k1z_zmmm512b32_er, Sqrtpd_xmm_xmmm128, VEX_Vsqrtpd_xmm_xmmm128, VEX_Vsqrtpd_ymm_ymmm256, EVEX_Vsqrtpd_xmm_k1z_xmmm128b64, EVEX_Vsqrtpd_ymm_k1z_ymmm256b64, EVEX_Vsqrtpd_zmm_k1z_zmmm512b64_er, Sqrtss_xmm_xmmm32, VEX_Vsqrtss_xmm_xmm_xmmm32, EVEX_Vsqrtss_xmm_k1z_xmm_xmmm32_er, Sqrtsd_xmm_xmmm64, VEX_Vsqrtsd_xmm_xmm_xmmm64, EVEX_Vsqrtsd_xmm_k1z_xmm_xmmm64_er, Rsqrtps_xmm_xmmm128, VEX_Vrsqrtps_xmm_xmmm128, VEX_Vrsqrtps_ymm_ymmm256, Rsqrtss_xmm_xmmm32, VEX_Vrsqrtss_xmm_xmm_xmmm32, Rcpps_xmm_xmmm128, VEX_Vrcpps_xmm_xmmm128, VEX_Vrcpps_ymm_ymmm256, Rcpss_xmm_xmmm32, VEX_Vrcpss_xmm_xmm_xmmm32, Andps_xmm_xmmm128, VEX_Vandps_xmm_xmm_xmmm128, VEX_Vandps_ymm_ymm_ymmm256, EVEX_Vandps_xmm_k1z_xmm_xmmm128b32, EVEX_Vandps_ymm_k1z_ymm_ymmm256b32, EVEX_Vandps_zmm_k1z_zmm_zmmm512b32, Andpd_xmm_xmmm128, VEX_Vandpd_xmm_xmm_xmmm128, VEX_Vandpd_ymm_ymm_ymmm256, EVEX_Vandpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vandpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vandpd_zmm_k1z_zmm_zmmm512b64, Andnps_xmm_xmmm128, VEX_Vandnps_xmm_xmm_xmmm128, VEX_Vandnps_ymm_ymm_ymmm256, EVEX_Vandnps_xmm_k1z_xmm_xmmm128b32, EVEX_Vandnps_ymm_k1z_ymm_ymmm256b32, EVEX_Vandnps_zmm_k1z_zmm_zmmm512b32, Andnpd_xmm_xmmm128, VEX_Vandnpd_xmm_xmm_xmmm128, VEX_Vandnpd_ymm_ymm_ymmm256, EVEX_Vandnpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vandnpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vandnpd_zmm_k1z_zmm_zmmm512b64, Orps_xmm_xmmm128, VEX_Vorps_xmm_xmm_xmmm128, VEX_Vorps_ymm_ymm_ymmm256, EVEX_Vorps_xmm_k1z_xmm_xmmm128b32, EVEX_Vorps_ymm_k1z_ymm_ymmm256b32, EVEX_Vorps_zmm_k1z_zmm_zmmm512b32, Orpd_xmm_xmmm128, VEX_Vorpd_xmm_xmm_xmmm128, VEX_Vorpd_ymm_ymm_ymmm256, EVEX_Vorpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vorpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vorpd_zmm_k1z_zmm_zmmm512b64, Xorps_xmm_xmmm128, VEX_Vxorps_xmm_xmm_xmmm128, VEX_Vxorps_ymm_ymm_ymmm256, EVEX_Vxorps_xmm_k1z_xmm_xmmm128b32, EVEX_Vxorps_ymm_k1z_ymm_ymmm256b32, EVEX_Vxorps_zmm_k1z_zmm_zmmm512b32, Xorpd_xmm_xmmm128, VEX_Vxorpd_xmm_xmm_xmmm128, VEX_Vxorpd_ymm_ymm_ymmm256, EVEX_Vxorpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vxorpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vxorpd_zmm_k1z_zmm_zmmm512b64, Addps_xmm_xmmm128, VEX_Vaddps_xmm_xmm_xmmm128, VEX_Vaddps_ymm_ymm_ymmm256, EVEX_Vaddps_xmm_k1z_xmm_xmmm128b32, EVEX_Vaddps_ymm_k1z_ymm_ymmm256b32, EVEX_Vaddps_zmm_k1z_zmm_zmmm512b32_er, Addpd_xmm_xmmm128, VEX_Vaddpd_xmm_xmm_xmmm128, VEX_Vaddpd_ymm_ymm_ymmm256, EVEX_Vaddpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vaddpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vaddpd_zmm_k1z_zmm_zmmm512b64_er, Addss_xmm_xmmm32, VEX_Vaddss_xmm_xmm_xmmm32, EVEX_Vaddss_xmm_k1z_xmm_xmmm32_er, Addsd_xmm_xmmm64, VEX_Vaddsd_xmm_xmm_xmmm64, EVEX_Vaddsd_xmm_k1z_xmm_xmmm64_er, Mulps_xmm_xmmm128, VEX_Vmulps_xmm_xmm_xmmm128, VEX_Vmulps_ymm_ymm_ymmm256, EVEX_Vmulps_xmm_k1z_xmm_xmmm128b32, EVEX_Vmulps_ymm_k1z_ymm_ymmm256b32, EVEX_Vmulps_zmm_k1z_zmm_zmmm512b32_er, Mulpd_xmm_xmmm128, VEX_Vmulpd_xmm_xmm_xmmm128, VEX_Vmulpd_ymm_ymm_ymmm256, EVEX_Vmulpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vmulpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vmulpd_zmm_k1z_zmm_zmmm512b64_er, Mulss_xmm_xmmm32, VEX_Vmulss_xmm_xmm_xmmm32, EVEX_Vmulss_xmm_k1z_xmm_xmmm32_er, Mulsd_xmm_xmmm64, VEX_Vmulsd_xmm_xmm_xmmm64, EVEX_Vmulsd_xmm_k1z_xmm_xmmm64_er, Cvtps2pd_xmm_xmmm64, VEX_Vcvtps2pd_xmm_xmmm64, VEX_Vcvtps2pd_ymm_xmmm128, EVEX_Vcvtps2pd_xmm_k1z_xmmm64b32, EVEX_Vcvtps2pd_ymm_k1z_xmmm128b32, EVEX_Vcvtps2pd_zmm_k1z_ymmm256b32_sae, Cvtpd2ps_xmm_xmmm128, VEX_Vcvtpd2ps_xmm_xmmm128, VEX_Vcvtpd2ps_xmm_ymmm256, EVEX_Vcvtpd2ps_xmm_k1z_xmmm128b64, EVEX_Vcvtpd2ps_xmm_k1z_ymmm256b64, EVEX_Vcvtpd2ps_ymm_k1z_zmmm512b64_er, Cvtss2sd_xmm_xmmm32, VEX_Vcvtss2sd_xmm_xmm_xmmm32, EVEX_Vcvtss2sd_xmm_k1z_xmm_xmmm32_sae, Cvtsd2ss_xmm_xmmm64, VEX_Vcvtsd2ss_xmm_xmm_xmmm64, EVEX_Vcvtsd2ss_xmm_k1z_xmm_xmmm64_er, Cvtdq2ps_xmm_xmmm128, VEX_Vcvtdq2ps_xmm_xmmm128, VEX_Vcvtdq2ps_ymm_ymmm256, EVEX_Vcvtdq2ps_xmm_k1z_xmmm128b32, EVEX_Vcvtdq2ps_ymm_k1z_ymmm256b32, EVEX_Vcvtdq2ps_zmm_k1z_zmmm512b32_er, EVEX_Vcvtqq2ps_xmm_k1z_xmmm128b64, EVEX_Vcvtqq2ps_xmm_k1z_ymmm256b64, EVEX_Vcvtqq2ps_ymm_k1z_zmmm512b64_er, Cvtps2dq_xmm_xmmm128, VEX_Vcvtps2dq_xmm_xmmm128, VEX_Vcvtps2dq_ymm_ymmm256, EVEX_Vcvtps2dq_xmm_k1z_xmmm128b32, EVEX_Vcvtps2dq_ymm_k1z_ymmm256b32, EVEX_Vcvtps2dq_zmm_k1z_zmmm512b32_er, Cvttps2dq_xmm_xmmm128, VEX_Vcvttps2dq_xmm_xmmm128, VEX_Vcvttps2dq_ymm_ymmm256, EVEX_Vcvttps2dq_xmm_k1z_xmmm128b32, EVEX_Vcvttps2dq_ymm_k1z_ymmm256b32, EVEX_Vcvttps2dq_zmm_k1z_zmmm512b32_sae, Subps_xmm_xmmm128, VEX_Vsubps_xmm_xmm_xmmm128, VEX_Vsubps_ymm_ymm_ymmm256, EVEX_Vsubps_xmm_k1z_xmm_xmmm128b32, EVEX_Vsubps_ymm_k1z_ymm_ymmm256b32, EVEX_Vsubps_zmm_k1z_zmm_zmmm512b32_er, Subpd_xmm_xmmm128, VEX_Vsubpd_xmm_xmm_xmmm128, VEX_Vsubpd_ymm_ymm_ymmm256, EVEX_Vsubpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vsubpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vsubpd_zmm_k1z_zmm_zmmm512b64_er, Subss_xmm_xmmm32, VEX_Vsubss_xmm_xmm_xmmm32, EVEX_Vsubss_xmm_k1z_xmm_xmmm32_er, Subsd_xmm_xmmm64, VEX_Vsubsd_xmm_xmm_xmmm64, EVEX_Vsubsd_xmm_k1z_xmm_xmmm64_er, Minps_xmm_xmmm128, VEX_Vminps_xmm_xmm_xmmm128, VEX_Vminps_ymm_ymm_ymmm256, EVEX_Vminps_xmm_k1z_xmm_xmmm128b32, EVEX_Vminps_ymm_k1z_ymm_ymmm256b32, EVEX_Vminps_zmm_k1z_zmm_zmmm512b32_sae, Minpd_xmm_xmmm128, VEX_Vminpd_xmm_xmm_xmmm128, VEX_Vminpd_ymm_ymm_ymmm256, EVEX_Vminpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vminpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vminpd_zmm_k1z_zmm_zmmm512b64_sae, Minss_xmm_xmmm32, VEX_Vminss_xmm_xmm_xmmm32, EVEX_Vminss_xmm_k1z_xmm_xmmm32_sae, Minsd_xmm_xmmm64, VEX_Vminsd_xmm_xmm_xmmm64, EVEX_Vminsd_xmm_k1z_xmm_xmmm64_sae, Divps_xmm_xmmm128, VEX_Vdivps_xmm_xmm_xmmm128, VEX_Vdivps_ymm_ymm_ymmm256, EVEX_Vdivps_xmm_k1z_xmm_xmmm128b32, EVEX_Vdivps_ymm_k1z_ymm_ymmm256b32, EVEX_Vdivps_zmm_k1z_zmm_zmmm512b32_er, Divpd_xmm_xmmm128, VEX_Vdivpd_xmm_xmm_xmmm128, VEX_Vdivpd_ymm_ymm_ymmm256, EVEX_Vdivpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vdivpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vdivpd_zmm_k1z_zmm_zmmm512b64_er, Divss_xmm_xmmm32, VEX_Vdivss_xmm_xmm_xmmm32, EVEX_Vdivss_xmm_k1z_xmm_xmmm32_er, Divsd_xmm_xmmm64, VEX_Vdivsd_xmm_xmm_xmmm64, EVEX_Vdivsd_xmm_k1z_xmm_xmmm64_er, Maxps_xmm_xmmm128, VEX_Vmaxps_xmm_xmm_xmmm128, VEX_Vmaxps_ymm_ymm_ymmm256, EVEX_Vmaxps_xmm_k1z_xmm_xmmm128b32, EVEX_Vmaxps_ymm_k1z_ymm_ymmm256b32, EVEX_Vmaxps_zmm_k1z_zmm_zmmm512b32_sae, Maxpd_xmm_xmmm128, VEX_Vmaxpd_xmm_xmm_xmmm128, VEX_Vmaxpd_ymm_ymm_ymmm256, EVEX_Vmaxpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vmaxpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vmaxpd_zmm_k1z_zmm_zmmm512b64_sae, Maxss_xmm_xmmm32, VEX_Vmaxss_xmm_xmm_xmmm32, EVEX_Vmaxss_xmm_k1z_xmm_xmmm32_sae, Maxsd_xmm_xmmm64, VEX_Vmaxsd_xmm_xmm_xmmm64, EVEX_Vmaxsd_xmm_k1z_xmm_xmmm64_sae, Punpcklbw_mm_mmm32, Punpcklbw_xmm_xmmm128, VEX_Vpunpcklbw_xmm_xmm_xmmm128, VEX_Vpunpcklbw_ymm_ymm_ymmm256, EVEX_Vpunpcklbw_xmm_k1z_xmm_xmmm128, EVEX_Vpunpcklbw_ymm_k1z_ymm_ymmm256, EVEX_Vpunpcklbw_zmm_k1z_zmm_zmmm512, Punpcklwd_mm_mmm32, Punpcklwd_xmm_xmmm128, VEX_Vpunpcklwd_xmm_xmm_xmmm128, VEX_Vpunpcklwd_ymm_ymm_ymmm256, EVEX_Vpunpcklwd_xmm_k1z_xmm_xmmm128, EVEX_Vpunpcklwd_ymm_k1z_ymm_ymmm256, EVEX_Vpunpcklwd_zmm_k1z_zmm_zmmm512, Punpckldq_mm_mmm32, Punpckldq_xmm_xmmm128, VEX_Vpunpckldq_xmm_xmm_xmmm128, VEX_Vpunpckldq_ymm_ymm_ymmm256, EVEX_Vpunpckldq_xmm_k1z_xmm_xmmm128b32, EVEX_Vpunpckldq_ymm_k1z_ymm_ymmm256b32, EVEX_Vpunpckldq_zmm_k1z_zmm_zmmm512b32, Packsswb_mm_mmm64, Packsswb_xmm_xmmm128, VEX_Vpacksswb_xmm_xmm_xmmm128, VEX_Vpacksswb_ymm_ymm_ymmm256, EVEX_Vpacksswb_xmm_k1z_xmm_xmmm128, EVEX_Vpacksswb_ymm_k1z_ymm_ymmm256, EVEX_Vpacksswb_zmm_k1z_zmm_zmmm512, Pcmpgtb_mm_mmm64, Pcmpgtb_xmm_xmmm128, VEX_Vpcmpgtb_xmm_xmm_xmmm128, VEX_Vpcmpgtb_ymm_ymm_ymmm256, EVEX_Vpcmpgtb_kr_k1_xmm_xmmm128, EVEX_Vpcmpgtb_kr_k1_ymm_ymmm256, EVEX_Vpcmpgtb_kr_k1_zmm_zmmm512, Pcmpgtw_mm_mmm64, Pcmpgtw_xmm_xmmm128, VEX_Vpcmpgtw_xmm_xmm_xmmm128, VEX_Vpcmpgtw_ymm_ymm_ymmm256, EVEX_Vpcmpgtw_kr_k1_xmm_xmmm128, EVEX_Vpcmpgtw_kr_k1_ymm_ymmm256, EVEX_Vpcmpgtw_kr_k1_zmm_zmmm512, Pcmpgtd_mm_mmm64, Pcmpgtd_xmm_xmmm128, VEX_Vpcmpgtd_xmm_xmm_xmmm128, VEX_Vpcmpgtd_ymm_ymm_ymmm256, EVEX_Vpcmpgtd_kr_k1_xmm_xmmm128b32, EVEX_Vpcmpgtd_kr_k1_ymm_ymmm256b32, EVEX_Vpcmpgtd_kr_k1_zmm_zmmm512b32, Packuswb_mm_mmm64, Packuswb_xmm_xmmm128, VEX_Vpackuswb_xmm_xmm_xmmm128, VEX_Vpackuswb_ymm_ymm_ymmm256, EVEX_Vpackuswb_xmm_k1z_xmm_xmmm128, EVEX_Vpackuswb_ymm_k1z_ymm_ymmm256, EVEX_Vpackuswb_zmm_k1z_zmm_zmmm512, Punpckhbw_mm_mmm64, Punpckhbw_xmm_xmmm128, VEX_Vpunpckhbw_xmm_xmm_xmmm128, VEX_Vpunpckhbw_ymm_ymm_ymmm256, EVEX_Vpunpckhbw_xmm_k1z_xmm_xmmm128, EVEX_Vpunpckhbw_ymm_k1z_ymm_ymmm256, EVEX_Vpunpckhbw_zmm_k1z_zmm_zmmm512, Punpckhwd_mm_mmm64, Punpckhwd_xmm_xmmm128, VEX_Vpunpckhwd_xmm_xmm_xmmm128, VEX_Vpunpckhwd_ymm_ymm_ymmm256, EVEX_Vpunpckhwd_xmm_k1z_xmm_xmmm128, EVEX_Vpunpckhwd_ymm_k1z_ymm_ymmm256, EVEX_Vpunpckhwd_zmm_k1z_zmm_zmmm512, Punpckhdq_mm_mmm64, Punpckhdq_xmm_xmmm128, VEX_Vpunpckhdq_xmm_xmm_xmmm128, VEX_Vpunpckhdq_ymm_ymm_ymmm256, EVEX_Vpunpckhdq_xmm_k1z_xmm_xmmm128b32, EVEX_Vpunpckhdq_ymm_k1z_ymm_ymmm256b32, EVEX_Vpunpckhdq_zmm_k1z_zmm_zmmm512b32, Packssdw_mm_mmm64, Packssdw_xmm_xmmm128, VEX_Vpackssdw_xmm_xmm_xmmm128, VEX_Vpackssdw_ymm_ymm_ymmm256, EVEX_Vpackssdw_xmm_k1z_xmm_xmmm128b32, EVEX_Vpackssdw_ymm_k1z_ymm_ymmm256b32, EVEX_Vpackssdw_zmm_k1z_zmm_zmmm512b32, Punpcklqdq_xmm_xmmm128, VEX_Vpunpcklqdq_xmm_xmm_xmmm128, VEX_Vpunpcklqdq_ymm_ymm_ymmm256, EVEX_Vpunpcklqdq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpunpcklqdq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpunpcklqdq_zmm_k1z_zmm_zmmm512b64, Punpckhqdq_xmm_xmmm128, VEX_Vpunpckhqdq_xmm_xmm_xmmm128, VEX_Vpunpckhqdq_ymm_ymm_ymmm256, EVEX_Vpunpckhqdq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpunpckhqdq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpunpckhqdq_zmm_k1z_zmm_zmmm512b64, Movd_mm_rm32, Movq_mm_rm64, Movd_xmm_rm32, Movq_xmm_rm64, VEX_Vmovd_xmm_rm32, VEX_Vmovq_xmm_rm64, EVEX_Vmovd_xmm_rm32, EVEX_Vmovq_xmm_rm64, Movq_mm_mmm64, Movdqa_xmm_xmmm128, VEX_Vmovdqa_xmm_xmmm128, VEX_Vmovdqa_ymm_ymmm256, EVEX_Vmovdqa32_xmm_k1z_xmmm128, EVEX_Vmovdqa32_ymm_k1z_ymmm256, EVEX_Vmovdqa32_zmm_k1z_zmmm512, EVEX_Vmovdqa64_xmm_k1z_xmmm128, EVEX_Vmovdqa64_ymm_k1z_ymmm256, EVEX_Vmovdqa64_zmm_k1z_zmmm512, Movdqu_xmm_xmmm128, VEX_Vmovdqu_xmm_xmmm128, VEX_Vmovdqu_ymm_ymmm256, EVEX_Vmovdqu32_xmm_k1z_xmmm128, EVEX_Vmovdqu32_ymm_k1z_ymmm256, EVEX_Vmovdqu32_zmm_k1z_zmmm512, EVEX_Vmovdqu64_xmm_k1z_xmmm128, EVEX_Vmovdqu64_ymm_k1z_ymmm256, EVEX_Vmovdqu64_zmm_k1z_zmmm512, EVEX_Vmovdqu8_xmm_k1z_xmmm128, EVEX_Vmovdqu8_ymm_k1z_ymmm256, EVEX_Vmovdqu8_zmm_k1z_zmmm512, EVEX_Vmovdqu16_xmm_k1z_xmmm128, EVEX_Vmovdqu16_ymm_k1z_ymmm256, EVEX_Vmovdqu16_zmm_k1z_zmmm512, Pshufw_mm_mmm64_imm8, Pshufd_xmm_xmmm128_imm8, VEX_Vpshufd_xmm_xmmm128_imm8, VEX_Vpshufd_ymm_ymmm256_imm8, EVEX_Vpshufd_xmm_k1z_xmmm128b32_imm8, EVEX_Vpshufd_ymm_k1z_ymmm256b32_imm8, EVEX_Vpshufd_zmm_k1z_zmmm512b32_imm8, Pshufhw_xmm_xmmm128_imm8, VEX_Vpshufhw_xmm_xmmm128_imm8, VEX_Vpshufhw_ymm_ymmm256_imm8, EVEX_Vpshufhw_xmm_k1z_xmmm128_imm8, EVEX_Vpshufhw_ymm_k1z_ymmm256_imm8, EVEX_Vpshufhw_zmm_k1z_zmmm512_imm8, Pshuflw_xmm_xmmm128_imm8, VEX_Vpshuflw_xmm_xmmm128_imm8, VEX_Vpshuflw_ymm_ymmm256_imm8, EVEX_Vpshuflw_xmm_k1z_xmmm128_imm8, EVEX_Vpshuflw_ymm_k1z_ymmm256_imm8, EVEX_Vpshuflw_zmm_k1z_zmmm512_imm8, Psrlw_mm_imm8, Psrlw_xmm_imm8, VEX_Vpsrlw_xmm_xmm_imm8, VEX_Vpsrlw_ymm_ymm_imm8, EVEX_Vpsrlw_xmm_k1z_xmmm128_imm8, EVEX_Vpsrlw_ymm_k1z_ymmm256_imm8, EVEX_Vpsrlw_zmm_k1z_zmmm512_imm8, Psraw_mm_imm8, Psraw_xmm_imm8, VEX_Vpsraw_xmm_xmm_imm8, VEX_Vpsraw_ymm_ymm_imm8, EVEX_Vpsraw_xmm_k1z_xmmm128_imm8, EVEX_Vpsraw_ymm_k1z_ymmm256_imm8, EVEX_Vpsraw_zmm_k1z_zmmm512_imm8, Psllw_mm_imm8, Psllw_xmm_imm8, VEX_Vpsllw_xmm_xmm_imm8, VEX_Vpsllw_ymm_ymm_imm8, EVEX_Vpsllw_xmm_k1z_xmmm128_imm8, EVEX_Vpsllw_ymm_k1z_ymmm256_imm8, EVEX_Vpsllw_zmm_k1z_zmmm512_imm8, EVEX_Vprord_xmm_k1z_xmmm128b32_imm8, EVEX_Vprord_ymm_k1z_ymmm256b32_imm8, EVEX_Vprord_zmm_k1z_zmmm512b32_imm8, EVEX_Vprorq_xmm_k1z_xmmm128b64_imm8, EVEX_Vprorq_ymm_k1z_ymmm256b64_imm8, EVEX_Vprorq_zmm_k1z_zmmm512b64_imm8, EVEX_Vprold_xmm_k1z_xmmm128b32_imm8, EVEX_Vprold_ymm_k1z_ymmm256b32_imm8, EVEX_Vprold_zmm_k1z_zmmm512b32_imm8, EVEX_Vprolq_xmm_k1z_xmmm128b64_imm8, EVEX_Vprolq_ymm_k1z_ymmm256b64_imm8, EVEX_Vprolq_zmm_k1z_zmmm512b64_imm8, Psrld_mm_imm8, Psrld_xmm_imm8, VEX_Vpsrld_xmm_xmm_imm8, VEX_Vpsrld_ymm_ymm_imm8, EVEX_Vpsrld_xmm_k1z_xmmm128b32_imm8, EVEX_Vpsrld_ymm_k1z_ymmm256b32_imm8, EVEX_Vpsrld_zmm_k1z_zmmm512b32_imm8, Psrad_mm_imm8, Psrad_xmm_imm8, VEX_Vpsrad_xmm_xmm_imm8, VEX_Vpsrad_ymm_ymm_imm8, EVEX_Vpsrad_xmm_k1z_xmmm128b32_imm8, EVEX_Vpsrad_ymm_k1z_ymmm256b32_imm8, EVEX_Vpsrad_zmm_k1z_zmmm512b32_imm8, EVEX_Vpsraq_xmm_k1z_xmmm128b64_imm8, EVEX_Vpsraq_ymm_k1z_ymmm256b64_imm8, EVEX_Vpsraq_zmm_k1z_zmmm512b64_imm8, Pslld_mm_imm8, Pslld_xmm_imm8, VEX_Vpslld_xmm_xmm_imm8, VEX_Vpslld_ymm_ymm_imm8, EVEX_Vpslld_xmm_k1z_xmmm128b32_imm8, EVEX_Vpslld_ymm_k1z_ymmm256b32_imm8, EVEX_Vpslld_zmm_k1z_zmmm512b32_imm8, Psrlq_mm_imm8, Psrlq_xmm_imm8, VEX_Vpsrlq_xmm_xmm_imm8, VEX_Vpsrlq_ymm_ymm_imm8, EVEX_Vpsrlq_xmm_k1z_xmmm128b64_imm8, EVEX_Vpsrlq_ymm_k1z_ymmm256b64_imm8, EVEX_Vpsrlq_zmm_k1z_zmmm512b64_imm8, Psrldq_xmm_imm8, VEX_Vpsrldq_xmm_xmm_imm8, VEX_Vpsrldq_ymm_ymm_imm8, EVEX_Vpsrldq_xmm_xmmm128_imm8, EVEX_Vpsrldq_ymm_ymmm256_imm8, EVEX_Vpsrldq_zmm_zmmm512_imm8, Psllq_mm_imm8, Psllq_xmm_imm8, VEX_Vpsllq_xmm_xmm_imm8, VEX_Vpsllq_ymm_ymm_imm8, EVEX_Vpsllq_xmm_k1z_xmmm128b64_imm8, EVEX_Vpsllq_ymm_k1z_ymmm256b64_imm8, EVEX_Vpsllq_zmm_k1z_zmmm512b64_imm8, Pslldq_xmm_imm8, VEX_Vpslldq_xmm_xmm_imm8, VEX_Vpslldq_ymm_ymm_imm8, EVEX_Vpslldq_xmm_xmmm128_imm8, EVEX_Vpslldq_ymm_ymmm256_imm8, EVEX_Vpslldq_zmm_zmmm512_imm8, Pcmpeqb_mm_mmm64, Pcmpeqb_xmm_xmmm128, VEX_Vpcmpeqb_xmm_xmm_xmmm128, VEX_Vpcmpeqb_ymm_ymm_ymmm256, EVEX_Vpcmpeqb_kr_k1_xmm_xmmm128, EVEX_Vpcmpeqb_kr_k1_ymm_ymmm256, EVEX_Vpcmpeqb_kr_k1_zmm_zmmm512, Pcmpeqw_mm_mmm64, Pcmpeqw_xmm_xmmm128, VEX_Vpcmpeqw_xmm_xmm_xmmm128, VEX_Vpcmpeqw_ymm_ymm_ymmm256, EVEX_Vpcmpeqw_kr_k1_xmm_xmmm128, EVEX_Vpcmpeqw_kr_k1_ymm_ymmm256, EVEX_Vpcmpeqw_kr_k1_zmm_zmmm512, Pcmpeqd_mm_mmm64, Pcmpeqd_xmm_xmmm128, VEX_Vpcmpeqd_xmm_xmm_xmmm128, VEX_Vpcmpeqd_ymm_ymm_ymmm256, EVEX_Vpcmpeqd_kr_k1_xmm_xmmm128b32, EVEX_Vpcmpeqd_kr_k1_ymm_ymmm256b32, EVEX_Vpcmpeqd_kr_k1_zmm_zmmm512b32, Emms, VEX_Vzeroupper, VEX_Vzeroall, Vmread_rm32_r32, Vmread_rm64_r64, EVEX_Vcvttps2udq_xmm_k1z_xmmm128b32, EVEX_Vcvttps2udq_ymm_k1z_ymmm256b32, EVEX_Vcvttps2udq_zmm_k1z_zmmm512b32_sae, EVEX_Vcvttpd2udq_xmm_k1z_xmmm128b64, EVEX_Vcvttpd2udq_xmm_k1z_ymmm256b64, EVEX_Vcvttpd2udq_ymm_k1z_zmmm512b64_sae, Extrq_xmm_imm8_imm8, EVEX_Vcvttps2uqq_xmm_k1z_xmmm64b32, EVEX_Vcvttps2uqq_ymm_k1z_xmmm128b32, EVEX_Vcvttps2uqq_zmm_k1z_ymmm256b32_sae, EVEX_Vcvttpd2uqq_xmm_k1z_xmmm128b64, EVEX_Vcvttpd2uqq_ymm_k1z_ymmm256b64, EVEX_Vcvttpd2uqq_zmm_k1z_zmmm512b64_sae, EVEX_Vcvttss2usi_r32_xmmm32_sae, EVEX_Vcvttss2usi_r64_xmmm32_sae, Insertq_xmm_xmm_imm8_imm8, EVEX_Vcvttsd2usi_r32_xmmm64_sae, EVEX_Vcvttsd2usi_r64_xmmm64_sae, Vmwrite_r32_rm32, Vmwrite_r64_rm64, EVEX_Vcvtps2udq_xmm_k1z_xmmm128b32, EVEX_Vcvtps2udq_ymm_k1z_ymmm256b32, EVEX_Vcvtps2udq_zmm_k1z_zmmm512b32_er, EVEX_Vcvtpd2udq_xmm_k1z_xmmm128b64, EVEX_Vcvtpd2udq_xmm_k1z_ymmm256b64, EVEX_Vcvtpd2udq_ymm_k1z_zmmm512b64_er, Extrq_xmm_xmm, EVEX_Vcvtps2uqq_xmm_k1z_xmmm64b32, EVEX_Vcvtps2uqq_ymm_k1z_xmmm128b32, EVEX_Vcvtps2uqq_zmm_k1z_ymmm256b32_er, EVEX_Vcvtpd2uqq_xmm_k1z_xmmm128b64, EVEX_Vcvtpd2uqq_ymm_k1z_ymmm256b64, EVEX_Vcvtpd2uqq_zmm_k1z_zmmm512b64_er, EVEX_Vcvtss2usi_r32_xmmm32_er, EVEX_Vcvtss2usi_r64_xmmm32_er, Insertq_xmm_xmm, EVEX_Vcvtsd2usi_r32_xmmm64_er, EVEX_Vcvtsd2usi_r64_xmmm64_er, EVEX_Vcvttps2qq_xmm_k1z_xmmm64b32, EVEX_Vcvttps2qq_ymm_k1z_xmmm128b32, EVEX_Vcvttps2qq_zmm_k1z_ymmm256b32_sae, EVEX_Vcvttpd2qq_xmm_k1z_xmmm128b64, EVEX_Vcvttpd2qq_ymm_k1z_ymmm256b64, EVEX_Vcvttpd2qq_zmm_k1z_zmmm512b64_sae, EVEX_Vcvtudq2pd_xmm_k1z_xmmm64b32, EVEX_Vcvtudq2pd_ymm_k1z_xmmm128b32, EVEX_Vcvtudq2pd_zmm_k1z_ymmm256b32_er, EVEX_Vcvtuqq2pd_xmm_k1z_xmmm128b64, EVEX_Vcvtuqq2pd_ymm_k1z_ymmm256b64, EVEX_Vcvtuqq2pd_zmm_k1z_zmmm512b64_er, EVEX_Vcvtudq2ps_xmm_k1z_xmmm128b32, EVEX_Vcvtudq2ps_ymm_k1z_ymmm256b32, EVEX_Vcvtudq2ps_zmm_k1z_zmmm512b32_er, EVEX_Vcvtuqq2ps_xmm_k1z_xmmm128b64, EVEX_Vcvtuqq2ps_xmm_k1z_ymmm256b64, EVEX_Vcvtuqq2ps_ymm_k1z_zmmm512b64_er, EVEX_Vcvtps2qq_xmm_k1z_xmmm64b32, EVEX_Vcvtps2qq_ymm_k1z_xmmm128b32, EVEX_Vcvtps2qq_zmm_k1z_ymmm256b32_er, EVEX_Vcvtpd2qq_xmm_k1z_xmmm128b64, EVEX_Vcvtpd2qq_ymm_k1z_ymmm256b64, EVEX_Vcvtpd2qq_zmm_k1z_zmmm512b64_er, EVEX_Vcvtusi2ss_xmm_xmm_rm32_er, EVEX_Vcvtusi2ss_xmm_xmm_rm64_er, EVEX_Vcvtusi2sd_xmm_xmm_rm32_er, EVEX_Vcvtusi2sd_xmm_xmm_rm64_er, Haddpd_xmm_xmmm128, VEX_Vhaddpd_xmm_xmm_xmmm128, VEX_Vhaddpd_ymm_ymm_ymmm256, Haddps_xmm_xmmm128, VEX_Vhaddps_xmm_xmm_xmmm128, VEX_Vhaddps_ymm_ymm_ymmm256, Hsubpd_xmm_xmmm128, VEX_Vhsubpd_xmm_xmm_xmmm128, VEX_Vhsubpd_ymm_ymm_ymmm256, Hsubps_xmm_xmmm128, VEX_Vhsubps_xmm_xmm_xmmm128, VEX_Vhsubps_ymm_ymm_ymmm256, Movd_rm32_mm, Movq_rm64_mm, Movd_rm32_xmm, Movq_rm64_xmm, VEX_Vmovd_rm32_xmm, VEX_Vmovq_rm64_xmm, EVEX_Vmovd_rm32_xmm, EVEX_Vmovq_rm64_xmm, Movq_xmm_xmmm64, VEX_Vmovq_xmm_xmmm64, EVEX_Vmovq_xmm_xmmm64, Movq_mmm64_mm, Movdqa_xmmm128_xmm, VEX_Vmovdqa_xmmm128_xmm, VEX_Vmovdqa_ymmm256_ymm, EVEX_Vmovdqa32_xmmm128_k1z_xmm, EVEX_Vmovdqa32_ymmm256_k1z_ymm, EVEX_Vmovdqa32_zmmm512_k1z_zmm, EVEX_Vmovdqa64_xmmm128_k1z_xmm, EVEX_Vmovdqa64_ymmm256_k1z_ymm, EVEX_Vmovdqa64_zmmm512_k1z_zmm, Movdqu_xmmm128_xmm, VEX_Vmovdqu_xmmm128_xmm, VEX_Vmovdqu_ymmm256_ymm, EVEX_Vmovdqu32_xmmm128_k1z_xmm, EVEX_Vmovdqu32_ymmm256_k1z_ymm, EVEX_Vmovdqu32_zmmm512_k1z_zmm, EVEX_Vmovdqu64_xmmm128_k1z_xmm, EVEX_Vmovdqu64_ymmm256_k1z_ymm, EVEX_Vmovdqu64_zmmm512_k1z_zmm, EVEX_Vmovdqu8_xmmm128_k1z_xmm, EVEX_Vmovdqu8_ymmm256_k1z_ymm, EVEX_Vmovdqu8_zmmm512_k1z_zmm, EVEX_Vmovdqu16_xmmm128_k1z_xmm, EVEX_Vmovdqu16_ymmm256_k1z_ymm, EVEX_Vmovdqu16_zmmm512_k1z_zmm, Jo_rel16, Jo_rel32_32, Jo_rel32_64, Jno_rel16, Jno_rel32_32, Jno_rel32_64, Jb_rel16, Jb_rel32_32, Jb_rel32_64, Jae_rel16, Jae_rel32_32, Jae_rel32_64, Je_rel16, Je_rel32_32, Je_rel32_64, Jne_rel16, Jne_rel32_32, Jne_rel32_64, Jbe_rel16, Jbe_rel32_32, Jbe_rel32_64, Ja_rel16, Ja_rel32_32, Ja_rel32_64, Js_rel16, Js_rel32_32, Js_rel32_64, Jns_rel16, Jns_rel32_32, Jns_rel32_64, Jp_rel16, Jp_rel32_32, Jp_rel32_64, Jnp_rel16, Jnp_rel32_32, Jnp_rel32_64, Jl_rel16, Jl_rel32_32, Jl_rel32_64, Jge_rel16, Jge_rel32_32, Jge_rel32_64, Jle_rel16, Jle_rel32_32, Jle_rel32_64, Jg_rel16, Jg_rel32_32, Jg_rel32_64, Seto_rm8, Setno_rm8, Setb_rm8, Setae_rm8, Sete_rm8, Setne_rm8, Setbe_rm8, Seta_rm8, Sets_rm8, Setns_rm8, Setp_rm8, Setnp_rm8, Setl_rm8, Setge_rm8, Setle_rm8, Setg_rm8, VEX_Kmovw_kr_km16, VEX_Kmovq_kr_km64, VEX_Kmovb_kr_km8, VEX_Kmovd_kr_km32, VEX_Kmovw_m16_kr, VEX_Kmovq_m64_kr, VEX_Kmovb_m8_kr, VEX_Kmovd_m32_kr, VEX_Kmovw_kr_r32, VEX_Kmovb_kr_r32, VEX_Kmovd_kr_r32, VEX_Kmovq_kr_r64, VEX_Kmovw_r32_kr, VEX_Kmovb_r32_kr, VEX_Kmovd_r32_kr, VEX_Kmovq_r64_kr, VEX_Kortestw_kr_kr, VEX_Kortestq_kr_kr, VEX_Kortestb_kr_kr, VEX_Kortestd_kr_kr, VEX_Ktestw_kr_kr, VEX_Ktestq_kr_kr, VEX_Ktestb_kr_kr, VEX_Ktestd_kr_kr, Pushw_FS, Pushd_FS, Pushq_FS, Popw_FS, Popd_FS, Popq_FS, Cpuid, Bt_rm16_r16, Bt_rm32_r32, Bt_rm64_r64, Shld_rm16_r16_imm8, Shld_rm32_r32_imm8, Shld_rm64_r64_imm8, Shld_rm16_r16_CL, Shld_rm32_r32_CL, Shld_rm64_r64_CL, Montmul_16, Montmul_32, Montmul_64, Xsha1_16, Xsha1_32, Xsha1_64, Xsha256_16, Xsha256_32, Xsha256_64, Xbts_r16_rm16, Xbts_r32_rm32, Xstore_16, Xstore_32, Xstore_64, Xcryptecb_16, Xcryptecb_32, Xcryptecb_64, Xcryptcbc_16, Xcryptcbc_32, Xcryptcbc_64, Xcryptctr_16, Xcryptctr_32, Xcryptctr_64, Xcryptcfb_16, Xcryptcfb_32, Xcryptcfb_64, Xcryptofb_16, Xcryptofb_32, Xcryptofb_64, Ibts_rm16_r16, Ibts_rm32_r32, Cmpxchg486_rm8_r8, Cmpxchg486_rm16_r16, Cmpxchg486_rm32_r32, Pushw_GS, Pushd_GS, Pushq_GS, Popw_GS, Popd_GS, Popq_GS, Rsm, Bts_rm16_r16, Bts_rm32_r32, Bts_rm64_r64, Shrd_rm16_r16_imm8, Shrd_rm32_r32_imm8, Shrd_rm64_r64_imm8, Shrd_rm16_r16_CL, Shrd_rm32_r32_CL, Shrd_rm64_r64_CL, Fxsave_m512byte, Fxsave64_m512byte, Rdfsbase_r32, Rdfsbase_r64, Fxrstor_m512byte, Fxrstor64_m512byte, Rdgsbase_r32, Rdgsbase_r64, Ldmxcsr_m32, Wrfsbase_r32, Wrfsbase_r64, VEX_Vldmxcsr_m32, Stmxcsr_m32, Wrgsbase_r32, Wrgsbase_r64, VEX_Vstmxcsr_m32, Xsave_mem, Xsave64_mem, Ptwrite_rm32, Ptwrite_rm64, Xrstor_mem, Xrstor64_mem, Incsspd_r32, Incsspq_r64, Xsaveopt_mem, Xsaveopt64_mem, Clwb_m8, Tpause_r32, Tpause_r64, Clrssbsy_m64, Umonitor_r16, Umonitor_r32, Umonitor_r64, Umwait_r32, Umwait_r64, Clflush_m8, Clflushopt_m8, Lfence, Lfence_E9, Lfence_EA, Lfence_EB, Lfence_EC, Lfence_ED, Lfence_EE, Lfence_EF, Mfence, Mfence_F1, Mfence_F2, Mfence_F3, Mfence_F4, Mfence_F5, Mfence_F6, Mfence_F7, Sfence, Sfence_F9, Sfence_FA, Sfence_FB, Sfence_FC, Sfence_FD, Sfence_FE, Sfence_FF, Pcommit, Imul_r16_rm16, Imul_r32_rm32, Imul_r64_rm64, Cmpxchg_rm8_r8, Cmpxchg_rm16_r16, Cmpxchg_rm32_r32, Cmpxchg_rm64_r64, Lss_r16_m1616, Lss_r32_m1632, Lss_r64_m1664, Btr_rm16_r16, Btr_rm32_r32, Btr_rm64_r64, Lfs_r16_m1616, Lfs_r32_m1632, Lfs_r64_m1664, Lgs_r16_m1616, Lgs_r32_m1632, Lgs_r64_m1664, Movzx_r16_rm8, Movzx_r32_rm8, Movzx_r64_rm8, Movzx_r16_rm16, Movzx_r32_rm16, Movzx_r64_rm16, Jmpe_disp16, Jmpe_disp32, Popcnt_r16_rm16, Popcnt_r32_rm32, Popcnt_r64_rm64, Ud1_r16_rm16, Ud1_r32_rm32, Ud1_r64_rm64, Bt_rm16_imm8, Bt_rm32_imm8, Bt_rm64_imm8, Bts_rm16_imm8, Bts_rm32_imm8, Bts_rm64_imm8, Btr_rm16_imm8, Btr_rm32_imm8, Btr_rm64_imm8, Btc_rm16_imm8, Btc_rm32_imm8, Btc_rm64_imm8, Btc_rm16_r16, Btc_rm32_r32, Btc_rm64_r64, Bsf_r16_rm16, Bsf_r32_rm32, Bsf_r64_rm64, Tzcnt_r16_rm16, Tzcnt_r32_rm32, Tzcnt_r64_rm64, Bsr_r16_rm16, Bsr_r32_rm32, Bsr_r64_rm64, Lzcnt_r16_rm16, Lzcnt_r32_rm32, Lzcnt_r64_rm64, Movsx_r16_rm8, Movsx_r32_rm8, Movsx_r64_rm8, Movsx_r16_rm16, Movsx_r32_rm16, Movsx_r64_rm16, Xadd_rm8_r8, Xadd_rm16_r16, Xadd_rm32_r32, Xadd_rm64_r64, Cmpps_xmm_xmmm128_imm8, VEX_Vcmpps_xmm_xmm_xmmm128_imm8, VEX_Vcmpps_ymm_ymm_ymmm256_imm8, EVEX_Vcmpps_kr_k1_xmm_xmmm128b32_imm8, EVEX_Vcmpps_kr_k1_ymm_ymmm256b32_imm8, EVEX_Vcmpps_kr_k1_zmm_zmmm512b32_imm8_sae, Cmppd_xmm_xmmm128_imm8, VEX_Vcmppd_xmm_xmm_xmmm128_imm8, VEX_Vcmppd_ymm_ymm_ymmm256_imm8, EVEX_Vcmppd_kr_k1_xmm_xmmm128b64_imm8, EVEX_Vcmppd_kr_k1_ymm_ymmm256b64_imm8, EVEX_Vcmppd_kr_k1_zmm_zmmm512b64_imm8_sae, Cmpss_xmm_xmmm32_imm8, VEX_Vcmpss_xmm_xmm_xmmm32_imm8, EVEX_Vcmpss_kr_k1_xmm_xmmm32_imm8_sae, Cmpsd_xmm_xmmm64_imm8, VEX_Vcmpsd_xmm_xmm_xmmm64_imm8, EVEX_Vcmpsd_kr_k1_xmm_xmmm64_imm8_sae, Movnti_m32_r32, Movnti_m64_r64, Pinsrw_mm_r32m16_imm8, Pinsrw_mm_r64m16_imm8, Pinsrw_xmm_r32m16_imm8, Pinsrw_xmm_r64m16_imm8, VEX_Vpinsrw_xmm_xmm_r32m16_imm8, VEX_Vpinsrw_xmm_xmm_r64m16_imm8, EVEX_Vpinsrw_xmm_xmm_r32m16_imm8, EVEX_Vpinsrw_xmm_xmm_r64m16_imm8, Pextrw_r32_mm_imm8, Pextrw_r64_mm_imm8, Pextrw_r32_xmm_imm8, Pextrw_r64_xmm_imm8, VEX_Vpextrw_r32_xmm_imm8, VEX_Vpextrw_r64_xmm_imm8, EVEX_Vpextrw_r32_xmm_imm8, EVEX_Vpextrw_r64_xmm_imm8, Shufps_xmm_xmmm128_imm8, VEX_Vshufps_xmm_xmm_xmmm128_imm8, VEX_Vshufps_ymm_ymm_ymmm256_imm8, EVEX_Vshufps_xmm_k1z_xmm_xmmm128b32_imm8, EVEX_Vshufps_ymm_k1z_ymm_ymmm256b32_imm8, EVEX_Vshufps_zmm_k1z_zmm_zmmm512b32_imm8, Shufpd_xmm_xmmm128_imm8, VEX_Vshufpd_xmm_xmm_xmmm128_imm8, VEX_Vshufpd_ymm_ymm_ymmm256_imm8, EVEX_Vshufpd_xmm_k1z_xmm_xmmm128b64_imm8, EVEX_Vshufpd_ymm_k1z_ymm_ymmm256b64_imm8, EVEX_Vshufpd_zmm_k1z_zmm_zmmm512b64_imm8, Cmpxchg8b_m64, Cmpxchg16b_m128, Xrstors_mem, Xrstors64_mem, Xsavec_mem, Xsavec64_mem, Xsaves_mem, Xsaves64_mem, Vmptrld_m64, Vmclear_m64, Vmxon_m64, Rdrand_r16, Rdrand_r32, Rdrand_r64, Vmptrst_m64, Rdseed_r16, Rdseed_r32, Rdseed_r64, Rdpid_r32, Rdpid_r64, Bswap_r16, Bswap_r32, Bswap_r64, Addsubpd_xmm_xmmm128, VEX_Vaddsubpd_xmm_xmm_xmmm128, VEX_Vaddsubpd_ymm_ymm_ymmm256, Addsubps_xmm_xmmm128, VEX_Vaddsubps_xmm_xmm_xmmm128, VEX_Vaddsubps_ymm_ymm_ymmm256, Psrlw_mm_mmm64, Psrlw_xmm_xmmm128, VEX_Vpsrlw_xmm_xmm_xmmm128, VEX_Vpsrlw_ymm_ymm_xmmm128, EVEX_Vpsrlw_xmm_k1z_xmm_xmmm128, EVEX_Vpsrlw_ymm_k1z_ymm_xmmm128, EVEX_Vpsrlw_zmm_k1z_zmm_xmmm128, Psrld_mm_mmm64, Psrld_xmm_xmmm128, VEX_Vpsrld_xmm_xmm_xmmm128, VEX_Vpsrld_ymm_ymm_xmmm128, EVEX_Vpsrld_xmm_k1z_xmm_xmmm128, EVEX_Vpsrld_ymm_k1z_ymm_xmmm128, EVEX_Vpsrld_zmm_k1z_zmm_xmmm128, Psrlq_mm_mmm64, Psrlq_xmm_xmmm128, VEX_Vpsrlq_xmm_xmm_xmmm128, VEX_Vpsrlq_ymm_ymm_xmmm128, EVEX_Vpsrlq_xmm_k1z_xmm_xmmm128, EVEX_Vpsrlq_ymm_k1z_ymm_xmmm128, EVEX_Vpsrlq_zmm_k1z_zmm_xmmm128, Paddq_mm_mmm64, Paddq_xmm_xmmm128, VEX_Vpaddq_xmm_xmm_xmmm128, VEX_Vpaddq_ymm_ymm_ymmm256, EVEX_Vpaddq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpaddq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpaddq_zmm_k1z_zmm_zmmm512b64, Pmullw_mm_mmm64, Pmullw_xmm_xmmm128, VEX_Vpmullw_xmm_xmm_xmmm128, VEX_Vpmullw_ymm_ymm_ymmm256, EVEX_Vpmullw_xmm_k1z_xmm_xmmm128, EVEX_Vpmullw_ymm_k1z_ymm_ymmm256, EVEX_Vpmullw_zmm_k1z_zmm_zmmm512, Movq_xmmm64_xmm, VEX_Vmovq_xmmm64_xmm, EVEX_Vmovq_xmmm64_xmm, Movq2dq_xmm_mm, Movdq2q_mm_xmm, Pmovmskb_r32_mm, Pmovmskb_r64_mm, Pmovmskb_r32_xmm, Pmovmskb_r64_xmm, VEX_Vpmovmskb_r32_xmm, VEX_Vpmovmskb_r64_xmm, VEX_Vpmovmskb_r32_ymm, VEX_Vpmovmskb_r64_ymm, Psubusb_mm_mmm64, Psubusb_xmm_xmmm128, VEX_Vpsubusb_xmm_xmm_xmmm128, VEX_Vpsubusb_ymm_ymm_ymmm256, EVEX_Vpsubusb_xmm_k1z_xmm_xmmm128, EVEX_Vpsubusb_ymm_k1z_ymm_ymmm256, EVEX_Vpsubusb_zmm_k1z_zmm_zmmm512, Psubusw_mm_mmm64, Psubusw_xmm_xmmm128, VEX_Vpsubusw_xmm_xmm_xmmm128, VEX_Vpsubusw_ymm_ymm_ymmm256, EVEX_Vpsubusw_xmm_k1z_xmm_xmmm128, EVEX_Vpsubusw_ymm_k1z_ymm_ymmm256, EVEX_Vpsubusw_zmm_k1z_zmm_zmmm512, Pminub_mm_mmm64, Pminub_xmm_xmmm128, VEX_Vpminub_xmm_xmm_xmmm128, VEX_Vpminub_ymm_ymm_ymmm256, EVEX_Vpminub_xmm_k1z_xmm_xmmm128, EVEX_Vpminub_ymm_k1z_ymm_ymmm256, EVEX_Vpminub_zmm_k1z_zmm_zmmm512, Pand_mm_mmm64, Pand_xmm_xmmm128, VEX_Vpand_xmm_xmm_xmmm128, VEX_Vpand_ymm_ymm_ymmm256, EVEX_Vpandd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpandd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpandd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpandq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpandq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpandq_zmm_k1z_zmm_zmmm512b64, Paddusb_mm_mmm64, Paddusb_xmm_xmmm128, VEX_Vpaddusb_xmm_xmm_xmmm128, VEX_Vpaddusb_ymm_ymm_ymmm256, EVEX_Vpaddusb_xmm_k1z_xmm_xmmm128, EVEX_Vpaddusb_ymm_k1z_ymm_ymmm256, EVEX_Vpaddusb_zmm_k1z_zmm_zmmm512, Paddusw_mm_mmm64, Paddusw_xmm_xmmm128, VEX_Vpaddusw_xmm_xmm_xmmm128, VEX_Vpaddusw_ymm_ymm_ymmm256, EVEX_Vpaddusw_xmm_k1z_xmm_xmmm128, EVEX_Vpaddusw_ymm_k1z_ymm_ymmm256, EVEX_Vpaddusw_zmm_k1z_zmm_zmmm512, Pmaxub_mm_mmm64, Pmaxub_xmm_xmmm128, VEX_Vpmaxub_xmm_xmm_xmmm128, VEX_Vpmaxub_ymm_ymm_ymmm256, EVEX_Vpmaxub_xmm_k1z_xmm_xmmm128, EVEX_Vpmaxub_ymm_k1z_ymm_ymmm256, EVEX_Vpmaxub_zmm_k1z_zmm_zmmm512, Pandn_mm_mmm64, Pandn_xmm_xmmm128, VEX_Vpandn_xmm_xmm_xmmm128, VEX_Vpandn_ymm_ymm_ymmm256, EVEX_Vpandnd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpandnd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpandnd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpandnq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpandnq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpandnq_zmm_k1z_zmm_zmmm512b64, Pavgb_mm_mmm64, Pavgb_xmm_xmmm128, VEX_Vpavgb_xmm_xmm_xmmm128, VEX_Vpavgb_ymm_ymm_ymmm256, EVEX_Vpavgb_xmm_k1z_xmm_xmmm128, EVEX_Vpavgb_ymm_k1z_ymm_ymmm256, EVEX_Vpavgb_zmm_k1z_zmm_zmmm512, Psraw_mm_mmm64, Psraw_xmm_xmmm128, VEX_Vpsraw_xmm_xmm_xmmm128, VEX_Vpsraw_ymm_ymm_xmmm128, EVEX_Vpsraw_xmm_k1z_xmm_xmmm128, EVEX_Vpsraw_ymm_k1z_ymm_xmmm128, EVEX_Vpsraw_zmm_k1z_zmm_xmmm128, Psrad_mm_mmm64, Psrad_xmm_xmmm128, VEX_Vpsrad_xmm_xmm_xmmm128, VEX_Vpsrad_ymm_ymm_xmmm128, EVEX_Vpsrad_xmm_k1z_xmm_xmmm128, EVEX_Vpsrad_ymm_k1z_ymm_xmmm128, EVEX_Vpsrad_zmm_k1z_zmm_xmmm128, EVEX_Vpsraq_xmm_k1z_xmm_xmmm128, EVEX_Vpsraq_ymm_k1z_ymm_xmmm128, EVEX_Vpsraq_zmm_k1z_zmm_xmmm128, Pavgw_mm_mmm64, Pavgw_xmm_xmmm128, VEX_Vpavgw_xmm_xmm_xmmm128, VEX_Vpavgw_ymm_ymm_ymmm256, EVEX_Vpavgw_xmm_k1z_xmm_xmmm128, EVEX_Vpavgw_ymm_k1z_ymm_ymmm256, EVEX_Vpavgw_zmm_k1z_zmm_zmmm512, Pmulhuw_mm_mmm64, Pmulhuw_xmm_xmmm128, VEX_Vpmulhuw_xmm_xmm_xmmm128, VEX_Vpmulhuw_ymm_ymm_ymmm256, EVEX_Vpmulhuw_xmm_k1z_xmm_xmmm128, EVEX_Vpmulhuw_ymm_k1z_ymm_ymmm256, EVEX_Vpmulhuw_zmm_k1z_zmm_zmmm512, Pmulhw_mm_mmm64, Pmulhw_xmm_xmmm128, VEX_Vpmulhw_xmm_xmm_xmmm128, VEX_Vpmulhw_ymm_ymm_ymmm256, EVEX_Vpmulhw_xmm_k1z_xmm_xmmm128, EVEX_Vpmulhw_ymm_k1z_ymm_ymmm256, EVEX_Vpmulhw_zmm_k1z_zmm_zmmm512, Cvttpd2dq_xmm_xmmm128, VEX_Vcvttpd2dq_xmm_xmmm128, VEX_Vcvttpd2dq_xmm_ymmm256, EVEX_Vcvttpd2dq_xmm_k1z_xmmm128b64, EVEX_Vcvttpd2dq_xmm_k1z_ymmm256b64, EVEX_Vcvttpd2dq_ymm_k1z_zmmm512b64_sae, Cvtdq2pd_xmm_xmmm64, VEX_Vcvtdq2pd_xmm_xmmm64, VEX_Vcvtdq2pd_ymm_xmmm128, EVEX_Vcvtdq2pd_xmm_k1z_xmmm64b32, EVEX_Vcvtdq2pd_ymm_k1z_xmmm128b32, EVEX_Vcvtdq2pd_zmm_k1z_ymmm256b32_er, EVEX_Vcvtqq2pd_xmm_k1z_xmmm128b64, EVEX_Vcvtqq2pd_ymm_k1z_ymmm256b64, EVEX_Vcvtqq2pd_zmm_k1z_zmmm512b64_er, Cvtpd2dq_xmm_xmmm128, VEX_Vcvtpd2dq_xmm_xmmm128, VEX_Vcvtpd2dq_xmm_ymmm256, EVEX_Vcvtpd2dq_xmm_k1z_xmmm128b64, EVEX_Vcvtpd2dq_xmm_k1z_ymmm256b64, EVEX_Vcvtpd2dq_ymm_k1z_zmmm512b64_er, Movntq_m64_mm, Movntdq_m128_xmm, VEX_Vmovntdq_m128_xmm, VEX_Vmovntdq_m256_ymm, EVEX_Vmovntdq_m128_xmm, EVEX_Vmovntdq_m256_ymm, EVEX_Vmovntdq_m512_zmm, Psubsb_mm_mmm64, Psubsb_xmm_xmmm128, VEX_Vpsubsb_xmm_xmm_xmmm128, VEX_Vpsubsb_ymm_ymm_ymmm256, EVEX_Vpsubsb_xmm_k1z_xmm_xmmm128, EVEX_Vpsubsb_ymm_k1z_ymm_ymmm256, EVEX_Vpsubsb_zmm_k1z_zmm_zmmm512, Psubsw_mm_mmm64, Psubsw_xmm_xmmm128, VEX_Vpsubsw_xmm_xmm_xmmm128, VEX_Vpsubsw_ymm_ymm_ymmm256, EVEX_Vpsubsw_xmm_k1z_xmm_xmmm128, EVEX_Vpsubsw_ymm_k1z_ymm_ymmm256, EVEX_Vpsubsw_zmm_k1z_zmm_zmmm512, Pminsw_mm_mmm64, Pminsw_xmm_xmmm128, VEX_Vpminsw_xmm_xmm_xmmm128, VEX_Vpminsw_ymm_ymm_ymmm256, EVEX_Vpminsw_xmm_k1z_xmm_xmmm128, EVEX_Vpminsw_ymm_k1z_ymm_ymmm256, EVEX_Vpminsw_zmm_k1z_zmm_zmmm512, Por_mm_mmm64, Por_xmm_xmmm128, VEX_Vpor_xmm_xmm_xmmm128, VEX_Vpor_ymm_ymm_ymmm256, EVEX_Vpord_xmm_k1z_xmm_xmmm128b32, EVEX_Vpord_ymm_k1z_ymm_ymmm256b32, EVEX_Vpord_zmm_k1z_zmm_zmmm512b32, EVEX_Vporq_xmm_k1z_xmm_xmmm128b64, EVEX_Vporq_ymm_k1z_ymm_ymmm256b64, EVEX_Vporq_zmm_k1z_zmm_zmmm512b64, Paddsb_mm_mmm64, Paddsb_xmm_xmmm128, VEX_Vpaddsb_xmm_xmm_xmmm128, VEX_Vpaddsb_ymm_ymm_ymmm256, EVEX_Vpaddsb_xmm_k1z_xmm_xmmm128, EVEX_Vpaddsb_ymm_k1z_ymm_ymmm256, EVEX_Vpaddsb_zmm_k1z_zmm_zmmm512, Paddsw_mm_mmm64, Paddsw_xmm_xmmm128, VEX_Vpaddsw_xmm_xmm_xmmm128, VEX_Vpaddsw_ymm_ymm_ymmm256, EVEX_Vpaddsw_xmm_k1z_xmm_xmmm128, EVEX_Vpaddsw_ymm_k1z_ymm_ymmm256, EVEX_Vpaddsw_zmm_k1z_zmm_zmmm512, Pmaxsw_mm_mmm64, Pmaxsw_xmm_xmmm128, VEX_Vpmaxsw_xmm_xmm_xmmm128, VEX_Vpmaxsw_ymm_ymm_ymmm256, EVEX_Vpmaxsw_xmm_k1z_xmm_xmmm128, EVEX_Vpmaxsw_ymm_k1z_ymm_ymmm256, EVEX_Vpmaxsw_zmm_k1z_zmm_zmmm512, Pxor_mm_mmm64, Pxor_xmm_xmmm128, VEX_Vpxor_xmm_xmm_xmmm128, VEX_Vpxor_ymm_ymm_ymmm256, EVEX_Vpxord_xmm_k1z_xmm_xmmm128b32, EVEX_Vpxord_ymm_k1z_ymm_ymmm256b32, EVEX_Vpxord_zmm_k1z_zmm_zmmm512b32, EVEX_Vpxorq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpxorq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpxorq_zmm_k1z_zmm_zmmm512b64, Lddqu_xmm_m128, VEX_Vlddqu_xmm_m128, VEX_Vlddqu_ymm_m256, Psllw_mm_mmm64, Psllw_xmm_xmmm128, VEX_Vpsllw_xmm_xmm_xmmm128, VEX_Vpsllw_ymm_ymm_xmmm128, EVEX_Vpsllw_xmm_k1z_xmm_xmmm128, EVEX_Vpsllw_ymm_k1z_ymm_xmmm128, EVEX_Vpsllw_zmm_k1z_zmm_xmmm128, Pslld_mm_mmm64, Pslld_xmm_xmmm128, VEX_Vpslld_xmm_xmm_xmmm128, VEX_Vpslld_ymm_ymm_xmmm128, EVEX_Vpslld_xmm_k1z_xmm_xmmm128, EVEX_Vpslld_ymm_k1z_ymm_xmmm128, EVEX_Vpslld_zmm_k1z_zmm_xmmm128, Psllq_mm_mmm64, Psllq_xmm_xmmm128, VEX_Vpsllq_xmm_xmm_xmmm128, VEX_Vpsllq_ymm_ymm_xmmm128, EVEX_Vpsllq_xmm_k1z_xmm_xmmm128, EVEX_Vpsllq_ymm_k1z_ymm_xmmm128, EVEX_Vpsllq_zmm_k1z_zmm_xmmm128, Pmuludq_mm_mmm64, Pmuludq_xmm_xmmm128, VEX_Vpmuludq_xmm_xmm_xmmm128, VEX_Vpmuludq_ymm_ymm_ymmm256, EVEX_Vpmuludq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpmuludq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpmuludq_zmm_k1z_zmm_zmmm512b64, Pmaddwd_mm_mmm64, Pmaddwd_xmm_xmmm128, VEX_Vpmaddwd_xmm_xmm_xmmm128, VEX_Vpmaddwd_ymm_ymm_ymmm256, EVEX_Vpmaddwd_xmm_k1z_xmm_xmmm128, EVEX_Vpmaddwd_ymm_k1z_ymm_ymmm256, EVEX_Vpmaddwd_zmm_k1z_zmm_zmmm512, Psadbw_mm_mmm64, Psadbw_xmm_xmmm128, VEX_Vpsadbw_xmm_xmm_xmmm128, VEX_Vpsadbw_ymm_ymm_ymmm256, EVEX_Vpsadbw_xmm_xmm_xmmm128, EVEX_Vpsadbw_ymm_ymm_ymmm256, EVEX_Vpsadbw_zmm_zmm_zmmm512, Maskmovq_rDI_mm_mm, Maskmovdqu_rDI_xmm_xmm, VEX_Vmaskmovdqu_rDI_xmm_xmm, Psubb_mm_mmm64, Psubb_xmm_xmmm128, VEX_Vpsubb_xmm_xmm_xmmm128, VEX_Vpsubb_ymm_ymm_ymmm256, EVEX_Vpsubb_xmm_k1z_xmm_xmmm128, EVEX_Vpsubb_ymm_k1z_ymm_ymmm256, EVEX_Vpsubb_zmm_k1z_zmm_zmmm512, Psubw_mm_mmm64, Psubw_xmm_xmmm128, VEX_Vpsubw_xmm_xmm_xmmm128, VEX_Vpsubw_ymm_ymm_ymmm256, EVEX_Vpsubw_xmm_k1z_xmm_xmmm128, EVEX_Vpsubw_ymm_k1z_ymm_ymmm256, EVEX_Vpsubw_zmm_k1z_zmm_zmmm512, Psubd_mm_mmm64, Psubd_xmm_xmmm128, VEX_Vpsubd_xmm_xmm_xmmm128, VEX_Vpsubd_ymm_ymm_ymmm256, EVEX_Vpsubd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpsubd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpsubd_zmm_k1z_zmm_zmmm512b32, Psubq_mm_mmm64, Psubq_xmm_xmmm128, VEX_Vpsubq_xmm_xmm_xmmm128, VEX_Vpsubq_ymm_ymm_ymmm256, EVEX_Vpsubq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpsubq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpsubq_zmm_k1z_zmm_zmmm512b64, Paddb_mm_mmm64, Paddb_xmm_xmmm128, VEX_Vpaddb_xmm_xmm_xmmm128, VEX_Vpaddb_ymm_ymm_ymmm256, EVEX_Vpaddb_xmm_k1z_xmm_xmmm128, EVEX_Vpaddb_ymm_k1z_ymm_ymmm256, EVEX_Vpaddb_zmm_k1z_zmm_zmmm512, Paddw_mm_mmm64, Paddw_xmm_xmmm128, VEX_Vpaddw_xmm_xmm_xmmm128, VEX_Vpaddw_ymm_ymm_ymmm256, EVEX_Vpaddw_xmm_k1z_xmm_xmmm128, EVEX_Vpaddw_ymm_k1z_ymm_ymmm256, EVEX_Vpaddw_zmm_k1z_zmm_zmmm512, Paddd_mm_mmm64, Paddd_xmm_xmmm128, VEX_Vpaddd_xmm_xmm_xmmm128, VEX_Vpaddd_ymm_ymm_ymmm256, EVEX_Vpaddd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpaddd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpaddd_zmm_k1z_zmm_zmmm512b32, Ud0_r16_rm16, Ud0_r32_rm32, Ud0_r64_rm64, Pshufb_mm_mmm64, Pshufb_xmm_xmmm128, VEX_Vpshufb_xmm_xmm_xmmm128, VEX_Vpshufb_ymm_ymm_ymmm256, EVEX_Vpshufb_xmm_k1z_xmm_xmmm128, EVEX_Vpshufb_ymm_k1z_ymm_ymmm256, EVEX_Vpshufb_zmm_k1z_zmm_zmmm512, Phaddw_mm_mmm64, Phaddw_xmm_xmmm128, VEX_Vphaddw_xmm_xmm_xmmm128, VEX_Vphaddw_ymm_ymm_ymmm256, Phaddd_mm_mmm64, Phaddd_xmm_xmmm128, VEX_Vphaddd_xmm_xmm_xmmm128, VEX_Vphaddd_ymm_ymm_ymmm256, Phaddsw_mm_mmm64, Phaddsw_xmm_xmmm128, VEX_Vphaddsw_xmm_xmm_xmmm128, VEX_Vphaddsw_ymm_ymm_ymmm256, Pmaddubsw_mm_mmm64, Pmaddubsw_xmm_xmmm128, VEX_Vpmaddubsw_xmm_xmm_xmmm128, VEX_Vpmaddubsw_ymm_ymm_ymmm256, EVEX_Vpmaddubsw_xmm_k1z_xmm_xmmm128, EVEX_Vpmaddubsw_ymm_k1z_ymm_ymmm256, EVEX_Vpmaddubsw_zmm_k1z_zmm_zmmm512, Phsubw_mm_mmm64, Phsubw_xmm_xmmm128, VEX_Vphsubw_xmm_xmm_xmmm128, VEX_Vphsubw_ymm_ymm_ymmm256, Phsubd_mm_mmm64, Phsubd_xmm_xmmm128, VEX_Vphsubd_xmm_xmm_xmmm128, VEX_Vphsubd_ymm_ymm_ymmm256, Phsubsw_mm_mmm64, Phsubsw_xmm_xmmm128, VEX_Vphsubsw_xmm_xmm_xmmm128, VEX_Vphsubsw_ymm_ymm_ymmm256, Psignb_mm_mmm64, Psignb_xmm_xmmm128, VEX_Vpsignb_xmm_xmm_xmmm128, VEX_Vpsignb_ymm_ymm_ymmm256, Psignw_mm_mmm64, Psignw_xmm_xmmm128, VEX_Vpsignw_xmm_xmm_xmmm128, VEX_Vpsignw_ymm_ymm_ymmm256, Psignd_mm_mmm64, Psignd_xmm_xmmm128, VEX_Vpsignd_xmm_xmm_xmmm128, VEX_Vpsignd_ymm_ymm_ymmm256, Pmulhrsw_mm_mmm64, Pmulhrsw_xmm_xmmm128, VEX_Vpmulhrsw_xmm_xmm_xmmm128, VEX_Vpmulhrsw_ymm_ymm_ymmm256, EVEX_Vpmulhrsw_xmm_k1z_xmm_xmmm128, EVEX_Vpmulhrsw_ymm_k1z_ymm_ymmm256, EVEX_Vpmulhrsw_zmm_k1z_zmm_zmmm512, VEX_Vpermilps_xmm_xmm_xmmm128, VEX_Vpermilps_ymm_ymm_ymmm256, EVEX_Vpermilps_xmm_k1z_xmm_xmmm128b32, EVEX_Vpermilps_ymm_k1z_ymm_ymmm256b32, EVEX_Vpermilps_zmm_k1z_zmm_zmmm512b32, VEX_Vpermilpd_xmm_xmm_xmmm128, VEX_Vpermilpd_ymm_ymm_ymmm256, EVEX_Vpermilpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vpermilpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vpermilpd_zmm_k1z_zmm_zmmm512b64, VEX_Vtestps_xmm_xmmm128, VEX_Vtestps_ymm_ymmm256, VEX_Vtestpd_xmm_xmmm128, VEX_Vtestpd_ymm_ymmm256, Pblendvb_xmm_xmmm128, EVEX_Vpsrlvw_xmm_k1z_xmm_xmmm128, EVEX_Vpsrlvw_ymm_k1z_ymm_ymmm256, EVEX_Vpsrlvw_zmm_k1z_zmm_zmmm512, EVEX_Vpmovuswb_xmmm64_k1z_xmm, EVEX_Vpmovuswb_xmmm128_k1z_ymm, EVEX_Vpmovuswb_ymmm256_k1z_zmm, EVEX_Vpsravw_xmm_k1z_xmm_xmmm128, EVEX_Vpsravw_ymm_k1z_ymm_ymmm256, EVEX_Vpsravw_zmm_k1z_zmm_zmmm512, EVEX_Vpmovusdb_xmmm32_k1z_xmm, EVEX_Vpmovusdb_xmmm64_k1z_ymm, EVEX_Vpmovusdb_xmmm128_k1z_zmm, EVEX_Vpsllvw_xmm_k1z_xmm_xmmm128, EVEX_Vpsllvw_ymm_k1z_ymm_ymmm256, EVEX_Vpsllvw_zmm_k1z_zmm_zmmm512, EVEX_Vpmovusqb_xmmm16_k1z_xmm, EVEX_Vpmovusqb_xmmm32_k1z_ymm, EVEX_Vpmovusqb_xmmm64_k1z_zmm, VEX_Vcvtph2ps_xmm_xmmm64, VEX_Vcvtph2ps_ymm_xmmm128, EVEX_Vcvtph2ps_xmm_k1z_xmmm64, EVEX_Vcvtph2ps_ymm_k1z_xmmm128, EVEX_Vcvtph2ps_zmm_k1z_ymmm256_sae, EVEX_Vpmovusdw_xmmm64_k1z_xmm, EVEX_Vpmovusdw_xmmm128_k1z_ymm, EVEX_Vpmovusdw_ymmm256_k1z_zmm, Blendvps_xmm_xmmm128, EVEX_Vprorvd_xmm_k1z_xmm_xmmm128b32, EVEX_Vprorvd_ymm_k1z_ymm_ymmm256b32, EVEX_Vprorvd_zmm_k1z_zmm_zmmm512b32, EVEX_Vprorvq_xmm_k1z_xmm_xmmm128b64, EVEX_Vprorvq_ymm_k1z_ymm_ymmm256b64, EVEX_Vprorvq_zmm_k1z_zmm_zmmm512b64, EVEX_Vpmovusqw_xmmm32_k1z_xmm, EVEX_Vpmovusqw_xmmm64_k1z_ymm, EVEX_Vpmovusqw_xmmm128_k1z_zmm, Blendvpd_xmm_xmmm128, EVEX_Vprolvd_xmm_k1z_xmm_xmmm128b32, EVEX_Vprolvd_ymm_k1z_ymm_ymmm256b32, EVEX_Vprolvd_zmm_k1z_zmm_zmmm512b32, EVEX_Vprolvq_xmm_k1z_xmm_xmmm128b64, EVEX_Vprolvq_ymm_k1z_ymm_ymmm256b64, EVEX_Vprolvq_zmm_k1z_zmm_zmmm512b64, EVEX_Vpmovusqd_xmmm64_k1z_xmm, EVEX_Vpmovusqd_xmmm128_k1z_ymm, EVEX_Vpmovusqd_ymmm256_k1z_zmm, VEX_Vpermps_ymm_ymm_ymmm256, EVEX_Vpermps_ymm_k1z_ymm_ymmm256b32, EVEX_Vpermps_zmm_k1z_zmm_zmmm512b32, EVEX_Vpermpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vpermpd_zmm_k1z_zmm_zmmm512b64, Ptest_xmm_xmmm128, VEX_Vptest_xmm_xmmm128, VEX_Vptest_ymm_ymmm256, VEX_Vbroadcastss_xmm_m32, VEX_Vbroadcastss_ymm_m32, EVEX_Vbroadcastss_xmm_k1z_xmmm32, EVEX_Vbroadcastss_ymm_k1z_xmmm32, EVEX_Vbroadcastss_zmm_k1z_xmmm32, VEX_Vbroadcastsd_ymm_m64, EVEX_Vbroadcastf32x2_ymm_k1z_xmmm64, EVEX_Vbroadcastf32x2_zmm_k1z_xmmm64, EVEX_Vbroadcastsd_ymm_k1z_xmmm64, EVEX_Vbroadcastsd_zmm_k1z_xmmm64, VEX_Vbroadcastf128_ymm_m128, EVEX_Vbroadcastf32x4_ymm_k1z_m128, EVEX_Vbroadcastf32x4_zmm_k1z_m128, EVEX_Vbroadcastf64x2_ymm_k1z_m128, EVEX_Vbroadcastf64x2_zmm_k1z_m128, EVEX_Vbroadcastf32x8_zmm_k1z_m256, EVEX_Vbroadcastf64x4_zmm_k1z_m256, Pabsb_mm_mmm64, Pabsb_xmm_xmmm128, VEX_Vpabsb_xmm_xmmm128, VEX_Vpabsb_ymm_ymmm256, EVEX_Vpabsb_xmm_k1z_xmmm128, EVEX_Vpabsb_ymm_k1z_ymmm256, EVEX_Vpabsb_zmm_k1z_zmmm512, Pabsw_mm_mmm64, Pabsw_xmm_xmmm128, VEX_Vpabsw_xmm_xmmm128, VEX_Vpabsw_ymm_ymmm256, EVEX_Vpabsw_xmm_k1z_xmmm128, EVEX_Vpabsw_ymm_k1z_ymmm256, EVEX_Vpabsw_zmm_k1z_zmmm512, Pabsd_mm_mmm64, Pabsd_xmm_xmmm128, VEX_Vpabsd_xmm_xmmm128, VEX_Vpabsd_ymm_ymmm256, EVEX_Vpabsd_xmm_k1z_xmmm128b32, EVEX_Vpabsd_ymm_k1z_ymmm256b32, EVEX_Vpabsd_zmm_k1z_zmmm512b32, EVEX_Vpabsq_xmm_k1z_xmmm128b64, EVEX_Vpabsq_ymm_k1z_ymmm256b64, EVEX_Vpabsq_zmm_k1z_zmmm512b64, Pmovsxbw_xmm_xmmm64, VEX_Vpmovsxbw_xmm_xmmm64, VEX_Vpmovsxbw_ymm_xmmm128, EVEX_Vpmovsxbw_xmm_k1z_xmmm64, EVEX_Vpmovsxbw_ymm_k1z_xmmm128, EVEX_Vpmovsxbw_zmm_k1z_ymmm256, EVEX_Vpmovswb_xmmm64_k1z_xmm, EVEX_Vpmovswb_xmmm128_k1z_ymm, EVEX_Vpmovswb_ymmm256_k1z_zmm, Pmovsxbd_xmm_xmmm32, VEX_Vpmovsxbd_xmm_xmmm32, VEX_Vpmovsxbd_ymm_xmmm64, EVEX_Vpmovsxbd_xmm_k1z_xmmm32, EVEX_Vpmovsxbd_ymm_k1z_xmmm64, EVEX_Vpmovsxbd_zmm_k1z_xmmm128, EVEX_Vpmovsdb_xmmm32_k1z_xmm, EVEX_Vpmovsdb_xmmm64_k1z_ymm, EVEX_Vpmovsdb_xmmm128_k1z_zmm, Pmovsxbq_xmm_xmmm16, VEX_Vpmovsxbq_xmm_xmmm16, VEX_Vpmovsxbq_ymm_xmmm32, EVEX_Vpmovsxbq_xmm_k1z_xmmm16, EVEX_Vpmovsxbq_ymm_k1z_xmmm32, EVEX_Vpmovsxbq_zmm_k1z_xmmm64, EVEX_Vpmovsqb_xmmm16_k1z_xmm, EVEX_Vpmovsqb_xmmm32_k1z_ymm, EVEX_Vpmovsqb_xmmm64_k1z_zmm, Pmovsxwd_xmm_xmmm64, VEX_Vpmovsxwd_xmm_xmmm64, VEX_Vpmovsxwd_ymm_xmmm128, EVEX_Vpmovsxwd_xmm_k1z_xmmm64, EVEX_Vpmovsxwd_ymm_k1z_xmmm128, EVEX_Vpmovsxwd_zmm_k1z_ymmm256, EVEX_Vpmovsdw_xmmm64_k1z_xmm, EVEX_Vpmovsdw_xmmm128_k1z_ymm, EVEX_Vpmovsdw_ymmm256_k1z_zmm, Pmovsxwq_xmm_xmmm32, VEX_Vpmovsxwq_xmm_xmmm32, VEX_Vpmovsxwq_ymm_xmmm64, EVEX_Vpmovsxwq_xmm_k1z_xmmm32, EVEX_Vpmovsxwq_ymm_k1z_xmmm64, EVEX_Vpmovsxwq_zmm_k1z_xmmm128, EVEX_Vpmovsqw_xmmm32_k1z_xmm, EVEX_Vpmovsqw_xmmm64_k1z_ymm, EVEX_Vpmovsqw_xmmm128_k1z_zmm, Pmovsxdq_xmm_xmmm64, VEX_Vpmovsxdq_xmm_xmmm64, VEX_Vpmovsxdq_ymm_xmmm128, EVEX_Vpmovsxdq_xmm_k1z_xmmm64, EVEX_Vpmovsxdq_ymm_k1z_xmmm128, EVEX_Vpmovsxdq_zmm_k1z_ymmm256, EVEX_Vpmovsqd_xmmm64_k1z_xmm, EVEX_Vpmovsqd_xmmm128_k1z_ymm, EVEX_Vpmovsqd_ymmm256_k1z_zmm, EVEX_Vptestmb_kr_k1_xmm_xmmm128, EVEX_Vptestmb_kr_k1_ymm_ymmm256, EVEX_Vptestmb_kr_k1_zmm_zmmm512, EVEX_Vptestmw_kr_k1_xmm_xmmm128, EVEX_Vptestmw_kr_k1_ymm_ymmm256, EVEX_Vptestmw_kr_k1_zmm_zmmm512, EVEX_Vptestnmb_kr_k1_xmm_xmmm128, EVEX_Vptestnmb_kr_k1_ymm_ymmm256, EVEX_Vptestnmb_kr_k1_zmm_zmmm512, EVEX_Vptestnmw_kr_k1_xmm_xmmm128, EVEX_Vptestnmw_kr_k1_ymm_ymmm256, EVEX_Vptestnmw_kr_k1_zmm_zmmm512, EVEX_Vptestmd_kr_k1_xmm_xmmm128b32, EVEX_Vptestmd_kr_k1_ymm_ymmm256b32, EVEX_Vptestmd_kr_k1_zmm_zmmm512b32, EVEX_Vptestmq_kr_k1_xmm_xmmm128b64, EVEX_Vptestmq_kr_k1_ymm_ymmm256b64, EVEX_Vptestmq_kr_k1_zmm_zmmm512b64, EVEX_Vptestnmd_kr_k1_xmm_xmmm128b32, EVEX_Vptestnmd_kr_k1_ymm_ymmm256b32, EVEX_Vptestnmd_kr_k1_zmm_zmmm512b32, EVEX_Vptestnmq_kr_k1_xmm_xmmm128b64, EVEX_Vptestnmq_kr_k1_ymm_ymmm256b64, EVEX_Vptestnmq_kr_k1_zmm_zmmm512b64, Pmuldq_xmm_xmmm128, VEX_Vpmuldq_xmm_xmm_xmmm128, VEX_Vpmuldq_ymm_ymm_ymmm256, EVEX_Vpmuldq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpmuldq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpmuldq_zmm_k1z_zmm_zmmm512b64, EVEX_Vpmovm2b_xmm_kr, EVEX_Vpmovm2b_ymm_kr, EVEX_Vpmovm2b_zmm_kr, EVEX_Vpmovm2w_xmm_kr, EVEX_Vpmovm2w_ymm_kr, EVEX_Vpmovm2w_zmm_kr, Pcmpeqq_xmm_xmmm128, VEX_Vpcmpeqq_xmm_xmm_xmmm128, VEX_Vpcmpeqq_ymm_ymm_ymmm256, EVEX_Vpcmpeqq_kr_k1_xmm_xmmm128b64, EVEX_Vpcmpeqq_kr_k1_ymm_ymmm256b64, EVEX_Vpcmpeqq_kr_k1_zmm_zmmm512b64, EVEX_Vpmovb2m_kr_xmm, EVEX_Vpmovb2m_kr_ymm, EVEX_Vpmovb2m_kr_zmm, EVEX_Vpmovw2m_kr_xmm, EVEX_Vpmovw2m_kr_ymm, EVEX_Vpmovw2m_kr_zmm, Movntdqa_xmm_m128, VEX_Vmovntdqa_xmm_m128, VEX_Vmovntdqa_ymm_m256, EVEX_Vmovntdqa_xmm_m128, EVEX_Vmovntdqa_ymm_m256, EVEX_Vmovntdqa_zmm_m512, EVEX_Vpbroadcastmb2q_xmm_kr, EVEX_Vpbroadcastmb2q_ymm_kr, EVEX_Vpbroadcastmb2q_zmm_kr, Packusdw_xmm_xmmm128, VEX_Vpackusdw_xmm_xmm_xmmm128, VEX_Vpackusdw_ymm_ymm_ymmm256, EVEX_Vpackusdw_xmm_k1z_xmm_xmmm128b32, EVEX_Vpackusdw_ymm_k1z_ymm_ymmm256b32, EVEX_Vpackusdw_zmm_k1z_zmm_zmmm512b32, VEX_Vmaskmovps_xmm_xmm_m128, VEX_Vmaskmovps_ymm_ymm_m256, EVEX_Vscalefps_xmm_k1z_xmm_xmmm128b32, EVEX_Vscalefps_ymm_k1z_ymm_ymmm256b32, EVEX_Vscalefps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vscalefpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vscalefpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vscalefpd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vmaskmovpd_xmm_xmm_m128, VEX_Vmaskmovpd_ymm_ymm_m256, EVEX_Vscalefss_xmm_k1z_xmm_xmmm32_er, EVEX_Vscalefsd_xmm_k1z_xmm_xmmm64_er, VEX_Vmaskmovps_m128_xmm_xmm, VEX_Vmaskmovps_m256_ymm_ymm, VEX_Vmaskmovpd_m128_xmm_xmm, VEX_Vmaskmovpd_m256_ymm_ymm, Pmovzxbw_xmm_xmmm64, VEX_Vpmovzxbw_xmm_xmmm64, VEX_Vpmovzxbw_ymm_xmmm128, EVEX_Vpmovzxbw_xmm_k1z_xmmm64, EVEX_Vpmovzxbw_ymm_k1z_xmmm128, EVEX_Vpmovzxbw_zmm_k1z_ymmm256, EVEX_Vpmovwb_xmmm64_k1z_xmm, EVEX_Vpmovwb_xmmm128_k1z_ymm, EVEX_Vpmovwb_ymmm256_k1z_zmm, Pmovzxbd_xmm_xmmm32, VEX_Vpmovzxbd_xmm_xmmm32, VEX_Vpmovzxbd_ymm_xmmm64, EVEX_Vpmovzxbd_xmm_k1z_xmmm32, EVEX_Vpmovzxbd_ymm_k1z_xmmm64, EVEX_Vpmovzxbd_zmm_k1z_xmmm128, EVEX_Vpmovdb_xmmm32_k1z_xmm, EVEX_Vpmovdb_xmmm64_k1z_ymm, EVEX_Vpmovdb_xmmm128_k1z_zmm, Pmovzxbq_xmm_xmmm16, VEX_Vpmovzxbq_xmm_xmmm16, VEX_Vpmovzxbq_ymm_xmmm32, EVEX_Vpmovzxbq_xmm_k1z_xmmm16, EVEX_Vpmovzxbq_ymm_k1z_xmmm32, EVEX_Vpmovzxbq_zmm_k1z_xmmm64, EVEX_Vpmovqb_xmmm16_k1z_xmm, EVEX_Vpmovqb_xmmm32_k1z_ymm, EVEX_Vpmovqb_xmmm64_k1z_zmm, Pmovzxwd_xmm_xmmm64, VEX_Vpmovzxwd_xmm_xmmm64, VEX_Vpmovzxwd_ymm_xmmm128, EVEX_Vpmovzxwd_xmm_k1z_xmmm64, EVEX_Vpmovzxwd_ymm_k1z_xmmm128, EVEX_Vpmovzxwd_zmm_k1z_ymmm256, EVEX_Vpmovdw_xmmm64_k1z_xmm, EVEX_Vpmovdw_xmmm128_k1z_ymm, EVEX_Vpmovdw_ymmm256_k1z_zmm, Pmovzxwq_xmm_xmmm32, VEX_Vpmovzxwq_xmm_xmmm32, VEX_Vpmovzxwq_ymm_xmmm64, EVEX_Vpmovzxwq_xmm_k1z_xmmm32, EVEX_Vpmovzxwq_ymm_k1z_xmmm64, EVEX_Vpmovzxwq_zmm_k1z_xmmm128, EVEX_Vpmovqw_xmmm32_k1z_xmm, EVEX_Vpmovqw_xmmm64_k1z_ymm, EVEX_Vpmovqw_xmmm128_k1z_zmm, Pmovzxdq_xmm_xmmm64, VEX_Vpmovzxdq_xmm_xmmm64, VEX_Vpmovzxdq_ymm_xmmm128, EVEX_Vpmovzxdq_xmm_k1z_xmmm64, EVEX_Vpmovzxdq_ymm_k1z_xmmm128, EVEX_Vpmovzxdq_zmm_k1z_ymmm256, EVEX_Vpmovqd_xmmm64_k1z_xmm, EVEX_Vpmovqd_xmmm128_k1z_ymm, EVEX_Vpmovqd_ymmm256_k1z_zmm, VEX_Vpermd_ymm_ymm_ymmm256, EVEX_Vpermd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpermd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpermq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpermq_zmm_k1z_zmm_zmmm512b64, Pcmpgtq_xmm_xmmm128, VEX_Vpcmpgtq_xmm_xmm_xmmm128, VEX_Vpcmpgtq_ymm_ymm_ymmm256, EVEX_Vpcmpgtq_kr_k1_xmm_xmmm128b64, EVEX_Vpcmpgtq_kr_k1_ymm_ymmm256b64, EVEX_Vpcmpgtq_kr_k1_zmm_zmmm512b64, Pminsb_xmm_xmmm128, VEX_Vpminsb_xmm_xmm_xmmm128, VEX_Vpminsb_ymm_ymm_ymmm256, EVEX_Vpminsb_xmm_k1z_xmm_xmmm128, EVEX_Vpminsb_ymm_k1z_ymm_ymmm256, EVEX_Vpminsb_zmm_k1z_zmm_zmmm512, EVEX_Vpmovm2d_xmm_kr, EVEX_Vpmovm2d_ymm_kr, EVEX_Vpmovm2d_zmm_kr, EVEX_Vpmovm2q_xmm_kr, EVEX_Vpmovm2q_ymm_kr, EVEX_Vpmovm2q_zmm_kr, Pminsd_xmm_xmmm128, VEX_Vpminsd_xmm_xmm_xmmm128, VEX_Vpminsd_ymm_ymm_ymmm256, EVEX_Vpminsd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpminsd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpminsd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpminsq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpminsq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpminsq_zmm_k1z_zmm_zmmm512b64, EVEX_Vpmovd2m_kr_xmm, EVEX_Vpmovd2m_kr_ymm, EVEX_Vpmovd2m_kr_zmm, EVEX_Vpmovq2m_kr_xmm, EVEX_Vpmovq2m_kr_ymm, EVEX_Vpmovq2m_kr_zmm, Pminuw_xmm_xmmm128, VEX_Vpminuw_xmm_xmm_xmmm128, VEX_Vpminuw_ymm_ymm_ymmm256, EVEX_Vpminuw_xmm_k1z_xmm_xmmm128, EVEX_Vpminuw_ymm_k1z_ymm_ymmm256, EVEX_Vpminuw_zmm_k1z_zmm_zmmm512, EVEX_Vpbroadcastmw2d_xmm_kr, EVEX_Vpbroadcastmw2d_ymm_kr, EVEX_Vpbroadcastmw2d_zmm_kr, Pminud_xmm_xmmm128, VEX_Vpminud_xmm_xmm_xmmm128, VEX_Vpminud_ymm_ymm_ymmm256, EVEX_Vpminud_xmm_k1z_xmm_xmmm128b32, EVEX_Vpminud_ymm_k1z_ymm_ymmm256b32, EVEX_Vpminud_zmm_k1z_zmm_zmmm512b32, EVEX_Vpminuq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpminuq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpminuq_zmm_k1z_zmm_zmmm512b64, Pmaxsb_xmm_xmmm128, VEX_Vpmaxsb_xmm_xmm_xmmm128, VEX_Vpmaxsb_ymm_ymm_ymmm256, EVEX_Vpmaxsb_xmm_k1z_xmm_xmmm128, EVEX_Vpmaxsb_ymm_k1z_ymm_ymmm256, EVEX_Vpmaxsb_zmm_k1z_zmm_zmmm512, Pmaxsd_xmm_xmmm128, VEX_Vpmaxsd_xmm_xmm_xmmm128, VEX_Vpmaxsd_ymm_ymm_ymmm256, EVEX_Vpmaxsd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpmaxsd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpmaxsd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpmaxsq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpmaxsq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpmaxsq_zmm_k1z_zmm_zmmm512b64, Pmaxuw_xmm_xmmm128, VEX_Vpmaxuw_xmm_xmm_xmmm128, VEX_Vpmaxuw_ymm_ymm_ymmm256, EVEX_Vpmaxuw_xmm_k1z_xmm_xmmm128, EVEX_Vpmaxuw_ymm_k1z_ymm_ymmm256, EVEX_Vpmaxuw_zmm_k1z_zmm_zmmm512, Pmaxud_xmm_xmmm128, VEX_Vpmaxud_xmm_xmm_xmmm128, VEX_Vpmaxud_ymm_ymm_ymmm256, EVEX_Vpmaxud_xmm_k1z_xmm_xmmm128b32, EVEX_Vpmaxud_ymm_k1z_ymm_ymmm256b32, EVEX_Vpmaxud_zmm_k1z_zmm_zmmm512b32, EVEX_Vpmaxuq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpmaxuq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpmaxuq_zmm_k1z_zmm_zmmm512b64, Pmulld_xmm_xmmm128, VEX_Vpmulld_xmm_xmm_xmmm128, VEX_Vpmulld_ymm_ymm_ymmm256, EVEX_Vpmulld_xmm_k1z_xmm_xmmm128b32, EVEX_Vpmulld_ymm_k1z_ymm_ymmm256b32, EVEX_Vpmulld_zmm_k1z_zmm_zmmm512b32, EVEX_Vpmullq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpmullq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpmullq_zmm_k1z_zmm_zmmm512b64, Phminposuw_xmm_xmmm128, VEX_Vphminposuw_xmm_xmmm128, EVEX_Vgetexpps_xmm_k1z_xmmm128b32, EVEX_Vgetexpps_ymm_k1z_ymmm256b32, EVEX_Vgetexpps_zmm_k1z_zmmm512b32_sae, EVEX_Vgetexppd_xmm_k1z_xmmm128b64, EVEX_Vgetexppd_ymm_k1z_ymmm256b64, EVEX_Vgetexppd_zmm_k1z_zmmm512b64_sae, EVEX_Vgetexpss_xmm_k1z_xmm_xmmm32_sae, EVEX_Vgetexpsd_xmm_k1z_xmm_xmmm64_sae, EVEX_Vplzcntd_xmm_k1z_xmmm128b32, EVEX_Vplzcntd_ymm_k1z_ymmm256b32, EVEX_Vplzcntd_zmm_k1z_zmmm512b32, EVEX_Vplzcntq_xmm_k1z_xmmm128b64, EVEX_Vplzcntq_ymm_k1z_ymmm256b64, EVEX_Vplzcntq_zmm_k1z_zmmm512b64, VEX_Vpsrlvd_xmm_xmm_xmmm128, VEX_Vpsrlvd_ymm_ymm_ymmm256, VEX_Vpsrlvq_xmm_xmm_xmmm128, VEX_Vpsrlvq_ymm_ymm_ymmm256, EVEX_Vpsrlvd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpsrlvd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpsrlvd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpsrlvq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpsrlvq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpsrlvq_zmm_k1z_zmm_zmmm512b64, VEX_Vpsravd_xmm_xmm_xmmm128, VEX_Vpsravd_ymm_ymm_ymmm256, EVEX_Vpsravd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpsravd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpsravd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpsravq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpsravq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpsravq_zmm_k1z_zmm_zmmm512b64, VEX_Vpsllvd_xmm_xmm_xmmm128, VEX_Vpsllvd_ymm_ymm_ymmm256, VEX_Vpsllvq_xmm_xmm_xmmm128, VEX_Vpsllvq_ymm_ymm_ymmm256, EVEX_Vpsllvd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpsllvd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpsllvd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpsllvq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpsllvq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpsllvq_zmm_k1z_zmm_zmmm512b64, EVEX_Vrcp14ps_xmm_k1z_xmmm128b32, EVEX_Vrcp14ps_ymm_k1z_ymmm256b32, EVEX_Vrcp14ps_zmm_k1z_zmmm512b32, EVEX_Vrcp14pd_xmm_k1z_xmmm128b64, EVEX_Vrcp14pd_ymm_k1z_ymmm256b64, EVEX_Vrcp14pd_zmm_k1z_zmmm512b64, EVEX_Vrcp14ss_xmm_k1z_xmm_xmmm32, EVEX_Vrcp14sd_xmm_k1z_xmm_xmmm64, EVEX_Vrsqrt14ps_xmm_k1z_xmmm128b32, EVEX_Vrsqrt14ps_ymm_k1z_ymmm256b32, EVEX_Vrsqrt14ps_zmm_k1z_zmmm512b32, EVEX_Vrsqrt14pd_xmm_k1z_xmmm128b64, EVEX_Vrsqrt14pd_ymm_k1z_ymmm256b64, EVEX_Vrsqrt14pd_zmm_k1z_zmmm512b64, EVEX_Vrsqrt14ss_xmm_k1z_xmm_xmmm32, EVEX_Vrsqrt14sd_xmm_k1z_xmm_xmmm64, EVEX_Vpdpbusd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpdpbusd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpdpbusd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpdpbusds_xmm_k1z_xmm_xmmm128b32, EVEX_Vpdpbusds_ymm_k1z_ymm_ymmm256b32, EVEX_Vpdpbusds_zmm_k1z_zmm_zmmm512b32, EVEX_Vpdpwssd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpdpwssd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpdpwssd_zmm_k1z_zmm_zmmm512b32, EVEX_Vdpbf16ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vdpbf16ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vdpbf16ps_zmm_k1z_zmm_zmmm512b32, EVEX_Vp4dpwssd_zmm_k1z_zmmp3_m128, EVEX_Vpdpwssds_xmm_k1z_xmm_xmmm128b32, EVEX_Vpdpwssds_ymm_k1z_ymm_ymmm256b32, EVEX_Vpdpwssds_zmm_k1z_zmm_zmmm512b32, EVEX_Vp4dpwssds_zmm_k1z_zmmp3_m128, EVEX_Vpopcntb_xmm_k1z_xmmm128, EVEX_Vpopcntb_ymm_k1z_ymmm256, EVEX_Vpopcntb_zmm_k1z_zmmm512, EVEX_Vpopcntw_xmm_k1z_xmmm128, EVEX_Vpopcntw_ymm_k1z_ymmm256, EVEX_Vpopcntw_zmm_k1z_zmmm512, EVEX_Vpopcntd_xmm_k1z_xmmm128b32, EVEX_Vpopcntd_ymm_k1z_ymmm256b32, EVEX_Vpopcntd_zmm_k1z_zmmm512b32, EVEX_Vpopcntq_xmm_k1z_xmmm128b64, EVEX_Vpopcntq_ymm_k1z_ymmm256b64, EVEX_Vpopcntq_zmm_k1z_zmmm512b64, VEX_Vpbroadcastd_xmm_xmmm32, VEX_Vpbroadcastd_ymm_xmmm32, EVEX_Vpbroadcastd_xmm_k1z_xmmm32, EVEX_Vpbroadcastd_ymm_k1z_xmmm32, EVEX_Vpbroadcastd_zmm_k1z_xmmm32, VEX_Vpbroadcastq_xmm_xmmm64, VEX_Vpbroadcastq_ymm_xmmm64, EVEX_Vbroadcasti32x2_xmm_k1z_xmmm64, EVEX_Vbroadcasti32x2_ymm_k1z_xmmm64, EVEX_Vbroadcasti32x2_zmm_k1z_xmmm64, EVEX_Vpbroadcastq_xmm_k1z_xmmm64, EVEX_Vpbroadcastq_ymm_k1z_xmmm64, EVEX_Vpbroadcastq_zmm_k1z_xmmm64, VEX_Vbroadcasti128_ymm_m128, EVEX_Vbroadcasti32x4_ymm_k1z_m128, EVEX_Vbroadcasti32x4_zmm_k1z_m128, EVEX_Vbroadcasti64x2_ymm_k1z_m128, EVEX_Vbroadcasti64x2_zmm_k1z_m128, EVEX_Vbroadcasti32x8_zmm_k1z_m256, EVEX_Vbroadcasti64x4_zmm_k1z_m256, EVEX_Vpexpandb_xmm_k1z_xmmm128, EVEX_Vpexpandb_ymm_k1z_ymmm256, EVEX_Vpexpandb_zmm_k1z_zmmm512, EVEX_Vpexpandw_xmm_k1z_xmmm128, EVEX_Vpexpandw_ymm_k1z_ymmm256, EVEX_Vpexpandw_zmm_k1z_zmmm512, EVEX_Vpcompressb_xmmm128_k1z_xmm, EVEX_Vpcompressb_ymmm256_k1z_ymm, EVEX_Vpcompressb_zmmm512_k1z_zmm, EVEX_Vpcompressw_xmmm128_k1z_xmm, EVEX_Vpcompressw_ymmm256_k1z_ymm, EVEX_Vpcompressw_zmmm512_k1z_zmm, EVEX_Vpblendmd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpblendmd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpblendmd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpblendmq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpblendmq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpblendmq_zmm_k1z_zmm_zmmm512b64, EVEX_Vblendmps_xmm_k1z_xmm_xmmm128b32, EVEX_Vblendmps_ymm_k1z_ymm_ymmm256b32, EVEX_Vblendmps_zmm_k1z_zmm_zmmm512b32, EVEX_Vblendmpd_xmm_k1z_xmm_xmmm128b64, EVEX_Vblendmpd_ymm_k1z_ymm_ymmm256b64, EVEX_Vblendmpd_zmm_k1z_zmm_zmmm512b64, EVEX_Vpblendmb_xmm_k1z_xmm_xmmm128, EVEX_Vpblendmb_ymm_k1z_ymm_ymmm256, EVEX_Vpblendmb_zmm_k1z_zmm_zmmm512, EVEX_Vpblendmw_xmm_k1z_xmm_xmmm128, EVEX_Vpblendmw_ymm_k1z_ymm_ymmm256, EVEX_Vpblendmw_zmm_k1z_zmm_zmmm512, EVEX_Vp2intersectd_kp1_xmm_xmmm128b32, EVEX_Vp2intersectd_kp1_ymm_ymmm256b32, EVEX_Vp2intersectd_kp1_zmm_zmmm512b32, EVEX_Vp2intersectq_kp1_xmm_xmmm128b64, EVEX_Vp2intersectq_kp1_ymm_ymmm256b64, EVEX_Vp2intersectq_kp1_zmm_zmmm512b64, EVEX_Vpshldvw_xmm_k1z_xmm_xmmm128, EVEX_Vpshldvw_ymm_k1z_ymm_ymmm256, EVEX_Vpshldvw_zmm_k1z_zmm_zmmm512, EVEX_Vpshldvd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpshldvd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpshldvd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpshldvq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpshldvq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpshldvq_zmm_k1z_zmm_zmmm512b64, EVEX_Vpshrdvw_xmm_k1z_xmm_xmmm128, EVEX_Vpshrdvw_ymm_k1z_ymm_ymmm256, EVEX_Vpshrdvw_zmm_k1z_zmm_zmmm512, EVEX_Vcvtneps2bf16_xmm_k1z_xmmm128b32, EVEX_Vcvtneps2bf16_xmm_k1z_ymmm256b32, EVEX_Vcvtneps2bf16_ymm_k1z_zmmm512b32, EVEX_Vcvtne2ps2bf16_xmm_k1z_xmm_xmmm128b32, EVEX_Vcvtne2ps2bf16_ymm_k1z_ymm_ymmm256b32, EVEX_Vcvtne2ps2bf16_zmm_k1z_zmm_zmmm512b32, EVEX_Vpshrdvd_xmm_k1z_xmm_xmmm128b32, EVEX_Vpshrdvd_ymm_k1z_ymm_ymmm256b32, EVEX_Vpshrdvd_zmm_k1z_zmm_zmmm512b32, EVEX_Vpshrdvq_xmm_k1z_xmm_xmmm128b64, EVEX_Vpshrdvq_ymm_k1z_ymm_ymmm256b64, EVEX_Vpshrdvq_zmm_k1z_zmm_zmmm512b64, EVEX_Vpermi2b_xmm_k1z_xmm_xmmm128, EVEX_Vpermi2b_ymm_k1z_ymm_ymmm256, EVEX_Vpermi2b_zmm_k1z_zmm_zmmm512, EVEX_Vpermi2w_xmm_k1z_xmm_xmmm128, EVEX_Vpermi2w_ymm_k1z_ymm_ymmm256, EVEX_Vpermi2w_zmm_k1z_zmm_zmmm512, EVEX_Vpermi2d_xmm_k1z_xmm_xmmm128b32, EVEX_Vpermi2d_ymm_k1z_ymm_ymmm256b32, EVEX_Vpermi2d_zmm_k1z_zmm_zmmm512b32, EVEX_Vpermi2q_xmm_k1z_xmm_xmmm128b64, EVEX_Vpermi2q_ymm_k1z_ymm_ymmm256b64, EVEX_Vpermi2q_zmm_k1z_zmm_zmmm512b64, EVEX_Vpermi2ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vpermi2ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vpermi2ps_zmm_k1z_zmm_zmmm512b32, EVEX_Vpermi2pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vpermi2pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vpermi2pd_zmm_k1z_zmm_zmmm512b64, VEX_Vpbroadcastb_xmm_xmmm8, VEX_Vpbroadcastb_ymm_xmmm8, EVEX_Vpbroadcastb_xmm_k1z_xmmm8, EVEX_Vpbroadcastb_ymm_k1z_xmmm8, EVEX_Vpbroadcastb_zmm_k1z_xmmm8, VEX_Vpbroadcastw_xmm_xmmm16, VEX_Vpbroadcastw_ymm_xmmm16, EVEX_Vpbroadcastw_xmm_k1z_xmmm16, EVEX_Vpbroadcastw_ymm_k1z_xmmm16, EVEX_Vpbroadcastw_zmm_k1z_xmmm16, EVEX_Vpbroadcastb_xmm_k1z_r32, EVEX_Vpbroadcastb_ymm_k1z_r32, EVEX_Vpbroadcastb_zmm_k1z_r32, EVEX_Vpbroadcastw_xmm_k1z_r32, EVEX_Vpbroadcastw_ymm_k1z_r32, EVEX_Vpbroadcastw_zmm_k1z_r32, EVEX_Vpbroadcastd_xmm_k1z_r32, EVEX_Vpbroadcastd_ymm_k1z_r32, EVEX_Vpbroadcastd_zmm_k1z_r32, EVEX_Vpbroadcastq_xmm_k1z_r64, EVEX_Vpbroadcastq_ymm_k1z_r64, EVEX_Vpbroadcastq_zmm_k1z_r64, EVEX_Vpermt2b_xmm_k1z_xmm_xmmm128, EVEX_Vpermt2b_ymm_k1z_ymm_ymmm256, EVEX_Vpermt2b_zmm_k1z_zmm_zmmm512, EVEX_Vpermt2w_xmm_k1z_xmm_xmmm128, EVEX_Vpermt2w_ymm_k1z_ymm_ymmm256, EVEX_Vpermt2w_zmm_k1z_zmm_zmmm512, EVEX_Vpermt2d_xmm_k1z_xmm_xmmm128b32, EVEX_Vpermt2d_ymm_k1z_ymm_ymmm256b32, EVEX_Vpermt2d_zmm_k1z_zmm_zmmm512b32, EVEX_Vpermt2q_xmm_k1z_xmm_xmmm128b64, EVEX_Vpermt2q_ymm_k1z_ymm_ymmm256b64, EVEX_Vpermt2q_zmm_k1z_zmm_zmmm512b64, EVEX_Vpermt2ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vpermt2ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vpermt2ps_zmm_k1z_zmm_zmmm512b32, EVEX_Vpermt2pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vpermt2pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vpermt2pd_zmm_k1z_zmm_zmmm512b64, Invept_r32_m128, Invept_r64_m128, Invvpid_r32_m128, Invvpid_r64_m128, Invpcid_r32_m128, Invpcid_r64_m128, EVEX_Vpmultishiftqb_xmm_k1z_xmm_xmmm128b64, EVEX_Vpmultishiftqb_ymm_k1z_ymm_ymmm256b64, EVEX_Vpmultishiftqb_zmm_k1z_zmm_zmmm512b64, EVEX_Vexpandps_xmm_k1z_xmmm128, EVEX_Vexpandps_ymm_k1z_ymmm256, EVEX_Vexpandps_zmm_k1z_zmmm512, EVEX_Vexpandpd_xmm_k1z_xmmm128, EVEX_Vexpandpd_ymm_k1z_ymmm256, EVEX_Vexpandpd_zmm_k1z_zmmm512, EVEX_Vpexpandd_xmm_k1z_xmmm128, EVEX_Vpexpandd_ymm_k1z_ymmm256, EVEX_Vpexpandd_zmm_k1z_zmmm512, EVEX_Vpexpandq_xmm_k1z_xmmm128, EVEX_Vpexpandq_ymm_k1z_ymmm256, EVEX_Vpexpandq_zmm_k1z_zmmm512, EVEX_Vcompressps_xmmm128_k1z_xmm, EVEX_Vcompressps_ymmm256_k1z_ymm, EVEX_Vcompressps_zmmm512_k1z_zmm, EVEX_Vcompresspd_xmmm128_k1z_xmm, EVEX_Vcompresspd_ymmm256_k1z_ymm, EVEX_Vcompresspd_zmmm512_k1z_zmm, EVEX_Vpcompressd_xmmm128_k1z_xmm, EVEX_Vpcompressd_ymmm256_k1z_ymm, EVEX_Vpcompressd_zmmm512_k1z_zmm, EVEX_Vpcompressq_xmmm128_k1z_xmm, EVEX_Vpcompressq_ymmm256_k1z_ymm, EVEX_Vpcompressq_zmmm512_k1z_zmm, VEX_Vpmaskmovd_xmm_xmm_m128, VEX_Vpmaskmovd_ymm_ymm_m256, VEX_Vpmaskmovq_xmm_xmm_m128, VEX_Vpmaskmovq_ymm_ymm_m256, EVEX_Vpermb_xmm_k1z_xmm_xmmm128, EVEX_Vpermb_ymm_k1z_ymm_ymmm256, EVEX_Vpermb_zmm_k1z_zmm_zmmm512, EVEX_Vpermw_xmm_k1z_xmm_xmmm128, EVEX_Vpermw_ymm_k1z_ymm_ymmm256, EVEX_Vpermw_zmm_k1z_zmm_zmmm512, VEX_Vpmaskmovd_m128_xmm_xmm, VEX_Vpmaskmovd_m256_ymm_ymm, VEX_Vpmaskmovq_m128_xmm_xmm, VEX_Vpmaskmovq_m256_ymm_ymm, EVEX_Vpshufbitqmb_kr_k1_xmm_xmmm128, EVEX_Vpshufbitqmb_kr_k1_ymm_ymmm256, EVEX_Vpshufbitqmb_kr_k1_zmm_zmmm512, VEX_Vpgatherdd_xmm_vm32x_xmm, VEX_Vpgatherdd_ymm_vm32y_ymm, VEX_Vpgatherdq_xmm_vm32x_xmm, VEX_Vpgatherdq_ymm_vm32x_ymm, EVEX_Vpgatherdd_xmm_k1_vm32x, EVEX_Vpgatherdd_ymm_k1_vm32y, EVEX_Vpgatherdd_zmm_k1_vm32z, EVEX_Vpgatherdq_xmm_k1_vm32x, EVEX_Vpgatherdq_ymm_k1_vm32x, EVEX_Vpgatherdq_zmm_k1_vm32y, VEX_Vpgatherqd_xmm_vm64x_xmm, VEX_Vpgatherqd_xmm_vm64y_xmm, VEX_Vpgatherqq_xmm_vm64x_xmm, VEX_Vpgatherqq_ymm_vm64y_ymm, EVEX_Vpgatherqd_xmm_k1_vm64x, EVEX_Vpgatherqd_xmm_k1_vm64y, EVEX_Vpgatherqd_ymm_k1_vm64z, EVEX_Vpgatherqq_xmm_k1_vm64x, EVEX_Vpgatherqq_ymm_k1_vm64y, EVEX_Vpgatherqq_zmm_k1_vm64z, VEX_Vgatherdps_xmm_vm32x_xmm, VEX_Vgatherdps_ymm_vm32y_ymm, VEX_Vgatherdpd_xmm_vm32x_xmm, VEX_Vgatherdpd_ymm_vm32x_ymm, EVEX_Vgatherdps_xmm_k1_vm32x, EVEX_Vgatherdps_ymm_k1_vm32y, EVEX_Vgatherdps_zmm_k1_vm32z, EVEX_Vgatherdpd_xmm_k1_vm32x, EVEX_Vgatherdpd_ymm_k1_vm32x, EVEX_Vgatherdpd_zmm_k1_vm32y, VEX_Vgatherqps_xmm_vm64x_xmm, VEX_Vgatherqps_xmm_vm64y_xmm, VEX_Vgatherqpd_xmm_vm64x_xmm, VEX_Vgatherqpd_ymm_vm64y_ymm, EVEX_Vgatherqps_xmm_k1_vm64x, EVEX_Vgatherqps_xmm_k1_vm64y, EVEX_Vgatherqps_ymm_k1_vm64z, EVEX_Vgatherqpd_xmm_k1_vm64x, EVEX_Vgatherqpd_ymm_k1_vm64y, EVEX_Vgatherqpd_zmm_k1_vm64z, VEX_Vfmaddsub132ps_xmm_xmm_xmmm128, VEX_Vfmaddsub132ps_ymm_ymm_ymmm256, VEX_Vfmaddsub132pd_xmm_xmm_xmmm128, VEX_Vfmaddsub132pd_ymm_ymm_ymmm256, EVEX_Vfmaddsub132ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfmaddsub132ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfmaddsub132ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfmaddsub132pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfmaddsub132pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfmaddsub132pd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vfmsubadd132ps_xmm_xmm_xmmm128, VEX_Vfmsubadd132ps_ymm_ymm_ymmm256, VEX_Vfmsubadd132pd_xmm_xmm_xmmm128, VEX_Vfmsubadd132pd_ymm_ymm_ymmm256, EVEX_Vfmsubadd132ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfmsubadd132ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfmsubadd132ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfmsubadd132pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfmsubadd132pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfmsubadd132pd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vfmadd132ps_xmm_xmm_xmmm128, VEX_Vfmadd132ps_ymm_ymm_ymmm256, VEX_Vfmadd132pd_xmm_xmm_xmmm128, VEX_Vfmadd132pd_ymm_ymm_ymmm256, EVEX_Vfmadd132ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfmadd132ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfmadd132ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfmadd132pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfmadd132pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfmadd132pd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vfmadd132ss_xmm_xmm_xmmm32, VEX_Vfmadd132sd_xmm_xmm_xmmm64, EVEX_Vfmadd132ss_xmm_k1z_xmm_xmmm32_er, EVEX_Vfmadd132sd_xmm_k1z_xmm_xmmm64_er, VEX_Vfmsub132ps_xmm_xmm_xmmm128, VEX_Vfmsub132ps_ymm_ymm_ymmm256, VEX_Vfmsub132pd_xmm_xmm_xmmm128, VEX_Vfmsub132pd_ymm_ymm_ymmm256, EVEX_Vfmsub132ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfmsub132ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfmsub132ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfmsub132pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfmsub132pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfmsub132pd_zmm_k1z_zmm_zmmm512b64_er, EVEX_V4fmaddps_zmm_k1z_zmmp3_m128, VEX_Vfmsub132ss_xmm_xmm_xmmm32, VEX_Vfmsub132sd_xmm_xmm_xmmm64, EVEX_Vfmsub132ss_xmm_k1z_xmm_xmmm32_er, EVEX_Vfmsub132sd_xmm_k1z_xmm_xmmm64_er, EVEX_V4fmaddss_xmm_k1z_xmmp3_m128, VEX_Vfnmadd132ps_xmm_xmm_xmmm128, VEX_Vfnmadd132ps_ymm_ymm_ymmm256, VEX_Vfnmadd132pd_xmm_xmm_xmmm128, VEX_Vfnmadd132pd_ymm_ymm_ymmm256, EVEX_Vfnmadd132ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfnmadd132ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfnmadd132ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfnmadd132pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfnmadd132pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfnmadd132pd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vfnmadd132ss_xmm_xmm_xmmm32, VEX_Vfnmadd132sd_xmm_xmm_xmmm64, EVEX_Vfnmadd132ss_xmm_k1z_xmm_xmmm32_er, EVEX_Vfnmadd132sd_xmm_k1z_xmm_xmmm64_er, VEX_Vfnmsub132ps_xmm_xmm_xmmm128, VEX_Vfnmsub132ps_ymm_ymm_ymmm256, VEX_Vfnmsub132pd_xmm_xmm_xmmm128, VEX_Vfnmsub132pd_ymm_ymm_ymmm256, EVEX_Vfnmsub132ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfnmsub132ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfnmsub132ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfnmsub132pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfnmsub132pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfnmsub132pd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vfnmsub132ss_xmm_xmm_xmmm32, VEX_Vfnmsub132sd_xmm_xmm_xmmm64, EVEX_Vfnmsub132ss_xmm_k1z_xmm_xmmm32_er, EVEX_Vfnmsub132sd_xmm_k1z_xmm_xmmm64_er, EVEX_Vpscatterdd_vm32x_k1_xmm, EVEX_Vpscatterdd_vm32y_k1_ymm, EVEX_Vpscatterdd_vm32z_k1_zmm, EVEX_Vpscatterdq_vm32x_k1_xmm, EVEX_Vpscatterdq_vm32x_k1_ymm, EVEX_Vpscatterdq_vm32y_k1_zmm, EVEX_Vpscatterqd_vm64x_k1_xmm, EVEX_Vpscatterqd_vm64y_k1_xmm, EVEX_Vpscatterqd_vm64z_k1_ymm, EVEX_Vpscatterqq_vm64x_k1_xmm, EVEX_Vpscatterqq_vm64y_k1_ymm, EVEX_Vpscatterqq_vm64z_k1_zmm, EVEX_Vscatterdps_vm32x_k1_xmm, EVEX_Vscatterdps_vm32y_k1_ymm, EVEX_Vscatterdps_vm32z_k1_zmm, EVEX_Vscatterdpd_vm32x_k1_xmm, EVEX_Vscatterdpd_vm32x_k1_ymm, EVEX_Vscatterdpd_vm32y_k1_zmm, EVEX_Vscatterqps_vm64x_k1_xmm, EVEX_Vscatterqps_vm64y_k1_xmm, EVEX_Vscatterqps_vm64z_k1_ymm, EVEX_Vscatterqpd_vm64x_k1_xmm, EVEX_Vscatterqpd_vm64y_k1_ymm, EVEX_Vscatterqpd_vm64z_k1_zmm, VEX_Vfmaddsub213ps_xmm_xmm_xmmm128, VEX_Vfmaddsub213ps_ymm_ymm_ymmm256, VEX_Vfmaddsub213pd_xmm_xmm_xmmm128, VEX_Vfmaddsub213pd_ymm_ymm_ymmm256, EVEX_Vfmaddsub213ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfmaddsub213ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfmaddsub213ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfmaddsub213pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfmaddsub213pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfmaddsub213pd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vfmsubadd213ps_xmm_xmm_xmmm128, VEX_Vfmsubadd213ps_ymm_ymm_ymmm256, VEX_Vfmsubadd213pd_xmm_xmm_xmmm128, VEX_Vfmsubadd213pd_ymm_ymm_ymmm256, EVEX_Vfmsubadd213ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfmsubadd213ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfmsubadd213ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfmsubadd213pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfmsubadd213pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfmsubadd213pd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vfmadd213ps_xmm_xmm_xmmm128, VEX_Vfmadd213ps_ymm_ymm_ymmm256, VEX_Vfmadd213pd_xmm_xmm_xmmm128, VEX_Vfmadd213pd_ymm_ymm_ymmm256, EVEX_Vfmadd213ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfmadd213ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfmadd213ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfmadd213pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfmadd213pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfmadd213pd_zmm_k1z_zmm_zmmm512b64_er, VEX_Vfmadd213ss_xmm_xmm_xmmm32, VEX_Vfmadd213sd_xmm_xmm_xmmm64, EVEX_Vfmadd213ss_xmm_k1z_xmm_xmmm32_er, EVEX_Vfmadd213sd_xmm_k1z_xmm_xmmm64_er, VEX_Vfmsub213ps_xmm_xmm_xmmm128, VEX_Vfmsub213ps_ymm_ymm_ymmm256, VEX_Vfmsub213pd_xmm_xmm_xmmm128, VEX_Vfmsub213pd_ymm_ymm_ymmm256, EVEX_Vfmsub213ps_xmm_k1z_xmm_xmmm128b32, EVEX_Vfmsub213ps_ymm_k1z_ymm_ymmm256b32, EVEX_Vfmsub213ps_zmm_k1z_zmm_zmmm512b32_er, EVEX_Vfmsub213pd_xmm_k1z_xmm_xmmm128b64, EVEX_Vfmsub213pd_ymm_k1z_ymm_ymmm256b64, EVEX_Vfmsub213pd_zmm_k1z_zmm_zmmm512b64_er, EVEX_V4fnmaddps_zmm_k1z_zmmp3_m128,
BepInExPack/BepInEx/core/MonoMod.ILHelpers.dll
Decompiled a day agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis; using MonoMod.Backports.ILHelpers; [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: CLSCompliant(false)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyTitle("MonoMod.ILHelpers")] [assembly: AssemblyCompany("0x0ade, DaNike")] [assembly: AssemblyDescription("Package Description")] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("IsTrimmable", "True")] [assembly: AssemblyCopyright("Copyright 2024 0x0ade, DaNike")] [assembly: AssemblyVersion("1.1.0.0")] [assembly: TypeForwardedTo(typeof(Unsafe))] [assembly: TypeForwardedTo(typeof(UnsafeRaw))] namespace System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class NonVersionableAttribute : Attribute { } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] A_0) { TransformFlags = A_0; } } [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [CompilerGenerated] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte A_0) { NullableFlags = new byte[1] { A_0 }; } public NullableAttribute(byte[] A_0) { NullableFlags = A_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte A_0) { Flag = A_0; } } } namespace MonoMod { public static class ILHelpers { [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static T TailCallDelegatePtr<T>(IntPtr source) { return ((delegate*<T>)source)(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T TailCallFunc<T>(Func<T> func) { return func(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static ref T ObjectAsRef<T>(object obj) { fixed (object obj2 = obj) { return ref *(T*)(nuint)obj2; } } } }
BepInExPack/BepInEx/core/MonoMod.RuntimeDetour.dll
Decompiled a day 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.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod; using MonoMod.Cil; using MonoMod.Core; using MonoMod.Core.Platforms; using MonoMod.Logs; using MonoMod.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CLSCompliant(true)] [assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] [assembly: AssemblyCompany("0x0ade, DaNike")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2026 0x0ade, DaNike")] [assembly: AssemblyDescription("Flexible and easily extensible runtime detouring library. Wrap, replace and manipulate (Mono.Cecil) methods at runtime.")] [assembly: AssemblyFileVersion("25.3.4.0")] [assembly: AssemblyInformationalVersion("25.3.4+69fdc9deb")] [assembly: AssemblyProduct("MonoMod.RuntimeDetour")] [assembly: AssemblyTitle("MonoMod.RuntimeDetour")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoMod/MonoMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("25.3.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { MMDbgLog.LogVersion(); } } namespace MonoMod { internal static class MMDbgLog { [InterpolatedStringHandler] internal ref struct DebugLogSpamStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogSpamStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)0, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogTraceStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogTraceStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)1, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogInfoStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogInfoStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)2, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogWarningStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogWarningStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)3, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogErrorStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogErrorStringHandler(int literalLen, int formattedCount, out bool isEnabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, (LogLevel)4, ref isEnabled); } public override string ToString() { return ((object)Unsafe.As<DebugLogInterpolatedStringHandler, DebugLogInterpolatedStringHandler>(ref handler)/*cast due to .constrained prefix*/).ToString(); } public string ToStringAndClear() { return ((DebugLogInterpolatedStringHandler)(ref handler)).ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { ((DebugLogInterpolatedStringHandler)(ref handler)).AppendFormatted<T>(value, alignment, format); } } public static bool IsWritingLog => DebugLog.IsWritingLog; [ModuleInitializer] internal static void LogVersion() { Info("Version 25.3.4"); } public static void Log(LogLevel level, string message) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) DebugLog.Log("MonoMod.RuntimeDetour", level, message); } public static void Log(LogLevel level, [InterpolatedStringHandlerArgument("level")] ref DebugLogInterpolatedStringHandler message) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) DebugLog.Log("MonoMod.RuntimeDetour", level, ref message); } public static void Spam(string message) { Log((LogLevel)0, message); } public static void Spam(ref DebugLogSpamStringHandler message) { Log((LogLevel)0, ref message.handler); } public static void Trace(string message) { Log((LogLevel)1, message); } public static void Trace(ref DebugLogTraceStringHandler message) { Log((LogLevel)1, ref message.handler); } public static void Info(string message) { Log((LogLevel)2, message); } public static void Info(ref DebugLogInfoStringHandler message) { Log((LogLevel)2, ref message.handler); } public static void Warning(string message) { Log((LogLevel)3, message); } public static void Warning(ref DebugLogWarningStringHandler message) { Log((LogLevel)3, ref message.handler); } public static void Error(string message) { Log((LogLevel)4, message); } public static void Error(ref DebugLogErrorStringHandler message) { Log((LogLevel)4, ref message.handler); } } internal static class MultiTargetShims { public static TypeReference GetConstraintType(this GenericParameterConstraint constraint) { return constraint.ConstraintType; } } } namespace MonoMod.SourceGen.Attributes { [AttributeUsage(AttributeTargets.Class)] internal sealed class EmitILOverloadsAttribute : Attribute { public EmitILOverloadsAttribute(string filename, string kind) { } } internal static class ILOverloadKind { public const string Cursor = "ILCursor"; public const string Matcher = "ILMatcher"; } } namespace MonoMod.RuntimeDetour { public class DetourConfig { public string Id { get; } public int? Priority { get; } public IEnumerable<string> Before { get; } public IEnumerable<string> After { get; } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public int SubPriority { get; } public DetourConfig(string id, int? priority = null, IEnumerable<string>? before = null, IEnumerable<string>? after = null) : this(id, priority, before, after, 0) { } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public DetourConfig(string id, int? priority, IEnumerable<string>? before, IEnumerable<string>? after, int subPriority) { Id = id; Priority = priority; Before = AsFixedSize(before ?? Enumerable.Empty<string>()); After = AsFixedSize(after ?? Enumerable.Empty<string>()); SubPriority = subPriority; } 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 DetourConfig WithPriority(int? priority) { return new DetourConfig(Id, priority, Before, After, SubPriority); } public DetourConfig WithBefore(IEnumerable<string> before) { return new DetourConfig(Id, Priority, before, After, SubPriority); } public DetourConfig WithBefore(params string[] before) { return WithBefore(before.AsEnumerable()); } public DetourConfig WithAfter(IEnumerable<string> after) { return new DetourConfig(Id, Priority, Before, after, SubPriority); } public DetourConfig WithAfter(params string[] after) { return WithAfter(after.AsEnumerable()); } public DetourConfig AddBefore(IEnumerable<string> before) { return WithBefore(Before.Concat(before)); } public DetourConfig AddBefore(params string[] before) { return AddBefore(before.AsEnumerable()); } public DetourConfig AddAfter(IEnumerable<string> after) { return WithAfter(After.Concat(after)); } public DetourConfig AddAfter(params string[] after) { return AddAfter(after.AsEnumerable()); } } public abstract class DetourContext { private sealed class Scope { public readonly DetourContext Context; public readonly Scope? Prev; public bool Active = true; public Scope(DetourContext context, Scope? prev) { Context = context; Prev = prev; } } private sealed class ContextScopeHandler : ScopeHandlerBase { public static readonly ContextScopeHandler Instance = new ContextScopeHandler(); public override void EndScope(object? data) { ((Scope)data).Active = false; while (true) { Scope current = DetourContext.current; if (current != null && !current.Active) { DetourContext.current = DetourContext.current.Prev; continue; } break; } } } private static DetourContext? globalCurrent; [ThreadStatic] private static Scope? current; public static DetourContext? Current { get { Scope prev = current; while (prev != null && !prev.Active) { prev = prev.Prev; } return prev?.Context ?? globalCurrent; } } public DetourConfig? Config { get { if (!TryGetConfig(out DetourConfig config)) { return null; } return config; } } public static DetourConfig? CurrentConfig { get { if (!TryGetCurrentConfig(out DetourConfig config)) { return null; } return config; } } public IDetourFactory? Factory { get { if (!TryGetFactory(out IDetourFactory detourFactory)) { return null; } return detourFactory; } } public static IDetourFactory? CurrentFactory { get { if (!TryGetCurrentFactory(out IDetourFactory detourFactory)) { return null; } return detourFactory; } } [EditorBrowsable(EditorBrowsableState.Advanced)] public static DetourContext? SetGlobalContext(DetourContext? context) { return Interlocked.Exchange(ref globalCurrent, context); } private static DataScope PushContext(DetourContext ctx) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) current = new Scope(ctx, current); return new DataScope((ScopeHandlerBase)(object)ContextScopeHandler.Instance, (object)current); } [CLSCompliant(false)] public DataScope Use() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return PushContext(this); } public static DetourConfig? GetDefaultConfig() { if (!TryGetCurrentConfig(out DetourConfig config)) { return null; } return config; } public static IDetourFactory GetDefaultFactory() { if (!TryGetCurrentFactory(out IDetourFactory detourFactory)) { return DetourFactory.Current; } return detourFactory; } protected abstract bool TryGetConfig(out DetourConfig? config); public static bool TryGetCurrentConfig(out DetourConfig? config) { for (Scope prev = current; prev != null; prev = prev.Prev) { if (prev.Active && prev.Context.TryGetConfig(out config)) { return true; } } DetourContext detourContext = globalCurrent; if (detourContext != null && detourContext.TryGetConfig(out config)) { return true; } config = null; return false; } protected abstract bool TryGetFactory([MaybeNullWhen(false)] out IDetourFactory detourFactory); public static bool TryGetCurrentFactory([MaybeNullWhen(false)] out IDetourFactory detourFactory) { for (Scope prev = current; prev != null; prev = prev.Prev) { if (prev.Context.TryGetFactory(out detourFactory)) { return true; } } DetourContext detourContext = globalCurrent; if (detourContext != null && detourContext.TryGetFactory(out detourFactory)) { return true; } detourFactory = null; return false; } } public abstract class EmptyDetourContext : DetourContext { protected override bool TryGetConfig(out DetourConfig? config) { config = null; return false; } protected override bool TryGetFactory([MaybeNullWhen(false)] out IDetourFactory detourFactory) { detourFactory = null; return false; } } public class DetourConfigContext : EmptyDetourContext { private readonly DetourConfig? cfg; public DetourConfigContext(DetourConfig? cfg) { this.cfg = cfg; } protected override bool TryGetConfig(out DetourConfig? config) { config = cfg; return true; } } public class DetourFactoryContext : EmptyDetourContext { private readonly IDetourFactory fac; public DetourFactoryContext(IDetourFactory fac) { this.fac = fac; } protected override bool TryGetFactory([MaybeNullWhen(false)] out IDetourFactory detourFactory) { detourFactory = fac; return true; } } public static class DetourManager { internal abstract class ManagedChainNode { public ManagedChainNode? Next; private MethodBase? lastTarget; private ICoreDetour? trampolineDetour; private bool hasStolenTrampoline; public abstract MethodBase Entry { get; } public abstract MethodBase NextTrampoline { get; } public abstract DetourConfig? Config { get; } public virtual bool DetourToFallback => true; public bool IsApplied { get; private set; } private void UndoTrampolineDetour() { ICoreDetour val = Interlocked.Exchange(ref trampolineDetour, null); if (val != null) { ((ICoreDetourBase)val).Undo(); ((IDisposable)val).Dispose(); } } public virtual void UpdateDetour(IDetourFactory factory, MethodBase fallback) { MethodBase methodBase = Next?.Entry; if ((object)methodBase == null && DetourToFallback) { methodBase = fallback; } if (!(methodBase == lastTarget)) { UndoTrampolineDetour(); if ((object)methodBase != null) { trampolineDetour = DetourFactory.CreateDetour(factory, NextTrampoline, methodBase, true); } lastTarget = methodBase; IsApplied = true; } } public void Remove() { if (!hasStolenTrampoline) { UndoTrampolineDetour(); } lastTarget = null; Next = null; IsApplied = false; } public void StealTrampoline(IDetourFactory factory) { Helpers.Assert(!hasStolenTrampoline, (string)null, "!hasStolenTrampoline"); StealTrampolineInner(); hasStolenTrampoline = true; UndoTrampolineDetour(); trampolineDetour = DetourFactory.CreateDetour(factory, NextTrampoline, (MethodBase)GetRemovedStub(MethodSignature.ForMethod(NextTrampoline)), true); } protected virtual void StealTrampolineInner() { throw new NotSupportedException("Can't steal ManagedChainNode trampoline"); } public virtual void ReturnStolenTrampoline() { Helpers.Assert(hasStolenTrampoline, (string)null, "hasStolenTrampoline"); UndoTrampolineDetour(); ReturnStolenTrampolineInner(); hasStolenTrampoline = false; } protected virtual void ReturnStolenTrampolineInner() { throw new NotSupportedException("Can't steal ManagedChainNode trampoline"); } } internal sealed class ManagedDetourChainNode : ManagedChainNode { public readonly SingleManagedDetourState Detour; public override MethodBase Entry => Detour.InvokeTarget; public override MethodBase NextTrampoline => Detour.NextTrampoline.TrampolineMethod; public override DetourConfig? Config => Detour.Config; public IDetourFactory Factory => Detour.Factory; public ManagedDetourChainNode(SingleManagedDetourState detour) { Detour = detour; } protected override void StealTrampolineInner() { Detour.NextTrampoline.StealTrampolineOwnership(); } protected override void ReturnStolenTrampolineInner() { Detour.NextTrampoline.ReturnTrampolineOwnership(); } } internal sealed class ManagedDetourSyncInfo : DetourSyncInfo { public int HasStolenTrampolines; public readonly ConcurrentQueue<ManagedChainNode> TrampolineStealers = new ConcurrentQueue<ManagedChainNode>(); public void StealTrampoline(IDetourFactory factory, ManagedChainNode node) { node.StealTrampoline(factory); TrampolineStealers.Enqueue(node); Volatile.Write(ref HasStolenTrampolines, 1); } public void ReturnStolenTrampolines() { if (Interlocked.CompareExchange(ref HasStolenTrampolines, 0, 1) == 1) { ManagedChainNode result; while (TrampolineStealers.TryDequeue(out result)) { result.ReturnStolenTrampoline(); } } } } internal sealed class RootManagedChainNode : ManagedChainNode { public readonly MethodSignature Sig; public readonly ManagedDetourSyncInfo SyncInfo = new ManagedDetourSyncInfo(); public readonly ConcurrentQueue<Action> StolenTrampolineReturners = new ConcurrentQueue<Action>(); private readonly DataScope<DynamicReferenceCell> syncProxyRefScope; public bool HasILHook; private ICoreDetour? syncDetour; private MethodInfo? sourceClone; private DynamicMethodDefinition? sourceCloneIl; public override MethodBase Entry { get; } public override MethodBase NextTrampoline { get; } public override DetourConfig? Config => null; public override bool DetourToFallback => true; public RootManagedChainNode(MethodBase method) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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) Sig = MethodSignature.ForMethod(method); Entry = method; NextTrampoline = TrampolinePool.Rent(Sig); DataScope<DynamicReferenceCell> refScope = default(DataScope<DynamicReferenceCell>); ManagedDetourSyncInfo syncInfo = SyncInfo; FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val))..ctor(0, 1); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<MethodBase>(Entry); syncInfo.SyncProxy = GenerateSyncProxy(DebugFormatter.Format(ref val), Sig, delegate(MethodDefinition val3, ILProcessor il) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) DynamicReferenceCell val2 = default(DynamicReferenceCell); refScope = DynamicReferenceManager.EmitNewTypedReference<ManagedDetourSyncInfo>(il, SyncInfo, ref val2); }, delegate(MethodDefinition val2, ILProcessor il, Action loadSyncInfo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Enumerator<ParameterDefinition> enumerator = ((MethodReference)val2).Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; il.Emit(OpCodes.Ldarg, current); } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } il.Emit(OpCodes.Call, ((MemberReference)val2).Module.ImportReference(NextTrampoline)); }, delegate(MethodDefinition val2, ILProcessor il, Action loadSyncInfo) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) loadSyncInfo(); Extensions.Emit(il, OpCodes.Call, (MethodBase)ManagedDetourSyncInfo_ReturnStolenTrampolines); }); syncProxyRefScope = refScope; } public override void UpdateDetour(IDetourFactory factory, MethodBase fallback) { base.UpdateDetour(factory, fallback); Helpers.Assert(syncDetour != null, (string)null, "syncDetour is not null"); if (!HasILHook && Next == null && ((ICoreDetourBase)syncDetour).IsApplied) { ((ICoreDetourBase)syncDetour).Undo(); ((IDisposable)syncDetour).Dispose(); syncDetour = null; } else if ((HasILHook || Next != null) && !((ICoreDetourBase)syncDetour).IsApplied) { ((ICoreDetourBase)syncDetour).Apply(); } } public void PrepareDetour(IDetourFactory factory, out MethodInfo sourceClone, out DynamicMethodDefinition? sourceCloneIl) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00a8: Expected O, but got Unknown if (syncDetour == null) { CreateDetourRequest val = default(CreateDetourRequest); ((CreateDetourRequest)(ref val))..ctor(Entry, SyncInfo.SyncProxy); ((CreateDetourRequest)(ref val)).set_ApplyByDefault(false); ((CreateDetourRequest)(ref val)).set_CreateSourceCloneIfNotILClone(true); ICoreDetour? obj = (syncDetour = factory.CreateDetour(val)); ICoreDetourWithClone val2 = (ICoreDetourWithClone)(object)((obj is ICoreDetourWithClone) ? obj : null); if (val2 != null) { MethodInfo sourceMethodClone = val2.SourceMethodClone; if ((object)sourceMethodClone != null) { sourceClone = (this.sourceClone = sourceMethodClone); DynamicMethodDefinition? obj2 = this.sourceCloneIl; if (obj2 != null) { obj2.Dispose(); } sourceCloneIl = (this.sourceCloneIl = val2.SourceMethodCloneIL); return; } } DynamicMethodDefinition obj3 = this.sourceCloneIl; if (obj3 == null) { DynamicMethodDefinition val3 = new DynamicMethodDefinition(Entry); DynamicMethodDefinition val4 = val3; this.sourceCloneIl = val3; obj3 = val4; } sourceCloneIl = obj3; sourceClone = this.sourceClone ?? (this.sourceClone = sourceCloneIl.Generate()); } else { Helpers.Assert((object)this.sourceClone != null, (string)null, "this.sourceClone is not null"); sourceClone = this.sourceClone; sourceCloneIl = this.sourceCloneIl; } } } internal sealed class ILHookEntry { public readonly SingleILHookState Hook; public ILContext? CurrentContext; public ILContext? LastContext; public bool IsApplied; public IDetourFactory Factory => Hook.Factory; public DetourConfig? Config => Hook.Config; public Manipulator Manip => Hook.Manip; public ILHookEntry(SingleILHookState hook) { Hook = hook; } public void Remove() { IsApplied = false; ILContext? lastContext = LastContext; if (lastContext != null) { lastContext.Dispose(); } } } internal sealed class ManagedDetourState { public readonly MethodBase Source; public MethodInfo? SourceClone; public DynamicMethodDefinition? SourceCloneIl; public MethodInfo? EndOfChain; private MethodDetourInfo? info; private readonly DepGraph<ManagedChainNode> detourGraph = new DepGraph<ManagedChainNode>(); internal readonly RootManagedChainNode detourList; private ManagedChainNode? noConfigChain; internal SpinLock detourLock = new SpinLock(enableThreadOwnerTracking: true); internal int detourChainVersion; internal readonly DepGraph<ILHookEntry> ilhookGraph = new DepGraph<ILHookEntry>(); internal readonly List<ILHookEntry> noConfigIlhooks = new List<ILHookEntry>(); internal int ilhookVersion; public MethodDetourInfo Info => info ?? (info = new MethodDetourInfo(this)); public event Action<DetourInfo>? DetourApplied; public event Action<DetourInfo>? DetourUndone; public event Action<ILHookInfo>? ILHookApplied; public event Action<ILHookInfo>? ILHookUndone; public ManagedDetourState(MethodBase src) { Source = src; detourList = new RootManagedChainNode(src); } public void AddDetour(SingleManagedDetourState detour, bool takeLock = true) { bool lockTaken = false; try { if (takeLock) { detourLock.Enter(ref lockTaken); } if (detour.ManagerData != null) { throw new InvalidOperationException("Trying to add a detour which was already added"); } ManagedDetourChainNode managedDetourChainNode = new ManagedDetourChainNode(detour); detourChainVersion++; DetourConfig config = managedDetourChainNode.Config; if (config != null) { DepGraphNode<ManagedChainNode> depGraphNode = new DepGraphNode<ManagedChainNode>(new DepListNode<ManagedChainNode>(config, managedDetourChainNode)); detourGraph.Insert(depGraphNode); detour.ManagerData = depGraphNode; } else { managedDetourChainNode.Next = noConfigChain; noConfigChain = managedDetourChainNode; detour.ManagerData = managedDetourChainNode; } PrepareEndOfChain(detour.Factory); UpdateChain(detour.Factory, out var _); } finally { if (lockTaken) { detourLock.Exit(useMemoryBarrier: true); } } InvokeDetourEvent(DetourManager.DetourApplied, this.DetourApplied, detour); } public void RemoveDetour(SingleManagedDetourState detour, bool takeLock = true) { bool lockTaken = false; try { if (takeLock) { detourLock.Enter(ref lockTaken); } detourChainVersion++; object obj = Interlocked.Exchange(ref detour.ManagerData, null); if (obj == null) { throw new InvalidOperationException("Trying to remove detour which wasn't added"); } if (!(obj is DepGraphNode<ManagedChainNode> depGraphNode)) { if (!(obj is ManagedDetourChainNode node)) { throw new InvalidOperationException("Trying to remove detour with unknown manager data"); } RemoveNoConfigDetour(detour, node); } else { RemoveGraphDetour(detour, depGraphNode); _ = (ManagedDetourChainNode)depGraphNode.ListNode.ChainNode; } } finally { if (lockTaken) { detourLock.Exit(useMemoryBarrier: true); } } InvokeDetourEvent(DetourManager.DetourUndone, this.DetourUndone, detour); } private void RemoveGraphDetour(SingleManagedDetourState detour, DepGraphNode<ManagedChainNode> node) { detourGraph.Remove(node); PrepareEndOfChain(detour.Factory); UpdateChain(detour.Factory, out var stealTrampolines); if (stealTrampolines) { detourList.SyncInfo.StealTrampoline(detour.Factory, node.ListNode.ChainNode); } node.ListNode.ChainNode.Remove(); } private void RemoveNoConfigDetour(SingleManagedDetourState detour, ManagedDetourChainNode node) { for (ref ManagedChainNode next = ref noConfigChain; next != null; next = ref next.Next) { if (next == node) { next = node.Next; node.Next = null; break; } } PrepareEndOfChain(detour.Factory); UpdateChain(detour.Factory, out var stealTrampolines); if (stealTrampolines) { detourList.SyncInfo.StealTrampoline(detour.Factory, node); } node.Remove(); } public void AddILHook(SingleILHookState ilhook, bool takeLock = true) { bool lockTaken = false; try { if (takeLock) { detourLock.Enter(ref lockTaken); } if (ilhook.ManagerData != null) { throw new InvalidOperationException("Trying to add an IL hook which was already added"); } ILHookEntry iLHookEntry = new ILHookEntry(ilhook); ilhookVersion++; DetourConfig config = iLHookEntry.Config; if (config != null) { DepGraphNode<ILHookEntry> depGraphNode = new DepGraphNode<ILHookEntry>(new DepListNode<ILHookEntry>(config, iLHookEntry)); ilhookGraph.Insert(depGraphNode); ilhook.ManagerData = depGraphNode; } else { noConfigIlhooks.Add(iLHookEntry); ilhook.ManagerData = iLHookEntry; } try { PrepareEndOfChain(ilhook.Factory); UpdateEndOfChain(); } catch { object obj2 = Interlocked.Exchange(ref ilhook.ManagerData, null); if (!(obj2 is DepGraphNode<ILHookEntry> node)) { if (!(obj2 is ILHookEntry item)) { throw new NotSupportedException("bad managerdata?"); } noConfigIlhooks.Remove(item); } else { ilhookGraph.Remove(node); } UpdateEndOfChain(); throw; } UpdateChain(ilhook.Factory, out var _); CleanILContexts(); } finally { if (lockTaken) { detourLock.Exit(useMemoryBarrier: true); } } InvokeILHookEvent(DetourManager.ILHookApplied, this.ILHookApplied, ilhook); } public void RemoveILHook(SingleILHookState ilhook, bool takeLock = true) { bool lockTaken = false; try { if (takeLock) { detourLock.Enter(ref lockTaken); } ilhookVersion++; object obj = Interlocked.Exchange(ref ilhook.ManagerData, null); if (obj == null) { throw new InvalidOperationException("Trying to remove IL hook which wasn't added"); } if (!(obj is DepGraphNode<ILHookEntry> depGraphNode)) { if (!(obj is ILHookEntry node)) { throw new InvalidOperationException("Trying to remove IL hook with unknown manager data"); } RemoveNoConfigILHook(ilhook, node); } else { RemoveGraphILHook(ilhook, depGraphNode); _ = depGraphNode.ListNode.ChainNode; } } finally { if (lockTaken) { detourLock.Exit(useMemoryBarrier: true); } } InvokeILHookEvent(DetourManager.ILHookUndone, this.ILHookUndone, ilhook); } private void RemoveGraphILHook(SingleILHookState ilhook, DepGraphNode<ILHookEntry> node) { ilhookGraph.Remove(node); PrepareEndOfChain(ilhook.Factory); UpdateEndOfChain(); UpdateChain(ilhook.Factory, out var _); CleanILContexts(); node.ListNode.ChainNode.Remove(); } private void RemoveNoConfigILHook(SingleILHookState ilhook, ILHookEntry node) { noConfigIlhooks.Remove(node); PrepareEndOfChain(ilhook.Factory); UpdateEndOfChain(); UpdateChain(ilhook.Factory, out var _); CleanILContexts(); node.Remove(); } private void PrepareEndOfChain(IDetourFactory factory) { detourList.PrepareDetour(factory, out SourceClone, out SourceCloneIl); if ((object)EndOfChain == null) { EndOfChain = SourceClone; } } private void UpdateEndOfChain() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown Helpers.Assert((object)SourceClone != null, (string)null, "SourceClone is not null"); if (noConfigIlhooks.Count == 0 && ilhookGraph.ListHead == null) { detourList.HasILHook = false; EndOfChain = SourceClone; return; } if (SourceCloneIl == null) { throw new InvalidOperationException("Target method cannot be ILHooked"); } detourList.HasILHook = true; DynamicMethodDefinition val = new DynamicMethodDefinition(SourceCloneIl); try { MethodDefinition definition = val.Definition; for (DepListNode<ILHookEntry> depListNode = ilhookGraph.ListHead; depListNode != null; depListNode = depListNode.Next) { InvokeManipulator(depListNode.ChainNode, definition); } foreach (ILHookEntry noConfigIlhook in noConfigIlhooks) { InvokeManipulator(noConfigIlhook, definition); } MethodInfo methodInfo = val.Generate(); PlatformTriple.Current.Compile((MethodBase)methodInfo); Thread.MemoryBarrier(); EndOfChain = methodInfo; } finally { ((IDisposable)val)?.Dispose(); } } private static void InvokeManipulator(ILHookEntry entry, MethodDefinition def) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown entry.IsApplied = true; ILContext val = (entry.CurrentContext = new ILContext(def)); val.Invoke(entry.Manip); if (val.IsReadOnly) { val.Dispose(); } else { val.MakeReadOnly(); } } private void CleanILContexts() { for (DepListNode<ILHookEntry> depListNode = ilhookGraph.ListHead; depListNode != null; depListNode = depListNode.Next) { CleanContext(depListNode.ChainNode); } foreach (ILHookEntry noConfigIlhook in noConfigIlhooks) { CleanContext(noConfigIlhook); } static void CleanContext(ILHookEntry entry) { if (entry.CurrentContext != entry.LastContext) { ILContext? lastContext = entry.LastContext; entry.LastContext = entry.CurrentContext; if (lastContext != null) { lastContext.Dispose(); } } } } private void UpdateChain(IDetourFactory updatingFactory, out bool stealTrampolines) { Helpers.Assert((object)SourceClone != null, (string)null, "SourceClone is not null"); Helpers.Assert((object)EndOfChain != null, (string)null, "EndOfChain is not null"); DepListNode<ManagedChainNode> depListNode = detourGraph.ListHead; ManagedChainNode managedChainNode = null; ref ManagedChainNode reference = ref managedChainNode; while (depListNode != null) { reference = depListNode.ChainNode; reference = ref reference.Next; reference = null; depListNode = depListNode.Next; } reference = noConfigChain; detourList.Next = managedChainNode; Volatile.Write(ref detourList.SyncInfo.UpdatingThread, EnvironmentEx.CurrentManagedThreadId); detourList.SyncInfo.WaitForNoActiveCalls(out stealTrampolines); try { for (managedChainNode = detourList; managedChainNode != null; managedChainNode = managedChainNode.Next) { IDetourFactory val = (managedChainNode.Next as ManagedDetourChainNode)?.Factory; if (val == null) { val = (managedChainNode as ManagedDetourChainNode)?.Factory; } if (val == null) { val = updatingFactory; } managedChainNode.UpdateDetour(val, EndOfChain); } } finally { Volatile.Write(ref detourList.SyncInfo.UpdatingThread, -1); } } private void InvokeDetourEvent(Action<DetourInfo>? evt1, Action<DetourInfo>? evt2, SingleManagedDetourState node) { if (evt1 != null || evt2 != null) { DetourInfo detourInfo = Info.GetDetourInfo(node); evt1?.Invoke(detourInfo); evt2?.Invoke(detourInfo); } } private void InvokeILHookEvent(Action<ILHookInfo>? evt1, Action<ILHookInfo>? evt2, SingleILHookState entry) { if (evt1 != null || evt2 != null) { ILHookInfo iLHookInfo = Info.GetILHookInfo(entry); evt1?.Invoke(iLHookInfo); evt2?.Invoke(iLHookInfo); } } } internal sealed class SingleManagedDetourState : SingleDetourStateBase { public readonly MethodInfo PublicTarget; public readonly MethodInfo InvokeTarget; public readonly IDetourTrampoline NextTrampoline; public DetourInfo? DetourInfo; public SingleManagedDetourState(IHook dt) : base(dt) { PublicTarget = dt.PublicTarget; InvokeTarget = dt.InvokeTarget; NextTrampoline = dt.NextTrampoline; } } internal sealed class SingleILHookState : SingleDetourStateBase { public readonly Manipulator Manip; public ILHookInfo? HookInfo; public SingleILHookState(IILHook hk) : base(hk) { Manip = hk.Manip; } } internal abstract class NativeChainNode { public NativeChainNode? Next; public abstract Delegate EntryDelegate { get; } public abstract void UpdateChain(IDetourFactory factory, Delegate? fallback); public virtual void Remove() { } } internal sealed class NativeDetourChainNode : NativeChainNode { public readonly SingleNativeDetourState Detour; public readonly ChainDelegateState? ChainState; public DetourConfig? Config => Detour.Config; public override Delegate EntryDelegate => ChainState?.GetDelegate() ?? Detour.Invoker; public NativeDetourChainNode(SingleNativeDetourState detour) { Detour = detour; if (detour.HasOrigParam) { ChainState = new ChainDelegateState(detour.Invoker, detour.NativeDelegateType); } } public override void UpdateChain(IDetourFactory factory, Delegate? fallback) { Delegate obj = Next?.EntryDelegate ?? fallback; obj = (((object)obj != null) ? Extensions.CastDelegate(obj, Detour.NativeDelegateType) : null); if (ChainState != null) { ChainState.Next = obj; } } public override void Remove() { if (ChainState != null) { ChainState.Remove(); } } } internal sealed class NativeDetourSyncInfo : DetourSyncInfo { public Delegate? FirstDelegate; } internal sealed class RootNativeDetourChainNode : NativeChainNode { public readonly NativeDetourSyncInfo SyncInfo; public Type EntryType; public Delegate SyncProxyDelegate; public nint SyncProxyNativeEntry; public readonly nint Function; private Delegate? origDelegate; private ICoreNativeDetour? nativeDetour; private nint lastNativeEntry; public override Delegate EntryDelegate { get { throw new InvalidOperationException(); } } public Delegate? OrigDelegate { get { Delegate obj = origDelegate; if ((object)obj != null) { return obj; } ICoreNativeDetour val = nativeDetour; if (val == null) { return null; } if (!val.HasOrigEntrypoint) { return null; } return origDelegate = Marshal.GetDelegateForFunctionPointer(val.OrigEntrypoint, EntryType); } } public RootNativeDetourChainNode(nint function) { SyncInfo = new NativeDetourSyncInfo(); Function = function; } public void MaybeSetEntryType(Type type) { if ((object)EntryType != null) { return; } MethodInfo delInvoke = type.GetMethod("Invoke"); FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val))..ctor(16, 1); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral("native->managed "); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<Type>(type); MethodInfo methodInfo = GenerateSyncProxy(DebugFormatter.Format(ref val), MethodSignature.ForMethod((MethodBase)delInvoke, true), delegate(MethodDefinition method, ILProcessor il) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) ((MethodReference)method).Parameters.Insert(0, new ParameterDefinition(((MemberReference)method).Module.ImportReference(typeof(NativeDetourSyncInfo)))); il.Emit(OpCodes.Ldarg_0); }, delegate(MethodDefinition method, ILProcessor il, Action loadSyncInfo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, ((MemberReference)method).Module.ImportReference(NativeDetourSyncInfo_FirstDelegate)); for (int i = 1; i < ((MethodReference)method).Parameters.Count; i++) { il.Emit(OpCodes.Ldarg, i); } il.Emit(OpCodes.Callvirt, ((MemberReference)method).Module.ImportReference((MethodBase)delInvoke)); }); Delegate obj = methodInfo.CreateDelegate(type, SyncInfo); SyncProxyNativeEntry = Marshal.GetFunctionPointerForDelegate(obj); EntryType = type; SyncInfo.SyncProxy = methodInfo; SyncProxyDelegate = obj; } public override void UpdateChain(IDetourFactory factory, Delegate? fallback) { if (nativeDetour == null || lastNativeEntry != SyncProxyNativeEntry) { ((IDisposable)nativeDetour)?.Dispose(); origDelegate = null; nativeDetour = DetourFactory.CreateNativeDetour(factory, (IntPtr)Function, (IntPtr)SyncProxyNativeEntry, false); lastNativeEntry = SyncProxyNativeEntry; } Delegate obj = Next?.EntryDelegate; obj = (((object)obj != null) ? Extensions.CastDelegate(obj, EntryType) : null); if ((object)obj != null && !((ICoreDetourBase)nativeDetour).IsApplied) { ((ICoreDetourBase)nativeDetour).Apply(); origDelegate = null; } else if ((object)obj == null && ((ICoreDetourBase)nativeDetour).IsApplied) { ((ICoreDetourBase)nativeDetour).Undo(); origDelegate = null; } SyncInfo.FirstDelegate = obj; } } internal sealed class ChainDelegateState { public readonly Delegate Orig; public readonly Type NextType; public Delegate? Next; private static readonly FieldInfo ChainDelegateState_Orig = typeof(ChainDelegateState).GetField("Orig"); private static readonly FieldInfo ChainDelegateState_Next = typeof(ChainDelegateState).GetField("Next"); private static readonly ConditionalWeakTable<Type, MethodInfo> chainMethodCache = new ConditionalWeakTable<Type, MethodInfo>(); private Delegate? selfDelegate; public ChainDelegateState(Delegate orig, Type nextType) { Orig = orig; NextType = nextType; } private static MethodInfo GenerateChainMethod(Type origDelType, Type nextDelType) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00c3: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0155: Unknown result type (might be due to invalid IL or missing references) MethodInfo method = origDelType.GetMethod("Invoke"); MethodInfo method2 = nextDelType.GetMethod("Invoke"); Helpers.Assert((object)method != null && (object)method2 != null, (string)null, "origInvoke is not null && nextInvoke is not null"); MethodSignature obj = MethodSignature.ForMethod((MethodBase)method2, true); FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val))..ctor(7, 1); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral("Chain<"); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<Type>(nextDelType); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(">"); DynamicMethodDefinition val2 = obj.CreateDmd(DebugFormatter.Format(ref val)); try { Helpers.Assert(val2.Module != null && val2.Definition != null, (string)null, "dmd.Module is not null && dmd.Definition is not null"); ModuleDefinition module = val2.Module; ((MethodReference)val2.Definition).Parameters.Insert(0, new ParameterDefinition(module.ImportReference(typeof(ChainDelegateState)))); ILProcessor iLProcessor = val2.GetILProcessor(); iLProcessor.Emit(OpCodes.Ldarg_0); iLProcessor.Emit(OpCodes.Ldfld, module.ImportReference(ChainDelegateState_Orig)); iLProcessor.Emit(OpCodes.Ldarg_0); iLProcessor.Emit(OpCodes.Ldfld, module.ImportReference(ChainDelegateState_Next)); for (int i = 1; i < ((MethodReference)val2.Definition).Parameters.Count; i++) { iLProcessor.Emit(OpCodes.Ldarg, i); } iLProcessor.Emit(OpCodes.Tail); iLProcessor.Emit(OpCodes.Callvirt, module.ImportReference((MethodBase)method)); iLProcessor.Emit(OpCodes.Ret); return val2.Generate(); } finally { ((IDisposable)val2)?.Dispose(); } } private static MethodInfo GetChainMethod(Type origDelType, Type nextDelType) { return chainMethodCache.GetValue(origDelType, (Type orig) => GenerateChainMethod(orig, nextDelType)); } public Delegate GetDelegate() { return selfDelegate ?? (selfDelegate = GetChainMethod(Orig.GetType(), NextType).CreateDelegate(NextType, this)); } public void Remove() { MethodInfo method = NextType.GetMethod("Invoke"); Helpers.Assert((object)method != null, (string)null, "nextInvoke is not null"); Next = GetRemovedStub(MethodSignature.ForMethod((MethodBase)method)).CreateDelegate(NextType, null); } } internal sealed class NativeDetourState { public readonly nint Function; internal RootNativeDetourChainNode detourList; private readonly DepGraph<NativeChainNode> detourGraph = new DepGraph<NativeChainNode>(); private NativeChainNode? noConfigChain; internal SpinLock detourLock = new SpinLock(enableThreadOwnerTracking: true); internal int detourChainVersion; private FunctionDetourInfo? info; public FunctionDetourInfo Info => info ?? (info = new FunctionDetourInfo(this)); public event Action<NativeDetourInfo>? NativeDetourApplied; public event Action<NativeDetourInfo>? NativeDetourUndone; public NativeDetourState(nint function) { Function = function; detourList = new RootNativeDetourChainNode(function); } public void AddDetour(SingleNativeDetourState detour, bool takeLock = true) { bool lockTaken = false; try { if (takeLock) { detourLock.Enter(ref lockTaken); } if (detour.ManagerData != null) { throw new InvalidOperationException("Trying to add a detour which was already added"); } NativeDetourChainNode nativeDetourChainNode = new NativeDetourChainNode(detour); detourChainVersion++; DetourConfig config = nativeDetourChainNode.Config; if (config != null) { DepGraphNode<NativeChainNode> depGraphNode = new DepGraphNode<NativeChainNode>(new DepListNode<NativeChainNode>(config, nativeDetourChainNode)); detourGraph.Insert(depGraphNode); detour.ManagerData = depGraphNode; } else { nativeDetourChainNode.Next = noConfigChain; noConfigChain = nativeDetourChainNode; detour.ManagerData = nativeDetourChainNode; } detourList.MaybeSetEntryType(detour.NativeDelegateType); UpdateChain(detour.Factory); } finally { if (lockTaken) { detourLock.Exit(useMemoryBarrier: true); } } InvokeDetourEvent(DetourManager.NativeDetourApplied, this.NativeDetourApplied, detour); } public void RemoveDetour(SingleNativeDetourState detour, bool takeLock = true) { bool lockTaken = false; try { if (takeLock) { detourLock.Enter(ref lockTaken); } detourChainVersion++; object obj = Interlocked.Exchange(ref detour.ManagerData, null); if (obj == null) { throw new InvalidOperationException("Trying to remove detour which wasn't added"); } if (!(obj is DepGraphNode<NativeChainNode> depGraphNode)) { if (!(obj is NativeDetourChainNode node)) { throw new InvalidOperationException("Trying to remove detour with unknown manager data"); } RemoveNoConfigDetour(detour, node); } else { RemoveGraphDetour(detour, depGraphNode); _ = (NativeDetourChainNode)depGraphNode.ListNode.ChainNode; } } finally { if (lockTaken) { detourLock.Exit(useMemoryBarrier: true); } } InvokeDetourEvent(DetourManager.NativeDetourUndone, this.NativeDetourUndone, detour); } private void RemoveGraphDetour(SingleNativeDetourState detour, DepGraphNode<NativeChainNode> node) { detourGraph.Remove(node); UpdateChain(detour.Factory); node.ListNode.ChainNode.Remove(); } private void RemoveNoConfigDetour(SingleNativeDetourState detour, NativeDetourChainNode node) { for (ref NativeChainNode next = ref noConfigChain; next != null; next = ref next.Next) { if (next == node) { next = node.Next; node.Next = null; break; } } UpdateChain(detour.Factory); node.Remove(); } private void UpdateChain(IDetourFactory updatingFactory) { DepListNode<NativeChainNode> depListNode = detourGraph.ListHead; NativeChainNode nativeChainNode = null; ref NativeChainNode reference = ref nativeChainNode; while (depListNode != null) { reference = depListNode.ChainNode; reference = ref reference.Next; reference = null; depListNode = depListNode.Next; } reference = noConfigChain; detourList.Next = nativeChainNode; Volatile.Write(ref detourList.SyncInfo.UpdatingThread, EnvironmentEx.CurrentManagedThreadId); detourList.SyncInfo.WaitForNoActiveCalls(out var _); try { for (nativeChainNode = detourList; nativeChainNode != null; nativeChainNode = nativeChainNode.Next) { IDetourFactory val = (nativeChainNode.Next as NativeDetourChainNode)?.Detour.Factory; if (val == null) { val = (nativeChainNode as NativeDetourChainNode)?.Detour.Factory; } if (val == null) { val = updatingFactory; } nativeChainNode.UpdateChain(val, detourList.OrigDelegate); } } finally { Volatile.Write(ref detourList.SyncInfo.UpdatingThread, -1); } } private void InvokeDetourEvent(Action<NativeDetourInfo>? evt1, Action<NativeDetourInfo>? evt2, SingleNativeDetourState node) { if (evt1 != null || evt2 != null) { NativeDetourInfo detourInfo = Info.GetDetourInfo(node); evt1?.Invoke(detourInfo); evt2?.Invoke(detourInfo); } } } internal sealed class SingleNativeDetourState : SingleDetourStateBase { public readonly nint Function; public readonly Type NativeDelegateType; public readonly Delegate Invoker; public readonly bool HasOrigParam; public NativeDetourInfo? DetourInfo; public SingleNativeDetourState(INativeDetour detour) : base(detour) { Function = detour.Function; NativeDelegateType = detour.NativeDelegateType; Invoker = detour.Invoker; HasOrigParam = detour.HasOrigParam; } } internal sealed class DepListNode<TNode> { public readonly DetourConfig Config; public readonly TNode ChainNode; public DepListNode<TNode>? Next; public DepListNode(DetourConfig config, TNode chainNode) { Config = config; ChainNode = chainNode; } } internal sealed class DepGraphNode<TNode> { public readonly DepListNode<TNode> ListNode; public readonly List<DepGraphNode<TNode>> BeforeThis = new List<DepGraphNode<TNode>>(); public bool Visiting; public bool Visited; public DetourConfig Config => ListNode.Config; public DepGraphNode(DepListNode<TNode> listNode) { ListNode = listNode; } } internal sealed class DepGraph<TNode> { private readonly List<DepGraphNode<TNode>> nodes = new List<DepGraphNode<TNode>>(); public DepListNode<TNode>? ListHead; private readonly DepListNode<TNode> dummyListNode = new DepListNode<TNode>(null, default(TNode)); private static void PrioInsert(List<DepGraphNode<TNode>> list, DepGraphNode<TNode> node) { int? priority = node.Config.Priority; if (priority.HasValue) { int valueOrDefault = priority.GetValueOrDefault(); int i = -1; for (int j = 0; j < list.Count; j++) { priority = list[j].Config.Priority; if (priority.HasValue) { int valueOrDefault2 = priority.GetValueOrDefault(); if (valueOrDefault >= valueOrDefault2) { i = j; break; } continue; } i = j; break; } if (i < 0) { i = list.Count; } else { for (; i < list.Count; i++) { DepGraphNode<TNode> depGraphNode = list[i]; if (depGraphNode.Config.Priority != node.Config.Priority || depGraphNode.Config.SubPriority <= node.Config.SubPriority) { break; } } } list.Insert(i, node); } else { list.Add(node); } } public void Insert(DepGraphNode<TNode> node) { node.ListNode.Next = null; node.BeforeThis.Clear(); node.Visited = false; node.Visiting = false; int i = -1; for (int j = 0; j < nodes.Count; j++) { DepGraphNode<TNode> depGraphNode = nodes[j]; depGraphNode.Visited = false; if (i < 0) { int? priority = node.Config.Priority; if (priority.HasValue) { int valueOrDefault = priority.GetValueOrDefault(); priority = depGraphNode.Config.Priority; if (priority.HasValue) { int valueOrDefault2 = priority.GetValueOrDefault(); if (valueOrDefault >= valueOrDefault2) { i = j; } } else { i = j; } } } bool flag = false; bool flag2 = false; if (node.Config.Before.Contains(depGraphNode.Config.Id)) { PrioInsert(depGraphNode.BeforeThis, node); flag = true; } bool isEnabled; if (node.Config.After.Contains(depGraphNode.Config.Id)) { if (flag) { MMDbgLog.DebugLogWarningStringHandler message = new MMDbgLog.DebugLogWarningStringHandler(53, 2, out isEnabled); if (isEnabled) { message.AppendLiteral("Detour '"); message.AppendFormatted(node.Config.Id); message.AppendLiteral("' is marked as being both before and after '"); message.AppendFormatted(depGraphNode.Config.Id); message.AppendLiteral("'"); } MMDbgLog.Warning(ref message); } else { PrioInsert(node.BeforeThis, depGraphNode); flag2 = true; } } if (depGraphNode.Config.Before.Contains(node.Config.Id)) { if (flag) { MMDbgLog.DebugLogWarningStringHandler message2 = new MMDbgLog.DebugLogWarningStringHandler(53, 2, out isEnabled); if (isEnabled) { message2.AppendLiteral("Detour '"); message2.AppendFormatted(node.Config.Id); message2.AppendLiteral("' is marked as being both before and after '"); message2.AppendFormatted(depGraphNode.Config.Id); message2.AppendLiteral("'"); } MMDbgLog.Warning(ref message2); } else { PrioInsert(node.BeforeThis, depGraphNode); flag2 = true; } } if (!depGraphNode.Config.After.Contains(node.Config.Id)) { continue; } if (flag2) { MMDbgLog.DebugLogWarningStringHandler message3 = new MMDbgLog.DebugLogWarningStringHandler(53, 2, out isEnabled); if (isEnabled) { message3.AppendLiteral("Detour '"); message3.AppendFormatted(node.Config.Id); message3.AppendLiteral("' is marked as being both before and after '"); message3.AppendFormatted(depGraphNode.Config.Id); message3.AppendLiteral("'"); } MMDbgLog.Warning(ref message3); } else { PrioInsert(depGraphNode.BeforeThis, node); } } if (i < 0) { i = nodes.Count; } else { for (; i < nodes.Count; i++) { DepGraphNode<TNode> depGraphNode2 = nodes[i]; if (depGraphNode2.Config.Priority != node.Config.Priority || depGraphNode2.Config.SubPriority <= node.Config.SubPriority) { break; } } } nodes.Insert(i, node); UpdateList(); } public void Remove(DepGraphNode<TNode> node) { nodes.Remove(node); foreach (DepGraphNode<TNode> node2 in nodes) { node2.BeforeThis.Remove(node); node2.Visited = false; } node.BeforeThis.Clear(); node.Visited = false; node.Visiting = false; node.ListNode.Next = null; UpdateList(); } private void UpdateList() { DepListNode<TNode> depListNode = dummyListNode; depListNode.Next = null; DepListNode<TNode> nextHolder = depListNode; foreach (DepGraphNode<TNode> node in nodes) { InsertListNode(ref nextHolder, node); } ListHead = depListNode.Next; } private static void InsertListNode(ref DepListNode<TNode> nextHolder, DepGraphNode<TNode> node) { if (node.Visiting) { throw new InvalidOperationException("Cycle detected"); } if (node.Visited) { return; } node.Visiting = true; try { DepListNode<TNode> listNode = node.ListNode; listNode.Next = null; foreach (DepGraphNode<TNode> beforeThi in node.BeforeThis) { InsertListNode(ref nextHolder, beforeThi); } nextHolder.Next = listNode; nextHolder = listNode; node.Visited = true; } finally { node.Visiting = false; } } } internal class DetourSyncInfo { public MethodBase? SyncProxy; public int ActiveCalls; public int UpdatingThread; public bool WaitForChainUpdate() { if (Volatile.Read(in ActiveCalls) > 1 && DetermineThreadCallDepth() > 1) { return true; } Interlocked.Decrement(ref ActiveCalls); if (UpdatingThread == EnvironmentEx.CurrentManagedThreadId) { throw new InvalidOperationException("Method's detour chain is being updated by the current thread!"); } SpinWait spinWait = default(SpinWait); while (Volatile.Read(in UpdatingThread) != -1) { spinWait.SpinOnce(); } return false; } public void WaitForNoActiveCalls(out bool hasActiveCallsFromThread) { int num = DetermineThreadCallDepth(); hasActiveCallsFromThread = num > 0; SpinWait spinWait = default(SpinWait); while (Volatile.Read(in ActiveCalls) > num) { spinWait.SpinOnce(); } } private int DetermineThreadCallDepth() { if (Volatile.Read(in ActiveCalls) <= 0 || SyncProxy == null) { return 0; } StackFrame[] frames = new StackTrace().GetFrames(); MethodBase syncProxyIdentif = PlatformTriple.Current.GetIdentifiable(SyncProxy); return frames.Count(delegate(StackFrame f) { MethodBase method = f.GetMethod(); return (object)method != null && PlatformTriple.Current.GetIdentifiable(method) == syncProxyIdentif; }); } } internal abstract class SingleDetourStateBase { public readonly IDetourFactory Factory; public readonly DetourConfig? Config; public object? ManagerData; public bool IsValid; public bool IsApplied => Volatile.Read(in ManagerData) != null; protected SingleDetourStateBase(IDetourBase detour) { Factory = detour.Factory; Config = detour.Config; ManagerData = null; IsValid = true; } } private static readonly MethodInfo ManagedDetourSyncInfo_ReturnStolenTrampolines = typeof(ManagedDetourSyncInfo).GetMethod("ReturnStolenTrampolines"); private static readonly ConcurrentDictionary<MethodBase, ManagedDetourState> detourStates = new ConcurrentDictionary<MethodBase, ManagedDetourState>(); private static readonly FieldInfo NativeDetourSyncInfo_FirstDelegate = typeof(NativeDetourSyncInfo).GetField("FirstDelegate"); private static readonly ConcurrentDictionary<nint, NativeDetourState> nativeDetourStates = new ConcurrentDictionary<nint, NativeDetourState>(); private static readonly FieldInfo DetourSyncInfo_ActiveCalls = typeof(DetourSyncInfo).GetField("ActiveCalls"); private static readonly FieldInfo DetourSyncInfo_UpdatingThread = typeof(DetourSyncInfo).GetField("UpdatingThread"); private static readonly MethodInfo DetourSyncInfo_WaitForChainUpdate = typeof(DetourSyncInfo).GetMethod("WaitForChainUpdate"); private static readonly MethodInfo Interlocked_Increment = typeof(Interlocked).GetMethod("Increment", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(int).MakeByRefType() }, null); private static readonly MethodInfo Interlocked_Decrement = typeof(Interlocked).GetMethod("Decrement", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(int).MakeByRefType() }, null); private static readonly ConditionalWeakTable<MethodSignature, MethodInfo> removedStubCache = new ConditionalWeakTable<MethodSignature, MethodInfo>(); public static event Action<DetourInfo>? DetourApplied; public static event Action<DetourInfo>? DetourUndone; public static event Action<ILHookInfo>? ILHookApplied; public static event Action<ILHookInfo>? ILHookUndone; public static event Action<NativeDetourInfo>? NativeDetourApplied; public static event Action<NativeDetourInfo>? NativeDetourUndone; internal static ManagedDetourState GetDetourState(MethodBase method) { method = PlatformTriple.Current.GetIdentifiable(method); return detourStates.GetOrAdd(method, (MethodBase m) => new ManagedDetourState(m)); } public static MethodDetourInfo GetDetourInfo(MethodBase method) { return GetDetourState(method).Info; } internal static NativeDetourState GetNativeDetourState(nint function) { return nativeDetourStates.GetOrAdd(function, (nint f) => new NativeDetourState(f)); } public static FunctionDetourInfo GetNativeDetourInfo(nint function) { return GetNativeDetourState(function).Info; } private static MethodInfo GenerateSyncProxy(string innerName, MethodSignature Sig, Action<MethodDefinition, ILProcessor> emitLoadSyncInfo, Action<MethodDefinition, ILProcessor, Action> emitInvoke, Action<MethodDefinition, ILProcessor, Action>? emitLastCallReturn = null) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Expected O, but got Unknown //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Expected O, but got Unknown //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val))..ctor(11, 1); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral("SyncProxy<"); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted(innerName); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(">"); DynamicMethodDefinition val2 = Sig.CreateDmd(DebugFormatter.Format(ref val)); try { ILProcessor il = val2.GetILProcessor(); MethodDefinition definition = val2.Definition; ModuleDefinition module = val2.Module; TypeReference val3 = module.ImportReference(typeof(DetourSyncInfo)); VariableDefinition syncInfoVar = new VariableDefinition(val3); il.Body.Variables.Add(syncInfoVar); emitLoadSyncInfo(definition, il); il.Emit(OpCodes.Stloc, syncInfoVar); Instruction val4 = il.Create(OpCodes.Nop); il.Append(val4); il.Emit(OpCodes.Ldloc, syncInfoVar); il.Emit(OpCodes.Ldflda, module.ImportReference(DetourSyncInfo_ActiveCalls)); il.Emit(OpCodes.Call, module.ImportReference((MethodBase)Interlocked_Increment)); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ldloc, syncInfoVar); il.Emit(OpCodes.Volatile); il.Emit(OpCodes.Ldfld, module.ImportReference(DetourSyncInfo_UpdatingThread)); il.Emit(OpCodes.Ldc_I4_M1); Instruction val5 = il.Create(OpCodes.Nop); il.Emit(OpCodes.Beq_S, val5); il.Emit(OpCodes.Ldloc, syncInfoVar); il.Emit(OpCodes.Call, module.ImportReference((MethodBase)DetourSyncInfo_WaitForChainUpdate)); il.Emit(OpCodes.Brtrue_S, val5); il.Emit(OpCodes.Br_S, val4); il.Append(val5); VariableDefinition val6 = null; if (Sig.ReturnType != typeof(void)) { val6 = new VariableDefinition(((MethodReference)definition).ReturnType); il.Body.Variables.Add(val6); } ExceptionHandler val7 = new ExceptionHandler((ExceptionHandlerType)2); il.Body.ExceptionHandlers.Add(val7); Instruction val8 = il.Create(OpCodes.Nop); il.Append(val8); val7.TryStart = val8; emitInvoke(definition, il, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) il.Emit(OpCodes.Ldloc, syncInfoVar); }); if (val6 != null) { il.Emit(OpCodes.Stloc, val6); } Instruction val9 = il.Create(OpCodes.Nop); il.Emit(OpCodes.Leave_S, val9); Instruction val10 = il.Create(OpCodes.Ldloc, syncInfoVar); Instruction tryEnd = (val7.HandlerStart = val10); val7.TryEnd = tryEnd; il.Append(val10); il.Emit(OpCodes.Ldflda, module.ImportReference(DetourSyncInfo_ActiveCalls)); il.Emit(OpCodes.Call, module.ImportReference((MethodBase)Interlocked_Decrement)); if (emitLastCallReturn == null) { il.Emit(OpCodes.Pop); } else { Instruction val12 = il.Create(OpCodes.Nop); il.Emit(OpCodes.Brtrue_S, val12); emitLastCallReturn(definition, il, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) il.Emit(OpCodes.Ldloc, syncInfoVar); }); il.Append(val12); } il.Emit(OpCodes.Endfinally); val7.HandlerEnd = val9; il.Append(val9); if (val6 != null) { il.Emit(OpCodes.Ldloc, val6); } il.Emit(OpCodes.Ret); return val2.Generate(); } finally { ((IDisposable)val2)?.Dispose(); } } private static MethodInfo GenerateRemovedStub(MethodSignature trampolineSig) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) FormatInterpolatedStringHandler val = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val))..ctor(13, 1); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral("RemovedStub<"); ((FormatInterpolatedStringHandler)(ref val)).AppendFormatted<MethodSignature>(trampolineSig); ((FormatInterpolatedStringHandler)(ref val)).AppendLiteral(">"); DynamicMethodDefinition val2 = trampolineSig.CreateDmd(DebugFormatter.Format(ref val)); try { Helpers.Assert(val2.Module != null && val2.Definition != null, (string)null, "dmd.Module is not null && dmd.Definition is not null"); ModuleDefinition module = val2.Module; ILProcessor iLProcessor = val2.GetILProcessor(); iLProcessor.Emit(OpCodes.Ldstr, "Detour has been removed"); iLProcessor.Emit(OpCodes.Newobj, module.ImportReference((MethodBase)typeof(InvalidOperationException).GetConstructor(new Type[1] { typeof(string) }))); iLProcessor.Emit(OpCodes.Throw); return val2.Generate(); } finally { ((IDisposable)val2)?.Dispose(); } } private static MethodInfo GetRemovedStub(MethodSignature trampolineSig) { return removedStubCache.GetValue(trampolineSig, (MethodSignature orig) => GenerateRemovedStub(trampolineSig)); } } internal static class Extensions { public static MethodInfo CreateILCopy(this MethodBase method) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown DynamicMethodDefinition val = new DynamicMethodDefinition(method); try { return val.Generate(); } finally { ((IDisposable)val)?.Dispose(); } } } public sealed class Hook : IHook, IDetourBase, IDetour, IDisposable { private sealed class TrampolineData : IDetourTrampoline, IDisposable { private readonly MethodInfo trampoline; private bool alive; private bool hasOwnership; public MethodBase TrampolineMethod => trampoline; public TrampolineData(MethodSignature sig) { trampoline = TrampolinePool.Rent(sig); alive = (hasOwnership = true); } public void Dispose() { lock (this) { if (alive) { alive = false; if (hasOwnership) { TrampolinePool.Return(trampoline); } } } } public void StealTrampolineOwnership() { lock (this) { Helpers.Assert(alive && hasOwnership, (string)null, "alive && hasOwnership"); hasOwnership = false; } } public void ReturnTrampolineOwnership() { lock (this) { Helpers.Assert(!hasOwnership, (string)null, "!hasOwnership"); if (!alive) { TrampolinePool.Return(trampoline); } else { hasOwnership = true; } } } } private sealed class HookData { public readonly object? Target; public readonly Delegate? InvokeNext; public HookData(object? target, Delegate? invokeNext) { Target = target; InvokeNext = invokeNext; } } private const bool ApplyByDefault = true; private readonly IDetourFactory factory; private readonly MethodInfo realTarget; private readonly TrampolineData trampoline; private readonly DetourManager.ManagedDetourState state; private readonly DetourManager.SingleManagedDetourState detour; private readonly DataScope<DynamicReferenceCell> delegateObjectScope; private static readonly FieldInfo HookData_Target = typeof(HookData).GetField("Target"); private static readonly FieldInfo HookData_InvokeNext = typeof(HookData).GetField("InvokeNext"); private bool disposedValue; IDetourFactory IDetourBase.Factory => factory; public DetourConfig? Config { get; } public MethodBase Source { get; } public MethodInfo Target { get; } MethodInfo IHook.PublicTarget => Target; MethodInfo IHook.InvokeTarget => realTarget; IDetourTrampoline IHook.NextTrampoline => trampoline; public bool IsValid => !disposedValue; public bool IsApplied => detour.IsApplied; public DetourInfo DetourInfo => state.Info.GetDetourInfo(detour); public Hook(Expression<Action> source, Expression<Action> target) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, Helpers.ThrowIfNull<Expression<Action>>(target, "target").Body) { } public Hook(Expression source, Expression target) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, ((MethodCallExpression)Helpers.ThrowIfNull<Expression>(target, "target")).Method) { } public Hook(MethodBase source, MethodInfo target) : this(source, target, DetourContext.GetDefaultConfig()) { } public Hook(Expression<Action> source, Expression<Action> target, bool applyByDefault) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, Helpers.ThrowIfNull<Expression<Action>>(target, "target").Body, applyByDefault) { } public Hook(Expression source, Expression target, bool applyByDefault) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, ((MethodCallExpression)Helpers.ThrowIfNull<Expression>(target, "target")).Method, applyByDefault) { } public Hook(MethodBase source, MethodInfo target, bool applyByDefault) : this(source, target, DetourContext.GetDefaultConfig(), applyByDefault) { } public Hook(Expression<Action> source, Expression<Action> target, DetourConfig? config) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, Helpers.ThrowIfNull<Expression<Action>>(target, "target").Body, config) { } public Hook(Expression source, Expression target, DetourConfig? config) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, ((MethodCallExpression)Helpers.ThrowIfNull<Expression>(target, "target")).Method, config) { } public Hook(MethodBase source, MethodInfo target, DetourConfig? config) : this(source, target, config, applyByDefault: true) { } public Hook(Expression<Action> source, Expression<Action> target, DetourConfig? config, bool applyByDefault) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, Helpers.ThrowIfNull<Expression<Action>>(target, "target").Body, config, applyByDefault) { } public Hook(Expression source, Expression target, DetourConfig? config, bool applyByDefault) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, ((MethodCallExpression)Helpers.ThrowIfNull<Expression>(target, "target")).Method, config, applyByDefault) { } public Hook(MethodBase source, MethodInfo target, DetourConfig? config, bool applyByDefault) : this(source, target, DetourContext.GetDefaultFactory(), config, applyByDefault) { } public Hook(MethodBase source, MethodInfo target, IDetourFactory factory, DetourConfig? config, bool applyByDefault) : this(source, target, null, factory, config, applyByDefault) { } public Hook(Expression<Action> source, Expression<Action> target, object? targetObj) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, Helpers.ThrowIfNull<Expression<Action>>(target, "target").Body, targetObj) { } public Hook(Expression source, Expression target, object? targetObj) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, ((MethodCallExpression)Helpers.ThrowIfNull<Expression>(target, "target")).Method, targetObj) { } public Hook(MethodBase source, MethodInfo target, object? targetObj) : this(source, target, targetObj, DetourContext.GetDefaultConfig()) { } public Hook(Expression<Action> source, Expression<Action> target, object? targetObj, bool applyByDefault) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, Helpers.ThrowIfNull<Expression<Action>>(target, "target").Body, targetObj, applyByDefault) { } public Hook(Expression source, Expression target, object? targetObj, bool applyByDefault) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, ((MethodCallExpression)Helpers.ThrowIfNull<Expression>(target, "target")).Method, targetObj, applyByDefault) { } public Hook(MethodBase source, MethodInfo target, object? targetObj, bool applyByDefault) : this(source, target, targetObj, DetourContext.GetDefaultConfig(), applyByDefault) { } public Hook(Expression<Action> source, Expression<Action> target, object? targetObj, DetourConfig? config) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, Helpers.ThrowIfNull<Expression<Action>>(target, "target").Body, targetObj, config) { } public Hook(Expression source, Expression target, object? targetObj, DetourConfig? config) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, ((MethodCallExpression)Helpers.ThrowIfNull<Expression>(target, "target")).Method, targetObj, config) { } public Hook(MethodBase source, MethodInfo target, object? targetObj, DetourConfig? config) : this(source, target, targetObj, config, applyByDefault: true) { } public Hook(Expression<Action> source, Expression<Action> target, object? targetObj, DetourConfig? config, bool applyByDefault) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, Helpers.ThrowIfNull<Expression<Action>>(target, "target").Body, targetObj, config, applyByDefault) { } public Hook(Expression source, Expression target, object? targetObj, DetourConfig? config, bool applyByDefault) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, ((MethodCallExpression)Helpers.ThrowIfNull<Expression>(target, "target")).Method, targetObj, config, applyByDefault) { } public Hook(MethodBase source, MethodInfo target, object? targetObj, DetourConfig? config, bool applyByDefault) : this(source, target, targetObj, DetourContext.GetDefaultFactory(), config, applyByDefault) { } public Hook(Expression<Action> source, Delegate target) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, target) { } public Hook(Expression source, Delegate target) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, target) { } public Hook(MethodBase source, Delegate target) : this(source, target, DetourContext.GetDefaultConfig()) { } public Hook(Expression<Action> source, Delegate target, bool applyByDefault) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, target, applyByDefault) { } public Hook(Expression source, Delegate target, bool applyByDefault) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, target, applyByDefault) { } public Hook(MethodBase source, Delegate target, bool applyByDefault) : this(source, target, DetourContext.GetDefaultConfig(), applyByDefault) { } public Hook(Expression<Action> source, Delegate target, DetourConfig? config) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, target, config) { } public Hook(Expression source, Delegate target, DetourConfig? config) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, target, config) { } public Hook(MethodBase source, Delegate target, DetourConfig? config) : this(source, target, config, applyByDefault: true) { } public Hook(Expression<Action> source, Delegate target, DetourConfig? config, bool applyByDefault) : this(Helpers.ThrowIfNull<Expression<Action>>(source, "source").Body, target, config, applyByDefault) { } public Hook(Expression source, Delegate target, DetourConfig? config, bool applyByDefault) : this(((MethodCallExpression)Helpers.ThrowIfNull<Expression>(source, "source")).Method, target, config, applyByDefault) { } public Hook(MethodBase source, Delegate target, DetourConfig? config, bool applyByDefault) : this(source, target, DetourContext.GetDefaultFactory(), config, applyByDefault) { } public Hook(MethodBase source, Delegate target, IDetourFactory factory, DetourConfig? config, bool applyByDefault) : this(source, GetDelegateHookInfo(Helpers.ThrowIfNull<Delegate>(target, "target"), out object target2), target2, factory, config, applyByDefault) { } private static MethodInfo GetDelegateHookInfo(Delegate del, out object? target) { if (del.GetInvocationList().Length == 1) { target = del.Target; return del.Method; } target = del; return del.GetType().GetMethod("Invoke") ?? throw new InvalidOperationException("Could not get Invoke method of delegate"); } public Hook(MethodBase source, MethodInfo target, object? targetObject, IDetourFactory factory, DetourConfig? config, bool applyByDefault) { Helpers.ThrowIfArgumentNull<MethodBase>(source, "source"); Helpers.ThrowIfArgumentNull<MethodInfo>(target, "target"); Helpers.ThrowIfArgumentNull<IDetourFactory>(factory, "factory"); this.factory = factory; Config = config; Source = PlatformTriple.Current.GetIdentifiable(source); Target = target; realTarget = PrepareRealTarget(targetObject, out trampoline, out delegateObjectScope); bool isEnabled; MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(23, 2, out isEnabled); if (isEnabled) { message.AppendLiteral("Creating Hook from "); message.AppendFormatted(Source); message.AppendLiteral(" to "); message.AppendFormatted(Target); } MMDbgLog.Trace(ref message); state = DetourManager.GetDetourState(source); detour = new DetourManager.SingleManagedDetourState(this); if (applyByDefault) { Apply(); } } private MethodInfo PrepareRealTarget(object? target, out TrampolineData trampoline, out DataScope<DynamicReferenceCell> scope) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_0199: 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_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0226: 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_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) CheckSupported(); MethodSignature val = MethodSignature.ForMethod(Source); MethodSignature val2 = MethodSignature.ForMethod((MethodBase)Target, true); if (target == null && !Target.IsStatic) { throw new ArgumentException("Target method is nonstatic, but no target object was provided"); } if (target != null && Target.IsStatic) { throw new ArgumentException("Target method is static, but a target object was provided"); } Type type = null; if (val2.ParameterCount == val.ParameterCount + 1) { type = val2.FirstParameter; val2 = new MethodSignature(val2.ReturnType, val2.Parameters.Skip(1)); } if (!val.IsCompatibleWith(val2)) { throw new ArgumentException("Target method is not compatible with source method"); } MethodSignature val3 = val; MethodInfo methodInfo = type?.GetMethod("Invoke"); if ((object)methodInfo != null) { val3 = MethodSignature.ForMethod((MethodBase)methodInfo, true); } if (!val3.IsCompatibleWith(val)) { throw new ArgumentException("Target method's delegate parameter is not compatible with the source method"); } trampoline = new TrampolineData(val3); if (target == null && (object)type == null) { scope = default(DataScope<DynamicReferenceCell>); return Target; } HookData hookData = new HookData(target, ((object)type != null) ? Extensions.CreateDelegate(trampoline.TrampolineMethod, type) : null); FormatInterpolatedStringHandler val4 = default(FormatInterpolatedStringHandler); ((FormatInterpolatedStringHandler)(ref val4))..ctor(6, 1); ((FormatInterpolatedStringHandler)(ref val4)).AppendLiteral("Hook<"); ((FormatInterpolatedStringHandler)(ref val4)).AppendFormatted(Extensions.GetID((MethodBase)Target, (string)null, (string)null, true, false, false)); ((FormatInterpolatedStringHandler)(ref val4)).AppendLiteral(">"); DynamicMethodDefinition val5 = val.CreateDmd(DebugFormatter.Format(ref val4)); try { ILProcessor iLProcessor = val5.GetILProcessor(); ModuleDefinition module = val5.Module; MethodDefinition definition = val5.Definition; VariableDefinition val6 = new VariableDefinition(module.ImportReference(typeof(HookData))); iLProcessor.Body.Variables.Add(val6); DynamicReferenceCell val7 = default(DynamicReferenceCell); scope = DynamicReferenceManager.EmitNewTypedReference<HookData>(iLProcessor, hookData, ref val7); iLProcessor.Emit(OpCodes.Stloc, val6); if (!Target.IsStatic) { iLProcessor.Emit(OpCodes.Ldloc, val6); iLProcessor.Emit(OpCodes.Ldfld, module.ImportReference(HookData_Target)); Type declaringType = Target.DeclaringType; if ((object)declaringType != null && declaringType.IsValueType) { iLProcessor.Emit(OpCodes.Unbox, module.ImportReference(declaringType)); } } if ((object)type != null) { iLProcessor.Emit(OpCodes.Ldloc, val6); iLProcessor.Emit(OpCodes.Ldfld, module.ImportReference(HookData_InvokeNext)); } Enumerator<ParameterDefinition> enumerator = ((MethodReference)definition).Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; iLProcessor.Emit(OpCodes.Ldarg, ((ParameterReference)current).Index); } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)Target); iLProcessor.Emit(OpCodes.Ret); return val5.Generate(); } finally { ((IDisposable)val5)?.Dispose(); } } private void CheckSupported() { if (!Source.IsGenericMethod) { Type declaringType = Source.DeclaringType; if ((object)declaringType == null || !declaringType.IsGenericType) { return; } } throw new ArgumentException("Source method is generic, generic hooks are not supported"); } private void CheckDisposed() { if (disposedValue) { throw new ObjectDisposedException(ToString()); } } public void Apply() { CheckDisposed(); bool lockTaken = false; try { state.detourLock.Enter(ref lockTaken); if (!IsApplied) { bool isEnabled; MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(23, 2, out isEnabled); if (isEnabled) { message.AppendLiteral("Applying Hook from "); message.AppendFormatted(Source); message.AppendLiteral(" to "); message.AppendFormatted(Target); } MMDbgLog.Trace(ref message); state.AddDetour(detour, !lockTaken); } } finally { if (lockTaken) { state.detourLock.Exit(useMemoryBarrier: true); } } } public void Undo() { CheckDisposed(); bool lockTaken = false; try { state.detourLock.Enter(ref lockTaken); if (IsApplied) { bool isEnabled; MMDbgLog.DebugLogTraceStringHandler message = new MMDbgLog.DebugLogTraceStringHandler(22, 2, out isEnabled); if (isEnabled) { message.AppendLiteral("Undoing Hook from "); message.AppendFormatted(Source); message.AppendLiteral(" to "); message.AppendFormatted(Target); } MMDbgLog.Trace(ref message); state.RemoveDetour(detour, !lockTaken); } } finally { if (lockTaken) { state.detourLock.Exit(useMemoryBarrier: true); } } } private void Dispose(bool disposing) { if (!disposedValue && detour != null) { detour.IsValid = false; if (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted) { Undo(); } delegateObjectScope.Dispose(); if (disposing) { trampoline.Dispose(); } disposedValue = true; } } ~Hook() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } } public interface IDetour : IDisposable { DetourConfig? Config { get; } bool IsValid { get; } bool IsApplied { get; } void Apply(); void Undo(); } internal interface IDetourBase { IDetourFactory Factory { get; } DetourConfig? Config { get; } } internal interface IDetourTrampoline
BepInExPack/BepInEx/core/MonoMod.Utils.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod; using MonoMod.Cil; using MonoMod.Logs; using MonoMod.SourceGen.Attributes; using MonoMod.Utils; using MonoMod.Utils.Cil; using MonoMod.Utils.Interop; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: DisableRuntimeMarshalling] [assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] [assembly: InternalsVisibleTo("MonoMod.Utils.Cil.ILGeneratorProxy")] [assembly: AssemblyCompany("0x0ade, DaNike")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2026 0x0ade, DaNike")] [assembly: AssemblyDescription("Utilities and smaller MonoMod \"components\" (f.e. ModInterop, DynDll, DynData). Can be used for your own mods. Required by all other MonoMod components.")] [assembly: AssemblyFileVersion("25.0.12.0")] [assembly: AssemblyInformationalVersion("25.0.12+69fdc9deb")] [assembly: AssemblyProduct("MonoMod.Utils")] [assembly: AssemblyTitle("MonoMod.Utils")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoMod/MonoMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("25.0.12.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { MMDbgLog.LogVersion(); } } namespace MonoMod { public static class Switches { private static readonly ConcurrentDictionary<string, object?> switchValues; private const string Prefix = "MONOMOD_"; public const string RunningOnWine = "RunningOnWine"; public const string DebugClr = "DebugClr"; public const string JitPath = "JitPath"; public const string HelperDropPath = "HelperDropPath"; public const string LogRecordHoles = "LogRecordHoles"; public const string LogInMemory = "LogInMemory"; public const string LogSpam = "LogSpam"; public const string LogReplayQueueLength = "LogReplayQueueLength"; public const string LogToFile = "LogToFile"; public const string LogToFileFilter = "LogToFileFilter"; public const string DMDType = "DMDType"; public const string DMDDebug = "DMDDebug"; public const string DMDDumpTo = "DMDDumpTo"; static Switches() { switchValues = new ConcurrentDictionary<string, object>(); foreach (DictionaryEntry environmentVariable in Environment.GetEnvironmentVariables()) { string text = (string)environmentVariable.Key; if (text.StartsWith("MONOMOD_", StringComparison.Ordinal) && environmentVariable.Value != null) { string key = text.Substring("MONOMOD_".Length); switchValues.TryAdd(key, BestEffortParseEnvVar((string)environmentVariable.Value)); } } } private static object? BestEffortParseEnvVar(string value) { if (value.Length == 0) { return null; } if (int.TryParse(value, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out var result)) { return result; } if (long.TryParse(value, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out var result2)) { return result2; } if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result)) { return result; } if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result2)) { return result2; } bool flag; switch (value[0]) { case 'F': case 'N': case 'T': case 'Y': case 'f': case 'n': case 't': case 'y': flag = true; break; default: flag = false; break; } if (flag) { if (bool.TryParse(value, out var result3)) { return result3; } if (value.Equals("yes", StringComparison.OrdinalIgnoreCase) || value.Equals("y", StringComparison.OrdinalIgnoreCase)) { return true; } if (value.Equals("no", StringComparison.OrdinalIgnoreCase) || value.Equals("n", StringComparison.OrdinalIgnoreCase)) { return false; } } return value; } public static void SetSwitchValue(string @switch, object? value) { switchValues[@switch] = value; } public static void ClearSwitchValue(string @switch) { switchValues.TryRemove(@switch, out object _); } public static bool TryGetSwitchValue(string @switch, out object? value) { if (switchValues.TryGetValue(@switch, out value)) { return true; } string text = "MonoMod." + @switch; object data = AppContext.GetData(text); if (data != null) { value = data; return true; } if (AppContext.TryGetSwitch(text, out var isEnabled)) { value = isEnabled; return true; } value = null; return false; } public static bool TryGetSwitchEnabled(string @switch, out bool isEnabled) { if (switchValues.TryGetValue(@switch, out object value) && value != null && TryProcessBoolData(value, out isEnabled)) { return true; } string text = "MonoMod." + @switch; if (AppContext.TryGetSwitch(text, out isEnabled)) { return true; } object data = AppContext.GetData(text); if (data != null && TryProcessBoolData(data, out isEnabled)) { return true; } isEnabled = false; return false; } private static bool TryProcessBoolData(object data, out bool boolVal) { if (!(data is bool flag)) { if (!(data is int num)) { if (!(data is long num2)) { IConvertible convertible; if (!(data is string value)) { convertible = data as IConvertible; if (convertible == null) { boolVal = false; return false; } } else { if (bool.TryParse(value, out boolVal)) { return true; } convertible = (IConvertible)data; } IConvertible convertible2 = convertible; boolVal = convertible2.ToBoolean(CultureInfo.CurrentCulture); return true; } long num3 = num2; boolVal = num3 != 0; return true; } int num4 = num; boolVal = num4 != 0; return true; } bool flag2 = flag; boolVal = flag2; return true; } } internal static class MMDbgLog { [InterpolatedStringHandler] internal ref struct DebugLogSpamStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogSpamStringHandler(int literalLen, int formattedCount, out bool isEnabled) { handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, LogLevel.Spam, out isEnabled); } public override string ToString() { return handler.ToString(); } public string ToStringAndClear() { return handler.ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { handler.AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { handler.AppendFormatted(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { handler.AppendFormatted(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { handler.AppendFormatted(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { handler.AppendFormatted(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogTraceStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogTraceStringHandler(int literalLen, int formattedCount, out bool isEnabled) { handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, LogLevel.Trace, out isEnabled); } public override string ToString() { return handler.ToString(); } public string ToStringAndClear() { return handler.ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { handler.AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { handler.AppendFormatted(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { handler.AppendFormatted(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { handler.AppendFormatted(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { handler.AppendFormatted(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogInfoStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogInfoStringHandler(int literalLen, int formattedCount, out bool isEnabled) { handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, LogLevel.Info, out isEnabled); } public override string ToString() { return handler.ToString(); } public string ToStringAndClear() { return handler.ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { handler.AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { handler.AppendFormatted(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { handler.AppendFormatted(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { handler.AppendFormatted(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { handler.AppendFormatted(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogWarningStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogWarningStringHandler(int literalLen, int formattedCount, out bool isEnabled) { handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, LogLevel.Warning, out isEnabled); } public override string ToString() { return handler.ToString(); } public string ToStringAndClear() { return handler.ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { handler.AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { handler.AppendFormatted(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { handler.AppendFormatted(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { handler.AppendFormatted(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { handler.AppendFormatted(value, alignment, format); } } [InterpolatedStringHandler] internal ref struct DebugLogErrorStringHandler { internal DebugLogInterpolatedStringHandler handler; public DebugLogErrorStringHandler(int literalLen, int formattedCount, out bool isEnabled) { handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, LogLevel.Error, out isEnabled); } public override string ToString() { return handler.ToString(); } public string ToStringAndClear() { return handler.ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { handler.AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { handler.AppendFormatted(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { handler.AppendFormatted(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { handler.AppendFormatted(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { handler.AppendFormatted(value, alignment, format); } } public static bool IsWritingLog => DebugLog.IsWritingLog; [ModuleInitializer] internal static void LogVersion() { Info("Version 25.0.12"); } public static void Log(LogLevel level, string message) { DebugLog.Log("MonoMod.Utils", level, message); } public static void Log(LogLevel level, [InterpolatedStringHandlerArgument("level")] ref DebugLogInterpolatedStringHandler message) { DebugLog.Log("MonoMod.Utils", level, ref message); } public static void Spam(string message) { Log(LogLevel.Spam, message); } public static void Spam(ref DebugLogSpamStringHandler message) { Log(LogLevel.Spam, ref message.handler); } public static void Trace(string message) { Log(LogLevel.Trace, message); } public static void Trace(ref DebugLogTraceStringHandler message) { Log(LogLevel.Trace, ref message.handler); } public static void Info(string message) { Log(LogLevel.Info, message); } public static void Info(ref DebugLogInfoStringHandler message) { Log(LogLevel.Info, ref message.handler); } public static void Warning(string message) { Log(LogLevel.Warning, message); } public static void Warning(ref DebugLogWarningStringHandler message) { Log(LogLevel.Warning, ref message.handler); } public static void Error(string message) { Log(LogLevel.Error, message); } public static void Error(ref DebugLogErrorStringHandler message) { Log(LogLevel.Error, ref message.handler); } } internal static class MultiTargetShims { public static TypeReference GetConstraintType(this GenericParameterConstraint constraint) { return constraint.ConstraintType; } } } namespace MonoMod.SourceGen.Attributes { [AttributeUsage(AttributeTargets.Class)] internal sealed class EmitILOverloadsAttribute : Attribute { public EmitILOverloadsAttribute(string filename, string kind) { } } internal static class ILOverloadKind { public const string Cursor = "ILCursor"; public const string Matcher = "ILMatcher"; } } namespace MonoMod.ModInterop { [AttributeUsage(AttributeTargets.Class)] public sealed class ModExportNameAttribute : Attribute { public string Name { get; } public ModExportNameAttribute(string name) { Name = name; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field)] public sealed class ModImportNameAttribute : Attribute { public string Name { get; } public ModImportNameAttribute(string name) { Name = name; } } public static class ModInteropManager { private static HashSet<Type> Registered = new HashSet<Type>(); private static Dictionary<string, List<MethodInfo>> Methods = new Dictionary<string, List<MethodInfo>>(); private static List<FieldInfo> Fields = new List<FieldInfo>(); public static void ModInterop(this Type type) { Helpers.ThrowIfArgumentNull(type, "type"); if (Registered.Contains(type)) { return; } Registered.Add(type); string name = type.Assembly.GetName().Name; object[] customAttributes = type.GetCustomAttributes(typeof(ModExportNameAttribute), inherit: false); for (int i = 0; i < customAttributes.Length; i++) { name = ((ModExportNameAttribute)customAttributes[i]).Name; } FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType)) { Fields.Add(fieldInfo); } } MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo method in methods) { method.RegisterModExport(); method.RegisterModExport(name); } foreach (FieldInfo field in Fields) { if (!Methods.TryGetValue(field.GetModImportName(), out List<MethodInfo> value)) { field.SetValue(null, null); continue; } bool flag = false; foreach (MethodInfo item in value) { try { field.SetValue(null, Delegate.CreateDelegate(field.FieldType, null, item)); flag = true; } catch { continue; } break; } if (!flag) { field.SetValue(null, null); } } } public static void RegisterModExport(this MethodInfo method, string? prefix = null) { Helpers.ThrowIfArgumentNull(method, "method"); if (!method.IsPublic || !method.IsStatic) { throw new MemberAccessException("Utility must be public static"); } string text = method.Name; if (!string.IsNullOrEmpty(prefix)) { text = prefix + "." + text; } if (!Methods.TryGetValue(text, out List<MethodInfo> value)) { value = (Methods[text] = new List<MethodInfo>()); } if (!value.Contains(method)) { value.Add(method); } } private static string GetModImportName(this FieldInfo field) { object[] customAttributes = field.GetCustomAttributes(typeof(ModImportNameAttribute), inherit: false); int num = 0; if (num < customAttributes.Length) { return ((ModImportNameAttribute)customAttributes[num]).Name; } if ((object)field.DeclaringType != null) { customAttributes = field.DeclaringType.GetCustomAttributes(typeof(ModImportNameAttribute), inherit: false); num = 0; if (num < customAttributes.Length) { return ((ModImportNameAttribute)customAttributes[num]).Name + "." + field.Name; } } return field.Name; } } } namespace MonoMod.Logs { public static class DebugFormatter { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CanDebugFormat<T>(in T value, out object? extraData) { extraData = null; if (typeof(T) == typeof(Type)) { return true; } if (typeof(T) == typeof(MethodBase)) { return true; } if (typeof(T) == typeof(MethodInfo)) { return true; } if (typeof(T) == typeof(ConstructorInfo)) { return true; } if (typeof(T) == typeof(FieldInfo)) { return true; } if (typeof(T) == typeof(PropertyInfo)) { return true; } if (typeof(T) == typeof(Exception)) { return true; } if (typeof(T) == typeof(IDebugFormattable)) { return true; } T val = value; if ((val is Type || val is MethodBase || val is FieldInfo || val is PropertyInfo) ? true : false) { return true; } if (value is Exception ex) { extraData = ex.ToString(); return true; } if (value is IDebugFormattable) { return true; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryFormatInto<T>(in T value, object? extraData, Span<char> into, out int wrote) { if (default(T) == null && value == null) { wrote = 0; return true; } if (typeof(T) == typeof(Type)) { return TryFormatType(Transmute<Type>(in value), into, out wrote); } if (typeof(T) == typeof(MethodInfo)) { return TryFormatMethodInfo(Transmute<MethodInfo>(in value), into, out wrote); } if (typeof(T) == typeof(ConstructorInfo)) { return TryFormatMethodBase(Transmute<ConstructorInfo>(in value), into, out wrote); } if (typeof(T) == typeof(FieldInfo)) { return TryFormatFieldInfo(Transmute<FieldInfo>(in value), into, out wrote); } if (typeof(T) == typeof(PropertyInfo)) { return TryFormatPropertyInfo(Transmute<PropertyInfo>(in value), into, out wrote); } if (typeof(T) == typeof(Exception)) { return TryFormatException(Transmute<Exception>(in value), Unsafe.As<string>(extraData), into, out wrote); } if (typeof(T) == typeof(IDebugFormattable)) { return Transmute<IDebugFormattable>(in value).TryFormatInto(into, out wrote); } if (value is Type type) { return TryFormatType(type, into, out wrote); } if (value is MethodInfo method) { return TryFormatMethodInfo(method, into, out wrote); } if (value is ConstructorInfo method2) { return TryFormatMethodBase(method2, into, out wrote); } if (value is MethodBase method3) { return TryFormatMethodBase(method3, into, out wrote); } if (value is FieldInfo field) { return TryFormatFieldInfo(field, into, out wrote); } if (value is PropertyInfo prop) { return TryFormatPropertyInfo(prop, into, out wrote); } if (value is Exception e) { return TryFormatException(e, Unsafe.As<string>(extraData), into, out wrote); } if (value is IDebugFormattable) { return ((IDebugFormattable)(object)value).TryFormatInto(into, out wrote); } bool flag = false; bool isEnabled; AssertionInterpolatedStringHandler message = new AssertionInterpolatedStringHandler(48, 1, flag, out isEnabled); if (isEnabled) { message.AppendLiteral("Called TryFormatInto with value of unknown type "); message.AppendFormatted(value.GetType()); } Helpers.Assert(flag, ref message, "false"); wrote = 0; return false; [MethodImpl(MethodImplOptions.AggressiveInlining)] static ref TOut Transmute<TOut>(in T val) { return ref Unsafe.As<T, TOut>(ref Unsafe.AsRef(in val)); } } private static bool TryFormatException(Exception e, string? eStr, Span<char> into, out int wrote) { wrote = 0; if (eStr == null) { eStr = e.ToString(); } string newLine = Environment.NewLine; if (into.Slice(wrote).Length < eStr.Length) { return false; } eStr.AsSpan().CopyTo(into.Slice(wrote)); wrote += eStr.Length; int wrote2; if (e is ReflectionTypeLoadException ex) { for (int i = 0; i < 4 && i < ex.Types.Length; i++) { Span<char> span = into.Slice(wrote); Span<char> span2 = span; bool enabled; FormatIntoInterpolatedStringHandler handler = new FormatIntoInterpolatedStringHandler(56, 3, span, out enabled); if (enabled && handler.AppendFormatted(newLine) && handler.AppendLiteral("System.Reflection.ReflectionTypeLoadException.Types[") && handler.AppendFormatted(i) && handler.AppendLiteral("] = ")) { handler.AppendFormatted(ex.Types[i]); } else _ = 0; if (!Into(span2, out wrote2, ref handler)) { return false; } wrote += wrote2; } if (ex.Types.Length >= 4) { Span<char> span = into.Slice(wrote); Span<char> span3 = span; bool enabled2; FormatIntoInterpolatedStringHandler handler2 = new FormatIntoInterpolatedStringHandler(62, 1, span, out enabled2); if (enabled2 && handler2.AppendFormatted(newLine)) { handler2.AppendLiteral("System.Reflection.ReflectionTypeLoadException.Types[...] = ..."); } else _ = 0; if (!Into(span3, out wrote2, ref handler2)) { return false; } wrote += wrote2; } if (ex.LoaderExceptions.Length != 0) { if (into.Slice(wrote).Length < newLine.Length + "System.Reflection.ReflectionTypeLoadException.LoaderExceptions = [".Length) { return false; } newLine.AsSpan().CopyTo(into.Slice(wrote)); wrote += newLine.Length; "System.Reflection.ReflectionTypeLoadException.LoaderExceptions = [".AsSpan().CopyTo(into.Slice(wrote)); wrote += "System.Reflection.ReflectionTypeLoadException.LoaderExceptions = [".Length; for (int j = 0; j < ex.LoaderExceptions.Length; j++) { Exception ex2 = ex.LoaderExceptions[j]; if (ex2 != null) { if (into.Slice(wrote).Length < newLine.Length) { return false; } newLine.AsSpan().CopyTo(into.Slice(wrote)); wrote += newLine.Length; if (!TryFormatException(ex2, null, into.Slice(wrote), out wrote2)) { return false; } wrote += wrote2; } } if (into.Slice(wrote).Length < newLine.Length + 1) { return false; } newLine.AsSpan().CopyTo(into.Slice(wrote)); wrote += newLine.Length; into[wrote++] = ']'; } } if (e is TypeLoadException ex3) { Span<char> span = into.Slice(wrote); Span<char> span4 = span; bool enabled3; FormatIntoInterpolatedStringHandler handler3 = new FormatIntoInterpolatedStringHandler(36, 2, span, out enabled3); if (enabled3 && handler3.AppendFormatted(newLine) && handler3.AppendLiteral("System.TypeLoadException.TypeName = ")) { handler3.AppendFormatted(ex3.TypeName); } else _ = 0; if (!Into(span4, out wrote2, ref handler3)) { return false; } wrote += wrote2; } if (e is BadImageFormatException ex4) { Span<char> span = into.Slice(wrote); Span<char> span5 = span; bool enabled4; FormatIntoInterpolatedStringHandler handler4 = new FormatIntoInterpolatedStringHandler(42, 2, span, out enabled4); if (enabled4 && handler4.AppendFormatted(newLine) && handler4.AppendLiteral("System.BadImageFormatException.FileName = ")) { handler4.AppendFormatted(ex4.FileName); } else _ = 0; if (!Into(span5, out wrote2, ref handler4)) { return false; } wrote += wrote2; } return true; } private static bool TryFormatType(Type type, Span<char> into, out int wrote) { wrote = 0; string text; if (type.HasElementType && type.GetElementType() == null) { text = type.Name; } else { string fullName = type.FullName; if (fullName == null) { return true; } text = fullName; } if (into.Length < text.Length) { return false; } text.AsSpan().CopyTo(into); wrote = text.Length; return true; } private static bool TryFormatMethodInfo(MethodInfo method, Span<char> into, out int wrote) { Type returnType = method.ReturnType; wrote = 0; if (!TryFormatType(returnType, into.Slice(wrote), out var wrote2)) { return false; } wrote += wrote2; if (into.Slice(wrote).Length < 1) { return false; } into[wrote++] = ' '; if (!TryFormatMethodBase(method, into.Slice(wrote), out wrote2)) { return false; } wrote += wrote2; return true; } private static bool TryFormatMemberInfoName(MemberInfo member, Span<char> into, out int wrote) { wrote = 0; Type declaringType = member.DeclaringType; if ((object)declaringType != null) { if (!TryFormatType(declaringType, into.Slice(wrote), out var wrote2)) { return false; } wrote += wrote2; if (into.Slice(wrote).Length < 1) { return false; } into[wrote++] = ':'; } string name = member.Name; if (into.Slice(wrote).Length < name.Length) { return false; } name.AsSpan().CopyTo(into.Slice(wrote)); wrote += name.Length; return true; } private static bool TryFormatMethodBase(MethodBase method, Span<char> into, out int wrote) { wrote = 0; if (!TryFormatMemberInfoName(method, into.Slice(wrote), out var wrote2)) { return false; } wrote += wrote2; if (method.IsGenericMethod) { if (into.Slice(wrote).Length < 1) { return false; } into[wrote++] = '<'; Type[] genericArguments = method.GetGenericArguments(); for (int i = 0; i < genericArguments.Length; i++) { if (i != 0) { if (into.Slice(wrote).Length < 2) { return false; } into[wrote++] = ','; into[wrote++] = ' '; } if (!TryFormatType(genericArguments[i], into.Slice(wrote), out wrote2)) { return false; } wrote += wrote2; } if (into.Slice(wrote).Length < 1) { return false; } into[wrote++] = '>'; } ParameterInfo[] parameters = method.GetParameters(); if (into.Slice(wrote).Length < 1) { return false; } into[wrote++] = '('; for (int j = 0; j < parameters.Length; j++) { if (j != 0) { if (into.Slice(wrote).Length < 2) { return false; } into[wrote++] = ','; into[wrote++] = ' '; } if (!TryFormatType(parameters[j].ParameterType, into.Slice(wrote), out wrote2)) { return false; } wrote += wrote2; } if (into.Slice(wrote).Length < 1) { return false; } into[wrote++] = ')'; return true; } private static bool TryFormatFieldInfo(FieldInfo field, Span<char> into, out int wrote) { wrote = 0; if (!TryFormatType(field.FieldType, into.Slice(wrote), out var wrote2)) { return false; } wrote += wrote2; if (into.Slice(wrote).Length < 1) { return false; } into[wrote++] = ' '; if (!TryFormatMemberInfoName(field, into.Slice(wrote), out wrote2)) { return false; } wrote += wrote2; return true; } private static bool TryFormatPropertyInfo(PropertyInfo prop, Span<char> into, out int wrote) { wrote = 0; if (!TryFormatType(prop.PropertyType, into.Slice(wrote), out var wrote2)) { return false; } wrote += wrote2; if (into.Slice(wrote).Length < 1) { return false; } into[wrote++] = ' '; if (!TryFormatMemberInfoName(prop, into.Slice(wrote), out wrote2)) { return false; } wrote += wrote2; bool canRead = prop.CanRead; bool canWrite = prop.CanWrite; int num = 5 + (canRead ? 4 : 0) + (canWrite ? 4 : 0) + ((canRead && canWrite) ? 1 : 0); if (into.Slice(wrote).Length < num) { return false; } " { ".AsSpan().CopyTo(into.Slice(wrote)); wrote += 3; if (canRead) { "get;".AsSpan().CopyTo(into.Slice(wrote)); wrote += 4; } if (canRead && canWrite) { into[wrote++] = ' '; } if (canWrite) { "set;".AsSpan().CopyTo(into.Slice(wrote)); wrote += 4; } " }".AsSpan().CopyTo(into.Slice(wrote)); wrote += 2; return true; } public static string Format(ref FormatInterpolatedStringHandler handler) { return handler.ToStringAndClear(); } public static bool Into(Span<char> into, out int wrote, [InterpolatedStringHandlerArgument("into")] ref FormatIntoInterpolatedStringHandler handler) { wrote = handler.pos; return !handler.incomplete; } } [InterpolatedStringHandler] public ref struct FormatInterpolatedStringHandler { private DebugLogInterpolatedStringHandler handler; [MethodImpl(MethodImplOptions.AggressiveInlining)] public FormatInterpolatedStringHandler(int literalLen, int formattedCount) { handler = new DebugLogInterpolatedStringHandler(literalLen, formattedCount, enabled: true, recordHoles: false, out var _); } public override string ToString() { return handler.ToString(); } public string ToStringAndClear() { return handler.ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string s) { handler.AppendLiteral(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s) { handler.AppendFormatted(s); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(ReadOnlySpan<char> s, int alignment = 0, string? format = null) { handler.AppendFormatted(s, alignment, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value) { handler.AppendFormatted(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { handler.AppendFormatted(value, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { handler.AppendFormatted(value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { handler.AppendFormatted(value, alignment, format); } } public readonly record struct MessageHole { public int Start { get; } public int End { get; } public object? Value { get; } public bool IsValueUnrepresentable { get; } public MessageHole(int start, int end) { Value = null; IsValueUnrepresentable = true; Start = start; End = end; } public MessageHole(int start, int end, object? value) { Value = value; IsValueUnrepresentable = false; Start = start; End = end; } } public sealed class DebugLog { public delegate void OnLogMessage(string source, DateTime time, LogLevel level, string message); public delegate void OnLogMessageDetailed(string source, DateTime time, LogLevel level, string formattedMessage, ReadOnlyMemory<MessageHole> holes); private sealed class LogMessage { public string Source { get; private set; } public DateTime Time { get; private set; } public LogLevel Level { get; private set; } public string FormattedMessage { get; private set; } public ReadOnlyMemory<MessageHole> FormatHoles { get; private set; } public LogMessage(string source, DateTime time, LogLevel level, string formatted, ReadOnlyMemory<MessageHole> holes) { Source = source; Time = time; Level = level; FormattedMessage = formatted; FormatHoles = holes; } public void Clear() { Source = ""; Time = default(DateTime); Level = LogLevel.Spam; FormattedMessage = ""; FormatHoles = default(ReadOnlyMemory<MessageHole>); } public void Init(string source, DateTime time, LogLevel level, string formatted, ReadOnlyMemory<MessageHole> holes) { Source = source; Time = time; Level = level; FormattedMessage = formatted; FormatHoles = holes; } public void ReportTo(OnLogMessage del) { try { del(Source, Time, Level, FormattedMessage); } catch (Exception ex) { Debugger.Log(int.MaxValue, "MonoMod.DebugLog", "Exception caught while reporting to message handler"); Debugger.Log(int.MaxValue, "MonoMod.DebugLog", ex.ToString()); } } public void ReportTo(OnLogMessageDetailed del) { try { del(Source, Time, Level, FormattedMessage, FormatHoles); } catch (Exception ex) { Debugger.Log(int.MaxValue, "MonoMod.DebugLog", "Exception caught while reporting to message handler"); Debugger.Log(int.MaxValue, "MonoMod.DebugLog", ex.ToString()); } } } private sealed class LevelSubscriptions { public LogLevelFilter ActiveLevels; public LogLevelFilter DetailLevels; public readonly OnLogMessage?[] SimpleRegs; public readonly OnLogMessageDetailed?[] DetailedRegs; private const LogLevelFilter ValidFilter = LogLevelFilter.Spam | LogLevelFilter.Trace | LogLevelFilter.Info | LogLevelFilter.Warning | LogLevelFilter.Error | LogLevelFilter.Assert; public static readonly LevelSubscriptions None = new LevelSubscriptions(); private LevelSubscriptions(LogLevelFilter active, LogLevelFilter detail, OnLogMessage?[] simple, OnLogMessageDetailed?[] detailed) { ActiveLevels = active | detail; DetailLevels = detail; SimpleRegs = simple; DetailedRegs = detailed; } private LevelSubscriptions() { ActiveLevels = LogLevelFilter.None; DetailLevels = LogLevelFilter.None; SimpleRegs = new OnLogMessage[6]; DetailedRegs = new OnLogMessageDetailed[SimpleRegs.Length]; } private LevelSubscriptions Clone(bool changingDetail) { OnLogMessage[] array = SimpleRegs; OnLogMessageDetailed[] array2 = DetailedRegs; if (!changingDetail) { array = new OnLogMessage[SimpleRegs.Length]; Array.Copy(SimpleRegs, array, array.Length); } else { array2 = new OnLogMessageDetailed[DetailedRegs.Length]; Array.Copy(DetailedRegs, array2, array2.Length); } return new LevelSubscriptions(ActiveLevels, DetailLevels, array, array2); } private void FixFilters() { ActiveLevels &= LogLevelFilter.Spam | LogLevelFilter.Trace | LogLevelFilter.Info | LogLevelFilter.Warning | LogLevelFilter.Error | LogLevelFilter.Assert; DetailLevels &= LogLevelFilter.Spam | LogLevelFilter.Trace | LogLevelFilter.Info | LogLevelFilter.Warning | LogLevelFilter.Error | LogLevelFilter.Assert; } public LevelSubscriptions AddSimple(LogLevelFilter filter, OnLogMessage del) { LevelSubscriptions levelSubscriptions = Clone(changingDetail: false); levelSubscriptions.ActiveLevels |= filter; for (int i = 0; i < levelSubscriptions.SimpleRegs.Length; i++) { if (((uint)filter & (uint)(1 << i)) != 0) { Helpers.EventAdd(ref levelSubscriptions.SimpleRegs[i], del); } } levelSubscriptions.FixFilters(); return levelSubscriptions; } public LevelSubscriptions RemoveSimple(LogLevelFilter filter, OnLogMessage del) { LevelSubscriptions levelSubscriptions = Clone(changingDetail: false); for (int i = 0; i < levelSubscriptions.SimpleRegs.Length; i++) { if (((uint)filter & (uint)(1 << i)) != 0 && Helpers.EventRemove(ref levelSubscriptions.SimpleRegs[i], del) == null) { levelSubscriptions.ActiveLevels &= (LogLevelFilter)(~(1 << i)); } } levelSubscriptions.ActiveLevels |= levelSubscriptions.DetailLevels; levelSubscriptions.FixFilters(); return levelSubscriptions; } public LevelSubscriptions AddDetailed(LogLevelFilter filter, OnLogMessageDetailed del) { LevelSubscriptions levelSubscriptions = Clone(changingDetail: true); levelSubscriptions.DetailLevels |= filter; for (int i = 0; i < levelSubscriptions.DetailedRegs.Length; i++) { if (((uint)filter & (uint)(1 << i)) != 0) { Helpers.EventAdd(ref levelSubscriptions.DetailedRegs[i], del); } } levelSubscriptions.ActiveLevels |= levelSubscriptions.DetailLevels; levelSubscriptions.FixFilters(); return levelSubscriptions; } public LevelSubscriptions RemoveDetailed(LogLevelFilter filter, OnLogMessageDetailed del) { LevelSubscriptions levelSubscriptions = Clone(changingDetail: true); for (int i = 0; i < levelSubscriptions.DetailedRegs.Length; i++) { if (((uint)filter & (uint)(1 << i)) != 0 && Helpers.EventRemove(ref levelSubscriptions.DetailedRegs[i], del) == null) { levelSubscriptions.DetailLevels &= (LogLevelFilter)(~(1 << i)); } } levelSubscriptions.ActiveLevels |= levelSubscriptions.DetailLevels; levelSubscriptions.FixFilters(); return levelSubscriptions; } } private sealed class LogSubscriptionSimple : IDisposable { private readonly DebugLog log; private readonly OnLogMessage del; private readonly LogLevelFilter filter; public LogSubscriptionSimple(DebugLog log, OnLogMessage del, LogLevelFilter filter) { this.log = log; this.del = del; this.filter = filter; } public void Dispose() { LevelSubscriptions subscriptions; LevelSubscriptions value; do { subscriptions = log.subscriptions; value = subscriptions.RemoveSimple(filter, del); } while (Interlocked.CompareExchange(ref log.subscriptions, value, subscriptions) != subscriptions); } } private sealed class LogSubscriptionDetailed : IDisposable { private readonly DebugLog log; private readonly OnLogMessageDetailed del; private readonly LogLevelFilter filter; public LogSubscriptionDetailed(DebugLog log, OnLogMessageDetailed del, LogLevelFilter filter) { this.log = log; this.del = del; this.filter = filter; } public void Dispose() { LevelSubscriptions subscriptions; LevelSubscriptions value; do { subscriptions = log.subscriptions; value = subscriptions.RemoveDetailed(filter, del); } while (Interlocked.CompareExchange(ref log.subscriptions, value, subscriptions) != subscriptions); } } internal static readonly DebugLog Instance = new DebugLog(); private static readonly ConcurrentBag<WeakReference<LogMessage>> weakRefCache = new ConcurrentBag<WeakReference<LogMessage>>(); private static readonly ConcurrentBag<WeakReference<LogMessage>> messageObjectCache = new ConcurrentBag<WeakReference<LogMessage>>(); private static readonly char[] listEnvSeparator = new char[3] { ' ', ';', ',' }; private readonly bool recordHoles; private readonly int replayQueueLength; private readonly ConcurrentQueue<LogMessage>? replayQueue; private LogLevelFilter globalFilter = LogLevelFilter.DefaultFilter; private static byte[]? memlog; private static int memlogPos; private LevelSubscriptions subscriptions = LevelSubscriptions.None; private static readonly ConcurrentDictionary<OnLogMessage, IDisposable> simpleRegDict = new ConcurrentDictionary<OnLogMessage, IDisposable>(); public static bool IsFinalizing { get { if (!Environment.HasShutdownStarted) { return AppDomain.CurrentDomain.IsFinalizingForUnload(); } return true; } } public static bool IsWritingLog => Instance.ShouldLog; internal bool AlwaysLog { get { if (replayQueue == null) { return Debugger.IsAttached; } return true; } } internal bool ShouldLog { get { if (subscriptions.ActiveLevels == LogLevelFilter.None) { return AlwaysLog; } return true; } } internal bool RecordHoles { get { if (!recordHoles) { return subscriptions.DetailLevels != LogLevelFilter.None; } return true; } } public static event OnLogMessage OnLog { add { IDisposable res = Subscribe(Instance.globalFilter, value); simpleRegDict.AddOrUpdate(value, res, delegate(OnLogMessage _, IDisposable d) { d.Dispose(); return res; }); } remove { if (simpleRegDict.TryRemove(value, out IDisposable value2)) { value2.Dispose(); } } } private LogMessage MakeMessage(string source, DateTime time, LogLevel level, string formatted, ReadOnlyMemory<MessageHole> holes) { try { if (replayQueue == null && !IsFinalizing) { WeakReference<LogMessage> result; while (messageObjectCache.TryTake(out result)) { if (result.TryGetTarget(out var target)) { target.Init(source, time, level, formatted, holes); weakRefCache.Add(result); return target; } weakRefCache.Add(result); } } } catch { } return new LogMessage(source, time, level, formatted, holes); } private void ReturnMessage(LogMessage message) { message.Clear(); try { if (replayQueue == null && !IsFinalizing) { if (weakRefCache.TryTake(out WeakReference<LogMessage> result)) { result.SetTarget(message); messageObjectCache.Add(result); } else { messageObjectCache.Add(new WeakReference<LogMessage>(message)); } } } catch { } } private void PostMessage(LogMessage message) { if (Debugger.IsAttached) { try { LogLevel level = message.Level; string source = message.Source; FormatInterpolatedStringHandler handler = new FormatInterpolatedStringHandler(6, 3); handler.AppendLiteral("["); handler.AppendFormatted(message.Source); handler.AppendLiteral("] "); handler.AppendFormatted(message.Level.FastToString()); handler.AppendLiteral(": "); handler.AppendFormatted(message.FormattedMessage); handler.AppendLiteral("\n"); Debugger.Log((int)level, source, DebugFormatter.Format(ref handler)); } catch { } } try { LevelSubscriptions levelSubscriptions = subscriptions; int level2 = (int)message.Level; OnLogMessage onLogMessage = levelSubscriptions.SimpleRegs[level2]; if (onLogMessage != null) { message.ReportTo(onLogMessage); } OnLogMessageDetailed onLogMessageDetailed = levelSubscriptions.DetailedRegs[level2]; if (onLogMessageDetailed != null) { message.ReportTo(onLogMessageDetailed); } if (IsFinalizing) { return; } ConcurrentQueue<LogMessage> concurrentQueue = replayQueue; if (concurrentQueue != null) { concurrentQueue.Enqueue(message); LogMessage result; while (concurrentQueue.Count > replayQueueLength && concurrentQueue.TryDequeue(out result)) { } } else { ReturnMessage(message); } } catch { } } internal bool ShouldLogLevel(LogLevel level) { if (((uint)(1 << (int)level) & (uint)subscriptions.ActiveLevels) == 0) { if (((uint)(1 << (int)level) & (uint)globalFilter) != 0) { return AlwaysLog; } return false; } return true; } internal bool ShouldLevelRecordHoles(LogLevel level) { if (!recordHoles) { return ((uint)(1 << (int)level) & (uint)subscriptions.DetailLevels) != 0; } return true; } public void Write(string source, DateTime time, LogLevel level, string message) { if (ShouldLogLevel(level)) { PostMessage(MakeMessage(source, time, level, message, default(ReadOnlyMemory<MessageHole>))); } } public void Write(string source, DateTime time, LogLevel level, [InterpolatedStringHandlerArgument("level")] ref DebugLogInterpolatedStringHandler message) { if (message.enabled && ShouldLogLevel(level)) { ReadOnlyMemory<MessageHole> holes; string formatted = message.ToStringAndClear(out holes); PostMessage(MakeMessage(source, time, level, formatted, holes)); } } internal void LogCore(string source, LogLevel level, string message) { if (ShouldLogLevel(level)) { Write(source, DateTime.UtcNow, level, message); } } internal void LogCore(string source, LogLevel level, [InterpolatedStringHandlerArgument("level")] ref DebugLogInterpolatedStringHandler message) { if (message.enabled && ShouldLogLevel(level)) { Write(source, DateTime.UtcNow, level, ref message); } } public static void Log(string source, LogLevel level, string message) { DebugLog instance = Instance; if (instance.ShouldLogLevel(level)) { instance.Write(source, DateTime.UtcNow, level, message); } } public static void Log(string source, LogLevel level, [InterpolatedStringHandlerArgument("level")] ref DebugLogInterpolatedStringHandler message) { DebugLog instance = Instance; if (message.enabled && instance.ShouldLogLevel(level)) { instance.Write(source, DateTime.UtcNow, level, ref message); } } private static string[]? GetListEnvVar(string text) { string text2 = text.Trim(); if (string.IsNullOrEmpty(text2)) { return null; } string[] array = text2.Split(listEnvSeparator, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { array[i] = array[i].Trim(); } return array; } private DebugLog() { recordHoles = Switches.TryGetSwitchEnabled("LogRecordHoles", out var isEnabled) && isEnabled; replayQueueLength = 0; if (Switches.TryGetSwitchValue("LogReplayQueueLength", out object value)) { replayQueueLength = (value as int?).GetValueOrDefault(); } if (Switches.TryGetSwitchEnabled("LogSpam", out isEnabled) && isEnabled) { globalFilter |= LogLevelFilter.Spam; } if (replayQueueLength > 0) { replayQueue = new ConcurrentQueue<LogMessage>(); } string text = (Switches.TryGetSwitchValue("LogToFile", out value) ? (value as string) : null); string[] sourceFilter = null; if (Switches.TryGetSwitchValue("LogToFileFilter", out value)) { sourceFilter = ((value is string[] array) ? array : ((!(value is string text2)) ? null : GetListEnvVar(text2))); } if (text != null) { TryInitializeLogToFile(text, sourceFilter, globalFilter); } if (Switches.TryGetSwitchEnabled("LogInMemory", out isEnabled) && isEnabled) { TryInitializeMemoryLog(globalFilter); } } private void TryInitializeLogToFile(string file, string[]? sourceFilter, LogLevelFilter filter) { try { StringComparer comparer = StringComparerEx.FromComparison(StringComparison.OrdinalIgnoreCase); if (sourceFilter != null) { Array.Sort(sourceFilter, (IComparer<string>?)comparer); } object sync = new object(); TextWriter writer; if (file == "-") { writer = Console.Out; } else { FileStream stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Write); writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true }; } SubscribeCore(filter, delegate(string source, DateTime time, LogLevel level2, string msg) { if (sourceFilter != null && sourceFilter.AsSpan().BinarySearch(source, comparer) < 0) { return; } DateTime value2 = time.ToLocalTime(); string value3 = $"[{source}]({value2}) {level2.FastToString()}: {msg}"; lock (sync) { writer.WriteLine(value3); } }); } catch (Exception value) { LogLevel logLevel = LogLevel.Error; LogLevel level = logLevel; bool isEnabled; DebugLogInterpolatedStringHandler message = new DebugLogInterpolatedStringHandler(61, 1, logLevel, out isEnabled); if (isEnabled) { message.AppendLiteral("Exception while trying to initialize writing logs to a file: "); message.AppendFormatted(value); } Instance.LogCore("DebugLog", level, ref message); } } private void TryInitializeMemoryLog(LogLevelFilter filter) { try { memlogPos = 0; memlog = new byte[4096]; object sync = new object(); _ = Encoding.UTF8; SubscribeCore(filter, delegate(string source, DateTime time, LogLevel logLevel2, string msg) { byte value2 = (byte)logLevel2; long ticks = time.Ticks; if (source.Length > 255) { source = source.Substring(0, 255); } byte b = (byte)source.Length; int length = msg.Length; int num = 14 + b * 2 + length * 2; lock (sync) { if (memlog.Length - memlogPos < num) { int num2 = memlog.Length * 4; while (num2 - memlogPos < num) { num2 *= 4; } Array.Resize(ref memlog, num2); } ref byte reference = ref MemoryMarshal.GetReference(memlog.AsSpan().Slice(memlogPos)); int num3 = 0; Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num3), value2); num3++; Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num3), ticks); num3 += 8; Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num3), b); num3++; Unsafe.CopyBlock(ref Unsafe.Add(ref reference, num3), in Unsafe.As<char, byte>(ref MemoryMarshal.GetReference(source.AsSpan())), (uint)(b * 2)); num3 += b * 2; Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num3), length); num3 += 4; Unsafe.CopyBlock(ref Unsafe.Add(ref reference, num3), in Unsafe.As<char, byte>(ref MemoryMarshal.GetReference(msg.AsSpan())), (uint)(length * 2)); num3 += length * 2; memlogPos += num3; } }); } catch (Exception value) { LogLevel logLevel = LogLevel.Error; LogLevel level = logLevel; bool isEnabled; DebugLogInterpolatedStringHandler message = new DebugLogInterpolatedStringHandler(45, 1, logLevel, out isEnabled); if (isEnabled) { message.AppendLiteral("Exception while initializing the memory log: "); message.AppendFormatted(value); } Instance.LogCore("DebugLog", level, ref message); } } private void MaybeReplayTo(LogLevelFilter filter, OnLogMessage del) { if (replayQueue == null || filter == LogLevelFilter.None) { return; } LogMessage[] array = replayQueue.ToArray(); foreach (LogMessage logMessage in array) { if (((uint)(1 << (int)logMessage.Level) & (uint)filter) != 0) { logMessage.ReportTo(del); } } } private void MaybeReplayTo(LogLevelFilter filter, OnLogMessageDetailed del) { if (replayQueue == null || filter == LogLevelFilter.None) { return; } LogMessage[] array = replayQueue.ToArray(); foreach (LogMessage logMessage in array) { if (((uint)(1 << (int)logMessage.Level) & (uint)filter) != 0) { logMessage.ReportTo(del); } } } public static IDisposable Subscribe(LogLevelFilter filter, OnLogMessage value) { return Instance.SubscribeCore(filter, value); } private IDisposable SubscribeCore(LogLevelFilter filter, OnLogMessage value) { LevelSubscriptions levelSubscriptions; LevelSubscriptions value2; do { levelSubscriptions = subscriptions; value2 = levelSubscriptions.AddSimple(filter, value); } while (Interlocked.CompareExchange(ref subscriptions, value2, levelSubscriptions) != levelSubscriptions); MaybeReplayTo(filter, value); return new LogSubscriptionSimple(this, value, filter); } public static IDisposable Subscribe(LogLevelFilter filter, OnLogMessageDetailed value) { return Instance.SubscribeCore(filter, value); } private IDisposable SubscribeCore(LogLevelFilter filter, OnLogMessageDetailed value) { LevelSubscriptions levelSubscriptions; LevelSubscriptions value2; do { levelSubscriptions = subscriptions; value2 = levelSubscriptions.AddDetailed(filter, value); } while (Interlocked.CompareExchange(ref subscriptions, value2, levelSubscriptions) != levelSubscriptions); MaybeReplayTo(filter, value); return new LogSubscriptionDetailed(this, value, filter); } } [InterpolatedStringHandler] public ref struct DebugLogInterpolatedStringHandler { private const int GuessedLengthPerHole = 11; private const int MinimumArrayPoolLength = 256; private char[]? _arrayToReturnToPool; private Span<char> _chars; private int _pos; private int holeBegin; private int holePos; private Memory<MessageHole> holes; internal readonly bool enabled; internal ReadOnlySpan<char> Text => _chars.Slice(0, _pos); public DebugLogInterpolatedStringHandler(int literalLength, int formattedCount, bool enabled, bool recordHoles, out bool isEnabled) { _pos = (holeBegin = (holePos = 0)); this.enabled = (isEnabled = enabled); if (enabled) { _chars = (_arrayToReturnToPool = ArrayPool<char>.Shared.Rent(GetDefaultLength(literalLength, formattedCount))); if (recordHoles) { holes = new MessageHole[formattedCount]; } else { holes = default(Memory<MessageHole>); } } else { _chars = (_arrayToReturnToPool = null); holes = default(Memory<MessageHole>); } } public DebugLogInterpolatedStringHandler(int literalLength, int formattedCount, out bool isEnabled) { DebugLog instance = DebugLog.Instance; _pos = (holeBegin = (holePos = 0)); if (instance.ShouldLog) { enabled = (isEnabled = true); _chars = (_arrayToReturnToPool = ArrayPool<char>.Shared.Rent(GetDefaultLength(literalLength, formattedCount))); if (instance.RecordHoles) { holes = new MessageHole[formattedCount]; } else { holes = default(Memory<MessageHole>); } } else { enabled = (isEnabled = false); _chars = (_arrayToReturnToPool = null); holes = default(Memory<MessageHole>); } } public DebugLogInterpolatedStringHandler(int literalLength, int formattedCount, LogLevel level, out bool isEnabled) { DebugLog instance = DebugLog.Instance; _pos = (holeBegin = (holePos = 0)); if (instance.ShouldLogLevel(level)) { enabled = (isEnabled = true); _chars = (_arrayToReturnToPool = ArrayPool<char>.Shared.Rent(GetDefaultLength(literalLength, formattedCount))); if (instance.ShouldLevelRecordHoles(level)) { holes = new MessageHole[formattedCount]; } else { holes = default(Memory<MessageHole>); } } else { enabled = (isEnabled = false); _chars = (_arrayToReturnToPool = null); holes = default(Memory<MessageHole>); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int GetDefaultLength(int literalLength, int formattedCount) { return Math.Max(256, literalLength + formattedCount * 11); } public override string ToString() { return Text.ToString(); } public string ToStringAndClear() { string result = Text.ToString(); Clear(); return result; } internal string ToStringAndClear(out ReadOnlyMemory<MessageHole> holes) { holes = this.holes; return ToStringAndClear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Clear() { char[] arrayToReturnToPool = _arrayToReturnToPool; this = default(DebugLogInterpolatedStringHandler); if (arrayToReturnToPool != null) { ArrayPool<char>.Shared.Return(arrayToReturnToPool); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLiteral(string value) { if (value.Length == 1) { Span<char> chars = _chars; int pos = _pos; if ((uint)pos < (uint)chars.Length) { chars[pos] = value[0]; _pos = pos + 1; } else { GrowThenCopyString(value); } } else if (value.Length == 2) { Span<char> chars2 = _chars; int pos2 = _pos; if ((uint)pos2 < chars2.Length - 1) { value.AsSpan().CopyTo(chars2.Slice(pos2)); _pos = pos2 + 2; } else { GrowThenCopyString(value); } } else { AppendStringDirect(value); } } private void AppendStringDirect(string value) { if (value.AsSpan().TryCopyTo(_chars.Slice(_pos))) { _pos += value.Length; } else { GrowThenCopyString(value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void BeginHole() { holeBegin = _pos; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void EndHole(object? obj, bool reprd) { EndHole(in obj, reprd); } [MethodImpl(MethodImplOptions.NoInlining)] private void EndHole<T>(in T obj, bool reprd) { if (!holes.IsEmpty) { holes.Span[holePos++] = (reprd ? new MessageHole(holeBegin, _pos, obj) : new MessageHole(holeBegin, _pos)); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? value) { BeginHole(); if (value != null && value.AsSpan().TryCopyTo(_chars.Slice(_pos))) { _pos += value.Length; } else { AppendFormattedSlow(value); } EndHole(in value, reprd: true); } [MethodImpl(MethodImplOptions.NoInlining)] private void AppendFormattedSlow(string? value) { if (value != null) { EnsureCapacityForAdditionalChars(value.Length); value.AsSpan().CopyTo(_chars.Slice(_pos)); _pos += value.Length; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted(string? value, int alignment = 0, string? format = null) { this.AppendFormatted<string>(value, alignment, format); } public void AppendFormatted(ReadOnlySpan<char> value) { BeginHole(); if (value.TryCopyTo(_chars.Slice(_pos))) { _pos += value.Length; } else { GrowThenCopySpan(value); } EndHole(null, reprd: false); } public void AppendFormatted(ReadOnlySpan<char> value, int alignment = 0, string? format = null) { bool flag = false; if (alignment < 0) { flag = true; alignment = -alignment; } int num = alignment - value.Length; if (num <= 0) { AppendFormatted(value); return; } BeginHole(); EnsureCapacityForAdditionalChars(value.Length + num); if (flag) { value.CopyTo(_chars.Slice(_pos)); _pos += value.Length; _chars.Slice(_pos, num).Fill(' '); _pos += num; } else { _chars.Slice(_pos, num).Fill(' '); _pos += num; value.CopyTo(_chars.Slice(_pos)); _pos += value.Length; } EndHole(null, reprd: false); } public void AppendFormatted<T>(T value) { if (typeof(T) == typeof(nint)) { AppendFormatted(Unsafe.As<T, nint>(ref value)); return; } if (typeof(T) == typeof(nuint)) { AppendFormatted(Unsafe.As<T, nuint>(ref value)); return; } BeginHole(); if (DebugFormatter.CanDebugFormat(in value, out object extraData)) { int wrote; while (!DebugFormatter.TryFormatInto(in value, extraData, _chars.Slice(_pos), out wrote)) { Grow(); } _pos += wrote; return; } string text = ((!(value is IFormattable)) ? value?.ToString() : ((IFormattable)(object)value).ToString(null, null)); if (text != null) { AppendStringDirect(text); } EndHole(in value, reprd: true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void AppendFormatted(nint value) { if (IntPtr.Size == 4) { AppendFormatted((int)value); } else { AppendFormatted((long)value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void AppendFormatted(nint value, string? format) { if (IntPtr.Size == 4) { AppendFormatted((int)value, format); } else { AppendFormatted((long)value, format); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void AppendFormatted(nuint value) { if (UIntPtr.Size == 4) { AppendFormatted((uint)value); } else { AppendFormatted((ulong)value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void AppendFormatted(nuint value, string? format) { if (UIntPtr.Size == 4) { AppendFormatted((uint)value, format); } else { AppendFormatted((ulong)value, format); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment) { int pos = _pos; AppendFormatted(value); if (alignment != 0) { AppendOrInsertAlignmentIfNeeded(pos, alignment); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, string? format) { if (typeof(T) == typeof(nint)) { AppendFormatted(Unsafe.As<T, nint>(ref value), format); return; } if (typeof(T) == typeof(nuint)) { AppendFormatted(Unsafe.As<T, nuint>(ref value), format); return; } BeginHole(); if (DebugFormatter.CanDebugFormat(in value, out object extraData)) { int wrote; while (!DebugFormatter.TryFormatInto(in value, extraData, _chars.Slice(_pos), out wrote)) { Grow(); } _pos += wrote; return; } string text = ((!(value is IFormattable)) ? value?.ToString() : ((IFormattable)(object)value).ToString(format, null)); if (text != null) { AppendStringDirect(text); } EndHole(in value, reprd: true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendFormatted<T>(T value, int alignment, string? format) { int pos = _pos; AppendFormatted(value, format); if (alignment != 0) { AppendOrInsertAlignmentIfNeeded(pos, alignment); } } private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) { int num = _pos - startingPos; bool flag = false; if (alignment < 0) { flag = true; alignment = -alignment; } int num2 = alignment - num; if (num2 > 0) { EnsureCapacityForAdditionalChars(num2); if (flag) { _chars.Slice(_pos, num2).Fill(' '); } else { _chars.Slice(startingPos, num).CopyTo(_chars.Slice(startingPos + num2)); _chars.Slice(startingPos, num2).Fill(' '); } _pos += num2; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void EnsureCapacityForAdditionalChars(int additionalChars) { if (_chars.Length - _pos < additionalChars) { Grow(additionalChars); } } [MethodImpl(MethodImplOptions.NoInlining)] private void GrowThenCopyString(string value) { Grow(value.Length); value.AsSpan().CopyTo(_chars.Slice(_pos)); _pos += value.Length; } [MethodImpl(MethodImplOptions.NoInlining)] private void GrowThenCopySpan(ReadOnlySpan<char> value) { Grow(value.Length); value.CopyTo(_chars.Slice(_pos)); _pos += value.Length; } [MethodImpl(MethodImplOptions.NoInlining)] private void Grow(int additionalChars) { GrowCore((uint)(_pos + additionalChars)); } [MethodImpl(MethodImplOptions.NoInlining)] private void Grow() { GrowCore((uint)(_chars.Length + 1)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void GrowCore(uint requiredMinCapacity) { int minimumLength = (int)MathEx.Clamp(Math.Max(requiredMinCapacity, Math.Min((uint)(_chars.Length * 2), uint.MaxValue)), 256u, 2147483647u); char[] array = ArrayPool<char>.Shared.Rent(minimumLength); _chars.Slice(0, _pos).CopyTo(array); char[] arrayToReturnToPool = _arrayToReturnToPool; _chars = (_arrayToReturnToPool = array); if (arrayToReturnToPool != null) { ArrayPool<char>.Shared.Return(arrayToReturnToPool); } } } [InterpolatedStringHandler] public ref struct FormatIntoInterpolatedStringHandler { private readonly Span<char> _chars; internal int pos; internal bool incomplete; public FormatIntoInterpolatedStringHandler(int literalLen, int numHoles, Span<char> into, out bool enabled) { _chars = into; pos = 0; if (into.Length < literalLen) { incomplete = true; enabled = false; } else { incomplete = false; enabled = true; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool AppendLiteral(string value) { if (value.Length == 1) { Span<char> chars = _chars; int num = pos; if ((uint)num < (uint)chars.Length) { chars[num] = value[0]; pos = num + 1; return true; } incomplete = true; return false; } if (value.Length == 2) { Span<char> chars2 = _chars; int num2 = pos; if ((uint)num2 < chars2.Length - 1) { value.AsSpan().CopyTo(chars2.Slice(num2)); pos = num2 + 2; return true; } incomplete = true; return false; } return AppendStringDirect(value); } private bool AppendStringDirect(string value) { if (value.AsSpan().TryCopyTo(_chars.Slice(pos))) { pos += value.Length; return true; } incomplete = true; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool AppendFormatted(string? value) { if (value == null) { return true; } if (value.AsSpan().TryCopyTo(_chars.Slice(pos))) { pos += value.Length; return true; } incomplete = true; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool AppendFormatted(string? value, int alignment = 0, string? format = null) { return this.AppendFormatted<string>(value, alignment, format); } public bool AppendFormatted(ReadOnlySpan<char> value) { if (value.TryCopyTo(_chars.Slice(pos))) { pos += value.Length; return true; } incomplete = true; return false; } public bool AppendFormatted(ReadOnlySpan<char> value, int alignment = 0, string? format = null) { bool flag = false; if (alignment < 0) { flag = true; alignment = -alignment; } int num = alignment - value.Length; if (num <= 0) { return AppendFormatted(value); } if (_chars.Slice(pos).Length < value.Length + num) { incomplete = true; return false; } if (flag) { value.CopyTo(_chars.Slice(pos)); pos += value.Length; _chars.Slice(pos, num).Fill(' '); pos += num; } else { _chars.Slice(pos, num).Fill(' '); pos += num; value.CopyTo(_chars.Slice(pos)); pos += value.Length; } return true; } public bool AppendFormatted<T>(T value) { if (typeof(T) == typeof(nint)) { return AppendFormatted(Unsafe.As<T, nint>(ref value)); } if (typeof(T) == typeof(nuint)) { return AppendFormatted(Unsafe.As<T, nuint>(ref value)); } if (DebugFormatter.CanDebugFormat(in value, out object extraData)) { if (!DebugFormatter.TryFormatInto(in value, extraData, _chars.Slice(pos), out var wrote)) { incomplete = true; return false; } pos += wrote; return true; } string text = ((!(value is IFormattable)) ? value?.ToString() : ((IFormattable)(object)value).ToString(null, null)); if (text != null) { return AppendStringDirect(text); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool AppendFormatted(nint value) { if (IntPtr.Size == 4) { return AppendFormatted((int)value); } return AppendFormatted((long)value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool AppendFormatted(nint value, string? format) { if (IntPtr.Size == 4) { return AppendFormatted((int)value, format); } return AppendFormatted((long)value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool AppendFormatted(nuint value) { if (UIntPtr.Size == 4) { return AppendFormatted((uint)value); } return AppendFormatted((ulong)value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool AppendFormatted(nuint value, string? format) { if (UIntPtr.Size == 4) { return AppendFormatted((uint)value, format); } return AppendFormatted((ulong)value, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool AppendFormatted<T>(T value, int alignment) { int startingPos = pos; if (!AppendFormatted(value)) { return false; } if (alignment != 0) { return AppendOrInsertAlignmentIfNeeded(startingPos, alignment); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool AppendFormatted<T>(T value, string? format) { if (typeof(T) == typeof(nint)) { return AppendFormatted(Unsafe.As<T, nint>(ref value), format); } if (typeof(T) == typeof(nuint)) { return AppendFormatted(Unsafe.As<T, nuint>(ref value), format); } if (DebugFormatter.CanDebugFormat(in value, out object extraData)) { if (!DebugFormatter.TryFormatInto(in value, extraData, _chars.Slice(pos), out var wrote)) { incomplete = true; return false; } pos += wrote; return true; } string text = ((!(value is IFormattable)) ? value?.ToString() : ((IFormattable)(object)value).ToString(format, null)); if (text != null) { return AppendStringDirect(text); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool AppendFormatted<T>(T value, int alignment, string? format) { int startingPos = pos; if (!AppendFormatted(value, format)) { return false; } if (alignment != 0) { return AppendOrInsertAlignmentIfNeeded(startingPos, alignment); } return true; } private bool AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) { int num = pos - startingPos; bool flag = false; if (alignment < 0) { flag = true; alignment = -alignment; } int num2 = alignment - num; if (num2 > 0) { if (_chars.Slice(pos).Length < num2) { incomplete = true; return false; } if (flag) { _chars.Slice(pos, num2).Fill(' '); } else { _chars.Slice(startingPos, num).CopyTo(_chars.Slice(startingPos + num2)); _chars.Slice(startingPos, num2).Fill(' '); } pos += num2; } return true; } } public interface IDebugFormattable { bool TryFormatInto(Span<char> span, out int wrote); } public enum LogLevel { Spam, Trace, Info, Warning, Error, Assert } [Flags] public enum LogLevelFilter { None = 0, Spam = 1, Trace = 2, Info = 4, Warning = 8, Error = 0x10, Assert = 0x20, DefaultFilter = -2 } public static class LogLevelExtensions { public const LogLevel MaxLevel = LogLevel.Assert; public static string FastToString(this LogLevel level, IFormatProvider? provider = null) { switch (level) { case LogLevel.Spam: return "Spam"; case LogLevel.Trace: return "Trace"; case LogLevel.Info: return "Info"; case LogLevel.Warning: return "Warning"; case LogLevel.Error: return "Error"; case LogLevel.Assert: return "Assert"; default: { int num = (int)level; return num.ToString(provider); } } } } } namespace MonoMod.Cil { [AttributeUsage(AttributeTargets.Method)] internal sealed class GetFastDelegateInvokersArrayAttribute : Attribute { public int MaxParams { get; } public GetFastDelegateInvokersArrayAttribute(int maxParams) { MaxParams = maxParams; } } public static class FastDelegateInvokers { private delegate void VoidVal1<T0>(T0 _0); private delegate TResult TypeVal1<TResult, T0>(T0 _0); private delegate void VoidRef1<T0>(ref T0 _0); private delegate TResult TypeRef1<TResult, T0>(ref T0 _0); private delegate void VoidVal2<T0, T1>(T0 _0, T1 _1); private delegate TResult TypeVal2<TResult, T0, T1>(T0 _0, T1 _1); private delegate void VoidRef2<T0, T1>(ref T0 _0, T1 _1); private delegate TResult TypeRef2<TResult, T0, T1>(ref T0 _0, T1 _1); private delegate void VoidVal3<T0, T1, T2>(T0 _0, T1 _1, T2 _2); private delegate TResult TypeVal3<TResult, T0, T1, T2>(T0 _0, T1 _1, T2 _2); private delegate void VoidRef3<T0, T1, T2>(ref T0 _0, T1 _1, T2 _2); private delegate TResult TypeRef3<TResult, T0, T1, T2>(ref T0 _0, T1 _1, T2 _2); private delegate void VoidVal4<T0, T1, T2, T3>(T0 _0, T1 _1, T2 _2, T3 _3); private delegate TResult TypeVal4<TResult, T0, T1, T2, T3>(T0 _0, T1 _1, T2 _2, T3 _3); private delegate void VoidRef4<T0, T1, T2, T3>(ref T0 _0, T1 _1, T2 _2, T3 _3); private delegate TResult TypeRef4<TResult, T0, T1, T2, T3>(ref T0 _0, T1 _1, T2 _2, T3 _3); private delegate void VoidVal5<T0, T1, T2, T3, T4>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4); private delegate TResult TypeVal5<TResult, T0, T1, T2, T3, T4>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4); private delegate void VoidRef5<T0, T1, T2, T3, T4>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4); private delegate TResult TypeRef5<TResult, T0, T1, T2, T3, T4>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4); private delegate void VoidVal6<T0, T1, T2, T3, T4, T5>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5); private delegate TResult TypeVal6<TResult, T0, T1, T2, T3, T4, T5>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5); private delegate void VoidRef6<T0, T1, T2, T3, T4, T5>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5); private delegate TResult TypeRef6<TResult, T0, T1, T2, T3, T4, T5>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5); private delegate void VoidVal7<T0, T1, T2, T3, T4, T5, T6>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6); private delegate TResult TypeVal7<TResult, T0, T1, T2, T3, T4, T5, T6>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6); private delegate void VoidRef7<T0, T1, T2, T3, T4, T5, T6>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6); private delegate TResult TypeRef7<TResult, T0, T1, T2, T3, T4, T5, T6>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6); private delegate void VoidVal8<T0, T1, T2, T3, T4, T5, T6, T7>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7); private delegate TResult TypeVal8<TResult, T0, T1, T2, T3, T4, T5, T6, T7>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7); private delegate void VoidRef8<T0, T1, T2, T3, T4, T5, T6, T7>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7); private delegate TResult TypeRef8<TResult, T0, T1, T2, T3, T4, T5, T6, T7>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7); private delegate void VoidVal9<T0, T1, T2, T3, T4, T5, T6, T7, T8>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8); private delegate TResult TypeVal9<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8); private delegate void VoidRef9<T0, T1, T2, T3, T4, T5, T6, T7, T8>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8); private delegate TResult TypeRef9<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8); private delegate void VoidVal10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9); private delegate TResult TypeVal10<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9); private delegate void VoidRef10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9); private delegate TResult TypeRef10<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9); private delegate void VoidVal11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10); private delegate TResult TypeVal11<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10); private delegate void VoidRef11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10); private delegate TResult TypeRef11<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10); private delegate void VoidVal12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11); private delegate TResult TypeVal12<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11); private delegate void VoidRef12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11); private delegate TResult TypeRef12<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11); private delegate void VoidVal13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12); private delegate TResult TypeVal13<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12); private delegate void VoidRef13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12); private delegate TResult TypeRef13<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12); private delegate void VoidVal14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13); private delegate TResult TypeVal14<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13); private delegate void VoidRef14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13); private delegate TResult TypeRef14<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13); private delegate void VoidVal15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13, T14 _14); private delegate TResult TypeVal15<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13, T14 _14); private delegate void VoidRef15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13, T14 _14); private delegate TResult TypeRef15<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13, T14 _14); private delegate void VoidVal16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13, T14 _14, T15 _15); private delegate TResult TypeVal16<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13, T14 _14, T15 _15); private delegate void VoidRef16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13, T14 _14, T15 _15); private delegate TResult TypeRef16<TResult, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(ref T0 _0, T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9, T10 _10, T11 _11, T12 _12, T13 _13, T14 _14, T15 _15); private static readonly (MethodInfo, Type)[] invokers = GetInvokers(); private const int MaxFastInvokerParams = 16; private static readonly ConditionalWeakTable<Type, Tuple<MethodInfo?, Type>> invokerCache = new ConditionalWeakTable<Type, Tuple<MethodInfo, Type>>(); [GetFastDelegateInvokersArray(16)] private static (MethodInfo, Type)[] GetInvokers() { return new(MethodInfo, Type)[64] { (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal1", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal1<>)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal1", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal1<, >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef1", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef1<>)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef1", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef1<, >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal2", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal2<, >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal2", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal2<, , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef2", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef2<, >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef2", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef2<, , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal3", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal3<, , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal3", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal3<, , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef3", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef3<, , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef3", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef3<, , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal4", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal4<, , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal4", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal4<, , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef4", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef4<, , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef4", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef4<, , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal5", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal5<, , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal5", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal5<, , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef5", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef5<, , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef5", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef5<, , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal6", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal6<, , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal6", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal6<, , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef6", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef6<, , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef6", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef6<, , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal7", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal7<, , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal7", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal7<, , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef7", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef7<, , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef7", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef7<, , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal8", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal8<, , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal8", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal8<, , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef8", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef8<, , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef8", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef8<, , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal9", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal9<, , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal9", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal9<, , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef9", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef9<, , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef9", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef9<, , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal10", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal10<, , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal10", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal10<, , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef10", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef10<, , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef10", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef10<, , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal11", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal11<, , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal11", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal11<, , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef11", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef11<, , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef11", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef11<, , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal12", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal12<, , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal12", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal12<, , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef12", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef12<, , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef12", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef12<, , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal13", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal13<, , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal13", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal13<, , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef13", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef13<, , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef13", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef13<, , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal14", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal14<, , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal14", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal14<, , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef14", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef14<, , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef14", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef14<, , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal15", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal15<, , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal15", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal15<, , , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef15", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef15<, , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef15", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef15<, , , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidVal16", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidVal16<, , , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeVal16", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeVal16<, , , , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeVoidRef16", BindingFlags.Static | BindingFlags.NonPublic), typeof(VoidRef16<, , , , , , , , , , , , , , , >)), (typeof(FastDelegateInvokers).GetMethod("InvokeTypeRef16", BindingFlags.Static | BindingFlags.NonPublic), typeof(TypeRef16<, , , , , , , , , , , , , , , , >)) }; } private static (MethodInfo Invoker, Type Delegate)? TryGetInvokerForSig(MethodSignature sig) { if (sig.ParameterCount == 0) { return null; } if (sig.ParameterCount > 16) { return null; } if (sig.ReturnType.IsByRef || TypeExtensions.IsByRefLike(sig.ReturnType)) { return null; } if (TypeExtensions.IsByRefLike(sig.FirstParameter)) { return null; } if (sig.Parameters.Skip(1).Any((Type t) => t.IsByRef || TypeExtensions.IsByRefLike(t))) { return null; } int num = 0; num |= ((sig.ReturnType != typeof(void)) ? 1 : 0); num |= (sig.FirstParameter.IsByRef ? 2 : 0); num |= sig.ParameterCount - 1 << 2; (MethodInfo, Type) tuple = invokers[num]; MethodInfo item = tuple.Item1; Type item2 = tuple.Item2; Type[] array = new Type[sig.ParameterCount + (num & 1)]; int num2 = 0; if ((num & 1) != 0) { array[num2++] = sig.ReturnType; } foreach (Type parameter in sig.Parameters) { Type type = parameter; if (type.IsByRef) { type = type.GetElementType(); } array[num2++] = type; } Helpers.Assert(num2 == array.Length, null, "i == typeParams.Length"); return (item.MakeGenericMethod(array), item2.MakeGenericType(array)); } public static (MethodInfo Invoker, Type Delegate)? GetDelegateInvoker(Type delegateType) { Helpers.ThrowIfArgumentNull(delegateType, "delegateType"); if (!typeof(Delegate).IsAssignableFrom(delegateType)) { throw new ArgumentException("Argument not a delegate type", "delegateType"); } Tuple<MethodInfo, Type> value = invokerCache.GetValue(delegateType, delegate(Type type) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) MethodInfo method = type.GetMethod("Invoke"); MethodSignature methodSignature = MethodSignature.ForMethod(method, ignoreThis: true); if (methodSignature.ParameterCount == 0) { return new Tuple<MethodInfo, Type>(null, type); } (MethodInfo, Type)? tuple = TryGetInvokerForSig(methodSignature); if (tuple.HasValue) { (MethodInfo, Type) valueOrDefault = tuple.GetValueOrDefault(); return new Tuple<MethodInfo, Type>(valueOrDefault.Item1, valueOrDefault.Item2); } Type[] array = new Type[methodSignature.ParameterCount + 1]; int num = 0; foreach (Type parameter in methodSignature.Parameters) { array[num++] = parameter; } array[methodSignature.ParameterCount] = type; using DynamicMethodDefinition dynamicMethodDefinition = new DynamicMethodDefinition("MMIL:Invoke<" + method.DeclaringType?.FullName + ">", method.ReturnType, array); ILProcessor iLProcessor = dynamicMethodDefinition.GetILProcessor(); iLProcessor.Emit(OpCodes.Ldarg, methodSignature.ParameterCount); for (num = 0; num < methodSignature.ParameterCount; num++) { iLProcessor.Emit(OpCodes.Ldarg, num); } iLProcessor.Emit(OpCodes.Callvirt, method); iLProcessor.Emit(OpCodes.Ret); return new Tuple<MethodInfo, Type>(dynamicMethodDefinition.Generate(), type); }); if ((object)value.Item1 == null) { return null; } return (value.Item1, value.Item2); } private static void InvokeVoidVal1<T0>(T0 _0, VoidVal1<T0> del) { Helpers.ThrowIfNull(del, "del")(_0); } private static TResult InvokeTypeVal1<TResult, T0>(T0 _0, TypeVal1<TResult, T0> del) { return Helpers.ThrowIfNull(del, "del")(_0); } private static void InvokeVoidRef1<T0>(ref T0 _0, VoidRef1<T0> del) { Helpers.ThrowIfNull(del, "del")(ref _0); } private static TResult InvokeTypeRef1<TResult, T0>(ref T0 _0, TypeRef1<TResult, T0> del) { return Helpers.ThrowIfNull(del, "del")(ref _0); } private static void InvokeVoidVal2<T0, T1>(T0 _0, T1 _1, VoidVal2<T0, T1> del) { Helpers.ThrowIfNull(del, "del")(_0, _1); } private static TResult InvokeTypeVal2<TResult, T0, T1>(T0 _0, T1 _1, TypeVal2<TResult, T0, T1> del) { return Helpers.ThrowIfNull(del, "del")(_0, _1); } private static void InvokeVoidRef2<T0, T1>(ref T0 _0, T1 _1, VoidRef2<T0, T1> del) { Helpers.ThrowIfNull(del, "del")(ref _0, _1); } private static TResult InvokeTypeRef2<TResult, T0, T1>(ref T0 _0, T1 _1, TypeRef2<TResult, T0, T1> del) { return Helpers.ThrowIfNull(del, "del")(ref _0, _1); } private static void InvokeVoidVal3<T0, T1, T2>(T0 _0, T1 _1, T2 _2, VoidVal3<T0, T1, T2> del) { Helpers.ThrowIfNull(del, "del")(_0, _1, _2); } private static TResult InvokeTypeVal3<TResult, T0, T1, T2>(T0 _0, T1 _1, T2 _2, TypeVal3<TResult, T0, T1, T2> del) { return Helpers.ThrowIfNull(del, "del")(_0, _1, _2); } private static void InvokeVoidRef3<T0, T1, T2>(ref T0 _0, T1 _1, T2 _2, VoidRef3<T0, T1, T2> del) { Helpers.ThrowIfNull(del, "del")(ref _0, _1, _2); } private static TResult InvokeTypeRef3<TResult, T0, T1, T2>(ref T0 _0, T1 _1, T2 _2, TypeRef3<TResult, T0, T1, T2> del) { return Helpers.ThrowIfNull(del, "del")(ref _0, _1, _2); } private static void InvokeVoidVal4<T0, T1, T2, T3>(T0 _0, T1 _1, T2 _2, T3 _3, VoidVal4<T0, T1, T2, T3> del) { Helpers.ThrowIfNull(del, "del")(_0, _1, _2, _3); } private static TResult InvokeTypeVal4<TResult, T0, T1, T2, T3>(T0 _0, T1 _1, T2 _2, T3 _3, TypeVal4<TResult, T0, T1, T2, T3> del) { return Helpers.ThrowIfNull(del, "del")(_0, _1, _2, _3); } private static void InvokeVoidRef4<T0, T1, T2, T3>(ref T0 _0, T1 _1, T2 _2, T
BepInExPack/BepInEx/core/SemanticVersioning.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SemanticVersioning")] [assembly: AssemblyTrademark("")] [assembly: InternalsVisibleTo("SemanticVersioning.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010019351d4288017757df1b69b4d0da9a775e6eec498ec93d209d6db4d62e9962476c8da01545cc47335cdc39ba803f4db368ce5f2fdd6cd395196f3328f9039dccdeb3c0f9aece7b8751cd3bc2cb2297d4f463a376eff61b7295b96af9b9faf3eef6005dc967a7a97431cc42cff72e60f05797f3e16186f8fbaf26074e96a2b5e1")] [assembly: ComVisible(false)] [assembly: Guid("a3ff1b6d-68bb-4a0a-a487-858aaa8e3573")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCopyright("Copyright 2016 Adam Reeve")] [assembly: AssemblyDescription("This library implements the Semantic Versioning 2.0.0 specification and the version range specification used by npm.")] [assembly: AssemblyFileVersion("2.0.2.0")] [assembly: AssemblyInformationalVersion("2.0.2")] [assembly: AssemblyTitle("SemanticVersioning")] [assembly: AssemblyVersion("2.0.2.0")] namespace SemanticVersioning; internal class Comparator : IEquatable<Comparator> { public enum Operator { Equal, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual, GreaterThanOrEqualIncludingPrereleases, LessThanExcludingPrereleases } public readonly Operator ComparatorType; public readonly Version Version; private const string pattern = "\n \\s*\n ([=<>]*) # Comparator type (can be empty)\n \\s*\n ([0-9a-zA-Z\\-\\+\\.\\*]+) # Version (potentially partial version)\n \\s*\n "; public Comparator(string input) { Match match = new Regex(string.Format("^{0}$", "\n \\s*\n ([=<>]*) # Comparator type (can be empty)\n \\s*\n ([0-9a-zA-Z\\-\\+\\.\\*]+) # Version (potentially partial version)\n \\s*\n "), RegexOptions.IgnorePatternWhitespace).Match(input); if (!match.Success) { throw new ArgumentException($"Invalid comparator string: {input}"); } ComparatorType = ParseComparatorType(match.Groups[1].Value); PartialVersion partialVersion = new PartialVersion(match.Groups[2].Value); if (!partialVersion.IsFull()) { switch (ComparatorType) { case Operator.LessThanOrEqual: ComparatorType = Operator.LessThan; if (!partialVersion.Major.HasValue) { ComparatorType = Operator.GreaterThanOrEqual; Version = new Version(0, 0, 0); } else if (!partialVersion.Minor.HasValue) { Version = new Version(partialVersion.Major.Value + 1, 0, 0); } else { Version = new Version(partialVersion.Major.Value, partialVersion.Minor.Value + 1, 0); } break; case Operator.GreaterThan: ComparatorType = Operator.GreaterThanOrEqualIncludingPrereleases; if (!partialVersion.Major.HasValue) { ComparatorType = Operator.LessThan; Version = new Version(0, 0, 0); } else if (!partialVersion.Minor.HasValue) { Version = new Version(partialVersion.Major.Value + 1, 0, 0); } else { Version = new Version(partialVersion.Major.Value, partialVersion.Minor.Value + 1, 0); } break; case Operator.LessThan: ComparatorType = Operator.LessThanExcludingPrereleases; Version = partialVersion.ToZeroVersion(); break; case Operator.GreaterThanOrEqual: ComparatorType = Operator.GreaterThanOrEqualIncludingPrereleases; Version = partialVersion.ToZeroVersion(); break; default: Version = partialVersion.ToZeroVersion(); break; } } else { Version = partialVersion.ToZeroVersion(); } } public Comparator(Operator comparatorType, Version comparatorVersion) { if (comparatorVersion == null) { throw new NullReferenceException("Null comparator version"); } ComparatorType = comparatorType; Version = comparatorVersion; } public static Tuple<int, Comparator> TryParse(string input) { Match match = new Regex(string.Format("^{0}", "\n \\s*\n ([=<>]*) # Comparator type (can be empty)\n \\s*\n ([0-9a-zA-Z\\-\\+\\.\\*]+) # Version (potentially partial version)\n \\s*\n "), RegexOptions.IgnorePatternWhitespace).Match(input); if (!match.Success) { return null; } return Tuple.Create(match.Length, new Comparator(match.Value)); } private static Operator ParseComparatorType(string input) { if (input != null) { if (input == null || input.Length != 0) { switch (input) { case "=": break; case "<": return Operator.LessThan; case "<=": return Operator.LessThanOrEqual; case ">": return Operator.GreaterThan; case ">=": return Operator.GreaterThanOrEqual; default: goto IL_005b; } } return Operator.Equal; } goto IL_005b; IL_005b: throw new ArgumentException($"Invalid comparator type: {input}"); } public bool IsSatisfied(Version version) { switch (ComparatorType) { case Operator.Equal: return version == Version; case Operator.LessThan: return version < Version; case Operator.LessThanOrEqual: return version <= Version; case Operator.GreaterThan: return version > Version; case Operator.GreaterThanOrEqual: return version >= Version; case Operator.GreaterThanOrEqualIncludingPrereleases: if (!(version >= Version)) { if (version.IsPreRelease) { return version.BaseVersion() == Version; } return false; } return true; case Operator.LessThanExcludingPrereleases: if (version < Version) { if (version.IsPreRelease) { return !(version.BaseVersion() == Version); } return true; } return false; default: throw new InvalidOperationException("Comparator type not recognised."); } } public bool Intersects(Comparator other) { Func<Comparator, bool> func = (Comparator c) => c.ComparatorType == Operator.GreaterThan || c.ComparatorType == Operator.GreaterThanOrEqual || c.ComparatorType == Operator.GreaterThanOrEqualIncludingPrereleases; Func<Comparator, bool> func2 = (Comparator c) => c.ComparatorType == Operator.LessThan || c.ComparatorType == Operator.LessThanOrEqual || c.ComparatorType == Operator.LessThanExcludingPrereleases; Func<Comparator, bool> func3 = (Comparator c) => c.ComparatorType == Operator.GreaterThanOrEqual || c.ComparatorType == Operator.GreaterThanOrEqualIncludingPrereleases || c.ComparatorType == Operator.Equal || c.ComparatorType == Operator.LessThanOrEqual; if (Version > other.Version && (func2(this) || func(other))) { return true; } if (Version < other.Version && (func(this) || func2(other))) { return true; } if (Version == other.Version && ((func3(this) && func3(other)) || (func2(this) && func2(other)) || (func(this) && func(other)))) { return true; } return false; } public override string ToString() { string text = null; switch (ComparatorType) { case Operator.Equal: text = "="; break; case Operator.LessThan: case Operator.LessThanExcludingPrereleases: text = "<"; break; case Operator.LessThanOrEqual: text = "<="; break; case Operator.GreaterThan: text = ">"; break; case Operator.GreaterThanOrEqual: case Operator.GreaterThanOrEqualIncludingPrereleases: text = ">="; break; default: throw new InvalidOperationException("Comparator type not recognised."); } return $"{text}{Version}"; } public bool Equals(Comparator other) { if (other == null) { return false; } if (ComparatorType == other.ComparatorType) { return Version == other.Version; } return false; } public override bool Equals(object other) { return Equals(other as Comparator); } public override int GetHashCode() { return new { ComparatorType, Version }.GetHashCode(); } } internal class ComparatorSet : IEquatable<ComparatorSet> { private readonly List<Comparator> _comparators; public ComparatorSet(string spec) { _comparators = new List<Comparator>(); spec = spec.Trim(); if (spec == "") { spec = "*"; } int num = 0; int length = spec.Length; while (num < length) { int num2 = num; Func<string, Tuple<int, Comparator[]>>[] array = new Func<string, Tuple<int, Comparator[]>>[4] { Desugarer.HyphenRange, Desugarer.TildeRange, Desugarer.CaretRange, Desugarer.StarRange }; for (int i = 0; i < array.Length; i++) { Tuple<int, Comparator[]> tuple = array[i](spec.Substring(num)); if (tuple != null) { num += tuple.Item1; _comparators.AddRange(tuple.Item2); } } Tuple<int, Comparator> tuple2 = Comparator.TryParse(spec.Substring(num)); if (tuple2 != null) { num += tuple2.Item1; _comparators.Add(tuple2.Item2); } if (num == num2) { throw new ArgumentException($"Invalid range specification: \"{spec}\""); } } } private ComparatorSet(IEnumerable<Comparator> comparators) { _comparators = comparators.ToList(); } public bool IsSatisfied(Version version, bool includePrerelease = false) { bool flag = _comparators.All((Comparator c) => c.IsSatisfied(version)); if (version.PreRelease != null && !includePrerelease) { if (flag) { return _comparators.Any((Comparator c) => c.Version.PreRelease != null && c.Version.BaseVersion() == version.BaseVersion()); } return false; } return flag; } public ComparatorSet Intersect(ComparatorSet other) { Func<Comparator, bool> predicate = (Comparator c) => c.ComparatorType == Comparator.Operator.GreaterThan || c.ComparatorType == Comparator.Operator.GreaterThanOrEqual || c.ComparatorType == Comparator.Operator.GreaterThanOrEqualIncludingPrereleases; Func<Comparator, bool> predicate2 = (Comparator c) => c.ComparatorType == Comparator.Operator.LessThan || c.ComparatorType == Comparator.Operator.LessThanOrEqual || c.ComparatorType == Comparator.Operator.LessThanExcludingPrereleases; Func<Comparator.Operator, int> operatorOrdering = (Comparator.Operator op) => op switch { Comparator.Operator.LessThanExcludingPrereleases => 0, Comparator.Operator.LessThan => 1, Comparator.Operator.LessThanOrEqual => 2, Comparator.Operator.GreaterThan => 0, Comparator.Operator.GreaterThanOrEqual => 1, Comparator.Operator.GreaterThanOrEqualIncludingPrereleases => 2, _ => throw new ArgumentOutOfRangeException("op", op, "Unexpected comparator operator"), }; Comparator comparator = (from c in _comparators.Concat(other._comparators).Where(predicate) orderby c.Version descending, operatorOrdering(c.ComparatorType) select c).FirstOrDefault(); Comparator comparator2 = (from c in _comparators.Concat(other._comparators).Where(predicate2) orderby c.Version, operatorOrdering(c.ComparatorType) select c).FirstOrDefault(); if (comparator != null && comparator2 != null && !comparator.Intersects(comparator2)) { return null; } List<Version> equalityVersions = (from c in _comparators.Concat(other._comparators) where c.ComparatorType == Comparator.Operator.Equal select c.Version).ToList(); if (equalityVersions.Count > 1 && equalityVersions.Any((Version v) => v != equalityVersions[0])) { return null; } if (equalityVersions.Count > 0) { if (comparator != null && !comparator.IsSatisfied(equalityVersions[0])) { return null; } if (comparator2 != null && !comparator2.IsSatisfied(equalityVersions[0])) { return null; } return new ComparatorSet(new List<Comparator> { new Comparator(Comparator.Operator.Equal, equalityVersions[0]) }); } List<Comparator> list = new List<Comparator>(); if (comparator != null) { list.Add(comparator); } if (comparator2 != null) { list.Add(comparator2); } if (list.Count <= 0) { return null; } return new ComparatorSet(list); } public bool Equals(ComparatorSet other) { if (other == null) { return false; } return new HashSet<Comparator>(_comparators).SetEquals(other._comparators); } public override bool Equals(object other) { return Equals(other as ComparatorSet); } public override string ToString() { return string.Join(" ", _comparators.Select((Comparator c) => c.ToString()).ToArray()); } public override int GetHashCode() { return _comparators.Aggregate(0, (int accum, Comparator next) => accum ^ next.GetHashCode()); } } internal static class Desugarer { private const string versionChars = "[0-9a-zA-Z\\-\\+\\.\\*]"; public static Tuple<int, Comparator[]> TildeRange(string spec) { Match match = new Regex(string.Format("^\\s*~\\s*({0}+)\\s*", "[0-9a-zA-Z\\-\\+\\.\\*]")).Match(spec); if (!match.Success) { return null; } Version version = null; Version version2 = null; PartialVersion partialVersion = new PartialVersion(match.Groups[1].Value); if (partialVersion.Minor.HasValue) { version = partialVersion.ToZeroVersion(); version2 = new Version(partialVersion.Major.Value, partialVersion.Minor.Value + 1, 0); } else { version = partialVersion.ToZeroVersion(); version2 = new Version(partialVersion.Major.Value + 1, 0, 0); } return Tuple.Create(match.Length, MinMaxComparators(version, version2)); } public static Tuple<int, Comparator[]> CaretRange(string spec) { Match match = new Regex(string.Format("^\\s*\\^\\s*({0}+)\\s*", "[0-9a-zA-Z\\-\\+\\.\\*]")).Match(spec); if (!match.Success) { return null; } Version version = null; Version version2 = null; PartialVersion partialVersion = new PartialVersion(match.Groups[1].Value); if (partialVersion.Major.Value > 0) { version = partialVersion.ToZeroVersion(); version2 = new Version(partialVersion.Major.Value + 1, 0, 0); } else if (!partialVersion.Minor.HasValue) { version = partialVersion.ToZeroVersion(); version2 = new Version(partialVersion.Major.Value + 1, 0, 0); } else if (!partialVersion.Patch.HasValue) { version = partialVersion.ToZeroVersion(); version2 = new Version(0, partialVersion.Minor.Value + 1, 0); } else if (partialVersion.Minor > 0) { version = partialVersion.ToZeroVersion(); version2 = new Version(0, partialVersion.Minor.Value + 1, 0); } else { version = partialVersion.ToZeroVersion(); version2 = new Version(0, 0, partialVersion.Patch.Value + 1); } return Tuple.Create(match.Length, MinMaxComparators(version, version2, Comparator.Operator.GreaterThanOrEqualIncludingPrereleases)); } public static Tuple<int, Comparator[]> HyphenRange(string spec) { Match match = new Regex(string.Format("^\\s*({0}+)\\s+\\-\\s+({0}+)\\s*", "[0-9a-zA-Z\\-\\+\\.\\*]")).Match(spec); if (!match.Success) { return null; } PartialVersion partialVersion = null; PartialVersion partialVersion2 = null; try { partialVersion = new PartialVersion(match.Groups[1].Value); partialVersion2 = new PartialVersion(match.Groups[2].Value); } catch (ArgumentException) { return null; } Version minVersion = partialVersion.ToZeroVersion(); Comparator.Operator maxOperator = (partialVersion2.IsFull() ? Comparator.Operator.LessThanOrEqual : Comparator.Operator.LessThanExcludingPrereleases); Version maxVersion = null; if (partialVersion2.Major.HasValue) { maxVersion = ((!partialVersion2.Minor.HasValue) ? new Version(partialVersion2.Major.Value + 1, 0, 0) : (partialVersion2.Patch.HasValue ? partialVersion2.ToZeroVersion() : new Version(partialVersion2.Major.Value, partialVersion2.Minor.Value + 1, 0))); } return Tuple.Create(match.Length, MinMaxComparators(minVersion, maxVersion, Comparator.Operator.GreaterThanOrEqualIncludingPrereleases, maxOperator)); } public static Tuple<int, Comparator[]> StarRange(string spec) { Match match = new Regex(string.Format("^\\s*=?\\s*({0}+)\\s*", "[0-9a-zA-Z\\-\\+\\.\\*]")).Match(spec); if (!match.Success) { return null; } PartialVersion partialVersion = null; try { partialVersion = new PartialVersion(match.Groups[1].Value); } catch (ArgumentException) { return null; } if (partialVersion.IsFull()) { return null; } Version version = null; Version maxVersion = null; if (!partialVersion.Major.HasValue) { version = partialVersion.ToZeroVersion(); } else if (!partialVersion.Minor.HasValue) { version = partialVersion.ToZeroVersion(); maxVersion = new Version(partialVersion.Major.Value + 1, 0, 0); } else { version = partialVersion.ToZeroVersion(); maxVersion = new Version(partialVersion.Major.Value, partialVersion.Minor.Value + 1, 0); } return Tuple.Create(match.Length, MinMaxComparators(version, maxVersion)); } private static Comparator[] MinMaxComparators(Version minVersion, Version maxVersion, Comparator.Operator minOperator = Comparator.Operator.GreaterThanOrEqual, Comparator.Operator maxOperator = Comparator.Operator.LessThanExcludingPrereleases) { Comparator comparator = new Comparator(minOperator, minVersion); if (!(maxVersion == null)) { Comparator comparator2 = new Comparator(maxOperator, maxVersion); return new Comparator[2] { comparator, comparator2 }; } return new Comparator[1] { comparator }; } } internal class PartialVersion { private static Regex regex = new Regex("^\n [v=\\s]*\n (\\d+|[Xx\\*]) # major version\n (\n \\.\n (\\d+|[Xx\\*]) # minor version\n (\n \\.\n (\\d+|[Xx\\*]) # patch version\n (\\-?([0-9A-Za-z\\-\\.]+))? # pre-release version\n (\\+([0-9A-Za-z\\-\\.]+))? # build version (ignored)\n )?\n )?\n $", RegexOptions.IgnorePatternWhitespace); public int? Major { get; set; } public int? Minor { get; set; } public int? Patch { get; set; } public string PreRelease { get; set; } public PartialVersion(string input) { string[] source = new string[3] { "X", "x", "*" }; if (input.Trim() == "") { return; } Match match = regex.Match(input); if (!match.Success) { throw new ArgumentException($"Invalid version string: \"{input}\""); } if (source.Contains(match.Groups[1].Value)) { Major = null; } else { Major = int.Parse(match.Groups[1].Value); } if (match.Groups[2].Success) { if (source.Contains(match.Groups[3].Value)) { Minor = null; } else { Minor = int.Parse(match.Groups[3].Value); } } if (match.Groups[4].Success) { if (source.Contains(match.Groups[5].Value)) { Patch = null; } else { Patch = int.Parse(match.Groups[5].Value); } } if (match.Groups[6].Success) { PreRelease = match.Groups[7].Value; } } public Version ToZeroVersion() { return new Version(Major.GetValueOrDefault(), Minor.GetValueOrDefault(), Patch.GetValueOrDefault(), PreRelease); } public bool IsFull() { if (Major.HasValue && Minor.HasValue) { return Patch.HasValue; } return false; } } internal static class PreReleaseVersion { private class Identifier { public bool IsNumeric { get; set; } public int IntValue { get; set; } public string Value { get; set; } public Identifier(string input) { Value = input; SetNumeric(); } public string Clean() { if (!IsNumeric) { return Value; } return IntValue.ToString(); } private void SetNumeric() { int result; bool flag = int.TryParse(Value, out result); IsNumeric = flag && result >= 0; IntValue = result; } } public static int Compare(string a, string b) { if (a == null && b == null) { return 0; } if (a == null) { return 1; } if (b == null) { return -1; } foreach (int item in IdentifierComparisons(Identifiers(a), Identifiers(b))) { if (item != 0) { return item; } } return 0; } public static string Clean(string input) { IEnumerable<string> source = from i in Identifiers(input) select i.Clean(); return string.Join(".", source.ToArray()); } private static IEnumerable<Identifier> Identifiers(string input) { string[] array = input.Split(new char[1] { '.' }); foreach (string input2 in array) { yield return new Identifier(input2); } } private static IEnumerable<int> IdentifierComparisons(IEnumerable<Identifier> aIdentifiers, IEnumerable<Identifier> bIdentifiers) { foreach (Tuple<Identifier, Identifier> item3 in ZipIdentifiers(aIdentifiers, bIdentifiers)) { Identifier item = item3.Item1; Identifier item2 = item3.Item2; if (item == item2) { yield return 0; } else if (item == null) { yield return -1; } else if (item2 == null) { yield return 1; } else if (item.IsNumeric && item2.IsNumeric) { yield return item.IntValue.CompareTo(item2.IntValue); } else if (!item.IsNumeric && !item2.IsNumeric) { yield return string.CompareOrdinal(item.Value, item2.Value); } else if (item.IsNumeric && !item2.IsNumeric) { yield return -1; } else { yield return 1; } } } private static IEnumerable<Tuple<Identifier, Identifier>> ZipIdentifiers(IEnumerable<Identifier> first, IEnumerable<Identifier> second) { using IEnumerator<Identifier> ie1 = first.GetEnumerator(); using IEnumerator<Identifier> ie2 = second.GetEnumerator(); while (ie1.MoveNext()) { if (ie2.MoveNext()) { yield return Tuple.Create(ie1.Current, ie2.Current); } else { yield return Tuple.Create<Identifier, Identifier>(ie1.Current, null); } } while (ie2.MoveNext()) { yield return Tuple.Create<Identifier, Identifier>(null, ie2.Current); } } } public class Range : IEquatable<Range> { private readonly ComparatorSet[] _comparatorSets; private readonly string _rangeSpec; public Range(string rangeSpec, bool loose = false) { _rangeSpec = rangeSpec; string[] source = rangeSpec.Split(new string[1] { "||" }, StringSplitOptions.None); _comparatorSets = source.Select((string s) => new ComparatorSet(s)).ToArray(); } private Range(IEnumerable<ComparatorSet> comparatorSets) { _comparatorSets = comparatorSets.ToArray(); _rangeSpec = string.Join(" || ", _comparatorSets.Select((ComparatorSet cs) => cs.ToString()).ToArray()); } public bool IsSatisfied(Version version, bool includePrerelease = false) { return _comparatorSets.Any((ComparatorSet s) => s.IsSatisfied(version, includePrerelease)); } public bool IsSatisfied(string versionString, bool loose = false, bool includePrerelease = false) { try { Version version = new Version(versionString, loose); return IsSatisfied(version, includePrerelease); } catch (ArgumentException) { return false; } } public IEnumerable<Version> Satisfying(IEnumerable<Version> versions, bool includePrerelease = false) { return versions.Where((Version v) => IsSatisfied(v, includePrerelease)); } public IEnumerable<string> Satisfying(IEnumerable<string> versions, bool loose = false, bool includePrerelease = false) { return versions.Where((string v) => IsSatisfied(v, loose, includePrerelease)); } public Version MaxSatisfying(IEnumerable<Version> versions, bool includePrerelease = false) { return Satisfying(versions, includePrerelease).Max(); } public string MaxSatisfying(IEnumerable<string> versionStrings, bool loose = false, bool includePrerelease = false) { IEnumerable<Version> versions = ValidVersions(versionStrings, loose); Version version = MaxSatisfying(versions, includePrerelease); if (!(version == null)) { return version.ToString(); } return null; } public Range Intersect(Range other) { List<ComparatorSet> list = (from cs in _comparatorSets.SelectMany((ComparatorSet thisCs) => other._comparatorSets.Select(thisCs.Intersect)) where cs != null select cs).ToList(); if (list.Count == 0) { return new Range("<0.0.0"); } return new Range(list); } public override string ToString() { return _rangeSpec; } public bool Equals(Range other) { if ((object)other == null) { return false; } return new HashSet<ComparatorSet>(_comparatorSets).SetEquals(other._comparatorSets); } public override bool Equals(object other) { return Equals(other as Range); } public static bool operator ==(Range a, Range b) { return a?.Equals(b) ?? ((object)b == null); } public static bool operator !=(Range a, Range b) { return !(a == b); } public override int GetHashCode() { return _comparatorSets.Aggregate(0, (int accum, ComparatorSet next) => accum ^ next.GetHashCode()); } public static bool IsSatisfied(string rangeSpec, string versionString, bool loose = false, bool includePrerelease = false) { return new Range(rangeSpec).IsSatisfied(versionString, loose, includePrerelease); } public static IEnumerable<string> Satisfying(string rangeSpec, IEnumerable<string> versions, bool loose = false, bool includePrerelease = false) { return new Range(rangeSpec).Satisfying(versions, loose, includePrerelease); } public static string MaxSatisfying(string rangeSpec, IEnumerable<string> versionStrings, bool loose = false, bool includePrerelease = false) { return new Range(rangeSpec).MaxSatisfying(versionStrings, loose: false, includePrerelease); } public static Range Parse(string rangeSpec, bool loose = false) { return new Range(rangeSpec, loose); } public static bool TryParse(string rangeSpec, out Range result) { return TryParse(rangeSpec, loose: false, out result); } public static bool TryParse(string rangeSpec, bool loose, out Range result) { try { result = Parse(rangeSpec, loose); return true; } catch { result = null; return false; } } private IEnumerable<Version> ValidVersions(IEnumerable<string> versionStrings, bool loose) { foreach (string versionString in versionStrings) { Version version = null; try { version = new Version(versionString, loose); } catch (ArgumentException) { } if (version != null) { yield return version; } } } } public class Version : IComparable<Version>, IComparable, IEquatable<Version> { private readonly string _inputString; private readonly int _major; private readonly int _minor; private readonly int _patch; private readonly string _preRelease; private readonly string _build; private static Regex strictRegex = new Regex("^\n \\s*v?\n ([0-9]|[1-9][0-9]+) # major version\n \\.\n ([0-9]|[1-9][0-9]+) # minor version\n \\.\n ([0-9]|[1-9][0-9]+) # patch version\n (\\-([0-9A-Za-z\\-\\.]+))? # pre-release version\n (\\+([0-9A-Za-z\\-\\.]+))? # build metadata\n \\s*\n $", RegexOptions.IgnorePatternWhitespace); private static Regex looseRegex = new Regex("^\n [v=\\s]*\n (\\d+) # major version\n \\.\n (\\d+) # minor version\n \\.\n (\\d+) # patch version\n (\\-?([0-9A-Za-z\\-\\.]+))? # pre-release version\n (\\+([0-9A-Za-z\\-\\.]+))? # build metadata\n \\s*\n $", RegexOptions.IgnorePatternWhitespace); public int Major => _major; public int Minor => _minor; public int Patch => _patch; public string PreRelease => _preRelease; public string Build => _build; public bool IsPreRelease => !string.IsNullOrEmpty(_preRelease); public Version(string input, bool loose = false) { _inputString = input; Match match = (loose ? looseRegex : strictRegex).Match(input); if (!match.Success) { throw new ArgumentException($"Invalid version string: {input}"); } _major = int.Parse(match.Groups[1].Value); _minor = int.Parse(match.Groups[2].Value); _patch = int.Parse(match.Groups[3].Value); if (match.Groups[4].Success) { string value = match.Groups[5].Value; string text = PreReleaseVersion.Clean(value); if (!loose && value != text) { throw new ArgumentException($"Invalid pre-release version: {value}"); } _preRelease = text; } if (match.Groups[6].Success) { _build = match.Groups[7].Value; } } public Version(int major, int minor, int patch, string preRelease = null, string build = null) { _major = major; _minor = minor; _patch = patch; _preRelease = preRelease; _build = build; } public Version BaseVersion() { return new Version(Major, Minor, Patch); } public override string ToString() { return _inputString ?? Clean(); } public string Clean() { string text = ((PreRelease == null) ? "" : $"-{PreReleaseVersion.Clean(PreRelease)}"); string text2 = ((Build == null) ? "" : $"+{Build}"); return $"{Major}.{Minor}.{Patch}{text}{text2}"; } public override int GetHashCode() { int num = 17; num = num * 23 + Major.GetHashCode(); num = num * 23 + Minor.GetHashCode(); num = num * 23 + Patch.GetHashCode(); if (PreRelease != null) { num = num * 23 + PreRelease.GetHashCode(); } return num; } public bool Equals(Version other) { if ((object)other == null) { return false; } return CompareTo(other) == 0; } public int CompareTo(object obj) { if (obj != null) { if (obj is Version other) { return CompareTo(other); } throw new ArgumentException("Object is not a Version"); } return 1; } public int CompareTo(Version other) { if ((object)other == null) { return 1; } foreach (int item in PartComparisons(other)) { if (item != 0) { return item; } } return PreReleaseVersion.Compare(PreRelease, other.PreRelease); } private IEnumerable<int> PartComparisons(Version other) { yield return Major.CompareTo(other.Major); yield return Minor.CompareTo(other.Minor); yield return Patch.CompareTo(other.Patch); } public override bool Equals(object other) { return Equals(other as Version); } public static Version Parse(string input, bool loose = false) { return new Version(input, loose); } public static bool TryParse(string input, out Version result) { return TryParse(input, loose: false, out result); } public static bool TryParse(string input, bool loose, out Version result) { try { result = Parse(input, loose); return true; } catch { result = null; return false; } } public static bool operator ==(Version a, Version b) { return a?.Equals(b) ?? ((object)b == null); } public static bool operator !=(Version a, Version b) { return !(a == b); } public static bool operator >(Version a, Version b) { if ((object)a == null) { return false; } return a.CompareTo(b) > 0; } public static bool operator >=(Version a, Version b) { if ((object)a == null) { if ((object)b != null) { return false; } return true; } return a.CompareTo(b) >= 0; } public static bool operator <(Version a, Version b) { if ((object)a == null) { if ((object)b != null) { return true; } return false; } return a.CompareTo(b) < 0; } public static bool operator <=(Version a, Version b) { if ((object)a == null) { return true; } return a.CompareTo(b) <= 0; } }
BepInExPack/BepInEx.NET.CoreCLR.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx.Bootstrap; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.NET.Common; using BepInEx.NET.CoreCLR; using BepInEx.NET.Shared; using BepInEx.Preloader.Core; using BepInEx.Preloader.Core.Logging; using BepInEx.Preloader.Core.Patching; using Mono.Cecil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] [assembly: AssemblyCompany("BepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2022 BepInEx Team")] [assembly: AssemblyDescription("BepInEx support library for CoreCLR games")] [assembly: AssemblyFileVersion("6.0.0.0")] [assembly: AssemblyInformationalVersion("6.0.0+802b84c947c2b8ab870be453776f7ab895d8cf09")] [assembly: AssemblyProduct("BepInEx.NET.CoreCLR")] [assembly: AssemblyTitle("BepInEx.NET.CoreCLR")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ibox233/BepinEx-6-CoreCLR-For-Romestead")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class StartupHook { public static List<string> ResolveDirectories = new List<string>(); public static string DoesNotExistPath = "_doesnotexist_.exe"; private static int initialized; private static Mutex initializationMutex; private const string AppDomainInitializedKey = "Romestead.BepInEx.NET.CoreCLR.StartupHook.Initialized"; public static void Initialize() { if (!TryBeginInitialize()) { return; } string text = $"bepinex_preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log"; try { string fileName = Process.GetCurrentProcess().MainModule.FileName; string text2 = TryDetermineAssemblyNameFromDotnet(fileName) ?? TryDetermineAssemblyNameFromStubExecutable(fileName) ?? TryDetermineAssemblyNameFromCurrentAssembly(fileName); string text3 = null; if (text2 != null) { text3 = Path.GetDirectoryName(text2); } string text4 = TryDetermineBepInExRootFromDoorstopTarget() ?? TryDetermineBepInExRootFromCurrentAssembly() ?? TryDetermineBepInExRootFromGameDirectory(text3); string text5 = null; if (text4 != null) { text5 = Path.Combine(text4, "core"); } if (text2 == null || text3 == null || !Directory.Exists(text5)) { throw new Exception("Could not determine game location, or BepInEx install location"); } text = Path.Combine(text3, text); ResolveDirectories.Add(text5); AppDomain.CurrentDomain.AssemblyResolve += SharedEntrypoint.RemoteResolve(ResolveDirectories); NetCorePreloaderRunner.OuterMain(text2, text4); } catch (Exception value) { string text6 = null; string text7 = null; try { text6 = Process.GetCurrentProcess().MainModule?.FileName; text7 = string.Join(' ', Environment.GetCommandLineArgs()); } catch { } string contents = $"Unhandled fatal exception\r\nExecutable location: {text6 ?? "<null>"}\r\nArguments: {text7 ?? "<null>"}\r\n{value}"; File.WriteAllText(text, contents); Console.WriteLine("Unhandled exception"); Console.WriteLine("Executable location: " + (text6 ?? "<null>")); Console.WriteLine("Arguments: " + (text7 ?? "<null>")); Console.WriteLine(value); } } private static bool TryBeginInitialize() { if (Interlocked.Exchange(ref initialized, 1) == 1) { return false; } if (AppDomain.CurrentDomain.GetData("Romestead.BepInEx.NET.CoreCLR.StartupHook.Initialized") != null) { return false; } try { string name = $"Romestead.BepInEx.NET.CoreCLR.StartupHook.{Environment.ProcessId}"; initializationMutex = new Mutex(initiallyOwned: true, name, out var createdNew); if (!createdNew) { return false; } } catch { } AppDomain.CurrentDomain.SetData("Romestead.BepInEx.NET.CoreCLR.StartupHook.Initialized", true); return true; } private static string TryDetermineAssemblyNameFromDotnet(string executableFilename) { if (Path.GetFileNameWithoutExtension(executableFilename) == "dotnet") { string[] commandLineArgs = Environment.GetCommandLineArgs(); foreach (string text in commandLineArgs) { if ((text.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || text.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) && File.Exists(text)) { return Path.GetFullPath(text); } } } return null; } private static string TryDetermineAssemblyNameFromStubExecutable(string executableFilename) { string text = Path.ChangeExtension(executableFilename, ".dll"); if (File.Exists(text)) { return text; } return null; } private static string TryDetermineAssemblyNameFromCurrentAssembly(string executableFilename) { string directoryName = Path.GetDirectoryName(typeof(StartupHook).Assembly.Location.Replace('/', Path.DirectorySeparatorChar)); if (directoryName == null) { return null; } string directoryName2 = Path.GetDirectoryName(Path.GetDirectoryName(directoryName)); if (directoryName2 == null) { return null; } return Path.Combine(directoryName2, DoesNotExistPath); } private static string TryDetermineBepInExRootFromDoorstopTarget() { string text = GetCommandLineArgValue("--doorstop-target") ?? GetCommandLineArgValue("--doorstop-target-assembly") ?? GetCommandLineArgValue("--doorstop_target_assembly"); if (string.IsNullOrWhiteSpace(text)) { return null; } return TryDetermineBepInExRootFromTargetAssembly(text); } private static string TryDetermineBepInExRootFromTargetAssembly(string targetAssembly) { string fullPath; try { fullPath = Path.GetFullPath(targetAssembly); } catch { return null; } if (!File.Exists(fullPath)) { return null; } if (!string.Equals(Path.GetFileName(fullPath), "BepInEx.NET.CoreCLR.dll", StringComparison.OrdinalIgnoreCase)) { return null; } string directoryName = Path.GetDirectoryName(fullPath); if (directoryName == null) { return null; } if (string.Equals(Path.GetFileName(directoryName), "core", StringComparison.OrdinalIgnoreCase)) { string text = ParentDirectory(fullPath, 2); if (HasBepInExCoreDirectory(text)) { return text; } } return TryDetermineBepInExRootFromGameDirectory(directoryName); } private static string TryDetermineBepInExRootFromCurrentAssembly() { return TryDetermineBepInExRootFromTargetAssembly(typeof(StartupHook).Assembly.Location.Replace('/', Path.DirectorySeparatorChar)); } private static string TryDetermineBepInExRootFromGameDirectory(string gameDirectory) { if (string.IsNullOrWhiteSpace(gameDirectory)) { return null; } string text = Path.Combine(gameDirectory, "BepInEx"); if (!HasBepInExCoreDirectory(text)) { return null; } return text; } private static bool HasBepInExCoreDirectory(string bepinexRoot) { if (!string.IsNullOrWhiteSpace(bepinexRoot)) { return Directory.Exists(Path.Combine(bepinexRoot, "core")); } return false; } private static string GetCommandLineArgValue(string name) { string[] commandLineArgs = Environment.GetCommandLineArgs(); for (int i = 1; i < commandLineArgs.Length - 1; i++) { if (string.Equals(commandLineArgs[i], name, StringComparison.OrdinalIgnoreCase)) { return commandLineArgs[i + 1]; } } return null; } private static string ParentDirectory(string path, int levels) { for (int i = 0; i < levels; i++) { path = Path.GetDirectoryName(path); } return path; } } namespace BepInEx.NET.Shared { internal static class SharedEntrypoint { public static ResolveEventHandler RemoteResolve(List<string> resolveDirectories) { return (object? sender, ResolveEventArgs args) => RemoteResolveInternal(sender, args, resolveDirectories); } private static Assembly RemoteResolveInternal(object sender, ResolveEventArgs reference, List<string> resolveDirectories) { AssemblyName assemblyName = new AssemblyName(reference.Name); foreach (string resolveDirectory in resolveDirectories) { if (!Directory.Exists(resolveDirectory)) { continue; } List<string> list = new List<string> { resolveDirectory }; list.AddRange(Directory.GetDirectories(resolveDirectory, "*", SearchOption.AllDirectories)); foreach (string item in list.Select((string x) => Path.Combine(x, assemblyName.Name + ".dll")).Concat(list.Select((string x) => Path.Combine(x, assemblyName.Name + ".exe")))) { if (File.Exists(item)) { Assembly assembly; try { assembly = Assembly.LoadFrom(item); } catch (Exception) { continue; } if (assembly.GetName().Name == assemblyName.Name) { return assembly; } } } } return null; } public static Assembly LocalResolve(object sender, ResolveEventArgs args) { AssemblyName assemblyName = new AssemblyName(args.Name); Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => x.GetName().Name == assemblyName.Name); if (assembly != null) { return assembly; } if (LocalUtility.TryResolveDllAssembly(assemblyName, Paths.BepInExAssemblyDirectory, out assembly) || LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PatcherPluginPath, out assembly) || LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PluginPath, out assembly)) { return assembly; } return null; } } internal static class LocalUtility { private static bool TryResolveDllAssembly<T>(AssemblyName assemblyName, string directory, Func<string, T> loader, out T assembly) where T : class { assembly = null; if (!Directory.Exists(directory)) { return false; } List<string> list = new List<string>(); list.Add(directory); list.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories)); foreach (string item in list) { string text = Path.Combine(item, assemblyName.Name + ".dll"); if (File.Exists(text)) { try { assembly = loader(text); } catch (Exception) { continue; } return true; } } return false; } public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly) { return TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFrom, out assembly); } } } namespace BepInEx.NET.CoreCLR { internal static class NetCorePreloaderRunner { internal static void PreloaderMain() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown ConsoleManager.Initialize(false, true); if (ConsoleManager.ConsoleEnabled) { ConsoleManager.CreateConsole(); Logger.Listeners.Add((ILogListener)new ConsoleLogListener()); } try { NetCorePreloader.Start(); } catch (Exception ex) { PreloaderLogger.Log.Log((LogLevel)1, (object)"Unhandled exception"); PreloaderLogger.Log.Log((LogLevel)1, (object)ex); } } internal static void OuterMain(string filename, string bepinexRootPath) { PlatformUtils.SetPlatform(); Paths.SetDotNetGamePath(filename, bepinexRootPath); AppDomain.CurrentDomain.AssemblyResolve += SharedEntrypoint.LocalResolve; PreloaderMain(); } } public static class NativeEntrypoint { public static int Initialize(nint args, int sizeBytes) { StartupHook.Initialize(); return 0; } } internal class NetCorePreloader { private static readonly ManualLogSource Log = PreloaderLogger.Log; public static void Start() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Expected O, but got Unknown //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Expected O, but got Unknown //IL_02ac: Expected O, but got Unknown PreloaderConsoleListener item = new PreloaderConsoleListener(); Logger.Listeners.Add((ILogListener)(object)item); string text = ((!Paths.ExecutablePath.EndsWith(StartupHook.DoesNotExistPath)) ? Paths.ExecutablePath : null); TypeLoader.SearchDirectories.Add(Paths.GameRootPath); Logger.Sources.Add(TraceLogSource.CreateSource()); ChainloaderLogHelper.PrintLogInfo(Log); bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CLR runtime version: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Version>(Environment.Version); } Log.LogInfo(val); val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Current executable: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Process.GetCurrentProcess().MainModule.FileName); } Log.LogInfo(val); val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Entrypoint assembly: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text ?? "<does not exist>"); } Log.LogInfo(val); val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Launch arguments: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(' ', Environment.GetCommandLineArgs())); } Log.LogInfo(val); if (text != null) { AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(text); AssemblyBuildInfo val3; try { val3 = AssemblyBuildInfo.DetermineInfo(val2); } finally { ((IDisposable)val2)?.Dispose(); } val = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Game executable build architecture: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<AssemblyBuildInfo>(val3); } Log.LogInfo(val); } else { Log.LogWarning((object)"Game assembly is unknown, can't determine build architecture"); } Log.LogMessage((object)"Preloader started"); AssemblyPatcher val4 = new AssemblyPatcher((Func<byte[], string, Assembly>)((byte[] data, string _) => Assembly.Load(data))); try { val4.AddPatchersFromDirectory(Paths.PatcherPluginPath); val = new BepInExInfoLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(val4.PatcherContext.PatchDefinitions.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" patcher definition(s) loaded"); } Log.LogInfo(val); val4.LoadAssemblyDirectories((IEnumerable<string>)new string[1] { Paths.GameRootPath }, (IEnumerable<string>)new string[2] { "dll", "exe" }); val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(val4.PatcherContext.AvailableAssemblies.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" assemblies discovered"); } Log.LogInfo(val); val4.PatchAndLoad(); } finally { ((IDisposable)val4)?.Dispose(); } Log.LogMessage((object)"Preloader finished"); Logger.Listeners.Remove((ILogListener)(object)item); NetChainloader val5 = new NetChainloader(); ((BaseChainloader<BasePlugin>)val5).Initialize(); ((BaseChainloader<BasePlugin>)val5).Execute(); } } }