添加字符串缓存

细节修改
This commit is contained in:
Perfare 2020-02-06 17:02:06 +08:00
parent af32015973
commit 8a1e42e726
8 changed files with 91 additions and 74 deletions

View file

@ -99,25 +99,4 @@ namespace Il2CppDumper
public static readonly Version Unity20183 = new Version(2018, 3); public static readonly Version Unity20183 = new Version(2018, 3);
public static readonly Version Unity20191 = new Version(2019, 1); public static readonly Version Unity20191 = new Version(2019, 1);
} }
static class ElfConstants
{
public const int DT_PLTGOT = 3;
public const int DT_STRTAB = 5;
public const int DT_SYMTAB = 6;
public const int DT_RELA = 7;
public const int DT_RELASZ = 8;
public const int DT_INIT = 12;
public const int DT_REL = 17;
public const int DT_RELSZ = 18;
public const int DT_INIT_ARRAY = 25;
public const int DT_INIT_ARRAYSZ = 27;
public const int R_ARM_ABS32 = 2;
public const int R_386_32 = 1;
public const int R_AARCH64_ABS64 = 257;
public const int R_AARCH64_RELATIVE = 1027;
}
} }

View file

@ -516,33 +516,7 @@ namespace Il2CppDumper
private void PrepareCustomAttribute() private void PrepareCustomAttribute()
{ {
var attributeNames = new[] foreach (var attributeName in knownAttributeNames)
{
//"System.Runtime.CompilerServices.CompilerGeneratedAttribute",
"System.Runtime.CompilerServices.ExtensionAttribute",
"System.Runtime.CompilerServices.NullableAttribute",
"System.Runtime.CompilerServices.NullableContextAttribute",
"System.Runtime.CompilerServices.IsReadOnlyAttribute", //in关键字
"System.Diagnostics.DebuggerHiddenAttribute",
"System.Diagnostics.DebuggerStepThroughAttribute",
// Type attributes:
"System.FlagsAttribute",
"System.Runtime.CompilerServices.IsByRefLikeAttribute",
// Field attributes:
"System.NonSerializedAttribute",
// Method attributes:
"System.Runtime.InteropServices.PreserveSigAttribute",
// Parameter attributes:
"System.ParamArrayAttribute",
"System.Runtime.CompilerServices.CallerMemberNameAttribute",
"System.Runtime.CompilerServices.CallerFilePathAttribute",
"System.Runtime.CompilerServices.CallerLineNumberAttribute",
// Type parameter attributes:
"System.Runtime.CompilerServices.IsUnmanagedAttribute",
// Unity
"UnityEngine.SerializeField" //MonoBehaviour的反序列化
};
foreach (var attributeName in attributeNames)
{ {
foreach (var assemblyDefinition in Assemblies) foreach (var assemblyDefinition in Assemblies)
{ {
@ -604,5 +578,32 @@ namespace Il2CppDumper
} }
return genericParameter; return genericParameter;
} }
private static readonly string[] knownAttributeNames = new[]
{
//"System.Runtime.CompilerServices.CompilerGeneratedAttribute",
"System.Runtime.CompilerServices.ExtensionAttribute",
"System.Runtime.CompilerServices.NullableAttribute",
"System.Runtime.CompilerServices.NullableContextAttribute",
"System.Runtime.CompilerServices.IsReadOnlyAttribute", //in关键字
"System.Diagnostics.DebuggerHiddenAttribute",
"System.Diagnostics.DebuggerStepThroughAttribute",
// Type attributes:
"System.FlagsAttribute",
"System.Runtime.CompilerServices.IsByRefLikeAttribute",
// Field attributes:
"System.NonSerializedAttribute",
// Method attributes:
"System.Runtime.InteropServices.PreserveSigAttribute",
// Parameter attributes:
"System.ParamArrayAttribute",
"System.Runtime.CompilerServices.CallerMemberNameAttribute",
"System.Runtime.CompilerServices.CallerFilePathAttribute",
"System.Runtime.CompilerServices.CallerLineNumberAttribute",
// Type parameter attributes:
"System.Runtime.CompilerServices.IsUnmanagedAttribute",
// Unity
"UnityEngine.SerializeField" //MonoBehaviour的反序列化
};
} }
} }

View file

@ -0,0 +1,23 @@
namespace Il2CppDumper
{
static class ElfConstants
{
public const int DT_PLTGOT = 3;
public const int DT_STRTAB = 5;
public const int DT_SYMTAB = 6;
public const int DT_RELA = 7;
public const int DT_RELASZ = 8;
public const int DT_INIT = 12;
public const int DT_REL = 17;
public const int DT_RELSZ = 18;
public const int DT_INIT_ARRAY = 25;
public const int DT_INIT_ARRAYSZ = 27;
public const int R_ARM_ABS32 = 2;
public const int R_386_32 = 1;
public const int R_AARCH64_ABS64 = 257;
public const int R_AARCH64_RELATIVE = 1027;
}
}

View file

