使用 GCC 创建的可执行文件是否包含可识别的元数据?



例如,PDF 文件可以包含默认情况下由 PDF 创建/修改软件包含的元数据,也可以包含用户自己选择的元数据。除此之外,元数据可以显示使用的PDF创建软件以及创建PDF的用户的名称。

  • 当使用 GCC 创建可执行文件时,可执行文件是否包含任何元数据(使用的编译器、编译日期等)?
  • 如何故意将元数据插入可执行文件?(例如,作者姓名、创建日期、使用的编译器标志、VCS 提交哈希等)

注意:我所说的元数据不必是"标准"的(即像PDF的情况)。以一种或另一种方式,它必须对检查可执行文件的人可见。

  • GCC将其版本记录在.comment部分(至少在支持它的目标上 - 例如ELF目标)。您可以编译一些内容并与objdump -s -j .comment a.out.

  • -frecord-gcc-switches(请参阅手册和此答案)

  • -grecord-gcc-switches

  • 通常,当您要求编译器发出调试信息(-g*选项系列)时,可能会发出大量元信息。我知道DW_AT_producer(有关编译器/汇编程序名称和版本以及命令行 swithes 的信息)和DW_AT_comp_dir(编译目录)标签。

还有-fverbose-asm,但这只会在程序集中发出注释;它们甚至无法通过目标文件,更不用说可执行文件了。

另请记住,编译器不会生成可执行文件。它只生成汇编代码(gcc命令是编译器驱动程序,它调用编译器,然后是汇编程序,然后是链接器)。链接器可以决定在将目标文件合并到可执行文件/库中时如何处理.comment节等。我认为,"正常"的行为是将它们连接起来,尽管在那个阶段或以后丢弃它们(例如strip)不应该让任何人感到惊讶。

如何故意将元数据插入可执行文件?

通常,SHT_NOTE部分用于它(如果我们说的是 ELF)。在这里,连接和保存到最后是有保证的,因为它们不仅仅是评论;工具链使用它们来存储程序的某些属性(参见man elf,grep 的"注释")。

另一种(笨拙的)方法是定义绝对符号。您可以在符号名称中对信息进行编码。 这可以在任何阶段完成。 例如,在源程序中,或在汇编中。或在链接阶段与ld --defsym.或者您可以使用objcopy --add-symbol修改生成的可执行文件 — 哦,这也适用于部分(objcopy --add-section)。

最新更新