韌體映像
.bin、flash dump、.img — 想先摸個底的檔案直接丟進來。整段分析都在這個分頁的 Web Worker 裡跑。
把韌體映像丟到這裡
也可以點一下選檔 — 上限 64 MiB,直接從磁碟讀
檔案不會離開這個分頁:用 File API 讀進來、轉交給 Web Worker、關掉頁面就沒了。這頁背後根本沒有可以上傳的端點。
面對一份來歷不明的映像,先摸清楚哪裡被壓縮、裡面埋了什麼、它自己講了什麼。
韌體在這個分頁裡讀、在 Web Worker 裡分析,一個位元組都不會上傳。
.bin、flash dump、.img — 想先摸個底的檔案直接丟進來。整段分析都在這個分頁的 Web Worker 裡跑。
把韌體映像丟到這裡
也可以點一下選檔 — 上限 64 MiB,直接從磁碟讀
檔案不會離開這個分頁:用 File API 讀進來、轉交給 Web Worker、關掉頁面就沒了。這頁背後根本沒有可以上傳的端點。
你手上有一份從路由器、攝影機或開發板挖出來的 .bin,沒有任何文件。要問的問題永遠是那四個:它多大、哪幾段被壓縮過、裡面埋了哪些已知格式、以及它有沒有用明文講出自己的來歷。那就是跑一次 binwalk 再配上兩三行 strings | grep,而這頁做的就是這件事 — 在 Web Worker 裡跑,在你自己的瀏覽器裡跑,檔案一步都不用移動。刻意不做的是解開:這個工具只負責認出來跟切開,你帶走的是位移跟長度,不是一整個解出來的目錄。
熵值是每個區塊一個數字,量的是 256 種位元組數值在裡面散得多平均:整塊都同一個位元組是 0,每種數值出現次數都一樣是 8。抹除過的 flash 貼在零,bootloader 的程式碼跟表格落在中段,壓縮過的內容則會貼著上緣一路不動 — 所以兩個段落的交界通常是一眼看得見的落差,而不是你得去翻的數字。區塊大小由你決定:4096 位元組看得到整份映像的輪廓,256 位元組則是在你大概知道位置之後,用來釘出精確邊界的。四個分帶是 padding、structured、mixed、compressed,最後一個不叫「加密」是刻意的。位元組分布分不出壓縮跟加密;替你貼上加密標籤的工具,是在講它其實不知道的事。
掃描把整份映像走一遍,把所有坐著已知 magic 的位移都挑出來:四種位元組序的 squashfs、JFFS2、CramFS、UBI 與 UBIFS、uImage、TRX、DfuSe、尾端的 DFU suffix、Android boot image、device tree、Netgear CHK、PEM 與 SSH 金鑰標記 — 再加上這個站本來就拿來判斷檔案類型的那整份共用格式目錄。重疊的命中一律照列,因為 gzip 區塊裡出現 squashfs magic 是關於這個檔案的事實,不是需要收拾掉的錯誤。每個命中會開一個區段,一路延伸到下一個命中,或者延伸到標頭自己宣告的長度 — 而會宣告長度的實際上只有 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 的 offsets;Android boot 的頁面大小與核心命令列;還有從檔案尾端讀出來的 DFU suffix。如果架構能從其中之一推出來,或能從有寫出目標平台的 Linux 版本字串推出來,就會連同依據一起列。推不出來就寫 unknown — 不套預設值,也不填最常見的答案。
會被拿來丟進韌體檢視器的檔案,剛好是最不能往外送的那一種:從客戶裝置上挖出來的映像、還沒出貨的版本、別人機器上倒出來的 dump。這頁是一個背後沒有 API 的靜態檔案。映像用 File API 讀進來、轉交給 Web Worker、在那裡分析完,關掉分頁就沒了。驗證方式也很直接:把 DevTools 停在網路分頁上,然後丟一份 64 MB 的映像進去分析,你會看到那一欄從頭到尾都是空的。
只有前半段。熵值量測、簽章掃描、字串抽取、標頭解析 —— 一次 binwalk 裡負責告訴你「手上這份是什麼」的部分,這裡都齊了。抽取則沒有:不做任何解壓縮、不掛載 squashfs、不展開 gzip 成員,所以你拿到的是內容的位移與長度,不是內容本身。這是刻意畫的界線,不是還沒做完的功能 —— 用 dd 把區段切出來丟給真正的工具,你少掉的只有等待的時間。
unknown?因為你這份映像裡沒有任何東西講出來。推測的依據只有三種,而且照順序試:arch 欄位對得上 U-Boot 實際定義值的 uImage 標頭、ESP 映像標頭、或是帶著 linux-version 標籤、字面上寫著 mips/armv7l/x86_64 這類目標平台的字串。三種都沒中就沒有第四條規則、也沒有備援,所以頁面直接寫 unknown,並列出它試過哪些規則。一個檔案沒有撐住的架構名稱,擺在畫面上跟有憑有據的名稱長得一模一樣 —— 這就是誠實那個答案比較值錢的原因。
熵值答不出這題,任何只看位元組分布的工具也一樣答不出來。壓縮資料跟加密資料在設計上都會接近均勻 —— 壓縮的目的就是這個,加密則是必須這樣 —— 所以 7.99 跟 gzip、LZMA、JPEG、AES 全都相符。真正能分開兩者的是邊緣的結構:壓縮格式幾乎一定會在區段開頭附近留下標頭、magic 或長度欄位,而簽章掃描就會撈到它。一段高熵值、但裡面跟前面都找不到任何格式簽章 —— 那個形狀才值得起疑。不過那是一條要繼續追的線索,不是這頁會替你下的判決。
先看信心度那一欄,還有它來自哪張表。信心度是機械規則:magic 有 8 個位元組以上、或 4 個以上且帶對齊條件算 high;4 到 7 個自由掃描算 medium;再短就是 low。淹掉清單的通常是 esp-image,它的 magic 只有 0xe9 一個位元組,隨機碰運氣大概每 256 個位元組就中一次。它出現在 ESP flash dump 的位移 0 是真資訊,出現在別處就是雜訊 —— 這也是標頭那一區只把 4 KiB 邊界上的位移當候選的原因。把最低信心度拉到 high,清單通常會縮回真正描述版面配置的那幾筆。
上限是 64 MiB,而且每一道上限都會講出來,不會默默套用。簽章掃描在 10,000 筆停手,字串抽取在 200,000 筆停手,兩者都是留位移比較前面的,所以少掉的是檔案後半段 —— 這件事頁面會明說,不讓一份被截斷的清單假裝自己跑完了。按下停止會取消進行中的分析,而且不給半套結果:掃到一半被打斷的清單根本沒看過後半個檔案,可是排在畫面上時,它跟跑完的清單長得一模一樣。
把同一份映像的兩個版本逐位元組比對。
知道 ELF 在哪之後,進去讀它的 section 跟符號。
把那個位移的原始位元組打開來改。