mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-10 03:27:28 -03:00
完善泛型相关输出
This commit is contained in:
parent
bbe3a7cec3
commit
5ab028807c
4 changed files with 97 additions and 35 deletions
|
@ -20,9 +20,11 @@ namespace Il2CppDumper
|
|||
private Dictionary<ulong, Il2CppType> typeDic = new Dictionary<ulong, Il2CppType>();
|
||||
public ulong[] metadataUsages;
|
||||
private Il2CppGenericMethodFunctionsDefinitions[] genericMethodTable;
|
||||
public ulong[] genericInstPointers;
|
||||
public Il2CppGenericInst[] genericInsts;
|
||||
public Il2CppMethodSpec[] methodSpecs;
|
||||
public Dictionary<int, List<(Il2CppMethodSpec, ulong)>> genericMethoddDictionary = new Dictionary<int, List<(Il2CppMethodSpec, ulong)>>();
|
||||
public Dictionary<int, List<Il2CppMethodSpec>> methodDefinitionMethodSpecs = new Dictionary<int, List<Il2CppMethodSpec>>();
|
||||
public Dictionary<Il2CppMethodSpec, ulong> methodSpecGenericMethodPointers = new Dictionary<Il2CppMethodSpec, ulong>();
|
||||
private bool fieldOffsetsArePointers;
|
||||
protected long maxMetadataUsages;
|
||||
private Il2CppCodeGenModule[] codeGenModules;
|
||||
|
@ -94,7 +96,8 @@ namespace Il2CppDumper
|
|||
if (pCodeRegistration.unresolvedVirtualCallCount != 0)
|
||||
unresolvedVirtualCallPointers = MapVATR<ulong>(pCodeRegistration.unresolvedVirtualCallPointers, pCodeRegistration.unresolvedVirtualCallCount);
|
||||
}
|
||||
genericInsts = Array.ConvertAll(MapVATR<ulong>(pMetadataRegistration.genericInsts, pMetadataRegistration.genericInstsCount), x => MapVATR<Il2CppGenericInst>(x));
|
||||
genericInstPointers = MapVATR<ulong>(pMetadataRegistration.genericInsts, pMetadataRegistration.genericInstsCount);
|
||||
genericInsts = Array.ConvertAll(genericInstPointers, MapVATR<Il2CppGenericInst>);
|
||||
fieldOffsetsArePointers = Version > 21;
|
||||
if (Version == 21)
|
||||
{
|
||||
|
@ -147,12 +150,13 @@ namespace Il2CppDumper
|
|||
{
|
||||
var methodSpec = methodSpecs[table.genericMethodIndex];
|
||||
var methodDefinitionIndex = methodSpec.methodDefinitionIndex;
|
||||
if (!genericMethoddDictionary.TryGetValue(methodDefinitionIndex, out var tuple))
|
||||
if (!methodDefinitionMethodSpecs.TryGetValue(methodDefinitionIndex, out var list))
|
||||
{
|
||||
tuple = new List<(Il2CppMethodSpec, ulong)>();
|
||||
genericMethoddDictionary.Add(methodDefinitionIndex, tuple);
|
||||
list = new List<Il2CppMethodSpec>();
|
||||
methodDefinitionMethodSpecs.Add(methodDefinitionIndex, list);
|
||||
}
|
||||
tuple.Add((methodSpec, genericMethodPointers[table.indices.methodIndex]));
|
||||
list.Add(methodSpec);
|
||||
methodSpecGenericMethodPointers.Add(methodSpec, genericMethodPointers[table.indices.methodIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -335,12 +335,13 @@ namespace Il2CppDumper
|
|||
writer.Write(string.Join(", ", parameterStrs));
|
||||
writer.Write(") { }\n");
|
||||
|
||||
if (il2Cpp.genericMethoddDictionary.TryGetValue(i, out var genericMethods))
|
||||
if (il2Cpp.methodDefinitionMethodSpecs.TryGetValue(i, out var methodSpecs))
|
||||
{
|
||||
writer.Write("\t/* GenericInstMethod :\n");
|
||||
foreach ((var methodSpec, var genericMethodPointer) in genericMethods)
|
||||
foreach (var methodSpec in methodSpecs)
|
||||
{
|
||||
writer.Write("\t|\n");
|
||||
var genericMethodPointer = il2Cpp.methodSpecGenericMethodPointers[methodSpec];
|
||||
if (genericMethodPointer > 0)
|
||||
{
|
||||
var fixedPointer = il2Cpp.GetRVA(genericMethodPointer);
|
||||
|
@ -350,7 +351,8 @@ namespace Il2CppDumper
|
|||
{
|
||||
writer.Write("\t|-RVA: -1 Offset: -1\n");
|
||||
}
|
||||
writer.Write($"\t|-{executor.GetMethodSpecMethodName(methodSpec)}\n");
|
||||
(var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec);
|
||||
writer.Write($"\t|-{methodSpecTypeName}.{methodSpecMethodName}\n");
|
||||
}
|
||||
writer.Write("\t*/\n");
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace Il2CppDumper
|
|||
public void WriteScript(Config config)
|
||||
{
|
||||
var json = new ScriptJson();
|
||||
// 生成唯一名称
|
||||
for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
|
||||
{
|
||||
var imageDef = metadata.imageDefs[imageIndex];
|
||||
|
@ -44,9 +45,21 @@ namespace Il2CppDumper
|
|||
for (int typeIndex = imageDef.typeStart; typeIndex < typeEnd; typeIndex++)
|
||||
{
|
||||
var typeDef = metadata.typeDefs[typeIndex];
|
||||
typeDefImageIndices.Add(typeDef, imageIndex);
|
||||
CreateStructNameDic(typeDef);
|
||||
}
|
||||
}
|
||||
// 处理类定义
|
||||
foreach (var typeDef in metadata.typeDefs)
|
||||
{
|
||||
AddStruct(typeDef);
|
||||
}
|
||||
// 处理泛型实例类
|
||||
foreach (var genericClass in il2Cpp.types.Where(x => x.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST))
|
||||
{
|
||||
ParseType(genericClass);
|
||||
}
|
||||
// 处理函数
|
||||
for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
|
||||
{
|
||||
var imageDef = metadata.imageDefs[imageIndex];
|
||||
|
@ -54,9 +67,7 @@ namespace Il2CppDumper
|
|||
for (int typeIndex = imageDef.typeStart; typeIndex < typeEnd; typeIndex++)
|
||||
{
|
||||
var typeDef = metadata.typeDefs[typeIndex];
|
||||
AddStruct(typeDef);
|
||||
var typeName = executor.GetTypeDefName(typeDef, true, true);
|
||||
typeDefImageIndices.Add(typeDef, imageIndex);
|
||||
var methodEnd = typeDef.methodStart + typeDef.method_count;
|
||||
for (var i = typeDef.methodStart; i < methodEnd; ++i)
|
||||
{
|
||||
|
@ -91,9 +102,54 @@ namespace Il2CppDumper
|
|||
signature += ");";
|
||||
scriptMethod.Signature = signature;
|
||||
}
|
||||
//泛型实例函数
|
||||
if (il2Cpp.methodDefinitionMethodSpecs.TryGetValue(i, out var methodSpecs))
|
||||
{
|
||||
foreach (var methodSpec in methodSpecs)
|
||||
{
|
||||
var genericMethodPointer = il2Cpp.methodSpecGenericMethodPointers[methodSpec];
|
||||
if (genericMethodPointer > 0)
|
||||
{
|
||||
var scriptMethod = new ScriptMethod();
|
||||
json.ScriptMethod.Add(scriptMethod);
|
||||
scriptMethod.Address = il2Cpp.GetRVA(genericMethodPointer);
|
||||
(var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec, true);
|
||||
var methodFullName = methodSpecTypeName + "$$" + methodSpecMethodName;
|
||||
scriptMethod.Name = methodFullName;
|
||||
|
||||
var genericContext = executor.GetMethodSpecGenericContext(methodSpec);
|
||||
var methodReturnType = il2Cpp.types[methodDef.returnType];
|
||||
var returnType = ParseType(methodReturnType, genericContext);
|
||||
var signature = $"{returnType} {FixName(methodFullName)} (";
|
||||
var parameterStrs = new List<string>();
|
||||
if (il2Cpp.Version <= 22f || (methodDef.flags & METHOD_ATTRIBUTE_STATIC) == 0)
|
||||
{
|
||||
var thisType = ParseType(il2Cpp.types[typeDef.byrefTypeIndex]);
|
||||
if (methodSpec.classIndexIndex != -1)
|
||||
{
|
||||
var typeToReplaceName = FixName(typeName);
|
||||
var typeReplaceName = FixName(methodSpecTypeName);
|
||||
thisType = thisType.Replace(typeToReplaceName, typeReplaceName);
|
||||
}
|
||||
parameterStrs.Add($"{thisType} __this");
|
||||
}
|
||||
for (var j = 0; j < methodDef.parameterCount; j++)
|
||||
{
|
||||
var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j];
|
||||
var parameterName = metadata.GetStringFromIndex(parameterDef.nameIndex);
|
||||
var parameterType = il2Cpp.types[parameterDef.typeIndex];
|
||||
parameterStrs.Add($"{ParseType(parameterType, genericContext)} {FixName(parameterName)}");
|
||||
}
|
||||
signature += string.Join(", ", parameterStrs);
|
||||
signature += ");";
|
||||
scriptMethod.Signature = signature;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理MetadataUsage
|
||||
if (il2Cpp.Version > 16)
|
||||
{
|
||||
foreach (var i in metadata.metadataUsageDic[1]) //kIl2CppMetadataUsageTypeInfo
|
||||
|
@ -177,30 +233,15 @@ namespace Il2CppDumper
|
|||
foreach (var i in metadata.metadataUsageDic[6]) //kIl2CppMetadataUsageMethodRef
|
||||
{
|
||||
var methodSpec = il2Cpp.methodSpecs[i.Value];
|
||||
var methodDef = metadata.methodDefs[methodSpec.methodDefinitionIndex];
|
||||
var typeDef = metadata.typeDefs[methodDef.declaringType];
|
||||
var typeName = executor.GetTypeDefName(typeDef, true, false);
|
||||
if (methodSpec.classIndexIndex != -1)
|
||||
{
|
||||
var classInst = il2Cpp.genericInsts[methodSpec.classIndexIndex];
|
||||
typeName += executor.GetGenericInstParams(classInst);
|
||||
}
|
||||
var methodName = typeName + "." + metadata.GetStringFromIndex(methodDef.nameIndex);
|
||||
if (methodSpec.methodIndexIndex != -1)
|
||||
{
|
||||
var methodInst = il2Cpp.genericInsts[methodSpec.methodIndexIndex];
|
||||
methodName += executor.GetGenericInstParams(methodInst);
|
||||
}
|
||||
methodName += "()";
|
||||
var scriptMetadataMethod = new ScriptMetadataMethod();
|
||||
json.ScriptMetadataMethod.Add(scriptMetadataMethod);
|
||||
scriptMetadataMethod.Address = il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key]);
|
||||
scriptMetadataMethod.Name = "Method$" + methodName;
|
||||
var imageIndex = typeDefImageIndices[typeDef];
|
||||
var methodPointer = il2Cpp.GetMethodPointer(methodDef, imageIndex);
|
||||
if (methodPointer > 0)
|
||||
(var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec, true);
|
||||
scriptMetadataMethod.Name = "Method$" + methodSpecTypeName + "." + methodSpecMethodName + "()";
|
||||
var genericMethodPointer = il2Cpp.methodSpecGenericMethodPointers[methodSpec];
|
||||
if (genericMethodPointer > 0)
|
||||
{
|
||||
scriptMetadataMethod.MethodAddress = il2Cpp.GetRVA(methodPointer);
|
||||
scriptMetadataMethod.MethodAddress = il2Cpp.GetRVA(genericMethodPointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,23 +178,38 @@ namespace Il2CppDumper
|
|||
return $"<{string.Join(", ", genericParameterNames)}>";
|
||||
}
|
||||
|
||||
public string GetMethodSpecMethodName(Il2CppMethodSpec methodSpec)
|
||||
public (string, string) GetMethodSpecName(Il2CppMethodSpec methodSpec, bool addNamespace = false)
|
||||
{
|
||||
var methodDef = metadata.methodDefs[methodSpec.methodDefinitionIndex];
|
||||
var typeDef = metadata.typeDefs[methodDef.declaringType];
|
||||
var typeName = GetTypeDefName(typeDef, false, false);
|
||||
var typeName = GetTypeDefName(typeDef, addNamespace, false);
|
||||
if (methodSpec.classIndexIndex != -1)
|
||||
{
|
||||
var classInst = il2Cpp.genericInsts[methodSpec.classIndexIndex];
|
||||
typeName += GetGenericInstParams(classInst);
|
||||
}
|
||||
var methodName = typeName + "." + metadata.GetStringFromIndex(methodDef.nameIndex);
|
||||
var methodName = metadata.GetStringFromIndex(methodDef.nameIndex);
|
||||
if (methodSpec.methodIndexIndex != -1)
|
||||
{
|
||||
var methodInst = il2Cpp.genericInsts[methodSpec.methodIndexIndex];
|
||||
methodName += GetGenericInstParams(methodInst);
|
||||
}
|
||||
return methodName;
|
||||
return (typeName, methodName);
|
||||
}
|
||||
|
||||
public Il2CppGenericContext GetMethodSpecGenericContext(Il2CppMethodSpec methodSpec)
|
||||
{
|
||||
var classInstPointer = 0ul;
|
||||
var methodInstPointer = 0ul;
|
||||
if (methodSpec.classIndexIndex != -1)
|
||||
{
|
||||
classInstPointer = il2Cpp.genericInstPointers[methodSpec.classIndexIndex];
|
||||
}
|
||||
if (methodSpec.methodIndexIndex != -1)
|
||||
{
|
||||
methodInstPointer = il2Cpp.genericInstPointers[methodSpec.methodIndexIndex];
|
||||
}
|
||||
return new Il2CppGenericContext { class_inst = classInstPointer, method_inst = methodInstPointer };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue