開源硬件USB抓包及協議分析工具分享

USB抓包工具屬於小衆產品,開源的就更少了!!

USB抓包工具分爲純軟件的和硬件的兩種,純軟件usb抓包工具需要在系統能正確枚舉usb設備的前提下才能讓內核的鉤子函數捕抓到數據,而後者在usb不正常時也能捕捉到鏈路數據(令牌包等),屬於更底層的抓包方式。

一、我用過的並且好用的純軟件USB抓包工具有:

1.USBlyzer(能很方便的幫你分析出HID報告描述符等等)

2.Bus Hound(沒有協議分析,但抓包很直觀,而且允許你發送一些自定義的控制傳輸命令給設備,用於調試。另外,Bus Hound不單能抓usb總線,包括串口、PCIE等都能抓)

很遺憾,他們都不是開源的,linux下倒是有開源的,如linux平臺下“usbmon驅動+tcpdump”方式抓包。tcpdump -D可以列舉可以抓包的設備,包括以太網、USB、CAN總線等。

3.linux使用usbmon驅動+tcpdump+wirshark調試:

需要編譯linux加入usbmon驅動:
make  ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
                   Device Drivers -->
                            USB Support -->
                                     USB Monitor --> Select "M"

modprobe usbmon
mount -t debugfs none_debugs /sys/kernel/debug
cat /sys/kernel/debug/usb/devices

選擇包含有 P: Vendor=xxx ProdID=xxx Rev= xxx 的段落(即篩選出你要抓包的USB設備的PID/VID號)
如果總線號是1,則是1u,如果總線號是2,則是2u,依次類推。特殊情況是0u表示監聽所有總線
cat /sys/kernel/debug/usb/usbmon/1u > ./usbmon.txt得到原始數據

或者使用tcpdump -i usbmon1 -w /var/usb_log.pcap將捕捉到的usb數據導入到wirshark上閱讀,能做簡單的Class協議分析。

另外,USB錯誤碼文檔在Linux內核源碼路徑下的Documentation/usb/error-codes.txt有關於usb的錯誤代碼意義說明。

二、開源硬件usb抓包工具

1.玩具級別的usb sniffer(硬件平臺FTDI+USB PHY+FPGA )

http://ultra-embedded.com/usb_sniffer/

對應github代碼路徑:https://github.com/ultraembedded/usb_sniffer

FPGA使用verilog開發,主機軟件使用C語言開發,功能比較簡單,而且過濾條件也簡陋,但麻雀雖小五臟俱全,有興趣可以研究一下,我自己做過實驗,我在USB PHY那裏跪了,FPGA怎麼都抓不到USB3300的數據包,沒有去深入分析問題所在。

2.OpenVizsla(硬件平臺FTDI+USB PHY+FPGA)

http://openvizsla.org/

對應github代碼路徑:https://github.com/openvizsla/ov_ftdi

完全開源,包括pcb電路板打樣文件和BOM物料清單都有,FPGA使用python開發,主機軟件亦使用python進行開發。個人覺得FPGA使用python開發目前還不成熟(Migen-A Python toolbox for building complex digital hardware),代碼看起來比較冗餘,我已經在ubuntu虛擬機上編譯出ov3.bit了,暫不打算閱讀FPGA源碼,而是嘗試改寫其主機軟件加入常用class的協議分析功能(但其實我改它用處並不大,因爲目前OpenVizsla已經支持很多分析軟件了,譬如wireshark、Beagle 480的分析軟件等等)。usb PHY使用了ULPI接口,優點是管腳少,缺點是FPGA需要實現一個適配層轉換爲UTMI+接口。FPGA使用老掉牙的spartan6,開發工具使用ISE14.7,不過還好Xilinx官網說至少會供貨到2027年,也勝在封裝夠簡易(TQFP-144),方便手工焊接。4層板打板也便宜,我已經焊接好一套,正在調試中,打算實測一下效果!


