protected override bool Init() { elf_header = ReadObject <elf_header>(); if (elf_header.m_dwFormat != 0x464c457f) { // Not an ELF file return(false); } if (elf_header.m_arch == 2)//64 { // 64-bit not supported return(false); } program_table_element = ReadArray <program_header_table>(elf_header.e_phoff, elf_header.e_phnum); return(true); }
protected override bool Init() { selfHeader = ReadObject <SElfHeader>(); // Check for magic bytes if ((SElfConsts)selfHeader.Magic != SElfConsts.Magic) { return(false); } if (selfHeader.Endian != 0x1) { Endianness = Endianness.Big; } // Read entries entries = ReadArray <SElfEntry>(selfHeader.NumberOfEntries); // We can't deal with encrypted or compressed segments right now if (entries.Any(e => e.HasBlocks && e.IsEncrypted)) { throw new NotImplementedException("This file contains encrypted segments not currently supported by Il2CppInspector."); } if (entries.Any(e => e.HasBlocks && e.IsDeflated)) { throw new NotImplementedException("This file contains compressed segments not currently supported by Il2CppInspector."); } // Read ELF header // PS4 files as follows: // m_arch = 0x2 (64-bit) // m_endian = 0x1 (little endian) // m_version = 0x1 (ELF version 1) // m_osabi = 0x9 (FreeBSD) // e_type = special type, see psdevwiki documentation; probably 0xFE10 or 0xFE18 // e_machine = 0x3E (x86-64) var startOfElf = Position; elfHeader = ReadObject <elf_header <ulong> >(); // Must be one of these supported binary types if (elfHeader.e_type != (ushort)Elf.ET_EXEC && elfHeader.e_type != (ushort)SElfETypes.ET_SCE_EXEC && elfHeader.e_type != (ushort)SElfETypes.ET_SCE_DYNEXEC && elfHeader.e_type != (ushort)SElfETypes.ET_SCE_DYNAMIC) { return(false); } // There are no sections, but read all the program headers // Each segment of type PT_LOAD, PT_SCE_RELRO, PT_SCE_DYNLIBDATA and PT_SCE_COMMENT // generates two SELF entries above - one pointing to the ELF segment and one pointing to a digest. // Only p_vaddr is used for memory mapping; all other fields are ignored. // offset, memsz and filesz are taken from the SELF entries. // The digests are all-zero in FSELF files. // All other ELF segments are ignored completely. pht = ReadArray <elf_64_phdr>(startOfElf + (long)elfHeader.e_phoff, elfHeader.e_phnum); // Read extended info sceData = ReadObject <SElfSCEData>(startOfElf + (long)elfHeader.e_phoff + elfHeader.e_phentsize * elfHeader.e_phnum); // Get SELF entries which point to segments defined in phdrs var dataEntries = entries.Where(e => e.HasBlocks).ToList(); // Fixup the used phdr entries foreach (var entry in dataEntries) { pht[entry.SegmentIndex].f_p_filesz = entry.EncryptedCompressedSize; pht[entry.SegmentIndex].f_p_offset = entry.FileOffset; pht[entry.SegmentIndex].f_p_memsz = entry.MemorySize; } // Filter out unused phdr entries var phdrIndices = dataEntries.Select(e => (int)e.SegmentIndex).ToList(); pht = pht.Where((e, i) => phdrIndices.Contains(i)).ToArray(); // Get offset of code section var codeSegment = pht.First(x => ((Elf)x.p_flags & Elf.PF_X) == Elf.PF_X); GlobalOffset = codeSegment.p_vaddr - codeSegment.p_offset; return(true); }