Implement MemberInfo, FieldInfo, TypeInfo.DeclaredFields
Rename Type to TypeInfo Add TypeInfo.CSharpName Implement some generic types/parameters Implement arrays Remove obsolete Il2CppType.GetTypeFromTypeIndex Implement enhanced Il2CppReflector.GetTypeFromTypeIndex (can create array and generic types on-the-fly from Il2CppType usages)
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
public static class DefineConstants
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public static class DefineConstants
|
||||||
{
|
{
|
||||||
public const int FIELD_ATTRIBUTE_PRIVATE = 0x0001;
|
public const int FIELD_ATTRIBUTE_PRIVATE = 0x0001;
|
||||||
public const int FIELD_ATTRIBUTE_PUBLIC = 0x0006;
|
public const int FIELD_ATTRIBUTE_PUBLIC = 0x0006;
|
||||||
@@ -17,4 +19,80 @@
|
|||||||
public const int TYPE_ATTRIBUTE_SERIALIZABLE = 0x00002000;
|
public const int TYPE_ATTRIBUTE_SERIALIZABLE = 0x00002000;
|
||||||
public const int PARAM_ATTRIBUTE_OUT = 0x0002;
|
public const int PARAM_ATTRIBUTE_OUT = 0x0002;
|
||||||
public const int PARAM_ATTRIBUTE_OPTIONAL = 0x0010;
|
public const int PARAM_ATTRIBUTE_OPTIONAL = 0x0010;
|
||||||
|
|
||||||
|
public static List<string> CSharpTypeString = new List<string>
|
||||||
|
{
|
||||||
|
"END",
|
||||||
|
"void",
|
||||||
|
"bool",
|
||||||
|
"char",
|
||||||
|
"sbyte",
|
||||||
|
"byte",
|
||||||
|
"short",
|
||||||
|
"ushort",
|
||||||
|
"int",
|
||||||
|
"uint",
|
||||||
|
"long",
|
||||||
|
"ulong",
|
||||||
|
"float",
|
||||||
|
"double",
|
||||||
|
"string",
|
||||||
|
"PTR", // Processed separately
|
||||||
|
"BYREF",
|
||||||
|
"VALUETYPE", // Processed separately
|
||||||
|
"CLASS", // Processed separately
|
||||||
|
"T",
|
||||||
|
"Array", // Processed separately
|
||||||
|
"GENERICINST", // Processed separately
|
||||||
|
"TYPEDBYREF",
|
||||||
|
"None",
|
||||||
|
"IntPtr",
|
||||||
|
"UIntPtr",
|
||||||
|
"None",
|
||||||
|
"delegate",
|
||||||
|
"object",
|
||||||
|
"SZARRAY", // Processed separately
|
||||||
|
"T",
|
||||||
|
"CMOD_REQD",
|
||||||
|
"CMOD_OPT",
|
||||||
|
"INTERNAL",
|
||||||
|
};
|
||||||
|
|
||||||
|
public static List<string> FullNameTypeString = new List<string>
|
||||||
|
{
|
||||||
|
"END",
|
||||||
|
"System.Void",
|
||||||
|
"System.Boolean",
|
||||||
|
"System.Char",
|
||||||
|
"System.SByte",
|
||||||
|
"System.Byte",
|
||||||
|
"System.Int16",
|
||||||
|
"System.UInt16",
|
||||||
|
"System.Int32",
|
||||||
|
"System.UInt32",
|
||||||
|
"System.Int64",
|
||||||
|
"System.UInt64",
|
||||||
|
"System.Single",
|
||||||
|
"System.Double",
|
||||||
|
"System.String",
|
||||||
|
"PTR", // Processed separately
|
||||||
|
"BYREF",
|
||||||
|
"System.ValueType", // Processed separately
|
||||||
|
"CLASS", // Processed separately
|
||||||
|
"T",
|
||||||
|
"System.Array", // Processed separately
|
||||||
|
"GENERICINST", // Processed separately
|
||||||
|
"TYPEDBYREF",
|
||||||
|
"None",
|
||||||
|
"System.IntPtr",
|
||||||
|
"System.UIntPtr",
|
||||||
|
"None",
|
||||||
|
"System.Delegate",
|
||||||
|
"System.Object",
|
||||||
|
"SZARRAY", // Processed separately
|
||||||
|
"T",
|
||||||
|
"CMOD_REQD",
|
||||||
|
"CMOD_OPT",
|
||||||
|
"INTERNAL",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
@@ -103,18 +104,13 @@ namespace Il2CppInspector
|
|||||||
ret = $"{GetTypeName(type)}[]";
|
ret = $"{GetTypeName(type)}[]";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((int)pType.type >= szTypeString.Length)
|
if ((int)pType.type >= DefineConstants.CSharpTypeString.Count)
|
||||||
ret = "unknow";
|
ret = "unknow";
|
||||||
else
|
else
|
||||||
ret = szTypeString[(int)pType.type];
|
ret = DefineConstants.CSharpTypeString[(int)pType.type];
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Il2CppType GetTypeFromTypeIndex(int idx) {
|
|
||||||
return Binary.Types[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType) {
|
public int GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType) {
|
||||||
// Versions from 22 onwards use an array of pointers in fieldOffsets
|
// Versions from 22 onwards use an array of pointers in fieldOffsets
|
||||||
bool fieldOffsetsArePointers = (Metadata.Version >= 22);
|
bool fieldOffsetsArePointers = (Metadata.Version >= 22);
|
||||||
@@ -144,7 +140,7 @@ namespace Il2CppInspector
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
var pValue = Metadata.Header.fieldAndParameterDefaultValueDataOffset + def.dataIndex;
|
var pValue = Metadata.Header.fieldAndParameterDefaultValueDataOffset + def.dataIndex;
|
||||||
Il2CppType type = GetTypeFromTypeIndex(def.typeIndex);
|
Il2CppType type = Binary.Types[def.typeIndex];
|
||||||
if (pValue == 0)
|
if (pValue == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -192,43 +188,5 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly string[] szTypeString =
|
|
||||||
{
|
|
||||||
"END",
|
|
||||||
"void",
|
|
||||||
"bool",
|
|
||||||
"char",
|
|
||||||
"sbyte",
|
|
||||||
"byte",
|
|
||||||
"short",
|
|
||||||
"ushort",
|
|
||||||
"int",
|
|
||||||
"uint",
|
|
||||||
"long",
|
|
||||||
"ulong",
|
|
||||||
"float",
|
|
||||||
"double",
|
|
||||||
"string",
|
|
||||||
"PTR",//eg. void*
|
|
||||||
"BYREF",
|
|
||||||
"VALUETYPE",
|
|
||||||
"CLASS",
|
|
||||||
"T",
|
|
||||||
"ARRAY",
|
|
||||||
"GENERICINST",
|
|
||||||
"TYPEDBYREF",
|
|
||||||
"None",
|
|
||||||
"IntPtr",
|
|
||||||
"UIntPtr",
|
|
||||||
"None",
|
|
||||||
"FNPTR",
|
|
||||||
"object",
|
|
||||||
"SZARRAY",
|
|
||||||
"T",
|
|
||||||
"CMOD_REQD",
|
|
||||||
"CMOD_OPT",
|
|
||||||
"INTERNAL",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,53 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Il2CppInspector.Reflection
|
namespace Il2CppInspector.Reflection
|
||||||
{
|
{
|
||||||
public class Il2CppReflector
|
public class Il2CppReflector
|
||||||
{
|
{
|
||||||
|
public Il2CppInspector Package { get; }
|
||||||
public List<Assembly> Assemblies { get; } = new List<Assembly>();
|
public List<Assembly> Assemblies { get; } = new List<Assembly>();
|
||||||
|
|
||||||
public Il2CppReflector(Il2CppInspector package) {
|
public Il2CppReflector(Il2CppInspector package) {
|
||||||
|
Package = package;
|
||||||
|
|
||||||
// Create Assembly objects from Il2Cpp package
|
// Create Assembly objects from Il2Cpp package
|
||||||
for (var image = 0; image < package.Metadata.Images.Length; image++)
|
for (var image = 0; image < package.Metadata.Images.Length; image++)
|
||||||
Assemblies.Add(new Assembly(package, image));
|
Assemblies.Add(new Assembly(this, image));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the assembly in which a type is defined
|
// Get the assembly in which a type is defined
|
||||||
public Assembly GetAssembly(Type type) => Assemblies.FirstOrDefault(x => x.DefinedTypes.Contains(type));
|
public Assembly GetAssembly(TypeInfo type) => Assemblies.FirstOrDefault(x => x.DefinedTypes.Contains(type));
|
||||||
|
|
||||||
// Get a type from its IL2CPP type index
|
// Get a type from its IL2CPP type index
|
||||||
public Type GetTypeFromIndex(int typeIndex) => Assemblies.SelectMany(x => x.DefinedTypes).FirstOrDefault(x => x.Index == typeIndex);
|
public TypeInfo GetTypeFromIndex(int typeIndex) => Assemblies.SelectMany(x => x.DefinedTypes).FirstOrDefault(x => x.Index == typeIndex);
|
||||||
|
|
||||||
|
// Get or generate a type from its IL2CPP binary type usage reference
|
||||||
|
// (field, return type, generic type parameter etc.)
|
||||||
|
public TypeInfo GetType(Il2CppType pType, MemberTypes memberType = MemberTypes.All) {
|
||||||
|
switch (pType.type) {
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
|
||||||
|
// Classes defined in the metadata
|
||||||
|
return GetTypeFromIndex((int) pType.datapoint);
|
||||||
|
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_VAR:
|
||||||
|
// Everything that requires special handling
|
||||||
|
return new TypeInfo(this, pType, memberType);
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Basic primitive types
|
||||||
|
if ((int) pType.type >= DefineConstants.FullNameTypeString.Count)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return Assemblies.SelectMany(x => x.DefinedTypes).First(x => x.FullName == DefineConstants.FullNameTypeString[(int)pType.type]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
public class Assembly
|
public class Assembly
|
||||||
{
|
{
|
||||||
// IL2CPP-specific data
|
// IL2CPP-specific data
|
||||||
|
public Il2CppReflector Model { get; }
|
||||||
public Il2CppImageDefinition Definition { get; }
|
public Il2CppImageDefinition Definition { get; }
|
||||||
public int Index { get; }
|
public int Index { get; }
|
||||||
|
|
||||||
@@ -15,27 +16,28 @@ namespace Il2CppInspector.Reflection {
|
|||||||
public string FullName { get; }
|
public string FullName { get; }
|
||||||
|
|
||||||
// Entry point method for the assembly
|
// Entry point method for the assembly
|
||||||
public MethodInfo EntryPoint { get; }
|
//public MethodInfo EntryPoint { get; } // TODO
|
||||||
|
|
||||||
// List of types defined in the assembly
|
// List of types defined in the assembly
|
||||||
public List<Type> DefinedTypes { get; } = new List<Type>();
|
public List<TypeInfo> DefinedTypes { get; } = new List<TypeInfo>();
|
||||||
|
|
||||||
// Get a type from its string name (including namespace)
|
// Get a type from its string name (including namespace)
|
||||||
public Type GetType(string typeName) => DefinedTypes.FirstOrDefault(x => x.FullName == typeName);
|
public TypeInfo GetType(string typeName) => DefinedTypes.FirstOrDefault(x => x.FullName == typeName);
|
||||||
|
|
||||||
// Initialize from specified assembly index in package
|
// Initialize from specified assembly index in package
|
||||||
public Assembly(Il2CppInspector pkg, int imageIndex) {
|
public Assembly(Il2CppReflector model, int imageIndex) {
|
||||||
Definition = pkg.Metadata.Images[imageIndex];
|
Model = model;
|
||||||
|
Definition = Model.Package.Metadata.Images[imageIndex];
|
||||||
Index = Definition.assemblyIndex;
|
Index = Definition.assemblyIndex;
|
||||||
FullName = pkg.Metadata.Strings[Definition.nameIndex];
|
FullName = Model.Package.Metadata.Strings[Definition.nameIndex];
|
||||||
|
|
||||||
if (Definition.entryPointIndex != -1) {
|
if (Definition.entryPointIndex != -1) {
|
||||||
// TODO: Generate EntryPoint method from entryPointIndex
|
// TODO: Generate EntryPoint method from entryPointIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate types in DefinedTypes from typeStart to typeStart+typeCount-1
|
// Generate types in DefinedTypes from typeStart to typeStart+typeCount-1
|
||||||
for (int t = Definition.typeStart; t < Definition.typeStart + Definition.typeCount; t++)
|
for (var t = Definition.typeStart; t < Definition.typeStart + Definition.typeCount; t++)
|
||||||
DefinedTypes.Add(new Type(pkg, t, this));
|
DefinedTypes.Add(new TypeInfo(Model.Package, t, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
63
Il2CppInspector/Reflection/FieldInfo.cs
Normal file
63
Il2CppInspector/Reflection/FieldInfo.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Reflection {
|
||||||
|
public class FieldInfo : MemberInfo
|
||||||
|
{
|
||||||
|
// IL2CPP-specific data
|
||||||
|
public Il2CppFieldDefinition Definition { get; }
|
||||||
|
public int Index { get; }
|
||||||
|
|
||||||
|
// Information/flags about the field
|
||||||
|
public FieldAttributes Attributes { get; }
|
||||||
|
|
||||||
|
// Type of field
|
||||||
|
private readonly Il2CppType fieldType;
|
||||||
|
public TypeInfo FieldType => Assembly.Model.GetType(fieldType, MemberTypes.Field);
|
||||||
|
|
||||||
|
// For the Is* definitions below, see:
|
||||||
|
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.fieldinfo.isfamilyandassembly?view=netframework-4.7.1#System_Reflection_FieldInfo_IsFamilyAndAssembly
|
||||||
|
|
||||||
|
// True if the field is declared as internal
|
||||||
|
public bool IsAssembly { get; } // TODO
|
||||||
|
|
||||||
|
// True if the field is declared as protected
|
||||||
|
public bool IsFamily { get; } // TODO
|
||||||
|
|
||||||
|
// True if the field is declared as 'protected private' (always false)
|
||||||
|
public bool IsFamilyAndAssembly => false;
|
||||||
|
|
||||||
|
// True if the field is declared as protected public
|
||||||
|
public bool IsFamilyOrAssembly { get; } // TODO
|
||||||
|
|
||||||
|
// True if the field is declared as readonly
|
||||||
|
public bool IsInitOnly => (Attributes & FieldAttributes.InitOnly) == FieldAttributes.InitOnly;
|
||||||
|
|
||||||
|
// True if the field is declared a private
|
||||||
|
public bool IsPrivate => (Attributes & FieldAttributes.Private) == FieldAttributes.Private;
|
||||||
|
|
||||||
|
// True if the field is declared as public
|
||||||
|
public bool IsPublic => (Attributes & FieldAttributes.Public) == FieldAttributes.Public;
|
||||||
|
|
||||||
|
// True if the field is declared as static
|
||||||
|
public bool IsStatic => (Attributes & FieldAttributes.Static) == FieldAttributes.Static;
|
||||||
|
|
||||||
|
public override MemberTypes MemberType { get; }
|
||||||
|
|
||||||
|
public FieldInfo(Il2CppInspector pkg, int fieldIndex, TypeInfo declaringType) :
|
||||||
|
base(declaringType) {
|
||||||
|
Definition = pkg.Metadata.Fields[fieldIndex];
|
||||||
|
Index = fieldIndex;
|
||||||
|
Name = pkg.Metadata.Strings[pkg.Metadata.Fields[fieldIndex].nameIndex];
|
||||||
|
|
||||||
|
fieldType = pkg.Binary.Types[Definition.typeIndex];
|
||||||
|
if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_PRIVATE) == DefineConstants.FIELD_ATTRIBUTE_PRIVATE)
|
||||||
|
Attributes |= FieldAttributes.Private;
|
||||||
|
if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_PUBLIC) == DefineConstants.FIELD_ATTRIBUTE_PUBLIC)
|
||||||
|
Attributes |= FieldAttributes.Public;
|
||||||
|
if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_STATIC) == DefineConstants.FIELD_ATTRIBUTE_STATIC)
|
||||||
|
Attributes |= FieldAttributes.Static;
|
||||||
|
if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_INIT_ONLY) == DefineConstants.FIELD_ATTRIBUTE_INIT_ONLY)
|
||||||
|
Attributes |= FieldAttributes.InitOnly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,21 +4,35 @@ using System.Reflection;
|
|||||||
namespace Il2CppInspector.Reflection {
|
namespace Il2CppInspector.Reflection {
|
||||||
public abstract class MemberInfo
|
public abstract class MemberInfo
|
||||||
{
|
{
|
||||||
// Assembly that this member is defined in
|
// Assembly that this member is defined in. Only set when MemberType == TypeInfo
|
||||||
public Assembly Assembly { get; set; }
|
public Assembly Assembly { get; }
|
||||||
|
|
||||||
// Custom attributes for this member
|
// Custom attributes for this member
|
||||||
public IEnumerable<CustomAttributeData> CustomAttributes { get; set; } // TODO
|
public IEnumerable<CustomAttributeData> CustomAttributes { get; } // TODO
|
||||||
|
|
||||||
// Type that this type is declared in for nested types
|
// Type that this type is declared in for nested types
|
||||||
public Type DeclaringType { get; set; } // TODO
|
public TypeInfo DeclaringType { get; }
|
||||||
|
|
||||||
// What sort of member this is, eg. method, field etc.
|
// What sort of member this is, eg. method, field etc.
|
||||||
public MemberTypes MemberType { get; set; } // TODO
|
public abstract MemberTypes MemberType { get; }
|
||||||
|
|
||||||
// Name of the member
|
// Name of the member
|
||||||
public string Name { get; set; }
|
public virtual string Name { get; protected set; }
|
||||||
|
|
||||||
// TODO: GetCustomAttributes etc.
|
// TODO: GetCustomAttributes etc.
|
||||||
|
|
||||||
|
// For top-level members in an assembly (ie. non-nested types)
|
||||||
|
protected MemberInfo(Assembly asm, TypeInfo declaringType = null) {
|
||||||
|
Assembly = asm;
|
||||||
|
DeclaringType = declaringType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For lower level members, eg. fields, properties etc. and nested types
|
||||||
|
protected MemberInfo(TypeInfo declaringType) {
|
||||||
|
if (declaringType != null) {
|
||||||
|
Assembly = declaringType.Assembly;
|
||||||
|
DeclaringType = declaringType;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ using System.Reflection;
|
|||||||
|
|
||||||
namespace Il2CppInspector.Reflection
|
namespace Il2CppInspector.Reflection
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
public abstract class MethodBase : MemberInfo
|
public abstract class MethodBase : MemberInfo
|
||||||
{
|
{
|
||||||
// (not code attributes)
|
// (not code attributes)
|
||||||
@@ -21,11 +22,6 @@ namespace Il2CppInspector.Reflection
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FieldInfo : MemberInfo
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PropertyInfo : MemberInfo
|
public class PropertyInfo : MemberInfo
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
@@ -35,4 +31,5 @@ namespace Il2CppInspector.Reflection
|
|||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Il2CppInspector.Reflection {
|
|
||||||
public class Type : MemberInfo
|
|
||||||
{
|
|
||||||
// IL2CPP-specific data
|
|
||||||
public Il2CppTypeDefinition Definition { get; }
|
|
||||||
public int Index { get; }
|
|
||||||
|
|
||||||
// (not code attributes)
|
|
||||||
// Undefined if the Type represents a generic type parameter
|
|
||||||
public TypeAttributes Attributes { get; } // TODO
|
|
||||||
|
|
||||||
// Type that this type inherits from
|
|
||||||
public Type BaseType { get; } // TODO
|
|
||||||
|
|
||||||
// TODO: ContainsGenericParameters
|
|
||||||
|
|
||||||
// Method that the type is declared in if this is a type parameter of a generic method
|
|
||||||
public MethodBase DeclaringMethod { get; } // TODO
|
|
||||||
|
|
||||||
// Gets the type of the object encompassed or referred to by the current array, pointer or reference type
|
|
||||||
public Type ElementType { get; } // TODO
|
|
||||||
|
|
||||||
// Type name including namespace
|
|
||||||
public string FullName => Namespace + "." + Name;
|
|
||||||
|
|
||||||
// TODO: Generic stuff
|
|
||||||
|
|
||||||
public bool HasElementType { get; } // TODO
|
|
||||||
public bool IsAbstract { get; }
|
|
||||||
public bool IsArray { get; } // TODO
|
|
||||||
public bool IsByRef { get; } // TODO
|
|
||||||
public bool IsClass { get; }
|
|
||||||
public bool IsEnum { get; } // TODO
|
|
||||||
public bool IsGenericParameter { get; } // TODO
|
|
||||||
public bool IsGenericType { get; } // TODO
|
|
||||||
public bool IsGenericTypeDefinition { get; } // TODO
|
|
||||||
public bool IsInterface { get; }
|
|
||||||
public bool IsNested { get; } // TODO
|
|
||||||
public bool IsNestedPrivate { get; } // TODO
|
|
||||||
public bool IsNestedPublic { get; } // TODO
|
|
||||||
public bool IsPointer { get; } // TODO
|
|
||||||
public bool IsPrimitive { get; } // TODO
|
|
||||||
public bool IsPublic { get; }
|
|
||||||
public bool IsSealed { get; }
|
|
||||||
public bool IsSerializable { get; }
|
|
||||||
public bool IsValueType { get; } // TODO
|
|
||||||
|
|
||||||
public string Namespace { get; }
|
|
||||||
|
|
||||||
// Number of dimensions of an array
|
|
||||||
public int GetArrayRank() => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public List<ConstructorInfo> Constructors { get; } // TODO
|
|
||||||
|
|
||||||
public List<Type> Inerfaces { get; } // TODO
|
|
||||||
|
|
||||||
public List<MemberInfo> Members { get; } // TODO
|
|
||||||
|
|
||||||
public List<MethodInfo> Methods { get; } // TODO
|
|
||||||
|
|
||||||
public List<FieldInfo> Fields { get; } // TODO
|
|
||||||
|
|
||||||
public List<Type> NestedTypes { get; } // TODO
|
|
||||||
|
|
||||||
public List<PropertyInfo> Properties { get; } // TODO
|
|
||||||
|
|
||||||
// TODO: Custom attribute stuff
|
|
||||||
|
|
||||||
public string[] GetEnumNames() => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public Type GetEnumUnderlyingType() => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public Array GetEnumValues() => throw new NotImplementedException();
|
|
||||||
|
|
||||||
// TODO: Event stuff
|
|
||||||
|
|
||||||
// TODO: Generic stuff
|
|
||||||
|
|
||||||
// Initialize from specified type index in package
|
|
||||||
public Type(Il2CppInspector pkg, int typeIndex, Assembly owner) {
|
|
||||||
Assembly = owner;
|
|
||||||
Definition = pkg.Metadata.Types[typeIndex];
|
|
||||||
Index = typeIndex;
|
|
||||||
Name = pkg.Metadata.Strings[Definition.nameIndex];
|
|
||||||
Namespace = pkg.Metadata.Strings[Definition.namespaceIndex];
|
|
||||||
|
|
||||||
IsSerializable = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SERIALIZABLE) != 0;
|
|
||||||
IsPublic = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_VISIBILITY_MASK) == DefineConstants.TYPE_ATTRIBUTE_PUBLIC;
|
|
||||||
IsAbstract = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_ABSTRACT) != 0;
|
|
||||||
IsSealed = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SEALED) != 0;
|
|
||||||
IsInterface = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_INTERFACE) != 0;
|
|
||||||
IsClass = !IsInterface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
202
Il2CppInspector/Reflection/TypeInfo.cs
Normal file
202
Il2CppInspector/Reflection/TypeInfo.cs
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Reflection {
|
||||||
|
public class TypeInfo : MemberInfo
|
||||||
|
{
|
||||||
|
// IL2CPP-specific data
|
||||||
|
public Il2CppTypeDefinition Definition { get; }
|
||||||
|
public int Index { get; }
|
||||||
|
|
||||||
|
// Information/flags about the type
|
||||||
|
// Undefined if the Type represents a generic type parameter
|
||||||
|
public TypeAttributes Attributes { get; } // TODO
|
||||||
|
|
||||||
|
// Type that this type inherits from
|
||||||
|
public TypeInfo BaseType { get; } // TODO
|
||||||
|
|
||||||
|
// True if the type contains unresolved generic type parameters
|
||||||
|
public bool ContainsGenericParameters { get; }
|
||||||
|
|
||||||
|
// C# colloquial name of the type (if available)
|
||||||
|
public string CSharpName {
|
||||||
|
get {
|
||||||
|
var s = Namespace + "." + base.Name;
|
||||||
|
var i = DefineConstants.FullNameTypeString.IndexOf(s);
|
||||||
|
var n = (i != -1 ? DefineConstants.CSharpTypeString[i] : base.Name);
|
||||||
|
if (IsArray)
|
||||||
|
n = ElementType.CSharpName;
|
||||||
|
var g = (GenericTypeParameters != null ? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.CSharpName)) + ">" : "");
|
||||||
|
return (IsPointer ? "void *" : "") + n + g + (IsArray ? "[]" : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ConstructorInfo> DeclaredConstructors { get; } // TODO
|
||||||
|
public List<EventInfo> DeclaredEvents { get; } // TODO
|
||||||
|
public List<FieldInfo> DeclaredFields { get; } = new List<FieldInfo>();
|
||||||
|
public List<MemberInfo> DeclaredMembers { get; } // TODO
|
||||||
|
public List<MethodInfo> DeclaredMethods { get; } // TODO
|
||||||
|
public List<TypeInfo> DeclaredNestedTypes { get; } // TODO
|
||||||
|
public List<PropertyInfo> DeclaredProperties { get; } // TODO
|
||||||
|
|
||||||
|
// Method that the type is declared in if this is a type parameter of a generic method
|
||||||
|
public MethodBase DeclaringMethod { get; } // TODO
|
||||||
|
|
||||||
|
// Gets the type of the object encompassed or referred to by the current array, pointer or reference type
|
||||||
|
public TypeInfo ElementType { get; }
|
||||||
|
|
||||||
|
// Type name including namespace
|
||||||
|
public string FullName => (IsPointer? "void *" : "")
|
||||||
|
+ Namespace
|
||||||
|
+ (Namespace.Length > 0? "." : "")
|
||||||
|
+ base.Name
|
||||||
|
+ (GenericTypeParameters != null ? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.Name)) + ">" : "")
|
||||||
|
+ (IsArray? "[]" : "");
|
||||||
|
|
||||||
|
// TODO: Alot of other generics stuff
|
||||||
|
|
||||||
|
public List<TypeInfo> GenericTypeParameters { get; }
|
||||||
|
|
||||||
|
public bool HasElementType => ElementType != null;
|
||||||
|
public bool IsAbstract { get; }
|
||||||
|
public bool IsArray { get; }
|
||||||
|
public bool IsByRef { get; } // TODO
|
||||||
|
public bool IsClass { get; }
|
||||||
|
public bool IsEnum { get; } // TODO
|
||||||
|
public bool IsGenericParameter { get; }
|
||||||
|
public bool IsGenericType { get; } // TODO
|
||||||
|
public bool IsGenericTypeDefinition { get; } // TODO
|
||||||
|
public bool IsInterface { get; }
|
||||||
|
public bool IsNested { get; } // TODO
|
||||||
|
public bool IsNestedPrivate { get; } // TODO
|
||||||
|
public bool IsNestedPublic { get; } // TODO
|
||||||
|
public bool IsPointer { get; } // TODO
|
||||||
|
public bool IsPrimitive { get; } // TODO
|
||||||
|
public bool IsPublic { get; }
|
||||||
|
public bool IsSealed { get; }
|
||||||
|
public bool IsSerializable { get; }
|
||||||
|
public bool IsValueType { get; } // TODO
|
||||||
|
|
||||||
|
public override MemberTypes MemberType { get; }
|
||||||
|
|
||||||
|
public override string Name {
|
||||||
|
get => (IsPointer ? "void *" : "")
|
||||||
|
+ base.Name
|
||||||
|
+ (GenericTypeParameters != null? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.Name)) + ">" : "")
|
||||||
|
+ (IsArray ? "[]" : "");
|
||||||
|
protected set => base.Name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Namespace { get; }
|
||||||
|
|
||||||
|
// Number of dimensions of an array
|
||||||
|
private readonly int arrayRank;
|
||||||
|
public int GetArrayRank() => arrayRank;
|
||||||
|
|
||||||
|
// TODO: Custom attribute stuff
|
||||||
|
|
||||||
|
public string[] GetEnumNames() => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public TypeInfo GetEnumUnderlyingType() => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public Array GetEnumValues() => throw new NotImplementedException();
|
||||||
|
|
||||||
|
// TODO: Event stuff
|
||||||
|
|
||||||
|
// TODO: Generic stuff
|
||||||
|
|
||||||
|
// Initialize from specified type index in metadata
|
||||||
|
public TypeInfo(Il2CppInspector pkg, int typeIndex, Assembly owner) :
|
||||||
|
base(owner) {
|
||||||
|
Definition = pkg.Metadata.Types[typeIndex];
|
||||||
|
Index = typeIndex;
|
||||||
|
Namespace = pkg.Metadata.Strings[Definition.namespaceIndex];
|
||||||
|
Name = pkg.Metadata.Strings[pkg.Metadata.Types[typeIndex].nameIndex];
|
||||||
|
|
||||||
|
IsSerializable = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SERIALIZABLE) != 0;
|
||||||
|
IsPublic = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_VISIBILITY_MASK) == DefineConstants.TYPE_ATTRIBUTE_PUBLIC;
|
||||||
|
IsAbstract = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_ABSTRACT) != 0;
|
||||||
|
IsSealed = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SEALED) != 0;
|
||||||
|
IsInterface = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_INTERFACE) != 0;
|
||||||
|
IsClass = !IsInterface;
|
||||||
|
|
||||||
|
for (var f = Definition.fieldStart; f < Definition.fieldStart + Definition.field_count; f++)
|
||||||
|
DeclaredFields.Add(new FieldInfo(pkg, f, this));
|
||||||
|
|
||||||
|
MemberType = MemberTypes.TypeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize type from binary usage
|
||||||
|
public TypeInfo(Il2CppReflector model, Il2CppType pType, MemberTypes memberType) : base(null) {
|
||||||
|
var image = model.Package.Binary.Image;
|
||||||
|
|
||||||
|
IsNested = true;
|
||||||
|
MemberType = memberType;
|
||||||
|
|
||||||
|
// Generic type unresolved and concrete instance types
|
||||||
|
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST) {
|
||||||
|
var generic = image.ReadMappedObject<Il2CppGenericClass>(pType.datapoint);
|
||||||
|
var genericTypeDef = model.GetTypeFromIndex(generic.typeDefinitionIndex);
|
||||||
|
|
||||||
|
Namespace = genericTypeDef.Namespace;
|
||||||
|
Name = genericTypeDef.Name;
|
||||||
|
|
||||||
|
// TODO: Generic* properties and ContainsGenericParameters
|
||||||
|
|
||||||
|
// Get the instantiation
|
||||||
|
var genericInstance = image.ReadMappedObject<Il2CppGenericInst>(generic.context.class_inst);
|
||||||
|
|
||||||
|
// Get list of pointers to type parameters (both unresolved and concrete)
|
||||||
|
var genericTypeParameters = image.ReadMappedArray<uint>(genericInstance.type_argv, (int)genericInstance.type_argc);
|
||||||
|
|
||||||
|
GenericTypeParameters = new List<TypeInfo>();
|
||||||
|
foreach (var pArg in genericTypeParameters) {
|
||||||
|
var argType = image.ReadMappedObject<Il2CppType>(pArg);
|
||||||
|
// TODO: Detect whether unresolved or concrete (add concrete to GenericTypeArguments instead)
|
||||||
|
// TODO: GenericParameterPosition etc. in types we generate here
|
||||||
|
GenericTypeParameters.Add(model.GetType(argType)); // TODO: Fix MemberType here
|
||||||
|
}
|
||||||
|
|
||||||
|
IsClass = true;
|
||||||
|
IsInterface = !IsClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array with known dimensions and bounds
|
||||||
|
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_ARRAY) {
|
||||||
|
var descriptor = image.ReadMappedObject<Il2CppArrayType>(pType.datapoint);
|
||||||
|
var elementType = image.ReadMappedObject<Il2CppType>(descriptor.etype);
|
||||||
|
ElementType = model.GetType(elementType);
|
||||||
|
Namespace = ElementType.Namespace;
|
||||||
|
Name = ElementType.Name;
|
||||||
|
|
||||||
|
IsArray = true;
|
||||||
|
arrayRank = descriptor.rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dynamically allocated array
|
||||||
|
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY) {
|
||||||
|
var elementType = image.ReadMappedObject<Il2CppType>(pType.datapoint);
|
||||||
|
ElementType = model.GetType(elementType);
|
||||||
|
Namespace = ElementType.Namespace;
|
||||||
|
Name = ElementType.Name;
|
||||||
|
|
||||||
|
IsArray = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unresolved generic type variable
|
||||||
|
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_VAR) {
|
||||||
|
ContainsGenericParameters = true;
|
||||||
|
IsClass = true;
|
||||||
|
IsGenericParameter = true;
|
||||||
|
Name = "T"; // TODO: Don't hardcode parameter name
|
||||||
|
|
||||||
|
// TODO: GenericTypeParameters?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pointer type
|
||||||
|
IsPointer = (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_PTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user