mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-27 03:03:00 -03:00
大幅度提升处理速度
This commit is contained in:
parent
805bd90fa2
commit
270ac529a2
7 changed files with 93 additions and 52 deletions
|
@ -129,7 +129,12 @@ namespace Il2CppDumper
|
||||||
|
|
||||||
public T MapVATR<T>(ulong addr) where T : new()
|
public T MapVATR<T>(ulong addr) where T : new()
|
||||||
{
|
{
|
||||||
return ReadClass<T>(MapVATR(addr));
|
if (!ReadClassCache<T>.TryGetValue(addr, out var value))
|
||||||
|
{
|
||||||
|
value = ReadClass<T>(MapVATR(addr));
|
||||||
|
ReadClassCache<T>.Add(addr, value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T[] MapVATR<T>(ulong addr, long count) where T : new()
|
public T[] MapVATR<T>(ulong addr, long count) where T : new()
|
||||||
|
|
|
@ -14,10 +14,13 @@ namespace Il2CppDumper
|
||||||
public Il2CppMethodDefinition[] methodDefs;
|
public Il2CppMethodDefinition[] methodDefs;
|
||||||
public Il2CppParameterDefinition[] parameterDefs;
|
public Il2CppParameterDefinition[] parameterDefs;
|
||||||
public Il2CppFieldDefinition[] fieldDefs;
|
public Il2CppFieldDefinition[] fieldDefs;
|
||||||
private Il2CppFieldDefaultValue[] fieldDefaultValues;
|
//private Il2CppFieldDefaultValue[] fieldDefaultValues;
|
||||||
private Il2CppParameterDefaultValue[] parameterDefaultValues;
|
//private Il2CppParameterDefaultValue[] parameterDefaultValues;
|
||||||
|
private Dictionary<int, Il2CppFieldDefaultValue> fieldDefaultValuesDic;
|
||||||
|
private Dictionary<int, Il2CppParameterDefaultValue> parameterDefaultValuesDic;
|
||||||
public Il2CppPropertyDefinition[] propertyDefs;
|
public Il2CppPropertyDefinition[] propertyDefs;
|
||||||
public Il2CppCustomAttributeTypeRange[] attributeTypeRanges;
|
public Il2CppCustomAttributeTypeRange[] attributeTypeRanges;
|
||||||
|
private Dictionary<Il2CppImageDefinition, Dictionary<uint, int>> attributeTypeRangesDic;
|
||||||
private Il2CppStringLiteral[] stringLiterals;
|
private Il2CppStringLiteral[] stringLiterals;
|
||||||
private Il2CppMetadataUsageList[] metadataUsageLists;
|
private Il2CppMetadataUsageList[] metadataUsageLists;
|
||||||
private Il2CppMetadataUsagePair[] metadataUsagePairs;
|
private Il2CppMetadataUsagePair[] metadataUsagePairs;
|
||||||
|
@ -69,8 +72,10 @@ namespace Il2CppDumper
|
||||||
methodDefs = ReadMetadataClassArray<Il2CppMethodDefinition>(metadataHeader.methodsOffset, metadataHeader.methodsCount);
|
methodDefs = ReadMetadataClassArray<Il2CppMethodDefinition>(metadataHeader.methodsOffset, metadataHeader.methodsCount);
|
||||||
parameterDefs = ReadMetadataClassArray<Il2CppParameterDefinition>(metadataHeader.parametersOffset, metadataHeader.parametersCount);
|
parameterDefs = ReadMetadataClassArray<Il2CppParameterDefinition>(metadataHeader.parametersOffset, metadataHeader.parametersCount);
|
||||||
fieldDefs = ReadMetadataClassArray<Il2CppFieldDefinition>(metadataHeader.fieldsOffset, metadataHeader.fieldsCount);
|
fieldDefs = ReadMetadataClassArray<Il2CppFieldDefinition>(metadataHeader.fieldsOffset, metadataHeader.fieldsCount);
|
||||||
fieldDefaultValues = ReadMetadataClassArray<Il2CppFieldDefaultValue>(metadataHeader.fieldDefaultValuesOffset, metadataHeader.fieldDefaultValuesCount);
|
var fieldDefaultValues = ReadMetadataClassArray<Il2CppFieldDefaultValue>(metadataHeader.fieldDefaultValuesOffset, metadataHeader.fieldDefaultValuesCount);
|
||||||
parameterDefaultValues = ReadMetadataClassArray<Il2CppParameterDefaultValue>(metadataHeader.parameterDefaultValuesOffset, metadataHeader.parameterDefaultValuesCount);
|
var parameterDefaultValues = ReadMetadataClassArray<Il2CppParameterDefaultValue>(metadataHeader.parameterDefaultValuesOffset, metadataHeader.parameterDefaultValuesCount);
|
||||||
|
fieldDefaultValuesDic = fieldDefaultValues.ToDictionary(x => x.fieldIndex);
|
||||||
|
parameterDefaultValuesDic = parameterDefaultValues.ToDictionary(x => x.parameterIndex);
|
||||||
propertyDefs = ReadMetadataClassArray<Il2CppPropertyDefinition>(metadataHeader.propertiesOffset, metadataHeader.propertiesCount);
|
propertyDefs = ReadMetadataClassArray<Il2CppPropertyDefinition>(metadataHeader.propertiesOffset, metadataHeader.propertiesCount);
|
||||||
interfaceIndices = ReadClassArray<int>(metadataHeader.interfacesOffset, metadataHeader.interfacesCount / 4);
|
interfaceIndices = ReadClassArray<int>(metadataHeader.interfacesOffset, metadataHeader.interfacesCount / 4);
|
||||||
nestedTypeIndices = ReadClassArray<int>(metadataHeader.nestedTypesOffset, metadataHeader.nestedTypesCount / 4);
|
nestedTypeIndices = ReadClassArray<int>(metadataHeader.nestedTypesOffset, metadataHeader.nestedTypesCount / 4);
|
||||||
|
@ -94,6 +99,20 @@ namespace Il2CppDumper
|
||||||
attributeTypeRanges = ReadMetadataClassArray<Il2CppCustomAttributeTypeRange>(metadataHeader.attributesInfoOffset, metadataHeader.attributesInfoCount);
|
attributeTypeRanges = ReadMetadataClassArray<Il2CppCustomAttributeTypeRange>(metadataHeader.attributesInfoOffset, metadataHeader.attributesInfoCount);
|
||||||
attributeTypes = ReadClassArray<int>(metadataHeader.attributeTypesOffset, metadataHeader.attributeTypesCount / 4);
|
attributeTypes = ReadClassArray<int>(metadataHeader.attributeTypesOffset, metadataHeader.attributeTypesCount / 4);
|
||||||
}
|
}
|
||||||
|
if (Version > 24)
|
||||||
|
{
|
||||||
|
attributeTypeRangesDic = new Dictionary<Il2CppImageDefinition, Dictionary<uint, int>>();
|
||||||
|
foreach (var imageDef in imageDefs)
|
||||||
|
{
|
||||||
|
var dic = new Dictionary<uint, int>();
|
||||||
|
attributeTypeRangesDic[imageDef] = dic;
|
||||||
|
var end = imageDef.customAttributeStart + imageDef.customAttributeCount;
|
||||||
|
for (int i = imageDef.customAttributeStart; i < end; i++)
|
||||||
|
{
|
||||||
|
dic.Add(attributeTypeRanges[i].token, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private T[] ReadMetadataClassArray<T>(uint addr, int count) where T : new()
|
private T[] ReadMetadataClassArray<T>(uint addr, int count) where T : new()
|
||||||
|
@ -101,14 +120,14 @@ namespace Il2CppDumper
|
||||||
return ReadClassArray<T>(addr, count / MySizeOf(typeof(T)));
|
return ReadClassArray<T>(addr, count / MySizeOf(typeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Il2CppFieldDefaultValue GetFieldDefaultValueFromIndex(int index)
|
public bool GetFieldDefaultValueFromIndex(int index, out Il2CppFieldDefaultValue value)
|
||||||
{
|
{
|
||||||
return fieldDefaultValues.FirstOrDefault(x => x.fieldIndex == index);
|
return fieldDefaultValuesDic.TryGetValue(index, out value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Il2CppParameterDefaultValue GetParameterDefaultValueFromIndex(int index)
|
public bool GetParameterDefaultValueFromIndex(int index, out Il2CppParameterDefaultValue value)
|
||||||
{
|
{
|
||||||
return parameterDefaultValues.FirstOrDefault(x => x.parameterIndex == index);
|
return parameterDefaultValuesDic.TryGetValue(index, out value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetDefaultValueFromIndex(int index)
|
public uint GetDefaultValueFromIndex(int index)
|
||||||
|
@ -130,15 +149,14 @@ namespace Il2CppDumper
|
||||||
{
|
{
|
||||||
if (Version > 24)
|
if (Version > 24)
|
||||||
{
|
{
|
||||||
var end = imageDef.customAttributeStart + imageDef.customAttributeCount;
|
if (attributeTypeRangesDic[imageDef].TryGetValue(token, out var index))
|
||||||
for (int i = imageDef.customAttributeStart; i < end; i++)
|
|
||||||
{
|
{
|
||||||
if (attributeTypeRanges[i].token == token)
|
return index;
|
||||||
{
|
}
|
||||||
return i;
|
else
|
||||||
}
|
{
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
<Compile Include="ExecutableFormats\NSOClass.cs" />
|
<Compile Include="ExecutableFormats\NSOClass.cs" />
|
||||||
<Compile Include="Outputs\ScriptGenerator.cs" />
|
<Compile Include="Outputs\ScriptGenerator.cs" />
|
||||||
<Compile Include="Utils\Il2CppExecutor.cs" />
|
<Compile Include="Utils\Il2CppExecutor.cs" />
|
||||||
|
<Compile Include="Utils\ReadCache.cs" />
|
||||||
<Compile Include="Utils\SearchSection.cs" />
|
<Compile Include="Utils\SearchSection.cs" />
|
||||||
<Compile Include="Extensions\StringExtensions.cs" />
|
<Compile Include="Extensions\StringExtensions.cs" />
|
||||||
<Compile Include="Attributes\VersionAttribute.cs" />
|
<Compile Include="Attributes\VersionAttribute.cs" />
|
||||||
|
|
|
@ -39,29 +39,13 @@ namespace Il2CppDumper
|
||||||
for (int typeDefIndex = imageDef.typeStart; typeDefIndex < typeEnd; typeDefIndex++)
|
for (int typeDefIndex = imageDef.typeStart; typeDefIndex < typeEnd; typeDefIndex++)
|
||||||
{
|
{
|
||||||
var typeDef = metadata.typeDefs[typeDefIndex];
|
var typeDef = metadata.typeDefs[typeDefIndex];
|
||||||
var isValueType = false;
|
|
||||||
var isEnum = false;
|
|
||||||
var extends = new List<string>();
|
var extends = new List<string>();
|
||||||
if (typeDef.parentIndex >= 0)
|
if (typeDef.parentIndex >= 0)
|
||||||
{
|
{
|
||||||
var parent = il2Cpp.types[typeDef.parentIndex];
|
var parent = il2Cpp.types[typeDef.parentIndex];
|
||||||
var parentFullName = executor.GetTypeName(parent, true, false);
|
var parentName = executor.GetTypeName(parent, false, false);
|
||||||
if (parentFullName == "System.ValueType")
|
if (!typeDef.IsValueType && !typeDef.IsEnum && parentName != "object")
|
||||||
{
|
{
|
||||||
var typeFullName = executor.GetTypeDefName(typeDef, true, true);
|
|
||||||
if (typeFullName != "System.Enum")
|
|
||||||
{
|
|
||||||
isValueType = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (parentFullName == "System.Enum")
|
|
||||||
{
|
|
||||||
isValueType = true;
|
|
||||||
isEnum = true;
|
|
||||||
}
|
|
||||||
else if (parentFullName != "object")
|
|
||||||
{
|
|
||||||
var parentName = executor.GetTypeName(parent, false, false);
|
|
||||||
extends.Add(parentName);
|
extends.Add(parentName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,13 +90,13 @@ namespace Il2CppDumper
|
||||||
writer.Write("static ");
|
writer.Write("static ");
|
||||||
else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0)
|
else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0)
|
||||||
writer.Write("abstract ");
|
writer.Write("abstract ");
|
||||||
else if (!isValueType && !isEnum && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
|
else if (!typeDef.IsValueType && !typeDef.IsEnum && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
|
||||||
writer.Write("sealed ");
|
writer.Write("sealed ");
|
||||||
if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0)
|
if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0)
|
||||||
writer.Write("interface ");
|
writer.Write("interface ");
|
||||||
else if (isEnum)
|
else if (typeDef.IsEnum)
|
||||||
writer.Write("enum ");
|
writer.Write("enum ");
|
||||||
else if (isValueType)
|
else if (typeDef.IsValueType)
|
||||||
writer.Write("struct ");
|
writer.Write("struct ");
|
||||||
else
|
else
|
||||||
writer.Write("class ");
|
writer.Write("class ");
|
||||||
|
@ -133,7 +117,6 @@ namespace Il2CppDumper
|
||||||
{
|
{
|
||||||
var fieldDef = metadata.fieldDefs[i];
|
var fieldDef = metadata.fieldDefs[i];
|
||||||
var fieldType = il2Cpp.types[fieldDef.typeIndex];
|
var fieldType = il2Cpp.types[fieldDef.typeIndex];
|
||||||
var fieldDefaultValue = metadata.GetFieldDefaultValueFromIndex(i);
|
|
||||||
if (config.DumpAttribute)
|
if (config.DumpAttribute)
|
||||||
{
|
{
|
||||||
writer.Write(GetCustomAttribute(imageDef, fieldDef.customAttributeIndex, fieldDef.token, "\t"));
|
writer.Write(GetCustomAttribute(imageDef, fieldDef.customAttributeIndex, fieldDef.token, "\t"));
|
||||||
|
@ -171,7 +154,7 @@ namespace Il2CppDumper
|
||||||
writer.Write("readonly ");
|
writer.Write("readonly ");
|
||||||
}
|
}
|
||||||
writer.Write($"{executor.GetTypeName(fieldType, false, false)} {metadata.GetStringFromIndex(fieldDef.nameIndex)}");
|
writer.Write($"{executor.GetTypeName(fieldType, false, false)} {metadata.GetStringFromIndex(fieldDef.nameIndex)}");
|
||||||
if (fieldDefaultValue != null && fieldDefaultValue.dataIndex != -1)
|
if (metadata.GetFieldDefaultValueFromIndex(i, out var fieldDefaultValue) && fieldDefaultValue.dataIndex != -1)
|
||||||
{
|
{
|
||||||
if (TryGetDefaultValue(fieldDefaultValue.typeIndex, fieldDefaultValue.dataIndex, out var value))
|
if (TryGetDefaultValue(fieldDefaultValue.typeIndex, fieldDefaultValue.dataIndex, out var value))
|
||||||
{
|
{
|
||||||
|
@ -196,7 +179,7 @@ namespace Il2CppDumper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (config.DumpFieldOffset)
|
if (config.DumpFieldOffset)
|
||||||
writer.Write("; // 0x{0:X}\n", il2Cpp.GetFieldOffsetFromIndex(typeDefIndex, i - typeDef.fieldStart, i, isValueType));
|
writer.Write("; // 0x{0:X}\n", il2Cpp.GetFieldOffsetFromIndex(typeDefIndex, i - typeDef.fieldStart, i, typeDef.IsValueType));
|
||||||
else
|
else
|
||||||
writer.Write(";\n");
|
writer.Write(";\n");
|
||||||
}
|
}
|
||||||
|
@ -315,8 +298,7 @@ namespace Il2CppDumper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parameterStr += $"{parameterTypeName} {parameterName}";
|
parameterStr += $"{parameterTypeName} {parameterName}";
|
||||||
var parameterDefault = metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j);
|
if (metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j, out var parameterDefault) && parameterDefault.dataIndex != -1)
|
||||||
if (parameterDefault != null && parameterDefault.dataIndex != -1)
|
|
||||||
{
|
{
|
||||||
if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value))
|
if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value))
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,8 +128,7 @@ namespace Il2CppDumper
|
||||||
typeDefinition.Fields.Add(fieldDefinition);
|
typeDefinition.Fields.Add(fieldDefinition);
|
||||||
fieldDefinitionDic.Add(i, fieldDefinition);
|
fieldDefinitionDic.Add(i, fieldDefinition);
|
||||||
//fieldDefault
|
//fieldDefault
|
||||||
var fieldDefault = metadata.GetFieldDefaultValueFromIndex(i);
|
if (metadata.GetFieldDefaultValueFromIndex(i, out var fieldDefault) && fieldDefault.dataIndex != -1)
|
||||||
if (fieldDefault != null && fieldDefault.dataIndex != -1)
|
|
||||||
{
|
{
|
||||||
if (TryGetDefaultValue(fieldDefault.typeIndex, fieldDefault.dataIndex, out var value))
|
if (TryGetDefaultValue(fieldDefault.typeIndex, fieldDefault.dataIndex, out var value))
|
||||||
{
|
{
|
||||||
|
@ -199,8 +198,7 @@ namespace Il2CppDumper
|
||||||
methodDefinition.Parameters.Add(parameterDefinition);
|
methodDefinition.Parameters.Add(parameterDefinition);
|
||||||
parameterDefinitionDic.Add(methodDef.parameterStart + j, parameterDefinition);
|
parameterDefinitionDic.Add(methodDef.parameterStart + j, parameterDefinition);
|
||||||
//ParameterDefault
|
//ParameterDefault
|
||||||
var parameterDefault = metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j);
|
if (metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j, out var parameterDefault) && parameterDefault.dataIndex != -1)
|
||||||
if (parameterDefault != null && parameterDefault.dataIndex != -1)
|
|
||||||
{
|
{
|
||||||
if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value))
|
if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value))
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace Il2CppDumper
|
||||||
{
|
{
|
||||||
public Metadata metadata;
|
public Metadata metadata;
|
||||||
public Il2Cpp il2Cpp;
|
public Il2Cpp il2Cpp;
|
||||||
|
private Dictionary<Il2CppGenericInst, string> GenericInstParamsCache = new Dictionary<Il2CppGenericInst, string>();
|
||||||
private static readonly Dictionary<int, string> TypeString = new Dictionary<int, string>
|
private static readonly Dictionary<int, string> TypeString = new Dictionary<int, string>
|
||||||
{
|
{
|
||||||
{1,"void"},
|
{1,"void"},
|
||||||
|
@ -170,14 +171,19 @@ namespace Il2CppDumper
|
||||||
|
|
||||||
public string GetGenericInstParams(Il2CppGenericInst genericInst)
|
public string GetGenericInstParams(Il2CppGenericInst genericInst)
|
||||||
{
|
{
|
||||||
var typeNames = new List<string>();
|
if (!GenericInstParamsCache.TryGetValue(genericInst, out var value))
|
||||||
var pointers = il2Cpp.MapVATR<ulong>(genericInst.type_argv, genericInst.type_argc);
|
|
||||||
for (uint i = 0; i < genericInst.type_argc; ++i)
|
|
||||||
{
|
{
|
||||||
var oriType = il2Cpp.GetIl2CppType(pointers[i]);
|
var typeNames = new List<string>();
|
||||||
typeNames.Add(GetTypeName(oriType, false, false));
|
var pointers = il2Cpp.MapVATR<ulong>(genericInst.type_argv, genericInst.type_argc);
|
||||||
|
for (uint i = 0; i < genericInst.type_argc; ++i)
|
||||||
|
{
|
||||||
|
var oriType = il2Cpp.GetIl2CppType(pointers[i]);
|
||||||
|
typeNames.Add(GetTypeName(oriType, false, false));
|
||||||
|
}
|
||||||
|
value = $"<{string.Join(", ", typeNames)}>";
|
||||||
|
GenericInstParamsCache.Add(genericInst, value);
|
||||||
}
|
}
|
||||||
return $"<{string.Join(", ", typeNames)}>";
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
31
Il2CppDumper/Utils/ReadCache.cs
Normal file
31
Il2CppDumper/Utils/ReadCache.cs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Il2CppDumper
|
||||||
|
{
|
||||||
|
internal static class ReadClassCache<T>
|
||||||
|
{
|
||||||
|
private static Dictionary<ulong, T> CacheInstance;
|
||||||
|
|
||||||
|
public static void Add(ulong key, T value)
|
||||||
|
{
|
||||||
|
if (CacheInstance == null)
|
||||||
|
{
|
||||||
|
CacheInstance = new Dictionary<ulong, T>();
|
||||||
|
}
|
||||||
|
CacheInstance.Add(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetValue(ulong key, out T value)
|
||||||
|
{
|
||||||
|
if (CacheInstance == null)
|
||||||
|
{
|
||||||
|
CacheInstance = new Dictionary<ulong, T>();
|
||||||
|
}
|
||||||
|
return CacheInstance.TryGetValue(key, out value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue