readelf简单介绍

readelf介绍

readelf 是一个在 Unix 和类 Unix 系统上用于查看 ELF(Executable and Linkable Format)文件信息的命令行工具。ELF 文件是一种常用的文件格式,用于定义程序或系统所需的不同类型的文件,如可执行文件、目标文件、共享库等。

readelf 提供了许多选项来查看 ELF 文件的不同部分和属性,例如程序头、段头、符号表、重定位条目等。这对于理解程序的编译和链接方式、调试以及进行系统级编程非常有用。

常用 readelf 命令选项:

  1. 查看文件头 (h-file-header):
    显示 ELF 文件的文件头信息,包括文件类型、机器类型、版本等。

    readelf -h <filename>
    
    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:                              DYN (Shared object file)
      Machine:                           AArch64
      Version:                           0x1
      Entry point address:               0xc000
      Start of program headers:          64 (bytes into file)
      Start of section headers:          113640 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         10
      Size of section headers:           64 (bytes)
      Number of section headers:         26
      Section header string table index: 24
    
  2. 查看段头 (S-section-headers):
    显示 ELF 文件的段头信息,包括各个段(如**.text.data**)的大小、位置等。

    readelf -S <filename>
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .note.android.ide NOTE             0000000000000270  00000270
           0000000000000018  0000000000000000   A       0     0     4
      [ 2] .note.gnu.build-i NOTE             0000000000000288  00000288
           0000000000000020  0000000000000000   A       0     0     4
      [ 3] .dynsym           DYNSYM           00000000000002a8  000002a8
           0000000000001c20  0000000000000018   A       7     1     8
      [ 4] .gnu.version      VERSYM           0000000000001ec8  00001ec8
           0000000000000258  0000000000000002   A       3     0     2
      [ 5] .gnu.version_r    VERNEED          0000000000002120  00002120
           0000000000000050  0000000000000000   A       7     2     4
      [ 6] .gnu.hash         GNU_HASH         0000000000002170  00002170
           0000000000000664  0000000000000000   A       3     0     8
      [ 7] .dynstr           STRTAB           00000000000027d4  000027d4
           0000000000005ac2  0000000000000000   A       0     0     1
      [ 8] .rela.dyn         LOOS+0x2         0000000000008298  00008298
           0000000000000728  0000000000000001   A       3     0     8
      [ 9] .relr.dyn         00000013: <unkn  00000000000089c0  000089c0
           0000000000000060  0000000000000008   A       0     0     8
      [10] .rela.plt         RELA             0000000000008a20  00008a20
           0000000000000888  0000000000000018  AI       3    21     8
      [11] .rodata           PROGBITS         00000000000092b0  000092b0
           00000000000002c6  0000000000000000 AMS       0     0     16
      [12] .eh_frame_hdr     PROGBITS         0000000000009578  00009578
           000000000000074c  0000000000000000   A       0     0     4
      [13] .eh_frame         PROGBITS         0000000000009cc8  00009cc8
           0000000000001f9c  0000000000000000   A       0     0     8
      [14] .text             PROGBITS         000000000000c000  0000c000
           000000000000d6cc  0000000000000000  AX       0     0     4
      [15] .plt              PROGBITS         00000000000196d0  000196d0
           00000000000005d0  0000000000000000  AX       0     0     16
      [16] .data.rel.ro      PROGBITS         000000000001a000  0001a000
           0000000000000fe0  0000000000000000  WA       0     0     8
      [17] .fini_array       FINI_ARRAY       000000000001afe0  0001afe0
           0000000000000010  0000000000000000  WA       0     0     8
      [18] .init_array       INIT_ARRAY       000000000001aff0  0001aff0
           0000000000000020  0000000000000000  WA       0     0     8
      [19] .dynamic          DYNAMIC          000000000001b010  0001b010
           0000000000000200  0000000000000010  WA       7     0     8
      [20] .got              PROGBITS         000000000001b210  0001b210
           00000000000000b8  0000000000000000  WA       0     0     8
      [21] .got.plt          PROGBITS         000000000001b2c8  0001b2c8
           00000000000002f0  0000000000000000  WA       0     0     8
      [22] .data             PROGBITS         000000000001c5b8  0001b5b8
           0000000000000030  0000000000000000  WA       0     0     8
      [23] .bss              NOBITS           000000000001c5e8  0001b5e8
           0000000000000070  0000000000000000  WA       0     0     8
      [24] .shstrtab         STRTAB           0000000000000000  0001b5e8
           0000000000000102  0000000000000000           0     0     1
      [25] .gnu_debugdata    PROGBITS         0000000000000000  0001b6ea
           00000000000004fc  0000000000000000           0     0     1
    
  3. 查看程序头 (l-program-headers-segments):
    显示程序头信息,通常用于可执行文件和共享库,展示如何映射到内存。

    readelf -l <filename>
    
    Elf file type is DYN (Shared object file)
    Entry point 0xc000
    There are 10 program headers, starting at offset 64
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                     0x0000000000000230 0x0000000000000230  R      0x8
      LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                     0x000000000000bc64 0x000000000000bc64  R      0x1000
      LOAD           0x000000000000c000 0x000000000000c000 0x000000000000c000
                     0x000000000000dca0 0x000000000000dca0  R E    0x1000
      LOAD           0x000000000001a000 0x000000000001a000 0x000000000001a000
                     0x00000000000015b8 0x00000000000015b8  RW     0x1000
      LOAD           0x000000000001b5b8 0x000000000001c5b8 0x000000000001c5b8
                     0x0000000000000030 0x00000000000000a0  RW     0x1000
      DYNAMIC        0x000000000001b010 0x000000000001b010 0x000000000001b010
                     0x0000000000000200 0x0000000000000200  RW     0x8
      GNU_RELRO      0x000000000001a000 0x000000000001a000 0x000000000001a000
                     0x00000000000015b8 0x0000000000002000  R      0x1
      GNU_EH_FRAME   0x0000000000009578 0x0000000000009578 0x0000000000009578
                     0x000000000000074c 0x000000000000074c  R      0x4
      GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                     0x0000000000000000 0x0000000000000000  RW     0x0
      NOTE           0x0000000000000270 0x0000000000000270 0x0000000000000270
                     0x0000000000000038 0x0000000000000038  R      0x4
    
     Section to Segment mapping:
      Segment Sections...
       00
       01     .note.android.ident .note.gnu.build-id .dynsym .gnu.version .gnu.version_r .gnu.hash .dynstr .rela.dyn .relr.dyn .rela.plt .rodata .eh_frame_hdr .eh_frame
       02     .text .plt
       03     .data.rel.ro .fini_array .init_array .dynamic .got .got.plt
       04     .data .bss
       05     .dynamic
       06     .data.rel.ro .fini_array .init_array .dynamic .got .got.plt
       07     .eh_frame_hdr
       08
       09     .note.android.ident .note.gnu.build-id
    
  4. 查看符号表 (s-symbols):
    显示符号表,其中包含函数和变量等符号的信息。

    readelf -s <filename>
    
    Symbol table '.dynsym' contains 300 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
         1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_atexit@LIBC (2)
         2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize@LIBC (2)
        75: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND malloc@LIBC (2)
        76: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strerror@LIBC (2)
        77: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND syslog@LIBC (2)
        78: 000000000001c620     8 OBJECT  WEAK   DEFAULT   23 _ZGVN4aidl6vendor3qti8har
        79: 00000000000151e8     4 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
        80: 0000000000010150   492 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
        81: 00000000000123b8   484 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
        82: 000000000001602c    52 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
        83: 000000000000c778   328 FUNC    WEAK   DEFAULT   14 _ZNSt3__16vectorIiNS_9all
        84: 0000000000010950   428 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
        85: 0000000000016264     8 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
        86: 0000000000016aa4     4 FUNC    WEAK   DEFAULT   14 _ZNSt3__120__shared_ptr_p
        87: 0000000000018b00    52 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
        88: 00000000000189e8   176 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
        89: 0000000000017a44    68 FUNC    GLOBAL DEFAULT   14 _ZN4aidl6vendor3qti8hardw
    
  5. 查看动态段 (d-dynamic):
    显示动态段的信息,主要用于共享库和动态链接。

    readelf -d <filename>
    
    Dynamic section at offset 0x1b010 contains 32 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libbinder_ndk.so]
     0x0000000000000001 (NEEDED)             Shared library: [android.hardware.common-V2-ndk_platform.so]
     0x0000000000000001 (NEEDED)             Shared library: [libc++.so]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so]
     0x0000000000000001 (NEEDED)             Shared library: [libm.so]
     0x0000000000000001 (NEEDED)             Shared library: [libdl.so]
     0x000000000000000e (SONAME)             Library soname: [vendor.qti.hardware.display.config-V6-ndk_platform.so]
     0x000000000000001e (FLAGS)              BIND_NOW
     0x000000006ffffffb (FLAGS_1)            Flags: NOW
     0x0000000060000011 (Operating System specific: 60000011)                0x8298
     0x0000000060000012 (Operating System specific: 60000012)                0x728
     0x0000000000000009 (RELAENT)            24 (bytes)
     0x0000000000000024 (<unknown>: 24)      0x89c0
     0x0000000000000023 (<unknown>: 23)      0x60
     0x0000000000000025 (<unknown>: 25)      0x8
     0x0000000000000017 (JMPREL)             0x8a20
     0x0000000000000002 (PLTRELSZ)           2184 (bytes)
     0x0000000000000003 (PLTGOT)             0x1b2c8
     0x0000000000000014 (PLTREL)             RELA
     0x0000000000000006 (SYMTAB)             0x2a8
    
  6. 查看重定位条目 (r):
    显示重定位条目,重要于了解动态链接过程。

    readelf -r <filename>
    
    Relocation section '.rela.plt' at offset 0x8a20 contains 91 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    00000001b2e0  000200000402 R_AARCH64_JUMP_SL 0000000000000000 __cxa_finalize@LIBC + 0
    00000001b2e8  000300000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_getDataPositio@LIBBINDER_NDK + 0
    00000001b2f0  000600000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_readInt32@LIBBINDER_NDK + 0
    00000001b2f8  000500000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_readFloat@LIBBINDER_NDK + 0
    00000001b300  000400000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_readBool@LIBBINDER_NDK + 0
    00000001b308  000700000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_setDataPositio@LIBBINDER_NDK + 0
    00000001b310  000b00000402 R_AARCH64_JUMP_SL 0000000000000000 __stack_chk_fail@LIBC + 0
    00000001b318  000a00000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_writeInt32@LIBBINDER_NDK + 0
    00000001b320  000900000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_writeFloat@LIBBINDER_NDK + 0
    00000001b328  000800000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_writeBool@LIBBINDER_NDK + 0
    00000001b330  000c00000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_readDouble@LIBBINDER_NDK + 0
    00000001b338  000d00000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_writeDouble@LIBBINDER_NDK + 0
    00000001b340  000e00000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_readInt32Array@LIBBINDER_NDK + 0
    00000001b348  000f00000402 R_AARCH64_JUMP_SL 0000000000000000 AParcel_writeInt32Arra@LIBBINDER_NDK + 0
    00000001b350  005300000402 R_AARCH64_JUMP_SL 000000000000c778 _ZNSt3__16vectorIiNS_9 + 0
    00000001b358  001200000402 R_AARCH64_JUMP_SL 0000000000000000 _Znwm + 0
    00000001b360  001500000402 R_AARCH64_JUMP_SL 0000000000000000 memset@LIBC + 0
    
  7. 查看所有信息 (a):
    显示 ELF 文件的所有信息。

    readelf -a <filename>
    
    #结果就是上面的所有信息
    