@ -11,15 +11,17 @@ namespace Il2CppDumper
{ {
private Metadata metadata; private Metadata metadata;
private Il2Cpp il2Cpp; private Il2Cpp il2Cpp;
private StreamWriter writer;
private Dictionary<Il2CppMethodDefinition, string> methodModifiers = new Dictionary<Il2CppMethodDefinition, string>(); private Dictionary<Il2CppMethodDefinition, string> methodModifiers = new Dictionary<Il2CppMethodDefinition, string>();
public Il2CppDecompiler(Metadata metadata, Il2Cpp il2Cpp) public Il2CppDecompiler(Metadata metadata, Il2Cpp il2Cpp)
{ {
writer = new StreamWriter(new FileStream("dump.cs", FileMode.Create), new UTF8Encoding(false));
this.metadata = metadata; this.metadata = metadata;
this.il2Cpp = il2Cpp; this.il2Cpp = il2Cpp;
} }
public void Decompile(StreamWriter writer, Config config) public void Decompile(Config config)
{ {
//dump image //dump image
for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++) for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
@ -399,12 +401,12 @@ namespace Il2CppDumper
public string GetTypeDefName(Il2CppTypeDefinition typeDef) public string GetTypeDefName(Il2CppTypeDefinition typeDef)
{ {
var ret = string.Empty; var prefix = string.Empty;
if (typeDef.declaringTypeIndex != -1) if (typeDef.declaringTypeIndex != -1)
{ {
ret += GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex]) + "."; prefix = GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex]) + ".";
} }
ret += metadata.GetStringFromIndex(typeDef.nameIndex); var typeName = metadata.GetStringFromIndex(typeDef.nameIndex);
var names = new List<string>(); var names = new List<string>();
if (typeDef.genericContainerIndex >= 0) if (typeDef.genericContainerIndex >= 0)
{ {
@ -415,10 +417,10 @@ namespace Il2CppDumper
var param = metadata.genericParameters[genericParameterIndex]; var param = metadata.genericParameters[genericParameterIndex];
names.Add(metadata.GetStringFromIndex(param.nameIndex)); names.Add(metadata.GetStringFromIndex(param.nameIndex));
} }
ret = ret.Replace($"`{genericContainer.type_argc}", ""); typeName = typeName.Replace($"`{genericContainer.type_argc}", "");
ret += $"<{string.Join(", ", names)}>"; typeName += $"<{string.Join(", ", names)}>";
} }
return ret; return prefix + typeName;
} }
public string GetGenericTypeParams(Il2CppGenericInst genericInst) public string GetGenericTypeParams(Il2CppGenericInst genericInst)

View file

@ -49,6 +49,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="BoyerMooreHorspool.cs" /> <Compile Include="BoyerMooreHorspool.cs" />
<Compile Include="ElfConstants.cs" />
<Compile Include="Il2CppDecompiler.cs" /> <Compile Include="Il2CppDecompiler.cs" />
<Compile Include="Il2CppDummyDll.cs" /> <Compile Include="Il2CppDummyDll.cs" />
<Compile Include="Lz4DecoderStream.cs" /> <Compile Include="Lz4DecoderStream.cs" />

View file

