Menu Close

Red Hat Training

A Red Hat training course is available for RHEL 8

第 17 章 Annobin 项目

Annobin 项目是 Setmark 规格项目的实现。水标规格项目旨在将标记添加到可执行和可链接格式(ELF)对象中,以确定它们的属性。Annobin 项目由 annobin 插件和 annockeck 程序组成。

annobin 插件扫描 GNU Compiler Collection(GCC)命令行、编译状态和编译过程,并生成 ELF 备注。ELF 记录如何构建二进制文件,并为 annocheck 程序提供执行安全强化检查的信息。

安全强化检查程序是 annocheck 程序的一部分,并默认启用。它检查二进制文件,以确定程序是否使用必要的安全强化选项构建并正确编译。annocheck 可以为 ELF 对象文件递归扫描目录、归档和 RPM 软件包。

注意

文件必须采用 ELF 格式。annocheck 不要处理任何其他二进制文件类型。

下面的部分描述了如何:

  • 使用 annobin 插件
  • 使用 annocheck 程序
  • 删除冗余 annobin 备注

17.1. 使用 annobin 插件

下面的部分描述了如何:

  • 启用 annobin 插件
  • 将选项传递给 annobin 插件

17.1.1. 启用 annobin 插件

下面的部分论述了如何通过 gccclang 启用 annobin 插件。

流程

  • 要启用带有 gccannobin 插件,请使用:

    $ gcc -fplugin=annobin
    • 如果 gcc 没有找到 annobin 插件,请使用:

      $ gcc -iplugindir=/path/to/directory/containing/annobin/

      使用 包含 annobin 的目录的绝对路径替换 /path/to/directory/con contain/annobin/

    • 要查找包含 annobin 插件的目录,请使用:

      $ gcc --print-file-name=plugin
  • 要启用带有 clangannobin 插件,请使用:

    $ clang -fplugin=/path/to/directory/containing/annobin/

    使用 包含 annobin 的目录的绝对路径替换 /path/to/directory/con contain/annobin/

17.1.2. 将选项传递给 annobin 插件

下面的部分论述了如何通过 gcc 或通过 clang 将选项传递给 annobin 插件。

流程

  • 要将选项传递给带有 gccannobin 插件,请使用:

    $ gcc -fplugin=annobin -fplugin-arg-annobin-option file-name

    使用 annobin 命令行参数替换 选项 ,并使用文件名 替换 file-name。

    示例

    • 要显示 annobin 正在做什么的更多详情,请使用:

      $ gcc -fplugin=annobin -fplugin-arg-annobin-verbose file-name

      用文件名替换 file-name

  • 要将选项传递给带有 clangannobin 插件,请使用:

    $ clang -fplugin=/path/to/directory/containing/annobin/ -Xclang -plugin-arg-annobin -Xclang option file-name

    使用 annobin 命令行参数替换 选项,并使用 包含 annobin 的目录的绝对路径替换 /path/to/directory/con contain/annobin/

    示例

    • 要显示 annobin 正在做什么的更多详情,请使用:

      $ clang -fplugin=/usr/lib64/clang/10/lib/annobin.so -Xclang -plugin-arg-annobin -Xclang verbose file-name

      用文件名替换 file-name

17.2. 使用 annocheck 程序

下面的部分论述了如何使用 annocheck 检查:

  • 文件
  • 目录
  • RPM 软件包
  • annocheck 额外工具
注意

annocheck 为 ELF 对象文件递归扫描目录、归档和 RPM 软件包。文件必须采用 ELF 格式。annocheck 不要处理任何其他二进制文件类型。

17.2.1. 使用 annocheck 检查文件

下面的部分论述了如何使用 annocheck 检查 ELF 文件。

流程

  • 要检查文件,请使用:

    $ annocheck file-name

    使用 文件名 替换 file-name。

注意

文件必须采用 ELF 格式。annocheck 不要处理任何其他二进制文件类型。annocheck 处理包含 ELF 对象文件的静态库。

附加信息

  • 有关 annocheck 和可能的命令行选项的详情请参考 annocheck man page。

17.2.2. 使用 annocheck 检查目录

下面的部分论述了如何使用 annocheck 检查目录中的 ELF 文件。

流程

  • 要扫描目录,请使用:

    $ annocheck directory-name

    使用 目录名 替换 directory-name。annocheck 自动检查目录、其子目录以及目录中的所有归档和 RPM 软件包的内容。

注意

annocheck 只查找 ELF 文件。其他文件类型将被忽略。

