歡迎來到 黑吧安全網 聚焦網絡安全前沿資訊,精華內容,交流技術心得!

硬件學習之通過樹莓派操控jtag

來源:本站整理 作者:佚名 時間:2019-11-12 TAG: 我要投稿

最近在搞路由器的時候,不小心把CFE給刷掛了,然后發現能通過jtag進行救磚,所以就對jtag進行了一波研究。
最開始只是想救磚,并沒有想深入研究的想法。
救磚嘗試
變磚的路由器型號為:LinkSys wrt54g v8
CPU 型號為:BCM5354
Flash型號為:K8D6316UBM
首先通過jtagulator得到了設備上jtag接口的順序。
正好公司有一個jlink,但是參試了一波失敗,識別不了設備。
隨后通過Google搜到發現了一個工具叫: tjtag-pi
可以通樹莓派來控制jtag,隨后學習了一波樹莓派的操作。
樹莓派Pins
我使用的是rpi3,其接口編號圖如下:

或者在樹莓派3中可以使用gpio readall查看各個接口的狀態:

rpi3中的Python有一個RPi.GPIO模塊,可以控制這些接口。
舉個例子:
>>> from RPi import GPIO
>>> GPIO.setmode(GPIO.BCM)
>>> GPIO.setup(2, GPIO.OUT)
>>> GPIO.setup(3, GPIO.IN)
首先是需要進行初始化GPIO的模式,BCM模式對應的針腳排序是上面圖中橙色的部門。
然后可以對各個針腳進行單獨設置,比如上圖中,把2號針腳設置為輸出,3號針腳設置為輸入。
>>> GPIO.output(2, 1)
>>> GPIO.output(2, 0)
使用output函數進行二進制輸出
>>> GPIO.input(3)
1
使用input函數獲取針腳的輸入。
我們可以用線把兩個針腳連起來測試上面的代碼。
將樹莓派對應針腳和路由器的連起來以后,可以運行tjtag-pi程序。但是在運行的過程中卻遇到了問題,經常會卡在寫flash的時候。通過調整配置,有時是可以寫成功的,但是CFE并沒有被救回來,備份flash的數據,發現并沒有成功寫入數據。
因為使用輪子失敗,所以我只能自己嘗試研究和造輪子了。
jtag
首先是針腳,我見過的設備給jtag一般是提供了5 * 2以上的引腳。其中有一般都是接地引腳,另一半只要知道4個最重要的引腳。
這四個引腳一般情況下的排序是:
TDI
TDO
TMS
TCK
TDI表示輸入,TDO表示輸出,TMS控制位,TCK時鐘輸入。

jtag大致架構如上圖所示,其中TAP-Controller的架構如下圖所示:

根據上面這兩個架構,對jtag的原理進行講解。
jtag的核心是TAP-Controller,通過解析TMS數據,來決定輸入和輸出的關系。所以我們先來看看TAP-Controller的架構。
從上面的圖中我們可以發現,在任何狀態下,輸出5次1,都會回到TEST LOGIC RESET狀態下。所以在使用jtag前,我們先通過TMS端口,發送5次為1的數據,jtag的狀態機將會進入到RESET的復原狀態。
當TAP進入到SHIFT-IR的狀態時,Instruction Register將會開始接收TDI傳入的數據,當輸入結束后,進入到UPDATE-IR狀態時將會解析指令寄存器的值,隨后決定輸出什么數據。
SHIFT-DR則是控制數據寄存器,一般是在讀寫數據的時候需要使用。
講到這里,就出現一個問題了,TMS就一個端口,jtag如何知道TMS每次輸入的值是多少呢?這個時候就需要用到TCK端口了,該端口可以稱為時鐘指令。當TCK從低頻變到高頻時,獲取一比特TMS/TDI輸入,TDO輸出1比特。
比如我們讓TAP進行一次復位操作:
for x in range(5):
    TCK 0
    TMS 1
    TCK 1
再比如,我們需要給指令寄存器傳入0b10:
1.復位
2.進入RUN-TEST/IDLE狀態
TCK 0
TMS 0
TCK 1
3.進入SELECT-DR-SCAN狀態
TCK 0
TMS 1
TCK 1
4.進入SELECT-IR-SCAN狀態
TCK 0
TMS 1
TCK 1
5.進入CAPTURE-IR狀態
TCK 0
TMS 0
TCK 1
6.進入SHIFT-IR狀態
TCK 0
TMS 0
TCK 1
7.輸入0b10
TCK 0
TMS 0
TDI 0
TCK 1
TCK 0
TMS 1
TDI 1
TCK 0
隨后就是進入EXIT-IR -> UPDATE-IR
根據上面的理論我們就可以通過寫一個設置IR的函數:
def clock(tms, tdi):
    tms = 1 if tms else 0
    tdi = 1 if tdi else 0
    GPIO.output(TCK, 0)
    GPIO.output(TMS, tms)
    GPIO.output(TDI, tdi)
    GPIO.output(TCK, 1)
    return GPIO.input(TDO)
def reset():
    clock(1, 0)
    clock(1, 0)
    clock(1, 0)
    clock(1, 0)
    clock(1, 0)
    clock(0, 0)
def set_instr(instr):
    clock(1, 0) 
    clock(1, 0)
    clock(0, 0)
    clock(0, 0)
    for i in range(INSTR_LENGTH):
        clock(i==(INSTR_LENGTH - 1), (instr>>i)&1)
    clock(1, 0)
    clock(0, 0)
把上面的代碼理解清楚后,基本就理解了TAP的邏輯。接下來就是指令的問題了,指令寄存器的長度是多少?指令寄存器的值為多少時是有意義的?

[1] [2]  下一頁

【聲明】:黑吧安全網(http://www.zjtpzs.live)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱[email protected],我們會在最短的時間內進行處理。
  • 最新更新
    • 相關閱讀
      • 本類熱門
        • 最近下載
        神秘东方电子游艺 麻将初学图解 熊猫麻将是哪个公司的 天天乐棋牌游戏官网? 四川快乐12组选玩法 华东15选5走势图大星 三级片人与狗 三人篮球比分网 土豪金麻将手机安卓 体彩十一运夺金预测 排三开机号试机号今天晚上 wnba比分结果查询 有什么股票推荐 黑桃棋牌正版app下载 安徽快3经验 秒速赛车有什么技巧 台湾股票分析师