ELF文件结构
ELF(Executable and Linkable Format)文件 可重定位文件(Relocatable File),包含由编译器生成的代码以及数据。链接器会将它与其它目标文件链接起来从而创建可执行文件或者共享目标文件。在 Linux 系统中,这种文件的后缀一般为 .o 。 可执行文件(Executable File),就是通常在 Linux 中执行的程序。 共享目标文件(Shared Object File),包含代码和数据,这种文件称为库文件,一般以 .so 结尾。一般情况下,它有以下两种使用情景: 链接器(ld)可能会处理它和其它可重定位文件以及共享目标文件,生成另外一个目标文件。 动态链接器(Dynamic Linker)将它与可执行文件以及其它共享目标组合在一起生成进程镜像。 ELF文件结构 ELF header(ELF头部):包含有关文件结构的基本信息,如文件编译的体系结构、文件类型(可执行文件、共享对象等)、可执行文件的入口点等。 Program header table(程序头表):描述了在加载和执行可执行文件时,操作系统如何处理文件的各个段(segments)的信息,包括段类型、段偏移、虚拟地址、物理地址、段大小、文件大小、段权限等。只有可执行文件和共享目标文件包含程序头表. Section header table(节头表):描述了ELF文件中每个分区的具体位置,包括节名称、节类型、标志、文件偏移、节区大小、链接信息、对齐信息、附加信息等。 段内容:一个段可能包括一到多个节区,这并不会影响程序的加载。通常包含代码段和数据段。 数据结构 文件头 include/elf.h #define EI_NIDENT (16) typedef struct elf32_hdr{ unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; /* Entry point */ Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; Program header table(程序头表):e_phoff、e_phentsize、e_phnum、e_entry Section header table(节头表): e_shoff、e_shentsize、e_shnum、e_shstrndx(字符串表相关的表项的索引 值) e_ident: 0x00~0x03为 Magic Number(魔数), 0x04指定格式为32位/64位,0x05指定大端/小端模式,0x06为 elf文件版本,0x07为OSABI,0x08为ABI版本,0x09~0x0f为保留位。 e_type(目标文件类型,ET_NONE ET_REL ET_EXEC ET_DYN ET_CORE ET_LOPROC ET_HIPROC) e_machine(机器架构) e_version(文件版本) e_flags(处理器相关标志) e_ehsize(ELF文件头长度) 程序头表 #define PF_R 0x4 #define PF_W 0x2 #define PF_X 0x1 typedef struct elf32_phdr{ Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; p_offset(偏移地址) p_vaddr(虚拟地址) p_paddr(物理地址) p_filez(文件中的大小) p_memsz(内存中的大小) p_align(对齐方式) p_type(段类型) PT_NULL:未使用 PT_LOAD:可加载段 PT_DYNAMIC:动态链接信息 PT_INTERP:此类型段给出了一个以 NULL 结尾的字符串的位置和长度,该字符串将被当作解释器调用。这种段类型仅对可执行文件有意义(也可能出现在共享目标文件中)。这种段在一个文件中最多出现一次。而且这种类型的段若存在,它必须在所有可加载段项的前面。 PT_NOTE:附加信息的位置和长度。 PT_SHLIB:保留 PT_PHDR:给出程序头表自身的大小和位置 PT_TLS:Thread-Local Storage Template(一种基于模板的通用方法,用于创建线程局部存储变量) PT_LOOS:保留范围(依赖操作系统) PT_HIOS:保留范围(依赖操作系统) PT_LOPROC:保留范围(依赖处理器) PT_HIPROC:保留范围(依赖处理器) p_flags(段权限) 代码段:包含只读的数据以及指令。通常包含....