2. 固件升级基础
做固件逆向分析,说白了就是跟芯片和它脑子里的代码打交道。你得先搞清楚这芯片是什么架构,跑的是什么系统,怎么跟外界说话。这一章,我把这些基础掰开揉碎了讲给你听。
2.1 微控制器 vs 微处理器:核心差异
很多人刚入行时搞不清 MCU 和 MPU 的区别。我简单总结一下:
- 微控制器 (MCU):芯片内部集成了 CPU、RAM、Flash、各种外设。一通电就能跑,适合做控制类产品。比如你家里的智能插座、遥控器。
- 微处理器 (MPU):只有 CPU 核心,需要外接 DDR、Flash、电源管理芯片。性能强,适合跑 Linux 这种复杂系统。比如路由器、智能音箱。
我在分析一个智能门锁固件时,第一件事就是看它用的是哪家 MCU。如果是 Cortex-M 系列,那固件大概率是裸机或 RTOS;如果是 Cortex-A 系列,那里面很可能跑着 Linux。
| 对比项 | MCU | MPU |
|---|---|---|
| 典型架构 | ARM Cortex-M, RISC-V, 8051 | ARM Cortex-A, x86, MIPS |
| 存储 | 片内 Flash + SRAM | 外接 DDR + eMMC/NAND |
| 功耗 | 毫瓦级 | 瓦级 |
| 操作系统 | 裸机 / RTOS | Linux / Android |
| 逆向难度 | 中等(无 MMU,地址直接映射) | 较高(有 MMU,虚拟地址) |
2.2 常见嵌入式操作系统
操作系统决定了固件的启动流程、任务调度方式、内存管理策略。逆向分析时,识别出操作系统类型,就等于找到了分析入口。
2.2.1 裸机 (Bare-metal)
没有操作系统,代码直接跑在硬件上。主循环 + 中断是它的灵魂。我见过很多小家电的固件都是裸机,代码量小,但逻辑非常紧凑。
2.2.2 实时操作系统 (RTOS)
像 FreeRTOS、uC/OS-III、RT-Thread 这些。它们有任务调度、信号量、消息队列。逆向时,你会在固件里看到任务控制块 (TCB)、就绪列表这些数据结构。
- FreeRTOS:开源免费,市场占有率最高。它的任务切换代码在
port.c里,逆向时找 PendSV 异常入口就能定位调度器。 - uC/OS-III:商业闭源,但很多老产品在用。它的任务栈初始化有固定模式,可以用来识别任务入口。
2.2.3 嵌入式 Linux
功能强大,但启动流程复杂。从 Bootloader → Kernel → Rootfs → 应用程序,每一层都可能藏有安全机制。
逆向要点:Linux 固件通常是一个完整的文件系统镜像。用 binwalk 解包后,重点关注 /etc/init.d/、/usr/bin/、/lib/ 目录下的文件。
2.3 外设与总线协议
固件怎么跟外界通信?靠的就是这些总线协议。逆向分析时,你经常需要从二进制代码里还原出 I2C 读写序列、SPI 传输逻辑、UART 调试输出。
2.3.1 UART (通用异步收发器)
这是我最喜欢的调试接口。很多产品会留一个 UART 调试口,波特率通常是 115200 或 9600。我曾经通过 UART 输出直接拿到了一个路由器的 root shell。
- 信号线:TX (发送)、RX (接收)、GND (地)
- 波特率:常见 9600、19200、38400、115200
- 数据格式:起始位(1) + 数据位(8) + 校验位(可选) + 停止位(1)
2.3.2 I2C (集成电路总线)
两根线 (SCL + SDA) 挂多个设备,靠地址区分。常用于传感器、EEPROM、RTC 芯片的通信。
- 主从模式:MCU 通常是主机,外设是从机
- 7位地址:每个从机有唯一地址,比如 0x50 是常见的 EEPROM 地址
- 速率:标准模式 100kHz,快速模式 400kHz
逆向时,在固件里搜索 0xA0 (EEPROM 写地址) 或 0xD0 (RTC 地址),往往能定位到 I2C 驱动代码。
2.3.3 SPI (串行外设接口)
四根线 (MOSI、MISO、SCLK、CS),全双工通信,速度比 I2C 快得多。常用于 Flash、LCD、SD 卡。
- CS (片选):每个从机一根独立的片选线
- 时钟极性 (CPOL) 和相位 (CPHA):有 4 种模式,必须匹配
- 速率:可达几十 MHz
2.4 知识体系结构图
下面这张图把本章的核心知识点串起来了。你可以看到,从芯片架构到操作系统,再到外设总线,是一条完整的知识链。
2.5 实战视角:如何快速识别目标系统
拿到一个陌生固件,我一般按这个步骤来:
- 看文件头:用
hexdump或binwalk查看前 64 字节。如果是 ELF 文件,说明是 Linux 系统;如果是纯二进制,可能是 MCU 固件。 - 搜字符串:在固件里搜索
FreeRTOS、uCOS、Linux version等关键词。 - 找中断向量表:MCU 固件通常在起始地址有中断向量表,第一个 4 字节是栈指针,第二个 4 字节是复位向量。
- 分析外设基地址:根据芯片手册,找到 UART、I2C、SPI 的寄存器基地址,然后在固件里搜索这些地址。
举个例子:我在分析一个智能灯泡固件时,发现起始地址 0x08000000 处有标准的 Cortex-M 中断向量表。确认是 STM32 系列 MCU,跑的是 FreeRTOS。然后通过搜索 UART 寄存器地址,找到了调试输出函数,成功提取了日志信息。
嗯,这一章的内容就到这里。记住,嵌入式系统逆向分析,基础决定上限。芯片架构、操作系统、外设协议,这三块地基打牢了,后面分析固件升级机制、做性能调优,才能游刃有余。