はじめに
Linux でバイナリファイル(実行ファイルやコンパイル済みのプログラムなど)の中身を確認したい場面があります。テキストファイルと同じ感覚で cat や less で開くと、画面が解読不能な記号で埋め尽くされ、ターミナルの表示が崩れることもあります。
less でバイナリファイルを開いた場合の例:
"wtmp" may be a binary file. See it anyway? y
^B^@^@^@^@^@^@^@~^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@~~^@^@rebootこうしたバイナリファイルから、人間が読める文字列(ASCII テキストなど)だけを抽出して表示できるのが strings コマンドです。本記事では、Ubuntu を例に、strings のインストール方法から、実務で役立つオプションや活用例までを解説します。
- インストール: binutils パッケージの導入方法
- 基本: バイナリから文字列を抽出する方法
- オプション: 出力を絞り込む
-n/-tと、走査範囲やエンコーディングを変える-a/-e - 活用: grep と組み合わせたバージョン調査・URL 抽出
strings コマンドのインストール(binutils)
strings を使う際、最初に迷いやすいのがインストールです。次のように strings という名前で導入しようとすると失敗します。
$ sudo apt install strings
E: Unable to locate package stringsUbuntu(Debian 系)には strings という名前のパッケージがありません。strings コマンドは binutils(Binary Utilities)パッケージに含まれるツールの 1 つです。次のコマンドで導入します。
sudo apt update
sudo apt install binutils開発環境が整っている Ubuntu では、最初から導入済みのことも多いです。
インストールの確認
導入後、バージョンを表示して確認します。
$ strings --version
# 出力例
GNU strings (GNU Binutils for Ubuntu) 2.42
Copyright (C) 2024 Free Software Foundation, Inc.
...バージョン情報が表示されれば準備完了です。標準で含まれる binutils は、Ubuntu 24.04 で 2.42、Ubuntu 22.04 で 2.38 です。
基本的な使い方
strings の使い方はシンプルで、中身を見たいバイナリファイルのパスを引数に指定します。基本構文は次のとおりです。
strings [オプション] ファイル名例として、基本的なコマンド /bin/ls(これもバイナリファイル)の中身を見てみます。
strings /bin/ls実行すると、バイナリデータの中から人間が読める文字列だけが抽出され、標準出力に表示されます。出力結果(一部抜粋)は次のようになります。
/lib64/ld-linux-x86-64.so.2
libselinux.so.1
_ITM_deregisterTMCloneTable
__gmon_start__
...
LS_COLORS
QUOTING_STYLE
COLUMNS文字化けしていたファイルから、ライブラリ名や環境変数名(LS_COLORS など)が読み取れるようになりました。

大量に出力される場合は less を活用する
strings の出力は、ファイルによっては数千行に及びます。実務では、パイプ(|)で less に渡すと扱いやすくなります。
strings /bin/ls | less上下キーでのスクロールや、less の検索機能(/キーワード)で特定の文字列を探せます。
grep と組み合わせた活用例
strings は、grep と組み合わせて特定のキーワードを探すことで実用性が高まります。現場でよく使われる 2 つの例を紹介します。
事例①: バージョンやコンパイラ情報を調べる
バージョン文字列やコンパイラ情報が、バイナリに埋め込まれていることがあります。strings の出力を grep で絞り込んで探します。
# バージョン情報を探す(-i は大文字小文字を区別しない)
strings ./my_program | grep -i "version"
# コンパイルに使われた GCC のバージョンを探す
strings ./my_program | grep "GCC"出力例:
Example Program version 1.2.3 (2025-01-15)
GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0--version オプションを持たない古いプログラムや、ライブラリファイル(.so)のバージョン確認に有効です。
事例②: 埋め込まれた URL やファイルパスを探す
ソースコードのないバイナリの挙動を調べる際、埋め込まれた URL やファイルパスが手がかりになります。
# HTTP / HTTPS の URL を探す
strings ./unknown_binary | grep "http"
# 設定ファイルのパス(例: /etc/ 以下)を探す
strings ./unknown_binary | grep "/etc/"出力例:
https://api.example.com/check_update
/etc/my_app/config.confセキュリティ調査や、仕様の分からないレガシーバイナリの解析で、最初の手がかりを得る方法としてよく使われます。
出力を絞り込む・拡張するオプション
strings には、出力を見やすくしたり、走査の範囲やエンコーディングを変えるオプションがあります。主なものを整理します。
-n: 最小文字数を指定する
既定では 4 文字以上の連続する文字列が対象です。これを長くすると、偶然テキストとして認識される短いノイズを減らせます。
# 10 文字以上連続する文字列のみ表示
strings -n 10 ./my_programURL やエラーメッセージなど、意味のある文章を探すときは -n 10 程度に設定すると見やすくなります。
-t: ファイル内の位置(オフセット)を表示する
抽出した文字列がファイルの何バイト目にあるかを表示します。引数に d(10 進)、o(8 進)、x(16 進)を指定します。
# 文字列の位置を 16 進数で表示
strings -t x ./my_program出力例:
4020 ELF
4040 /lib64/ld-linux-x86-64.so.2
4200 version 1.0.0判明したオフセットを元に、バイナリエディタで該当箇所を開くといった解析につなげられます。
-a: ファイル全体を走査する(取りこぼし対策)
見落とされやすいポイントです。Ubuntu / Debian の strings は、ELF などのオブジェクトファイルに対して、既定ではロード済み・初期化済みのセクションだけを走査します。そのため、素の strings ではセクション外に置かれた文字列を取りこぼすことがあります。-a(--all)を付けると、セクション構成に関係なくファイル全体を走査します。
# ファイル全体を走査して文字列を抽出
strings -a ./my_program参考: GNU Binutils strings(1) man ページ
“it only prints the strings from the initialized and loaded sections”
(既定ではオブジェクトファイルの初期化済み・ロード済みセクションからのみ出力する)
https://manpages.debian.org/testing/binutils-common/strings.1.en.html