ELF的格式

so文件,bin,object file都是ELF的格式?

是的,你的理解是正确的。在Unix和类Unix系统(如Linux)中,.so 文件(共享库)、二进制可执行文件(通常没有扩展名,简称为 “bin”)、以及目标文件(.o 文件)通常都采用 ELF(Executable and Linkable Format)格式。

  • 共享库(.so 文件):这些是动态链接的库文件,可以被多个程序共享。它们在运行时被加载,而不是在编译时静态链接到程序中。
  • 二进制可执行文件:这些是编译后的程序,可以直接运行。在Unix-like系统中,它们没有扩展名,通常被称为"binaries"或"executable files"。
  • 目标文件(.o 文件):这些是编译源代码(如C或C++源文件)得到的中间结果。它们通常在创建可执行文件或共享库之前被链接器处理。

ELF格式为这些不同类型的文件提供了一个标准化的方式来描述它们的内容和结构,如程序的代码段、数据段、符号表、重定位信息等。这使得操作系统和工具能够有效地解析和处理这些文件。

这些文件的后缀名却是不同的呢?

是的,文件的后缀名和文件的格式是两个不同的概念,它们并不总是直接相关。

  • 文件格式:这是文件内容的结构化描述,它定义了数据如何在文件内部组织。文件格式由文件的创建者或生成程序决定,它决定了文件的内部结构。例如,ELF(Executable and Linkable Format)是一种文件格式,用于指定可执行文件、目标文件、和动态链接库的结构。
  • 文件后缀名:这通常是文件名的一部分,位于文件名的最后,用于指示文件的类型或用途。在许多操作系统中,文件后缀名(如**.txt.jpg.o.so**)帮助用户和程序快速识别文件的用途和打开方式。但后缀名本身并不改变文件的内容或格式。

对于使用ELF格式的文件,虽然它们内部结构相似或相同,但不同类型的文件(如目标文件、可执行文件、动态链接库)可能会使用不同的后缀名(如**.o、无后缀、.so**),这主要是为了方便使用和识别。例如,在Linux系统中:

  • 目标文件(Object files)通常有**.o**后缀。
  • 可执行文件通常没有特定后缀。
  • 动态链接库(Shared libraries)通常有**.so**后缀。

因此,虽然这些文件可能都是ELF格式,它们的后缀名却不同,以反映它们的不同用途。

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值