如何确定一个ELF文件是否是Go ELF文件?

huangapple go评论106阅读模式
英文:

How to determine if an ELF file is a Go ELF file?

问题

我需要确定给定的ELF文件是否来自Go。根据这个链接

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

这种方法在任何方面是否不如Go的本地方法:

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

这两种方法在剥离的二进制文件上都能保证工作吗?

英文:

I need to determine whether a given ELF file originated from Go. According to this link:

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

Is this in any way inferior to go's native way:

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

Are both methods guaranteed to work on stripped binaries?

答案1

得分: 2

我需要确定一个给定的ELF文件是否来自Go语言。

这在一般情况下是不可能的。什么是Go二进制文件,什么不是,没有明确定义,而且经过足够优化的Go二进制文件可能只包含几条指令。例如,在x86_64架构上,你可能只会得到一条HLT指令。

为什么strip本身不会删除这个节?

这个节(实际上是每个节)对于执行来说并不是必需的——你可以删除所有节,二进制文件仍然可以正常工作。

这个节只是为了帮助开发者识别特定的构建。strip默认情况下不会删除它,因为那样会破坏这个节的目的,但它当然可以删除。

一个无辜的Go开发者可以构建一个Golang ELF文件并意外地删除这个(多余的?)节吗?

当然可以。开发者可能运行了一个有问题的strip版本,或者他可能将strip别名为strip --strip-all,或者他可能使用了其他的ELF后处理工具,或者他可能使用了UPX,等等。

英文:

> I need to determine whether a given ELF file originated from Go

That is impossible to do in general. What is and isn't a Go binary is not well defined, and a sufficiently optimized Go binary may end up containing just a few instructions. E.g. on x86_64, you may end up with a single HLT instruction.

> how come strip itself doesn't remove this section?

This section (indeed every section) is not necessary for execution -- you can remove all sections, and the binary will still work.

This section is present only to help developers identify a particular build. strip doesn't remove it by default because that would defeat the purpose of this section, but it certainly can do so.

> can an innocent go developer build a golang ELF and accidentally remove this (redundant??) section

Sure. The developer can run a broken version of strip, or he can have aliased strip with strip --strip-all, or he could have used some other ELF post-processing tool, or he could have used UPX, or ...

答案2

得分: 1

提到的部分是一个NOTE部分:

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

显然,NOTE部分有时会被删除以减小文件大小(相关链接):

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

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

英文:

The mentioned section is a NOTE section:

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

And apparently NOTE sections might sometimes be removed for size reductions (related):

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

Removing the mentioned section does not seem to harm the integrity of the whole binary

答案3

得分: 1

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

英文:

As for using standard go tools the section should be there, but there is a way that the go nature of a binary can be hidden without any malicious intent. Using upx to reduce the size of the binary will completely hide the go nature of the binary as upx works with binaries from any language.

huangapple
  • 本文由 发表于 2021年11月3日 16:52:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/69821995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定