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>();
|
private Dictionary<ulong, Il2CppType> typeDic = new Dictionary<ulong, Il2CppType>();
|
||||||
public ulong[] metadataUsages;
|
public ulong[] metadataUsages;
|
||||||
private Il2CppGenericMethodFunctionsDefinitions[] genericMethodTable;
|
private Il2CppGenericMethodFunctionsDefinitions[] genericMethodTable;
|
||||||
|
public ulong[] genericInstPointers;
|
||||||
public Il2CppGenericInst[] genericInsts;
|
public Il2CppGenericInst[] genericInsts;
|
||||||
public Il2CppMethodSpec[] methodSpecs;
|
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;
|
private bool fieldOffsetsArePointers;
|
||||||
protected long maxMetadataUsages;
|
protected long maxMetadataUsages;
|
||||||
private Il2CppCodeGenModule[] codeGenModules;
|
private Il2CppCodeGenModule[] codeGenModules;
|
||||||
|
@ -94,7 +96,8 @@ namespace Il2CppDumper
|
||||||
if (pCodeRegistration.unresolvedVirtualCallCount != 0)
|
if (pCodeRegistration.unresolvedVirtualCallCount != 0)
|
||||||
unresolvedVirtualCallPointers = MapVATR<ulong>(pCodeRegistration.unresolvedVirtualCallPointers, pCodeRegistration.unresolvedVirtualCallCount);
|
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;
|
fieldOffsetsArePointers = Version > 21;
|
||||||
if (Version == 21)
|
if (Version == 21)
|
||||||
{
|
{
|
||||||
|
@ -147,12 +150,13 @@ namespace Il2CppDumper
|
||||||
{
|
{
|
||||||
var methodSpec = methodSpecs[table.genericMethodIndex];
|
var methodSpec = methodSpecs[table.genericMethodIndex];
|
||||||
var methodDefinitionIndex = methodSpec.methodDefinitionIndex;
|
var methodDefinitionIndex = methodSpec.methodDefinitionIndex;
|
||||||
if (!genericMethoddDictionary.TryGetValue(methodDefinitionIndex, out var tuple))
|
if (!methodDefinitionMethodSpecs.TryGetValue(methodDefinitionIndex, out var list))
|
||||||
{
|
{
|
||||||
tuple = new List<(Il2CppMethodSpec, ulong)>();
|
list = new List<Il2CppMethodSpec>();
|
||||||
genericMethoddDictionary.Add(methodDefinitionIndex, tuple);
|
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(string.Join(", ", parameterStrs));
|
||||||
writer.Write(") { }\n");
|
writer.Write(") { }\n");
|
||||||
|
|
||||||
if (il2Cpp.genericMethoddDictionary.TryGetValue(i, out var genericMethods))
|
if (il2Cpp.methodDefinitionMethodSpecs.TryGetValue(i, out var methodSpecs))
|
||||||
{
|
{
|
||||||
writer.Write("\t/* GenericInstMethod :\n");
|
writer.Write("\t/* GenericInstMethod :\n");
|
||||||
foreach ((var methodSpec, var genericMethodPointer) in genericMethods)
|
foreach (var methodSpec in methodSpecs)
|
||||||
{
|
{
|
||||||
writer.Write("\t|\n");
|
writer.Write("\t|\n");
|
||||||
|
var genericMethodPointer = il2Cpp.methodSpecGenericMethodPointers[methodSpec];
|
||||||
if (genericMethodPointer > 0)
|
if (genericMethodPointer > 0)
|
||||||
{
|
{
|
||||||
var fixedPointer = il2Cpp.GetRVA(genericMethodPointer);
|
var fixedPointer = il2Cpp.GetRVA(genericMethodPointer);
|
||||||
|
@ -350,7 +351,8 @@ namespace Il2CppDumper
|
||||||
{
|
{
|
||||||
writer.Write("\t|-RVA: -1 Offset: -1\n");
|
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");
|
writer.Write("\t*/\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace Il2CppDumper
|
||||||
public void WriteScript(Config config)
|
public void WriteScript(Config config)
|
||||||
{
|
{
|
||||||
var json = new ScriptJson();
|
var json = new ScriptJson();
|
||||||
|
// 生成唯一名称
|
||||||
for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
|
for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
|
||||||
{
|
{
|
||||||
var imageDef = metadata.imageDefs[imageIndex];
|
var imageDef = metadata.imageDefs[imageIndex];
|
||||||
|
@ -44,9 +45,21 @@ namespace Il2CppDumper
|
||||||
for (int typeIndex = imageDef.typeStart; typeIndex < typeEnd; typeIndex++)
|
for (int typeIndex = imageDef.typeStart; typeIndex < typeEnd; typeIndex++)
|
||||||
{
|
{
|
||||||
var typeDef = metadata.typeDefs[typeIndex];
|
var typeDef = metadata.typeDefs[typeIndex];
|
||||||
|
typeDefImageIndices.Add(typeDef, imageIndex);
|
||||||
CreateStructNameDic(typeDef);
|
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++)
|
for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
|
||||||
{
|
{
|
||||||
var imageDef = metadata.imageDefs[imageIndex];
|
var imageDef = metadata.imageDefs[imageIndex];
|
||||||
|
@ -54,9 +67,7 @@ namespace Il2CppDumper
|
||||||
for (int typeIndex = imageDef.typeStart; typeIndex < typeEnd; typeIndex++)
|
for (int typeIndex = imageDef.typeStart; typeIndex < typeEnd; typeIndex++)
|
||||||
{
|
{
|
||||||
var typeDef = metadata.typeDefs[typeIndex];
|
var typeDef = metadata.typeDefs[typeIndex];
|
||||||
AddStruct(typeDef);
|
|
||||||
var typeName = executor.GetTypeDefName(typeDef, true, true);
|
var typeName = executor.GetTypeDefName(typeDef, true, true);
|
||||||
typeDefImageIndices.Add(typeDef, imageIndex);
|
|
||||||
var methodEnd = typeDef.methodStart + typeDef.method_count;
|
var methodEnd = typeDef.methodStart + typeDef.method_count;
|
||||||
for (var i = typeDef.methodStart; i < methodEnd; ++i)
|
for (var i = typeDef.methodStart; i < methodEnd; ++i)
|
||||||
{
|
{
|
||||||
|
@ -91,9 +102,54 @@ namespace Il2CppDumper
|
||||||
signature += ");";
|
signature += ");";
|
||||||
scriptMethod.Signature = 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)
|
if (il2Cpp.Version > 16)
|
||||||
{
|
{
|
||||||
foreach (var i in metadata.metadataUsageDic[1]) //kIl2CppMetadataUsageTypeInfo
|
foreach (var i in metadata.metadataUsageDic[1]) //kIl2CppMetadataUsageTypeInfo
|
||||||
|
@ -177,30 +233,15 @@ namespace Il2CppDumper
|
||||||
foreach (var i in metadata.metadataUsageDic[6]) //kIl2CppMetadataUsageMethodRef
|
foreach (var i in metadata.metadataUsageDic[6]) //kIl2CppMetadataUsageMethodRef
|
||||||
{
|
{
|
||||||
var methodSpec = il2Cpp.methodSpecs[i.Value];
|
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();
|
var scriptMetadataMethod = new ScriptMetadataMethod();
|
||||||
json.ScriptMetadataMethod.Add(scriptMetadataMethod);
|
json.ScriptMetadataMethod.Add(scriptMetadataMethod);
|
||||||
scriptMetadataMethod.Address = il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key]);
|
scriptMetadataMethod.Address = il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key]);
|
||||||
scriptMetadataMethod.Name = "Method$" + methodName;
|
(var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec, true);
|
||||||
var imageIndex = typeDefImageIndices[typeDef];
|
scriptMetadataMethod.Name = "Method$" + methodSpecTypeName + "." + methodSpecMethodName + "()";
|
||||||
var methodPointer = il2Cpp.GetMethodPointer(methodDef, imageIndex);
|
var genericMethodPointer = il2Cpp.methodSpecGenericMethodPointers[methodSpec];
|
||||||
if (methodPointer > 0)
|
if (genericMethodPointer > 0)
|
||||||
{
|
{
|
||||||
scriptMetadataMethod.MethodAddress = il2Cpp.GetRVA(methodPointer);
|
scriptMetadataMethod.MethodAddress = il2Cpp.GetRVA(genericMethodPointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,23 +178,38 @@ namespace Il2CppDumper
|
||||||
return $"<{string.Join(", ", genericParameterNames)}>";
|
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 methodDef = metadata.methodDefs[methodSpec.methodDefinitionIndex];
|
||||||
var typeDef = metadata.typeDefs[methodDef.declaringType];
|
var typeDef = metadata.typeDefs[methodDef.declaringType];
|
||||||
var typeName = GetTypeDefName(typeDef, false, false);
|
var typeName = GetTypeDefName(typeDef, addNamespace, false);
|
||||||
if (methodSpec.classIndexIndex != -1)
|
if (methodSpec.classIndexIndex != -1)
|
||||||
{
|
{
|
||||||
var classInst = il2Cpp.genericInsts[methodSpec.classIndexIndex];
|
var classInst = il2Cpp.genericInsts[methodSpec.classIndexIndex];
|
||||||
typeName += GetGenericInstParams(classInst);
|
typeName += GetGenericInstParams(classInst);
|
||||||
}
|
}
|
||||||
var methodName = typeName + "." + metadata.GetStringFromIndex(methodDef.nameIndex);
|
var methodName = metadata.GetStringFromIndex(methodDef.nameIndex);
|
||||||
if (methodSpec.methodIndexIndex != -1)
|
if (methodSpec.methodIndexIndex != -1)
|
||||||
{
|
{
|
||||||
var methodInst = il2Cpp.genericInsts[methodSpec.methodIndexIndex];
|
var methodInst = il2Cpp.genericInsts[methodSpec.methodIndexIndex];
|
||||||
methodName += GetGenericInstParams(methodInst);
|
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