Calculate and output pointers to the end of each method
This commit is contained in:
@@ -38,7 +38,7 @@ namespace Il2CppInspector
|
||||
public long[] FieldOffsetPointers { get; private set; }
|
||||
|
||||
// Generated functions which call constructors on custom attributes
|
||||
public long[] CustomAttributeGenerators { get; private set; }
|
||||
public ulong[] CustomAttributeGenerators { get; private set; }
|
||||
|
||||
// Every defined type
|
||||
public List<Il2CppType> Types { get; private set; }
|
||||
@@ -187,7 +187,7 @@ namespace Il2CppInspector
|
||||
Types = image.ReadMappedObjectPointerArray<Il2CppType>(MetadataRegistration.ptypes, (int) MetadataRegistration.typesCount);
|
||||
|
||||
// Custom attribute constructors
|
||||
CustomAttributeGenerators = Image.ReadMappedWordArray(CodeRegistration.customAttributeGenerators, (int) CodeRegistration.customAttributeCount);
|
||||
CustomAttributeGenerators = Image.ReadMappedArray<ulong>(CodeRegistration.customAttributeGenerators, (int) CodeRegistration.customAttributeCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ namespace Il2CppInspector
|
||||
private Il2CppBinary Binary { get; }
|
||||
private Metadata Metadata { get; }
|
||||
|
||||
// All method pointers sorted in ascending order (for finding the end of a method)
|
||||
private List<ulong> sortedMethodPointers { get; set; }
|
||||
|
||||
// Shortcuts
|
||||
public double Version => Metadata.Version;
|
||||
|
||||
@@ -43,7 +46,7 @@ namespace Il2CppInspector
|
||||
public List<long> FieldOffsets { get; }
|
||||
public List<Il2CppType> TypeUsages => Binary.Types;
|
||||
public Dictionary<string, Il2CppCodeGenModule> Modules => Binary.Modules;
|
||||
public long[] CustomAttributeGenerators => Binary.CustomAttributeGenerators;
|
||||
public ulong[] CustomAttributeGenerators => Binary.CustomAttributeGenerators;
|
||||
|
||||
// TODO: Finish all file access in the constructor and eliminate the need for this
|
||||
public IFileFormatReader BinaryImage => Binary.Image;
|
||||
@@ -149,33 +152,50 @@ namespace Il2CppInspector
|
||||
|
||||
FieldOffsets = offsets.OrderBy(x => x.Key).Select(x => x.Value).ToList();
|
||||
}
|
||||
|
||||
// Get sorted list of method pointers
|
||||
if (Version <= 24.1)
|
||||
sortedMethodPointers = Binary.GlobalMethodPointers.OrderBy(m => m).ToList();
|
||||
if (Version >= 24.2)
|
||||
sortedMethodPointers = Binary.ModuleMethodPointers.SelectMany(module => module.Value).OrderBy(m => m).ToList();
|
||||
}
|
||||
|
||||
public ulong GetMethodPointer(Il2CppCodeGenModule module, Il2CppMethodDefinition methodDef) {
|
||||
public (ulong Start, ulong End)? GetMethodPointer(Il2CppCodeGenModule module, Il2CppMethodDefinition methodDef) {
|
||||
// Find method pointer
|
||||
if (methodDef.methodIndex < 0)
|
||||
return 0;
|
||||
return null;
|
||||
|
||||
ulong start = 0;
|
||||
|
||||
// Global method pointer array
|
||||
if (Version <= 24.1) {
|
||||
return Binary.GlobalMethodPointers[methodDef.methodIndex] & 0xffff_ffff_ffff_fffe;
|
||||
start = Binary.GlobalMethodPointers[methodDef.methodIndex] & 0xffff_ffff_ffff_fffe;
|
||||
}
|
||||
|
||||
// Per-module method pointer array uses the bottom 24 bits of the method's metadata token
|
||||
// Derived from il2cpp::vm::MetadataCache::GetMethodPointer
|
||||
var method = (methodDef.token & 0xffffff);
|
||||
if (method == 0)
|
||||
return 0;
|
||||
if (Version >= 24.2) {
|
||||
var method = (methodDef.token & 0xffffff);
|
||||
if (method == 0)
|
||||
return null;
|
||||
|
||||
// In the event of an exception, the method pointer is not set in the file
|
||||
// This probably means it has been optimized away by the compiler, or is an unused generic method
|
||||
try {
|
||||
// Remove ARM Thumb marker LSB if necessary
|
||||
return Binary.ModuleMethodPointers[module][method - 1] & 0xffff_ffff_ffff_fffe;
|
||||
// In the event of an exception, the method pointer is not set in the file
|
||||
// This probably means it has been optimized away by the compiler, or is an unused generic method
|
||||
try {
|
||||
// Remove ARM Thumb marker LSB if necessary
|
||||
start = Binary.ModuleMethodPointers[module][method - 1] & 0xffff_ffff_ffff_fffe;
|
||||
}
|
||||
catch (IndexOutOfRangeException) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException) { }
|
||||
|
||||
return 0;
|
||||
if (start == 0)
|
||||
return null;
|
||||
|
||||
// Consider the end of the method to be the start of the next method (or zero)
|
||||
// The last method end will be wrong but there is no way to calculate it
|
||||
return (start, sortedMethodPointers.FirstOrDefault(p => p > start));
|
||||
}
|
||||
|
||||
public static List<Il2CppInspector> LoadFromFile(string codeFile, string metadataFile) {
|
||||
|
||||
@@ -21,7 +21,9 @@ namespace Il2CppInspector.Reflection
|
||||
// The type of the attribute
|
||||
public TypeInfo AttributeType { get; set; }
|
||||
|
||||
public long VirtualAddress => package.CustomAttributeGenerators[Index];
|
||||
public (ulong Start, ulong End)? VirtualAddress =>
|
||||
// The last one will be wrong but there is no way to calculate it
|
||||
(package.CustomAttributeGenerators[Index], package.CustomAttributeGenerators[Math.Min(Index + 1, package.CustomAttributeGenerators.Length - 1)]);
|
||||
|
||||
public override string ToString() => "[" + AttributeType.FullName + "]";
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Il2CppInspector.Reflection
|
||||
name = name[..suffix];
|
||||
sb.Append($"{linePrefix}[{attributePrefix}{name}]");
|
||||
if (emitPointer)
|
||||
sb.Append($" {(inline? "/*" : "//")} {((ulong)cad.VirtualAddress).ToAddressString()}{(inline? " */" : "")}");
|
||||
sb.Append($" {(inline? "/*" : "//")} {cad.VirtualAddress.ToAddressString()}{(inline? " */" : "")}");
|
||||
sb.Append(inline? " ":"\n");
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace Il2CppInspector.Reflection
|
||||
? string.Format($"0x{(uint)address:X8}")
|
||||
: string.Format($"0x{address:X16}");
|
||||
|
||||
public static string ToAddressString(this (ulong start, ulong end)? address) => ToAddressString(address?.start ?? 0) + "-" + ToAddressString(address?.end ?? 0);
|
||||
|
||||
// Output a value in C#-friendly syntax
|
||||
public static string ToCSharpValue(this object value) {
|
||||
if (value is bool)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Il2CppInspector.Reflection
|
||||
// IL2CPP-specific data
|
||||
public Il2CppMethodDefinition Definition { get; }
|
||||
public int Index { get; }
|
||||
public ulong VirtualAddress { get; }
|
||||
public (ulong Start, ulong End)? VirtualAddress { get; }
|
||||
|
||||
// Information/flags about the method
|
||||
public MethodAttributes Attributes { get; protected set; }
|
||||
|
||||
Reference in New Issue
Block a user