此分割線之間的內容更新於2020-02-06:

       利用疫情期間豐富的春節假期,調試了一下openvizsla板子,雖然年前我手工焊接好一套,但在調試過程中相當於要重新再焊接一次,因爲超多虛焊和管腳短路,反覆焊接焊到我心灰意冷,尤其USB3343芯片,4mmx4mm QFN-24封裝的,熱風槍焊接完眼睛都花了。焊接技巧:拿鑷子的手不要抖,拖錫(吸錫)要耐心。最後,焊接方面應該沒問題了,又發現SDRAM型號兼容性不太好,由AS4C16M16S-7TCN改爲MT48LC16M16A2P-75貌似好一點,過年快遞不工作,唯有加點錢順豐發貨。最後貌似能抓包了,但運行官方的測試SDRAM命令貌似有點問題(我還沒研究怎麼去定位,理論上應該要在FPGA上寫測試代碼,用chipscope抓包分析看是控制時序不行還是虛焊還是其他問題,如果是用verilog寫的還好,不過本項目是使用Migen庫,沒閱讀過該庫api說明,都不知道怎麼例化chipscope來抓信號調試,先放下了,因爲換另一批MT48LC16M16A2P-75又好了):

測試:$sudo ./ovctl.py report
USB PHY Tests
    ULPI PHY ID: 04240009 (SMSC 334x)
    ULPI Scratch register IO test: OK
    PHY Function Control Reg:  48
    PHY Interface Control Reg: 00
SDRAM tests
    ... 0: OK
    ... 1: OK
    ... 2: OK
    ... 3: FAIL

換另一批次的MT48LC16M16A2P-75芯片後測試正常:

$ sudo ./ovctl.preport
USB PHY Tests
    ULPI PHY ID: 04240009 (SMSC 334x)
    ULPI Scratch register IO test: OK
    PHY Function Control Reg:  48
    PHY Interface Control Reg: 00
SDRAM tests
    ... 0: OK
    ... 1: OK
    ... 2: OK
    ... 3: OK
    ... 4: OK
    ... 5: OK
    ... all passed

1)接上U盤後“$ sudo ./ovctl.py sniff hs | tee usbdump.log”能抓包:
[        ]  10.379599 d=  0.000000 [ 43.3 + 74.383] [ 34] DATA0: 55 53 42 43 40 28 79 13 00 00 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 34 3e 
[        ]  10.379600 d=  0.000001 [ 43.3 + 75.333] [  1] NYET 
[        ]  10.379627 d=  0.000027 [ 43.3 +102.800] [  3] IN   : 18.1 
[        ]  10.379628 d=  0.000000 [ 43.3 +103.300] [  1] NAK 
[        ]  10.379650 d=  0.000022 [ 43.4 +  0.667] [  3] IN   : 18.1 
[        ]  10.379651 d=  0.000000 [ 43.4 +  1.167] [ 16] DATA0: 55 53 42 53 40 28 79 13 00 00 00 00 00 81 ab 
[        ]  10.379651 d=  0.000001 [ 43.4 +  1.900] [  1] ACK 
0 / 16777216 (0.00 % utilization) 411 kB | 0 overflow, 39cdd08a total | R00066fc7 W00066fc7
[        ]  10.784078 d=  0.404427 [191.7 +106.433] [  3] PING : 18.2 
[        ]  10.784079 d=  0.000000 [191.7 +106.933] [  1] ACK 
[        ]  10.784081 d=  0.000002 [191.7 +109.417] [  3] OUT  : 18.2 
[        ]  10.784081 d=  0.000000 [191.7 +109.750] [ 34] DATA1: 55 53 42 43 10 70 fb 1a 00 00 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81 37 
[        ]  10.784082 d=  0.000001 [191.7 +110.667] [  1] NYET 
[        ]  10.784112 d=  0.000030 [192.0 + 15.817] [  3] IN   : 18.1 
[        ]  10.784113 d=  0.000000 [192.0 + 16.317] [  1] NAK 
[        ]  10.784134 d=  0.000021 [192.0 + 37.400] [  3] IN   : 18.1 
[        ]  10.784135 d=  0.000000 [192.0 + 37.883] [ 16] DATA1: 55 53 42 53 10 70 fb 1a 00 00 00 00 00 db a3 
[        ]  10.784135 d=  0.000001 [192.0 + 38.617] [  1] ACK 
[        ]  10.784249 d=  0.000113 [192.1 + 27.117] [  3] PING : 18.2 
[        ]  10.784249 d=  0.000000 [192.1 + 27.617] [  1] ACK 
[        ]  10.784252 d=  0.000002 [192.1 + 30.083] [  3] OUT  : 18.2 

