using System; using System.Collections.Generic; using System.Linq; using LibCpp2IL; namespace Cpp2IL.Core; public static class Il2CppArrayUtils { public static uint GetFirstItemOffset(Il2CppBinary binary) => (uint)(binary.is32Bit ? 0x10 : 0x20); //32-bit: //0x0: klass ptr //0x4: monitor ptr //0x8: bounds ptr (where offset 0 is length) //0xc: max length (uintptr) //0x10: first item ptr public static readonly List UsefulOffsets = [ new UsefulOffset("length", 0xC, typeof(int), true), //64-bit offsets: new UsefulOffset("length", 0x18, typeof(int), false) ]; public static string? GetOffsetName(uint offset, Il2CppBinary binary) { var is32Bit = binary.is32Bit; return UsefulOffsets.FirstOrDefault(o => o.is32Bit == is32Bit && o.offset == offset)?.name; } public static bool IsIl2cppLengthAccessor(uint offset, Il2CppBinary binary) { return GetOffsetName(offset, binary) == "length"; } public static bool IsAtLeastFirstItemPtr(uint offset, Il2CppBinary binary) { return offset >= GetFirstItemOffset(binary); } public class UsefulOffset(string name, uint offset, Type type, bool is32Bit) { public string name = name; public uint offset = offset; public Type type = type; public bool is32Bit = is32Bit; } }