添加字符串缓存

细节修改
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 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()
{
var attributeNames = 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的反序列化
};
foreach (var attributeName in attributeNames)
foreach (var attributeName in knownAttributeNames)
{
foreach (var assemblyDefinition in Assemblies)
{
@ -604,5 +578,32 @@ namespace Il2CppDumper
}
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 Il2Cpp il2Cpp;
private StreamWriter writer;
private Dictionary<Il2CppMethodDefinition, string> methodModifiers = new Dictionary<Il2CppMethodDefinition, string>();
public Il2CppDecompiler(Metadata metadata, Il2Cpp il2Cpp)
{
writer = new StreamWriter(new FileStream("dump.cs", FileMode.Create), new UTF8Encoding(false));
this.metadata = metadata;
this.il2Cpp = il2Cpp;
}
public void Decompile(StreamWriter writer, Config config)
public void Decompile(Config config)
{
//dump image
for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
@ -399,12 +401,12 @@ namespace Il2CppDumper
public string GetTypeDefName(Il2CppTypeDefinition typeDef)
{
var ret = string.Empty;
var prefix = string.Empty;
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)
{
@ -415,10 +417,10 @@ namespace Il2CppDumper
var param = metadata.genericParameters[genericParameterIndex];
names.Add(metadata.GetStringFromIndex(param.nameIndex));
}
ret = ret.Replace($"`{genericContainer.type_argc}", "");
ret += $"<{string.Join(", ", names)}>";
typeName = typeName.Replace($"`{genericContainer.type_argc}", "");
typeName += $"<{string.Join(", ", names)}>";
}
return ret;
return prefix + typeName;
}
public string GetGenericTypeParams(Il2CppGenericInst genericInst)

View file

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

View file

@ -31,6 +31,7 @@ namespace Il2CppDumper
public Il2CppFieldRef[] fieldRefs;
public Il2CppGenericParameter[] genericParameters;
public int[] constraintIndices;
private Dictionary<uint, string> stringCache = new Dictionary<uint, string>();
public Metadata(Stream stream, float version) : base(stream)
{
@ -106,7 +107,13 @@ namespace Il2CppDumper
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)

View file

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

View file

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