From 8a1e42e7266c6029156da648e2bd99b91642cc95 Mon Sep 17 00:00:00 2001 From: Perfare Date: Thu, 6 Feb 2020 17:02:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?=E7=BC=93=E5=AD=98=20=E7=BB=86=E8=8A=82=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Il2CppDumper/DefineConstants.cs | 21 ---------- Il2CppDumper/DummyAssemblyGenerator.cs | 55 +++++++++++++------------- Il2CppDumper/ElfConstants.cs | 23 +++++++++++ Il2CppDumper/Il2CppDecompiler.cs | 16 ++++---- Il2CppDumper/Il2CppDumper.csproj | 1 + Il2CppDumper/Metadata.cs | 9 ++++- Il2CppDumper/Program.cs | 6 +-- Il2CppDumper/ScriptGenerator.cs | 34 +++++++++------- 8 files changed, 91 insertions(+), 74 deletions(-) create mode 100644 Il2CppDumper/ElfConstants.cs diff --git a/Il2CppDumper/DefineConstants.cs b/Il2CppDumper/DefineConstants.cs index 274d1c2..9a032ca 100644 --- a/Il2CppDumper/DefineConstants.cs +++ b/Il2CppDumper/DefineConstants.cs @@ -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; - } } \ No newline at end of file diff --git a/Il2CppDumper/DummyAssemblyGenerator.cs b/Il2CppDumper/DummyAssemblyGenerator.cs index e96b58a..e336910 100644 --- a/Il2CppDumper/DummyAssemblyGenerator.cs +++ b/Il2CppDumper/DummyAssemblyGenerator.cs @@ -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的反序列化 + }; } } diff --git a/Il2CppDumper/ElfConstants.cs b/Il2CppDumper/ElfConstants.cs new file mode 100644 index 0000000..7a29420 --- /dev/null +++ b/Il2CppDumper/ElfConstants.cs @@ -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; + } +} \ No newline at end of file diff --git a/Il2CppDumper/Il2CppDecompiler.cs b/Il2CppDumper/Il2CppDecompiler.cs index 114cbcd..32d86c8 100644 --- a/Il2CppDumper/Il2CppDecompiler.cs +++ b/Il2CppDumper/Il2CppDecompiler.cs @@ -11,15 +11,17 @@ namespace Il2CppDumper { private Metadata metadata; private Il2Cpp il2Cpp; + private StreamWriter writer; private Dictionary methodModifiers = new Dictionary(); 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(); 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) diff --git a/Il2CppDumper/Il2CppDumper.csproj b/Il2CppDumper/Il2CppDumper.csproj index 61a83a2..6a19536 100644 --- a/Il2CppDumper/Il2CppDumper.csproj +++ b/Il2CppDumper/Il2CppDumper.csproj @@ -49,6 +49,7 @@ + diff --git a/Il2CppDumper/Metadata.cs b/Il2CppDumper/Metadata.cs index ec6d6d0..92e2cec 100644 --- a/Il2CppDumper/Metadata.cs +++ b/Il2CppDumper/Metadata.cs @@ -31,6 +31,7 @@ namespace Il2CppDumper public Il2CppFieldRef[] fieldRefs; public Il2CppGenericParameter[] genericParameters; public int[] constraintIndices; + private Dictionary stringCache = new Dictionary(); 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) diff --git a/Il2CppDumper/Program.cs b/Il2CppDumper/Program.cs index 85f2ee6..62657f3 100644 --- a/Il2CppDumper/Program.cs +++ b/Il2CppDumper/Program.cs @@ -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) { diff --git a/Il2CppDumper/ScriptGenerator.cs b/Il2CppDumper/ScriptGenerator.cs index a388fe7..f482b17 100644 --- a/Il2CppDumper/ScriptGenerator.cs +++ b/Il2CppDumper/ScriptGenerator.cs @@ -11,15 +11,17 @@ namespace Il2CppDumper { private Metadata metadata; private Il2Cpp il2Cpp; + private StreamWriter writer; private Dictionary typeDefImageIndices = new Dictionary(); 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(); - 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(); + 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)