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

匿名 (未验证) 提交于 2019-12-03 01:52:01

问题:

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 the following output with:

readelf -h

ELF Header:   Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00    Class:                             ELF32   Data:                              2's complement, little endian   Version:                           1 (current)   OS/ABI:                            UNIX - System V   ABI Version:                       0   Type:                              REL (Relocatable file)     Machine:                           Intel 80386   Version:                           0x1   Entry point address:               0x0   Start of program headers:          0 (bytes into file)   Start of section headers:          17636 (bytes into file)   Flags:                             0x0   Size of this header:               52 (bytes)   Size of program headers:           0 (bytes)   Number of program headers:         0   Size of section headers:           40 (bytes)   Number of section headers:         23   Section header string table index: 20

and with:

readelf -S:

There are 23 section headers, starting at offset 0x44e4: Section Headers:   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al   [ 0]                   NULL            00000000 000000 000000 00      0   0  0   [ 1] .text             PROGBITS        00000000 000034 000028 00  AX  0   0  4   [ 2] .rel.text         REL             00000000 0049d0 000018 08     21   1  4   [ 3] .data             PROGBITS        00000000 00005c 000000 00  WA  0   0  4   [ 4] .bss              NOBITS          00000000 00005c 000000 00  WA  0   0  4   [ 5] .rodata           PROGBITS        00000000 00005c 00000a 00   A  0   0  1   [ 6] .debug_info       PROGBITS        00000000 000066 00008f 00      0   0  1   [ 7] .rel.debug_info   REL             00000000 0049e8 0000b0 08     21   6  4   [ 8] .debug_abbrev     PROGBITS        00000000 0000f5 000041 00      0   0  1   [ 9] .debug_loc        PROGBITS        00000000 000136 000038 00      0   0  1   [10] .debug_aranges    PROGBITS        00000000 00016e 000020 00      0   0  1   [11] .rel.debug_arange REL             00000000 004a98 000010 08     21  10  4   [12] .debug_line       PROGBITS        00000000 00018e 0001b3 00      0   0  1   [13] .rel.debug_line   REL             00000000 004aa8 000008 08     21  12  4   [14] .debug_macinfo    PROGBITS        00000000 000341 003fb9 00      0   0  1   [15] .debug_str        PROGBITS        00000000 0042fa 0000bf 01  MS  0   0  1   [16] .comment          PROGBITS        00000000 0043b9 00002b 01  MS  0   0  1   [17] .note.GNU-stack   PROGBITS        00000000 0043e4 000000 00      0   0  1   [18] .eh_frame         PROGBITS        00000000 0043e4 000038 00   A  0   0  4   [19] .rel.eh_frame     REL             00000000 004ab0 000008 08     21  18  4   [20] .shstrtab         STRTAB          00000000 00441c 0000c5 00      0   0  1   [21] .symtab           SYMTAB          00000000 00487c 000130 10     22  16  4   [22] .strtab           STRTAB          00000000 0049ac 000021 00      0   0  1 Key to Flags:   W (write), A (alloc), X (execute), M (merge), S (strings)   I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)   O (extra OS processing required) o (OS specific), p (processor specific)

How would I be able to calculate the location of the section header string table?

回答1:

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 


回答2:

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.



回答3:

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?



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!