【源码分析】ELF 文件格式分析

源码文件在 /usr/include/elf.h 中,说明可用 man ELF 来查看

本文会在 ELF 手册 的基础上补充 elf.h 中的内容

基本数据类型 - Basic types

ElfN_Addr       Unsigned program address, uintN_t
ElfN_Off        Unsigned file offset, uintN_t
ElfN_Section    Unsigned section index, uint16_t
ElfN_Versym     Unsigned version symbol information, uint16_t
Elf_Byte        unsigned char
ElfN_Half       uint16_t
ElfN_Sword      int32_t
ElfN_Word       uint32_t
ElfN_Sxword     int64_t
ElfN_Xword      uint64_t

ELF 文件头 - ELF header (ElfN_Ehdr)

#define EI_NIDENT 16

typedef struct{
    unsigned char e_ident[EI_NIDENT];
    uint16_t      e_type;
    uint16_t      e_machine;
    uint32_t      e_version;
    ElfN_Addr     e_entry;
    ElfN_Off      e_phoff;
    ElfN_Off      e_shoff;
    uint32_t      e_flags;
    uint16_t      e_ehsize;
    uint16_t      e_phentsize;
    uint16_t      e_phnum;
    uint16_t      e_shentsize;
    uint16_t      e_shnum;
    uint16_t      e_shstrndx;
} ElfN_Ehdr;

后面对应元素的表示都为 (下标:值)的形式

e_ident

EI_MAG0  (e_ident[0]: '\x7f') 魔数,不能修改

EI_MAG1  (e_ident[1]: 'E') 魔数,不能修改

EI_MAG2  (e_ident[2]: 'L') 魔数,不能修改

EI_MAG3  (e_ident[3]: 'F') 魔数,不能修改

EI_CLASS 用于指定该二进制文件的架构

         ELFCLASSNONE  (e_ident[4]: '\x00') 非法的架构
         ELFCLASS32    (e_ident[4]: '\x01') 32位架构
         ELFCLASS64    (e_ident[4]: '\x02') 64位架构

EI_DATA  用于指定该二进制文件的数据编码格式

         ELFDATANONE   (e_ident[5]: '\x00') 非法的格式
         ELFDATA2LSB   (e_ident[5]: '\x01') 小端序格式
         ELFDATA2MSB   (e_ident[5]: '\x02') 大端序格式

EI_VERSION 
         用于指定该二进制文件的版本号,说是值一定要为
         EV_CURRENT,但实际测试表明该项可以是任意值

         EV_NONE       (e_ident[6]: '\x00') 非法的版本
         EV_CURRENT    (e_ident[6]: '\x01') 当前的版本

EI_OSABI 对其他架构的 ABI 接口标识

         ELFOSABI_NONE        (e_ident[7]: '\x00') UNIX System V ABI
         ELFOSABI_SYSV        (e_ident[7]: '\x00') UNIX System V ABI(Alias)
         ELFOSABI_HPUX        (e_ident[7]: '\x01') HP - UX ABI
         ELFOSABI_NETBSD      (e_ident[7]: '\x02') NetBSD ABI
         ELFOSABI_GNU         (e_ident[7]: '\x03') Linux ABI
         ELFOSABI_LINUX       (e_ident[7]: '\x03') Linux ABI(Alias)
         ELFOSABI_SOLARIS     (e_ident[7]: '\x06') Solaris ABI
         ELFOSABI_AIX         (e_ident[7]: '\x07') IBM AIX ABI
         ELFOSABI_IRIX        (e_ident[7]: '\x08') IRIX ABI
         ELFOSABI_FREEBSD     (e_ident[7]: '\x09') FreeBSD ABI
         ELFOSABI_TRU64       (e_ident[7]: '\x0a') TRU64 UNIX ABI
         ELFOSABI_MODESTO     (e_ident[7]: '\x0b') Novell Modesto ABI
         ELFOSABI_OPENBSD     (e_ident[7]: '\x0c') OpenBSD ABI
         ELFOSABI_ARM_AEABI   (e_ident[7]: '\x40') ARM EABI
         ELFOSABI_ARM         (e_ident[7]: '\x61') ARM architecture ABI
         ELFOSABI_STANDALONE  (e_ident[7]: '\xff') Stand - alone(embedded) ABI

EI_ABIVERSION
         该项依赖于 EI_OSABI,若该二进制文件和其中的 ABI 兼容,
         那么该项的值为 0  (e_ident[8]: '\x00')

EI_PAD   预留位,以后如果有需要会启用 (e_ident[9-15]: '\x00')

经测试这一元素最大限度可以修改为(可修改的数据标为 x)

00000000: 7f45 4c46 xxxx xxxx xxxx xxxx xxxx xxxx  .ELF............
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注