Disambiguate field offset array; fix pre-v21.x field offset word size in 64-bit binaries
This commit is contained in:
@@ -23,11 +23,16 @@ namespace Il2CppInspector
|
|||||||
// Only for <=v24.1
|
// Only for <=v24.1
|
||||||
public ulong[] GlobalMethodPointers { get; set; }
|
public ulong[] GlobalMethodPointers { get; set; }
|
||||||
|
|
||||||
// NOTE: In versions <21 and earlier releases of v21, this array has the format:
|
// NOTE: In versions <21 and earlier releases of v21, use FieldOffsets:
|
||||||
// global field index => field offset
|
// global field index => field offset
|
||||||
// In versions >=22 and later releases of v21, this array has the format:
|
// In versions >=22 and later releases of v21, use FieldOffsetPointers:
|
||||||
// type index => RVA in image where the list of field offsets for the type start (4 bytes per field)
|
// type index => RVA in image where the list of field offsets for the type start (4 bytes per field)
|
||||||
public long[] FieldOffsetData { get; private set; }
|
|
||||||
|
// Negative field offsets from start of each function
|
||||||
|
public uint[] FieldOffsets { get; private set; }
|
||||||
|
|
||||||
|
// Pointers to field offsets
|
||||||
|
public long[] FieldOffsetPointers { get; private set; }
|
||||||
|
|
||||||
// Every defined type
|
// Every defined type
|
||||||
public List<Il2CppType> Types { get; private set; }
|
public List<Il2CppType> Types { get; private set; }
|
||||||
@@ -149,7 +154,25 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Field offset data. Metadata <=21.x uses a value-type array; >=21.x uses a pointer array
|
// Field offset data. Metadata <=21.x uses a value-type array; >=21.x uses a pointer array
|
||||||
FieldOffsetData = image.ReadMappedWordArray(MetadataRegistration.pfieldOffsets, (int) MetadataRegistration.fieldOffsetsCount);
|
|
||||||
|
// Versions from 22 onwards use an array of pointers in Binary.FieldOffsetData
|
||||||
|
bool fieldOffsetsArePointers = (image.Version >= 22);
|
||||||
|
|
||||||
|
// Some variants of 21 also use an array of pointers
|
||||||
|
if (image.Version == 21) {
|
||||||
|
// Always 4-byte values even for 64-bit builds when array is NOT pointers
|
||||||
|
var fieldTest = image.ReadMappedArray<uint>(MetadataRegistration.pfieldOffsets, 6);
|
||||||
|
|
||||||
|
// We detect this by relying on the fact Module, Object, ValueType, Attribute, _Attribute and Int32
|
||||||
|
// are always the first six defined types, and that all but Int32 have no fields
|
||||||
|
fieldOffsetsArePointers = (fieldTest[0] == 0 && fieldTest[1] == 0 && fieldTest[2] == 0 && fieldTest[3] == 0 && fieldTest[4] == 0 && fieldTest[5] > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All older versions use values directly in the array
|
||||||
|
if (!fieldOffsetsArePointers)
|
||||||
|
FieldOffsets = image.ReadMappedArray<uint>(MetadataRegistration.pfieldOffsets, (int)MetadataRegistration.fieldOffsetsCount);
|
||||||
|
else
|
||||||
|
FieldOffsetPointers = image.ReadMappedWordArray(MetadataRegistration.pfieldOffsets, (int)MetadataRegistration.fieldOffsetsCount);
|
||||||
|
|
||||||
// Type definitions (pointer array)
|
// Type definitions (pointer array)
|
||||||
Types = image.ReadMappedObjectPointerArray<Il2CppType>(MetadataRegistration.ptypes, (int) MetadataRegistration.typesCount);
|
Types = image.ReadMappedObjectPointerArray<Il2CppType>(MetadataRegistration.ptypes, (int) MetadataRegistration.typesCount);
|
||||||
|
|||||||
@@ -111,28 +111,16 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get all field offsets
|
// Get all field offsets
|
||||||
|
if (Binary.FieldOffsets != null) {
|
||||||
// Versions from 22 onwards use an array of pointers in Binary.FieldOffsetData
|
FieldOffsets = Binary.FieldOffsets.Select(x => (long) x).ToList();
|
||||||
bool fieldOffsetsArePointers = (Version >= 22);
|
|
||||||
|
|
||||||
// Some variants of 21 also use an array of pointers
|
|
||||||
if (Version == 21) {
|
|
||||||
var f = Binary.FieldOffsetData;
|
|
||||||
// We detect this by relying on the fact Module, Object, ValueType, Attribute, _Attribute and Int32
|
|
||||||
// are always the first six defined types, and that all but Int32 have no fields
|
|
||||||
fieldOffsetsArePointers = (f[0] == 0 && f[1] == 0 && f[2] == 0 && f[3] == 0 && f[4] == 0 && f[5] > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// All older versions use values directly in the array
|
|
||||||
if (!fieldOffsetsArePointers) {
|
|
||||||
FieldOffsets = Binary.FieldOffsetData.ToList();
|
|
||||||
}
|
|
||||||
// Convert pointer list into fields
|
// Convert pointer list into fields
|
||||||
else {
|
else {
|
||||||
var offsets = new Dictionary<int, long>();
|
var offsets = new Dictionary<int, long>();
|
||||||
for (var i = 0; i < TypeDefinitions.Length; i++) {
|
for (var i = 0; i < TypeDefinitions.Length; i++) {
|
||||||
var def = TypeDefinitions[i];
|
var def = TypeDefinitions[i];
|
||||||
var pFieldOffsets = Binary.FieldOffsetData[i];
|
var pFieldOffsets = Binary.FieldOffsetPointers[i];
|
||||||
if (pFieldOffsets != 0) {
|
if (pFieldOffsets != 0) {
|
||||||
BinaryImage.Position = BinaryImage.MapVATR((ulong) pFieldOffsets);
|
BinaryImage.Position = BinaryImage.MapVATR((ulong) pFieldOffsets);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user