固件逆向学习
2025-08-09 00:28:24 # iot

前言

由于接触到的各种设备的固件都有不同的架构,在逆向的过程中也会遇到各种各样的问题,所以打算写一篇文章记录下来。

奇奇怪怪的芯片和架构

芯片名称: Tlsr8251
架构名称: Telink
ghidra插件: https://github.com/trust1995/Ghidra_TELink_TC32
官方sdk:https://wiki.telink-semi.cn/wiki/chip-series/TLSR825x-Series/
开发文档:https://wiki.telink-semi.cn/doc/an/AN-21112301-C_Telink%20B85m%20BLE%20Single%20Connection%20SDK%20Developer%20Handbook.pdf

OM(昂瑞微)

芯片名称: OMEM6621
架构名称: arm-cortex-m4
开发文档: 需要找官方签署保密协议
官方sdk: 需要找官方签署保密协议

BK

芯片名称: bk3432

固件分析遇到的特殊情况

需要自己新增segment

逆向omem6621芯片的固件中遇到的这个问题,一开始是通过中断入口地址来确定固件的基地址,但是ida一通分析之后只解析出来400多个函数,用bindiff恢复符号表后还有很多库函数比对不出来,那大概率就是少分析了很多函数。
比对了sdk编译出来的固件,得知了在ROM中还有两块区域需要单独抓到其他地址处,这样才能满足调用需求,所以要在ida中edit segment再move segment。

固件分析的经验之谈

Arm架构m核心的启动

很常见的一个知识点,arm架构中的m系列芯片,主打的是一个低成本高能效的需求。常用于小型设备中,比如家用电子设备等。
Mcu复位后需要一段启动代码来引导程序,而存储于固件头部的地址信息,称之为中断入口地址。
image.png
从上到下分别是:

1
2
3
4
1. __initial_sp 栈顶
2. Reset_Handler 复位中断
3. NMI_Handler NMI
4. HardFault_Handler 硬件错误

通过将栈顶赋值为sp寄存器,随后跳转到复位中断函数,初始号Mcu时钟,然后执行main函数。
image.png
所以通常可以用这个知识点来判断固件的基地址以及main函数的位置

ROM LIB库

在嵌入式设备中,将稳定且不常修改的功能模块预先编译为二进制代码,烧录到设备的Flash或ROM区域,称之为ROM Library。
应用程序运行时,通过地址跳转或者符号引用来调用函数和访问数据。
一些芯片的官方文档中,通常会随着sdk一同给出lib文件。

多地址启动机制

这个机制第一次看到是在采用telink芯片的设备中,可以在flash中烧录多个固件,bootloder根据标识位来决定启动哪个固件。
以telink为例,默认的启动地址是0x0开始的,此外还可以从0x20000,0x40000开始启动。
这一机制的用处,我个人认为是为了方便dfu升级,dfu传入的新固件可以存放于0x20000处,这样就不需要删除原本的固件也可以做到更新固件了。
那么还有一个问题,bootloader是如何判断该从哪个地址启动的呢。根据的是启动地址的0x8偏移处的4个标识字节
image.png
bootloader会先从0x0开始读取这个位置的值,如果符合那么就启动该位置的固件,否则继续往后。

Prev
2025-08-09 00:28:24 # iot