首页
社区
课程
招聘
[原创]STM32固件逆向
发表于: 2022-5-15 14:48 37470

[原创]STM32固件逆向

2022-5-15 14:48
37470

用的很久之前做的一个电风扇的课设来做实验
Oc1fje.png
用到了外部中断,定时器中断,pwm。MCU是STM32F103ZET6
Oc3xxO.png
在keil的设置中可以看到固件的起始地址,默认情况下为0x8000000。另外,keil生成的是hex文件,hex文件是带有基地址信息的bin文件,如果我们要生成bin文件,需要进行如下设置:
Oc83iq.png
另外,烧录到mcu中的固件是不带符号表等调试信息的,即hex和bin文件都不带调试信息,因为mcu的内存有限,但keil会单独生成一个带有调试信息的axf文件,我们可以以这个axf文件为基准,对照着恢复bin文件或者hex文件,下面我们来观察一下这三个文件的区别:
首先是axf文件
OcJebQ.png
O2Y4Yj.png
几乎和源代码一摸一样,除了一些外设名用地址代替了。
再看到hex文件
OcJ7qg.png
首先需要将架构修改为arm小端序,再修改一下架构版本,stm32f103zet6是cortex-m3内核的,armv7架构
OcYZz6.png
修改完后加载hex文件
OcYNy8.png
IDA会自动识别出基地址,能识别出不少函数了,但伪代码是真的难看
OctU91.png
基本上是看不出个什么东西来。
最后是bin文件
Octfjf.png
bin文件去除了地址信息的hex文件,需要手动设置基地址。

我们的分析将以bin文件为目标。
将基地址重设为0x8000000,这个地址怎么来的?可以看stm32f103zet6的datasheet
OcUEJs.png
从0x8000000开始就是flash的空间
重新设置加载地址之后再将其按照代码解析就变成了hex文件的样子
OcaQjP.png
但此时存在很多标红的地址,这是因为这些地址在IDA中并没有设置,因此IDA将其解析为非法地址,标红了,我们现在要做的就是手动添加一些段。


在axf文件中,IDA解析出了如下几个段
Oca4u6.png

单片机内存被总分为flash(rom)和sram(ram),flash里面的数据掉电可保存,sram中的数据掉电就丢失,sram的执行速度要快于flash,flash容量大于sram上方的最低内存地址,最高地址,都是在flash和sram中。
我们正常下载程序都是下载存储进flash里面,这也是为什么断电可保存的原因
单片机的程序存储分为code(代码存储区)、RO-data(只读数据存储区)、RW-data(读写数据存储区) 和 ZI-data(零初始化数据区)
Flash 存储 code和RO-data
Sram 存储 RW-data 和ZI-data

在datasheet中一样可以找到sram的起始地址,为0x20000000,结束地址为0x2000ffff,我们自己添加段不必像IDA自动分析的那样详细,一个sram的段即可。
也可以在IDA启动时设置好固件加载地址和sram的开始以及结束地址。
添加了sram段之后,红色的非法地址消失了,如下
O29j0g.png

下一步,我们需要恢复符号表,由于bin文件不存在调试信息,所以IDA生成的伪代码几乎没眼看,为了方便我们的逆向,我们需要恢复函数名以及导入一些结构体。在这里就需要用到axf文件。

在前面我们看到axf文件几乎和源代码是一样的效果,里面有丰富的调试信息,当然,我们不使用这个课设的axf文件来恢复bin,这样就太刻意了。

由于我这个课设使用的是库函数来开发的,所以就不能使用stm32cube生成的hal库来恢复。具体该怎么恢复?我们采用bindiff来恢复符号表。

如果有闲工夫或者是对stm32的开发非常上手,就可以自己写一个demo,尽可能多的使用到各种库函数,然后编译出一个axf文件。我这里的话,由于好久没有用stm32了,开发起来有些生疏,所以就不自己手写了,我选择捡现成的项目。我学习stm32的时候买的是xx原子家的开发板,他们提供的例程也是非常丰富的,有五十多个,由易到难,涵盖了stm32开发的方方面面,因此我就直接拿这些例程中的一部分,编译出axf文件。比如下面这个内存分配的例程:
O2k0iQ.png
又比如这个pwm的例程
O2k6s0.png
可以多选几个例程,能涵盖更多的库函数,将这些axf文件用IDA打开,然后生成idb文件。然后在我们的目标bin文件中,使用bindiff加载idb文件
O2Auyq.png
选择一个idb文件,然后会出现这样一个比较界面
O2AfnP.png
选取similarity大的函数导入到bin文件中
O2AIAS.png
导入之后实际上就能恢复大部分的函数名了
O2EW8J.png
但实际上,由于我这个课设的开发中使用了一些xx原子封装好的初始化函数(相当于xx原子对原本的库函数做了二次开发),例如uart_init,delay_init这两个函数均是二次封装后的函数,所以恢复出来的函数会比一般情况下多一点。
多使用几个idb文件进行恢复后,已经可以看了
O2ZaXn.png