附加信息

  • 有关 annocheck 和可能的命令行选项的详情请参考 annocheck man page。

17.2.3. 使用 annocheck 检查 RPM 软件包

下面的部分论述了如何使用 annocheck 检查 RPM 软件包中的 ELF 文件。

流程

  • 要扫描 RPM 软件包,请使用:

    $ annocheck rpm-package-name

    使用 RPM 软件包的名称替换 rpm- package-name。annocheck 递归扫描 RPM 软件包中的所有 ELF 文件。

注意

annocheck 只查找 ELF 文件。其他文件类型将被忽略。

  • 要使用提供的 debug info RPM 扫描 RPM 软件包,请使用:

    $ annocheck rpm-package-name --debug-rpm debuginfo-rpm

    使用 RPM 软件包的名称替换 rpm- package-name, debuginfo-rpm 替换为与二进制 RPM 关联的 debug info RPM 的名称。

附加信息

  • 有关 annocheck 和可能的命令行选项的详情请参考 annocheck man page。

17.2.4. 使用 annocheck 额外工具

annocheck 包括多个用来检查二进制文件的工具。您可以使用命令行选项启用这些工具。

下面的部分描述了如何启用:

  • built-by 工具
  • notes 工具
  • section-size 工具

您可以同时启用多个工具。

注意

默认启用强化检查程序。

17.2.4.1. 启用 built-by 工具

您可以使用 annocheck built-by 工具查找构建二进制文件的编译器名称。

流程

  • 要启用 built-by 工具,请使用:

    $ annocheck --enable-built-by

附加信息

  • 有关 built-by 工具的详情请参考 --help 命令行选项。

17.2.4.2. 启用 notes 工具

您可以使用 annocheck notes 工具显示存储在 annobin 插件创建的二进制文件中的备注。

流程

  • 要启用 notes 工具,请使用:

    $ annocheck --enable-notes

    备注显示在按地址范围排序的序列中。

附加信息

  • 有关 notes 工具的详情请参考 --help 命令行选项。

17.2.4.3. 启用 section-size 工具

您可以使用 annocheck section-size 工具显示命名部分的大小。

流程

  • 要启用 section-size 工具,请使用:

    $ annocheck --section-size=name

    使用命名部分的 名称 替换 name。输出仅限于特定的部分。最后会生成一个累积结果。

附加信息

  • 有关 section-size 工具的详情请参考 --help 命令行选项。

17.2.4.4. 强化检查程序基础

默认启用强化检查程序。您可以使用 --disable-hardened 命令行选项禁用强化检查程序。

17.2.4.4.1. 强化检查器选项

annocheck 程序检查以下选项:

  • 使用 -z now linker 选项禁用 lazy 绑定。
  • 该程序没有可执行内存的堆栈。
  • GOT 表的重新定位仅限读取。
  • 没有程序片段中的所有三个读、写和执行权限位集。
  • 无法对可执行代码进行重新定位。
  • 在运行时查找共享库的 runpath 信息只包括根于 /usr 的目录。
  • 程序编译时启用了 annobin 备注。
  • 该程序已启用 -fstack-protector-strong 选项编译。
  • 该程序已使用 -D_FORTIFY_SOURCE=2 编译。
  • 该程序已使用 -D_GLIBCXX_ASSERTIONS 编译。
  • 该程序被编译为启用 -fexceptions
  • 该程序被编译为启用 -fstack-clash-protection
  • 该程序被编译为 -O2 或更高版本。
  • 该程序没有以写入形式进行的重新定位。
  • 动态可执行文件有一个动态片段。
  • 共享库使用 -fPIC-fPIE 编译。
  • 动态可执行文件使用 -fPIE 编译并链接到 -pie
  • 如果可用,使用 -fcf-protection=full 选项。
  • 如果可用,使用 -mbranch-protection 选项。
  • 如果可用,使用 -mstackrealign 选项。
17.2.4.4.2. 禁用强化检查器

下面的部分论述了如何禁用强化检查器。

流程

  • 要在没有强化检查器的情况下扫描文件中的备注,请使用:

    $ annocheck --enable-notes --disable-hardened file-name

    使用 文件名 替换 file-name。

17.3. 删除冗余 annobin 备注

使用 annobin 会增加二进制文件的大小。要减少使用 annobin 编译的二进制文件的大小,您可以删除冗余 annobin 备注。要删除冗余 annobin 备注,使用 objcopy 程序,它是 binutils 软件包的一部分。

流程

  • 要删除冗余 annobin 备注,请使用:

      $ objcopy --merge-notes file-name

    用文件名替换 file-name