-e: 文字エンコーディングを指定する
既定では 7 ビット ASCII の文字列が対象です。-e でエンコーディングを変えると、ワイド文字(16 ビットや 32 ビット)の文字列も抽出できます。指定できる主な値は次のとおりです。
- s: 7 ビット ASCII(既定)
- S: 8 ビット
- b / l: 16 ビット(ビッグ / リトルエンディアン)
- B / L: 32 ビット(ビッグ / リトルエンディアン)
# 16 ビット リトルエンディアン(UTF-16LE など)の文字列を探す
strings -e l ./unknown_binaryUTF-16 を使う Windows 由来のバイナリやマルウェア解析では、既定の ASCII 走査だけでは文字列が現れないことがあり、-e l が手がかりになります。
-f: ファイル名を併記する
複数のファイルをまとめて走査するとき、-f(--print-file-name)を付けると、各文字列の前にファイル名を表示します。どのファイル由来かを区別しやすくなります。
strings -f *.so | grep -i "version"strings の使い分けと限界
strings は手軽ですが、万能ではありません。目的に応じて関連ツールと使い分け、限界を理解しておくと解析の精度が上がります。
関連ツールとの使い分け
バイナリの中身を調べるツールは strings だけではありません。代表的なものとの違いを整理します。
| ツール | 主な用途 | strings との違い |
|---|---|---|
| strings | バイナリから印字可能な文字列を抽出 | 文字列の所在を問わず横断的に拾う |
| nm | シンボル(関数名・変数名)の一覧表示 | シンボルテーブルが対象。strip 済みでは表示されない |
| readelf -p(セクション名) | 指定セクションの文字列をダンプ | .rodata など特定セクションに絞って確認できる |
| objdump -s -j(セクション名) | 指定セクションの内容を 16 進 + ASCII で表示 | バイト列と文字列を対応づけて確認できる |
| xxd / hexdump | ファイルを生の 16 進 + ASCII で表示 | 印字可能文字に限らず全バイトを確認できる |
| file | ファイル種別の判定 | 中身ではなく「何のファイルか」を最初に判定する |
使い分けの目安としては、最初に file で種別を判定し、strings で全体の手がかりを得て、特定セクションを深掘りする段階で readelf -p や objdump -s を使う流れが実用的です。シンボルが残っているバイナリなら、nm で関数名や変数名を確認できます。
参考: readelf(1) man ページ
“readelf displays information about one or more ELF format object files”
(readelf は 1 つ以上の ELF 形式オブジェクトファイルの情報を表示する)
https://man7.org/linux/man-pages/man1/readelf.1.html
strings の限界と注意点
strings は「印字可能な文字が一定長以上連続する箇所」を抜き出す仕組みのため、次のような限界があります。
- 難読化・暗号化・パック(圧縮)されたバイナリでは、文字列が平文で現れないことがある。実行時に復号・展開される文字列は、静的な strings では取得できない。
- 偶然印字可能文字が並んだだけの箇所も拾うため、抽出結果にはノイズが混じる(
-nでの最小長指定や grep での絞り込みが前提になる) - マルウェア解析では、strings の結果だけで挙動を判断せず、動的解析やほかのツールと併用する前提で使う。
これらを踏まえると、strings は「最初の手がかりを得る軽量な一手」と位置づけ、深い解析は前述の関連ツールや動的解析と組み合わせるのが現実的です。
まとめ
本記事では、Ubuntu を例に strings コマンドの使い方を解説しました。strings は binutils に含まれ、バイナリから印字可能な文字列を抽出して、バージョン調査やバイナリ解析の手がかりを得るのに役立ちます。既定の走査範囲やエンコーディングには注意点があり、目的に応じてオプションや関連ツールを使い分けるのが実用的です。
- パッケージ名は strings ではなく binutils
- 既定は 4 文字以上の印字可能文字列を抽出
- grep 連携でバージョンや URL を効率的に抽出
- -n でノイズ削減、-t でオフセット表示
- Ubuntu の既定走査は -a で全体走査に切り替え
- -e でワイド文字(UTF-16 など)の文字列も抽出
- 深い解析は readelf や objdump と使い分け
以上、最後までお読みいただきありがとうございました。