.................

但不穩定,有時會出現異常,尤其在U盤傳輸大文件時:

........
[        ] 396.229368 d=  0.000009 [142.4 + 29.783] [  1] ACK 
[        ] 396.229369 d=  0.000000 [142.4 + 30.083] [  3] IN   : 12.1 
[        ] 396.229369 d=  0.000000 [142.4 + 30.583] [  1] NAK 
[        ] 396.229395 d=  0.000026 [142.4 + 56.383] [  3] IN   : 12.1 
Unmatched byte ba - discarding
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/home/default/work/other/usb_stuff/ov_ftdi/software/host/LibOV.py", line 637, in __comms
    raise self.__comm_exc
  File "/home/default/work/other/usb_stuff/ov_ftdi/software/host/LibOV.py", line 616, in callback
    code = service.presentBytes(self.__buf)
  File "/home/default/work/other/usb_stuff/ov_ftdi/software/host/LibOV.py", line 310, in presentBytes
    self.consume(b[:size])
  File "/home/default/work/other/usb_stuff/ov_ftdi/software/host/LibOV.py", line 558, in consume
    assert ''.join("%02x"% r for r in buf) in ["e0e1e2", "e8e9ea"], buf
AssertionError: b'\xe0b\xb1'
需要運行“sudo ./ovctl.py -l”重新加載FPGA程序後,再重新抓包才恢復正常!

2)另外,出現抓不了包時,有可能需要重新插拔被測設備。

3)接上USB鼠標,打算抓取低速鼠標數據“sudo ./ovctl.py sniff ls”,發現只能抓取到最開始的枚舉數據(setup階段)就停掉了,手動鼠標,抓取不到X和Y的數據變化,重新加載FPGA重新也無濟於事!(後面發現原來此時PC並沒有識別出鼠標來,抓不到xy座標數據也能說得通,但問題是,爲什麼此時PC會識別不出來鼠標設備呢?拔掉直接接到PC上其實是ok的,即鼠標本身是沒問題的,難道是接PC這端的USB線纜太長了!--0207--換筆記本上的USB充電口(黃色,沒有測試藍色的USB3.x),發現只有這個USB口能抓到鼠標數據,用萬用表測量openvizsla上的USB端子,無論PC是否用充電口,Vbus均爲4.96v,板上兩個usb口間各個引腳電阻均爲0.5歐左右,符合規範。猜想是D+/D-對地的阻抗不符合USB協議規範,我去掉R4/R5兩個電阻,防止FPGA輸出雜訊影響D+/D-,但沒有改善。)

4)抓包輸出標準文檔,供第三方軟件協議分析

目前抓包輸出格式僅支持"verbose", "custom", "pcap"和 "iti1480a",如:

sudo ./ovctl.py -l sniff hs --format pcap --out ./my_upan.pcap供wireshark分析

如果要限定抓包時間爲5s,可以設置timeout參數,如:

sudo ./ovctl.py -l sniff hs --timeout 5 --format iti1480a --out ./my_upan.iti1480a等

總結一下:

1.如果下次有開源硬件感興趣需要製作,我寧願花錢請貼片廠焊接算了,手工焊接太折騰人了!

2.openvizsla抓包需要手工指定ls、fs和hs(即低速、全速和高速)這個不好,不夠自動化,搞錯了會抓不到數據。

3.openvizsla終究不是企業產品,沒有經過大量驗證,有很多兼容性問題,如即使芯片型號一致(如SDRAM),時序還是有偏差,導致抓包不穩定。(我懷疑兼容性問題是由於該項目使用python轉換爲verilog代碼的Migen庫有關,開發過FPGA的人都知道,邏輯正確並不代表實際硬件能正確運行,自動轉換的東西肯定沒有手工編寫verilog代碼的時序優化做得好。綜合前仿真過了,實現後也可能出現時序不過關,如產生毛刺,建立保持時間不足等,SDRAM這種運行頻率達100MHz甚至133MHz高頻的器件,沒有做時序仿真真的很容易出問題!)

