Add name mangling to Methods/MethodInfo/TypeInfo/TypeRef, remove Boxing from ValueTypes when used as the this parameter, fix crashes when a module has no attributes
This commit is contained in:
@@ -1,45 +1,50 @@
|
||||
/*
|
||||
Copyright 2020-2021 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
using Il2CppInspector.Cpp;
|
||||
using Il2CppInspector.Reflection;
|
||||
|
||||
namespace Il2CppInspector.Model
|
||||
{
|
||||
// Class that represents a composite IL/C++ method
|
||||
public class AppMethod
|
||||
{
|
||||
// The logical group this method is part of
|
||||
// This is purely for querying methods in related groups and has no bearing on the code
|
||||
public string Group { get; set; }
|
||||
|
||||
// The corresponding C++ function pointer type
|
||||
public CppFnPtrType CppFnPtrType { get; internal set; }
|
||||
|
||||
// The corresponding .NET method
|
||||
public MethodBase Method { get; internal set; }
|
||||
|
||||
// The VA of the MethodInfo* (VA of the pointer to the MethodInfo) object which defines this method
|
||||
// Methods not referenced by the binary will be 0xffffffff_ffffffff
|
||||
public ulong MethodInfoPtrAddress { get; internal set; }
|
||||
|
||||
// The VA of the method code itself
|
||||
// Generic method definitions do not have a code address but may have a reference above
|
||||
public ulong MethodCodeAddress => Method.VirtualAddress?.Start ?? 0xffffffff_ffffffff;
|
||||
|
||||
// Helpers
|
||||
public bool HasMethodInfo => MethodInfoPtrAddress != 0xffffffff_ffffffff;
|
||||
public bool HasCompiledCode => Method.VirtualAddress.HasValue && Method.VirtualAddress.Value.Start != 0;
|
||||
|
||||
public AppMethod(MethodBase method, CppFnPtrType cppMethod, ulong methodInfoPtr = 0xffffffff_ffffffff) {
|
||||
Method = method;
|
||||
CppFnPtrType = cppMethod;
|
||||
MethodInfoPtrAddress = methodInfoPtr;
|
||||
}
|
||||
|
||||
public override string ToString() => CppFnPtrType.ToSignatureString();
|
||||
}
|
||||
}
|
||||
/*
|
||||
Copyright 2020-2021 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
Copyright 2023 LukeFZ - https://github.com/LukeFZ
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
using System.Diagnostics;
|
||||
using Il2CppInspector.Cpp;
|
||||
using Il2CppInspector.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Il2CppInspector.Model
|
||||
{
|
||||
// Class that represents a composite IL/C++ method
|
||||
public class AppMethod
|
||||
{
|
||||
// The logical group this method is part of
|
||||
// This is purely for querying methods in related groups and has no bearing on the code
|
||||
public string Group { get; set; }
|
||||
|
||||
// The corresponding C++ function pointer type
|
||||
public CppFnPtrType CppFnPtrType { get; internal set; }
|
||||
|
||||
// The corresponding .NET method
|
||||
public MethodBase Method { get; internal set; }
|
||||
|
||||
// The VA of the MethodInfo* (VA of the pointer to the MethodInfo) object which defines this method
|
||||
// Methods not referenced by the binary will be 0xffffffff_ffffffff
|
||||
public ulong MethodInfoPtrAddress { get; internal set; }
|
||||
|
||||
// The VA of the method code itself
|
||||
// Generic method definitions do not have a code address but may have a reference above
|
||||
public ulong MethodCodeAddress => Method.VirtualAddress?.Start ?? 0xffffffff_ffffffff;
|
||||
|
||||
// Helpers
|
||||
public bool HasMethodInfo => MethodInfoPtrAddress != 0xffffffff_ffffffff;
|
||||
public bool HasCompiledCode => Method.VirtualAddress.HasValue && Method.VirtualAddress.Value.Start != 0;
|
||||
|
||||
public AppMethod(MethodBase method, CppFnPtrType cppMethod, ulong methodInfoPtr = 0xffffffff_ffffffff) {
|
||||
Method = method;
|
||||
CppFnPtrType = cppMethod;
|
||||
MethodInfoPtrAddress = methodInfoPtr;
|
||||
}
|
||||
|
||||
public override string ToString() => CppFnPtrType.ToSignatureString();
|
||||
|
||||
public string ToMangledString() => MangledNameBuilder.Method(Method);
|
||||
public string ToMangledMethodInfoString() => MangledNameBuilder.MethodInfo(Method);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ namespace Il2CppInspector.Model
|
||||
// For il2cpp < 19, the key is the string literal ordinal instead of the address
|
||||
public Dictionary<ulong, string> Strings { get; } = [];
|
||||
|
||||
public Dictionary<ulong, (string Name, string Value)> Fields { get; } = [];
|
||||
public Dictionary<ulong, (string Name, string Value)> FieldRvas { get; } = [];
|
||||
public Dictionary<ulong, (FieldInfo Field, string Value)> Fields { get; } = [];
|
||||
public Dictionary<ulong, (FieldInfo Field, string Value)> FieldRvas { get; } = [];
|
||||
|
||||
public bool StringIndexesAreOrdinals => Package.Version < 19;
|
||||
|
||||
@@ -254,10 +254,6 @@ namespace Il2CppInspector.Model
|
||||
var fieldType = TypeModel.GetMetadataUsageType(usage);
|
||||
var field = fieldType.DeclaredFields.First(f => f.Index == fieldType.Definition.fieldStart + fieldRef.fieldIndex);
|
||||
|
||||
var name = usage.Type == MetadataUsageType.FieldInfo
|
||||
? $"{fieldType.Name}.{field.Name}".ToCIdentifier()
|
||||
: $"{fieldType.Name}.{field.Name}_FieldRva".ToCIdentifier();
|
||||
|
||||
var value = field.HasFieldRVA
|
||||
? Convert.ToHexString(Package.Metadata.ReadBytes(
|
||||
(long) field.DefaultValueMetadataAddress, field.FieldType.Sizes.nativeSize))
|
||||
@@ -265,9 +261,9 @@ namespace Il2CppInspector.Model
|
||||
|
||||
|
||||
if (usage.Type == MetadataUsageType.FieldInfo)
|
||||
Fields[usage.VirtualAddress] = (name, value);
|
||||
Fields[usage.VirtualAddress] = (field, value);
|
||||
else
|
||||
FieldRvas[usage.VirtualAddress] = (name, value);
|
||||
FieldRvas[usage.VirtualAddress] = (field, value);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -345,11 +341,8 @@ namespace Il2CppInspector.Model
|
||||
// Get the address map for the model
|
||||
// This takes a while to construct so we only build it if requested
|
||||
private AddressMap addressMap;
|
||||
public AddressMap GetAddressMap() {
|
||||
if (addressMap == null)
|
||||
addressMap = new AddressMap(this);
|
||||
return addressMap;
|
||||
}
|
||||
public AddressMap GetAddressMap()
|
||||
=> addressMap ??= new AddressMap(this);
|
||||
|
||||
// Get the byte offset in Il2CppClass for this app's Unity version to the vtable
|
||||
public int GetVTableOffset() => CppTypeCollection.GetComplexType("Il2CppClass")["vtable"].OffsetBytes;
|
||||
|
||||
@@ -1,52 +1,56 @@
|
||||
/*
|
||||
Copyright 2020-2021 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
using Il2CppInspector.Cpp;
|
||||
using Il2CppInspector.Reflection;
|
||||
|
||||
namespace Il2CppInspector.Model
|
||||
{
|
||||
// Class that represents a composite IL/C++ type
|
||||
public class AppType
|
||||
{
|
||||
// The logical group this type is part of
|
||||
// This is purely for querying types in related groups and has no bearing on the code
|
||||
public string Group { get; set; }
|
||||
|
||||
// The corresponding C++ type definition which represents an instance of the object
|
||||
// This is derived from Il2CppObject
|
||||
// If the underlying .NET type is a struct (value type), this will return the boxed version
|
||||
public CppComplexType CppType { get; internal set; }
|
||||
|
||||
// For an underlying .NET type which is a struct (value type), the unboxed type, otherwise null
|
||||
public CppComplexType CppValueType { get; internal set; }
|
||||
|
||||
// The type in the .NET type model this object maps to
|
||||
public TypeInfo Type { get; internal set; }
|
||||
|
||||
// The VA of the Il2CppClass object which defines this type (ClassName__TypeInfo)
|
||||
public ulong TypeClassAddress { get; internal set; }
|
||||
|
||||
// The VA of the Il2CppType* (VA of the pointer to the Il2CppType) object which references this type (ClassName__TypeRef)
|
||||
public ulong TypeRefPtrAddress { get; internal set; }
|
||||
|
||||
public AppType(TypeInfo ilType, CppComplexType cppType, CppComplexType valueType = null,
|
||||
ulong cppClassPtr = 0xffffffff_ffffffff, ulong cppTypeRefPtr = 0xffffffff_ffffffff) {
|
||||
CppType = cppType;
|
||||
Type = ilType;
|
||||
CppValueType = valueType;
|
||||
TypeClassAddress = cppClassPtr;
|
||||
TypeRefPtrAddress = cppTypeRefPtr;
|
||||
}
|
||||
|
||||
// The C++ name of the type
|
||||
// TODO: Known issue here where we should be using CppDeclarationGenerator.TypeNamer to ensure uniqueness
|
||||
// Prefer Foo over Foo__Boxed; if there is no C++ type defined, just convert the IL type to a C identifier
|
||||
public string Name => CppValueType?.Name ?? CppType?.Name ?? Type.Name.ToCIdentifier();
|
||||
|
||||
public override string ToString() => Type.FullName + " -> " + CppType.Name;
|
||||
}
|
||||
/*
|
||||
Copyright 2020-2021 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
using Il2CppInspector.Cpp;
|
||||
using Il2CppInspector.Reflection;
|
||||
|
||||
namespace Il2CppInspector.Model
|
||||
{
|
||||
// Class that represents a composite IL/C++ type
|
||||
public class AppType
|
||||
{
|
||||
// The logical group this type is part of
|
||||
// This is purely for querying types in related groups and has no bearing on the code
|
||||
public string Group { get; set; }
|
||||
|
||||
// The corresponding C++ type definition which represents an instance of the object
|
||||
// This is derived from Il2CppObject
|
||||
// If the underlying .NET type is a struct (value type), this will return the boxed version
|
||||
public CppComplexType CppType { get; internal set; }
|
||||
|
||||
// For an underlying .NET type which is a struct (value type), the unboxed type, otherwise null
|
||||
public CppComplexType CppValueType { get; internal set; }
|
||||
|
||||
// The type in the .NET type model this object maps to
|
||||
public TypeInfo Type { get; internal set; }
|
||||
|
||||
// The VA of the Il2CppClass object which defines this type (ClassName__TypeInfo)
|
||||
public ulong TypeClassAddress { get; internal set; }
|
||||
|
||||
// The VA of the Il2CppType* (VA of the pointer to the Il2CppType) object which references this type (ClassName__TypeRef)
|
||||
public ulong TypeRefPtrAddress { get; internal set; }
|
||||
|
||||
public AppType(TypeInfo ilType, CppComplexType cppType, CppComplexType valueType = null,
|
||||
ulong cppClassPtr = 0xffffffff_ffffffff, ulong cppTypeRefPtr = 0xffffffff_ffffffff) {
|
||||
CppType = cppType;
|
||||
Type = ilType;
|
||||
CppValueType = valueType;
|
||||
TypeClassAddress = cppClassPtr;
|
||||
TypeRefPtrAddress = cppTypeRefPtr;
|
||||
}
|
||||
|
||||
// The C++ name of the type
|
||||
// TODO: Known issue here where we should be using CppDeclarationGenerator.TypeNamer to ensure uniqueness
|
||||
// Prefer Foo over Foo__Boxed; if there is no C++ type defined, just convert the IL type to a C identifier
|
||||
public string Name => CppValueType?.Name ?? CppType?.Name ?? Type.Name.ToCIdentifier();
|
||||
|
||||
public override string ToString() => Type.FullName + " -> " + CppType.Name;
|
||||
|
||||
public string ToMangledTypeInfoString() => MangledNameBuilder.TypeInfo(Type);
|
||||
|
||||
public string ToMangledTypeRefString() => MangledNameBuilder.TypeRef(Type);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user