ファームウェアイメージ
.bin、フラッシュのダンプ、.img — 最初のひと当たりを付けたいものをそのまま置けばいい。解析はすべてこのタブの Web Worker で走る。
ファームウェアイメージをここへ
クリックして選択も可 — 64 MiB まで、ディスクから直接読む
ファイルはこのタブから出ない。File API で読み、Web Worker へ転送し、ページを閉じれば消える。そもそも送信先になるエンドポイントがこのページの裏に存在しない。
素性の分からないイメージへの最初のひと当たり。どこが圧縮されていて、何が埋まっていて、自分について何を書いているか。
イメージはこのタブで読み、Web Worker の中だけで解析する。どこにもアップロードしない。
.bin、フラッシュのダンプ、.img — 最初のひと当たりを付けたいものをそのまま置けばいい。解析はすべてこのタブの Web Worker で走る。
ファームウェアイメージをここへ
クリックして選択も可 — 64 MiB まで、ディスクから直接読む
ファイルはこのタブから出ない。File API で読み、Web Worker へ転送し、ページを閉じれば消える。そもそも送信先になるエンドポイントがこのページの裏に存在しない。
ルーターやカメラや開発ボードから吸い出した .bin が手元にあって、資料は何もない。最初に知りたいことはいつも同じ四つで、サイズはどれくらいか、どこが圧縮されているか、既知の形式が何か埋まっていないか、そして平文で自分のことを喋っていないか。binwalk を一回と strings | grep を二、三回、というあの作業をそのままこのページがやる — ブラウザの Web Worker の中で、ファイルはどこへも動かさずに。意図的にやらないのは展開のほうで、このツールは特定して切り出すところまで。持ち帰るのは展開済みのディレクトリではなく、オフセットと長さになる。
エントロピーはブロックごとに一つの数字で、256 通りのバイト値がどれくらい均等にばらけているかを表す。同じバイトの繰り返しなら 0、すべての値が同じ頻度で現れれば 8。消去済みのフラッシュはゼロに張り付き、ブートローダーのコードやテーブルは中ほどに落ち、圧縮済みのペイロードは上端に貼り付いたまま動かない — だからセクションの境目は、探しにいく数値ではなく目に見える段差になる。ブロックサイズは選べて、4096 バイトなら全体の形が、256 バイトならおおよその位置が分かったあとの正確な境界が見える。帯は padding・structured・mixed・compressed の四つで、最後を「暗号化」と呼ばないのは意図的だ。バイトの頻度分布では圧縮と暗号化を区別できない。区別してみせるツールは、知らないことを言っている。
走査はイメージを一度なめて、既知のマジックが座っている位置を全部挙げる。四種類のバイトオーダーの squashfs、JFFS2、CramFS、UBI と UBIFS、uImage、TRX、DfuSe、末尾の DFU サフィックス、Android ブートイメージ、デバイスツリー、Netgear CHK、PEM や SSH 鍵の目印 — さらにこのサイトがファイル種別判定に使っている共通カタログも丸ごと。重なった当たりも全部出す。gzip の塊の中にある squashfs のマジックは、片付けるべき誤りではなくファイルについての事実だから。当たった位置からは領域が始まり、次の当たりまで、あるいはヘッダ自身が長さを申告していればそこまで続く。申告するのは実質 uImage と TRX だけだ。申告された長さが次の当たりまでの距離より短ければ、地図には隙間が残る — その隙間はそのまま描く。どのシグネチャも名乗らなかったバイト列は発見であって、そこまで領域を伸ばすのは枠を付けた当て推量になる。
可読な並びは ASCII と UTF-16LE で取り出し、見た目でタグを付ける。url・ip・email・path・version・private-key・ssh-key・certificate・credential・busybox・linux-version・u-boot の十二種類。タグは形であって主張ではない — 1.2.3.4 に ip と version の両方が付くのは本当に両方の形をしているからで、片方に決めてやるよりも、どちらでありうるかを見せるほうが役に立つ。ヘッダが解ければフィールドはその形式自身の名前のまま出る。uImage のロードアドレスとエントリポイントと CRC、ESP の各セグメントのロードアドレスと長さ、TRX のオフセット、Android boot のページサイズとカーネルコマンドライン、そしてファイル末尾から読む DFU サフィックス。アーキテクチャがそのどれかから、あるいはターゲット名を含む Linux バージョン文字列から導けるなら、根拠を添えて出す。導けなければ unknown と出す — 既定値も、いちばんよくある答えも使わない。
ファームウェア解析に持ち込まれるファイルは、いちばん外に出せない類のものだ。顧客の機器から吸い出したイメージ、まだ出荷していないビルド、他人の箱から取ったダンプ。このページは裏に API のない静的ファイルで、イメージは File API で読み、Web Worker へ転送し、そこで解析し、タブを閉じれば消える。確かめ方も直接的で、DevTools のネットワークタブを開いたまま 64 MB のイメージを解析すれば、そこが空のままなのが見える。
前半だけです。エントロピー計測、シグネチャ走査、文字列抽出、ヘッダ解析 — binwalk の実行のうち「手元にあるのが何か」を教えてくれる部分は、ここに全部あります。展開はありません。何も伸長せず、squashfs をマウントもせず、gzip メンバーも展開しないので、返ってくるのは中身ではなくペイロードのオフセットと長さです。これは未完成ではなく引いた線で、dd で領域を切り出して本物のツールに渡せば、失うのは待ち時間だけです。
unknown と出るのはなぜ?そのイメージの中に、それを名乗るものがなかったからです。推定の根拠は三つだけで、順に試します。arch フィールドが U-Boot の定義値になっている uImage ヘッダ、ESP イメージヘッダ、mips や armv7l や x86_64 のようなターゲット名を含む linux-version タグ付きの文字列。三つとも当たらなければ四つ目の規則もフォールバックもないので、unknown と出し、何を試したかを並べます。ファイルが裏付けていないアーキテクチャ名は、裏付けのある名前と画面上では見分けが付きません。だから正直な答えのほうが価値があります。
エントロピーでは答えられませんし、バイト分布しか見ない他のどのツールでも答えられません。圧縮データも暗号化データも、設計上どちらもほぼ一様になります — 圧縮はそれが目的で、暗号化はそれが要件だからです。7.99 は gzip とも LZMA とも JPEG とも AES とも矛盾しません。両者を分けうるのは端の構造のほうで、圧縮形式はたいてい領域の先頭付近にヘッダなりマジックなり長さフィールドなりを残し、シグネチャ走査がそれを拾います。高エントロピーなのに、その中にも手前にも形式のシグネチャが一つもない — それが疑ってよい形です。ただしそれは追いかける手掛かりであって、このページが下す判決ではありません。
確度の列と、どのテーブル由来かから見てください。確度は機械的で、マジックが 8 バイト以上、または 4 バイト以上でアラインメント条件付きなら high、4〜7 バイトの自由走査なら medium、それ未満は low です。洪水の正体はたいてい esp-image で、マジックが 1 バイトの 0xe9 しかないため偶然でも 256 バイトに一度ほど当たります。ESP のフラッシュダンプのオフセット 0 に出れば本物の情報、それ以外はノイズ — ヘッダのパネルが 4 KiB 境界でしか候補にしないのはそのためです。最低の確度を high にすれば、たいてい実際のレイアウトを説明する数件まで一気に減ります。
64 MiB までで、上限はどれも黙って適用せず必ず表示します。シグネチャ走査は 10,000 件、文字列抽出は 200,000 件で打ち切り、どちらもオフセットの若いほうから残すので、欠けるのはファイルの後ろ側です。そのことをページ側で言うので、途中で切れた一覧が完走した一覧のふりをすることはありません。停止を押せば実行中の解析は取り消され、途中結果は出しません。半分で止まった走査は残りを見ていないのに、画面の上では完走したものと区別が付かないからです。
同じイメージの二つのビルドをバイト単位で比べる。
ELF の位置が分かったら、セクションとシンボルを読む。
そのオフセットの生のバイトを開いて直す。