
ロジックアナライザのキャプチャからSPIフラッシュイメージを再構築するためのツール
spidump は、起動時にデバイスが SPI/QSPI NOR フラッシュを読み込む際のロジックアナライザキャプチャを解析し、その読み取りトラフィックからフラッシュイメージを再構築します — チップを直接読み取る必要はありません。フラッシュコマンドセットは Scapy でモデル化されているため、読み取りトランザクションは、1本のワイヤーで送られても4本で送られても同じ論理オブジェクトです。
| フォーマット | ヘッダー | 備考 |
|---|---|---|
| Saleae Logic 2 "SPI" アナライザテーブル | name,type,start_time,...,mosi,miso | enable/result/disable 行、1バイトにつき1つの result |
| Saleae 生のバイト単位テーブル | Time [s],Packet ID,MOSI,MISO | 1バイトにつき1行、Packet ID でグループ化 |
| QSPI-Analyzer エクスポート | Time [s],Packet ID, Transaction State, DATA, Lines Used | ステートマシン: 1=cmd, 2=addr, 3=dummy, 4=data |
Saleae Logic / KingstVIS 用の QSPI-Analyzer プラグインは、通常の SPI アナライザではデコードできないクアッドモードのフレーミング(例: 0x6B Fast Read Quad Output、1-1-4)をデコードします。
# 標準的なシングルレーン SPI キャプチャ(Logic 2 SPI アナライザエクスポート)
python main.py examples/bigger-boot.csv -o recovered_flash.bin -v
# クアッド SPI キャプチャ(QSPI-Analyzer エクスポート)— 同じコマンド、フォーマットは自動検出
python main.py big-quad-spi-analyzed-dump.txt -o quad.bin -v
# シングルレーンの区間(U-Boot)とクアッドの区間(rootfs)を1つのイメージにマージ。
# シングルレーンで起動してから QSPI に切り替えるデバイスでは、各領域が
# 異なるキャプチャに残る。--merge はそれらを接合する。データレーン幅が
# オペコードと一致しない読み取り(例: クアッド読み取りをシングルレーンの
# アナライザが誤デコードしたもの)は自動的に破棄されるため、混在した
# キャプチャが結果を汚染することはない。
python main.py single_lane_boot.csv --merge quad_boot.txt -o full.bin -v
# チップセレクトのフレーミングがない生エクスポート(Packet ID が一定)は、
# アイドルギャップ(バイト周期の中央値の4倍)で自動的に分割される。
# しきい値は --gap SECONDS で上書きするか、--gap 0 で Packet ID による
# グループ化を強制する
python main.py raw_boot.csv --gap 2e-6 -o raw.bin -v
# 自動サイズ推定が誤っている場合にフラッシュサイズ / フィルバイトを強制
python main.py capture.txt --flash-size 0x1000000 --fill 0xFF -o out.bin
-v は検出されたフォーマット、オペコードごとのトランザクションのヒストグラム、選択されたフラッシュサイズ、読み取りカバレッジを表示します。未読み取り領域は 0xFF(消去済み NOR の状態)で埋められるため、出力はそのまま binwalk に投入しても安全です。
フラッシュ読み取りは、ワイヤー幅に関係なく同じ論理トランザクションです: オペコード、アドレス、そして一連のデータバイト。以下の2つのトレースは、同じ4バイト(0x2D0000 にある SquashFS マジック hsqs、bigger-boot.csv から取得)をシングルレーンモードとクアッドモードで読み取ったものです:
(python docs/diagrams/mkwave.py で再生成できます。wavedrom-cli が必要で、PNG には rsvg-convert も必要です。)
{cmd, addr, data, lines} に変換します。SPIFlashCmd(Scapy)がオペコード / アドレス / ダミーヘッダーをモデル化します。読み取り
オペコード(シングルおよびクアッド: 0x03 0x0B 0x6B 0xEB 0x6C 0x0C …)はすべて
READ_COMMANDS のエントリにすぎません。reconstruct_image がすべての読み取りを bytearray に再生し、カバレッジを追跡します。起動時は必要なものだけを読み取るため、カバレッジは設計上部分的です — デバイスが実際に触れた領域(ブートローダー、カーネル、マウントされた rootfs)を復元できます。シングルレーンで起動してからクアッドに切り替えるデバイスでは、両方の区間をキャプチャして接合してください。