ELF文件-結構體數據


ELF文件包含文件頭(ELF Header)、程序頭表(Program Head Table)、節(Sections)或段(Segments)、節頭表(Section Header Table)四個部分。ELF文件提供了兩種視圖,分別是鏈接視圖和執行視圖。其中,節是鏈接視圖的基本單位,在文件進行鏈接操作時使用;段是執行視圖的基本單位,在文件運行時使用。一個段可包含一個或多個節,段和節在文件中沒有固定的順序。以下是elf.h中相關結構體的定義。

 

1. 文件頭結構體(ELF Header)

文件頭描述整個文件的組織結構。使用Elf32_EhdrElf64_Ehdr描述。

#define EI_NIDENT (16)

typedef struct
{
    unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
    Elf32_Half    e_type;                 /* Object file type */
    Elf32_Half    e_machine;              /* Architecture */
    Elf32_Word    e_version;              /* Object file version */
    Elf32_Addr    e_entry;                /* Entry point virtual address */
    Elf32_Off     e_phoff;                /* Program header table file offset */
    Elf32_Off     e_shoff;                /* Section header table file offset */
    Elf32_Word    e_flags;                /* Processor-specific flags */
    Elf32_Half    e_ehsize;               /* ELF header size in bytes */
    Elf32_Half    e_phentsize;            /* Program header table entry size */
    Elf32_Half    e_phnum;                /* Program header table entry count */
    Elf32_Half    e_shentsize;            /* Section header table entry size */
    Elf32_Half    e_shnum;                /* Section header table entry count */
    Elf32_Half    e_shstrndx;             /* Section header string table index */
} Elf32_Ehdr;
typedef struct
{
    unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
    Elf64_Half    e_type;                 /* Object file type */
    Elf64_Half    e_machine;              /* Architecture */
    Elf64_Word    e_version;              /* Object file version */
    Elf64_Addr    e_entry;                /* Entry point virtual address */
    Elf64_Off     e_phoff;                /* Program header table file offset */
    Elf64_Off     e_shoff;                /* Section header table file offset */
    Elf64_Word    e_flags;                /* Processor-specific flags */
    Elf64_Half    e_ehsize;               /* ELF header size in bytes */
    Elf64_Half    e_phentsize;            /* Program header table entry size */
    Elf64_Half    e_phnum;                /* Program header table entry count */
    Elf64_Half    e_shentsize;            /* Section header table entry size */
    Elf64_Half    e_shnum;                /* Section header table entry count */
    Elf64_Half    e_shstrndx;             /* Section header string table index */
} Elf64_Ehdr;

以上,

e_ident 字段前四位為文件標識,一般為“\x7fELF”,通過這四位,可以查看該文件是否為ELF文件。

e_type  字段表示ELF文件的類型,如ET_REL表示可重定位文件,ET_EXEC表示可執行文件,ET_DYN表示共享目標文件。

e_phoff 字段表示程序頭表在文件中的偏移,可根據該字段找到程序頭表的起始地址。

e_shoff 字段表示節頭表在文件中的偏移,可根據該字段找到節頭表的起始地址。

e_shstrndx 字段表示字符串表在節頭表中的索引,一般為節頭表中的最后一個,即e_shstrndx=e_shnum-1。

 

2. 程序頭結構體(Program Header)

程序頭表描述文件中各種段的信息。每個程序頭的結構體定義如下,使用Elf32_PhdrElf64_Phdr描述。

