美文网首页逆向
ELF文件结构

ELF文件结构

作者: minhelloworld | 来源:发表于2020-05-12 16:34 被阅读0次

    作为一名Android开发工程师,尤其是音视频领域,NDK开发一直都是主流,但是我们是否有认真了解过我们经常使用的.so等文件具体是怎样的一个格式呢??

    一、ELF简介

    ELF(Executableand Linking Format 可执行和链接格式),ELF文件格式是一个开放标准,各种UNIX系统的可执行文件都采用ELF格式,它有三种不同的类型:

    1. 可重定位的目标文件(Relocatable)也就是通常称的目标文件,后缀为.o
    2. 可执行文件(Executable)
    3. 共享库(Shared Object)共享文件:也就是通常称的库文件,后缀为.so

    二、ELF文件结构

    elf-file-format

    注意:段(Segment)与节(Section)的区别。很多地方对两者有所混淆。段是程序执行的必要组成,当多个目标文件链接成一个可执行文件时,会将相同权限的节合并到一个段中。相比而言,节的粒度更小。

    如图所示,为ELF文件的基本结构,其主要由四部分组成:

    • ELF Header
    • ELF Program Header Table (或称Program Headers、程序头)
    • ELF Section Header Table (或称Section Headers、节头表)
    • ELF Sections

    从图中,我们就能看出它们各自的数据结构以及相互之间的索引关系。

    三、ELF示例

    如下是一个C语言的Hello world示例,来帮助我们理解ELF文件类型:

    #include <stdio.h>
    int main() {
       printf("Hello, World!");
       return 0;
    }
    

    使用如下命令编译:

    gcc hello_world.c -o hello_world
    

    在编译完成后,使用如下命令查看编译完成后的hello_worldELF文件信息:

    readelf -a hello_world
    

    显示信息如下:

    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0x400430
      Start of program headers:          64 (bytes into file)
      Start of section headers:          6624 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         9
      Size of section headers:           64 (bytes)
      Number of section headers:         31
      Section header string table index: 28
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .interp           PROGBITS         0000000000400238  00000238
           000000000000001c  0000000000000000   A       0     0     1
      [ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
           0000000000000020  0000000000000000   A       0     0     4
      [ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
           0000000000000024  0000000000000000   A       0     0     4
      [ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
           000000000000001c  0000000000000000   A       5     0     8
      [ 5] .dynsym           DYNSYM           00000000004002b8  000002b8
           0000000000000060  0000000000000018   A       6     1     8
      [ 6] .dynstr           STRTAB           0000000000400318  00000318
           000000000000003f  0000000000000000   A       0     0     1
      [ 7] .gnu.version      VERSYM           0000000000400358  00000358
           0000000000000008  0000000000000002   A       5     0     2
      [ 8] .gnu.version_r    VERNEED          0000000000400360  00000360
           0000000000000020  0000000000000000   A       6     1     8
      [ 9] .rela.dyn         RELA             0000000000400380  00000380
           0000000000000018  0000000000000018   A       5     0     8
      [10] .rela.plt         RELA             0000000000400398  00000398
           0000000000000030  0000000000000018  AI       5    24     8
      [11] .init             PROGBITS         00000000004003c8  000003c8
           000000000000001a  0000000000000000  AX       0     0     4
      [12] .plt              PROGBITS         00000000004003f0  000003f0
           0000000000000030  0000000000000010  AX       0     0     16
      [13] .plt.got          PROGBITS         0000000000400420  00000420
           0000000000000008  0000000000000000  AX       0     0     8
      [14] .text             PROGBITS         0000000000400430  00000430
           0000000000000182  0000000000000000  AX       0     0     16
      [15] .fini             PROGBITS         00000000004005b4  000005b4
           0000000000000009  0000000000000000  AX       0     0     4
      [16] .rodata           PROGBITS         00000000004005c0  000005c0
           0000000000000012  0000000000000000   A       0     0     4
      [17] .eh_frame_hdr     PROGBITS         00000000004005d4  000005d4
           0000000000000034  0000000000000000   A       0     0     4
      [18] .eh_frame         PROGBITS         0000000000400608  00000608
           00000000000000f4  0000000000000000   A       0     0     8
      [19] .init_array       INIT_ARRAY       0000000000600e10  00000e10
           0000000000000008  0000000000000000  WA       0     0     8
      [20] .fini_array       FINI_ARRAY       0000000000600e18  00000e18
           0000000000000008  0000000000000000  WA       0     0     8
      [21] .jcr              PROGBITS         0000000000600e20  00000e20
           0000000000000008  0000000000000000  WA       0     0     8
      [22] .dynamic          DYNAMIC          0000000000600e28  00000e28
           00000000000001d0  0000000000000010  WA       6     0     8
      [23] .got              PROGBITS         0000000000600ff8  00000ff8
           0000000000000008  0000000000000008  WA       0     0     8
      [24] .got.plt          PROGBITS         0000000000601000  00001000
           0000000000000028  0000000000000008  WA       0     0     8
      [25] .data             PROGBITS         0000000000601028  00001028
           0000000000000010  0000000000000000  WA       0     0     8
      [26] .bss              NOBITS           0000000000601038  00001038
           0000000000000008  0000000000000000  WA       0     0     1
      [27] .comment          PROGBITS         0000000000000000  00001038
           0000000000000035  0000000000000001  MS       0     0     1
      [28] .shstrtab         STRTAB           0000000000000000  000018d4
           000000000000010c  0000000000000000           0     0     1
      [29] .symtab           SYMTAB           0000000000000000  00001070
           0000000000000648  0000000000000018          30    47     8
      [30] .strtab           STRTAB           0000000000000000  000016b8
           000000000000021c  0000000000000000           0     0     1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
      I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
      O (extra OS processing required) o (OS specific), p (processor specific)
    
    There are no section groups in this file.
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                     0x00000000000001f8 0x00000000000001f8  R E    8
      INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                     0x000000000000001c 0x000000000000001c  R      1
          [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
      LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                     0x00000000000006fc 0x00000000000006fc  R E    200000
      LOAD           0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
                     0x0000000000000228 0x0000000000000230  RW     200000
      DYNAMIC        0x0000000000000e28 0x0000000000600e28 0x0000000000600e28
                     0x00000000000001d0 0x00000000000001d0  RW     8
      NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254
                     0x0000000000000044 0x0000000000000044  R      4
      GNU_EH_FRAME   0x00000000000005d4 0x00000000004005d4 0x00000000004005d4
                     0x0000000000000034 0x0000000000000034  R      4
      GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                     0x0000000000000000 0x0000000000000000  RW     10
      GNU_RELRO      0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
                     0x00000000000001f0 0x00000000000001f0  R      1
    
     Section to Segment mapping:
      Segment Sections...
       00     
       01     .interp 
       02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 
       03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 
       04     .dynamic 
       05     .note.ABI-tag .note.gnu.build-id 
       06     .eh_frame_hdr 
       07     
       08     .init_array .fini_array .jcr .dynamic .got 
    
    Dynamic section at offset 0xe28 contains 24 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
     0x000000000000000c (INIT)               0x4003c8
     0x000000000000000d (FINI)               0x4005b4
     0x0000000000000019 (INIT_ARRAY)         0x600e10
     0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
     0x000000000000001a (FINI_ARRAY)         0x600e18
     0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
     0x000000006ffffef5 (GNU_HASH)           0x400298
     0x0000000000000005 (STRTAB)             0x400318
     0x0000000000000006 (SYMTAB)             0x4002b8
     0x000000000000000a (STRSZ)              63 (bytes)
     0x000000000000000b (SYMENT)             24 (bytes)
     0x0000000000000015 (DEBUG)              0x0
     0x0000000000000003 (PLTGOT)             0x601000
     0x0000000000000002 (PLTRELSZ)           48 (bytes)
     0x0000000000000014 (PLTREL)             RELA
     0x0000000000000017 (JMPREL)             0x400398
     0x0000000000000007 (RELA)               0x400380
     0x0000000000000008 (RELASZ)             24 (bytes)
     0x0000000000000009 (RELAENT)            24 (bytes)
     0x000000006ffffffe (VERNEED)            0x400360
     0x000000006fffffff (VERNEEDNUM)         1
     0x000000006ffffff0 (VERSYM)             0x400358
     0x0000000000000000 (NULL)               0x0
    
    Relocation section '.rela.dyn' at offset 0x380 contains 1 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000600ff8  000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
    
    Relocation section '.rela.plt' at offset 0x398 contains 2 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000601018  000100000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0
    000000601020  000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
    
    The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
    
    Symbol table '.dynsym' contains 4 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
         2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
         3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    
    Symbol table '.symtab' contains 67 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1 
         2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2 
         3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3 
         4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4 
         5: 00000000004002b8     0 SECTION LOCAL  DEFAULT    5 
         6: 0000000000400318     0 SECTION LOCAL  DEFAULT    6 
         7: 0000000000400358     0 SECTION LOCAL  DEFAULT    7 
         8: 0000000000400360     0 SECTION LOCAL  DEFAULT    8 
         9: 0000000000400380     0 SECTION LOCAL  DEFAULT    9 
        10: 0000000000400398     0 SECTION LOCAL  DEFAULT   10 
        11: 00000000004003c8     0 SECTION LOCAL  DEFAULT   11 
        12: 00000000004003f0     0 SECTION LOCAL  DEFAULT   12 
        13: 0000000000400420     0 SECTION LOCAL  DEFAULT   13 
        14: 0000000000400430     0 SECTION LOCAL  DEFAULT   14 
        15: 00000000004005b4     0 SECTION LOCAL  DEFAULT   15 
        16: 00000000004005c0     0 SECTION LOCAL  DEFAULT   16 
        17: 00000000004005d4     0 SECTION LOCAL  DEFAULT   17 
        18: 0000000000400608     0 SECTION LOCAL  DEFAULT   18 
        19: 0000000000600e10     0 SECTION LOCAL  DEFAULT   19 
        20: 0000000000600e18     0 SECTION LOCAL  DEFAULT   20 
        21: 0000000000600e20     0 SECTION LOCAL  DEFAULT   21 
        22: 0000000000600e28     0 SECTION LOCAL  DEFAULT   22 
        23: 0000000000600ff8     0 SECTION LOCAL  DEFAULT   23 
        24: 0000000000601000     0 SECTION LOCAL  DEFAULT   24 
        25: 0000000000601028     0 SECTION LOCAL  DEFAULT   25 
        26: 0000000000601038     0 SECTION LOCAL  DEFAULT   26 
        27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27 
        28: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
        29: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
        30: 0000000000400460     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones
        31: 00000000004004a0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones
        32: 00000000004004e0     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
        33: 0000000000601038     1 OBJECT  LOCAL  DEFAULT   26 completed.7594
        34: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   20 __do_global_dtors_aux_fin
        35: 0000000000400500     0 FUNC    LOCAL  DEFAULT   14 frame_dummy
        36: 0000000000600e10     0 OBJECT  LOCAL  DEFAULT   19 __frame_dummy_init_array_
        37: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello_world.c
        38: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
        39: 00000000004006f8     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
        40: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   21 __JCR_END__
        41: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
        42: 0000000000600e18     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_end
        43: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   22 _DYNAMIC
        44: 0000000000600e10     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_start
        45: 00000000004005d4     0 NOTYPE  LOCAL  DEFAULT   17 __GNU_EH_FRAME_HDR
        46: 0000000000601000     0 OBJECT  LOCAL  DEFAULT   24 _GLOBAL_OFFSET_TABLE_
        47: 00000000004005b0     2 FUNC    GLOBAL DEFAULT   14 __libc_csu_fini
        48: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
        49: 0000000000601028     0 NOTYPE  WEAK   DEFAULT   25 data_start
        50: 0000000000601038     0 NOTYPE  GLOBAL DEFAULT   25 _edata
        51: 00000000004005b4     0 FUNC    GLOBAL DEFAULT   15 _fini
        52: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@@GLIBC_2.2.5
        53: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
        54: 0000000000601028     0 NOTYPE  GLOBAL DEFAULT   25 __data_start
        55: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
        56: 0000000000601030     0 OBJECT  GLOBAL HIDDEN    25 __dso_handle
        57: 00000000004005c0     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
        58: 0000000000400540   101 FUNC    GLOBAL DEFAULT   14 __libc_csu_init
        59: 0000000000601040     0 NOTYPE  GLOBAL DEFAULT   26 _end
        60: 0000000000400430    42 FUNC    GLOBAL DEFAULT   14 _start
        61: 0000000000601038     0 NOTYPE  GLOBAL DEFAULT   26 __bss_start
        62: 0000000000400526    26 FUNC    GLOBAL DEFAULT   14 main
        63: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
        64: 0000000000601038     0 OBJECT  GLOBAL HIDDEN    25 __TMC_END__
        65: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
        66: 00000000004003c8     0 FUNC    GLOBAL DEFAULT   11 _init
    
    Version symbols section '.gnu.version' contains 4 entries:
     Addr: 0000000000400358  Offset: 0x000358  Link: 5 (.dynsym)
      000:   0 (*local*)       2 (GLIBC_2.2.5)   2 (GLIBC_2.2.5)   0 (*local*)    
    
    Version needs section '.gnu.version_r' contains 1 entries:
     Addr: 0x0000000000400360  Offset: 0x000360  Link: 6 (.dynstr)
      000000: Version: 1  File: libc.so.6  Cnt: 1
      0x0010:   Name: GLIBC_2.2.5  Flags: none  Version: 2
    
    Displaying notes found at file offset 0x00000254 with length 0x00000020:
      Owner                 Data size   Description
      GNU                  0x00000010   NT_GNU_ABI_TAG (ABI version tag)
        OS: Linux, ABI: 2.6.32
    
    Displaying notes found at file offset 0x00000274 with length 0x00000024:
      Owner                 Data size   Description
      GNU                  0x00000014   NT_GNU_BUILD_ID (unique build ID bitstring)
        Build ID: 8536b12b7afe5ab7bc13e77d30f3d4c84fa099ee
    

    如上是一个完成的ELF文件信息,其实对于我们来讲,分析ELF文件格式更多是为了帮助我们理解程序运行的原理,比如程序是如何找到对应的函数等等,其实都是有特定的规则,比如在此文件的238行,我们能够找到我们写的main函数以及228行中的print函数等,这些信息都是可以帮助我们理解计算机世界里的活动轨迹,关于ELF的更多细节,详见参考链接。

    四、参考

    相关文章

      网友评论

        本文标题:ELF文件结构

        本文链接:https://www.haomeiwen.com/subject/juzbnhtx.html