How to find the offset of the section header string table of an elf file?

前端 未结 4 1557
醉酒成梦
醉酒成梦 2020-12-08 17:48

I have to write a C program that prints an ELF file. I\'m having trouble figuring out where the section header string table is.

Let\'s say I have a file that gave me

相关标签:
4条回答
  • 2020-12-08 18:02

    Here is how you would get to section name string table:

    • The e_shstrndx field of the ELF Executable Header (EHDR) specifies the index of the section header table entry describing the string table containing section names.
    • The e_shentsize field of the EHDR specifies the size in bytes of each section header table entry.
    • The e_shoff field of the EHDR specifies the file offset to the start of the section header table.

    Thus the header entry for the string table will be at file offset:

    header_table_entry_offset = (e_shentsize * e_shstrndx) + e_shoff
    

    Depending on the ELF class of the object, this header table entry will be either an Elf32_Shdr or an Elf64_Shdr. Note that the file representation of the header table entry may differ from its in-memory representation on the host that your program is running on.

    The sh_offset field in the header entry will specify the starting file offset of the string table, while the sh_size field will specify its size.

    Further reading: The "libelf by Example" tutorial covers the ELF Executable Header and ELF Section Header Table in greater depth.

    0 讨论(0)
  • 2020-12-08 18:10

    It seems that the one you want is STRTAB, which has an offset of 0x441c (line [20]). The headers start 17636 bytes into the file (according to

    Start of section headers:          17636 (bytes into file)
    

    So I am going to guess that your string table starts at 17636 + 17436 = 35072 bytes from the start of the file.

    I could be completely wrong, but that's where I would start. Do you know how to use od or some such utility to do a dump of file bytes?

    0 讨论(0)
  • 2020-12-08 18:19

    The section header table starts at starting point of your file + e_shoff. The elf.h file already has Elfxx_Shdr struct and a Elfxx_Ehdr struct, where xx above is either 32 or 64 for 32 bit or 64 bit respectively.

    You can use e_shentsize from the Elfxx_Ehdr to get the section header string table index and then use sh_name and sh_offset from the Elfxx_Shdr. sh_name will give you an index of strtab in which if you add the sh_offset. That will give you the full name of the section. Same for the type, flag and others by using sh_type, sh_flag etc.

    I would suggest you to go over executable and linkable format wikipedia article and the efl.h file man page.

    0 讨论(0)
  • 2020-12-08 18:21

    This is what I do:

    #pragma pack(push,1)
    
    typedef struct
    {
      uint8  e_ident[16];
      uint16 e_type;
      uint16 e_machine;
      uint32 e_version;
      uint32 e_entry;
      uint32 e_phoff;
      uint32 e_shoff;
      uint32 e_flags;
      uint16 e_ehsize;
      uint16 e_phentsize;
      uint16 e_phnum;
      uint16 e_shentsize;
      uint16 e_shnum;
      uint16 e_shstrndx;
    } Elf32Hdr;
    
    typedef struct
    {
      uint32 sh_name;
      uint32 sh_type;
      uint32 sh_flags;
      uint32 sh_addr;
      uint32 sh_offset;
      uint32 sh_size;
      uint32 sh_link;
      uint32 sh_info;
      uint32 sh_addralign;
      uint32 sh_entsize;
    } Elf32SectHdr;
    
    #pragma pack(pop)
    
    {
      FILE* ElfFile = NULL;
      char* SectNames = NULL;
      Elf32Hdr elfHdr;
      Elf32SectHdr sectHdr;
      uint idx;
    
      // ...
    
      // read ELF header
      fread(&elfHdr, 1, sizeof elfHdr, ElfFile);
    
      // read section name string table
      // first, read its header
      fseek(ElfFile, elfHdr.e_shoff + elfHdr.e_shstrndx * sizeof sectHdr, SEEK_SET);
      fread(&sectHdr, 1, sizeof sectHdr, ElfFile);
    
      // next, read the section, string data
      SectNames = malloc(sectHdr.sh_size);
      fseek(ElfFile, sectHdr.sh_offset, SEEK_SET);
      fread(SectNames, 1, sectHdr.sh_size, ElfFile);
    
      // read all section headers
      for (idx = 0; idx < elfHdr.e_shnum; idx++)
      {
        const char* name = "";
    
        fseek(ElfFile, elfHdr.e_shoff + idx * sizeof sectHdr, SEEK_SET);
        fread(&sectHdr, 1, sizeof sectHdr, ElfFile);
    
        // print section name
        if (sectHdr.sh_name);
          name = SectNames + sectHdr.sh_name;
        printf("%2u %s\n", idx, name);
      }
    
      // ...
    }
    
    0 讨论(0)
提交回复
热议问题