typedef struct
{
    Elf32_Word  p_type;          /* Segment type */
    Elf32_Off   p_offset;        /* Segment file offset */
    Elf32_Addr  p_vaddr;         /* Segment virtual address */
    Elf32_Addr  p_paddr;         /* Segment physical address */
    Elf32_Word  p_filesz;        /* Segment size in file */
    Elf32_Word  p_memsz;         /* Segment size in memory */
    Elf32_Word  p_flags;         /* Segment flags */
    Elf32_Word  p_align;         /* Segment alignment */
}Elf32_Phdr;
typedef struct
{
    Elf64_Word  p_type;          /* Segment type */
    Elf64_Word  p_flags;         /* Segment flags */
    Elf64_Off   p_offset;        /* Segment file offset */
    Elf64_Addr  p_vaddr;         /* Segment virtual address */
    Elf64_Addr  p_paddr;         /* Segment physical address */
    Elf64_Xword p_filesz;        /* Segment size in file */
    Elf64_Xword p_memsz;         /* Segment size in memory */
    Elf64_Xword p_align;         /* Segment alignment */
}Elf64_Phdr;

以上,

p_type 字段表示該段的類型,如果值為PT_LOAD,則表示該段是一個可加載到內存中的段,且必須滿足 p_memsz ≥ p_filesz ,多出的字節清零,否則該段的內容不能完全加載。在程序頭表中,所有PT_LOAD類型的程序頭都按照p_vaddr的值升序排列。

 

3. 節頭結構體(Section Header)

節頭表描述文件中各種節的信息。每個節頭的結構體定義如下,使用Elf32_ShdrElf64_Shdr描述。

typedef struct
{
    Elf32_Word  sh_name;       /* Section name (string tbl index) */
    Elf32_Word  sh_type;       /* Section type */
    Elf32_Word  sh_flags;      /* Section flags */
    Elf32_Addr  sh_addr;       /* Section virtual addr at execution */
    Elf32_Off   sh_offset;     /* Section file offset */
    Elf32_Word  sh_size;       /* Section size in bytes */
    Elf32_Word  sh_link;       /* Link to another section */
    Elf32_Word  sh_info;       /* Additional section information */
    Elf32_Word  sh_addralign;  /* Section alignment */
    Elf32_Word  sh_entsize;    /* Entry size if section holds table */
}Elf32_Shdr;
typedef struct
{
    Elf64_Word   sh_name;      /* Section name (string tbl index) */
    Elf64_Word   sh_type;      /* Section type */
    Elf64_Xword  sh_flags;     /* Section flags */
    Elf64_Addr   sh_addr;      /* Section virtual addr at execution */
    Elf64_Off    sh_offset;    /* Section file offset */
    Elf64_Xword  sh_size;      /* Section size in bytes */
    Elf64_Word   sh_link;      /* Link to another section */
    Elf64_Word   sh_info;      /* Additional section information */
    Elf64_Xword  sh_addralign; /* Section alignment */
    Elf64_Xword  sh_entsize;   /* Entry size if section holds table */
}Elf64_Shdr;

以上,

sh_name 字段指出節的名字索引,節名字符串以'\0'結尾,統一存儲在字符串表中,然后該字段的值就表示對應節名字符串在字符串表中的索引。

 

4. 字符串表

字符串表存儲ELF文件中的節名、符號名等字符串,下面是一個示例,來說明字符串表的存儲方式。

假設字符串表如下所示:

則可以理解為:

如示例所示,字符串表索引可以引用節中的任何字節。字符串可以出現多次(11,16);可能存在對子字符串的引用(7,11);一個字符串可能被引用多次;也允許未引用的字符串(索引為22的"xx"字符串)。

下面是從字符串表中獲取節名字符串的偽代碼示例:

//The target is to get a section's name
//1. get sh_name
index = section_head_table[i]->sh_name;
//2. find string_table
string_table = section_head_table[e_shstrndx]->sh_offset;
//3. get name
name = string_table + index;

 

補充一個PDF文件鏈接:Tool Interface Standard (TIS)Executable and Linking Format (ELF) Specification [Version 1.2](全方位帶你了解ELF文件結構)

參考資料

1. ELF文件格式解析

2. ELF文件格式分析(ELF文件頭)

3. ELF文件-段和程序頭

4. ELF文件-節和節頭

5. 字符串表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM