Merge GetFieldOffsetFromIndex into Il2CppInspector ctor

This commit is contained in:
Katy Coe
2017-11-08 00:24:19 +01:00
parent 2a2617674a
commit 138c2cec48
3 changed files with 43 additions and 24 deletions

View File

@@ -17,7 +17,13 @@ namespace Il2CppInspector
public Il2CppMetadataRegistration MetadataRegistration { get; protected set; }
public uint[] MethodPointers { get; set; }
public int[] FieldOffsets { get; private set; }
// NOTE: In versions <21 and earlier releases of v21, this array has the format:
// global field index => field offset
// In versions >=22 and later releases of v21, this array has the format:
// type index => RVA in image where the list of field offsets for the type start (4 bytes per field)
public int[] FieldOffsetData { get; private set; }
public List<Il2CppType> Types { get; } = new List<Il2CppType>();
protected Il2CppBinary(IFileFormatReader stream) {
@@ -53,7 +59,7 @@ namespace Il2CppInspector
CodeRegistration = image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
MetadataRegistration = image.ReadMappedObject<Il2CppMetadataRegistration>(metadataRegistration);
MethodPointers = image.ReadMappedArray<uint>(CodeRegistration.pmethodPointers, (int) CodeRegistration.methodPointersCount);
FieldOffsets = image.ReadMappedArray<int>(MetadataRegistration.pfieldOffsets, MetadataRegistration.fieldOffsetsCount);
FieldOffsetData = image.ReadMappedArray<int>(MetadataRegistration.pfieldOffsets, MetadataRegistration.fieldOffsetsCount);
var types = image.ReadMappedArray<uint>(MetadataRegistration.ptypes, MetadataRegistration.typesCount);
for (int i = 0; i < MetadataRegistration.typesCount; i++)
Types.Add(image.ReadMappedObject<Il2CppType>(types[i]));

View File

@@ -19,10 +19,10 @@ namespace Il2CppInspector
// Shortcuts
public Dictionary<int, string> Strings => Metadata.Strings;
public Il2CppTypeDefinition[] TypeDefinitions => Metadata.Types;
public List<Il2CppType> TypeUsages => Binary.Types;
public Dictionary<int, object> FieldDefaultValue { get; } = new Dictionary<int, object>();
public List<int> FieldOffsets { get; }
public Il2CppInspector(Il2CppBinary binary, Metadata metadata) {
// Store stream representations
@@ -91,6 +91,39 @@ namespace Il2CppInspector
}
FieldDefaultValue.Add(fdv.fieldIndex, value);
}
// Get all field offsets
// Versions from 22 onwards use an array of pointers in Binary.FieldOffsetData
bool fieldOffsetsArePointers = (Metadata.Version >= 22);
// Some variants of 21 also use an array of pointers
if (Metadata.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
else {
var offsets = new Dictionary<int, int>();
for (var i = 0; i < TypeDefinitions.Length; i++) {
var def = TypeDefinitions[i];
var pFieldOffsets = Binary.FieldOffsetData[i];
if (pFieldOffsets != 0) {
Binary.Image.Stream.Position = Binary.Image.MapVATR((uint) pFieldOffsets);
for (var f = 0; f < def.field_count; f++)
offsets.Add(def.fieldStart + f, Binary.Image.Stream.ReadInt32());
}
}
FieldOffsets = offsets.OrderBy(x => x.Key).Select(x => x.Value).ToList();
}
}
public static List<Il2CppInspector> LoadFromFile(string codeFile, string metadataFile) {
@@ -182,26 +215,5 @@ namespace Il2CppInspector
}
return ret;
}
public int GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType) {
// Versions from 22 onwards use an array of pointers in fieldOffsets
bool fieldOffsetsArePointers = (Metadata.Version >= 22);
// Some variants of 21 also use an array of pointers
if (Metadata.Version == 21) {
var f = Binary.FieldOffsets;
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) {
var typeDef = TypeDefinitions[typeIndex];
return Binary.FieldOffsets[typeDef.fieldStart + fieldIndexInType];
}
var ptr = Binary.FieldOffsets[typeIndex];
Binary.Image.Stream.Position = Binary.Image.MapVATR((uint) ptr) + 4 * fieldIndexInType;
return Binary.Image.Stream.ReadInt32();
}
}
}

View File

@@ -53,6 +53,7 @@ namespace Il2CppInspector
FieldDefaultValues = ReadArray<Il2CppFieldDefaultValue>(Header.fieldDefaultValuesOffset, Header.fieldDefaultValuesCount / Sizeof(typeof(Il2CppFieldDefaultValue)));
// TODO: Events, Properties, ParameterDefaultValue, GenericParameters, ParameterConstraints, GenericContainers, Interfaces, MetadataUsage, CustomAttributes
// Get all string literals
Position = Header.stringOffset;
while (Position < Header.stringOffset + Header.stringCount)
Strings.Add((int)Position - Header.stringOffset, ReadNullTerminatedString());