ELF(Executable and Linking Format)格式教學文件, #7: 讀 ELF 的 Section Name(透過 strtab)

jollen 發表於 December 4, 2006 5:25 PM

根據 SysV ABI 的定義,若 section 的類型為 SHT_STRTAB,則該 section entry 即為 string table 的 section header。Section 的類型可由 section header 的 sh_type 欄位來判斷,SysV ABI 定義的 section 類型(sh_type)如下表所示。

sh_type 欄位的定義

Name  Value
SHT_NULL  0
SHT_PROGBITS  1
SHT_SYMTAB  2
SHT_STRTAB  3
SHT_RELA  4
SHT_HASH  5
SHT_DYNAMIC  6
SHT_NOTE  7
SHT_NOBITS  8
SHT_REL  9
SHT_SHLIB  10
SHT_DYNSYM  11
SHT_LOPROC  0x70000000
SHT_HIPROC  0x7fffffff
SHT_LOUSER  0x80000000
SHT_HIUSER  0xffffffff

我們在範例程式 loader-0.3.c 中,試著由一堆的 section 裡找出類型為 string table(SHT_STRTAB)的section。接下來程式 loader-0.4.c 將會試著實作讀取 ELF 的 string table,並將有 section 的名稱印出。

讀取 Section Name String Table

String table 是一個特殊的 section,此 section 紀錄所有 section 的名稱(ASCII 字串)。String table 是一個字元型別的陣列,每一個 section 都會有一個索引值來索引自己的 section name 字串,section header sh_name 欄位則是存放了此索引值,如圖所示。

elf_strtab.JPG

圖 ELF section name string table

接下來的範例程式將不再直接列表,請大家由 http://tw.jollen.org/elf-programming 下載。

程式說明

呼叫了 parse_sections() 函數來讀取section header table:

parse_sections(&f_header, fd);

相較於 loader-0.3.cparse_sections() 函數,在 0.4 的版本裡,我們所做的改變如下:

1. 讀取 string table 的內容
2. 列印所有 section 的名稱

首先,我們新增一個陣列來存放 string table 的內容:

char strtab[65535];

接下來一樣讀取所有的 section entry,並且找出 string table:

   for (i = 0; i < hdr->e_shnum; i++) {
      read(fd, &header_ent[i], sizeof(Elf32_Shdr));

      /* load section name string table */
      if (i == hdr->e_shstrndx) {
         sh_strtab = &header_ent[i];
      }
   }

我們試著用另外一種方法來找出 string table 吧!根據 SysV ABI 的定義,string table 在 section header table 裡的 section entry index(索引值)紀錄在 ELF header 的 e_shstrndx 欄位,因此,我們判斷目前的 section header table 索引值是否等於 e_shstrndx 來找出 string table。接下來再讀取string table 的內容:

   /* read “String Table” */
   lseek(fd, sh_strtab->sh_offset, SEEK_SET);
   read(fd, strtab, sh_strtab->sh_size);

程式裡利用 lseek() 函數將檔案讀寫指標移 string table 開始的地方,然後再將整個 string table 讀出。要注意的是,section 的長度紀錄於 section header裡的 sh_size 欄位。最後再逐一將每個section的名稱列印在螢幕上:

   /* Index 0: undefined */
   for (i = 1; i < hdr->e_shnum; i++) {
      printf("%s\n", &strtab[header_ent[i].sh_name]);
   }

小結

我們知道一個很重要的觀念了。ELF section 的字串名稱是由 string table 查表得知,section 名稱在 string table 陣列裡的索引值則是紀錄在 section header 裡的 sh_name 欄位。

Also See

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw