c++ - 了解ELF执行程序的SHT_NOTE节 “.note.ABI-tag”

标签 c++ c executable elf

我正在尝试了解Linux ELF可执行文件。我编写了一个简单的C“Hello World”程序,并使用GCC将其编译为可执行文件。

对于“Section Headers”,我可以理解最后一个“.shstrtab”和第二个“.interp”,因为只有一些偏移可以让我找出它所指的是什么。

但是对于段标题“.note.ABI-tag”,我只是感到困惑。

下面列出的内容来自我的HelloWorld可执行文件:

...
00000230  01 00 00 00 00 00 00 00  2f 6c 69 62 36 34 2f 6c  |......../lib64/l|
00000240  64 2d 6c 69 6e 75 78 2d  78 38 36 2d 36 34 2e 73  |d-linux-x86-64.s|
00000250  6f 2e 32 00 04 00 00 00  10 00 00 00 01 00 00 00  |o.2.............| <-- (5) start at 0x0254 (value: "0x04")
00000260  47 4e 55 00 00 00 00 00  03 00 00 00 02 00 00 00  |GNU.............|
00000270  00 00 00 00 04 00 00 00  14 00 00 00 03 00 00 00  |................| <-- (6) end at 0x0274 (note included)
00000280  47 4e 55 00 42 5c e5 58  cc 7b 78 91 e0 e1 b0 9a  |GNU.B\.X.{x.....|
00000290  3d 09 5b 6a 03 c1 7c bb  01 00 00 00 01 00 00 00  |=.[j..|.........|
000002a0  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000002b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
...
000022a0  72 54 4d 43 6c 6f 6e 65  54 61 62 6c 65 00 00 2e  |rTMCloneTable...|
000022b0  73 79 6d 74 61 62 00 2e  73 74 72 74 61 62 00 2e  |symtab..strtab..|
000022c0  73 68 73 74 72 74 61 62  00 2e 69 6e 74 65 72 70  |shstrtab..interp|
000022d0  00 2e 6e 6f 74 65 2e 41  42 49 2d 74 61 67 00 2e  |..note.ABI-tag..| <-- (3) name starts at 0x22d1
000022e0  6e 6f 74 65 2e 67 6e 75  2e 62 75 69 6c 64 2d 69  |note.gnu.build-i|
000022f0  64 00 2e 67 6e 75 2e 68  61 73 68 00 2e 64 79 6e  |d..gnu.hash..dyn|
...
00002440  00 00 00 00 00 00 00 00  23 00 00 00 07 00 00 00  |........#.......| <-- (2) sh_name offset is 0x23
00002450  02 00 00 00 00 00 00 00  54 02 40 00 00 00 00 00  |........T.@.....|
00002460  54 02 00 00 00 00 00 00  20 00 00 00 00 00 00 00  |T....... .......| <-- (4) sh_offset = 0x0254, sh_size = 0x20
00002470  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00002480  00 00 00 00 00 00 00 00  31 00 00 00 07 00 00 00  |........1.......|

...
00002b00  00 00 00 00 00 00 00 00  11 00 00 00 03 00 00 00  |................|
00002b10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00002b20  ae 22 00 00 00 00 00 00  19 01 00 00 00 00 00 00  |."..............| <-- (1).shstrtab starts at 0x22ae
00002b30  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00002b40  00 00 00 00 00 00 00 00  (end of the file)        |........|
00002b48

我能理解的是:
  • 在位置(1)(在节标题“.shstrtab”中),它显示.shstrtab从0x22ae开始
  • 在位置(2),它表明此部分的sh_name偏移量是0x23
  • 所以我可以找到它在位置(3)的sh_name(0x22ae + 0x23 = 0x22d1),它是“.note.ABI-tag”
  • 在位置(4)处,它显示sh_offset为0x0254,而sh_size为0x20
  • 所以我可以找到从0x0254到0x0274的内容(不包括在内)(0x0254 + 0x20 = 0x0274)

  • 这就是我能找到的所有信息。

    但是我不明白的是:

    为什么我的ELF解析器告诉我它可以找到更多信息:
    Note Segment (offset=0x254, size=32)
        Name="GNU"
        Type=1
        Type String="NT_GNU_ABI_TAG"
        Description="OS Linux 3.2.0"
    

    这些关键和值(value)观从何而来?如何手动找到它?

    网络上的文章似乎无济于事:

    我搜索了一些文章,也许这是最详细的文章:https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html

    但是我仍然不明白这一点。

    例如,它说“每个条目都是目标处理器格式的4字节字的数组”,因此看来我应该将0x0254(包括)和0x0274(不包括)之间的字节划分为8个“4字节字” “,应为:
    1st word: 04 00 00 00
    2nd word: 10 00 00 00
    3rd word: 01 00 00 00
    4th word: 47 4e 55 00
    5th word: 00 00 00 00
    6th word: 03 00 00 00
    7th word: 02 00 00 00
    8th word: 00 00 00 00
    

    然后,它说:“名称中的第一个namesz字节包含条目所有者或始发者的以空字符结尾的字符表示。”

    但是在第一个“4字节字”中,以“0x00”结尾的“0x04”不是可打印字符,而是ASCII控制字符“传输结束”。

    因此,基本上的问题是,如何从二进制文件中手动查找ELF解析器显示的那些信息?

    最佳答案

    elf(5)注释部分(Nhdr)进行了抓取,我能够确定:

    1st word: 04 00 00 00 - n_namesz - the name of the name field in bytes. It is 4 - "GNU"
    2nd word: 10 00 00 00 - n_descsz - The length of the descriptor field in bytes.
    3rd word: 01 00 00 00 - n_type - The NT_GNU_ABI_TAG label (or ELF_NOTE_ABI or similar)
    4th word: 47 4e 55 00 - "GNU" with zero terminator
    5th word: 00 00 00 00 - OS descriptor - ELF_NOTE_OS_LINUX,
    6th word: 03 00 00 00 - major version of the ABI
    7th word: 02 00 00 00 - minor version of the ABI
    8th word: 00 00 00 00 - subminor version of the ABI
    

    关于c++ - 了解ELF执行程序的SHT_NOTE节 “.note.ABI-tag”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59608986/

    相关文章:

    qt - 如何为我的基于 Qt 的应用程序创建 .exe 文件

    c# - 从 C# 应用程序调用 C++ DLL 方法

    java - 将 .mm 文件转换为 java 可读形式

    c++ - 别名漏洞是否适用于签名字符?

    c - 如何在 C 中创建结构的 "objects"

    c - 从左到右、从上到下翻转图像

    c++ - 使用此 CMake 链接命令仍然需要针对 OpenMP::OpenMP_CXX 的显式链接吗?

    c - 批处理文件中的 If-else 条件

    haskell - ghc 编译的二进制文件是否需要 GHC 还是它们是独立的?

    python - Py2exe - 运行后窗口立即消失