看雪论坛
发新帖
6

[原创]华为HG8245H救砖番外篇之利用JTAG完成硬件初始化

bxc 2017-3-6 18:46 834

原文发在我的blog:http://blog.csersoft.net/archives/196

正文:

前言

前几天使用UBoot恢复mtd分区时,因为误操作,导致flash全部被擦除。这下设备上电时连StartCode都跑不了。写内存跑StartCode都不行(外部设备没有初始化,无法访问DRAM):

> mdw 0x82000000
data abort at 0x82000000, dfsr = 0x00001008

可以看到,原本是放置StartCode的地址,现在都无法访问。折腾了几天,大致成功的利用JTAG完成硬件初步初始化,并且可以加载StartCode到内存并成功运行了。

问题解决思路

想要写内存来运行代码,就必须对内存进行初始化操作。但这个初始化操作应该都是StartCode里做的。现在StartCode都跑不起,更别说写内存了。

如果用JTAG来模拟StartCode的初始操作的话,也不太现实,毕竟100多KB的代码分析起来就够累人了,别说模拟了。但是如果能找到一个平衡点,模拟少量的操作,让硬件环境刚好够我利用来跑StartCode,这样实现还是比较容易的。

在网上查了很多关于ARM处理器复位时的流程和低级bootloader做的工作相关的资料。大致感觉有路可走:

一般对于采用非可直接寻址的存储设备(Nand Flash)来引导的话,CPU内部会有一个bootrom,bootrom在上电时会从非可直接寻址的存储设备的固定位置装载固定大小的内容到片内SRAM(比如从Nand Flash的0地址读取2KB内容到片内SRAM),然后设置pc过去并运行。这很小的一部分bootloader就会做简单的初始化操作,然后读取完整的bootloader到内存中的指定位置并运行。

逆向分析StartCode

StartCode的一开始就是ARM经典的中断向量表:

 

第一个中断向量就是偏移0的复位中断向量。CPU在复位时会从这里开始执行,复位中断向量直接跳到0x5C处(处理reset中断的实际代码位置)。

在StartCode的0x5C处,IDA Pro就可以直接F5了,以下为还原的伪代码(部分地方还原的有问题,手工修改过):

可以看出,在

v9 = sub_0;
v10 = sub_82000000;

之后就开始代码的自搬移了。其中v9是程序装载的位置,v10是StartCode应该被放置的地址。

也就是说,只要通过JTAG完成这两句代码之前StartCode所做的操作,就可以使用JTAG访问外部RAM了(起始地址大约在0x80000000)。

使用TCL脚本模拟实现初始化操作

好在OpenOCD支持tcl脚本,大概熟悉了一下tcl的语法,并结合逆向的数据,写了个模拟初始化操作的脚本: