├── Attributes ├── ArrayLengthAttribute.cs └── VersionAttribute.cs ├── Config.cs ├── ExecutableFormats ├── Elf.cs ├── Elf64.cs ├── ElfBase.cs ├── ElfClass.cs ├── Macho.cs ├── Macho64.cs ├── MachoClass.cs ├── MachoFat.cs ├── NSO.cs ├── NSOClass.cs ├── PE.cs ├── PEClass.cs ├── WebAssembly.cs ├── WebAssemblyClass.cs └── WebAssemblyMemory.cs ├── Extensions ├── BinaryReaderExtensions.cs ├── BoyerMooreHorspool.cs ├── HexExtensions.cs └── StringExtensions.cs ├── IO ├── BinaryStream.cs └── Lz4DecoderStream.cs ├── Il2Cpp ├── Il2Cpp.cs ├── Il2CppClass.cs ├── Metadata.cs └── MetadataClass.cs ├── Il2CppBinaryNinja ├── __init__.py └── plugin.json ├── Libraries └── Il2CppDummyDll.dll ├── Outputs ├── DummyAssemblyExporter.cs ├── HeaderConstants.cs ├── Il2CppConstants.cs ├── Il2CppDecompiler.cs ├── ScriptJson.cs ├── StructGenerator.cs └── StructInfo.cs ├── Program.cs ├── README.md ├── Resource1.Designer.cs ├── Resource1.resx ├── Utils ├── ArmUtils.cs ├── AttributeArgument.cs ├── BlobValue.cs ├── CustomAttributeDataReader.cs ├── CustomAttributeReaderVisitor.cs ├── DummyAssemblyGenerator.cs ├── FileDialogNative.cs ├── Il2CppExecutor.cs ├── MyAssemblyResolver.cs ├── OpenFileDialog.cs ├── PELoader.cs ├── SearchSection.cs └── SectionHelper.cs ├── config.json ├── deer2cpp.csproj ├── ghidra.py ├── ghidra_wasm.py ├── ghidra_with_struct.py ├── hopper-py3.py ├── ida.py ├── ida_py3.py ├── ida_with_struct.py ├── ida_with_struct_py3.py ├── il2cpp_header_to_binja.py ├── il2cpp_header_to_ghidra.py └── obj ├── Debug ├── net6.0 │ ├── Il2CppDumper.AssemblyInfo.cs │ ├── Il2CppDumper.AssemblyInfoInputs.cache │ ├── Il2CppDumper.GeneratedMSBuildEditorConfig.editorconfig │ ├── Il2CppDumper.assets.cache │ ├── Il2CppDumper.csproj.AssemblyReference.cache │ ├── apphost.exe │ ├── deer2cpp.AssemblyInfo.cs │ ├── deer2cpp.AssemblyInfoInputs.cache │ ├── deer2cpp.GeneratedMSBuildEditorConfig.editorconfig │ ├── deer2cpp.Resource1.resources │ ├── deer2cpp.assets.cache │ ├── deer2cpp.csproj.AssemblyReference.cache │ ├── deer2cpp.csproj.CoreCompileInputs.cache │ ├── deer2cpp.csproj.FileListAbsolute.txt │ ├── deer2cpp.csproj.GenerateResource.cache │ ├── deer2cpp.csproj.Up2Date │ ├── deer2cpp.dll │ ├── deer2cpp.genruntimeconfig.cache │ ├── ref │ │ └── deer2cpp.dll │ └── refint │ │ └── deer2cpp.dll └── net8.0 │ ├── Il2CppDumper.AssemblyInfo.cs │ ├── Il2CppDumper.AssemblyInfoInputs.cache │ ├── Il2CppDumper.GeneratedMSBuildEditorConfig.editorconfig │ ├── Il2CppDumper.assets.cache │ ├── Il2CppDumper.csproj.AssemblyReference.cache │ ├── apphost.exe │ ├── deer2cpp.AssemblyInfo.cs │ ├── deer2cpp.AssemblyInfoInputs.cache │ ├── deer2cpp.GeneratedMSBuildEditorConfig.editorconfig │ ├── deer2cpp.Resource1.resources │ ├── deer2cpp.assets.cache │ ├── deer2cpp.csproj.AssemblyReference.cache │ ├── deer2cpp.csproj.CoreCompileInputs.cache │ ├── deer2cpp.csproj.FileListAbsolute.txt │ ├── deer2cpp.csproj.GenerateResource.cache │ ├── deer2cpp.csproj.Up2Date │ ├── deer2cpp.dll │ ├── deer2cpp.genruntimeconfig.cache │ ├── ref │ └── deer2cpp.dll │ └── refint │ └── deer2cpp.dll ├── Il2CppDumper.csproj.nuget.dgspec.json ├── Il2CppDumper.csproj.nuget.g.props ├── Il2CppDumper.csproj.nuget.g.targets ├── deer2cpp.csproj.nuget.dgspec.json ├── deer2cpp.csproj.nuget.g.props ├── deer2cpp.csproj.nuget.g.targets ├── project.assets.json └── project.nuget.cache /Attributes/ArrayLengthAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Il2CppDumper 4 | { 5 | [AttributeUsage(AttributeTargets.Field)] 6 | class ArrayLengthAttribute : Attribute 7 | { 8 | public int Length { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Attributes/VersionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Il2CppDumper 4 | { 5 | [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)] 6 | class VersionAttribute : Attribute 7 | { 8 | public double Min { get; set; } = 0; 9 | public double Max { get; set; } = 99; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Config.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public class Config 4 | { 5 | public bool DumpMethod { get; set; } = true; 6 | public bool DumpField { get; set; } = true; 7 | public bool DumpProperty { get; set; } = false; 8 | public bool DumpAttribute { get; set; } = false; 9 | public bool DumpFieldOffset { get; set; } = true; 10 | public bool DumpMethodOffset { get; set; } = true; 11 | public bool DumpTypeDefIndex { get; set; } = true; 12 | public bool GenerateDummyDll { get; set; } = true; 13 | public bool GenerateStruct { get; set; } = true; 14 | public bool DummyDllAddToken { get; set; } = true; 15 | public bool RequireAnyKey { get; set; } = true; 16 | public bool ForceIl2CppVersion { get; set; } = false; 17 | public double ForceVersion { get; set; } = 24.3; 18 | public bool ForceDump { get; set; } = false; 19 | public bool NoRedirectedPointer { get; set; } = false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ExecutableFormats/ElfBase.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Il2CppDumper 4 | { 5 | public abstract class ElfBase : Il2Cpp 6 | { 7 | protected ElfBase(Stream stream) : base(stream) { } 8 | protected abstract void Load(); 9 | protected abstract bool CheckSection(); 10 | 11 | public override bool CheckDump() => !CheckSection(); 12 | 13 | public void Reload() => Load(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ExecutableFormats/ElfClass.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public class Elf32_Ehdr 4 | { 5 | public uint ei_mag; 6 | public byte ei_class; 7 | public byte ei_data; 8 | public byte ei_version; 9 | public byte ei_osabi; 10 | public byte ei_abiversion; 11 | [ArrayLength(Length = 7)] 12 | public byte[] ei_pad; 13 | public ushort e_type; 14 | public ushort e_machine; 15 | public uint e_version; 16 | public uint e_entry; 17 | public uint e_phoff; 18 | public uint e_shoff; 19 | public uint e_flags; 20 | public ushort e_ehsize; 21 | public ushort e_phentsize; 22 | public ushort e_phnum; 23 | public ushort e_shentsize; 24 | public ushort e_shnum; 25 | public ushort e_shstrndx; 26 | } 27 | 28 | public class Elf32_Phdr 29 | { 30 | public uint p_type; 31 | public uint p_offset; 32 | public uint p_vaddr; 33 | public uint p_paddr; 34 | public uint p_filesz; 35 | public uint p_memsz; 36 | public uint p_flags; 37 | public uint p_align; 38 | } 39 | 40 | public class Elf32_Shdr 41 | { 42 | public uint sh_name; 43 | public uint sh_type; 44 | public uint sh_flags; 45 | public uint sh_addr; 46 | public uint sh_offset; 47 | public uint sh_size; 48 | public uint sh_link; 49 | public uint sh_info; 50 | public uint sh_addralign; 51 | public uint sh_entsize; 52 | } 53 | 54 | public class Elf32_Sym 55 | { 56 | public uint st_name; 57 | public uint st_value; 58 | public uint st_size; 59 | public byte st_info; 60 | public byte st_other; 61 | public ushort st_shndx; 62 | } 63 | 64 | public class Elf32_Dyn 65 | { 66 | public int d_tag; 67 | public uint d_un; 68 | } 69 | 70 | public class Elf32_Rel 71 | { 72 | public uint r_offset; 73 | public uint r_info; 74 | } 75 | 76 | public class Elf64_Ehdr 77 | { 78 | public uint ei_mag; 79 | public byte ei_class; 80 | public byte ei_data; 81 | public byte ei_version; 82 | public byte ei_osabi; 83 | public byte ei_abiversion; 84 | [ArrayLength(Length = 7)] 85 | public byte[] ei_pad; 86 | public ushort e_type; 87 | public ushort e_machine; 88 | public uint e_version; 89 | public ulong e_entry; 90 | public ulong e_phoff; 91 | public ulong e_shoff; 92 | public uint e_flags; 93 | public ushort e_ehsize; 94 | public ushort e_phentsize; 95 | public ushort e_phnum; 96 | public ushort e_shentsize; 97 | public ushort e_shnum; 98 | public ushort e_shstrndx; 99 | } 100 | 101 | public class Elf64_Phdr 102 | { 103 | public uint p_type; 104 | public uint p_flags; 105 | public ulong p_offset; 106 | public ulong p_vaddr; 107 | public ulong p_paddr; 108 | public ulong p_filesz; 109 | public ulong p_memsz; 110 | public ulong p_align; 111 | } 112 | 113 | public class Elf64_Shdr 114 | { 115 | public uint sh_name; 116 | public uint sh_type; 117 | public ulong sh_flags; 118 | public ulong sh_addr; 119 | public ulong sh_offset; 120 | public ulong sh_size; 121 | public uint sh_link; 122 | public uint sh_info; 123 | public ulong sh_addralign; 124 | public ulong sh_entsize; 125 | } 126 | 127 | public class Elf64_Sym 128 | { 129 | public uint st_name; 130 | public byte st_info; 131 | public byte st_other; 132 | public ushort st_shndx; 133 | public ulong st_value; 134 | public ulong st_size; 135 | } 136 | 137 | public class Elf64_Dyn 138 | { 139 | public long d_tag; 140 | public ulong d_un; 141 | } 142 | 143 | public class Elf64_Rela 144 | { 145 | public ulong r_offset; 146 | public ulong r_info; 147 | public ulong r_addend; 148 | } 149 | 150 | public static class ElfConstants 151 | { 152 | //e_machine 153 | public const int EM_386 = 3; 154 | public const int EM_ARM = 40; 155 | public const int EM_X86_64 = 62; 156 | public const int EM_AARCH64 = 183; 157 | 158 | //p_type 159 | public const int PT_LOAD = 1; 160 | public const int PT_DYNAMIC = 2; 161 | 162 | //p_flags 163 | public const int PF_X = 1; 164 | 165 | //d_tag 166 | public const int DT_PLTGOT = 3; 167 | public const int DT_HASH = 4; 168 | public const int DT_STRTAB = 5; 169 | public const int DT_SYMTAB = 6; 170 | public const int DT_RELA = 7; 171 | public const int DT_RELASZ = 8; 172 | public const int DT_INIT = 12; 173 | public const int DT_FINI = 13; 174 | public const int DT_REL = 17; 175 | public const int DT_RELSZ = 18; 176 | public const int DT_JMPREL = 23; 177 | public const int DT_INIT_ARRAY = 25; 178 | public const int DT_FINI_ARRAY = 26; 179 | public const int DT_GNU_HASH = 0x6ffffef5; 180 | 181 | //sh_type 182 | public const uint SHT_LOUSER = 0x80000000; 183 | 184 | //ARM relocs 185 | public const int R_ARM_ABS32 = 2; 186 | 187 | //i386 relocs 188 | public const int R_386_32 = 1; 189 | 190 | //AArch64 relocs 191 | public const int R_AARCH64_ABS64 = 257; 192 | public const int R_AARCH64_RELATIVE = 1027; 193 | 194 | //AMD x86-64 relocations 195 | public const int R_X86_64_64 = 1; 196 | public const int R_X86_64_RELATIVE = 8; 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /ExecutableFormats/Macho.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using static Il2CppDumper.ArmUtils; 7 | 8 | namespace Il2CppDumper 9 | { 10 | public sealed class Macho : Il2Cpp 11 | { 12 | private static readonly byte[] FeatureBytes1 = { 0x0, 0x22 };//MOVS R2, #0 13 | private static readonly byte[] FeatureBytes2 = { 0x78, 0x44, 0x79, 0x44 };//ADD R0, PC and ADD R1, PC 14 | private readonly List sections = new(); 15 | private readonly ulong vmaddr; 16 | 17 | public Macho(Stream stream) : base(stream) 18 | { 19 | Is32Bit = true; 20 | Position += 16; //skip magic, cputype, cpusubtype, filetype 21 | var ncmds = ReadUInt32(); 22 | Position += 8; //skip sizeofcmds, flags 23 | for (var i = 0; i < ncmds; i++) 24 | { 25 | var pos = Position; 26 | var cmd = ReadUInt32(); 27 | var cmdsize = ReadUInt32(); 28 | switch (cmd) 29 | { 30 | case 1: //LC_SEGMENT 31 | var segname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0'); 32 | if (segname == "__TEXT") //__PAGEZERO 33 | { 34 | vmaddr = ReadUInt32(); 35 | } 36 | else 37 | { 38 | Position += 4; 39 | } 40 | Position += 20; //skip vmsize, fileoff, filesize, maxprot, initprot 41 | var nsects = ReadUInt32(); 42 | Position += 4; //skip flags 43 | for (var j = 0; j < nsects; j++) 44 | { 45 | var section = new MachoSection(); 46 | sections.Add(section); 47 | section.sectname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0'); 48 | Position += 16; //skip segname 49 | section.addr = ReadUInt32(); 50 | section.size = ReadUInt32(); 51 | section.offset = ReadUInt32(); 52 | Position += 12; //skip align, reloff, nreloc 53 | section.flags = ReadUInt32(); 54 | Position += 8; //skip reserved1, reserved2 55 | } 56 | break; 57 | case 0x21: //LC_ENCRYPTION_INFO 58 | Position += 8; 59 | var cryptID = ReadUInt32(); 60 | if (cryptID != 0) 61 | { 62 | Console.WriteLine("ERROR: This Mach-O executable is encrypted and cannot be processed."); 63 | } 64 | break; 65 | } 66 | Position = pos + cmdsize;//next 67 | } 68 | } 69 | 70 | public override void Init(ulong codeRegistration, ulong metadataRegistration) 71 | { 72 | base.Init(codeRegistration, metadataRegistration); 73 | methodPointers = methodPointers.Select(x => x - 1).ToArray(); 74 | customAttributeGenerators = customAttributeGenerators.Select(x => x - 1).ToArray(); 75 | } 76 | 77 | public override ulong MapVATR(ulong addr) 78 | { 79 | var section = sections.First(x => addr >= x.addr && addr <= x.addr + x.size); 80 | return addr - section.addr + section.offset; 81 | } 82 | 83 | public override ulong MapRTVA(ulong addr) 84 | { 85 | var section = sections.FirstOrDefault(x => addr >= x.offset && addr <= x.offset + x.size); 86 | if (section == null) 87 | { 88 | return 0; 89 | } 90 | return addr - section.offset + section.addr; 91 | } 92 | 93 | public override bool Search() 94 | { 95 | if (Version < 21) 96 | { 97 | var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func"); 98 | var addrs = ReadClassArray(__mod_init_func.offset, __mod_init_func.size / 4u); 99 | foreach (var a in addrs) 100 | { 101 | if (a > 0) 102 | { 103 | var i = a - 1; 104 | Position = MapVATR(i); 105 | Position += 4; 106 | var buff = ReadBytes(2); 107 | if (FeatureBytes1.SequenceEqual(buff)) 108 | { 109 | Position += 12; 110 | buff = ReadBytes(4); 111 | if (FeatureBytes2.SequenceEqual(buff)) 112 | { 113 | Position = MapVATR(i) + 10; 114 | var subaddr = DecodeMov(ReadBytes(8)) + i + 24u - 1u; 115 | var rsubaddr = MapVATR(subaddr); 116 | Position = rsubaddr; 117 | var ptr = DecodeMov(ReadBytes(8)) + subaddr + 16u; 118 | Position = MapVATR(ptr); 119 | var metadataRegistration = ReadUInt32(); 120 | Position = rsubaddr + 8; 121 | buff = ReadBytes(4); 122 | Position = rsubaddr + 14; 123 | buff = buff.Concat(ReadBytes(4)).ToArray(); 124 | var codeRegistration = DecodeMov(buff) + subaddr + 22u; 125 | Console.WriteLine("CodeRegistration : {0:x}", codeRegistration); 126 | Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration); 127 | Init(codeRegistration, metadataRegistration); 128 | return true; 129 | } 130 | } 131 | } 132 | } 133 | return false; 134 | } 135 | else 136 | { 137 | var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func"); 138 | var addrs = ReadClassArray(__mod_init_func.offset, __mod_init_func.size / 4u); 139 | foreach (var a in addrs) 140 | { 141 | if (a > 0) 142 | { 143 | var i = a - 1; 144 | Position = MapVATR(i); 145 | Position += 4; 146 | var buff = ReadBytes(2); 147 | if (FeatureBytes1.SequenceEqual(buff)) 148 | { 149 | Position += 12; 150 | buff = ReadBytes(4); 151 | if (FeatureBytes2.SequenceEqual(buff)) 152 | { 153 | Position = MapVATR(i) + 10; 154 | var subaddr = DecodeMov(ReadBytes(8)) + i + 24u - 1u; 155 | var rsubaddr = MapVATR(subaddr); 156 | Position = rsubaddr; 157 | var ptr = DecodeMov(ReadBytes(8)) + subaddr + 16u; 158 | Position = MapVATR(ptr); 159 | var metadataRegistration = ReadUInt32(); 160 | Position = rsubaddr + 8; 161 | buff = ReadBytes(4); 162 | Position = rsubaddr + 14; 163 | buff = buff.Concat(ReadBytes(4)).ToArray(); 164 | var codeRegistration = DecodeMov(buff) + subaddr + 26u; 165 | Console.WriteLine("CodeRegistration : {0:x}", codeRegistration); 166 | Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration); 167 | Init(codeRegistration, metadataRegistration); 168 | return true; 169 | } 170 | } 171 | } 172 | } 173 | return false; 174 | } 175 | } 176 | 177 | public override bool PlusSearch(int methodCount, int typeDefinitionsCount, int imageCount) 178 | { 179 | var sectionHelper = GetSectionHelper(methodCount, typeDefinitionsCount, imageCount); 180 | var codeRegistration = sectionHelper.FindCodeRegistration(); 181 | var metadataRegistration = sectionHelper.FindMetadataRegistration(); 182 | return AutoPlusInit(codeRegistration, metadataRegistration); 183 | } 184 | 185 | public override bool SymbolSearch() 186 | { 187 | return false; 188 | } 189 | 190 | public override ulong GetRVA(ulong pointer) 191 | { 192 | return pointer - vmaddr; 193 | } 194 | 195 | public override SectionHelper GetSectionHelper(int methodCount, int typeDefinitionsCount, int imageCount) 196 | { 197 | var data = sections.Where(x => x.sectname == "__const").ToArray(); 198 | var code = sections.Where(x => x.flags == 0x80000400).ToArray(); 199 | var bss = sections.Where(x => x.flags == 1u).ToArray(); 200 | var sectionHelper = new SectionHelper(this, methodCount, typeDefinitionsCount, metadataUsagesCount, imageCount); 201 | sectionHelper.SetSection(SearchSectionType.Exec, code); 202 | sectionHelper.SetSection(SearchSectionType.Data, data); 203 | sectionHelper.SetSection(SearchSectionType.Bss, bss); 204 | return sectionHelper; 205 | } 206 | 207 | public override bool CheckDump() => false; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /ExecutableFormats/MachoClass.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public class MachoSection 4 | { 5 | public string sectname; 6 | public uint addr; 7 | public uint size; 8 | public uint offset; 9 | public uint flags; 10 | } 11 | 12 | public class MachoSection64Bit 13 | { 14 | public string sectname; 15 | public ulong addr; 16 | public ulong size; 17 | public ulong offset; 18 | public uint flags; 19 | } 20 | 21 | public class Fat 22 | { 23 | public uint offset; 24 | public uint size; 25 | public uint magic; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ExecutableFormats/MachoFat.cs: -------------------------------------------------------------------------------- 1 | using System.Buffers.Binary; 2 | using System.IO; 3 | 4 | namespace Il2CppDumper 5 | { 6 | public sealed class MachoFat : BinaryStream 7 | { 8 | public Fat[] fats; 9 | 10 | public MachoFat(Stream stream) : base(stream) 11 | { 12 | Position += 4; 13 | var size = BinaryPrimitives.ReadInt32BigEndian(ReadBytes(4)); 14 | fats = new Fat[size]; 15 | for (var i = 0; i < size; i++) 16 | { 17 | Position += 8; 18 | fats[i] = new Fat 19 | { 20 | offset = BinaryPrimitives.ReadUInt32BigEndian(ReadBytes(4)), 21 | size = BinaryPrimitives.ReadUInt32BigEndian(ReadBytes(4)) 22 | }; 23 | Position += 4; 24 | } 25 | for (var i = 0; i < size; i++) 26 | { 27 | Position = fats[i].offset; 28 | fats[i].magic = ReadUInt32(); 29 | } 30 | } 31 | 32 | public byte[] GetMacho(int index) 33 | { 34 | Position = fats[index].offset; 35 | return ReadBytes((int)fats[index].size); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ExecutableFormats/NSOClass.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public class NSOHeader 4 | { 5 | public uint Magic; 6 | public uint Version; 7 | public uint Reserved; 8 | public uint Flags; 9 | public NSOSegmentHeader TextSegment; 10 | public uint ModuleOffset; 11 | public NSOSegmentHeader RoDataSegment; 12 | public uint ModuleFileSize; 13 | public NSOSegmentHeader DataSegment; 14 | public uint BssSize; 15 | public byte[] DigestBuildID; 16 | public uint TextCompressedSize; 17 | public uint RoDataCompressedSize; 18 | public uint DataCompressedSize; 19 | public byte[] Padding; 20 | public NSORelativeExtent APIInfo; 21 | public NSORelativeExtent DynStr; 22 | public NSORelativeExtent DynSym; 23 | public byte[] TextHash; 24 | public byte[] RoDataHash; 25 | public byte[] DataHash; 26 | 27 | public NSOSegmentHeader BssSegment; 28 | } 29 | 30 | public class NSOSegmentHeader 31 | { 32 | public uint FileOffset; 33 | public uint MemoryOffset; 34 | public uint DecompressedSize; 35 | } 36 | 37 | public class NSORelativeExtent 38 | { 39 | public uint RegionRoDataOffset; 40 | public uint RegionSize; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ExecutableFormats/PE.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace Il2CppDumper 7 | { 8 | public sealed class PE : Il2Cpp 9 | { 10 | private readonly SectionHeader[] sections; 11 | 12 | public PE(Stream stream) : base(stream) 13 | { 14 | var dosHeader = ReadClass(); 15 | if (dosHeader.Magic != 0x5A4D) 16 | { 17 | throw new InvalidDataException("ERROR: Invalid PE file"); 18 | } 19 | Position = dosHeader.Lfanew; 20 | if (ReadUInt32() != 0x4550u) //Signature 21 | { 22 | throw new InvalidDataException("ERROR: Invalid PE file"); 23 | } 24 | var fileHeader = ReadClass(); 25 | var pos = Position; 26 | var magic = ReadUInt16(); 27 | Position -= 2; 28 | if (magic == 0x10b) 29 | { 30 | Is32Bit = true; 31 | var optionalHeader = ReadClass(); 32 | ImageBase = optionalHeader.ImageBase; 33 | } 34 | else if (magic == 0x20b) 35 | { 36 | var optionalHeader = ReadClass(); 37 | ImageBase = optionalHeader.ImageBase; 38 | } 39 | else 40 | { 41 | throw new NotSupportedException($"Invalid Optional header magic {magic}"); 42 | } 43 | Position = pos + fileHeader.SizeOfOptionalHeader; 44 | sections = ReadClassArray(fileHeader.NumberOfSections); 45 | } 46 | 47 | public void LoadFromMemory(ulong addr) 48 | { 49 | ImageBase = addr; 50 | foreach (var section in sections) 51 | { 52 | section.PointerToRawData = section.VirtualAddress; 53 | section.SizeOfRawData = section.VirtualSize; 54 | } 55 | } 56 | 57 | public override ulong MapVATR(ulong absAddr) 58 | { 59 | var addr = absAddr - ImageBase; 60 | var section = sections.FirstOrDefault(x => addr >= x.VirtualAddress && addr <= x.VirtualAddress + x.VirtualSize); 61 | if (section == null) 62 | { 63 | return 0ul; 64 | } 65 | return addr - section.VirtualAddress + section.PointerToRawData; 66 | } 67 | 68 | public override ulong MapRTVA(ulong addr) 69 | { 70 | var section = sections.FirstOrDefault(x => addr >= x.PointerToRawData && addr <= x.PointerToRawData + x.SizeOfRawData); 71 | if (section == null) 72 | { 73 | return 0ul; 74 | } 75 | return addr - section.PointerToRawData + section.VirtualAddress + ImageBase; 76 | } 77 | 78 | public override bool Search() 79 | { 80 | return false; 81 | } 82 | 83 | public override bool PlusSearch(int methodCount, int typeDefinitionsCount, int imageCount) 84 | { 85 | var sectionHelper = GetSectionHelper(methodCount, typeDefinitionsCount, imageCount); 86 | var codeRegistration = sectionHelper.FindCodeRegistration(); 87 | var metadataRegistration = sectionHelper.FindMetadataRegistration(); 88 | return AutoPlusInit(codeRegistration, metadataRegistration); 89 | } 90 | 91 | public override bool SymbolSearch() 92 | { 93 | return false; 94 | } 95 | 96 | public override ulong GetRVA(ulong pointer) 97 | { 98 | return pointer - ImageBase; 99 | } 100 | 101 | public override SectionHelper GetSectionHelper(int methodCount, int typeDefinitionsCount, int imageCount) 102 | { 103 | var execList = new List(); 104 | var dataList = new List(); 105 | foreach (var section in sections) 106 | { 107 | switch (section.Characteristics) 108 | { 109 | case 0x60000020: 110 | execList.Add(section); 111 | break; 112 | case 0x40000040: 113 | case 0xC0000040: 114 | dataList.Add(section); 115 | break; 116 | } 117 | } 118 | var sectionHelper = new SectionHelper(this, methodCount, typeDefinitionsCount, metadataUsagesCount, imageCount); 119 | var data = dataList.ToArray(); 120 | var exec = execList.ToArray(); 121 | sectionHelper.SetSection(SearchSectionType.Exec, ImageBase, exec); 122 | sectionHelper.SetSection(SearchSectionType.Data, ImageBase, data); 123 | sectionHelper.SetSection(SearchSectionType.Bss, ImageBase, data); 124 | return sectionHelper; 125 | } 126 | 127 | public override bool CheckDump() 128 | { 129 | if (Is32Bit) 130 | { 131 | return ImageBase != 0x10000000; 132 | } 133 | else 134 | { 135 | return ImageBase != 0x180000000; 136 | } 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /ExecutableFormats/PEClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Il2CppDumper 4 | { 5 | public class DosHeader 6 | { 7 | public ushort Magic; 8 | public ushort Cblp; 9 | public ushort Cp; 10 | public ushort Crlc; 11 | public ushort Cparhdr; 12 | public ushort Minalloc; 13 | public ushort Maxalloc; 14 | public ushort Ss; 15 | public ushort Sp; 16 | public ushort Csum; 17 | public ushort Ip; 18 | public ushort Cs; 19 | public ushort Lfarlc; 20 | public ushort Ovno; 21 | [ArrayLength(Length = 4)] 22 | public ushort[] Res; 23 | public ushort Oemid; 24 | public ushort Oeminfo; 25 | [ArrayLength(Length = 10)] 26 | public ushort[] Res2; 27 | public uint Lfanew; 28 | } 29 | 30 | public class FileHeader 31 | { 32 | public ushort Machine; 33 | public ushort NumberOfSections; 34 | public uint TimeDateStamp; 35 | public uint PointerToSymbolTable; 36 | public uint NumberOfSymbols; 37 | public ushort SizeOfOptionalHeader; 38 | public ushort Characteristics; 39 | } 40 | 41 | public class OptionalHeader 42 | { 43 | public ushort Magic; 44 | public byte MajorLinkerVersion; 45 | public byte MinorLinkerVersion; 46 | public uint SizeOfCode; 47 | public uint SizeOfInitializedData; 48 | public uint SizeOfUninitializedData; 49 | public uint AddressOfEntryPoint; 50 | public uint BaseOfCode; 51 | public uint BaseOfData; 52 | public uint ImageBase; 53 | public uint SectionAlignment; 54 | public uint FileAlignment; 55 | public ushort MajorOperatingSystemVersion; 56 | public ushort MinorOperatingSystemVersion; 57 | public ushort MajorImageVersion; 58 | public ushort MinorImageVersion; 59 | public ushort MajorSubsystemVersion; 60 | public ushort MinorSubsystemVersion; 61 | public uint Win32VersionValue; 62 | public uint SizeOfImage; 63 | public uint SizeOfHeaders; 64 | public uint CheckSum; 65 | public ushort Subsystem; 66 | public ushort DllCharacteristics; 67 | public uint SizeOfStackReserve; 68 | public uint SizeOfStackCommit; 69 | public uint SizeOfHeapReserve; 70 | public uint SizeOfHeapCommit; 71 | public uint LoaderFlags; 72 | public uint NumberOfRvaAndSizes; 73 | //public DataDirectory[] DataDirectory; 74 | } 75 | 76 | public class OptionalHeader64 77 | { 78 | public ushort Magic; 79 | public byte MajorLinkerVersion; 80 | public byte MinorLinkerVersion; 81 | public uint SizeOfCode; 82 | public uint SizeOfInitializedData; 83 | public uint SizeOfUninitializedData; 84 | public uint AddressOfEntryPoint; 85 | public uint BaseOfCode; 86 | public ulong ImageBase; 87 | public uint SectionAlignment; 88 | public uint FileAlignment; 89 | public ushort MajorOperatingSystemVersion; 90 | public ushort MinorOperatingSystemVersion; 91 | public ushort MajorImageVersion; 92 | public ushort MinorImageVersion; 93 | public ushort MajorSubsystemVersion; 94 | public ushort MinorSubsystemVersion; 95 | public uint Win32VersionValue; 96 | public uint SizeOfImage; 97 | public uint SizeOfHeaders; 98 | public uint CheckSum; 99 | public ushort Subsystem; 100 | public ushort DllCharacteristics; 101 | public ulong SizeOfStackReserve; 102 | public ulong SizeOfStackCommit; 103 | public ulong SizeOfHeapReserve; 104 | public ulong SizeOfHeapCommit; 105 | public uint LoaderFlags; 106 | public uint NumberOfRvaAndSizes; 107 | //public DataDirectory[] DataDirectory; 108 | } 109 | 110 | /*public class DataDirectory 111 | { 112 | public uint VirtualAddress; 113 | public uint Size; 114 | }*/ 115 | 116 | public class SectionHeader 117 | { 118 | [ArrayLength(Length = 8)] 119 | public byte[] Name; 120 | public uint VirtualSize; 121 | public uint VirtualAddress; 122 | public uint SizeOfRawData; 123 | public uint PointerToRawData; 124 | public uint PointerToRelocations; 125 | public uint PointerToLinenumbers; 126 | public ushort NumberOfRelocations; 127 | public ushort NumberOfLinenumbers; 128 | public uint Characteristics; 129 | } 130 | 131 | [Flags] 132 | public enum SectionCharacteristics : uint 133 | { 134 | IMAGE_SCN_MEM_EXECUTE = 0x20000000, 135 | IMAGE_SCN_MEM_READ = 0x40000000, 136 | IMAGE_SCN_MEM_WRITE = 0x80000000 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /ExecutableFormats/WebAssembly.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Il2CppDumper 5 | { 6 | public sealed class WebAssembly : BinaryStream 7 | { 8 | private readonly DataSection[] dataSections; 9 | 10 | public WebAssembly(Stream stream) : base(stream) 11 | { 12 | Is32Bit = true; 13 | var magic = ReadUInt32(); 14 | var version = ReadInt32(); 15 | while (Position < Length) 16 | { 17 | var id = ReadULeb128(); 18 | var len = ReadULeb128(); 19 | if (id == 11) 20 | { 21 | var count = ReadULeb128(); 22 | dataSections = new DataSection[count]; 23 | for (int i = 0; i < count; i++) 24 | { 25 | var dataSection = new DataSection(); 26 | dataSections[i] = dataSection; 27 | dataSection.Index = ReadULeb128(); 28 | var opCode = ReadByte(); 29 | if (opCode != 0x41) //i32.const 30 | { 31 | throw new InvalidOperationException(); 32 | } 33 | dataSection.Offset = ReadULeb128(); 34 | opCode = ReadByte(); 35 | if (opCode != 0xB) //end 36 | { 37 | throw new InvalidOperationException(); 38 | } 39 | dataSection.Data = ReadBytes((int)ReadULeb128()); 40 | } 41 | break; 42 | } 43 | Position += len; 44 | } 45 | } 46 | 47 | public WebAssemblyMemory CreateMemory() 48 | { 49 | var last = dataSections[^1]; 50 | var bssStart = last.Offset + (uint)last.Data.Length; 51 | var stream = new MemoryStream(new byte[Length]); 52 | foreach (var dataSection in dataSections) 53 | { 54 | stream.Position = dataSection.Offset; 55 | stream.Write(dataSection.Data, 0, dataSection.Data.Length); 56 | } 57 | return new WebAssemblyMemory(stream, bssStart); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ExecutableFormats/WebAssemblyClass.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public class DataSection 4 | { 5 | public uint Index; 6 | public uint Offset; 7 | public byte[] Data; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ExecutableFormats/WebAssemblyMemory.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Il2CppDumper 4 | { 5 | public sealed class WebAssemblyMemory : Il2Cpp 6 | { 7 | private readonly uint bssStart; 8 | 9 | public WebAssemblyMemory(Stream stream, uint bssStart) : base(stream) 10 | { 11 | Is32Bit = true; 12 | this.bssStart = bssStart; 13 | } 14 | 15 | public override ulong MapVATR(ulong addr) 16 | { 17 | return addr; 18 | } 19 | 20 | public override ulong MapRTVA(ulong addr) 21 | { 22 | return addr; 23 | } 24 | 25 | public override bool PlusSearch(int methodCount, int typeDefinitionsCount, int imageCount) 26 | { 27 | var sectionHelper = GetSectionHelper(methodCount, typeDefinitionsCount, imageCount); 28 | var codeRegistration = sectionHelper.FindCodeRegistration(); 29 | var metadataRegistration = sectionHelper.FindMetadataRegistration(); 30 | return AutoPlusInit(codeRegistration, metadataRegistration); 31 | } 32 | 33 | public override bool Search() 34 | { 35 | return false; 36 | } 37 | 38 | public override bool SymbolSearch() 39 | { 40 | return false; 41 | } 42 | 43 | public override SectionHelper GetSectionHelper(int methodCount, int typeDefinitionsCount, int imageCount) 44 | { 45 | var exec = new SearchSection 46 | { 47 | offset = 0, 48 | offsetEnd = (ulong)methodCount, //hack 49 | address = 0, 50 | addressEnd = (ulong)methodCount //hack 51 | }; 52 | var data = new SearchSection 53 | { 54 | offset = 1024, 55 | offsetEnd = Length, 56 | address = 1024, 57 | addressEnd = Length 58 | }; 59 | var bss = new SearchSection 60 | { 61 | offset = bssStart, 62 | offsetEnd = long.MaxValue, //hack 63 | address = bssStart, 64 | addressEnd = long.MaxValue //hack 65 | }; 66 | var sectionHelper = new SectionHelper(this, methodCount, typeDefinitionsCount, metadataUsagesCount, imageCount); 67 | sectionHelper.SetSection(SearchSectionType.Exec, exec); 68 | sectionHelper.SetSection(SearchSectionType.Data, data); 69 | sectionHelper.SetSection(SearchSectionType.Bss, bss); 70 | return sectionHelper; 71 | } 72 | 73 | public override bool CheckDump() => false; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Extensions/BinaryReaderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace Il2CppDumper 6 | { 7 | public static class BinaryReaderExtensions 8 | { 9 | public static string ReadString(this BinaryReader reader, int numChars) 10 | { 11 | var start = reader.BaseStream.Position; 12 | // UTF8 takes up to 4 bytes per character 13 | var str = Encoding.UTF8.GetString(reader.ReadBytes(numChars * 4))[..numChars]; 14 | // make our position what it would have been if we'd known the exact number of bytes needed. 15 | reader.BaseStream.Position = start; 16 | reader.ReadBytes(Encoding.UTF8.GetByteCount(str)); 17 | return str; 18 | } 19 | 20 | public static uint ReadULeb128(this BinaryReader reader) 21 | { 22 | uint value = reader.ReadByte(); 23 | if (value >= 0x80) 24 | { 25 | var bitshift = 0; 26 | value &= 0x7f; 27 | while (true) 28 | { 29 | var b = reader.ReadByte(); 30 | bitshift += 7; 31 | value |= (uint)((b & 0x7f) << bitshift); 32 | if (b < 0x80) 33 | break; 34 | } 35 | } 36 | return value; 37 | } 38 | 39 | public static uint ReadCompressedUInt32(this BinaryReader reader) 40 | { 41 | uint val; 42 | var read = reader.ReadByte(); 43 | 44 | if ((read & 0x80) == 0) 45 | { 46 | // 1 byte written 47 | val = read; 48 | } 49 | else if ((read & 0xC0) == 0x80) 50 | { 51 | // 2 bytes written 52 | val = (read & ~0x80u) << 8; 53 | val |= reader.ReadByte(); 54 | } 55 | else if ((read & 0xE0) == 0xC0) 56 | { 57 | // 4 bytes written 58 | val = (read & ~0xC0u) << 24; 59 | val |= ((uint)reader.ReadByte() << 16); 60 | val |= ((uint)reader.ReadByte() << 8); 61 | val |= reader.ReadByte(); 62 | } 63 | else if (read == 0xF0) 64 | { 65 | // 5 bytes written, we had a really large int32! 66 | val = reader.ReadUInt32(); 67 | } 68 | else if (read == 0xFE) 69 | { 70 | // Special encoding for Int32.MaxValue 71 | val = uint.MaxValue - 1; 72 | } 73 | else if (read == 0xFF) 74 | { 75 | // Yes we treat UInt32.MaxValue (and Int32.MinValue, see ReadCompressedInt32) specially 76 | val = uint.MaxValue; 77 | } 78 | else 79 | { 80 | throw new Exception("Invalid compressed integer format"); 81 | } 82 | 83 | return val; 84 | } 85 | 86 | public static int ReadCompressedInt32(this BinaryReader reader) 87 | { 88 | var encoded = reader.ReadCompressedUInt32(); 89 | 90 | // -UINT32_MAX can't be represted safely in an int32_t, so we treat it specially 91 | if (encoded == uint.MaxValue) 92 | return int.MinValue; 93 | 94 | bool isNegative = (encoded & 1) != 0; 95 | encoded >>= 1; 96 | if (isNegative) 97 | return -(int)(encoded + 1); 98 | return (int)encoded; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Extensions/BoyerMooreHorspool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Il2CppDumper 5 | { 6 | static class BoyerMooreHorspool 7 | { 8 | public static IEnumerable Search(this byte[] source, byte[] pattern) 9 | { 10 | if (source == null) 11 | { 12 | throw new ArgumentNullException(nameof(source)); 13 | } 14 | 15 | if (pattern == null) 16 | { 17 | throw new ArgumentNullException(nameof(pattern)); 18 | } 19 | 20 | int valueLength = source.Length; 21 | int patternLength = pattern.Length; 22 | 23 | if (valueLength == 0 || patternLength == 0 || patternLength > valueLength) 24 | { 25 | yield break; 26 | } 27 | 28 | var badCharacters = new int[256]; 29 | 30 | for (var i = 0; i < 256; i++) 31 | { 32 | badCharacters[i] = patternLength; 33 | } 34 | 35 | var lastPatternByte = patternLength - 1; 36 | 37 | for (int i = 0; i < lastPatternByte; i++) 38 | { 39 | badCharacters[pattern[i]] = lastPatternByte - i; 40 | } 41 | 42 | int index = 0; 43 | 44 | while (index <= valueLength - patternLength) 45 | { 46 | for (var i = lastPatternByte; source[index + i] == pattern[i]; i--) 47 | { 48 | if (i == 0) 49 | { 50 | yield return index; 51 | break; 52 | } 53 | } 54 | 55 | index += badCharacters[source[index + lastPatternByte]]; 56 | } 57 | } 58 | 59 | public static IEnumerable Search(this byte[] source, string stringPattern) 60 | { 61 | if (source == null) 62 | { 63 | throw new ArgumentNullException(nameof(source)); 64 | } 65 | 66 | if (stringPattern == null) 67 | { 68 | throw new ArgumentNullException(nameof(stringPattern)); 69 | } 70 | 71 | var pattern = stringPattern.Split(' '); 72 | 73 | int valueLength = source.Length; 74 | int patternLength = pattern.Length; 75 | 76 | if (valueLength == 0 || patternLength == 0 || patternLength > valueLength) 77 | { 78 | yield break; 79 | } 80 | 81 | var badCharacters = new int[256]; 82 | 83 | for (var i = 0; i < 256; i++) 84 | { 85 | badCharacters[i] = patternLength; 86 | } 87 | 88 | var lastPatternByte = patternLength - 1; 89 | 90 | for (int i = 0; i < lastPatternByte; i++) 91 | { 92 | if (pattern[i] != "?") 93 | { 94 | var result = Convert.ToInt32(pattern[i], 16); 95 | badCharacters[result] = lastPatternByte - i; 96 | } 97 | } 98 | 99 | int index = 0; 100 | 101 | while (index <= valueLength - patternLength) 102 | { 103 | for (var i = lastPatternByte; CheckEqual(source, pattern, index, i); i--) 104 | { 105 | if (i == 0) 106 | { 107 | yield return index; 108 | break; 109 | } 110 | } 111 | 112 | index += badCharacters[source[index + lastPatternByte]]; 113 | } 114 | } 115 | 116 | private static bool CheckEqual(byte[] source, string[] pattern, int index, int i) 117 | { 118 | if (pattern[i] != "?") 119 | { 120 | var result = Convert.ToInt32(pattern[i], 16); 121 | return source[index + i] == result; 122 | } 123 | return true; 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Extensions/HexExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Il2CppDumper 5 | { 6 | static class HexExtensions 7 | { 8 | public static string HexToBin(this byte b) 9 | { 10 | return Convert.ToString(b, 2).PadLeft(8, '0'); 11 | } 12 | 13 | public static string HexToBin(this byte[] bytes) 14 | { 15 | var result = new StringBuilder(bytes.Length * 8); 16 | foreach (var b in bytes) 17 | { 18 | result.Insert(0, b.HexToBin()); 19 | } 20 | return result.ToString(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace Il2CppDumper 4 | { 5 | public static class StringExtensions 6 | { 7 | public static string ToEscapedString(this string s) 8 | { 9 | var re = new StringBuilder(s.Length); 10 | foreach (var c in s) 11 | { 12 | switch (c) 13 | { 14 | case '\'': 15 | re.Append(@"\'"); 16 | break; 17 | case '"': 18 | re.Append(@"\"""); 19 | break; 20 | case '\\': 21 | re.Append(@"\\"); 22 | break; 23 | case '\0': 24 | re.Append(@"\0"); 25 | break; 26 | case '\a': 27 | re.Append(@"\a"); 28 | break; 29 | case '\b': 30 | re.Append(@"\b"); 31 | break; 32 | case '\f': 33 | re.Append(@"\f"); 34 | break; 35 | case '\n': 36 | re.Append(@"\n"); 37 | break; 38 | case '\r': 39 | re.Append(@"\r"); 40 | break; 41 | case '\t': 42 | re.Append(@"\t"); 43 | break; 44 | case '\v': 45 | re.Append(@"\v"); 46 | break; 47 | case '\u0085': 48 | re.Append(@"\u0085"); 49 | break; 50 | case '\u2028': 51 | re.Append(@"\u2028"); 52 | break; 53 | case '\u2029': 54 | re.Append(@"\u2029"); 55 | break; 56 | default: 57 | re.Append(c); 58 | break; 59 | } 60 | } 61 | return re.ToString(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /IO/BinaryStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | 8 | namespace Il2CppDumper 9 | { 10 | public class BinaryStream : IDisposable 11 | { 12 | public double Version; 13 | public bool Is32Bit; 14 | public ulong ImageBase; 15 | private readonly Stream stream; 16 | private readonly BinaryReader reader; 17 | private readonly BinaryWriter writer; 18 | private readonly MethodInfo readClass; 19 | private readonly MethodInfo readClassArray; 20 | private readonly Dictionary genericMethodCache; 21 | private readonly Dictionary attributeCache; 22 | 23 | public BinaryStream(Stream input) 24 | { 25 | stream = input; 26 | reader = new BinaryReader(stream, Encoding.UTF8, true); 27 | writer = new BinaryWriter(stream, Encoding.UTF8, true); 28 | readClass = GetType().GetMethod("ReadClass", Type.EmptyTypes); 29 | readClassArray = GetType().GetMethod("ReadClassArray", new[] { typeof(long) }); 30 | genericMethodCache = new(); 31 | attributeCache = new(); 32 | } 33 | 34 | public bool ReadBoolean() => reader.ReadBoolean(); 35 | 36 | public byte ReadByte() => reader.ReadByte(); 37 | 38 | public byte[] ReadBytes(int count) => reader.ReadBytes(count); 39 | 40 | public sbyte ReadSByte() => reader.ReadSByte(); 41 | 42 | public short ReadInt16() => reader.ReadInt16(); 43 | 44 | public ushort ReadUInt16() => reader.ReadUInt16(); 45 | 46 | public int ReadInt32() => reader.ReadInt32(); 47 | 48 | public uint ReadUInt32() => reader.ReadUInt32(); 49 | 50 | public long ReadInt64() => reader.ReadInt64(); 51 | 52 | public ulong ReadUInt64() => reader.ReadUInt64(); 53 | 54 | public float ReadSingle() => reader.ReadSingle(); 55 | 56 | public double ReadDouble() => reader.ReadDouble(); 57 | 58 | public uint ReadCompressedUInt32() => reader.ReadCompressedUInt32(); 59 | 60 | public int ReadCompressedInt32() => reader.ReadCompressedInt32(); 61 | 62 | public uint ReadULeb128() => reader.ReadULeb128(); 63 | 64 | public void Write(bool value) => writer.Write(value); 65 | 66 | public void Write(byte value) => writer.Write(value); 67 | 68 | public void Write(sbyte value) => writer.Write(value); 69 | 70 | public void Write(short value) => writer.Write(value); 71 | 72 | public void Write(ushort value) => writer.Write(value); 73 | 74 | public void Write(int value) => writer.Write(value); 75 | 76 | public void Write(uint value) => writer.Write(value); 77 | 78 | public void Write(long value) => writer.Write(value); 79 | 80 | public void Write(ulong value) => writer.Write(value); 81 | 82 | public void Write(float value) => writer.Write(value); 83 | 84 | public void Write(double value) => writer.Write(value); 85 | 86 | public ulong Position 87 | { 88 | get => (ulong)stream.Position; 89 | set => stream.Position = (long)value; 90 | } 91 | 92 | public ulong Length => (ulong)stream.Length; 93 | 94 | private object ReadPrimitive(Type type) 95 | { 96 | return type.Name switch 97 | { 98 | "Int32" => ReadInt32(), 99 | "UInt32" => ReadUInt32(), 100 | "Int16" => ReadInt16(), 101 | "UInt16" => ReadUInt16(), 102 | "Byte" => ReadByte(), 103 | "Int64" => ReadIntPtr(), 104 | "UInt64" => ReadUIntPtr(), 105 | _ => throw new NotSupportedException() 106 | }; 107 | } 108 | 109 | public T ReadClass(ulong addr) where T : new() 110 | { 111 | Position = addr; 112 | return ReadClass(); 113 | } 114 | 115 | public T ReadClass() where T : new() 116 | { 117 | var type = typeof(T); 118 | if (type.IsPrimitive) 119 | { 120 | return (T)ReadPrimitive(type); 121 | } 122 | else 123 | { 124 | var t = new T(); 125 | foreach (var i in t.GetType().GetFields()) 126 | { 127 | if (!attributeCache.TryGetValue(i, out var versionAttributes)) 128 | { 129 | if (Attribute.IsDefined(i, typeof(VersionAttribute))) 130 | { 131 | versionAttributes = i.GetCustomAttributes().ToArray(); 132 | attributeCache.Add(i, versionAttributes); 133 | } 134 | } 135 | if (versionAttributes?.Length > 0) 136 | { 137 | var read = false; 138 | foreach (var versionAttribute in versionAttributes) 139 | { 140 | if (Version >= versionAttribute.Min && Version <= versionAttribute.Max) 141 | { 142 | read = true; 143 | break; 144 | } 145 | } 146 | if (!read) 147 | { 148 | continue; 149 | } 150 | } 151 | var fieldType = i.FieldType; 152 | if (fieldType.IsPrimitive) 153 | { 154 | i.SetValue(t, ReadPrimitive(fieldType)); 155 | } 156 | else if (fieldType.IsEnum) 157 | { 158 | var e = fieldType.GetField("value__").FieldType; 159 | i.SetValue(t, ReadPrimitive(e)); 160 | } 161 | else if (fieldType.IsArray) 162 | { 163 | var arrayLengthAttribute = i.GetCustomAttribute(); 164 | if (!genericMethodCache.TryGetValue(fieldType, out var methodInfo)) 165 | { 166 | methodInfo = readClassArray.MakeGenericMethod(fieldType.GetElementType()); 167 | genericMethodCache.Add(fieldType, methodInfo); 168 | } 169 | i.SetValue(t, methodInfo.Invoke(this, new object[] { arrayLengthAttribute.Length })); 170 | } 171 | else 172 | { 173 | if (!genericMethodCache.TryGetValue(fieldType, out var methodInfo)) 174 | { 175 | methodInfo = readClass.MakeGenericMethod(fieldType); 176 | genericMethodCache.Add(fieldType, methodInfo); 177 | } 178 | i.SetValue(t, methodInfo.Invoke(this, null)); 179 | } 180 | } 181 | return t; 182 | } 183 | } 184 | 185 | public T[] ReadClassArray(long count) where T : new() 186 | { 187 | var t = new T[count]; 188 | for (var i = 0; i < count; i++) 189 | { 190 | t[i] = ReadClass(); 191 | } 192 | return t; 193 | } 194 | 195 | public T[] ReadClassArray(ulong addr, ulong count) where T : new() 196 | { 197 | return ReadClassArray(addr, (long)count); 198 | } 199 | 200 | public T[] ReadClassArray(ulong addr, long count) where T : new() 201 | { 202 | Position = addr; 203 | return ReadClassArray(count); 204 | } 205 | 206 | public string ReadStringToNull(ulong addr) 207 | { 208 | Position = addr; 209 | var bytes = new List(); 210 | byte b; 211 | while ((b = ReadByte()) != 0) 212 | bytes.Add(b); 213 | return Encoding.UTF8.GetString(bytes.ToArray()); 214 | } 215 | 216 | public long ReadIntPtr() 217 | { 218 | return Is32Bit ? ReadInt32() : ReadInt64(); 219 | } 220 | 221 | public virtual ulong ReadUIntPtr() 222 | { 223 | return Is32Bit ? ReadUInt32() : ReadUInt64(); 224 | } 225 | 226 | public ulong PointerSize 227 | { 228 | get => Is32Bit ? 4ul : 8ul; 229 | } 230 | 231 | public BinaryReader Reader => reader; 232 | 233 | public BinaryWriter Writer => writer; 234 | 235 | protected virtual void Dispose(bool disposing) 236 | { 237 | if (disposing) 238 | { 239 | reader.Dispose(); 240 | writer.Dispose(); 241 | stream.Close(); 242 | } 243 | } 244 | 245 | public void Dispose() 246 | { 247 | Dispose(true); 248 | GC.SuppressFinalize(this); 249 | } 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /Il2Cpp/Il2CppClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Il2CppDumper 4 | { 5 | public class Il2CppCodeRegistration 6 | { 7 | [Version(Max = 24.1)] 8 | public ulong methodPointersCount; 9 | [Version(Max = 24.1)] 10 | public ulong methodPointers; 11 | [Version(Max = 21)] 12 | public ulong delegateWrappersFromNativeToManagedCount; 13 | [Version(Max = 21)] 14 | public ulong delegateWrappersFromNativeToManaged; // note the double indirection to handle different calling conventions 15 | [Version(Min = 22)] 16 | public ulong reversePInvokeWrapperCount; 17 | [Version(Min = 22)] 18 | public ulong reversePInvokeWrappers; 19 | [Version(Max = 22)] 20 | public ulong delegateWrappersFromManagedToNativeCount; 21 | [Version(Max = 22)] 22 | public ulong delegateWrappersFromManagedToNative; 23 | [Version(Max = 22)] 24 | public ulong marshalingFunctionsCount; 25 | [Version(Max = 22)] 26 | public ulong marshalingFunctions; 27 | [Version(Min = 21, Max = 22)] 28 | public ulong ccwMarshalingFunctionsCount; 29 | [Version(Min = 21, Max = 22)] 30 | public ulong ccwMarshalingFunctions; 31 | public ulong genericMethodPointersCount; 32 | public ulong genericMethodPointers; 33 | [Version(Min = 24.5, Max = 24.5)] 34 | [Version(Min = 27.1)] 35 | public ulong genericAdjustorThunks; 36 | public ulong invokerPointersCount; 37 | public ulong invokerPointers; 38 | [Version(Max = 24.5)] 39 | public ulong customAttributeCount; 40 | [Version(Max = 24.5)] 41 | public ulong customAttributeGenerators; 42 | [Version(Min = 21, Max = 22)] 43 | public ulong guidCount; 44 | [Version(Min = 21, Max = 22)] 45 | public ulong guids; // Il2CppGuid 46 | [Version(Min = 22)] 47 | public ulong unresolvedVirtualCallCount; //29.1 unresolvedIndirectCallCount; 48 | [Version(Min = 22)] 49 | public ulong unresolvedVirtualCallPointers; 50 | [Version(Min = 29.1)] 51 | public ulong unresolvedInstanceCallPointers; 52 | [Version(Min = 29.1)] 53 | public ulong unresolvedStaticCallPointers; 54 | [Version(Min = 23)] 55 | public ulong interopDataCount; 56 | [Version(Min = 23)] 57 | public ulong interopData; 58 | [Version(Min = 24.3)] 59 | public ulong windowsRuntimeFactoryCount; 60 | [Version(Min = 24.3)] 61 | public ulong windowsRuntimeFactoryTable; 62 | [Version(Min = 24.2)] 63 | public ulong codeGenModulesCount; 64 | [Version(Min = 24.2)] 65 | public ulong codeGenModules; 66 | } 67 | 68 | public class Il2CppMetadataRegistration 69 | { 70 | public long genericClassesCount; 71 | public ulong genericClasses; 72 | public long genericInstsCount; 73 | public ulong genericInsts; 74 | public long genericMethodTableCount; 75 | public ulong genericMethodTable; 76 | public long typesCount; 77 | public ulong types; 78 | public long methodSpecsCount; 79 | public ulong methodSpecs; 80 | [Version(Max = 16)] 81 | public long methodReferencesCount; 82 | [Version(Max = 16)] 83 | public ulong methodReferences; 84 | 85 | public long fieldOffsetsCount; 86 | public ulong fieldOffsets; 87 | 88 | public long typeDefinitionsSizesCount; 89 | public ulong typeDefinitionsSizes; 90 | [Version(Min = 19)] 91 | public ulong metadataUsagesCount; 92 | [Version(Min = 19)] 93 | public ulong metadataUsages; 94 | } 95 | 96 | public enum Il2CppTypeEnum 97 | { 98 | IL2CPP_TYPE_END = 0x00, /* End of List */ 99 | IL2CPP_TYPE_VOID = 0x01, 100 | IL2CPP_TYPE_BOOLEAN = 0x02, 101 | IL2CPP_TYPE_CHAR = 0x03, 102 | IL2CPP_TYPE_I1 = 0x04, 103 | IL2CPP_TYPE_U1 = 0x05, 104 | IL2CPP_TYPE_I2 = 0x06, 105 | IL2CPP_TYPE_U2 = 0x07, 106 | IL2CPP_TYPE_I4 = 0x08, 107 | IL2CPP_TYPE_U4 = 0x09, 108 | IL2CPP_TYPE_I8 = 0x0a, 109 | IL2CPP_TYPE_U8 = 0x0b, 110 | IL2CPP_TYPE_R4 = 0x0c, 111 | IL2CPP_TYPE_R8 = 0x0d, 112 | IL2CPP_TYPE_STRING = 0x0e, 113 | IL2CPP_TYPE_PTR = 0x0f, /* arg: token */ 114 | IL2CPP_TYPE_BYREF = 0x10, /* arg: token */ 115 | IL2CPP_TYPE_VALUETYPE = 0x11, /* arg: token */ 116 | IL2CPP_TYPE_CLASS = 0x12, /* arg: token */ 117 | IL2CPP_TYPE_VAR = 0x13, /* Generic parameter in a generic type definition, represented as number (compressed unsigned integer) number */ 118 | IL2CPP_TYPE_ARRAY = 0x14, /* type, rank, boundsCount, bound1, loCount, lo1 */ 119 | IL2CPP_TYPE_GENERICINST = 0x15, /* \x{2026} */ 120 | IL2CPP_TYPE_TYPEDBYREF = 0x16, 121 | IL2CPP_TYPE_I = 0x18, 122 | IL2CPP_TYPE_U = 0x19, 123 | IL2CPP_TYPE_FNPTR = 0x1b, /* arg: full method signature */ 124 | IL2CPP_TYPE_OBJECT = 0x1c, 125 | IL2CPP_TYPE_SZARRAY = 0x1d, /* 0-based one-dim-array */ 126 | IL2CPP_TYPE_MVAR = 0x1e, /* Generic parameter in a generic method definition, represented as number (compressed unsigned integer) */ 127 | IL2CPP_TYPE_CMOD_REQD = 0x1f, /* arg: typedef or typeref token */ 128 | IL2CPP_TYPE_CMOD_OPT = 0x20, /* optional arg: typedef or typref token */ 129 | IL2CPP_TYPE_INTERNAL = 0x21, /* CLR internal type */ 130 | 131 | IL2CPP_TYPE_MODIFIER = 0x40, /* Or with the following types */ 132 | IL2CPP_TYPE_SENTINEL = 0x41, /* Sentinel for varargs method signature */ 133 | IL2CPP_TYPE_PINNED = 0x45, /* Local var that points to pinned object */ 134 | 135 | IL2CPP_TYPE_ENUM = 0x55, /* an enumeration */ 136 | IL2CPP_TYPE_IL2CPP_TYPE_INDEX = 0xff /* an index into IL2CPP type metadata table */ 137 | } 138 | 139 | public class Il2CppType 140 | { 141 | public ulong datapoint; 142 | public uint bits; 143 | public Union data { get; set; } 144 | public uint attrs { get; set; } 145 | public Il2CppTypeEnum type { get; set; } 146 | public uint num_mods { get; set; } 147 | public uint byref { get; set; } 148 | public uint pinned { get; set; } 149 | public uint valuetype { get; set; } 150 | 151 | public void Init(double version) 152 | { 153 | attrs = bits & 0xffff; 154 | type = (Il2CppTypeEnum)((bits >> 16) & 0xff); 155 | if (version >= 27.2) 156 | { 157 | num_mods = (bits >> 24) & 0x1f; 158 | byref = (bits >> 29) & 1; 159 | pinned = (bits >> 30) & 1; 160 | valuetype = bits >> 31; 161 | } 162 | else 163 | { 164 | num_mods = (bits >> 24) & 0x3f; 165 | byref = (bits >> 30) & 1; 166 | pinned = bits >> 31; 167 | } 168 | data = new Union { dummy = datapoint }; 169 | } 170 | 171 | public class Union 172 | { 173 | public ulong dummy; 174 | /// 175 | /// for VALUETYPE and CLASS 176 | /// 177 | public long klassIndex => (long)dummy; 178 | /// 179 | /// for VALUETYPE and CLASS at runtime 180 | /// 181 | public ulong typeHandle => dummy; 182 | /// 183 | /// for PTR and SZARRAY 184 | /// 185 | public ulong type => dummy; 186 | /// 187 | /// for ARRAY 188 | /// 189 | public ulong array => dummy; 190 | /// 191 | /// for VAR and MVAR 192 | /// 193 | public long genericParameterIndex => (long)dummy; 194 | /// 195 | /// for VAR and MVAR at runtime 196 | /// 197 | public ulong genericParameterHandle => dummy; 198 | /// 199 | /// for GENERICINST 200 | /// 201 | public ulong generic_class => dummy; 202 | } 203 | } 204 | 205 | public class Il2CppGenericClass 206 | { 207 | [Version(Max = 24.5)] 208 | public long typeDefinitionIndex; /* the generic type definition */ 209 | [Version(Min = 27)] 210 | public ulong type; /* the generic type definition */ 211 | public Il2CppGenericContext context; /* a context that contains the type instantiation doesn't contain any method instantiation */ 212 | public ulong cached_class; /* if present, the Il2CppClass corresponding to the instantiation. */ 213 | } 214 | 215 | public class Il2CppGenericContext 216 | { 217 | /* The instantiation corresponding to the class generic parameters */ 218 | public ulong class_inst; 219 | /* The instantiation corresponding to the method generic parameters */ 220 | public ulong method_inst; 221 | } 222 | 223 | public class Il2CppGenericInst 224 | { 225 | public long type_argc; 226 | public ulong type_argv; 227 | } 228 | 229 | public class Il2CppArrayType 230 | { 231 | public ulong etype; 232 | public byte rank; 233 | public byte numsizes; 234 | public byte numlobounds; 235 | public ulong sizes; 236 | public ulong lobounds; 237 | } 238 | 239 | public class Il2CppGenericMethodFunctionsDefinitions 240 | { 241 | public int genericMethodIndex; 242 | public Il2CppGenericMethodIndices indices; 243 | } 244 | 245 | public class Il2CppGenericMethodIndices 246 | { 247 | public int methodIndex; 248 | public int invokerIndex; 249 | [Version(Min = 24.5, Max = 24.5)] 250 | [Version(Min = 27.1)] 251 | public int adjustorThunk; 252 | }; 253 | 254 | public class Il2CppMethodSpec 255 | { 256 | public int methodDefinitionIndex; 257 | public int classIndexIndex; 258 | public int methodIndexIndex; 259 | }; 260 | 261 | public class Il2CppCodeGenModule 262 | { 263 | public ulong moduleName; 264 | public long methodPointerCount; 265 | public ulong methodPointers; 266 | [Version(Min = 24.5, Max = 24.5)] 267 | [Version(Min = 27.1)] 268 | public long adjustorThunkCount; 269 | [Version(Min = 24.5, Max = 24.5)] 270 | [Version(Min = 27.1)] 271 | public ulong adjustorThunks; 272 | public ulong invokerIndices; 273 | public ulong reversePInvokeWrapperCount; 274 | public ulong reversePInvokeWrapperIndices; 275 | public long rgctxRangesCount; 276 | public ulong rgctxRanges; 277 | public long rgctxsCount; 278 | public ulong rgctxs; 279 | public ulong debuggerMetadata; 280 | [Version(Min = 27, Max = 27.2)] 281 | public ulong customAttributeCacheGenerator; 282 | [Version(Min = 27)] 283 | public ulong moduleInitializer; 284 | [Version(Min = 27)] 285 | public ulong staticConstructorTypeIndices; 286 | [Version(Min = 27)] 287 | public ulong metadataRegistration; // Per-assembly mode only 288 | [Version(Min = 27)] 289 | public ulong codeRegistaration; // Per-assembly mode only 290 | } 291 | 292 | public class Il2CppRange 293 | { 294 | public int start; 295 | public int length; 296 | } 297 | 298 | public class Il2CppTokenRangePair 299 | { 300 | public uint token; 301 | public Il2CppRange range; 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /Il2CppBinaryNinja/__init__.py: -------------------------------------------------------------------------------- 1 | from binaryninja import * 2 | from os.path import exists 3 | 4 | def get_addr(bv: BinaryView, addr: int): 5 | imageBase = bv.start 6 | return imageBase + addr 7 | 8 | class Il2CppProcessTask(BackgroundTaskThread): 9 | def __init__(self, bv: BinaryView, script_path: str, 10 | header_path: str): 11 | BackgroundTaskThread.__init__(self, "Il2Cpp start", True) 12 | self.bv = bv 13 | self.script_path = script_path 14 | self.header_path = header_path 15 | self.has_types = False 16 | 17 | def process_header(self): 18 | self.progress = "Il2Cpp types (1/3)" 19 | with open(self.header_path) as f: 20 | result = self.bv.parse_types_from_string(f.read()) 21 | length = len(result.types) 22 | i = 0 23 | for name in result.types: 24 | i += 1 25 | if i % 100 == 0: 26 | percent = i / length * 100 27 | self.progress = f"Il2Cpp types: {percent:.2f}%" 28 | if self.bv.get_type_by_name(name): 29 | continue 30 | self.bv.define_user_type(name, result.types[name]) 31 | 32 | def process_methods(self, data: dict): 33 | self.progress = f"Il2Cpp methods (2/3)" 34 | scriptMethods = data["ScriptMethod"] 35 | length = len(scriptMethods) 36 | i = 0 37 | for scriptMethod in scriptMethods: 38 | if self.cancelled: 39 | self.progress = "Il2Cpp cancelled, aborting" 40 | return 41 | i += 1 42 | if i % 100 == 0: 43 | percent = i / length * 100 44 | self.progress = f"Il2Cpp methods: {percent:.2f}%" 45 | addr = get_addr(self.bv, scriptMethod["Address"]) 46 | name = scriptMethod["Name"].replace("$", "_").replace(".", "_") 47 | signature = scriptMethod["Signature"] 48 | func = self.bv.get_function_at(addr) 49 | if func != None: 50 | if func.name == name: 51 | continue 52 | if self.has_types: 53 | func.function_type = signature 54 | else: 55 | func.name = scriptMethod["Name"] 56 | 57 | def process_strings(self, data: dict): 58 | self.progress = "Il2Cpp strings (3/3)" 59 | scriptStrings = data["ScriptString"] 60 | i = 0 61 | for scriptString in scriptStrings: 62 | i += 1 63 | if self.cancelled: 64 | self.progress = "Il2Cpp cancelled, aborting" 65 | return 66 | addr = get_addr(self.bv, scriptString["Address"]) 67 | value = scriptString["Value"] 68 | var = self.bv.get_data_var_at(addr) 69 | if var != None: 70 | var.name = f"StringLiteral_{i}" 71 | self.bv.set_comment_at(addr, value) 72 | 73 | def run(self): 74 | if exists(self.header_path): 75 | self.process_header() 76 | else: 77 | log_warn("Header file not found") 78 | if self.bv.get_type_by_name("Il2CppClass"): 79 | self.has_types = True 80 | data = json.loads(open(self.script_path, 'rb').read().decode('utf-8')) 81 | if "ScriptMethod" in data: 82 | self.process_methods(data) 83 | if "ScriptString" in data: 84 | self.process_strings(data) 85 | 86 | def process(bv: BinaryView): 87 | scriptDialog = OpenFileNameField("Select script.json", "script.json", "script.json") 88 | headerDialog = OpenFileNameField("Select il2cpp_binja.h", "il2cpp_binja.h", "il2cpp_binja.h") 89 | if not get_form_input([scriptDialog, headerDialog], "script.json from deer2cpp"): 90 | return log_error("File not selected, try again!") 91 | if not exists(scriptDialog.result): 92 | return log_error("File not found, try again!") 93 | task = Il2CppProcessTask(bv, scriptDialog.result, headerDialog.result) 94 | task.start() 95 | 96 | PluginCommand.register("deer2cpp", "Process file", process) 97 | -------------------------------------------------------------------------------- /Il2CppBinaryNinja/plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginmetadataversion": 2, 3 | "name": "Il2CppDumper", 4 | "type": [ 5 | "core", 6 | "ui", 7 | "binaryview" 8 | ], 9 | "api": [ 10 | "python3" 11 | ], 12 | "description": "Add Il2Cpp structs and method signatures", 13 | "longdescription": "", 14 | "license": { 15 | "name": "MIT", 16 | "text": "Copyright (c) 2022 Il2CppDumper contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." 17 | }, 18 | "platforms": [ 19 | "Darwin", 20 | "Linux", 21 | "Windows" 22 | ], 23 | "installinstructions": { 24 | "Darwin": "Install Il2CppDumper", 25 | "Linux": "Install Il2CppDumper", 26 | "Windows": "Install Il2CppDumper" 27 | }, 28 | "dependencies": { 29 | }, 30 | "version": "1.0.0", 31 | "author": "Il2CppDumper contributors", 32 | "minimumbinaryninjaversion": 3164 33 | } 34 | -------------------------------------------------------------------------------- /Libraries/Il2CppDummyDll.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/Libraries/Il2CppDummyDll.dll -------------------------------------------------------------------------------- /Outputs/DummyAssemblyExporter.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Il2CppDumper 4 | { 5 | public static class DummyAssemblyExporter 6 | { 7 | public static void Export(Il2CppExecutor il2CppExecutor, string outputDir, bool addToken) 8 | { 9 | Directory.SetCurrentDirectory(outputDir); 10 | if (Directory.Exists("DummyDll")) 11 | Directory.Delete("DummyDll", true); 12 | Directory.CreateDirectory("DummyDll"); 13 | Directory.SetCurrentDirectory("DummyDll"); 14 | var dummy = new DummyAssemblyGenerator(il2CppExecutor, addToken); 15 | foreach (var assembly in dummy.Assemblies) 16 | { 17 | using var stream = new MemoryStream(); 18 | assembly.Write(stream); 19 | File.WriteAllBytes(assembly.MainModule.Name, stream.ToArray()); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Outputs/Il2CppConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | class Il2CppConstants 4 | { 5 | /* 6 | * Field Attributes (21.1.5). 7 | */ 8 | public const int FIELD_ATTRIBUTE_FIELD_ACCESS_MASK = 0x0007; 9 | public const int FIELD_ATTRIBUTE_COMPILER_CONTROLLED = 0x0000; 10 | public const int FIELD_ATTRIBUTE_PRIVATE = 0x0001; 11 | public const int FIELD_ATTRIBUTE_FAM_AND_ASSEM = 0x0002; 12 | public const int FIELD_ATTRIBUTE_ASSEMBLY = 0x0003; 13 | public const int FIELD_ATTRIBUTE_FAMILY = 0x0004; 14 | public const int FIELD_ATTRIBUTE_FAM_OR_ASSEM = 0x0005; 15 | public const int FIELD_ATTRIBUTE_PUBLIC = 0x0006; 16 | 17 | public const int FIELD_ATTRIBUTE_STATIC = 0x0010; 18 | public const int FIELD_ATTRIBUTE_INIT_ONLY = 0x0020; 19 | public const int FIELD_ATTRIBUTE_LITERAL = 0x0040; 20 | 21 | /* 22 | * Method Attributes (22.1.9) 23 | */ 24 | public const int METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK = 0x0007; 25 | public const int METHOD_ATTRIBUTE_COMPILER_CONTROLLED = 0x0000; 26 | public const int METHOD_ATTRIBUTE_PRIVATE = 0x0001; 27 | public const int METHOD_ATTRIBUTE_FAM_AND_ASSEM = 0x0002; 28 | public const int METHOD_ATTRIBUTE_ASSEM = 0x0003; 29 | public const int METHOD_ATTRIBUTE_FAMILY = 0x0004; 30 | public const int METHOD_ATTRIBUTE_FAM_OR_ASSEM = 0x0005; 31 | public const int METHOD_ATTRIBUTE_PUBLIC = 0x0006; 32 | 33 | public const int METHOD_ATTRIBUTE_STATIC = 0x0010; 34 | public const int METHOD_ATTRIBUTE_FINAL = 0x0020; 35 | public const int METHOD_ATTRIBUTE_VIRTUAL = 0x0040; 36 | 37 | public const int METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK = 0x0100; 38 | public const int METHOD_ATTRIBUTE_REUSE_SLOT = 0x0000; 39 | public const int METHOD_ATTRIBUTE_NEW_SLOT = 0x0100; 40 | 41 | public const int METHOD_ATTRIBUTE_ABSTRACT = 0x0400; 42 | 43 | public const int METHOD_ATTRIBUTE_PINVOKE_IMPL = 0x2000; 44 | 45 | /* 46 | * Type Attributes (21.1.13). 47 | */ 48 | public const int TYPE_ATTRIBUTE_VISIBILITY_MASK = 0x00000007; 49 | public const int TYPE_ATTRIBUTE_NOT_PUBLIC = 0x00000000; 50 | public const int TYPE_ATTRIBUTE_PUBLIC = 0x00000001; 51 | public const int TYPE_ATTRIBUTE_NESTED_PUBLIC = 0x00000002; 52 | public const int TYPE_ATTRIBUTE_NESTED_PRIVATE = 0x00000003; 53 | public const int TYPE_ATTRIBUTE_NESTED_FAMILY = 0x00000004; 54 | public const int TYPE_ATTRIBUTE_NESTED_ASSEMBLY = 0x00000005; 55 | public const int TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM = 0x00000006; 56 | public const int TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM = 0x00000007; 57 | 58 | 59 | public const int TYPE_ATTRIBUTE_INTERFACE = 0x00000020; 60 | 61 | public const int TYPE_ATTRIBUTE_ABSTRACT = 0x00000080; 62 | public const int TYPE_ATTRIBUTE_SEALED = 0x00000100; 63 | 64 | public const int TYPE_ATTRIBUTE_SERIALIZABLE = 0x00002000; 65 | 66 | /* 67 | * Flags for Params (22.1.12) 68 | */ 69 | public const int PARAM_ATTRIBUTE_IN = 0x0001; 70 | public const int PARAM_ATTRIBUTE_OUT = 0x0002; 71 | public const int PARAM_ATTRIBUTE_OPTIONAL = 0x0010; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Outputs/Il2CppDecompiler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using static Il2CppDumper.Il2CppConstants; 7 | 8 | namespace Il2CppDumper 9 | { 10 | public class Il2CppDecompiler 11 | { 12 | private readonly Il2CppExecutor executor; 13 | private readonly Metadata metadata; 14 | private readonly Il2Cpp il2Cpp; 15 | private readonly Dictionary methodModifiers; 16 | 17 | public Il2CppDecompiler(Il2CppExecutor il2CppExecutor) 18 | { 19 | executor = il2CppExecutor; 20 | metadata = il2CppExecutor.metadata; 21 | il2Cpp = il2CppExecutor.il2Cpp; 22 | methodModifiers = new(); 23 | } 24 | 25 | public void Decompile(Config config, string outputDir) 26 | { 27 | using var writer = new StreamWriter(new FileStream(Path.Combine(outputDir, "dump.cs"), FileMode.Create), new UTF8Encoding(false)); 28 | 29 | // Dump images 30 | for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++) 31 | { 32 | var imageDef = metadata.imageDefs[imageIndex]; 33 | writer.WriteLine($"// Image {imageIndex}: {metadata.GetStringFromIndex(imageDef.nameIndex)} - {imageDef.typeStart}"); 34 | } 35 | 36 | // Dump types 37 | foreach (var imageDef in metadata.imageDefs) 38 | { 39 | try 40 | { 41 | var imageName = metadata.GetStringFromIndex(imageDef.nameIndex); 42 | var typeEnd = imageDef.typeStart + imageDef.typeCount; 43 | for (int typeDefIndex = imageDef.typeStart; typeDefIndex < typeEnd; typeDefIndex++) 44 | { 45 | var typeDef = metadata.typeDefs[typeDefIndex]; 46 | var extends = new List(); 47 | 48 | if (typeDef.parentIndex >= 0) 49 | { 50 | var parentMetadataIndex = typeDef.parentIndex; 51 | var parentName = metadata.GetStringFromIndex((uint)parentMetadataIndex); // Fetch name directly from metadata 52 | if (!typeDef.IsValueType && !typeDef.IsEnum && parentName != "object") 53 | { 54 | extends.Add(parentName); 55 | } 56 | } 57 | 58 | 59 | if (typeDef.parentIndex >= 0) 60 | { 61 | // Fetch the parent type metadata index 62 | var parentMetadataIndex = typeDef.parentIndex; 63 | 64 | // Fetch the parent type name directly from the metadata 65 | var parentName = metadata.GetStringFromIndex((uint)parentMetadataIndex); // Cast to uint if necessary 66 | 67 | // Add the parent name to extends if it's not a value type, enum, or object 68 | if (!typeDef.IsValueType && !typeDef.IsEnum && parentName != "object") 69 | { 70 | extends.Add(parentName); 71 | } 72 | } 73 | 74 | 75 | 76 | 77 | 78 | writer.WriteLine($"\n// Namespace: {metadata.GetStringFromIndex(typeDef.namespaceIndex)}"); 79 | 80 | if (config.DumpAttribute) 81 | { 82 | writer.Write((imageDef, typeDef.customAttributeIndex, typeDef.token)); 83 | } 84 | 85 | if (config.DumpAttribute && (typeDef.flags & TYPE_ATTRIBUTE_SERIALIZABLE) != 0) 86 | writer.WriteLine("[Serializable]"); 87 | 88 | var visibility = typeDef.flags & TYPE_ATTRIBUTE_VISIBILITY_MASK; 89 | switch (visibility) 90 | { 91 | case TYPE_ATTRIBUTE_PUBLIC: 92 | case TYPE_ATTRIBUTE_NESTED_PUBLIC: 93 | writer.Write("public "); 94 | break; 95 | case TYPE_ATTRIBUTE_NOT_PUBLIC: 96 | case TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM: 97 | case TYPE_ATTRIBUTE_NESTED_ASSEMBLY: 98 | writer.Write("internal "); 99 | break; 100 | case TYPE_ATTRIBUTE_NESTED_PRIVATE: 101 | writer.Write("private "); 102 | break; 103 | case TYPE_ATTRIBUTE_NESTED_FAMILY: 104 | writer.Write("protected "); 105 | break; 106 | case TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM: 107 | writer.Write("protected internal "); 108 | break; 109 | } 110 | 111 | if ((typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0 && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0) 112 | writer.Write("static "); 113 | else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0) 114 | writer.Write("abstract "); 115 | else if (!typeDef.IsValueType && !typeDef.IsEnum && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0) 116 | writer.Write("sealed "); 117 | 118 | if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0) 119 | writer.Write("interface "); 120 | else if (typeDef.IsEnum) 121 | writer.Write("enum "); 122 | else if (typeDef.IsValueType) 123 | writer.Write("struct "); 124 | else 125 | writer.Write("class "); 126 | 127 | // Fetch the type name directly from the metadata 128 | var typeName = metadata.GetStringFromIndex((uint)typeDef.nameIndex); // Assuming 'nameIndex' holds the index to the type's name 129 | 130 | // Write the type name to the output 131 | writer.WriteLine(typeName); 132 | 133 | } 134 | } 135 | catch (Exception ex) 136 | { 137 | Console.WriteLine($"Error decompiling image {metadata.GetStringFromIndex(imageDef.nameIndex)} !! {ex.Message}"); 138 | } 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Outputs/ScriptJson.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Il2CppDumper 4 | { 5 | public class ScriptJson 6 | { 7 | public List ScriptMethod = new(); 8 | public List ScriptString = new(); 9 | public List ScriptMetadata = new(); 10 | public List ScriptMetadataMethod = new(); 11 | public ulong[] Addresses; 12 | } 13 | 14 | public class ScriptMethod 15 | { 16 | public ulong Address; 17 | public string Name; 18 | public string Signature; 19 | public string TypeSignature; 20 | } 21 | 22 | public class ScriptString 23 | { 24 | public ulong Address; 25 | public string Value; 26 | } 27 | 28 | public class ScriptMetadata 29 | { 30 | public ulong Address; 31 | public string Name; 32 | public string Signature; 33 | } 34 | 35 | public class ScriptMetadataMethod 36 | { 37 | public ulong Address; 38 | public string Name; 39 | public ulong MethodAddress; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Outputs/StructInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Il2CppDumper 5 | { 6 | public class StructInfo 7 | { 8 | public string TypeName; 9 | public bool IsValueType; 10 | public string Parent; 11 | public List Fields = new(); 12 | public List StaticFields = new(); 13 | public StructVTableMethodInfo[] VTableMethod = Array.Empty(); 14 | public List RGCTXs = new(); 15 | } 16 | 17 | public class StructFieldInfo 18 | { 19 | public string FieldTypeName; 20 | public string FieldName; 21 | public bool IsValueType; 22 | public bool IsCustomType; 23 | } 24 | 25 | public class StructVTableMethodInfo 26 | { 27 | public string MethodName; 28 | } 29 | 30 | public class StructRGCTXInfo 31 | { 32 | public Il2CppRGCTXDataType Type; 33 | public string TypeName; 34 | public string ClassName; 35 | public string MethodName; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Text.Json; 6 | 7 | namespace Il2CppDumper 8 | { 9 | class Program 10 | { 11 | private static Config config; 12 | 13 | [STAThread] 14 | static void Main(string[] args) 15 | { 16 | config = JsonSerializer.Deserialize(File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"config.json")); 17 | string il2cppPath = null; 18 | string metadataPath = null; 19 | string outputDir = null; 20 | 21 | if (args.Length == 1) 22 | { 23 | if (args[0] == "-h" || args[0] == "--help" || args[0] == "/?" || args[0] == "/h") 24 | { 25 | ShowHelp(); 26 | return; 27 | } 28 | } 29 | if (args.Length > 3) 30 | { 31 | ShowHelp(); 32 | return; 33 | } 34 | if (args.Length > 1) 35 | { 36 | foreach (var arg in args) 37 | { 38 | if (File.Exists(arg)) 39 | { 40 | var file = File.ReadAllBytes(arg); 41 | if (BitConverter.ToUInt32(file, 0) == 0xFAB11BAF) 42 | { 43 | metadataPath = arg; 44 | } 45 | else 46 | { 47 | il2cppPath = arg; 48 | } 49 | } 50 | else if (Directory.Exists(arg)) 51 | { 52 | outputDir = Path.GetFullPath(arg) + Path.DirectorySeparatorChar; 53 | } 54 | } 55 | } 56 | outputDir ??= AppDomain.CurrentDomain.BaseDirectory; 57 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 58 | { 59 | if (il2cppPath == null) 60 | { 61 | var ofd = new OpenFileDialog 62 | { 63 | Filter = "IL2CPP binary file|*.*" 64 | }; 65 | if (ofd.ShowDialog()) 66 | { 67 | il2cppPath = ofd.FileName; 68 | ofd.Filter = "global-metadata|global-metadata.dat"; 69 | if (ofd.ShowDialog()) 70 | { 71 | metadataPath = ofd.FileName; 72 | } 73 | else 74 | { 75 | return; 76 | } 77 | } 78 | else 79 | { 80 | return; 81 | } 82 | } 83 | } 84 | if (il2cppPath == null) 85 | { 86 | ShowHelp(); 87 | return; 88 | } 89 | if (metadataPath == null) 90 | { 91 | Console.WriteLine($"ERROR: Metadata file not found or encrypted."); 92 | } 93 | else 94 | { 95 | try 96 | { 97 | if (Init(il2cppPath, metadataPath, out var metadata, out var il2Cpp)) 98 | { 99 | Dump(metadata, il2Cpp, outputDir); 100 | } 101 | } 102 | catch (Exception e) 103 | { 104 | Console.WriteLine(e); 105 | } 106 | } 107 | if (config.RequireAnyKey) 108 | { 109 | Console.WriteLine("Press any key to exit :3"); 110 | Console.ReadKey(true); 111 | } 112 | } 113 | 114 | static void ShowHelp() 115 | { 116 | Console.WriteLine($"usage: {AppDomain.CurrentDomain.FriendlyName} "); 117 | } 118 | 119 | private static bool Init(string il2cppPath, string metadataPath, out Metadata metadata, out Il2Cpp il2Cpp) 120 | { 121 | Console.WriteLine("Initializing metadata ..."); 122 | var metadataBytes = File.ReadAllBytes(metadataPath); 123 | metadata = new Metadata(new MemoryStream(metadataBytes)); 124 | Console.WriteLine($"Metadata Version: {metadata.Version}"); 125 | 126 | Console.WriteLine("Initializing Il2Cpp file ..."); 127 | var il2cppBytes = File.ReadAllBytes(il2cppPath); 128 | var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0); 129 | var il2CppMemory = new MemoryStream(il2cppBytes); 130 | switch (il2cppMagic) 131 | { 132 | default: 133 | throw new NotSupportedException("ERROR: Il2Cpp file not supported !!"); 134 | case 0x6D736100: 135 | var web = new WebAssembly(il2CppMemory); 136 | il2Cpp = web.CreateMemory(); 137 | break; 138 | case 0x304F534E: 139 | var nso = new NSO(il2CppMemory); 140 | il2Cpp = nso.UnCompress(); 141 | break; 142 | case 0x905A4D: //PE 143 | il2Cpp = new PE(il2CppMemory); 144 | break; 145 | case 0x464c457f: //ELF 146 | if (il2cppBytes[4] == 2) //ELF64 147 | { 148 | il2Cpp = new Elf64(il2CppMemory); 149 | } 150 | else 151 | { 152 | il2Cpp = new Elf(il2CppMemory); 153 | } 154 | break; 155 | case 0xCAFEBABE: //FAT Mach-O 156 | case 0xBEBAFECA: 157 | var machofat = new MachoFat(new MemoryStream(il2cppBytes)); 158 | Console.Write("Select Platform: "); 159 | for (var i = 0; i < machofat.fats.Length; i++) 160 | { 161 | var fat = machofat.fats[i]; 162 | Console.Write(fat.magic == 0xFEEDFACF ? $"{i + 1}.64bit " : $"{i + 1}.32bit "); 163 | } 164 | Console.WriteLine(); 165 | var key = Console.ReadKey(true); 166 | var index = int.Parse(key.KeyChar.ToString()) - 1; 167 | var magic = machofat.fats[index % 2].magic; 168 | il2cppBytes = machofat.GetMacho(index % 2); 169 | il2CppMemory = new MemoryStream(il2cppBytes); 170 | if (magic == 0xFEEDFACF) 171 | goto case 0xFEEDFACF; 172 | else 173 | goto case 0xFEEDFACE; 174 | case 0xFEEDFACF: // 64bit Mach-O 175 | il2Cpp = new Macho64(il2CppMemory); 176 | break; 177 | case 0xFEEDFACE: // 32bit Mach-O 178 | il2Cpp = new Macho(il2CppMemory); 179 | break; 180 | } 181 | var version = config.ForceIl2CppVersion ? config.ForceVersion : metadata.Version; 182 | il2Cpp.SetProperties(version, metadata.metadataUsagesCount); 183 | Console.WriteLine($"Il2Cpp Version: {il2Cpp.Version}"); 184 | if (config.ForceDump || il2Cpp.CheckDump()) 185 | { 186 | if (il2Cpp is ElfBase elf) 187 | { 188 | Console.WriteLine("Detected this may be a dump file."); 189 | Console.WriteLine("Input Il2Cpp dump address or input 0 to force continue:"); 190 | var DumpAddr = Convert.ToUInt64(Console.ReadLine(), 16); 191 | if (DumpAddr != 0) 192 | { 193 | il2Cpp.ImageBase = DumpAddr; 194 | il2Cpp.IsDumped = true; 195 | if (!config.NoRedirectedPointer) 196 | { 197 | elf.Reload(); 198 | } 199 | } 200 | } 201 | else 202 | { 203 | il2Cpp.IsDumped = true; 204 | } 205 | } 206 | 207 | Console.WriteLine("Searching ..."); 208 | try 209 | { 210 | var flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length, metadata.imageDefs.Length); 211 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 212 | { 213 | if (!flag && il2Cpp is PE) 214 | { 215 | Console.WriteLine("Use custom PE loader"); 216 | il2Cpp = PELoader.Load(il2cppPath); 217 | il2Cpp.SetProperties(version, metadata.metadataUsagesCount); 218 | flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length, metadata.imageDefs.Length); 219 | } 220 | } 221 | if (!flag) 222 | { 223 | flag = il2Cpp.Search(); 224 | } 225 | if (!flag) 226 | { 227 | flag = il2Cpp.SymbolSearch(); 228 | } 229 | if (!flag) 230 | { 231 | Console.WriteLine("ERROR: Can't use auto mode to process file, try manual mode."); 232 | Console.Write("Input CodeRegistration: "); 233 | var codeRegistration = Convert.ToUInt64(Console.ReadLine(), 16); 234 | Console.Write("Input MetadataRegistration: "); 235 | var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16); 236 | il2Cpp.Init(codeRegistration, metadataRegistration); 237 | } 238 | if (il2Cpp.Version >= 27 && il2Cpp.IsDumped) 239 | { 240 | var typeDef = metadata.typeDefs[0]; 241 | var il2CppType = il2Cpp.types[typeDef.byvalTypeIndex]; 242 | metadata.ImageBase = il2CppType.data.typeHandle - metadata.header.typeDefinitionsOffset; 243 | } 244 | } 245 | catch (Exception e) 246 | { 247 | Console.WriteLine(e); 248 | Console.WriteLine("ERROR: An error occurred while processing !!"); 249 | return false; 250 | } 251 | return true; 252 | } 253 | 254 | private static void Dump(Metadata metadata, Il2Cpp il2Cpp, string outputDir) 255 | { 256 | Console.WriteLine("Dumping ..."); 257 | var executor = new Il2CppExecutor(metadata, il2Cpp); 258 | var decompiler = new Il2CppDecompiler(executor); 259 | decompiler.Decompile(config, outputDir); 260 | Console.WriteLine("Done ;3"); 261 | if (config.GenerateStruct) 262 | { 263 | Console.WriteLine("Generating struct ..."); 264 | var scriptGenerator = new StructGenerator(executor); 265 | scriptGenerator.WriteScript(outputDir); 266 | Console.WriteLine("Done ;3"); 267 | } 268 | if (config.GenerateDummyDll) 269 | { 270 | Console.WriteLine("Generating dummy dll ..."); 271 | DummyAssemblyExporter.Export(executor, outputDir, config.DummyDllAddToken); 272 | Console.WriteLine("Done ;3"); 273 | } 274 | } 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | when the dump is sus ! 2 | -------------------------------------------------------------------------------- /Resource1.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Il codice è stato generato da uno strumento. 4 | // Versione runtime:4.0.30319.42000 5 | // 6 | // Le modifiche apportate a questo file possono provocare un comportamento non corretto e andranno perse se 7 | // il codice viene rigenerato. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace deer2cpp { 12 | using System; 13 | 14 | 15 | /// 16 | /// Classe di risorse fortemente tipizzata per la ricerca di stringhe localizzate e così via. 17 | /// 18 | // Questa classe è stata generata automaticamente dalla classe StronglyTypedResourceBuilder. 19 | // tramite uno strumento quale ResGen o Visual Studio. 20 | // Per aggiungere o rimuovere un membro, modificare il file con estensione ResX ed eseguire nuovamente ResGen 21 | // con l'opzione /str oppure ricompilare il progetto VS. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resource1 { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resource1() { 33 | } 34 | 35 | /// 36 | /// Restituisce l'istanza di ResourceManager nella cache utilizzata da questa classe. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("deer2cpp.Resource1", typeof(Resource1).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Esegue l'override della proprietà CurrentUICulture del thread corrente per tutte le 51 | /// ricerche di risorse eseguite utilizzando questa classe di risorse fortemente tipizzata. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Cerca una risorsa localizzata di tipo System.Byte[]. 65 | /// 66 | internal static byte[] Il2CppDummyDll { 67 | get { 68 | object obj = ResourceManager.GetObject("Il2CppDummyDll", resourceCulture); 69 | return ((byte[])(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Resource1.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | Libraries\Il2CppDummyDll.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 123 | 124 | -------------------------------------------------------------------------------- /Utils/ArmUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Il2CppDumper 4 | { 5 | static class ArmUtils 6 | { 7 | public static uint DecodeMov(byte[] asm) 8 | { 9 | var low = (ushort)(asm[2] + ((asm[3] & 0x70) << 4) + ((asm[1] & 0x04) << 9) + ((asm[0] & 0x0f) << 12)); 10 | var high = (ushort)(asm[6] + ((asm[7] & 0x70) << 4) + ((asm[5] & 0x04) << 9) + ((asm[4] & 0x0f) << 12)); 11 | return (uint)((high << 16) + low); 12 | } 13 | 14 | public static ulong DecodeAdr(ulong pc, byte[] inst) 15 | { 16 | var bin = inst.HexToBin(); 17 | var uint64 = string.Concat(bin.AsSpan(8, 19), bin.AsSpan(1, 2)); 18 | uint64 = uint64.PadLeft(64, uint64[0]); 19 | return pc + Convert.ToUInt64(uint64, 2); 20 | } 21 | 22 | public static ulong DecodeAdrp(ulong pc, byte[] inst) 23 | { 24 | pc &= 0xFFFFFFFFFFFFF000; 25 | var bin = inst.HexToBin(); 26 | var uint64 = string.Concat(bin.AsSpan(8, 19), bin.AsSpan(1, 2), new string('0', 12)); 27 | uint64 = uint64.PadLeft(64, uint64[0]); 28 | return pc + Convert.ToUInt64(uint64, 2); 29 | } 30 | 31 | public static ulong DecodeAdd(byte[] inst) 32 | { 33 | var bin = inst.HexToBin(); 34 | var uint64 = Convert.ToUInt64(bin.Substring(10, 12), 2); 35 | if (bin[9] == '1') 36 | uint64 <<= 12; 37 | return uint64; 38 | } 39 | 40 | public static bool IsAdr(byte[] inst) 41 | { 42 | var bin = inst.HexToBin(); 43 | return bin[0] == '0' && bin.Substring(3, 5) == "10000"; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Utils/AttributeArgument.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public class AttributeArgument 4 | { 5 | public BlobValue Value; 6 | public int Index; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Utils/BlobValue.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public class BlobValue 4 | { 5 | public object Value; 6 | public Il2CppTypeEnum il2CppTypeEnum; 7 | public Il2CppType EnumType; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Utils/CustomAttributeDataReader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace Il2CppDumper 5 | { 6 | public class CustomAttributeDataReader : BinaryReader 7 | { 8 | private readonly Il2CppExecutor executor; 9 | private readonly Metadata metadata; 10 | private long ctorBuffer; 11 | private long dataBuffer; 12 | 13 | public uint Count { get; set; } 14 | 15 | public CustomAttributeDataReader(Il2CppExecutor executor, byte[] buff) : base(new MemoryStream(buff)) 16 | { 17 | this.executor = executor; 18 | metadata = executor.metadata; 19 | Count = this.ReadCompressedUInt32(); 20 | ctorBuffer = BaseStream.Position; 21 | dataBuffer = BaseStream.Position + Count * 4; 22 | } 23 | 24 | public string GetStringCustomAttributeData() 25 | { 26 | BaseStream.Position = ctorBuffer; 27 | var ctorIndex = ReadInt32(); 28 | var methodDef = metadata.methodDefs[ctorIndex]; 29 | var typeDef = metadata.typeDefs[methodDef.declaringType]; 30 | ctorBuffer = BaseStream.Position; 31 | 32 | BaseStream.Position = dataBuffer; 33 | var argumentCount = this.ReadCompressedUInt32(); 34 | var fieldCount = this.ReadCompressedUInt32(); 35 | var propertyCount = this.ReadCompressedUInt32(); 36 | 37 | var argList = new List(); 38 | 39 | for (var i = 0; i < argumentCount; i++) 40 | { 41 | argList.Add($"{AttributeDataToString(ReadAttributeDataValue())}"); 42 | } 43 | for (var i = 0; i < fieldCount; i++) 44 | { 45 | var str = AttributeDataToString(ReadAttributeDataValue()); 46 | (var declaring, var fieldIndex) = ReadCustomAttributeNamedArgumentClassAndIndex(typeDef); 47 | var fieldDef = metadata.fieldDefs[declaring.fieldStart + fieldIndex]; 48 | argList.Add($"{metadata.GetStringFromIndex(fieldDef.nameIndex)} = {str}"); 49 | } 50 | for (var i = 0; i < propertyCount; i++) 51 | { 52 | var str = AttributeDataToString(ReadAttributeDataValue()); 53 | (var declaring, var propertyIndex) = ReadCustomAttributeNamedArgumentClassAndIndex(typeDef); 54 | var propertyDef = metadata.propertyDefs[declaring.propertyStart + propertyIndex]; 55 | argList.Add($"{metadata.GetStringFromIndex(propertyDef.nameIndex)} = {str}"); 56 | } 57 | dataBuffer = BaseStream.Position; 58 | 59 | 60 | var typeName = metadata.GetStringFromIndex(typeDef.nameIndex).Replace("Attribute", ""); 61 | if (argList.Count > 0) 62 | { 63 | return $"[{typeName}({string.Join(", ", argList)})]"; 64 | } 65 | else 66 | { 67 | return $"[{typeName}]"; 68 | } 69 | } 70 | 71 | private string AttributeDataToString(BlobValue blobValue) 72 | { 73 | //TODO enum 74 | if (blobValue.Value == null) 75 | { 76 | return "null"; 77 | } 78 | switch (blobValue.il2CppTypeEnum) 79 | { 80 | case Il2CppTypeEnum.IL2CPP_TYPE_STRING: 81 | return $"\"{blobValue.Value}\""; 82 | case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: 83 | var array = (BlobValue[])blobValue.Value; 84 | var list = new List(); 85 | foreach (var item in array) 86 | { 87 | list.Add(AttributeDataToString(item)); 88 | } 89 | return $"new[] {{ {string.Join(", ", list)} }}"; 90 | case Il2CppTypeEnum.IL2CPP_TYPE_IL2CPP_TYPE_INDEX: 91 | var il2CppType = (Il2CppType)blobValue.Value; 92 | return $"typeof({executor.GetType()})"; 93 | default: 94 | return blobValue.Value.ToString(); 95 | } 96 | } 97 | 98 | public CustomAttributeReaderVisitor VisitCustomAttributeData() 99 | { 100 | var visitor = new CustomAttributeReaderVisitor(); 101 | 102 | BaseStream.Position = ctorBuffer; 103 | var ctorIndex = ReadInt32(); 104 | visitor.CtorIndex = ctorIndex; 105 | var methodDef = metadata.methodDefs[ctorIndex]; 106 | var typeDef = metadata.typeDefs[methodDef.declaringType]; 107 | ctorBuffer = BaseStream.Position; 108 | 109 | BaseStream.Position = dataBuffer; 110 | var argumentCount = this.ReadCompressedUInt32(); 111 | var fieldCount = this.ReadCompressedUInt32(); 112 | var propertyCount = this.ReadCompressedUInt32(); 113 | 114 | visitor.Arguments = new AttributeArgument[argumentCount]; 115 | for (var i = 0; i < argumentCount; i++) 116 | { 117 | var argument = visitor.Arguments[i] = new AttributeArgument(); 118 | argument.Value = ReadAttributeDataValue(); 119 | argument.Index = i; 120 | } 121 | visitor.Fields = new AttributeArgument[fieldCount]; 122 | for (var i = 0; i < fieldCount; i++) 123 | { 124 | var field = visitor.Fields[i] = new AttributeArgument(); 125 | field.Value = ReadAttributeDataValue(); 126 | (var declaring, var fieldIndex) = ReadCustomAttributeNamedArgumentClassAndIndex(typeDef); 127 | field.Index = declaring.fieldStart + fieldIndex; 128 | } 129 | visitor.Properties = new AttributeArgument[propertyCount]; 130 | for (var i = 0; i < propertyCount; i++) 131 | { 132 | var property = visitor.Properties[i] = new AttributeArgument(); 133 | property.Value = ReadAttributeDataValue(); 134 | (var declaring, var propertyIndex) = ReadCustomAttributeNamedArgumentClassAndIndex(typeDef); 135 | property.Index = declaring.propertyStart + propertyIndex; 136 | } 137 | 138 | dataBuffer = BaseStream.Position; 139 | return visitor; 140 | } 141 | 142 | private BlobValue ReadAttributeDataValue() 143 | { 144 | // Ensure you are calling GetTypeDefinitionFromIl2CppType correctly with the necessary parameters 145 | var type = executor.GetType(); // Replace `someType` with the correct argument for your use case 146 | 147 | // You may also want to use GetType, but make sure it is necessary 148 | var typeInfo = executor.GetType(); // If GetType is necessary, you should use it properly (e.g., to retrieve type information) 149 | 150 | if (type != null) 151 | { 152 | var ok = new BlobValue(); 153 | return ok; // Return the BlobValue object if the type is valid 154 | } 155 | 156 | // Handle the case where type is null (if needed) 157 | // You might want to return null, throw an exception, or handle it differently 158 | return null; // Adjust based on how you want to handle null types 159 | } 160 | 161 | 162 | private (Il2CppTypeDefinition, int) ReadCustomAttributeNamedArgumentClassAndIndex(Il2CppTypeDefinition typeDef) 163 | { 164 | var memberIndex = this.ReadCompressedInt32(); 165 | if (memberIndex >= 0) 166 | { 167 | return (typeDef, memberIndex); 168 | } 169 | memberIndex = -(memberIndex + 1); 170 | 171 | var typeIndex = this.ReadCompressedUInt32(); 172 | var declaringClass = metadata.typeDefs[typeIndex]; 173 | 174 | return (declaringClass, memberIndex); 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /Utils/CustomAttributeReaderVisitor.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public class CustomAttributeReaderVisitor 4 | { 5 | public int CtorIndex; 6 | public AttributeArgument[] Arguments; 7 | public AttributeArgument[] Fields; 8 | public AttributeArgument[] Properties; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Utils/FileDialogNative.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Il2CppDumper 5 | { 6 | static class FileDialogNative 7 | { 8 | [ComImport] 9 | [ClassInterface(ClassInterfaceType.None)] 10 | [TypeLibType(TypeLibTypeFlags.FCanCreate)] 11 | [Guid(CLSIDGuid.FileOpenDialog)] 12 | internal class FileOpenDialogRCW 13 | { } 14 | 15 | internal class IIDGuid 16 | { 17 | private IIDGuid() { } // Avoid FxCop violation AvoidUninstantiatedInternalClasses 18 | // IID GUID strings for relevant COM interfaces 19 | internal const string IModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802"; 20 | internal const string IFileDialog = "42f85136-db7e-439c-85f1-e4075d135fc8"; 21 | internal const string IFileOpenDialog = "d57c7288-d4ad-4768-be02-9d969532d960"; 22 | internal const string IFileSaveDialog = "84bccd23-5fde-4cdb-aea4-af64b83d78ab"; 23 | internal const string IFileDialogEvents = "973510DB-7D7F-452B-8975-74A85828D354"; 24 | internal const string IShellItem = "43826D1E-E718-42EE-BC55-A1E261C37BFE"; 25 | internal const string IShellItemArray = "B63EA76D-1F85-456F-A19C-48159EFA858B"; 26 | } 27 | 28 | internal class CLSIDGuid 29 | { 30 | private CLSIDGuid() { } // Avoid FxCop violation AvoidUninstantiatedInternalClasses 31 | internal const string FileOpenDialog = "DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7"; 32 | internal const string FileSaveDialog = "C0B4E2F3-BA21-4773-8DBA-335EC946EB8B"; 33 | } 34 | 35 | [ComImport()] 36 | [Guid(IIDGuid.IFileDialog)] 37 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 38 | internal interface IFileDialog 39 | { 40 | [PreserveSig] 41 | int Show([In] IntPtr parent); 42 | 43 | void SetFileTypes([In] uint cFileTypes, [In][MarshalAs(UnmanagedType.LPArray)] COMDLG_FILTERSPEC[] rgFilterSpec); 44 | 45 | void SetFileTypeIndex([In] uint iFileType); 46 | 47 | void GetFileTypeIndex(out uint piFileType); 48 | 49 | void Advise([In, MarshalAs(UnmanagedType.Interface)] IFileDialogEvents pfde, out uint pdwCookie); 50 | 51 | void Unadvise([In] uint dwCookie); 52 | 53 | void SetOptions([In] FOS fos); 54 | 55 | void GetOptions(out FOS pfos); 56 | 57 | void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); 58 | 59 | void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); 60 | 61 | void GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); 62 | 63 | void GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); 64 | 65 | void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName); 66 | 67 | void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); 68 | 69 | void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle); 70 | 71 | void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText); 72 | 73 | void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel); 74 | 75 | void GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); 76 | 77 | void AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, int alignment); 78 | 79 | void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); 80 | 81 | void Close([MarshalAs(UnmanagedType.Error)] int hr); 82 | 83 | void SetClientGuid([In] ref Guid guid); 84 | 85 | void ClearClientData(); 86 | 87 | void SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter); 88 | } 89 | 90 | [ComImport, 91 | Guid(IIDGuid.IFileDialogEvents), 92 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 93 | internal interface IFileDialogEvents 94 | { 95 | // NOTE: some of these callbacks are cancelable - returning S_FALSE means that 96 | // the dialog should not proceed (e.g. with closing, changing folder); to 97 | // support this, we need to use the PreserveSig attribute to enable us to return 98 | // the proper HRESULT 99 | [PreserveSig] 100 | int OnFileOk([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); 101 | 102 | [PreserveSig] 103 | int OnFolderChanging([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psiFolder); 104 | 105 | void OnFolderChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); 106 | 107 | void OnSelectionChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); 108 | 109 | void OnShareViolation([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, out FDE_SHAREVIOLATION_RESPONSE pResponse); 110 | 111 | void OnTypeChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); 112 | 113 | void OnOverwrite([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, out FDE_OVERWRITE_RESPONSE pResponse); 114 | } 115 | 116 | [ComImport, 117 | Guid(IIDGuid.IShellItem), 118 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 119 | internal interface IShellItem 120 | { 121 | void BindToHandler([In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, [In] ref Guid bhid, [In] ref Guid riid, out IntPtr ppv); 122 | 123 | void GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); 124 | 125 | void GetDisplayName([In] SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName); 126 | 127 | void GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs); 128 | 129 | void Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder); 130 | } 131 | 132 | internal enum SIGDN : uint 133 | { 134 | SIGDN_NORMALDISPLAY = 0x00000000, // SHGDN_NORMAL 135 | SIGDN_PARENTRELATIVEPARSING = 0x80018001, // SHGDN_INFOLDER | SHGDN_FORPARSING 136 | SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000, // SHGDN_FORPARSING 137 | SIGDN_PARENTRELATIVEEDITING = 0x80031001, // SHGDN_INFOLDER | SHGDN_FOREDITING 138 | SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, // SHGDN_FORPARSING | SHGDN_FORADDRESSBAR 139 | SIGDN_FILESYSPATH = 0x80058000, // SHGDN_FORPARSING 140 | SIGDN_URL = 0x80068000, // SHGDN_FORPARSING 141 | SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001, // SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR 142 | SIGDN_PARENTRELATIVE = 0x80080001 // SHGDN_INFOLDER 143 | } 144 | 145 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] 146 | internal struct COMDLG_FILTERSPEC 147 | { 148 | [MarshalAs(UnmanagedType.LPWStr)] 149 | internal string pszName; 150 | [MarshalAs(UnmanagedType.LPWStr)] 151 | internal string pszSpec; 152 | } 153 | 154 | [Flags] 155 | internal enum FOS : uint 156 | { 157 | FOS_OVERWRITEPROMPT = 0x00000002, 158 | FOS_STRICTFILETYPES = 0x00000004, 159 | FOS_NOCHANGEDIR = 0x00000008, 160 | FOS_PICKFOLDERS = 0x00000020, 161 | FOS_FORCEFILESYSTEM = 0x00000040, // Ensure that items returned are filesystem items. 162 | FOS_ALLNONSTORAGEITEMS = 0x00000080, // Allow choosing items that have no storage. 163 | FOS_NOVALIDATE = 0x00000100, 164 | FOS_ALLOWMULTISELECT = 0x00000200, 165 | FOS_PATHMUSTEXIST = 0x00000800, 166 | FOS_FILEMUSTEXIST = 0x00001000, 167 | FOS_CREATEPROMPT = 0x00002000, 168 | FOS_SHAREAWARE = 0x00004000, 169 | FOS_NOREADONLYRETURN = 0x00008000, 170 | FOS_NOTESTFILECREATE = 0x00010000, 171 | FOS_HIDEMRUPLACES = 0x00020000, 172 | FOS_HIDEPINNEDPLACES = 0x00040000, 173 | FOS_NODEREFERENCELINKS = 0x00100000, 174 | FOS_DONTADDTORECENT = 0x02000000, 175 | FOS_FORCESHOWHIDDEN = 0x10000000, 176 | FOS_DEFAULTNOMINIMODE = 0x20000000 177 | } 178 | 179 | internal enum FDE_SHAREVIOLATION_RESPONSE 180 | { 181 | FDESVR_DEFAULT = 0x00000000, 182 | FDESVR_ACCEPT = 0x00000001, 183 | FDESVR_REFUSE = 0x00000002 184 | } 185 | 186 | internal enum FDE_OVERWRITE_RESPONSE 187 | { 188 | FDEOR_DEFAULT = 0x00000000, 189 | FDEOR_ACCEPT = 0x00000001, 190 | FDEOR_REFUSE = 0x00000002 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /Utils/Il2CppExecutor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Il2CppDumper 8 | { 9 | public class Il2CppExecutor 10 | { 11 | public Metadata metadata; 12 | public Il2Cpp il2Cpp; 13 | private static readonly Dictionary TypeString = new() 14 | { 15 | {1,"void"}, 16 | {2,"bool"}, 17 | {3,"char"}, 18 | {4,"sbyte"}, 19 | {5,"byte"}, 20 | {6,"short"}, 21 | {7,"ushort"}, 22 | {8,"int"}, 23 | {9,"uint"}, 24 | {10,"long"}, 25 | {11,"ulong"}, 26 | {12,"float"}, 27 | {13,"double"}, 28 | {14,"string"}, 29 | {22,"TypedReference"}, 30 | {24,"IntPtr"}, 31 | {25,"UIntPtr"}, 32 | {28,"object"}, 33 | }; 34 | public ulong[] customAttributeGenerators; 35 | 36 | public Il2CppExecutor(Metadata metadata, Il2Cpp il2Cpp) 37 | { 38 | this.metadata = metadata; 39 | this.il2Cpp = il2Cpp; 40 | 41 | if (il2Cpp.Version >= 27 && il2Cpp.Version < 30) // Adjust for Unity 6 (2025) 42 | { 43 | customAttributeGenerators = new ulong[metadata.imageDefs.Sum(x => x.customAttributeCount)]; 44 | foreach (var imageDef in metadata.imageDefs) 45 | { 46 | var imageDefName = metadata.GetStringFromIndex(imageDef.nameIndex); 47 | var codeGenModule = il2Cpp.codeGenModules[imageDefName]; 48 | if (imageDef.customAttributeCount > 0) 49 | { 50 | var pointers = il2Cpp.ReadClassArray(il2Cpp.MapVATR(codeGenModule.customAttributeCacheGenerator), imageDef.customAttributeCount); 51 | pointers.CopyTo(customAttributeGenerators, imageDef.customAttributeStart); 52 | } 53 | } 54 | } 55 | else if (il2Cpp.Version < 27) 56 | { 57 | customAttributeGenerators = il2Cpp.customAttributeGenerators; 58 | } 59 | } 60 | 61 | public Il2CppTypeDefinition GetTypeDefinitionFromIl2CppType(Il2CppType il2CppType) 62 | { 63 | if (il2Cpp.Version >= 30 && il2Cpp.IsDumped) // Unity 6 adjustment 64 | { 65 | var offset = il2CppType.data.typeHandle - metadata.ImageBase - metadata.header.typeDefinitionsOffset; 66 | var index = offset / (ulong)metadata.SizeOf(typeof(Il2CppTypeDefinition)); 67 | return metadata.typeDefs[index]; 68 | } 69 | else 70 | { 71 | return metadata.typeDefs[il2CppType.data.klassIndex]; 72 | } 73 | } 74 | 75 | public Il2CppGenericParameter GetGenericParameteFromIl2CppType(Il2CppType il2CppType) 76 | { 77 | if (il2Cpp.Version >= 30 && il2Cpp.IsDumped) // Unity 6 adjustment 78 | { 79 | var offset = il2CppType.data.genericParameterHandle - metadata.ImageBase - metadata.header.genericParametersOffset; 80 | var index = offset / (ulong)metadata.SizeOf(typeof(Il2CppGenericParameter)); 81 | return metadata.genericParameters[index]; 82 | } 83 | else 84 | { 85 | return metadata.genericParameters[il2CppType.data.genericParameterIndex]; 86 | } 87 | } 88 | 89 | internal bool TryGetDefaultValue(int typeIndex, int dataIndex, out object value) 90 | { 91 | throw new NotImplementedException(); 92 | } 93 | 94 | internal Il2CppTypeDefinition GetGenericClassTypeDefinition(Il2CppGenericClass genericClass) 95 | { 96 | throw new NotImplementedException(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Utils/MyAssemblyResolver.cs: -------------------------------------------------------------------------------- 1 | using Mono.Cecil; 2 | 3 | namespace Il2CppDumper 4 | { 5 | public class MyAssemblyResolver : DefaultAssemblyResolver 6 | { 7 | public void Register(AssemblyDefinition assembly) 8 | { 9 | RegisterAssembly(assembly); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Utils/OpenFileDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using static Il2CppDumper.FileDialogNative; 3 | 4 | namespace Il2CppDumper 5 | { 6 | public class OpenFileDialog 7 | { 8 | public string Title { get; set; } 9 | public string Filter { get; set; } 10 | public string FileName { get; set; } 11 | 12 | public bool ShowDialog() 13 | { 14 | var dialog = (IFileDialog)(new FileOpenDialogRCW()); 15 | dialog.GetOptions(out var options); 16 | options |= FOS.FOS_FORCEFILESYSTEM | FOS.FOS_NOVALIDATE | FOS.FOS_DONTADDTORECENT; 17 | dialog.SetOptions(options); 18 | if (!string.IsNullOrEmpty(Title)) 19 | { 20 | dialog.SetTitle(Title); 21 | } 22 | if (!string.IsNullOrEmpty(Filter)) 23 | { 24 | string[] filterElements = Filter.Split(new char[] { '|' }); 25 | COMDLG_FILTERSPEC[] filter = new COMDLG_FILTERSPEC[filterElements.Length / 2]; 26 | for (int x = 0; x < filterElements.Length; x += 2) 27 | { 28 | filter[x / 2].pszName = filterElements[x]; 29 | filter[x / 2].pszSpec = filterElements[x + 1]; 30 | } 31 | dialog.SetFileTypes((uint)filter.Length, filter); 32 | } 33 | if (dialog.Show(IntPtr.Zero) == 0) 34 | { 35 | dialog.GetResult(out var shellItem); 36 | shellItem.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var ppszName); 37 | FileName = ppszName; 38 | return true; 39 | } 40 | else 41 | { 42 | return false; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Utils/PELoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.IO; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace Il2CppDumper 8 | { 9 | public class PELoader 10 | { 11 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 12 | private extern static IntPtr LoadLibrary(string path); 13 | 14 | public static PE Load(string fileName) 15 | { 16 | var buff = File.ReadAllBytes(fileName); 17 | using var reader = new BinaryStream(new MemoryStream(buff)); 18 | var dosHeader = reader.ReadClass(); 19 | if (dosHeader.Magic != 0x5A4D) 20 | { 21 | throw new InvalidDataException("ERROR: Invalid PE file"); 22 | } 23 | reader.Position = dosHeader.Lfanew; 24 | if (reader.ReadUInt32() != 0x4550u) //Signature 25 | { 26 | throw new InvalidDataException("ERROR: Invalid PE file"); 27 | } 28 | var fileHeader = reader.ReadClass(); 29 | if (fileHeader.Machine == 0x14c && Environment.Is64BitProcess) //64bit process can't load 32bit dll 30 | { 31 | throw new InvalidOperationException("The file is a 32-bit file, please try to load it with Il2CppDumper-x86.exe"); 32 | } 33 | if (fileHeader.Machine == 0x8664 && !Environment.Is64BitProcess) //32bit process can't load 64bit dll 34 | { 35 | throw new InvalidOperationException("The file is a 64-bit file, please try to load it with Il2CppDumper.exe"); 36 | } 37 | var pos = reader.Position; 38 | reader.Position = pos + fileHeader.SizeOfOptionalHeader; 39 | var sections = reader.ReadClassArray(fileHeader.NumberOfSections); 40 | var last = sections[^1]; 41 | var size = last.VirtualAddress + last.VirtualSize; 42 | var peBuff = new byte[size]; 43 | var handle = LoadLibrary(fileName); 44 | if (handle == IntPtr.Zero) 45 | { 46 | throw new Win32Exception(Marshal.GetLastWin32Error()); 47 | } 48 | foreach (var section in sections) 49 | { 50 | switch (section.Characteristics) 51 | { 52 | case 0x60000020: 53 | case 0x40000040: 54 | case 0xC0000040: 55 | Marshal.Copy(new IntPtr(handle.ToInt64() + section.VirtualAddress), peBuff, (int)section.VirtualAddress, (int)section.VirtualSize); 56 | break; 57 | } 58 | } 59 | var peMemory = new MemoryStream(peBuff); 60 | var writer = new BinaryWriter(peMemory, Encoding.UTF8, true); 61 | var headerSize = reader.Position; 62 | reader.Position = 0; 63 | var buff2 = reader.ReadBytes((int)headerSize); 64 | writer.Write(buff2); 65 | writer.Flush(); 66 | writer.Close(); 67 | peMemory.Position = 0; 68 | var pe = new PE(peMemory); 69 | pe.LoadFromMemory((ulong)handle.ToInt64()); 70 | return pe; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Utils/SearchSection.cs: -------------------------------------------------------------------------------- 1 | namespace Il2CppDumper 2 | { 3 | public enum SearchSectionType 4 | { 5 | Exec, 6 | Data, 7 | Bss 8 | } 9 | 10 | public class SearchSection 11 | { 12 | public ulong offset; 13 | public ulong offsetEnd; 14 | public ulong address; 15 | public ulong addressEnd; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "DumpMethod": true, 3 | "DumpField": true, 4 | "DumpProperty": true, 5 | "DumpAttribute": true, 6 | "DumpFieldOffset": true, 7 | "DumpMethodOffset": true, 8 | "DumpTypeDefIndex": true, 9 | "GenerateDummyDll": true, 10 | "GenerateStruct": true, 11 | "DummyDllAddToken": true, 12 | "RequireAnyKey": true, 13 | "ForceIl2CppVersion": false, 14 | "ForceVersion": 16, 15 | "ForceDump": false, 16 | "NoRedirectedPointer": false 17 | } -------------------------------------------------------------------------------- /deer2cpp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net6.0;net8.0 6 | 1.0.0.0 7 | 1.0.0.0 8 | 1.0.0.0 9 | Copyright © Perfare 2016-2024 10 | embedded 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | True 21 | True 22 | Resource1.resx 23 | 24 | 25 | 26 | 27 | 28 | ResXFileCodeGenerator 29 | Resource1.Designer.cs 30 | 31 | 32 | 33 | 34 | 35 | PreserveNewest 36 | 37 | 38 | PreserveNewest 39 | 40 | 41 | PreserveNewest 42 | 43 | 44 | PreserveNewest 45 | 46 | 47 | PreserveNewest 48 | 49 | 50 | PreserveNewest 51 | 52 | 53 | PreserveNewest 54 | 55 | 56 | PreserveNewest 57 | 58 | 59 | PreserveNewest 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /ghidra.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | processFields = [ 5 | "ScriptMethod", 6 | "ScriptString", 7 | "ScriptMetadata", 8 | "ScriptMetadataMethod", 9 | "Addresses", 10 | ] 11 | 12 | functionManager = currentProgram.getFunctionManager() 13 | baseAddress = currentProgram.getImageBase() 14 | USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED 15 | 16 | def get_addr(addr): 17 | return baseAddress.add(addr) 18 | 19 | def set_name(addr, name): 20 | name = name.replace(' ', '-') 21 | createLabel(addr, name, True, USER_DEFINED) 22 | 23 | def make_function(start): 24 | func = getFunctionAt(start) 25 | if func is None: 26 | createFunction(start, None) 27 | 28 | f = askFile("script.json from deer2cpp", "Open") 29 | data = json.loads(open(f.absolutePath, 'rb').read().decode('utf-8')) 30 | 31 | if "ScriptMethod" in data and "ScriptMethod" in processFields: 32 | scriptMethods = data["ScriptMethod"] 33 | monitor.initialize(len(scriptMethods)) 34 | monitor.setMessage("Methods") 35 | for scriptMethod in scriptMethods: 36 | addr = get_addr(scriptMethod["Address"]) 37 | name = scriptMethod["Name"].encode("utf-8") 38 | set_name(addr, name) 39 | monitor.incrementProgress(1) 40 | 41 | if "ScriptString" in data and "ScriptString" in processFields: 42 | index = 1 43 | scriptStrings = data["ScriptString"] 44 | monitor.initialize(len(scriptStrings)) 45 | monitor.setMessage("Strings") 46 | for scriptString in scriptStrings: 47 | addr = get_addr(scriptString["Address"]) 48 | value = scriptString["Value"].encode("utf-8") 49 | name = "StringLiteral_" + str(index) 50 | createLabel(addr, name, True, USER_DEFINED) 51 | setEOLComment(addr, value) 52 | index += 1 53 | monitor.incrementProgress(1) 54 | 55 | if "ScriptMetadata" in data and "ScriptMetadata" in processFields: 56 | scriptMetadatas = data["ScriptMetadata"] 57 | monitor.initialize(len(scriptMetadatas)) 58 | monitor.setMessage("Metadata") 59 | for scriptMetadata in scriptMetadatas: 60 | addr = get_addr(scriptMetadata["Address"]) 61 | name = scriptMetadata["Name"].encode("utf-8") 62 | set_name(addr, name) 63 | setEOLComment(addr, name) 64 | monitor.incrementProgress(1) 65 | 66 | if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: 67 | scriptMetadataMethods = data["ScriptMetadataMethod"] 68 | monitor.initialize(len(scriptMetadataMethods)) 69 | monitor.setMessage("Metadata Methods") 70 | for scriptMetadataMethod in scriptMetadataMethods: 71 | addr = get_addr(scriptMetadataMethod["Address"]) 72 | name = scriptMetadataMethod["Name"].encode("utf-8") 73 | methodAddr = get_addr(scriptMetadataMethod["MethodAddress"]) 74 | set_name(addr, name) 75 | setEOLComment(addr, name) 76 | monitor.incrementProgress(1) 77 | 78 | if "Addresses" in data and "Addresses" in processFields: 79 | addresses = data["Addresses"] 80 | monitor.initialize(len(addresses)) 81 | monitor.setMessage("Addresses") 82 | for index in range(len(addresses) - 1): 83 | start = get_addr(addresses[index]) 84 | make_function(start) 85 | monitor.incrementProgress(1) 86 | 87 | print 'Script finished!' 88 | -------------------------------------------------------------------------------- /ghidra_wasm.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | from wasm import WasmLoader 5 | from wasm.analysis import WasmAnalysis 6 | from ghidra.util.task import ConsoleTaskMonitor 7 | 8 | monitor = ConsoleTaskMonitor() 9 | WasmLoader.loadElementsToTable(currentProgram, WasmAnalysis.getState(currentProgram).module, 0, 0, 0, monitor) 10 | 11 | runScript("analyze_dyncalls.py") 12 | 13 | processFields = [ 14 | "ScriptMethod", 15 | "ScriptString", 16 | "ScriptMetadata", 17 | "ScriptMetadataMethod", 18 | "Addresses", 19 | ] 20 | 21 | functionManager = currentProgram.getFunctionManager() 22 | progspace = currentProgram.addressFactory.getAddressSpace("ram") 23 | USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED 24 | 25 | def get_addr(addr): 26 | return progspace.getAddress(addr) 27 | 28 | def set_name(addr, name): 29 | name = name.replace(' ', '-') 30 | createLabel(addr, name, True, USER_DEFINED) 31 | 32 | def make_function(start): 33 | func = getFunctionAt(start) 34 | if func is None: 35 | createFunction(start, None) 36 | 37 | f = askFile("script.json from deer2cpp", "Open") 38 | data = json.loads(open(f.absolutePath, 'rb').read().decode('utf-8')) 39 | 40 | 41 | if "ScriptMethod" in data and "ScriptMethod" in processFields: 42 | scriptMethods = data["ScriptMethod"] 43 | dynCallNamespace = currentProgram.symbolTable.getNamespace("dynCall", None) 44 | monitor.initialize(len(scriptMethods)) 45 | monitor.setMessage("Methods") 46 | for scriptMethod in scriptMethods: 47 | offset = scriptMethod["Address"] 48 | sig = scriptMethod["TypeSignature"] 49 | symbolName = "func_%s_%d" % (sig, offset) 50 | symbol = currentProgram.symbolTable.getSymbols(symbolName, dynCallNamespace) 51 | if len(symbol) > 0: 52 | addr = symbol[0].address 53 | name = scriptMethod["Name"].encode("utf-8") 54 | set_name(addr, name) 55 | else: 56 | print "Warning at %s:" % scriptMethod["Name"] 57 | print "Symbol %s not found!" % symbolName 58 | monitor.incrementProgress(1) 59 | 60 | if "ScriptString" in data and "ScriptString" in processFields: 61 | index = 1 62 | scriptStrings = data["ScriptString"] 63 | monitor.initialize(len(scriptStrings)) 64 | monitor.setMessage("Strings") 65 | for scriptString in scriptStrings: 66 | addr = get_addr(scriptString["Address"]) 67 | value = scriptString["Value"].encode("utf-8") 68 | name = "StringLiteral_" + str(index) 69 | createLabel(addr, name, True, USER_DEFINED) 70 | setEOLComment(addr, value) 71 | index += 1 72 | monitor.incrementProgress(1) 73 | 74 | if "ScriptMetadata" in data and "ScriptMetadata" in processFields: 75 | scriptMetadatas = data["ScriptMetadata"] 76 | monitor.initialize(len(scriptMetadatas)) 77 | monitor.setMessage("Metadata") 78 | for scriptMetadata in scriptMetadatas: 79 | addr = get_addr(scriptMetadata["Address"]) 80 | name = scriptMetadata["Name"].encode("utf-8") 81 | set_name(addr, name) 82 | setEOLComment(addr, name) 83 | monitor.incrementProgress(1) 84 | 85 | if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: 86 | scriptMetadataMethods = data["ScriptMetadataMethod"] 87 | monitor.initialize(len(scriptMetadataMethods)) 88 | monitor.setMessage("Metadata Methods") 89 | for scriptMetadataMethod in scriptMetadataMethods: 90 | addr = get_addr(scriptMetadataMethod["Address"]) 91 | name = scriptMetadataMethod["Name"].encode("utf-8") 92 | methodAddr = get_addr(scriptMetadataMethod["MethodAddress"]) 93 | set_name(addr, name) 94 | setEOLComment(addr, name) 95 | monitor.incrementProgress(1) 96 | 97 | if "Addresses" in data and "Addresses" in processFields: 98 | pass 99 | 100 | print 'Script finished!' 101 | -------------------------------------------------------------------------------- /ghidra_with_struct.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | from ghidra.app.util.cparser.C import CParserUtils 5 | from ghidra.app.cmd.function import ApplyFunctionSignatureCmd 6 | 7 | processFields = [ 8 | "ScriptMethod", 9 | "ScriptString", 10 | "ScriptMetadata", 11 | "ScriptMetadataMethod", 12 | "Addresses", 13 | ] 14 | 15 | functionManager = currentProgram.getFunctionManager() 16 | baseAddress = currentProgram.getImageBase() 17 | USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED 18 | 19 | def get_addr(addr): 20 | return baseAddress.add(addr) 21 | 22 | def set_name(addr, name): 23 | try: 24 | name = name.replace(' ', '-') 25 | createLabel(addr, name, True, USER_DEFINED) 26 | except: 27 | print("set_name() Failed.") 28 | 29 | def set_type(addr, type): 30 | # Requires types (il2cpp.h) to be imported first 31 | newType = type.replace("*"," *").replace(" "," ").strip() 32 | dataTypes = getDataTypes(newType) 33 | addrType = None 34 | if len(dataTypes) == 0: 35 | if newType == newType[:-2] + " *": 36 | baseType = newType[:-2] 37 | dataTypes = getDataTypes(baseType) 38 | if len(dataTypes) == 1: 39 | dtm = currentProgram.getDataTypeManager() 40 | pointerType = dtm.getPointer(dataTypes[0]) 41 | addrType = dtm.addDataType(pointerType, None) 42 | elif len(dataTypes) > 1: 43 | print("Conflicting data types found for type " + type + "(parsed as '" + newType + "')") 44 | return 45 | else: 46 | addrType = dataTypes[0] 47 | if addrType is None: 48 | print("Could not identify type " + type + "(parsed as '" + newType + "')") 49 | else: 50 | try: 51 | createData(addr, addrType) 52 | except ghidra.program.model.util.CodeUnitInsertionException: 53 | print("Warning: unable to set type (CodeUnitInsertionException)") 54 | 55 | 56 | def make_function(start): 57 | func = getFunctionAt(start) 58 | if func is None: 59 | try: 60 | createFunction(start, None) 61 | except: 62 | print("Warning: Unable to create function") 63 | 64 | def set_sig(addr, name, sig): 65 | try: 66 | typeSig = CParserUtils.parseSignature(None, currentProgram, sig, False) 67 | except ghidra.app.util.cparser.C.ParseException: 68 | print("Warning: Unable to parse") 69 | print(sig) 70 | print("Attempting to modify...") 71 | # try to fix by renaming the parameters 72 | try: 73 | newSig = sig.replace(", ","ext, ").replace("\)","ext\)") 74 | typeSig = CParserUtils.parseSignature(None, currentProgram, newSig, False) 75 | except: 76 | print("Warning: also unable to parse") 77 | print(newSig) 78 | print("Skipping.") 79 | return 80 | if typeSig is not None: 81 | try: 82 | typeSig.setName(name) 83 | ApplyFunctionSignatureCmd(addr, typeSig, USER_DEFINED, False, True).applyTo(currentProgram) 84 | except: 85 | print("Warning: unable to set Signature. ApplyFunctionSignatureCmd() Failed.") 86 | 87 | f = askFile("script.json from deer2cpp", "Open") 88 | data = json.loads(open(f.absolutePath, 'rb').read().decode('utf-8')) 89 | 90 | if "ScriptMethod" in data and "ScriptMethod" in processFields: 91 | scriptMethods = data["ScriptMethod"] 92 | monitor.initialize(len(scriptMethods)) 93 | monitor.setMessage("Methods") 94 | for scriptMethod in scriptMethods: 95 | addr = get_addr(scriptMethod["Address"]) 96 | name = scriptMethod["Name"].encode("utf-8") 97 | set_name(addr, name) 98 | monitor.incrementProgress(1) 99 | 100 | if "ScriptString" in data and "ScriptString" in processFields: 101 | index = 1 102 | scriptStrings = data["ScriptString"] 103 | monitor.initialize(len(scriptStrings)) 104 | monitor.setMessage("Strings") 105 | for scriptString in scriptStrings: 106 | addr = get_addr(scriptString["Address"]) 107 | value = scriptString["Value"].encode("utf-8") 108 | name = "StringLiteral_" + str(index) 109 | createLabel(addr, name, True, USER_DEFINED) 110 | setEOLComment(addr, value) 111 | index += 1 112 | monitor.incrementProgress(1) 113 | 114 | if "ScriptMetadata" in data and "ScriptMetadata" in processFields: 115 | scriptMetadatas = data["ScriptMetadata"] 116 | monitor.initialize(len(scriptMetadatas)) 117 | monitor.setMessage("Metadata") 118 | for scriptMetadata in scriptMetadatas: 119 | addr = get_addr(scriptMetadata["Address"]) 120 | name = scriptMetadata["Name"].encode("utf-8") 121 | set_name(addr, name) 122 | setEOLComment(addr, name) 123 | monitor.incrementProgress(1) 124 | if scriptMetadata["Signature"]: 125 | set_type(addr, scriptMetadata["Signature"].encode("utf-8")) 126 | 127 | if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: 128 | scriptMetadataMethods = data["ScriptMetadataMethod"] 129 | monitor.initialize(len(scriptMetadataMethods)) 130 | monitor.setMessage("Metadata Methods") 131 | for scriptMetadataMethod in scriptMetadataMethods: 132 | addr = get_addr(scriptMetadataMethod["Address"]) 133 | name = scriptMetadataMethod["Name"].encode("utf-8") 134 | methodAddr = get_addr(scriptMetadataMethod["MethodAddress"]) 135 | set_name(addr, name) 136 | setEOLComment(addr, name) 137 | monitor.incrementProgress(1) 138 | 139 | if "Addresses" in data and "Addresses" in processFields: 140 | addresses = data["Addresses"] 141 | monitor.initialize(len(addresses)) 142 | monitor.setMessage("Addresses") 143 | for index in range(len(addresses) - 1): 144 | start = get_addr(addresses[index]) 145 | make_function(start) 146 | monitor.incrementProgress(1) 147 | 148 | if "ScriptMethod" in data and "ScriptMethod" in processFields: 149 | scriptMethods = data["ScriptMethod"] 150 | for scriptMethod in scriptMethods: 151 | addr = get_addr(scriptMethod["Address"]) 152 | sig = scriptMethod["Signature"][:-1].encode("utf-8") 153 | name = scriptMethod["Name"].encode("utf-8") 154 | set_sig(addr, name, sig) 155 | 156 | print 'Script finished!' 157 | -------------------------------------------------------------------------------- /hopper-py3.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | import json 3 | 4 | def deserializeJSON(script_file): 5 | if script_file is not None: 6 | f = codecs.open(script_file, "r","utf-8") 7 | 8 | # Reading from file 9 | data = json.loads(f.read()) 10 | f.close() 11 | 12 | return data 13 | 14 | def changeAddressNames(script): 15 | for i in script['ScriptMethod']: 16 | addr = i['Address'] 17 | name = i['Name'] 18 | #sig = i['Signature'] 19 | #typesig = i['TypeSignature'] 20 | 21 | #print(addr, name) 22 | doc.setNameAtAddress(addr, name) 23 | 24 | return 25 | 26 | def main(): 27 | script_file = doc.askFile('Select script.py', None, None) 28 | script = deserializeJSON(script_file) 29 | changeAddressNames(script) 30 | 31 | doc = Document.getCurrentDocument() 32 | main() 33 | -------------------------------------------------------------------------------- /ida.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | processFields = [ 5 | "ScriptMethod", 6 | "ScriptString", 7 | "ScriptMetadata", 8 | "ScriptMetadataMethod", 9 | "Addresses", 10 | ] 11 | 12 | imageBase = idaapi.get_imagebase() 13 | 14 | def get_addr(addr): 15 | return imageBase + addr 16 | 17 | def set_name(addr, name): 18 | ret = idc.set_name(addr, name, SN_NOWARN | SN_NOCHECK) 19 | if ret == 0: 20 | new_name = name + '_' + str(addr) 21 | ret = idc.set_name(addr, new_name, SN_NOWARN | SN_NOCHECK) 22 | 23 | def make_function(start, end): 24 | next_func = idc.get_next_func(start) 25 | if next_func < end: 26 | end = next_func 27 | if idc.get_func_attr(start, FUNCATTR_START) == start: 28 | ida_funcs.del_func(start) 29 | ida_funcs.add_func(start, end) 30 | 31 | path = idaapi.ask_file(False, '*.json', 'script.json from Il2cppdumper') 32 | data = json.loads(open(path, 'rb').read().decode('utf-8')) 33 | 34 | if "Addresses" in data and "Addresses" in processFields: 35 | addresses = data["Addresses"] 36 | for index in range(len(addresses) - 1): 37 | start = get_addr(addresses[index]) 38 | end = get_addr(addresses[index + 1]) 39 | make_function(start, end) 40 | 41 | if "ScriptMethod" in data and "ScriptMethod" in processFields: 42 | scriptMethods = data["ScriptMethod"] 43 | for scriptMethod in scriptMethods: 44 | addr = get_addr(scriptMethod["Address"]) 45 | name = scriptMethod["Name"].encode("utf-8") 46 | set_name(addr, name) 47 | 48 | if "ScriptString" in data and "ScriptString" in processFields: 49 | index = 1 50 | scriptStrings = data["ScriptString"] 51 | for scriptString in scriptStrings: 52 | addr = get_addr(scriptString["Address"]) 53 | value = scriptString["Value"].encode("utf-8") 54 | name = "StringLiteral_" + str(index) 55 | idc.set_name(addr, name, SN_NOWARN) 56 | idc.set_cmt(addr, value, 1) 57 | index += 1 58 | 59 | if "ScriptMetadata" in data and "ScriptMetadata" in processFields: 60 | scriptMetadatas = data["ScriptMetadata"] 61 | for scriptMetadata in scriptMetadatas: 62 | addr = get_addr(scriptMetadata["Address"]) 63 | name = scriptMetadata["Name"].encode("utf-8") 64 | set_name(addr, name) 65 | idc.set_cmt(addr, name, 1) 66 | 67 | if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: 68 | scriptMetadataMethods = data["ScriptMetadataMethod"] 69 | for scriptMetadataMethod in scriptMetadataMethods: 70 | addr = get_addr(scriptMetadataMethod["Address"]) 71 | name = scriptMetadataMethod["Name"].encode("utf-8") 72 | methodAddr = get_addr(scriptMetadataMethod["MethodAddress"]) 73 | set_name(addr, name) 74 | idc.set_cmt(addr, name, 1) 75 | idc.set_cmt(addr, '{0:X}'.format(methodAddr), 0) 76 | 77 | print 'Script finished!' 78 | 79 | -------------------------------------------------------------------------------- /ida_py3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | processFields = [ 5 | "ScriptMethod", 6 | "ScriptString", 7 | "ScriptMetadata", 8 | "ScriptMetadataMethod", 9 | "Addresses", 10 | ] 11 | 12 | imageBase = idaapi.get_imagebase() 13 | 14 | def get_addr(addr): 15 | return imageBase + addr 16 | 17 | def set_name(addr, name): 18 | ret = idc.set_name(addr, name, SN_NOWARN | SN_NOCHECK) 19 | if ret == 0: 20 | new_name = name + '_' + str(addr) 21 | ret = idc.set_name(addr, new_name, SN_NOWARN | SN_NOCHECK) 22 | 23 | def make_function(start, end): 24 | next_func = idc.get_next_func(start) 25 | if next_func < end: 26 | end = next_func 27 | if idc.get_func_attr(start, FUNCATTR_START) == start: 28 | ida_funcs.del_func(start) 29 | ida_funcs.add_func(start, end) 30 | 31 | path = idaapi.ask_file(False, '*.json', 'script.json from Il2cppdumper') 32 | data = json.loads(open(path, 'rb').read().decode('utf-8')) 33 | 34 | if "Addresses" in data and "Addresses" in processFields: 35 | addresses = data["Addresses"] 36 | for index in range(len(addresses) - 1): 37 | start = get_addr(addresses[index]) 38 | end = get_addr(addresses[index + 1]) 39 | make_function(start, end) 40 | 41 | if "ScriptMethod" in data and "ScriptMethod" in processFields: 42 | scriptMethods = data["ScriptMethod"] 43 | for scriptMethod in scriptMethods: 44 | addr = get_addr(scriptMethod["Address"]) 45 | name = scriptMethod["Name"] 46 | set_name(addr, name) 47 | 48 | if "ScriptString" in data and "ScriptString" in processFields: 49 | index = 1 50 | scriptStrings = data["ScriptString"] 51 | for scriptString in scriptStrings: 52 | addr = get_addr(scriptString["Address"]) 53 | value = scriptString["Value"] 54 | name = "StringLiteral_" + str(index) 55 | idc.set_name(addr, name, SN_NOWARN) 56 | idc.set_cmt(addr, value, 1) 57 | index += 1 58 | 59 | if "ScriptMetadata" in data and "ScriptMetadata" in processFields: 60 | scriptMetadatas = data["ScriptMetadata"] 61 | for scriptMetadata in scriptMetadatas: 62 | addr = get_addr(scriptMetadata["Address"]) 63 | name = scriptMetadata["Name"] 64 | set_name(addr, name) 65 | idc.set_cmt(addr, name, 1) 66 | 67 | if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: 68 | scriptMetadataMethods = data["ScriptMetadataMethod"] 69 | for scriptMetadataMethod in scriptMetadataMethods: 70 | addr = get_addr(scriptMetadataMethod["Address"]) 71 | name = scriptMetadataMethod["Name"] 72 | methodAddr = get_addr(scriptMetadataMethod["MethodAddress"]) 73 | set_name(addr, name) 74 | idc.set_cmt(addr, name, 1) 75 | idc.set_cmt(addr, '{0:X}'.format(methodAddr), 0) 76 | 77 | print('Script finished!') 78 | 79 | -------------------------------------------------------------------------------- /ida_with_struct.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | processFields = [ 5 | "ScriptMethod", 6 | "ScriptString", 7 | "ScriptMetadata", 8 | "ScriptMetadataMethod", 9 | "Addresses", 10 | ] 11 | 12 | imageBase = idaapi.get_imagebase() 13 | 14 | def get_addr(addr): 15 | return imageBase + addr 16 | 17 | def set_name(addr, name): 18 | ret = idc.set_name(addr, name, SN_NOWARN | SN_NOCHECK) 19 | if ret == 0: 20 | new_name = name + '_' + str(addr) 21 | ret = idc.set_name(addr, new_name, SN_NOWARN | SN_NOCHECK) 22 | 23 | def make_function(start, end): 24 | next_func = idc.get_next_func(start) 25 | if next_func < end: 26 | end = next_func 27 | if idc.get_func_attr(start, FUNCATTR_START) == start: 28 | ida_funcs.del_func(start) 29 | ida_funcs.add_func(start, end) 30 | 31 | path = idaapi.ask_file(False, '*.json', 'script.json from Il2cppdumper') 32 | hpath = idaapi.ask_file(False, '*.h', 'il2cpp.h from Il2cppdumper') 33 | parse_decls(open(hpath, 'rb').read(), 0) 34 | data = json.loads(open(path, 'rb').read().decode('utf-8')) 35 | 36 | if "Addresses" in data and "Addresses" in processFields: 37 | addresses = data["Addresses"] 38 | for index in range(len(addresses) - 1): 39 | start = get_addr(addresses[index]) 40 | end = get_addr(addresses[index + 1]) 41 | make_function(start, end) 42 | 43 | if "ScriptMethod" in data and "ScriptMethod" in processFields: 44 | scriptMethods = data["ScriptMethod"] 45 | for scriptMethod in scriptMethods: 46 | addr = get_addr(scriptMethod["Address"]) 47 | name = scriptMethod["Name"].encode("utf-8") 48 | set_name(addr, name) 49 | signature = scriptMethod["Signature"].encode("utf-8") 50 | if apply_type(addr, parse_decl(signature, 0), 1) == False: 51 | print "apply_type failed:", hex(addr), signature 52 | 53 | if "ScriptString" in data and "ScriptString" in processFields: 54 | index = 1 55 | scriptStrings = data["ScriptString"] 56 | for scriptString in scriptStrings: 57 | addr = get_addr(scriptString["Address"]) 58 | value = scriptString["Value"].encode("utf-8") 59 | name = "StringLiteral_" + str(index) 60 | idc.set_name(addr, name, SN_NOWARN) 61 | idc.set_cmt(addr, value, 1) 62 | index += 1 63 | 64 | if "ScriptMetadata" in data and "ScriptMetadata" in processFields: 65 | scriptMetadatas = data["ScriptMetadata"] 66 | for scriptMetadata in scriptMetadatas: 67 | addr = get_addr(scriptMetadata["Address"]) 68 | name = scriptMetadata["Name"].encode("utf-8") 69 | set_name(addr, name) 70 | idc.set_cmt(addr, name, 1) 71 | if scriptMetadata["Signature"] is not None: 72 | signature = scriptMetadata["Signature"].encode("utf-8") 73 | if apply_type(addr, parse_decl(signature, 0), 1) == False: 74 | print "apply_type failed:", hex(addr), signature 75 | 76 | if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: 77 | scriptMetadataMethods = data["ScriptMetadataMethod"] 78 | for scriptMetadataMethod in scriptMetadataMethods: 79 | addr = get_addr(scriptMetadataMethod["Address"]) 80 | name = scriptMetadataMethod["Name"].encode("utf-8") 81 | methodAddr = get_addr(scriptMetadataMethod["MethodAddress"]) 82 | set_name(addr, name) 83 | idc.set_cmt(addr, name, 1) 84 | idc.set_cmt(addr, '{0:X}'.format(methodAddr), 0) 85 | 86 | print 'Script finished!' 87 | 88 | -------------------------------------------------------------------------------- /ida_with_struct_py3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | processFields = [ 5 | "ScriptMethod", 6 | "ScriptString", 7 | "ScriptMetadata", 8 | "ScriptMetadataMethod", 9 | "Addresses", 10 | ] 11 | 12 | imageBase = idaapi.get_imagebase() 13 | 14 | def get_addr(addr): 15 | return imageBase + addr 16 | 17 | def set_name(addr, name): 18 | ret = idc.set_name(addr, name, SN_NOWARN | SN_NOCHECK) 19 | if ret == 0: 20 | new_name = name + '_' + str(addr) 21 | ret = idc.set_name(addr, new_name, SN_NOWARN | SN_NOCHECK) 22 | 23 | def make_function(start, end): 24 | next_func = idc.get_next_func(start) 25 | if next_func < end: 26 | end = next_func 27 | if idc.get_func_attr(start, FUNCATTR_START) == start: 28 | ida_funcs.del_func(start) 29 | ida_funcs.add_func(start, end) 30 | 31 | path = idaapi.ask_file(False, '*.json', 'script.json from Il2cppdumper') 32 | hpath = idaapi.ask_file(False, '*.h', 'il2cpp.h from Il2cppdumper') 33 | parse_decls(open(hpath, 'r').read(), 0) 34 | data = json.loads(open(path, 'rb').read().decode('utf-8')) 35 | 36 | if "Addresses" in data and "Addresses" in processFields: 37 | addresses = data["Addresses"] 38 | for index in range(len(addresses) - 1): 39 | start = get_addr(addresses[index]) 40 | end = get_addr(addresses[index + 1]) 41 | make_function(start, end) 42 | 43 | if "ScriptMethod" in data and "ScriptMethod" in processFields: 44 | scriptMethods = data["ScriptMethod"] 45 | for scriptMethod in scriptMethods: 46 | addr = get_addr(scriptMethod["Address"]) 47 | name = scriptMethod["Name"] 48 | set_name(addr, name) 49 | signature = scriptMethod["Signature"] 50 | if apply_type(addr, parse_decl(signature, 0), 1) == False: 51 | print("apply_type failed:", hex(addr), signature) 52 | 53 | if "ScriptString" in data and "ScriptString" in processFields: 54 | index = 1 55 | scriptStrings = data["ScriptString"] 56 | for scriptString in scriptStrings: 57 | addr = get_addr(scriptString["Address"]) 58 | value = scriptString["Value"] 59 | name = "StringLiteral_" + str(index) 60 | idc.set_name(addr, name, SN_NOWARN) 61 | idc.set_cmt(addr, value, 1) 62 | index += 1 63 | 64 | if "ScriptMetadata" in data and "ScriptMetadata" in processFields: 65 | scriptMetadatas = data["ScriptMetadata"] 66 | for scriptMetadata in scriptMetadatas: 67 | addr = get_addr(scriptMetadata["Address"]) 68 | name = scriptMetadata["Name"] 69 | set_name(addr, name) 70 | idc.set_cmt(addr, name, 1) 71 | if scriptMetadata["Signature"] is not None: 72 | signature = scriptMetadata["Signature"] 73 | if apply_type(addr, parse_decl(signature, 0), 1) == False: 74 | print("apply_type failed:", hex(addr), signature) 75 | 76 | if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: 77 | scriptMetadataMethods = data["ScriptMetadataMethod"] 78 | for scriptMetadataMethod in scriptMetadataMethods: 79 | addr = get_addr(scriptMetadataMethod["Address"]) 80 | name = scriptMetadataMethod["Name"] 81 | methodAddr = get_addr(scriptMetadataMethod["MethodAddress"]) 82 | set_name(addr, name) 83 | idc.set_cmt(addr, name, 1) 84 | idc.set_cmt(addr, '{0:X}'.format(methodAddr), 0) 85 | 86 | print('Script finished!') 87 | 88 | -------------------------------------------------------------------------------- /il2cpp_header_to_binja.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | data = open("./il2cpp.h").read() 4 | 5 | builtin = ["void", "intptr_t", "uint32_t", "uint16_t", "int32_t", "uint8_t", "bool", 6 | "int64_t", "uint64_t", "double", "int16_t", "int8_t", "float", "uintptr_t", 7 | "const", "union", "{", "};", "il2cpp_array_size_t", "il2cpp_array_lower_bound_t", 8 | "struct", "Il2CppMethodPointer"] 9 | structs = [] 10 | notfound = [] 11 | header = "" 12 | 13 | for line in data.splitlines(): 14 | if line.startswith("struct") or line.startswith("union"): 15 | struct = line.split()[1] 16 | if struct.endswith(";"): 17 | struct = struct[:-1] 18 | structs.append(struct) 19 | if line.startswith("\t"): 20 | struct = line[1:].split()[0] 21 | if struct == "struct": 22 | struct = line[1:].split()[1] 23 | if struct.endswith("*"): 24 | struct = struct[:-1] 25 | if struct.endswith("*"): 26 | struct = struct[:-1] 27 | if struct in builtin: 28 | continue 29 | if struct not in structs and struct not in notfound: 30 | notfound.append(struct) 31 | for struct in notfound: 32 | header += f"struct {struct};" + "\n" 33 | to_replace = re.findall("struct (.*) {\n};", data) 34 | for item in to_replace: 35 | data = data.replace("struct "+item+" {\n};", "") 36 | data = data.replace("\t"+item.split()[0]+" ", "\tvoid *") 37 | data = data.replace("\t struct "+item.split()[0]+" ", "\t void *") 38 | data = re.sub(r": (\w+) {", r"{\n\t\1 super;", data) 39 | with open("./il2cpp_binja.h", "w") as f: 40 | f.write(header) 41 | f.write(data) 42 | -------------------------------------------------------------------------------- /il2cpp_header_to_ghidra.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | header = "typedef unsigned __int8 uint8_t;\n" \ 4 | "typedef unsigned __int16 uint16_t;\n" \ 5 | "typedef unsigned __int32 uint32_t;\n" \ 6 | "typedef unsigned __int64 uint64_t;\n" \ 7 | "typedef __int8 int8_t;\n" \ 8 | "typedef __int16 int16_t;\n" \ 9 | "typedef __int32 int32_t;\n" \ 10 | "typedef __int64 int64_t;\n" \ 11 | "typedef __int64 intptr_t;\n" \ 12 | "typedef __int64 uintptr_t;\n" \ 13 | "typedef unsigned __int64 size_t;\n" \ 14 | "typedef _Bool bool;\n" 15 | 16 | 17 | def main(): 18 | fixed_header_data = "" 19 | with open("il2cpp.h", 'r') as f: 20 | print("il2cpp.h opened...") 21 | original_header_data = f.read() 22 | print("il2cpp.h read...") 23 | fixed_header_data = re.sub(r": (\w+) {", r"{\n \1 super;", original_header_data) 24 | print("il2cpp.h data fixed...") 25 | print("il2cpp.h closed.") 26 | with open("il2cpp_ghidra.h", 'w') as f: 27 | print("il2cpp_ghidra.h opened...") 28 | f.write(header) 29 | print("header written...") 30 | f.write(fixed_header_data) 31 | print("fixed data written...") 32 | print("il2cpp_ghidra.h closed.") 33 | 34 | 35 | if __name__ == '__main__': 36 | print("Script started...") 37 | main() 38 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/Il2CppDumper.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Il codice è stato generato da uno strumento. 4 | // Versione runtime:4.0.30319.42000 5 | // 6 | // Le modifiche apportate a questo file possono provocare un comportamento non corretto e andranno perse se 7 | // il codice viene rigenerato. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("Il2CppDumper")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyCopyrightAttribute("Copyright © Perfare 2016-2024")] 17 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 18 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0.0")] 19 | [assembly: System.Reflection.AssemblyProductAttribute("Il2CppDumper")] 20 | [assembly: System.Reflection.AssemblyTitleAttribute("Il2CppDumper")] 21 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 22 | 23 | // Generato dalla classe WriteCodeFragment di MSBuild. 24 | 25 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/Il2CppDumper.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | f34c235763424bde487f6d4cfeff21723161d97cb15fd6cc09b4fe29261c81ca 2 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/Il2CppDumper.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net6.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = 5 | build_property.ProjectTypeGuids = 6 | build_property.InvariantGlobalization = 7 | build_property.PlatformNeutralAssembly = 8 | build_property.EnforceExtendedAnalyzerRules = 9 | build_property._SupportedPlatformList = Linux,macOS,Windows 10 | build_property.RootNamespace = Il2CppDumper 11 | build_property.ProjectDir = C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\ 12 | build_property.EnableComHosting = 13 | build_property.EnableGeneratedComInterfaceComImportInterop = 14 | build_property.EffectiveAnalysisLevelStyle = 6.0 15 | build_property.EnableCodeStyleSeverity = 16 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/Il2CppDumper.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/Il2CppDumper.assets.cache -------------------------------------------------------------------------------- /obj/Debug/net6.0/Il2CppDumper.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/Il2CppDumper.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /obj/Debug/net6.0/apphost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/apphost.exe -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Il codice è stato generato da uno strumento. 4 | // Versione runtime:4.0.30319.42000 5 | // 6 | // Le modifiche apportate a questo file possono provocare un comportamento non corretto e andranno perse se 7 | // il codice viene rigenerato. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("deer2cpp")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyCopyrightAttribute("Copyright © Perfare 2016-2024")] 17 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 18 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0.0")] 19 | [assembly: System.Reflection.AssemblyProductAttribute("deer2cpp")] 20 | [assembly: System.Reflection.AssemblyTitleAttribute("deer2cpp")] 21 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 22 | 23 | // Generato dalla classe WriteCodeFragment di MSBuild. 24 | 25 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 75711a9c08734449ff60212376aad44c17422921f6eff745deecb9c2462bfb29 2 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net6.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = 5 | build_property.ProjectTypeGuids = 6 | build_property.InvariantGlobalization = 7 | build_property.PlatformNeutralAssembly = 8 | build_property.EnforceExtendedAnalyzerRules = 9 | build_property._SupportedPlatformList = Linux,macOS,Windows 10 | build_property.RootNamespace = deer2cpp 11 | build_property.ProjectDir = C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\ 12 | build_property.EnableComHosting = 13 | build_property.EnableGeneratedComInterfaceComImportInterop = 14 | build_property.EffectiveAnalysisLevelStyle = 6.0 15 | build_property.EnableCodeStyleSeverity = 16 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.Resource1.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/deer2cpp.Resource1.resources -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/deer2cpp.assets.cache -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/deer2cpp.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 27d382f50ae5c514850245a84c8598312a05ffc962aa040886ce61684ac08018 2 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.csproj.AssemblyReference.cache 2 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.Resource1.resources 3 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.csproj.GenerateResource.cache 4 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.GeneratedMSBuildEditorConfig.editorconfig 5 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.AssemblyInfoInputs.cache 6 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.AssemblyInfo.cs 7 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.csproj.CoreCompileInputs.cache 8 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\config.json 9 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\ghidra.py 10 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\ghidra_wasm.py 11 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\ghidra_with_struct.py 12 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\ida.py 13 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\ida_py3.py 14 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\ida_with_struct.py 15 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\ida_with_struct_py3.py 16 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\il2cpp_header_to_ghidra.py 17 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\deer2cpp.exe 18 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\deer2cpp.deps.json 19 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\deer2cpp.runtimeconfig.json 20 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\deer2cpp.dll 21 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\Mono.Cecil.Mdb.dll 22 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\Mono.Cecil.Pdb.dll 23 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\Mono.Cecil.Rocks.dll 24 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net6.0\Mono.Cecil.dll 25 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.csproj.Up2Date 26 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.dll 27 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\refint\deer2cpp.dll 28 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\deer2cpp.genruntimeconfig.cache 29 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net6.0\ref\deer2cpp.dll 30 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.csproj.GenerateResource.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/deer2cpp.csproj.GenerateResource.cache -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.csproj.Up2Date: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/deer2cpp.csproj.Up2Date -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/deer2cpp.dll -------------------------------------------------------------------------------- /obj/Debug/net6.0/deer2cpp.genruntimeconfig.cache: -------------------------------------------------------------------------------- 1 | 45da1d1cbf14468ebac94fe43c35a598129bcc4890b8b22c04e94adbd05f4034 2 | -------------------------------------------------------------------------------- /obj/Debug/net6.0/ref/deer2cpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/ref/deer2cpp.dll -------------------------------------------------------------------------------- /obj/Debug/net6.0/refint/deer2cpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net6.0/refint/deer2cpp.dll -------------------------------------------------------------------------------- /obj/Debug/net8.0/Il2CppDumper.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Il codice è stato generato da uno strumento. 4 | // Versione runtime:4.0.30319.42000 5 | // 6 | // Le modifiche apportate a questo file possono provocare un comportamento non corretto e andranno perse se 7 | // il codice viene rigenerato. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("Il2CppDumper")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyCopyrightAttribute("Copyright © Perfare 2016-2024")] 17 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 18 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0.0")] 19 | [assembly: System.Reflection.AssemblyProductAttribute("Il2CppDumper")] 20 | [assembly: System.Reflection.AssemblyTitleAttribute("Il2CppDumper")] 21 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 22 | 23 | // Generato dalla classe WriteCodeFragment di MSBuild. 24 | 25 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/Il2CppDumper.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | f34c235763424bde487f6d4cfeff21723161d97cb15fd6cc09b4fe29261c81ca 2 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/Il2CppDumper.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net8.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = 5 | build_property.ProjectTypeGuids = 6 | build_property.InvariantGlobalization = 7 | build_property.PlatformNeutralAssembly = 8 | build_property.EnforceExtendedAnalyzerRules = 9 | build_property._SupportedPlatformList = Linux,macOS,Windows 10 | build_property.RootNamespace = Il2CppDumper 11 | build_property.ProjectDir = C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\ 12 | build_property.EnableComHosting = 13 | build_property.EnableGeneratedComInterfaceComImportInterop = 14 | build_property.EffectiveAnalysisLevelStyle = 8.0 15 | build_property.EnableCodeStyleSeverity = 16 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/Il2CppDumper.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/Il2CppDumper.assets.cache -------------------------------------------------------------------------------- /obj/Debug/net8.0/Il2CppDumper.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/Il2CppDumper.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /obj/Debug/net8.0/apphost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/apphost.exe -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Il codice è stato generato da uno strumento. 4 | // Versione runtime:4.0.30319.42000 5 | // 6 | // Le modifiche apportate a questo file possono provocare un comportamento non corretto e andranno perse se 7 | // il codice viene rigenerato. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("deer2cpp")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyCopyrightAttribute("Copyright © Perfare 2016-2024")] 17 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 18 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0.0")] 19 | [assembly: System.Reflection.AssemblyProductAttribute("deer2cpp")] 20 | [assembly: System.Reflection.AssemblyTitleAttribute("deer2cpp")] 21 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 22 | 23 | // Generato dalla classe WriteCodeFragment di MSBuild. 24 | 25 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 75711a9c08734449ff60212376aad44c17422921f6eff745deecb9c2462bfb29 2 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net8.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = 5 | build_property.ProjectTypeGuids = 6 | build_property.InvariantGlobalization = 7 | build_property.PlatformNeutralAssembly = 8 | build_property.EnforceExtendedAnalyzerRules = 9 | build_property._SupportedPlatformList = Linux,macOS,Windows 10 | build_property.RootNamespace = deer2cpp 11 | build_property.ProjectDir = C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\ 12 | build_property.EnableComHosting = 13 | build_property.EnableGeneratedComInterfaceComImportInterop = 14 | build_property.EffectiveAnalysisLevelStyle = 8.0 15 | build_property.EnableCodeStyleSeverity = 16 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.Resource1.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/deer2cpp.Resource1.resources -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/deer2cpp.assets.cache -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/deer2cpp.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 7ad9e74019995998f827813d395da53ac3328ccd025e2552c9f87f1ef011354b 2 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.csproj.AssemblyReference.cache 2 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.Resource1.resources 3 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.csproj.GenerateResource.cache 4 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.GeneratedMSBuildEditorConfig.editorconfig 5 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.AssemblyInfoInputs.cache 6 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.AssemblyInfo.cs 7 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.csproj.CoreCompileInputs.cache 8 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\config.json 9 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\ghidra.py 10 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\ghidra_wasm.py 11 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\ghidra_with_struct.py 12 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\ida.py 13 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\ida_py3.py 14 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\ida_with_struct.py 15 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\ida_with_struct_py3.py 16 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\il2cpp_header_to_ghidra.py 17 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\deer2cpp.exe 18 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\deer2cpp.deps.json 19 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\deer2cpp.runtimeconfig.json 20 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\deer2cpp.dll 21 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\Mono.Cecil.Mdb.dll 22 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\Mono.Cecil.Pdb.dll 23 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\Mono.Cecil.Rocks.dll 24 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\bin\Debug\net8.0\Mono.Cecil.dll 25 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.csproj.Up2Date 26 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.dll 27 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\refint\deer2cpp.dll 28 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\deer2cpp.genruntimeconfig.cache 29 | C:\Users\lokino\Downloads\Il2CppDumper-master\Il2CppDumper-master\Il2CppDumper\obj\Debug\net8.0\ref\deer2cpp.dll 30 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.csproj.GenerateResource.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/deer2cpp.csproj.GenerateResource.cache -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.csproj.Up2Date: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/deer2cpp.csproj.Up2Date -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/deer2cpp.dll -------------------------------------------------------------------------------- /obj/Debug/net8.0/deer2cpp.genruntimeconfig.cache: -------------------------------------------------------------------------------- 1 | ccf4d6b49957e97c593115af0541f140b510c0e0cbd34fc2e5b36dfc2ba34f60 2 | -------------------------------------------------------------------------------- /obj/Debug/net8.0/ref/deer2cpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/ref/deer2cpp.dll -------------------------------------------------------------------------------- /obj/Debug/net8.0/refint/deer2cpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deer2cpp/deer2cppdumper/772697c6611201837e90b5c0bfa27bb80b37fa21/obj/Debug/net8.0/refint/deer2cpp.dll -------------------------------------------------------------------------------- /obj/Il2CppDumper.csproj.nuget.dgspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 1, 3 | "restore": { 4 | "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\Il2CppDumper.csproj": {} 5 | }, 6 | "projects": { 7 | "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\Il2CppDumper.csproj": { 8 | "version": "1.0.0", 9 | "restore": { 10 | "projectUniqueName": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\Il2CppDumper.csproj", 11 | "projectName": "Il2CppDumper", 12 | "projectPath": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\Il2CppDumper.csproj", 13 | "packagesPath": "C:\\Users\\lokino\\.nuget\\packages\\", 14 | "outputPath": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\obj\\", 15 | "projectStyle": "PackageReference", 16 | "crossTargeting": true, 17 | "fallbackFolders": [ 18 | "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" 19 | ], 20 | "configFilePaths": [ 21 | "C:\\Users\\lokino\\AppData\\Roaming\\NuGet\\NuGet.Config", 22 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", 23 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 24 | ], 25 | "originalTargetFrameworks": [ 26 | "net6.0", 27 | "net8.0" 28 | ], 29 | "sources": { 30 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 31 | "https://api.nuget.org/v3/index.json": {} 32 | }, 33 | "frameworks": { 34 | "net6.0": { 35 | "targetAlias": "net6.0", 36 | "projectReferences": {} 37 | }, 38 | "net8.0": { 39 | "targetAlias": "net8.0", 40 | "projectReferences": {} 41 | } 42 | }, 43 | "warningProperties": { 44 | "warnAsError": [ 45 | "NU1605" 46 | ] 47 | }, 48 | "restoreAuditProperties": { 49 | "enableAudit": "true", 50 | "auditLevel": "low", 51 | "auditMode": "direct" 52 | }, 53 | "SdkAnalysisLevel": "9.0.200" 54 | }, 55 | "frameworks": { 56 | "net6.0": { 57 | "targetAlias": "net6.0", 58 | "dependencies": { 59 | "Mono.Cecil": { 60 | "target": "Package", 61 | "version": "[0.11.4, )" 62 | } 63 | }, 64 | "imports": [ 65 | "net461", 66 | "net462", 67 | "net47", 68 | "net471", 69 | "net472", 70 | "net48", 71 | "net481" 72 | ], 73 | "assetTargetFallback": true, 74 | "warn": true, 75 | "frameworkReferences": { 76 | "Microsoft.NETCore.App": { 77 | "privateAssets": "all" 78 | } 79 | }, 80 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.200-preview.0.25057.12\\RuntimeIdentifierGraph.json" 81 | }, 82 | "net8.0": { 83 | "targetAlias": "net8.0", 84 | "dependencies": { 85 | "Mono.Cecil": { 86 | "target": "Package", 87 | "version": "[0.11.4, )" 88 | } 89 | }, 90 | "imports": [ 91 | "net461", 92 | "net462", 93 | "net47", 94 | "net471", 95 | "net472", 96 | "net48", 97 | "net481" 98 | ], 99 | "assetTargetFallback": true, 100 | "warn": true, 101 | "frameworkReferences": { 102 | "Microsoft.NETCore.App": { 103 | "privateAssets": "all" 104 | } 105 | }, 106 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.200-preview.0.25057.12/PortableRuntimeIdentifierGraph.json" 107 | } 108 | } 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /obj/Il2CppDumper.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | NuGet 6 | $(MSBuildThisFileDirectory)project.assets.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\lokino\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages 9 | PackageReference 10 | 6.13.0 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /obj/Il2CppDumper.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /obj/deer2cpp.csproj.nuget.dgspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 1, 3 | "restore": { 4 | "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\deer2cpp.csproj": {} 5 | }, 6 | "projects": { 7 | "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\deer2cpp.csproj": { 8 | "version": "1.0.0", 9 | "restore": { 10 | "projectUniqueName": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\deer2cpp.csproj", 11 | "projectName": "deer2cpp", 12 | "projectPath": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\deer2cpp.csproj", 13 | "packagesPath": "C:\\Users\\lokino\\.nuget\\packages\\", 14 | "outputPath": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\obj\\", 15 | "projectStyle": "PackageReference", 16 | "crossTargeting": true, 17 | "fallbackFolders": [ 18 | "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" 19 | ], 20 | "configFilePaths": [ 21 | "C:\\Users\\lokino\\AppData\\Roaming\\NuGet\\NuGet.Config", 22 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", 23 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 24 | ], 25 | "originalTargetFrameworks": [ 26 | "net6.0", 27 | "net8.0" 28 | ], 29 | "sources": { 30 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 31 | "https://api.nuget.org/v3/index.json": {} 32 | }, 33 | "frameworks": { 34 | "net6.0": { 35 | "targetAlias": "net6.0", 36 | "projectReferences": {} 37 | }, 38 | "net8.0": { 39 | "targetAlias": "net8.0", 40 | "projectReferences": {} 41 | } 42 | }, 43 | "warningProperties": { 44 | "warnAsError": [ 45 | "NU1605" 46 | ] 47 | }, 48 | "restoreAuditProperties": { 49 | "enableAudit": "true", 50 | "auditLevel": "low", 51 | "auditMode": "direct" 52 | }, 53 | "SdkAnalysisLevel": "9.0.200" 54 | }, 55 | "frameworks": { 56 | "net6.0": { 57 | "targetAlias": "net6.0", 58 | "dependencies": { 59 | "Mono.Cecil": { 60 | "target": "Package", 61 | "version": "[0.11.4, )" 62 | } 63 | }, 64 | "imports": [ 65 | "net461", 66 | "net462", 67 | "net47", 68 | "net471", 69 | "net472", 70 | "net48", 71 | "net481" 72 | ], 73 | "assetTargetFallback": true, 74 | "warn": true, 75 | "frameworkReferences": { 76 | "Microsoft.NETCore.App": { 77 | "privateAssets": "all" 78 | } 79 | }, 80 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.200-preview.0.25057.12\\RuntimeIdentifierGraph.json" 81 | }, 82 | "net8.0": { 83 | "targetAlias": "net8.0", 84 | "dependencies": { 85 | "Mono.Cecil": { 86 | "target": "Package", 87 | "version": "[0.11.4, )" 88 | } 89 | }, 90 | "imports": [ 91 | "net461", 92 | "net462", 93 | "net47", 94 | "net471", 95 | "net472", 96 | "net48", 97 | "net481" 98 | ], 99 | "assetTargetFallback": true, 100 | "warn": true, 101 | "frameworkReferences": { 102 | "Microsoft.NETCore.App": { 103 | "privateAssets": "all" 104 | } 105 | }, 106 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.200-preview.0.25057.12/PortableRuntimeIdentifierGraph.json" 107 | } 108 | } 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /obj/deer2cpp.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | NuGet 6 | $(MSBuildThisFileDirectory)project.assets.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\lokino\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages 9 | PackageReference 10 | 6.13.0 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /obj/deer2cpp.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /obj/project.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "targets": { 4 | "net6.0": { 5 | "Mono.Cecil/0.11.4": { 6 | "type": "package", 7 | "compile": { 8 | "lib/netstandard2.0/Mono.Cecil.Mdb.dll": { 9 | "related": ".pdb" 10 | }, 11 | "lib/netstandard2.0/Mono.Cecil.Pdb.dll": { 12 | "related": ".pdb" 13 | }, 14 | "lib/netstandard2.0/Mono.Cecil.Rocks.dll": { 15 | "related": ".pdb" 16 | }, 17 | "lib/netstandard2.0/Mono.Cecil.dll": { 18 | "related": ".Mdb.pdb;.pdb;.Pdb.pdb;.Rocks.pdb" 19 | } 20 | }, 21 | "runtime": { 22 | "lib/netstandard2.0/Mono.Cecil.Mdb.dll": { 23 | "related": ".pdb" 24 | }, 25 | "lib/netstandard2.0/Mono.Cecil.Pdb.dll": { 26 | "related": ".pdb" 27 | }, 28 | "lib/netstandard2.0/Mono.Cecil.Rocks.dll": { 29 | "related": ".pdb" 30 | }, 31 | "lib/netstandard2.0/Mono.Cecil.dll": { 32 | "related": ".Mdb.pdb;.pdb;.Pdb.pdb;.Rocks.pdb" 33 | } 34 | } 35 | } 36 | }, 37 | "net8.0": { 38 | "Mono.Cecil/0.11.4": { 39 | "type": "package", 40 | "compile": { 41 | "lib/netstandard2.0/Mono.Cecil.Mdb.dll": { 42 | "related": ".pdb" 43 | }, 44 | "lib/netstandard2.0/Mono.Cecil.Pdb.dll": { 45 | "related": ".pdb" 46 | }, 47 | "lib/netstandard2.0/Mono.Cecil.Rocks.dll": { 48 | "related": ".pdb" 49 | }, 50 | "lib/netstandard2.0/Mono.Cecil.dll": { 51 | "related": ".Mdb.pdb;.pdb;.Pdb.pdb;.Rocks.pdb" 52 | } 53 | }, 54 | "runtime": { 55 | "lib/netstandard2.0/Mono.Cecil.Mdb.dll": { 56 | "related": ".pdb" 57 | }, 58 | "lib/netstandard2.0/Mono.Cecil.Pdb.dll": { 59 | "related": ".pdb" 60 | }, 61 | "lib/netstandard2.0/Mono.Cecil.Rocks.dll": { 62 | "related": ".pdb" 63 | }, 64 | "lib/netstandard2.0/Mono.Cecil.dll": { 65 | "related": ".Mdb.pdb;.pdb;.Pdb.pdb;.Rocks.pdb" 66 | } 67 | } 68 | } 69 | } 70 | }, 71 | "libraries": { 72 | "Mono.Cecil/0.11.4": { 73 | "sha512": "IC1h5g0NeJGHIUgzM1P82ld57knhP0IcQfrYITDPXlNpMYGUrsG5TxuaWTjaeqDNQMBDNZkB8L0rBnwsY6JHuQ==", 74 | "type": "package", 75 | "path": "mono.cecil/0.11.4", 76 | "files": [ 77 | ".nupkg.metadata", 78 | ".signature.p7s", 79 | "lib/net40/Mono.Cecil.Mdb.dll", 80 | "lib/net40/Mono.Cecil.Mdb.pdb", 81 | "lib/net40/Mono.Cecil.Pdb.dll", 82 | "lib/net40/Mono.Cecil.Pdb.pdb", 83 | "lib/net40/Mono.Cecil.Rocks.dll", 84 | "lib/net40/Mono.Cecil.Rocks.pdb", 85 | "lib/net40/Mono.Cecil.dll", 86 | "lib/net40/Mono.Cecil.pdb", 87 | "lib/netstandard2.0/Mono.Cecil.Mdb.dll", 88 | "lib/netstandard2.0/Mono.Cecil.Mdb.pdb", 89 | "lib/netstandard2.0/Mono.Cecil.Pdb.dll", 90 | "lib/netstandard2.0/Mono.Cecil.Pdb.pdb", 91 | "lib/netstandard2.0/Mono.Cecil.Rocks.dll", 92 | "lib/netstandard2.0/Mono.Cecil.Rocks.pdb", 93 | "lib/netstandard2.0/Mono.Cecil.dll", 94 | "lib/netstandard2.0/Mono.Cecil.pdb", 95 | "mono.cecil.0.11.4.nupkg.sha512", 96 | "mono.cecil.nuspec" 97 | ] 98 | } 99 | }, 100 | "projectFileDependencyGroups": { 101 | "net6.0": [ 102 | "Mono.Cecil >= 0.11.4" 103 | ], 104 | "net8.0": [ 105 | "Mono.Cecil >= 0.11.4" 106 | ] 107 | }, 108 | "packageFolders": { 109 | "C:\\Users\\lokino\\.nuget\\packages\\": {}, 110 | "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} 111 | }, 112 | "project": { 113 | "version": "1.0.0", 114 | "restore": { 115 | "projectUniqueName": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\deer2cpp.csproj", 116 | "projectName": "deer2cpp", 117 | "projectPath": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\deer2cpp.csproj", 118 | "packagesPath": "C:\\Users\\lokino\\.nuget\\packages\\", 119 | "outputPath": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\obj\\", 120 | "projectStyle": "PackageReference", 121 | "crossTargeting": true, 122 | "fallbackFolders": [ 123 | "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" 124 | ], 125 | "configFilePaths": [ 126 | "C:\\Users\\lokino\\AppData\\Roaming\\NuGet\\NuGet.Config", 127 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", 128 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 129 | ], 130 | "originalTargetFrameworks": [ 131 | "net6.0", 132 | "net8.0" 133 | ], 134 | "sources": { 135 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 136 | "https://api.nuget.org/v3/index.json": {} 137 | }, 138 | "frameworks": { 139 | "net6.0": { 140 | "targetAlias": "net6.0", 141 | "projectReferences": {} 142 | }, 143 | "net8.0": { 144 | "targetAlias": "net8.0", 145 | "projectReferences": {} 146 | } 147 | }, 148 | "warningProperties": { 149 | "warnAsError": [ 150 | "NU1605" 151 | ] 152 | }, 153 | "restoreAuditProperties": { 154 | "enableAudit": "true", 155 | "auditLevel": "low", 156 | "auditMode": "direct" 157 | }, 158 | "SdkAnalysisLevel": "9.0.200" 159 | }, 160 | "frameworks": { 161 | "net6.0": { 162 | "targetAlias": "net6.0", 163 | "dependencies": { 164 | "Mono.Cecil": { 165 | "target": "Package", 166 | "version": "[0.11.4, )" 167 | } 168 | }, 169 | "imports": [ 170 | "net461", 171 | "net462", 172 | "net47", 173 | "net471", 174 | "net472", 175 | "net48", 176 | "net481" 177 | ], 178 | "assetTargetFallback": true, 179 | "warn": true, 180 | "frameworkReferences": { 181 | "Microsoft.NETCore.App": { 182 | "privateAssets": "all" 183 | } 184 | }, 185 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.200-preview.0.25057.12\\RuntimeIdentifierGraph.json" 186 | }, 187 | "net8.0": { 188 | "targetAlias": "net8.0", 189 | "dependencies": { 190 | "Mono.Cecil": { 191 | "target": "Package", 192 | "version": "[0.11.4, )" 193 | } 194 | }, 195 | "imports": [ 196 | "net461", 197 | "net462", 198 | "net47", 199 | "net471", 200 | "net472", 201 | "net48", 202 | "net481" 203 | ], 204 | "assetTargetFallback": true, 205 | "warn": true, 206 | "frameworkReferences": { 207 | "Microsoft.NETCore.App": { 208 | "privateAssets": "all" 209 | } 210 | }, 211 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.200-preview.0.25057.12/PortableRuntimeIdentifierGraph.json" 212 | } 213 | } 214 | } 215 | } -------------------------------------------------------------------------------- /obj/project.nuget.cache: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "dgSpecHash": "xnnI2HgXqic=", 4 | "success": true, 5 | "projectFilePath": "C:\\Users\\lokino\\Downloads\\Il2CppDumper-master\\Il2CppDumper-master\\Il2CppDumper\\deer2cpp.csproj", 6 | "expectedPackageFiles": [ 7 | "C:\\Users\\lokino\\.nuget\\packages\\mono.cecil\\0.11.4\\mono.cecil.0.11.4.nupkg.sha512" 8 | ], 9 | "logs": [] 10 | } --------------------------------------------------------------------------------