@ -31,6 +31,7 @@ namespace Il2CppDumper
public Il2CppFieldRef[] fieldRefs; public Il2CppFieldRef[] fieldRefs;
public Il2CppGenericParameter[] genericParameters; public Il2CppGenericParameter[] genericParameters;
public int[] constraintIndices; public int[] constraintIndices;
private Dictionary<uint, string> stringCache = new Dictionary<uint, string>();
public Metadata(Stream stream, float version) : base(stream) public Metadata(Stream stream, float version) : base(stream)
{ {
@ -106,7 +107,13 @@ namespace Il2CppDumper
public string GetStringFromIndex(uint index) public string GetStringFromIndex(uint index)
{ {
return ReadStringToNull(metadataHeader.stringOffset + index); if (!stringCache.TryGetValue(index, out var result))
{
var str = ReadStringToNull(metadataHeader.stringOffset + index);
stringCache.Add(index, str);
return str;
}
return result;
} }
public int GetCustomAttributeIndex(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token) public int GetCustomAttributeIndex(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token)

View file

@ -266,14 +266,12 @@ namespace Il2CppDumper
private static void Dump(Metadata metadata, Il2Cpp il2Cpp) private static void Dump(Metadata metadata, Il2Cpp il2Cpp)
{ {
Console.WriteLine("Dumping..."); Console.WriteLine("Dumping...");
var writer = new StreamWriter(new FileStream("dump.cs", FileMode.Create), new UTF8Encoding(false));
var decompiler = new Il2CppDecompiler(metadata, il2Cpp); var decompiler = new Il2CppDecompiler(metadata, il2Cpp);
decompiler.Decompile(writer, config); decompiler.Decompile(config);
Console.WriteLine("Done!"); Console.WriteLine("Done!");
Console.WriteLine("Generate script..."); Console.WriteLine("Generate script...");
var scriptwriter = new StreamWriter(new FileStream("script.py", FileMode.Create), new UTF8Encoding(false));
var scriptGenerator = new ScriptGenerator(metadata, il2Cpp); var scriptGenerator = new ScriptGenerator(metadata, il2Cpp);
scriptGenerator.WriteScript(scriptwriter, config); scriptGenerator.WriteScript(config);
Console.WriteLine("Done!"); Console.WriteLine("Done!");
if (config.DummyDll) if (config.DummyDll)
{ {

View file

@ -11,15 +11,17 @@ namespace Il2CppDumper
{ {
private Metadata metadata; private Metadata metadata;
private Il2Cpp il2Cpp; private Il2Cpp il2Cpp;
private StreamWriter writer;
private Dictionary<Il2CppTypeDefinition, int> typeDefImageIndices = new Dictionary<Il2CppTypeDefinition, int>(); private Dictionary<Il2CppTypeDefinition, int> typeDefImageIndices = new Dictionary<Il2CppTypeDefinition, int>();
public ScriptGenerator(Metadata metadata, Il2Cpp il2Cpp) public ScriptGenerator(Metadata metadata, Il2Cpp il2Cpp)
{ {
writer = new StreamWriter(new FileStream("ida.py", FileMode.Create), new UTF8Encoding(false));
this.metadata = metadata; this.metadata = metadata;
this.il2Cpp = il2Cpp; this.il2Cpp = il2Cpp;
} }
public void WriteScript(StreamWriter writer, Config config) public void WriteScript(Config config)
{ {
writer.WriteLine("#encoding: utf-8"); writer.WriteLine("#encoding: utf-8");
writer.WriteLine("import idaapi"); writer.WriteLine("import idaapi");
@ -138,12 +140,13 @@ namespace Il2CppDumper
var classInst = il2Cpp.genericInsts[methodSpec.classIndexIndex]; var classInst = il2Cpp.genericInsts[methodSpec.classIndexIndex];
typeName += GetGenericTypeParams(classInst); typeName += GetGenericTypeParams(classInst);
} }
var methodName = typeName + "." + metadata.GetStringFromIndex(methodDef.nameIndex) + "()"; var methodName = typeName + "." + 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 += GetGenericTypeParams(methodInst); methodName += GetGenericTypeParams(methodInst);
} }
methodName += "()";
writer.WriteLine($"SetName(0x{il2Cpp.metadataUsages[i.Key]:X}, '{"Method$" + methodName}')"); writer.WriteLine($"SetName(0x{il2Cpp.metadataUsages[i.Key]:X}, '{"Method$" + methodName}')");
writer.WriteLine($"idc.set_cmt(0x{il2Cpp.metadataUsages[i.Key]:X}, '{"Method$" + methodName}', 1)"); writer.WriteLine($"idc.set_cmt(0x{il2Cpp.metadataUsages[i.Key]:X}, '{"Method$" + methodName}', 1)");
var imageIndex = typeDefImageIndices[typeDef]; var imageIndex = typeDefImageIndices[typeDef];
@ -256,26 +259,29 @@ namespace Il2CppDumper
private string GetTypeDefName(Il2CppTypeDefinition typeDef, bool generic = true) private string GetTypeDefName(Il2CppTypeDefinition typeDef, bool generic = true)
{ {
var ret = string.Empty; var prefix = string.Empty;
if (typeDef.declaringTypeIndex != -1) if (typeDef.declaringTypeIndex != -1)
{ {
ret += GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex]) + "."; prefix = GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex]) + ".";
} }
ret += metadata.GetStringFromIndex(typeDef.nameIndex); var typeName = metadata.GetStringFromIndex(typeDef.nameIndex);
var names = new List<string>(); if (typeDef.genericContainerIndex >= 0)
if (generic && typeDef.genericContainerIndex >= 0)
{ {
var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex]; var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex];
for (int i = 0; i < genericContainer.type_argc; i++) typeName = typeName.Replace($"`{genericContainer.type_argc}", "");
if (generic)
{ {
var genericParameterIndex = genericContainer.genericParameterStart + i; var genericParameterNames = new List<string>();
var param = metadata.genericParameters[genericParameterIndex]; for (int i = 0; i < genericContainer.type_argc; i++)
names.Add(metadata.GetStringFromIndex(param.nameIndex)); {
var genericParameterIndex = genericContainer.genericParameterStart + i;
var param = metadata.genericParameters[genericParameterIndex];
genericParameterNames.Add(metadata.GetStringFromIndex(param.nameIndex));
}
typeName += $"<{string.Join(", ", genericParameterNames)}>";
} }
ret = ret.Replace($"`{genericContainer.type_argc}", "");
ret += $"<{string.Join(", ", names)}>";
} }
return ret; return prefix + typeName;
} }
public string GetGenericTypeParams(Il2CppGenericInst genericInst) public string GetGenericTypeParams(Il2CppGenericInst genericInst)