从编译后的二进制可执行文件中解析 Go 项目的依赖包信息

本文介绍从编译后的二进制可执行文件中解析原 Go 项目中的依赖包信息的一些方法, 解决类似:接手一个老项目但是这个老项目中又依赖了另一个老项目的二进制可执行文件, 导致无法知道这个二进制可执行文件具体是其对应源代码仓库的哪个版本的代码编译出来的尴尬情况, 通过依赖包信息间接定位源码版本(无法完全实现这个需求,还需要结合代码仓库变更历史等手段)。

go version 命令

可以先尝试使用 go version 命令获取二进制文件中包含的依赖包信息:

$ go version -m go-bin
go-bin: go1.17.1
        path    github.com/mozillazg/go-bin-dep-sample/gomodule
        mod     github.com/mozillazg/go-bin-dep-sample/gomodule (devel)
        dep     github.com/mozillazg/go-pinyin  v0.18.0 h1:hQompXO23/0ohH8YNjvfsAITnCQImCiR/Fny8EhIeW0=

strings 命令

也可以使用 strings 命令获取二进制文件中的信息:

$ strings go-bin |grep github.com
github.com/mozillazg/go-bin-dep-sample/gomodule
github.com/mozillazg/go-bin-dep-sample/gomodule
github.com/mozillazg/go-pinyin
github.com/mozillazg/go-pinyin.initial
...
github.com/mozillazg/go-pinyin.NewArgs
/go/pkg/mod/github.com/mozillazg/go-pinyin@v0.18.0/pinyin.go
/go/pkg/mod/github.com/mozillazg/go-pinyin@v0.18.0/phonetic_symbol.go
/go/pkg/mod/github.com/mozillazg/go-pinyin@v0.18.0/pinyin_dict.go
/go/src/github.com/mozillazg/go-bin-dep-sample/gomodule/main.go
github.com/mozillazg/go-pinyin.initial
...
github.com/mozillazg/go-pinyin.PinyinDict

go tool nm 命令

go tool nm 命令也可以得到相关信息:

$ go tool nm go-bin |grep github.com
  64ab00 D github.com/mozillazg/go-pinyin..inittask
  65b588 D github.com/mozillazg/go-pinyin.Fallback
  ...
  49ba60 T github.com/mozillazg/go-pinyin.toFixed.func1

go tool objdump 命令

go tool objdump 命令也可以间接得到相关信息:

$ go tool objdump go-bin |grep github.com
TEXT github.com/mozillazg/go-pinyin.initial(SB) /go/pkg/mod/github.com/mozillazg/go-pinyin@v0.18.0/pinyin.go
  pinyin.go:108             0x49b37d                488b1534831c00          MOVQ github.com/mozillazg/go-pinyin.initialArray+8(SB), DX
  pinyin.go:108             0x49b384                488b3525831c00          MOVQ github.com/mozillazg/go-pinyin.initialArray(SB), SI
  pinyin.go:106             0x49b44f                e90cffffff              JMP github.com/mozillazg/go-pinyin.initial(SB)
TEXT github.com/mozillazg/go-pinyin.final(SB) /go/pkg/mod/github.com/mozillazg/go-pinyin@v0.18.0/pinyin.go
  pinyin.go:119             0x49b482                e8d9feffff              CALL github.com/mozillazg/go-pinyin.initial(SB)
  ...
  phonetic_symbol.go:4      0x49c6a7                e974fbffff              JMP github.com/mozillazg/go-pinyin.init(SB)
TEXT main.main(SB) /go/src/github.com/mozillazg/go-bin-dep-sample/gomodule/main.go
  pinyin.go:102             0x49c6f3                488b15be5c1f00          MOVQ github.com/mozillazg/go-pinyin.Style(SB), DX
  pinyin.go:102             0x49c70a                488b350ff61b00          MOVQ github.com/mozillazg/go-pinyin.Separator(SB), SI
  pinyin.go:102             0x49c711                4c8b0510f61b00          MOVQ github.com/mozillazg/go-pinyin.Separator+8(SB), R8
  pinyin.go:102             0x49c722                4c8b0d5fee1b00          MOVQ github.com/mozillazg/go-pinyin.Fallback(SB), R9
  main.go:10                0x49c744                e897f7ffff              CALL github.com/mozillazg/go-pinyin.Pinyin(SB)

redress 工具

redress 是一个专门用于分析 Go 二进制可执行文件的开源软件,通过这个工具也可以得到想要的包信息:

$ redress -pkg -filepath -vendor -unknown go-bin
Packages:
main | /go/src/github.com/mozillazg/go-bin-dep-sample/gomodule

Vendors:
github.com/mozillazg/go-pinyin | /go/pkg/mod/github.com/mozillazg/go-pinyin@v0.18.0

Unknown Libraries:

Comments