openvizsla的調試暫告一段落,初步能抓包分析,但不夠穩定,還不能用於調試usb設備!!


3.PhyWhisperer-USB(硬件平臺M3+USB PHY+FPGA)

https://www.crowdsupply.com/newae/phywhisperer-usb

對應github代碼路徑:https://github.com/newaetech/phywhispererusb

也是完全開源,這個項目比較新,2019年才啓動,同樣也是4層板。FPGA使用verilog語言開發,主機軟件使用python開發。它除了支持普通的usb抓包外,還支持簡單的功率分析。usb PHY使用UTMI+接口的USB3500-ABZJ芯片,無需操作寄存器直接對接FPGA。而FPGA使用spartan 7,屬於比較新的系列,使用xilinx新一代開發工具vivado進行開發。因爲芯片是BGA封裝不方便手工焊接,需要花錢讓貼片廠焊接,把動手能力差的創客/極客擋在門外,當然有錢人除外。另外板內也不含SDRAM,沒法對數據進行緩衝處理,只使用FPGA片內有限的Block RAM(僅360Kbit容量)作爲緩衝區,所以當抓USB2.0攝像頭這種大量、連續的USB數據時應該存在丟數據的可能,最後,該項目還包含一個microchip的單片機,我認爲是一個敗筆,雖說可編程器件比較靈活(官網是這麼說的),但不應該搞那麼多可編程器件,維護那麼多份不同類型的代碼,容易出bug,使用FTDI的usb轉FIFO多好,無需編程,我想該項目應該是micochip公司有份出錢搞的,看PhyWhisperer-USB官網介紹就知道了(PhyWhisperer-USB is part of the Microchip Get Launched 2019 design competition!),肯定儘量用多點micochip的芯片(另外usb PHY也是他家的產品)才能申請到錢,有錢纔有動力,作爲中國人,你懂的。綜上,PhyWhisperer-USB對比先驅OpenVizsla,還沒有完全成熟,各位創客/極客們可以先觀望一段時間再動手製作,有能力者也可以參與開發,在github上提交push請求,或者修改Altium Designer工程,修改PCB和代碼以適應自己的需求,畢竟它是完全開源的,可以任意修改!

        以上3款硬件USB抓包工具均支持硬件級別的條件觸發,譬如選擇只捕捉某個地址的端點、只看IN+ACK,過濾掉OUT+NAK等等。

        FPGA均使用“從串配置”的配置模式,優點是方便隨時升級fpga固件、省掉一個spi nor flash,具體可參考Xilinx官網的UG470等文檔。其工作原理是“微控制器MCU/FTDI等芯片利用SPI總線或並行總線將配置文件傳到FPGA後加載,MCU先主動拉低PROGRAM_B(CS#)管腳以啓動配置,然後輪詢FPGA的INIT_B管腳電平,當它爲高電平時代表FPGA準備好了,此時MCU提供SPI時鐘(CLK)和數據(MOSI)直至FPGA配置完畢,當FPGA的DONE管腳被拉高就代表FPGA加載成功。但如果INIT_B被拉低或DONE一直爲低電平則代表配置失敗,需重試,如果重試多次均失敗就需要排查問題了”,參考電路圖如下,其中箭頭代表信號的傳輸方向:

爲了對比幾種開源的usb分析儀,盜用PhyWhisperer-USB的圖:

        正如我開頭所說,USB協議分析儀終究是小衆產品,這導致了商業抓包工具非常昂貴,譬如國外的Beagle 480、USB Explorer 200等,國內的,要點名批評沁恆科技的usb2.0分析儀,自己軟件做得不好沒關係,還不開放API接口讓我們二次開發分析軟件,也不能輸出wireshark能分析的文檔格式,不過它硬件做得也還行,也是支持觸發源輸入的。所以對於我們調試USB設備的朋友來說,擁有一臺自己的USB抓包儀真是如虎添翼,上述三款開源的usb抓包工具你值得擁有,感興趣的同學趕緊去打板、去github下載代碼編譯吧!

        最後,很感慨我們國內的開發者不如國外的,這裏我說的不是技術這一層面,而是指那一份開源精神,那一份熱情!

 

發佈了105 篇原創文章 · 獲贊 62 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章