但这还不够,我们还需要导入SVD文件,啥是SVD文件捏?
O2mKdP.png
在IDA7.5以后,就自带SVD文件加载插件了,如下图
O2myQJ.png
打开之后如下
O2mhFK.png
我们可以自行下载相应的SVD文件,或者加载GitHub上的仓库,我这里选择自行下载然后在本地加载。下载链接是这个:cmsis-svd
选中想要加载的svd文件之后,IDA就会自动恢复bin文件中的外设结构,体现在伪代码中就是这样:
O2nU6H.png
这样
O2nB7t.png
当然,也不是所有的外设都能恢复,和axf文件中的肯定是有差别的,但对我们的逆向已经起到了很大的作用了。

到目前位置我们已经做了如下几步:加载bin文件->设置固件加载基地址->添加sram段->恢复符号表->恢复外设信息。程序还原工作已经接近尾声,还剩下最后一步,恢复结构体。

打开某个例程的axf文件,可以查看下其中使用的结构体
O2Mmp8.png
这些结构体中,有TIM_TimeBaseInitTypeDefNVIC_InitTypeDefGPIO_InitTypeDefUSART_InitTypeDefGPIO_TypeDef等是我们经常使用的,用来进行定时器初始化,中断初始化,IO口初始化等等。
我们生成c header file
O2QSNq.png
然后在bin文件中解析生成的头文件
O2QmU1.png
然后在local type中就能看到不少结构体了
O2QHaR.png
光导入了结构体还不够,我们还得手动将IDA的伪代码中的变量重新设置类型,怎么确定某个变量的类型是什么呢?需要结合库函数的变量类型来设置。
GPIO_Init这个函数为例
O21u6O.png
我们打开固件库使用手册,找到GPIO_Init的原型
O21fuF.png
可以看到原型为


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2022-5-15 14:50 被Lpwn编辑 ,原因:
收藏
免费 21
支持
分享
打赏 + 100.00雪花
打赏次数 1 雪花 + 100.00
 
赞赏  Editor   +100.00 2022/06/10 恭喜您获得“雪花”奖励,安全圈有你而精彩!
最新回复 (14)
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢 分享
2022-5-16 08:59
0
雪    币: 8745
活跃值: (5673)
能力值: ( LV13,RANK:296 )
在线值:
发帖
回帖
粉丝
3
mark
2022-5-16 22:59
0
雪    币: 199
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
感谢分享!!
2022-5-17 18:51
0
雪    币: 226
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
感谢分享!!
2022-5-17 23:06
0
雪    币: 927
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
请前辈移步帮查看这个帖子https://bbs.pediy.com/thread-272872.htm
2022-5-18 10:48
0
雪    币: 2143
活跃值: (2727)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
wx_Vae luo 请前辈移步帮查看这个帖子https://bbs.pediy.com/thread-272872.htm[em_13]
我不是前辈。。。初学者而已
2022-5-18 16:47
0
雪    币: 927
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
Lpwn 我不是前辈。。。初学者而已
我也是参照您的教程去IDA逆向stm32固件,遇到些问题不会解决还得请您指点一二
2022-5-18 22:05
0
雪    币: 631
活跃值: (3006)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
9
mark
2022-5-30 08:54
0
雪    币: 433
活跃值: (2509)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
10
mark
2022-6-1 14:27
0
雪    币: 256
活跃值: (4060)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
mark
2022-6-6 18:14
0
雪    币: 11
活跃值: (226)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
感谢分享。
2022-6-9 19:24
0
雪    币: 1060
活跃值: (65)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
方便详聊吗
2023-4-28 10:05
0
雪    币: 1856
活跃值: (1211)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
14
狠狠支持了
2024-5-8 11:28
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
最近在msp430的bin逆向不能反成伪C,也不知道是idapro不支持还是我操作不对。。。
2024-6-24 23:30
0
游客
登录 | 注册 方可回帖
返回
//