いろいろ備忘録日記

主に .NET とか Go とか Python絡みのメモを公開しています。

linuxでアプリが32ビット版か64ビット版かを判定 (file, od, hexdump)

概要

小ネタ。頻繁に使うわけでもないですが、知っておくと便利なことなので、メモメモ。

linux の実行ファイルは ELF (Executable and Linkable Format) というフォーマットのバイナリになります。

で、これが32ビットなのか64ビットなのかを判定したい場合、以下のようなやり方があります。

file コマンドで見る

これが一番手軽ですね。

$ file -e elf xxx

ってするだけです。

32ビットの場合は ELF 32-bit 、 64ビットの場合は ELF 64-bit って表示されます。

od コマンド, hexdump コマンドでみる

odコマンドやhexdumpコマンドでバイナリをダンプして確認することもできます。

ELF フォーマットは、先頭5バイト目に32ビットか64ビットかの識別が設定されます。

32ビットの場合は 0x01 、64ビットの場合は 0x02 です。

en.wikipedia.org

試してみる

今回はクロスコンパイルが簡単ってことで、Goを使って試してみます。

以下のような helloworld を用意します。

package main

import "fmt"

func main() {
    fmt.Println("hello world")
}

んで、以下のような Makefile を用意

all: \
   display \
   clean


build: \
   _build_linux_x86 \
   _build_linux_x64

_build_linux_x86:
  GOOS=linux GOARCH=386 go build -o linux_x86 main.go

_build_linux_x64:
  GOOS=linux GOARCH=amd64 go build -o linux_x64 main.go


display: \
   build \
   _display_file \
   _display_od \
   _display_hexdump \
   _display_elf_format

_display_file:
   @echo ''
   @echo '[file   ]----------------------------------------------------'
  file -e elf linux_x86
   @echo '[file   ]----------------------------------------------------'
  file -e elf linux_x64
   @echo '[file   ]----------------------------------------------------'
   @echo ''

_display_od:
   @echo ''
   @echo '[od     ]----------------------------------------------------'
  od -t x1 < linux_x86 2>/dev/null | head -n 1
   @echo '[od     ]----------------------------------------------------'
  od -t x1 < linux_x64 2>/dev/null | head -n 1
   @echo '[od     ]----------------------------------------------------'
   @echo ''

_display_hexdump:
   @echo ''
   @echo '[hexdump]----------------------------------------------------'
  hexdump -C < linux_x86 2>/dev/null | head -n 1
   @echo '[hexdump]----------------------------------------------------'
  hexdump -C < linux_x64 2>/dev/null | head -n 1
   @echo '[hexdump]----------------------------------------------------'
   @echo ''

_display_elf_format:
   @echo 'ELF形式は先頭 5バイト 目の値が 0x01 なら32bit, 0x02 なら64bit'
   @echo 'ref: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header'


clean:
   @$(RM) linux_*

で、実行すると以下のようになります。

$ make
GOOS=linux GOARCH=386 go build -o linux_x86 main.go
GOOS=linux GOARCH=amd64 go build -o linux_x64 main.go

[file   ]----------------------------------------------------
file -e elf linux_x86
linux_x86: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV)
[file   ]----------------------------------------------------
file -e elf linux_x64
linux_x64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV)
[file   ]----------------------------------------------------


[od     ]----------------------------------------------------
od -t x1 < linux_x86 2>/dev/null | head -n 1
0000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
[od     ]----------------------------------------------------
od -t x1 < linux_x64 2>/dev/null | head -n 1
0000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
[od     ]----------------------------------------------------


[hexdump]----------------------------------------------------
hexdump -C < linux_x86 2>/dev/null | head -n 1
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
[hexdump]----------------------------------------------------
hexdump -C < linux_x64 2>/dev/null | head -n 1
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
[hexdump]----------------------------------------------------

ELF形式は先頭 5バイト 目の値が 0x01 なら32bit, 0x02 なら64bit
ref: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header

ちゃんと、5バイト目の値が異なっていますね。


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com