【问题标题】:How to determine if an ELF file is a Go ELF file?如何确定 ELF 文件是否为 Go ELF 文件?
【发布时间】:2021-12-17 15:56:22
【问题描述】:

我需要确定给定的 ELF 文件是否来自 Go。根据this link

$ readelf -a traefik.stripped | grep "\.note\.go\.buildid"

这是否比 Go 的原生方式逊色:

$ go tool buildid traefik.stripped
oPIWoPjqt1P3rttpA3ee/ByNXPhvgS37nIoJY-HYB/8b25JYXrgktA-FYgU5MU/0Posfq41xZW9BEPEG4Ub

这两种方法都保证可以处理剥离的二进制文件吗?

【问题讨论】:

  • 我确定这取决于您所说的“保证”是什么意思。毫无疑问,可以制作/修改一个欺骗工具的 ELF 二进制文件,以产生假阴性或假阳性。
  • @Flimzy 能否描述一个场景,即在 不影响 ELF 文件功能的情况下删除此部分?
  • 我不能。我对 ELF 二进制格式不太熟悉。但我知道这正是病毒作者(和其他人)所做的事情,所以我确信它可以做到。我不知道是否有人有理由这样做。但你问的是保证。我认为没有。
  • 这样想:与 Go 编译器生成的相比,如何防止 Python 脚本构建逐字节相同的 ELF 二进制文件?显然,除了时间和动机之外,什么都没有。
  • 我不知道。这是一个非常不同的问题。 strip 如何/为什么表现出它的行为方式与欺骗启发式的技术可能性几乎没有关系。

标签: go elf readelf


【解决方案1】:

我需要确定给定的 ELF 文件是否来自 Go

一般来说是不可能的。什么是和不是 Go 二进制文件没有很好的定义,一个充分优化的 Go 二进制文件最终可能只包含几条指令。例如。在x86_64 上,您可能会得到一条HLT 指令。

为什么 strip 本身不删除这个部分?

此部分(实际上是 每个 部分)不是执行所必需的——您可以删除 所有 部分,二进制文件仍然可以工作。

此部分用于帮助开发人员识别特定构建。 strip 不会默认删除它,因为这会违背本节的目的,但它肯定可以这样做。

一个无辜的 go 开发人员可以构建一个 golang ELF 并意外删除这个(冗余??)部分

当然。开发人员可以运行strip 的损坏版本,或者他可以将strip 别名为strip --strip-all,或者他可以使用其他一些ELF 后处理工具,或者他可以使用UPX,或者...

【讨论】:

    【解决方案2】:

    至于使用标准的 go 工具,该部分应该存在,但是有一种方法可以隐藏二进制文件的 go 特性而没有任何恶意。使用 upx 减小二进制文件的大小将完全隐藏二进制文件的 go 特性,因为 upx 可以处理任何语言的二进制文件。

    【讨论】:

      【解决方案3】:

      提到的部分是NOTE 部分:

      $ readelf -a traefik.stripped | grep "\.note\.go\.buildid" | sed -n "1,1p"
        [11] .note.go.buildid  NOTE             0000000000400f9c  00000f9c
      

      显然NOTE 部分有时可能会被删除以减小大小 (related):

      objcopy --remove-section=.note.go.buildid traefik.stripped traefik.super.stripped
      

      删除上述部分似乎不会损害整个二进制文件的完整性

      【讨论】:

        猜你喜欢
        • 2011-03-16
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        • 2011-05-15
        • 1970-01-01
        • 2014-05-25
        • 2011-03-07
        • 2013-03-29
        相关资源
        最近更新 更多