From eab151c9945d2f3e57101b80ba8a365adb345160 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Mon, 29 Mar 2021 15:14:41 +0300 Subject: [PATCH] LibElf+readelf: Parse ELFs with no program headers correctly This simply fixes a check which assumed the program header count was always non zero. --- Userland/Libraries/LibELF/Validation.cpp | 2 +- Userland/Utilities/readelf.cpp | 36 +++++++++++++----------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Userland/Libraries/LibELF/Validation.cpp b/Userland/Libraries/LibELF/Validation.cpp index 403353cdde..2b48c17672 100644 --- a/Userland/Libraries/LibELF/Validation.cpp +++ b/Userland/Libraries/LibELF/Validation.cpp @@ -95,7 +95,7 @@ bool validate_elf_header(const Elf32_Ehdr& elf_header, size_t file_size, bool ve return false; } - if (elf_header.e_phoff < elf_header.e_ehsize || (elf_header.e_shnum != SHN_UNDEF && elf_header.e_shoff < elf_header.e_ehsize)) { + if ((elf_header.e_phnum != 0 && elf_header.e_phoff < elf_header.e_ehsize) || (elf_header.e_shnum != SHN_UNDEF && elf_header.e_shoff < elf_header.e_ehsize)) { if (verbose) { dbgln("SHENANIGANS! program header offset ({}) or section header offset ({}) overlap with ELF header!", elf_header.e_phoff, elf_header.e_shoff); diff --git a/Userland/Utilities/readelf.cpp b/Userland/Utilities/readelf.cpp index a22750f743..3024d765e7 100644 --- a/Userland/Utilities/readelf.cpp +++ b/Userland/Utilities/readelf.cpp @@ -552,25 +552,29 @@ int main(int argc, char** argv) printf("\n"); } - printf("Program Headers:\n"); - printf(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"); + if (!elf_image.program_header_count()) { + printf("There are no program headers in this file.\n"); + } else { + printf("Program Headers:\n"); + printf(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"); - elf_image.for_each_program_header([](const ELF::Image::ProgramHeader& program_header) { - printf(" %-14s ", object_program_header_type_to_string(program_header.type())); - printf("0x%08x ", program_header.offset()); - printf("%p ", program_header.vaddr().as_ptr()); - printf("%p ", program_header.vaddr().as_ptr()); // FIXME: assumes PhysAddr = VirtAddr - printf("0x%08x ", program_header.size_in_image()); - printf("0x%08x ", program_header.size_in_memory()); - printf("%04x ", program_header.flags()); - printf("0x%08x", program_header.alignment()); - printf("\n"); + elf_image.for_each_program_header([](const ELF::Image::ProgramHeader& program_header) { + printf(" %-14s ", object_program_header_type_to_string(program_header.type())); + printf("0x%08x ", program_header.offset()); + printf("%p ", program_header.vaddr().as_ptr()); + printf("%p ", program_header.vaddr().as_ptr()); // FIXME: assumes PhysAddr = VirtAddr + printf("0x%08x ", program_header.size_in_image()); + printf("0x%08x ", program_header.size_in_memory()); + printf("%04x ", program_header.flags()); + printf("0x%08x", program_header.alignment()); + printf("\n"); - if (program_header.type() == PT_INTERP) - printf(" [Interpreter: %s]\n", program_header.raw_data()); + if (program_header.type() == PT_INTERP) + printf(" [Interpreter: %s]\n", program_header.raw_data()); - return IterationDecision::Continue; - }); + return IterationDecision::Continue; + }); + } // TODO: Display section to segment mapping printf("\n");