Decompiled source of CroatiaUtils v1.0.3

VaigaLegaAPI.dll

Decompiled 11 months ago
using System;
using System.CodeDom.Compiler;
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.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CroatiaUtils.Extensions;
using CroatiaUtils.Imports;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.FieldInfo;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Type;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("VaigaLegaAPI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("VaigaLegaAPI")]
[assembly: AssemblyTitle("VaigaLegaAPI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.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[] P_0)
		{
			TransformFlags = P_0;
		}
	}
}
namespace CroatiaUtils
{
	internal static class CroatiaLogger
	{
		private static ManualLogSource m_LogSource;

		public static void SetupFromInit(ManualLogSource logSource)
		{
			m_LogSource = logSource;
		}

		private static string Format(object data)
		{
			return data.ToString();
		}

		public static void Debug(object msg)
		{
			m_LogSource.LogDebug((object)Format(msg));
		}

		public static void Info(object msg)
		{
			m_LogSource.LogInfo((object)Format(msg));
		}

		public static void Message(object msg)
		{
			m_LogSource.LogMessage((object)Format(msg));
		}

		public static void Warn(object msg)
		{
			m_LogSource.LogWarning((object)Format(msg));
		}

		public static void Error(object msg)
		{
			m_LogSource.LogError((object)Format(msg));
		}

		public static void Fatal(object msg)
		{
			m_LogSource.LogFatal((object)Format(msg));
		}
	}
	[BepInPlugin("com.kasuromi.croatiautils", "CroatiaUtils", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EntryPoint : BasePlugin
	{
		public override void Load()
		{
			if (new StackTrace().GetFrame(1).GetMethod().DeclaringType.Assembly != typeof(IL2CPPChainloader).Assembly)
			{
				Environment.FailFast("VAIGA LEGA KASUROM!!! 2 FATHER");
				throw null;
			}
			CroatiaLogger.SetupFromInit(((BasePlugin)this).Log);
		}
	}
	public static class Il2CppUtils
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public static INativeClassStruct GetClass<TClass>()
		{
			return Il2CppClassPointerStore<TClass>.NativeClassPtr.AsIl2CppClass();
		}

		public unsafe static void AddField(IntPtr classPointer, IntPtr fieldTypeClassPointer, string fieldName)
		{
			INativeClassStruct val = classPointer.AsIl2CppClass();
			INativeClassStruct val2 = fieldTypeClassPointer.AsIl2CppClass();
			INativeFieldInfoStruct val3 = UnityVersionHandler.NewField();
			val3.Name = Marshal.StringToHGlobalAnsi(fieldName);
			val3.Type = (val2.ValueType ? val2.ByValArg.TypePointer : val2.ThisArg.TypePointer);
			val3.Parent = val.ClassPointer;
			uint num = 0u;
			uint num2 = (uint)(val2.ValueType ? IL2CPP.il2cpp_class_value_size(((INativeStruct)val2).Pointer, ref num) : sizeof(void*));
			val3.Offset = (int)val.InstanceSize;
			val.ActualSize += num2;
			val.InstanceSize += num2;
			nint num3 = Marshal.AllocHGlobal((val.FieldCount + 1) * UnityVersionHandler.FieldInfoSize());
			num = 0u;
			IEnumerable<INativeFieldInfoStruct> enumerable = val.GetFields().ToArray();
			foreach (INativeFieldInfoStruct item in enumerable)
			{
				Unsafe.CopyBlock((void*)(num3 + (nint)(num * UnityVersionHandler.FieldInfoSize())), (void*)((INativeStruct)item).Pointer, (uint)UnityVersionHandler.FieldInfoSize());
				num++;
			}
			Unsafe.CopyBlock((void*)(num3 + (nint)(num * UnityVersionHandler.FieldInfoSize())), (void*)((INativeStruct)val3).Pointer, (uint)UnityVersionHandler.FieldInfoSize());
			Marshal.FreeHGlobal(((INativeStruct)val3).Pointer);
			val.Fields = (Il2CppFieldInfo*)(void*)(IntPtr)num3;
			val.FieldCount++;
			foreach (INativeFieldInfoStruct item2 in enumerable)
			{
				IL2CPP.il2cpp_free(((INativeStruct)item2).Pointer);
			}
		}
	}
	public struct MemoryProtectionCookie : IDisposable
	{
		private Kernel32.MemoryProtectionConstant m_OldProtection;

		private readonly nint m_Address;

		private readonly nint m_Size;

		public MemoryProtectionCookie(nint address, Kernel32.MemoryProtectionConstant newProtection, nint size = 16)
		{
			m_Address = address;
			m_Size = size;
			if (!Kernel32.VirtualProtect(m_Address, m_Size, newProtection, out m_OldProtection))
			{
				Environment.FailFast($"Failed to protect address 0x{m_Address:X2} with protection {newProtection}");
			}
			CroatiaLogger.Debug($"MemoryProtectionCookie: Modified protection of address 0x{m_Address:X2} from {m_OldProtection} to {newProtection}");
		}

		public void Dispose()
		{
			Kernel32.MemoryProtectionConstant oldProtection = m_OldProtection;
			if (!Kernel32.VirtualProtect(m_Address, m_Size, m_OldProtection, out m_OldProtection))
			{
				Environment.FailFast($"Failed to revert memory protection of address 0x{m_Address:X2}");
			}
			CroatiaLogger.Debug($"MemoryProtectionCookie: Reverted protection of address 0x{m_Address:X2} to {oldProtection}");
		}
	}
	public static class MemoryUtils
	{
		private unsafe delegate void* d_FindSignatureInBlock(void* block, ulong blockSize, string pattern, string mask, ulong sigOffset);

		private static readonly byte[] s_TrampolineShellcode = new byte[12]
		{
			72, 184, 0, 0, 0, 0, 0, 0, 0, 0,
			255, 224
		};

		private static readonly Type s_MemoryUtilsType = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins["dev.gtfomodding.gtfo-api"].Instance.GetType().Assembly.GetType("GTFO.API.Utilities.MemoryUtils");

		private static d_FindSignatureInBlock fnFindSignatureInBlock;

		public unsafe static byte[] MakeTrampoline(nint destination)
		{
			byte[] array = new byte[s_TrampolineShellcode.Length];
			Array.Copy(s_TrampolineShellcode, 0, array, 0, s_TrampolineShellcode.Length);
			fixed (byte* ptr = array)
			{
				*(long*)(ptr + 2) = destination;
			}
			return array;
		}

		public unsafe static void CreateTrampolineBetween(nint start, nint end, nint destination)
		{
			nint num = end - start;
			if (num < s_TrampolineShellcode.Length)
			{
				throw new Exception("Trampoline block size is not enough to create.");
			}
			using (new MemoryProtectionCookie(start, Kernel32.MemoryProtectionConstant.ExecuteReadWrite, num))
			{
				CroatiaLogger.Debug("NOPing trampoline section");
				for (nint num2 = 0; num2 < num; num2++)
				{
					*(sbyte*)(start + num2) = -112;
				}
				CroatiaLogger.Debug("Creating trampoline shellcode");
				byte[] array = MakeTrampoline(destination);
				CroatiaLogger.Debug("Writing shellcode to trampoline section");
				Unsafe.CopyBlock((void*)start, Unsafe.AsPointer(ref array[0]), (uint)array.Length);
			}
		}

		public unsafe static nint FindSignatureInBlock(nint block, ulong blockSize, string pattern, string mask, ulong sigOffset = 0uL)
		{
			if (fnFindSignatureInBlock == null)
			{
				fnFindSignatureInBlock = AccessTools.MethodDelegate<d_FindSignatureInBlock>(AccessTools.Method(s_MemoryUtilsType, "FindSignatureInBlock", new Type[5]
				{
					typeof(void*),
					typeof(ulong),
					typeof(string),
					typeof(string),
					typeof(ulong)
				}, (Type[])null), (object)null, true);
			}
			return (nint)fnFindSignatureInBlock((void*)block, blockSize, pattern, mask, sigOffset);
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "CroatiaUtils";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = null;

		public const string SemVer = "1.0.0";

		public const string GitRevShort = null;

		public const string GitRevLong = null;

		public const string GitBranch = null;

		public const string GitTag = null;

		public const bool GitIsDirty = false;
	}
}
namespace CroatiaUtils.Imports
{
	public static class Kernel32
	{
		[Flags]
		public enum MemoryAllocationConstant : uint
		{
			Commit = 0x1000u,
			Reserve = 0x2000u,
			Reset = 0x80000u,
			ResetUndo = 0x1000000u,
			LargePages = 0x20000000u,
			Physical = 0x400000u,
			TopDown = 0x100000u,
			WriteWatch = 0x200000u
		}

		[Flags]
		public enum MemoryProtectionConstant : uint
		{
			NoAccess = 1u,
			ReadOnly = 2u,
			ReadWrite = 4u,
			WriteCopy = 8u,
			Execute = 0x10u,
			ExecuteRead = 0x20u,
			ExecuteReadWrite = 0x40u,
			ExecuteWriteCopy = 0x80u
		}

		[DllImport("kernel32.dll")]
		public static extern nint VirtualAlloc(nint lpAddress, nint dwSize, MemoryAllocationConstant flAllocationType, MemoryProtectionConstant flProtect);

		[DllImport("kernel32.dll")]
		public static extern bool VirtualProtect(nint lpAddress, nint dwSize, MemoryProtectionConstant flNewProtect, out MemoryProtectionConstant lpflOldProtect);
	}
}
namespace CroatiaUtils.Extensions
{
	public static class ArrayExtensions
	{
		public static void ShuffleWithRandom<T>(this T[] array, Random rngProvider)
		{
			for (int i = 0; i < array.Length; i++)
			{
				int num = rngProvider.Next(0, array.Length);
				int num2 = i;
				int num3 = num;
				T val = array[num];
				T val2 = array[i];
				array[num2] = val;
				array[num3] = val2;
			}
		}
	}
	public static class INativeClassStructExtensions
	{
		public static IEnumerable<INativeMethodInfoStruct> GetMethods(this INativeClassStruct nativeClassStruct)
		{
			for (int i = 0; i < nativeClassStruct.MethodCount; i++)
			{
				yield return nativeClassStruct.GetMethod(i);
			}
		}

		public static IEnumerable<INativeFieldInfoStruct> GetFields(this INativeClassStruct nativeClassStruct)
		{
			for (int i = 0; i < nativeClassStruct.FieldCount; i++)
			{
				yield return nativeClassStruct.GetField(i);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public unsafe static INativeMethodInfoStruct GetMethod(this INativeClassStruct il2cppClass, int idx)
		{
			return UnityVersionHandler.Wrap(il2cppClass.Methods[idx]);
		}

		public static INativeMethodInfoStruct? GetMethod(this INativeClassStruct il2cppClass, string name)
		{
			return il2cppClass.GetMethods().FirstOrDefault((Func<INativeMethodInfoStruct, bool>)((INativeMethodInfoStruct x) => Marshal.PtrToStringUTF8(x.Name) == name));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public unsafe static INativeFieldInfoStruct GetField(this INativeClassStruct il2cppClass, int idx)
		{
			return ((nint)((byte*)il2cppClass.Fields + idx * UnityVersionHandler.FieldInfoSize())).AsIl2CppFieldInfo();
		}
	}
	public static class IntPtrExtensions
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public unsafe static INativeClassStruct AsIl2CppClass(this IntPtr ptr)
		{
			return UnityVersionHandler.Wrap((Il2CppClass*)(void*)ptr);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public unsafe static INativeTypeStruct AsIl2CppType(this IntPtr ptr)
		{
			return UnityVersionHandler.Wrap((Il2CppTypeStruct*)(void*)ptr);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public unsafe static INativeFieldInfoStruct AsIl2CppFieldInfo(this IntPtr ptr)
		{
			return UnityVersionHandler.Wrap((Il2CppFieldInfo*)(void*)ptr);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public unsafe static INativeMethodInfoStruct AsIl2CppMethodInfo(this IntPtr ptr)
		{
			return UnityVersionHandler.Wrap((Il2CppMethodInfo*)(void*)ptr);
		}
	}
	public static class TypeExtensions
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public static IntPtr GetIl2CppClassPointer(this Type type)
		{
			return Il2CppClassPointerStore.GetNativeClassPointer(type);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
		public static INativeClassStruct GetIl2CppClass(this Type type)
		{
			return type.GetIl2CppClassPointer().AsIl2CppClass();
		}
	}
}