-
-
[原创] CrazyRadio固件故障分析与SPI编程器制作
-
2021-8-30 05:38
14704
-
[原创] CrazyRadio固件故障分析与SPI编程器制作
● 起因
手误将优联接收器的固件刷入CrazyRadio,出现设备失灵的情况,既无法将CrazyRadio作为接收器使用,也无法通过usb再对设备进行读写操作。为了找出原因,在修复之前我想先把整个flash提取出来简单分析一下,于是便有了这个项目。
● 问题分析
1.查阅资料
进行多次尝试与查阅资料后在nRF24LU1+官方文档发现:
这款芯片都预置了一个USB bootloader: boot24lu1p-f32.hex ( 可在官方SDK中找到)
理论上来讲,只要能将该hex文件写入Flash中,一定可以让设备重新运行,但是为了弄清问题的原因,先避免对Flash进行任何写入操作。
2.读取Flash
在此为了分析问题的成因,决定先将整个Flash读出来进行分析。这里选择用一块Arduino对其进行SPI读写。
接线方式与引脚对应关系:
1 2 3 4 5 6 7 8 | Arduino CrazyRadio
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
MOSI: 11 = = > 6
MISO: 12 = = > 8
SCK : 13 = = > 4
SS : 10 = = > 10
3V3 : 3V3 = = > 5
GND : GND = = > 9
|
需要注意的是,在Arduino内置函数SPISettings()中,参数1为SPI通信速度,该值不能使用官方示例程序中的默认值(14000000),否则速度过快会导致数据丢失,出现大规模的0x00。
将读取到的数据通过串口以十六进制字符打印出来,得到Flash中的全部内容。可以发现,其中包含有优联接收器的完整固件。
3.Flash中内容分析
a.出厂Flash
出厂Flash的起始位置:
跳转到0x7800的位置,再看0x7800处:
b.刷入优联固件后的Flash:
优联Flash的起始位置:
跳转到bootloader的指令被优联固件覆盖
● 结论
跳转到bootloader的指令被优联固件覆盖,导致设备加电后无法执行bootloader代码,而bootloader中可能包含有拷贝Flash中固件到RAM中的代码,以及初始化USB的代码。所以导致设备失灵且无法使用USB进行读写操作。
● 解决方案
制作一个SPI编程器,通过写入出厂bootloader,将设备重新运行起来。
为Arduino编写程序,在加电后监听串口,有数据传来就将数据通过SPI写入外部Flash。同时用python编写上位机程序,将hex文件数据通过串口发送给Arduino。
1.Arduino部分 :
此部分主要涉及到Arduino与CrazyRadio的SPI通信
需要注意:
1 2 3 4 | a. 根据官方文档描述:在激活PROG引脚后,必须等待至少 1.5 ms才能发送第一条Flash命令 ( 文档: 17.7 . 1 )
b. 一次擦写操作完成后,下一次擦写时需要再次配置FSR.WEN ,比如执行了擦出操作后,再写入时需要再次配置FSR.WEN ( 文档: 17.7 . 1 )
c. 在不擦出整页的情况下,不能对该页进行写入操作 ( 文档: 17.7 . 1.5 )
d. 写入时,一页数据需要分成两个 256 字节分别写入。
|
2.上位机部分:
此部分主要涉及到PC与Arduino的串口通信
需要注意:
1 2 3 4 | a. Flash写入时,需要以页作为单位 (写入前必须进行整页擦除操作)
b. 串口传输的速度要远大于通过SPI写入Flash的速度,所以要做PC与Arduino的反馈机制,Arduino将此次接收到的一页数据处理完后,再主动向PC请求数据
c. 即便是Arduino主动请求数据,并且每次串口写入一个字节sleep 10 毫秒,仍然会出现数据丢失的情况,经过查看文档后发现,Arduino默认的串口缓冲区为 64 字节,而这里的一页为 512 字节,可以使用宏定义
d. 使用python初始化串口后,一定不要马上发送数据 (此时Arduino还没准备好),需要先Sleep一下再进行发送,否则会出现数据开头几个字节丢失的情况
|
3.写入
写入hex文件后,CrazyRadio又可以正常工作。
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界