大幅度提升处理速度

This commit is contained in:
Perfare 2020-02-27 16:23:50 +08:00
parent 805bd90fa2
commit 270ac529a2
7 changed files with 93 additions and 52 deletions

View file

@ -129,7 +129,12 @@ namespace Il2CppDumper
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()

View file

@ -14,10 +14,13 @@ namespace Il2CppDumper
public Il2CppMethodDefinition[] methodDefs;
public Il2CppParameterDefinition[] parameterDefs;
public Il2CppFieldDefinition[] fieldDefs;
private Il2CppFieldDefaultValue[] fieldDefaultValues;
private Il2CppParameterDefaultValue[] parameterDefaultValues;
//private Il2CppFieldDefaultValue[] fieldDefaultValues;
//private Il2CppParameterDefaultValue[] parameterDefaultValues;
private Dictionary<int, Il2CppFieldDefaultValue> fieldDefaultValuesDic;
private Dictionary<int, Il2CppParameterDefaultValue> parameterDefaultValuesDic;
public Il2CppPropertyDefinition[] propertyDefs;
public Il2CppCustomAttributeTypeRange[] attributeTypeRanges;
private Dictionary<Il2CppImageDefinition, Dictionary<uint, int>> attributeTypeRangesDic;
private Il2CppStringLiteral[] stringLiterals;
private Il2CppMetadataUsageList[] metadataUsageLists;
private Il2CppMetadataUsagePair[] metadataUsagePairs;
@ -69,8 +72,10 @@ namespace Il2CppDumper
methodDefs = ReadMetadataClassArray<Il2CppMethodDefinition>(metadataHeader.methodsOffset, metadataHeader.methodsCount);
parameterDefs = ReadMetadataClassArray<Il2CppParameterDefinition>(metadataHeader.parametersOffset, metadataHeader.parametersCount);
fieldDefs = ReadMetadataClassArray<Il2CppFieldDefinition>(metadataHeader.fieldsOffset, metadataHeader.fieldsCount);
fieldDefaultValues = ReadMetadataClassArray<Il2CppFieldDefaultValue>(metadataHeader.fieldDefaultValuesOffset, metadataHeader.fieldDefaultValuesCount);
parameterDefaultValues = ReadMetadataClassArray<Il2CppParameterDefaultValue>(metadataHeader.parameterDefaultValuesOffset, metadataHeader.parameterDefaultValuesCount);
var fieldDefaultValues = ReadMetadataClassArray<Il2CppFieldDefaultValue>(metadataHeader.fieldDefaultValuesOffset, metadataHeader.fieldDefaultValuesCount);
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);
interfaceIndices = ReadClassArray<int>(metadataHeader.interfacesOffset, metadataHeader.interfacesCount / 4);
nestedTypeIndices = ReadClassArray<int>(metadataHeader.nestedTypesOffset, metadataHeader.nestedTypesCount / 4);
@ -94,6 +99,20 @@ namespace Il2CppDumper
attributeTypeRanges = ReadMetadataClassArray<Il2CppCustomAttributeTypeRange>(metadataHeader.attributesInfoOffset, metadataHeader.attributesInfoCount);
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()
@ -101,14 +120,14 @@ namespace Il2CppDumper
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)
@ -130,15 +149,14 @@ namespace Il2CppDumper
{
if (Version > 24)
{
var end = imageDef.customAttributeStart + imageDef.customAttributeCount;
for (int i = imageDef.customAttributeStart; i < end; i++)
if (attributeTypeRangesDic[imageDef].TryGetValue(token, out var index))
{
if (attributeTypeRanges[i].token == token)
{
return i;
}
return index;
}
else
{
return -1;
}
return -1;
}
else
{

View file

@ -66,6 +66,7 @@
<Compile Include="ExecutableFormats\NSOClass.cs" />
<Compile Include="Outputs\ScriptGenerator.cs" />
<Compile Include="Utils\Il2CppExecutor.cs" />
<Compile Include="Utils\ReadCache.cs" />
<Compile Include="Utils\SearchSection.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Attributes\VersionAttribute.cs" />

View file

@ -39,29 +39,13 @@ namespace Il2CppDumper
for (int typeDefIndex = imageDef.typeStart; typeDefIndex < typeEnd; typeDefIndex++)
{
var typeDef = metadata.typeDefs[typeDefIndex];
var isValueType = false;
var isEnum = false;
var extends = new List<string>();
if (typeDef.parentIndex >= 0)
{
var parent = il2Cpp.types[typeDef.parentIndex];
var parentFullName = executor.GetTypeName(parent, true, false);
if (parentFullName == "System.ValueType")
var parentName = executor.GetTypeName(parent, false, false);
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);
}
}
@ -106,13 +90,13 @@ namespace Il2CppDumper
writer.Write("static ");
else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0)
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 ");
if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0)
writer.Write("interface ");
else if (isEnum)
else if (typeDef.IsEnum)
writer.Write("enum ");
else if (isValueType)
else if (typeDef.IsValueType)
writer.Write("struct ");
else
writer.Write("class ");
@ -133,7 +117,6 @@ namespace Il2CppDumper
{
var fieldDef = metadata.fieldDefs[i];
var fieldType = il2Cpp.types[fieldDef.typeIndex];
var fieldDefaultValue = metadata.GetFieldDefaultValueFromIndex(i);
if (config.DumpAttribute)
{
writer.Write(GetCustomAttribute(imageDef, fieldDef.customAttributeIndex, fieldDef.token, "\t"));
@ -171,7 +154,7 @@ namespace Il2CppDumper
writer.Write("readonly ");
}
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))
{
@ -196,7 +179,7 @@ namespace Il2CppDumper
}
}
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
writer.Write(";\n");
}
@ -315,8 +298,7 @@ namespace Il2CppDumper
}
}
parameterStr += $"{parameterTypeName} {parameterName}";
var parameterDefault = metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j);
if (parameterDefault != null && parameterDefault.dataIndex != -1)
if (metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j, out var parameterDefault) && parameterDefault.dataIndex != -1)
{
if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value))
{

View file

@ -128,8 +128,7 @@ namespace Il2CppDumper
typeDefinition.Fields.Add(fieldDefinition);
fieldDefinitionDic.Add(i, fieldDefinition);
//fieldDefault
var fieldDefault = metadata.GetFieldDefaultValueFromIndex(i);
if (fieldDefault != null && fieldDefault.dataIndex != -1)
if (metadata.GetFieldDefaultValueFromIndex(i, out var fieldDefault) && fieldDefault.dataIndex != -1)
{
if (TryGetDefaultValue(fieldDefault.typeIndex, fieldDefault.dataIndex, out var value))
{
@ -199,8 +198,7 @@ namespace Il2CppDumper
methodDefinition.Parameters.Add(parameterDefinition);
parameterDefinitionDic.Add(methodDef.parameterStart + j, parameterDefinition);
//ParameterDefault
var parameterDefault = metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j);
if (parameterDefault != null && parameterDefault.dataIndex != -1)
if (metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j, out var parameterDefault) && parameterDefault.dataIndex != -1)
{
if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value))
{

View file

@ -6,6 +6,7 @@ namespace Il2CppDumper
{
public Metadata metadata;
public Il2Cpp il2Cpp;
private Dictionary<Il2CppGenericInst, string> GenericInstParamsCache = new Dictionary<Il2CppGenericInst, string>();
private static readonly Dictionary<int, string> TypeString = new Dictionary<int, string>
{
{1,"void"},
@ -170,14 +171,19 @@ namespace Il2CppDumper
public string GetGenericInstParams(Il2CppGenericInst genericInst)
{
var typeNames = new List<string>();
var pointers = il2Cpp.MapVATR<ulong>(genericInst.type_argv, genericInst.type_argc);
for (uint i = 0; i < genericInst.type_argc; ++i)
if (!GenericInstParamsCache.TryGetValue(genericInst, out var value))
{
var oriType = il2Cpp.GetIl2CppType(pointers[i]);
typeNames.Add(GetTypeName(oriType, false, false));
var typeNames = new List<string>();
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;
}
}
}

View 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);
}
}
}