diff --git a/Il2CppInspector.Common/FileFormatReaders/ElfReader.cs b/Il2CppInspector.Common/FileFormatReaders/ElfReader.cs index 4d7bc48..73eb519 100644 --- a/Il2CppInspector.Common/FileFormatReaders/ElfReader.cs +++ b/Il2CppInspector.Common/FileFormatReaders/ElfReader.cs @@ -463,6 +463,39 @@ namespace Il2CppInspector return init_array.Select(x => MapVATR(x)).ToArray(); } + public override IEnumerable
GetSections() { + // If the sections have been stripped, use the segment list from the PHT instead + if (section_header_table.All(s => conv.Int(s.sh_offset) == 0)) { + return program_header_table.Select(p => new Section { + VirtualStart = conv.ULong(p.p_vaddr), + VirtualEnd = conv.ULong(p.p_vaddr) + conv.ULong(p.p_memsz) - 1, + ImageStart = (uint) conv.Int(p.p_offset), + ImageEnd = (uint) conv.Int(p.p_offset) + (uint) conv.Int(p.p_filesz) - 1, + + // Not correct but probably the best we can do + IsData = (Elf) p.p_type == Elf.PT_LOAD, + IsExec = (Elf) p.p_type == Elf.PT_LOAD, + IsBSS = (Elf) p.p_type == Elf.PT_LOAD, + + Name = string.Empty + }); + } + + // Return sections list + return section_header_table.Select(s => new Section { + VirtualStart = conv.ULong(s.sh_addr), + VirtualEnd = conv.ULong(s.sh_addr) + conv.ULong(s.sh_size) - 1, + ImageStart = (uint) conv.Int(s.sh_offset), + ImageEnd = (uint) conv.Int(s.sh_offset) + (uint) conv.Int(s.sh_size) - 1, + + IsData = ((Elf) conv.Int(s.sh_flags) & Elf.SHF_ALLOC) == Elf.SHF_ALLOC && ((Elf) conv.Int(s.sh_flags) & Elf.SHF_EXECINSTR) == 0 && ((Elf) s.sh_type & Elf.SHT_PROGBITS) == Elf.SHT_PROGBITS, + IsExec = ((Elf) conv.Int(s.sh_flags) & Elf.SHF_EXECINSTR) == Elf.SHF_EXECINSTR && ((Elf) s.sh_type & Elf.SHT_PROGBITS) == Elf.SHT_PROGBITS, + IsBSS = ((Elf) s.sh_type & Elf.SHT_NOBITS) == Elf.SHT_NOBITS, + + Name = sectionByName.First(sbn => conv.Int(sbn.Value.sh_offset) == conv.Int(s.sh_offset)).Key + }); + } + // Map a virtual address to an offset into the image file. Throws an exception if the virtual address is not mapped into the file. // Note if uiAddr is a valid segment but filesz < memsz and the adjusted uiAddr falls between the range of filesz and memsz, // an exception will be thrown. This area of memory is assumed to contain all zeroes. diff --git a/Il2CppInspector.Common/FileFormatReaders/FormatLayouts/Elf.cs b/Il2CppInspector.Common/FileFormatReaders/FormatLayouts/Elf.cs index 518aa6b..2f1b8b8 100644 --- a/Il2CppInspector.Common/FileFormatReaders/FormatLayouts/Elf.cs +++ b/Il2CppInspector.Common/FileFormatReaders/FormatLayouts/Elf.cs @@ -37,9 +37,11 @@ namespace Il2CppInspector PF_X = 1, // SHTs + SHT_PROGBITS = 1, SHT_SYMTAB = 2, SHT_STRTAB = 3, SHT_RELA = 4, + SHT_NOBITS = 8, SHT_REL = 9, SHT_DYNSYM = 11, @@ -59,6 +61,10 @@ namespace Il2CppInspector STT_SPARC_REGISTER = 13, STT_HIPROC = 15, + // SHFs + SHF_ALLOC = 2, + SHF_EXECINSTR = 4, + // dynamic sections DT_STRTAB = 5, DT_SYMTAB = 6, @@ -146,6 +152,7 @@ namespace Il2CppInspector uint p_type { get; } TWord p_offset { get; } TWord p_filesz { get; } + TWord p_memsz { get; } TWord p_vaddr { get; } uint p_flags { get; } } @@ -157,13 +164,14 @@ namespace Il2CppInspector public uint p_filesz => f_p_filesz; public uint p_vaddr => f_p_vaddr; public uint p_flags => f_p_flags; + public uint p_memsz => f_p_memsz; public uint f_p_type; public uint f_p_offset; public uint f_p_vaddr; public uint p_paddr; public uint f_p_filesz; - public uint p_memsz; + public uint f_p_memsz; public uint f_p_flags; public uint p_align; } @@ -173,6 +181,7 @@ namespace Il2CppInspector public uint p_type => f_p_type; public ulong p_offset => f_p_offset; public ulong p_filesz => f_p_filesz; + public ulong p_memsz => f_p_memsz; public ulong p_vaddr => f_p_vaddr; public uint p_flags => f_p_flags; @@ -182,7 +191,7 @@ namespace Il2CppInspector public ulong f_p_vaddr; public ulong p_paddr; public ulong f_p_filesz; - public ulong p_memsz; + public ulong f_p_memsz; public ulong p_align; }