memoメモ

最近はGo言語関連で。φ(..)メモメモ

ビルドしたバイナリからビルドに利用したGoのバージョン情報を読む

なにができる?

  • goでビルド済みのバイナリからgoのバージョン情報が取得できます。

なにがうれしいの?

  • 配布した(された)バイナリはどのgoのバージョンでビルドされたのかわかります。ので、goの本体にセキュリティ修正などが行われた際、もし古いバージョンだと困るのであれば調べることができます。

やってみよう

適当な実行ファイルをビルドする。とりあえずhelloworldレベルで。

$ cd hello
$ cat main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}
$ go build

go tool nmコマンドで、変数buildVersionのアドレスが特定できる(ちなみに、buildVersion$GOROOT/src/runtime/zversion.goにある変数):

$ go tool nm hello | grep buildVersion
  258ec0 D runtime.buildVersion

これをgdbで見てみると:

$ gdb hello
GNU gdb (GDB) 7.9.1
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin13.4.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from hello...done.
Loading Go Runtime support.
(gdb) x/s *0x258ec0
0x18f110 <go.string.*+8176>:    "go1.5.1"
(gdb) 

で読めます。なお、以前go getしたコンパイル済みのバイナリからもGoのバージョン情報を引き出すことができます。

簡単にバージョンを調べたい

gdbで見るのは面倒なので、objdumpでバージョン情報を取得できるようにしてみました(Linux):

使い方:

$ ./goversion.bash hello
go1.5.1

さらに簡単に・・

動かなくなるかもしれませんが単純にgrepしてもいいかもしれません。

力技:

$ objdump -s hello | grep -E "go[0-9]" | sed -e 's/.*\(go.*\).*/\1/' -e 's/\.\.\+//g'
go1.5.1

他にいい方法があれば教えて下さい!

Binary Hacks ―ハッカー秘伝のテクニック100選

Binary Hacks ―ハッカー秘伝のテクニック100選