mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-25 02:03:02 -03:00
处理MethodInfo和RGCTX
This commit is contained in:
parent
67837998fb
commit
c116200e06
9 changed files with 399 additions and 90 deletions
|
@ -164,6 +164,11 @@ namespace Il2CppDumper
|
|||
{
|
||||
i.SetValue(t, ReadPrimitive(fieldType));
|
||||
}
|
||||
else if (fieldType.IsEnum)
|
||||
{
|
||||
var e = fieldType.GetField("value__").FieldType;
|
||||
i.SetValue(t, ReadPrimitive(e));
|
||||
}
|
||||
else if (fieldType.IsArray)
|
||||
{
|
||||
var arrayLengthAttribute = i.GetCustomAttribute<ArrayLengthAttribute>();
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace Il2CppDumper
|
|||
protected long maxMetadataUsages;
|
||||
private Il2CppCodeGenModule[] codeGenModules;
|
||||
public ulong[][] codeGenModuleMethodPointers;
|
||||
public Dictionary<int, Dictionary<uint, Il2CppRGCTXDefinition[]>> rgctxsDictionary = new Dictionary<int, Dictionary<uint, Il2CppRGCTXDefinition[]>>();
|
||||
|
||||
public abstract ulong MapVATR(ulong uiAddr);
|
||||
public abstract bool Search();
|
||||
|
@ -138,6 +139,20 @@ namespace Il2CppDumper
|
|||
{
|
||||
codeGenModuleMethodPointers[i] = new ulong[codeGenModule.methodPointerCount];
|
||||
}
|
||||
|
||||
var rgctxsDefDictionary = new Dictionary<uint, Il2CppRGCTXDefinition[]>();
|
||||
rgctxsDictionary.Add(i, rgctxsDefDictionary);
|
||||
if (codeGenModule.rgctxsCount > 0)
|
||||
{
|
||||
var rgctxs = MapVATR<Il2CppRGCTXDefinition>(codeGenModule.rgctxs, codeGenModule.rgctxsCount);
|
||||
var rgctxRanges = MapVATR<Il2CppTokenRangePair>(codeGenModule.rgctxRanges, codeGenModule.rgctxRangesCount);
|
||||
foreach (var rgctxRange in rgctxRanges)
|
||||
{
|
||||
var rgctxDefs = new Il2CppRGCTXDefinition[rgctxRange.range.length];
|
||||
Array.Copy(rgctxs, rgctxRange.range.start, rgctxDefs, 0, rgctxRange.range.length);
|
||||
rgctxsDefDictionary.Add(rgctxRange.token, rgctxDefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -231,10 +231,22 @@ namespace Il2CppDumper
|
|||
public ulong invokerIndices;
|
||||
public ulong reversePInvokeWrapperCount;
|
||||
public ulong reversePInvokeWrapperIndices;
|
||||
public ulong rgctxRangesCount;
|
||||
public long rgctxRangesCount;
|
||||
public ulong rgctxRanges;
|
||||
public ulong rgctxsCount;
|
||||
public long rgctxsCount;
|
||||
public ulong rgctxs;
|
||||
public ulong debuggerMetadata;
|
||||
}
|
||||
|
||||
public class Il2CppRange
|
||||
{
|
||||
public int start;
|
||||
public int length;
|
||||
}
|
||||
|
||||
public class Il2CppTokenRangePair
|
||||
{
|
||||
public uint token;
|
||||
public Il2CppRange range;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ namespace Il2CppDumper
|
|||
public Il2CppGenericParameter[] genericParameters;
|
||||
public int[] constraintIndices;
|
||||
public uint[] vtableMethods;
|
||||
public Il2CppRGCTXDefinition[] rgctxEntries;
|
||||
|
||||
private Dictionary<uint, string> stringCache = new Dictionary<uint, string>();
|
||||
|
||||
public Metadata(Stream stream) : base(stream)
|
||||
|
@ -113,6 +115,10 @@ namespace Il2CppDumper
|
|||
}
|
||||
}
|
||||
}
|
||||
if (Version <= 24.1f)
|
||||
{
|
||||
rgctxEntries = ReadMetadataClassArray<Il2CppRGCTXDefinition>(metadataHeader.rgctxEntriesOffset, metadataHeader.rgctxEntriesCount);
|
||||
}
|
||||
}
|
||||
|
||||
private T[] ReadMetadataClassArray<T>(uint addr, int count) where T : new()
|
||||
|
@ -213,19 +219,33 @@ namespace Il2CppDumper
|
|||
if (Version < attr.Min || Version > attr.Max)
|
||||
continue;
|
||||
}
|
||||
switch (i.FieldType.Name)
|
||||
var fieldType = i.FieldType;
|
||||
if (fieldType.IsPrimitive)
|
||||
{
|
||||
case "Int32":
|
||||
case "UInt32":
|
||||
size += 4;
|
||||
break;
|
||||
case "Int16":
|
||||
case "UInt16":
|
||||
size += 2;
|
||||
break;
|
||||
size += GetPrimitiveTypeSize(fieldType.Name);
|
||||
}
|
||||
else if (fieldType.IsEnum)
|
||||
{
|
||||
var e = fieldType.GetField("value__").FieldType;
|
||||
size += GetPrimitiveTypeSize(e.Name);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
|
||||
int GetPrimitiveTypeSize(string name)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "Int32":
|
||||
case "UInt32":
|
||||
return 4;
|
||||
case "Int16":
|
||||
case "UInt16":
|
||||
return 2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace Il2CppDumper
|
|||
public uint typeDefinitionsOffset; // Il2CppTypeDefinition
|
||||
public int typeDefinitionsCount;
|
||||
[Version(Max = 24.1f)]
|
||||
public int rgctxEntriesOffset; // Il2CppRGCTXDefinition
|
||||
public uint rgctxEntriesOffset; // Il2CppRGCTXDefinition
|
||||
[Version(Max = 24.1f)]
|
||||
public int rgctxEntriesCount;
|
||||
public uint imagesOffset; // Il2CppImageDefinition
|
||||
|
@ -320,4 +320,26 @@ namespace Il2CppDumper
|
|||
public ushort num;
|
||||
public ushort flags;
|
||||
}
|
||||
|
||||
public enum Il2CppRGCTXDataType
|
||||
{
|
||||
IL2CPP_RGCTX_DATA_INVALID,
|
||||
IL2CPP_RGCTX_DATA_TYPE,
|
||||
IL2CPP_RGCTX_DATA_CLASS,
|
||||
IL2CPP_RGCTX_DATA_METHOD,
|
||||
IL2CPP_RGCTX_DATA_ARRAY,
|
||||
}
|
||||
|
||||
public class Il2CppRGCTXDefinitionData
|
||||
{
|
||||
public int rgctxDataDummy;
|
||||
public int methodIndex => rgctxDataDummy;
|
||||
public int typeIndex => rgctxDataDummy;
|
||||
}
|
||||
|
||||
public class Il2CppRGCTXDefinition
|
||||
{
|
||||
public Il2CppRGCTXDataType type;
|
||||
public Il2CppRGCTXDefinitionData data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,10 +23,14 @@ typedef unsigned long long uint64_t;
|
|||
";
|
||||
|
||||
public readonly static string GenericHeader =
|
||||
@"struct VirtualInvokeData
|
||||
@"typedef void(*Il2CppMethodPointer)();
|
||||
|
||||
struct MethodInfo;
|
||||
|
||||
struct VirtualInvokeData
|
||||
{
|
||||
uintptr_t methodPtr;
|
||||
void* method;
|
||||
Il2CppMethodPointer methodPtr;
|
||||
const MethodInfo* method;
|
||||
};
|
||||
|
||||
struct Il2CppType
|
||||
|
@ -43,10 +47,12 @@ struct Il2CppObject
|
|||
void *monitor;
|
||||
};
|
||||
|
||||
struct Il2CppArrayBounds
|
||||
union Il2CppRGCTXData
|
||||
{
|
||||
uintptr_t length;
|
||||
int32_t lower_bound;
|
||||
void* rgctxDataDummy;
|
||||
const MethodInfo* method;
|
||||
const Il2CppType* type;
|
||||
Il2CppClass* klass;
|
||||
};
|
||||
|
||||
";
|
||||
|
@ -79,7 +85,6 @@ struct Il2CppArrayBounds
|
|||
|
||||
struct Il2CppClass_2
|
||||
{
|
||||
void* rgctx_data;
|
||||
Il2CppClass** typeHierarchy;
|
||||
void *unity_user_data;
|
||||
uint32_t initializationExceptionGCHandle;
|
||||
|
@ -118,10 +123,45 @@ struct Il2CppClass
|
|||
{
|
||||
Il2CppClass_1 _1;
|
||||
void* static_fields;
|
||||
Il2CppRGCTXData* rgctx_data;
|
||||
Il2CppClass_2 _2;
|
||||
VirtualInvokeData vtable[255];
|
||||
};
|
||||
|
||||
typedef uintptr_t il2cpp_array_size_t;
|
||||
typedef int32_t il2cpp_array_lower_bound_t;
|
||||
struct Il2CppArrayBounds
|
||||
{
|
||||
il2cpp_array_size_t length;
|
||||
il2cpp_array_lower_bound_t lower_bound;
|
||||
};
|
||||
|
||||
struct MethodInfo
|
||||
{
|
||||
Il2CppMethodPointer methodPointer;
|
||||
void* invoker_method;
|
||||
const char* name;
|
||||
Il2CppClass *klass;
|
||||
const Il2CppType *return_type;
|
||||
const void* parameters;
|
||||
union
|
||||
{
|
||||
const Il2CppRGCTXData* rgctx_data;
|
||||
const void* methodDefinition;
|
||||
};
|
||||
union
|
||||
{
|
||||
const void* genericMethod;
|
||||
const void* genericContainer;
|
||||
};
|
||||
uint32_t token;
|
||||
uint16_t flags;
|
||||
uint16_t iflags;
|
||||
uint16_t slot;
|
||||
uint8_t parameters_count;
|
||||
uint8_t bitflags;
|
||||
};
|
||||
|
||||
";
|
||||
|
||||
public readonly static string HeaderV241 =
|
||||
|
@ -152,7 +192,6 @@ struct Il2CppClass
|
|||
|
||||
struct Il2CppClass_2
|
||||
{
|
||||
void* rgctx_data;
|
||||
Il2CppClass** typeHierarchy;
|
||||
uint32_t initializationExceptionGCHandle;
|
||||
uint32_t cctor_started;
|
||||
|
@ -190,10 +229,45 @@ struct Il2CppClass
|
|||
{
|
||||
Il2CppClass_1 _1;
|
||||
void* static_fields;
|
||||
Il2CppRGCTXData* rgctx_data;
|
||||
Il2CppClass_2 _2;
|
||||
VirtualInvokeData vtable[255];
|
||||
};
|
||||
|
||||
typedef uintptr_t il2cpp_array_size_t;
|
||||
typedef int32_t il2cpp_array_lower_bound_t;
|
||||
struct Il2CppArrayBounds
|
||||
{
|
||||
il2cpp_array_size_t length;
|
||||
il2cpp_array_lower_bound_t lower_bound;
|
||||
};
|
||||
|
||||
struct MethodInfo
|
||||
{
|
||||
Il2CppMethodPointer methodPointer;
|
||||
void* invoker_method;
|
||||
const char* name;
|
||||
Il2CppClass *klass;
|
||||
const Il2CppType *return_type;
|
||||
const void* parameters;
|
||||
union
|
||||
{
|
||||
const Il2CppRGCTXData* rgctx_data;
|
||||
const void* methodDefinition;
|
||||
};
|
||||
union
|
||||
{
|
||||
const void* genericMethod;
|
||||
const void* genericContainer;
|
||||
};
|
||||
uint32_t token;
|
||||
uint16_t flags;
|
||||
uint16_t iflags;
|
||||
uint16_t slot;
|
||||
uint8_t parameters_count;
|
||||
uint8_t bitflags;
|
||||
};
|
||||
|
||||
";
|
||||
|
||||
public readonly static string HeaderV240 =
|
||||
|
@ -223,7 +297,6 @@ struct Il2CppClass
|
|||
|
||||
struct Il2CppClass_2
|
||||
{
|
||||
void* rgctx_data;
|
||||
Il2CppClass** typeHierarchy;
|
||||
uint32_t cctor_started;
|
||||
uint32_t cctor_finished;
|
||||
|
@ -260,10 +333,46 @@ struct Il2CppClass
|
|||
{
|
||||
Il2CppClass_1 _1;
|
||||
void* static_fields;
|
||||
Il2CppRGCTXData* rgctx_data;
|
||||
Il2CppClass_2 _2;
|
||||
VirtualInvokeData vtable[255];
|
||||
};
|
||||
|
||||
typedef int32_t il2cpp_array_size_t;
|
||||
typedef int32_t il2cpp_array_lower_bound_t;
|
||||
struct Il2CppArrayBounds
|
||||
{
|
||||
il2cpp_array_size_t length;
|
||||
il2cpp_array_lower_bound_t lower_bound;
|
||||
};
|
||||
|
||||
struct MethodInfo
|
||||
{
|
||||
Il2CppMethodPointer methodPointer;
|
||||
void* invoker_method;
|
||||
const char* name;
|
||||
Il2CppClass *declaring_type;
|
||||
const Il2CppType *return_type;
|
||||
const void* parameters;
|
||||
union
|
||||
{
|
||||
const Il2CppRGCTXData* rgctx_data;
|
||||
const void* methodDefinition;
|
||||
};
|
||||
union
|
||||
{
|
||||
const void* genericMethod;
|
||||
const void* genericContainer;
|
||||
};
|
||||
int32_t customAttributeIndex;
|
||||
uint32_t token;
|
||||
uint16_t flags;
|
||||
uint16_t iflags;
|
||||
uint16_t slot;
|
||||
uint8_t parameters_count;
|
||||
uint8_t bitflags;
|
||||
};
|
||||
|
||||
";
|
||||
|
||||
public readonly static string HeaderV22 =
|
||||
|
@ -292,7 +401,6 @@ struct Il2CppClass
|
|||
|
||||
struct Il2CppClass_2
|
||||
{
|
||||
void* rgctx_data;
|
||||
Il2CppClass** typeHierarchy;
|
||||
uint32_t cctor_started;
|
||||
uint32_t cctor_finished;
|
||||
|
@ -329,77 +437,44 @@ struct Il2CppClass
|
|||
{
|
||||
Il2CppClass_1 _1;
|
||||
void* static_fields;
|
||||
Il2CppRGCTXData* rgctx_data;
|
||||
Il2CppClass_2 _2;
|
||||
VirtualInvokeData vtable[255];
|
||||
};
|
||||
|
||||
";
|
||||
|
||||
public readonly static string HeaderV21 =
|
||||
@"struct Il2CppClass_1
|
||||
typedef int32_t il2cpp_array_size_t;
|
||||
typedef int32_t il2cpp_array_lower_bound_t;
|
||||
struct Il2CppArrayBounds
|
||||
{
|
||||
void* image;
|
||||
void* gc_desc;
|
||||
il2cpp_array_size_t length;
|
||||
il2cpp_array_lower_bound_t lower_bound;
|
||||
};
|
||||
|
||||
struct MethodInfo
|
||||
{
|
||||
Il2CppMethodPointer methodPointer;
|
||||
void* invoker_method;
|
||||
const char* name;
|
||||
const char* namespaze;
|
||||
Il2CppType* byval_arg;
|
||||
Il2CppType* this_arg;
|
||||
Il2CppClass* element_class;
|
||||
Il2CppClass* castClass;
|
||||
Il2CppClass* declaringType;
|
||||
Il2CppClass* parent;
|
||||
void *generic_class;
|
||||
void* typeDefinition;
|
||||
void* fields;
|
||||
void* events;
|
||||
void* properties;
|
||||
void* methods;
|
||||
Il2CppClass** nestedTypes;
|
||||
Il2CppClass** implementedInterfaces;
|
||||
VirtualInvokeData* vtable;
|
||||
void* interfaceOffsets;
|
||||
};
|
||||
|
||||
struct Il2CppClass_2
|
||||
{
|
||||
void* rgctx_data;
|
||||
Il2CppClass** typeHierarchy;
|
||||
uint32_t cctor_started;
|
||||
uint32_t cctor_finished;
|
||||
uint64_t cctor_thread;
|
||||
int32_t genericContainerIndex;
|
||||
Il2CppClass *declaring_type;
|
||||
const Il2CppType *return_type;
|
||||
const void* parameters;
|
||||
union
|
||||
{
|
||||
const Il2CppRGCTXData* rgctx_data;
|
||||
const void* methodDefinition;
|
||||
};
|
||||
union
|
||||
{
|
||||
const void* genericMethod;
|
||||
const void* genericContainer;
|
||||
};
|
||||
int32_t customAttributeIndex;
|
||||
uint32_t instance_size;
|
||||
uint32_t actualSize;
|
||||
uint32_t element_size;
|
||||
int32_t native_size;
|
||||
uint32_t static_fields_size;
|
||||
uint32_t thread_static_fields_size;
|
||||
int32_t thread_static_fields_offset;
|
||||
uint32_t flags;
|
||||
uint32_t token;
|
||||
uint16_t method_count;
|
||||
uint16_t property_count;
|
||||
uint16_t field_count;
|
||||
uint16_t event_count;
|
||||
uint16_t nested_type_count;
|
||||
uint16_t vtable_count;
|
||||
uint16_t interfaces_count;
|
||||
uint16_t interface_offsets_count;
|
||||
uint8_t typeHierarchyDepth;
|
||||
uint8_t rank;
|
||||
uint8_t minimumAlignment;
|
||||
uint8_t packingSize;
|
||||
uint8_t bitflags1;
|
||||
uint8_t bitflags2;
|
||||
};
|
||||
|
||||
struct Il2CppClass
|
||||
{
|
||||
Il2CppClass_1 _1;
|
||||
void* static_fields;
|
||||
Il2CppClass_2 _2;
|
||||
VirtualInvokeData vtable[255];
|
||||
uint16_t flags;
|
||||
uint16_t iflags;
|
||||
uint16_t slot;
|
||||
uint8_t parameters_count;
|
||||
uint8_t bitflags;
|
||||
};
|
||||
|
||||
";
|
||||
|
|
|
@ -25,8 +25,9 @@ namespace Il2CppDumper
|
|||
private List<ulong> genericClassList = new List<ulong>();
|
||||
private StringBuilder arrayClassPreHeader = new StringBuilder();
|
||||
private StringBuilder arrayClassHeader = new StringBuilder();
|
||||
private StringBuilder methodInfoHeader = new StringBuilder();
|
||||
private static HashSet<string> keyword = new HashSet<string>(StringComparer.Ordinal)
|
||||
{ "klass", "monitor", "register", "_cs", "auto", "friend", "template", "near", "far", "flat", "default", "_ds", "interrupt" };
|
||||
{ "klass", "monitor", "register", "_cs", "auto", "friend", "template", "near", "far", "flat", "default", "_ds", "interrupt", "inline", "unsigned", "signed"};
|
||||
|
||||
public ScriptGenerator(Il2CppExecutor il2CppExecutor)
|
||||
{
|
||||
|
@ -71,6 +72,9 @@ namespace Il2CppDumper
|
|||
{
|
||||
var typeDef = metadata.typeDefs[typeIndex];
|
||||
AddStruct(typeDef);
|
||||
var methodInfoName = $"MethodInfo_{typeIndex}";
|
||||
var structTypeName = structNameDic[typeDef];
|
||||
GenerateMethodInfo(structTypeName, methodInfoName);
|
||||
var typeName = executor.GetTypeDefName(typeDef, true, true);
|
||||
var methodEnd = typeDef.methodStart + typeDef.method_count;
|
||||
for (var i = typeDef.methodStart; i < methodEnd; ++i)
|
||||
|
@ -94,11 +98,15 @@ namespace Il2CppDumper
|
|||
}
|
||||
var signature = $"{returnType} {FixName(methodFullName)} (";
|
||||
var parameterStrs = new List<string>();
|
||||
if (il2Cpp.Version <= 22f || (methodDef.flags & METHOD_ATTRIBUTE_STATIC) == 0)
|
||||
if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) == 0)
|
||||
{
|
||||
var thisType = ParseType(il2Cpp.types[typeDef.byrefTypeIndex]);
|
||||
parameterStrs.Add($"{thisType} __this");
|
||||
}
|
||||
else if (il2Cpp.Version <= 24f)
|
||||
{
|
||||
parameterStrs.Add($"Il2CppObject* __this");
|
||||
}
|
||||
for (var j = 0; j < methodDef.parameterCount; j++)
|
||||
{
|
||||
var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j];
|
||||
|
@ -111,6 +119,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
parameterStrs.Add($"{parameterCType} {FixName(parameterName)}");
|
||||
}
|
||||
parameterStrs.Add("const MethodInfo* method");
|
||||
signature += string.Join(", ", parameterStrs);
|
||||
signature += ");";
|
||||
scriptMethod.Signature = signature;
|
||||
|
@ -139,7 +148,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
var signature = $"{returnType} {FixName(methodFullName)} (";
|
||||
var parameterStrs = new List<string>();
|
||||
if (il2Cpp.Version <= 22f || (methodDef.flags & METHOD_ATTRIBUTE_STATIC) == 0)
|
||||
if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) == 0)
|
||||
{
|
||||
string thisType;
|
||||
if (methodSpec.classIndexIndex != -1)
|
||||
|
@ -157,6 +166,10 @@ namespace Il2CppDumper
|
|||
}
|
||||
parameterStrs.Add($"{thisType} __this");
|
||||
}
|
||||
else if (il2Cpp.Version <= 24f)
|
||||
{
|
||||
parameterStrs.Add($"Il2CppObject* __this");
|
||||
}
|
||||
for (var j = 0; j < methodDef.parameterCount; j++)
|
||||
{
|
||||
var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j];
|
||||
|
@ -169,6 +182,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
parameterStrs.Add($"{parameterCType} {FixName(parameterName)}");
|
||||
}
|
||||
parameterStrs.Add($"const {methodInfoName}* method");
|
||||
signature += string.Join(", ", parameterStrs);
|
||||
signature += ");";
|
||||
scriptMethod.Signature = signature;
|
||||
|
@ -332,6 +346,25 @@ namespace Il2CppDumper
|
|||
}
|
||||
else
|
||||
{
|
||||
headerClass.Append($"struct {info.TypeName}_RGCTXs {{\n");
|
||||
for (int i = 0; i < info.RGCTXs.Count; i++)
|
||||
{
|
||||
StructRGCTXInfo rgctx = info.RGCTXs[i];
|
||||
switch (rgctx.Type)
|
||||
{
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_TYPE:
|
||||
headerClass.Append($"\tIl2CppType* _{i}_{rgctx.TypeName};\n");
|
||||
break;
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_CLASS:
|
||||
headerClass.Append($"\tIl2CppClass* _{i}_{rgctx.ClassName};\n");
|
||||
break;
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_METHOD:
|
||||
headerClass.Append($"\tMethodInfo* _{i}_{rgctx.MethodName};\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
headerClass.Append("};\n");
|
||||
|
||||
headerClass.Append($"struct {info.TypeName}_StaticFields {{\n");
|
||||
foreach (var field in info.StaticFields)
|
||||
{
|
||||
|
@ -349,6 +382,7 @@ namespace Il2CppDumper
|
|||
headerClass.Append($"struct {info.TypeName}_c {{\n" +
|
||||
$"\tIl2CppClass_1 _1;\n" +
|
||||
$"\t{info.TypeName}_StaticFields* static_fields;\n" +
|
||||
$"\t{info.TypeName}_RGCTXs* rgctx_data;\n" +
|
||||
$"\tIl2CppClass_2 _2;\n" +
|
||||
$"\t{info.TypeName}_VTable vtable;\n" +
|
||||
$"}};\n");
|
||||
|
@ -395,6 +429,7 @@ namespace Il2CppDumper
|
|||
sb.Append(headerStruct);
|
||||
sb.Append(headerClass);
|
||||
sb.Append(arrayClassHeader);
|
||||
sb.Append(methodInfoHeader);
|
||||
File.WriteAllText("il2cpp.h", sb.ToString());
|
||||
}
|
||||
|
||||
|
@ -554,6 +589,7 @@ namespace Il2CppDumper
|
|||
structInfo.IsValueType = typeDef.IsValueType;
|
||||
AddFields(typeDef, structInfo.Fields, structInfo.StaticFields, null, false);
|
||||
AddVTableMethod(structInfo, typeDef);
|
||||
AddRGCTX(structInfo, typeDef);
|
||||
}
|
||||
|
||||
private void AddGenericClassStruct(ulong pointer)
|
||||
|
@ -655,6 +691,43 @@ namespace Il2CppDumper
|
|||
}
|
||||
}
|
||||
|
||||
private void AddRGCTX(StructInfo structInfo, Il2CppTypeDefinition typeDef)
|
||||
{
|
||||
var imageIndex = typeDefImageIndices[typeDef];
|
||||
var collection = executor.GetTypeRGCTXDefinition(typeDef, imageIndex);
|
||||
if (collection != null)
|
||||
{
|
||||
foreach (var definitionData in collection)
|
||||
{
|
||||
var structRGCTXInfo = new StructRGCTXInfo();
|
||||
structInfo.RGCTXs.Add(structRGCTXInfo);
|
||||
structRGCTXInfo.Type = definitionData.type;
|
||||
switch (definitionData.type)
|
||||
{
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_TYPE:
|
||||
{
|
||||
var il2CppType = il2Cpp.types[definitionData.data.typeIndex];
|
||||
structRGCTXInfo.TypeName = FixName(executor.GetTypeName(il2CppType, true, false));
|
||||
break;
|
||||
}
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_CLASS:
|
||||
{
|
||||
var il2CppType = il2Cpp.types[definitionData.data.typeIndex];
|
||||
structRGCTXInfo.ClassName = FixName(executor.GetTypeName(il2CppType, true, false));
|
||||
break;
|
||||
}
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_METHOD:
|
||||
{
|
||||
var methodSpec = il2Cpp.methodSpecs[definitionData.data.methodIndex];
|
||||
(var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec, true);
|
||||
structRGCTXInfo.MethodName = FixName(methodSpecTypeName + "." + methodSpecMethodName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseArrayClassStruct(Il2CppType il2CppType, Il2CppGenericContext context)
|
||||
{
|
||||
var structName = GetIl2CppStructName(il2CppType, context);
|
||||
|
@ -662,7 +735,7 @@ namespace Il2CppDumper
|
|||
arrayClassHeader.Append($"struct {structName}_array {{\n" +
|
||||
$"\tIl2CppObject obj;\n" +
|
||||
$"\tIl2CppArrayBounds *bounds;\n" +
|
||||
$"\tuintptr_t max_length;\n" +
|
||||
$"\til2cpp_array_size_t max_length;\n" +
|
||||
$"\t{ParseType(il2CppType, context)} m_Items[65535];\n" +
|
||||
$"}};\n");
|
||||
}
|
||||
|
@ -730,6 +803,25 @@ namespace Il2CppDumper
|
|||
}
|
||||
sb.Append("};\n");
|
||||
|
||||
sb.Append($"struct {info.TypeName}_RGCTXs {{\n");
|
||||
for (int i = 0; i < info.RGCTXs.Count; i++)
|
||||
{
|
||||
var rgctx = info.RGCTXs[i];
|
||||
switch (rgctx.Type)
|
||||
{
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_TYPE:
|
||||
sb.Append($"\tIl2CppType* _{i}_{rgctx.TypeName};\n");
|
||||
break;
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_CLASS:
|
||||
sb.Append($"\tIl2CppClass* _{i}_{rgctx.ClassName};\n");
|
||||
break;
|
||||
case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_METHOD:
|
||||
sb.Append($"\tMethodInfo* _{i}_{rgctx.MethodName};\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
sb.Append("};\n");
|
||||
|
||||
sb.Append($"struct {info.TypeName}_StaticFields {{\n");
|
||||
foreach (var field in info.StaticFields)
|
||||
{
|
||||
|
@ -752,6 +844,7 @@ namespace Il2CppDumper
|
|||
sb.Append($"struct {info.TypeName}_c {{\n" +
|
||||
$"\tIl2CppClass_1 _1;\n" +
|
||||
$"\t{info.TypeName}_StaticFields* static_fields;\n" +
|
||||
$"\t{info.TypeName}_RGCTXs* rgctx_data;\n" +
|
||||
$"\tIl2CppClass_2 _2;\n" +
|
||||
$"\t{info.TypeName}_VTable vtable;\n" +
|
||||
$"}};\n");
|
||||
|
@ -900,5 +993,44 @@ namespace Il2CppDumper
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateMethodInfo(string structTypeName, string methodInfoName)
|
||||
{
|
||||
methodInfoHeader.Append($"struct {methodInfoName} {{\n");
|
||||
methodInfoHeader.Append($"\tIl2CppMethodPointer methodPointer;\n");
|
||||
methodInfoHeader.Append($"\tvoid* invoker_method;\n");
|
||||
methodInfoHeader.Append($"\tconst char* name;\n");
|
||||
if (il2Cpp.Version <= 24f)
|
||||
{
|
||||
methodInfoHeader.Append($"\t{structTypeName}_c *declaring_type;\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
methodInfoHeader.Append($"\t{structTypeName}_c *klass;\n");
|
||||
}
|
||||
methodInfoHeader.Append($"\tconst Il2CppType *return_type;\n");
|
||||
methodInfoHeader.Append($"\tconst void* parameters;\n");
|
||||
methodInfoHeader.Append($"\tunion\n");
|
||||
methodInfoHeader.Append($"\t{{\n");
|
||||
methodInfoHeader.Append($"\t\tconst Il2CppRGCTXData* rgctx_data;\n");
|
||||
methodInfoHeader.Append($"\t\tconst void* methodDefinition;\n");
|
||||
methodInfoHeader.Append($"\t}};\n");
|
||||
methodInfoHeader.Append($"\tunion\n");
|
||||
methodInfoHeader.Append($"\t{{\n");
|
||||
methodInfoHeader.Append($"\t\tconst void* genericMethod;\n");
|
||||
methodInfoHeader.Append($"\t\tconst void* genericContainer;\n");
|
||||
methodInfoHeader.Append($"\t}};\n");
|
||||
if (il2Cpp.Version <= 24f)
|
||||
{
|
||||
methodInfoHeader.Append($"\tint32_t customAttributeIndex;\n");
|
||||
}
|
||||
methodInfoHeader.Append($"\tuint32_t token;\n");
|
||||
methodInfoHeader.Append($"\tuint16_t flags;\n");
|
||||
methodInfoHeader.Append($"\tuint16_t iflags;\n");
|
||||
methodInfoHeader.Append($"\tuint16_t slot;\n");
|
||||
methodInfoHeader.Append($"\tuint8_t parameters_count;\n");
|
||||
methodInfoHeader.Append($"\tuint8_t bitflags;\n");
|
||||
methodInfoHeader.Append($"}};\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Il2CppDumper
|
|||
public List<StructFieldInfo> Fields = new List<StructFieldInfo>();
|
||||
public List<StructFieldInfo> StaticFields = new List<StructFieldInfo>();
|
||||
public List<StructVTableMethodInfo> VTableMethod = new List<StructVTableMethodInfo>();
|
||||
public List<StructRGCTXInfo> RGCTXs = new List<StructRGCTXInfo>();
|
||||
}
|
||||
|
||||
public class StructFieldInfo
|
||||
|
@ -26,4 +27,12 @@ namespace Il2CppDumper
|
|||
{
|
||||
public string MethodName;
|
||||
}
|
||||
|
||||
public class StructRGCTXInfo
|
||||
{
|
||||
public Il2CppRGCTXDataType Type;
|
||||
public string TypeName;
|
||||
public string ClassName;
|
||||
public string MethodName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Il2CppDumper
|
||||
{
|
||||
|
@ -211,5 +212,23 @@ namespace Il2CppDumper
|
|||
}
|
||||
return new Il2CppGenericContext { class_inst = classInstPointer, method_inst = methodInstPointer };
|
||||
}
|
||||
|
||||
public Il2CppRGCTXDefinition[] GetTypeRGCTXDefinition(Il2CppTypeDefinition typeDef, int imageIndex)
|
||||
{
|
||||
Il2CppRGCTXDefinition[] collection = null;
|
||||
if (il2Cpp.Version >= 24.2f)
|
||||
{
|
||||
il2Cpp.rgctxsDictionary[imageIndex].TryGetValue(typeDef.token, out collection);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeDef.rgctxCount > 0)
|
||||
{
|
||||
collection = new Il2CppRGCTXDefinition[typeDef.rgctxCount];
|
||||
Array.Copy(metadata.rgctxEntries, typeDef.rgctxStartIndex, collection, 0, typeDef.rgctxCount);
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue