施用logic analyzer和python对JTAG调试器进行逆向工程

使用logic analyzer和python对JTAG调试器进行逆向工程对JTAG调试器进行逆向工程这篇文章展示了如何对一个j

使用logic analyzer和python对JTAG调试器进行逆向工程
对JTAG调试器进行逆向工程这篇文章展示了如何对一个jtag调试器进行”逆向工程“,使用逻辑分析仪采集jtag调试器的时序数据,导出成cvs格式数据,然后使用python进行数据处理生成C语言源代码。帮助分析提取jtag协议,完成jtag调试器的”逆向工程“。

对jtag调试器进行逆向工程,分析mcu的jtag协议,这是个巨大的工程,方法不对,根本做不出来。但是借助逻辑分析仪进行数据采集,用python进行数据处理,直接生产程序代码,看起来能很容易的取得调试器的协议。


msp430的jtag,官方只开源了烧写flash部分的源码和协议,至于单步调试,读写寄存器,断点设置等,都没有公开,只有几家商业公司掌握着,msp430开源社区里没这方面的任何进展。因此,我下定决心对fet430uif进行“逆向工程",完成arm板的jtag调试器,实现对msp430的gdb调试。


msp430的jtag使用的是4pin的jtag接口,TCK,TMS,TDI, TDO。使用agient logic analyzer采集jta个的时序,分别多次采集mspdebug的基本命令:读寄存器,写寄存器,单步,断点设置,运行,运行到断点等。

施用logic analyzer和python对JTAG调试器进行逆向工程


把采集到的数据保存好,再选着list数据(并非waveform数据)导出成cvs格式的数据格式,方便python读取分析。采集到的jtag数据量非常大,50ns的采样间隔,500ms就有160mb的数据。

施用logic analyzer和python对JTAG调试器进行逆向工程


msp430的jtag的基本操作只有shiftIR,shiftDR8,shiftDR16等几个,不多,用python写一个状态机,即可对这些数据进行处理。使用python对数据进行初步处理生成对应的jtag基本操作,生成一个只有几十kb的txt文本。


施用logic analyzer和python对JTAG调试器进行逆向工程


从采集的时序数据中初步得出了上面这些jtag基本操作的数据,这样进行分析手工编写代码,具有一定难度,工作量巨大。我再次使用python进行处理,生成C语言代码,为了方便阅读,还会自动生成一些简单的注释,生成的代码包含了宏定义。

施用logic analyzer和python对JTAG调试器进行逆向工程


这样,fet430uif调试器产生的时序,我都可以很方便的解释成C语言代码,分析出jtag协议,易如反掌。本来一个非常有难度的逆向工程,借助了逻辑分析仪与python就变得异常简单容易,大大减少了工作量。作为一个嵌入式工程师,学习掌握多种编程语言,对工作的帮助是不可估量。当初我学习python语言也是因为网上看到许多大牛对python的推崇,没想到却短期内给我的工作带来如此巨大的帮助。所以,尽量多学习掌握不同的语言,你永远也不知道它有多么重要,但它可能某一天帮了你一把。


附录python源码:

decode-msp430-jtag.py

import sys#travel all lines in filedatafile = sys.argv[1]print """/* * %s */""" % sys.argv[1]codeDict = {"0xC8":"IR_CNTRL_SIG_16BIT", "0xc8":"IR_CNTRL_SIG_16BIT", "0x88":"IR_CNTRL_SIG_M8BIT","0x48":"IR_CNTRL_SIG_L8BIT","0x28":"IR_CNTRL_SIG_CAPTURE","0xA8":"IR_CNTRL_SIG_RELEASE", "0xa8":"IR_CNTRL_SIG_RELEASE","0x44":"IR_PREPARE_BLOW","0x24":"IR_EX_BLOW","0x82":"IR_DATA_16BIT","0xC2":"IR_DATA_QUICK", "0xc2":"IR_DATA_QUICK","0x22":"IR_DATA_PSA","0x62":"IR_SHIFT_OUT_PSA","0xC1":"IR_ADDR_16BIT", "0xc1":"IR_ADDR_16BIT","0x21":"IR_ADDR_CAPTURE","0xA1":"IR_DATA_TO_ADDR", "0xa1":"IR_DATA_TO_ADDR","0xFF":"IR_BYPASS", "0xff":"IR_BYPASS","0x90":"IR_CTRL_SETTING","0x30":"IR_30_SETTING","0x42":"IR_DATA_CAPTURE","0xD0": "IR_D0_CHECK", "0xd0": "IR_D0_CHECK"}lastTime = "0"for line in open(datafile):#print line.strip("\n")try:myTime, sym, operation, code =  line.split()except:print "//FIXME: error - line.split() %s" % linecontinuecode = code.strip("\n")if sym != "us":interval = (float(myTime) - float(lastTime))if  interval > 0.1:print "\n//Interval  %F ms" % intervalprint "MsDelay(%d);" % int(interval)lastTime = myTimeif operation == "ShiftIR":if codeDict[code] == "IR_CNTRL_SIG_CAPTURE":print "\n//fetch"elif codeDict[code] == "IR_CTRL_SETTING":print "\n//setting"elif codeDict[code] == "IR_D0_CHECK":print "\n//check"elif codeDict[code] == "IR_CNTRL_SIG_RELEASE":print "\n//run"print "IR_Shift(" + codeDict[code] + ");"elif operation == "ShiftDR":if len(code) == 4:print "DR_Shift8(" + code + ");",else:print "DR_Shift16(" + code + ");",elif operation == "=":print "\t\t//=" + codeelif operation == "clrTCLK": print "ClrTCLK();"elif operation == "setTCLK": print "SetTCLK();"