Parcourir la source

LibElf+readelf: Parse ELFs with no program headers correctly

This simply fixes a check which assumed the program header count was
always non zero.
Idan Horowitz il y a 4 ans
Parent
commit
eab151c994
2 fichiers modifiés avec 22 ajouts et 18 suppressions
  1. 1 1
      Userland/Libraries/LibELF/Validation.cpp
  2. 21 17
      Userland/Utilities/readelf.cpp

+ 1 - 1
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);

+ 21 - 17
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");
-
-        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 (!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");
 
-            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");