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,虚拟地址)
我的经验:拿到一个固件包,先看文件大小。小于 2MB 的,基本是 MCU 固件;大于 10MB 的,大概率是 Linux 系统镜像。

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)
注意:UART 是异步通信,收发双方必须约定相同的波特率。逆向时如果发现乱码,先检查波特率设置。

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
避坑指南:我曾经分析过一个 IoT 模块,它的 SPI Flash 通信一直失败。后来发现是 CPOL/CPHA 配置反了。逆向时,如果发现 Flash 读写异常,优先检查 SPI 模式配置。

2.4 知识体系结构图

下面这张图把本章的核心知识点串起来了。你可以看到,从芯片架构到操作系统,再到外设总线,是一条完整的知识链。

嵌入式系统基础知识体系 嵌入式系统基础:知识体系结构 嵌入式系统 芯片架构 操作系统 外设总线 MCU (Cortex-M) MPU (Cortex-A) 裸机 RTOS Linux UART I2C SPI 逆向分析时,先识别芯片架构 → 再确定操作系统 → 最后分析外设通信 这三层信息决定了你的分析工具和思路

2.5 实战视角:如何快速识别目标系统

拿到一个陌生固件,我一般按这个步骤来:

  1. 看文件头:用 hexdump 或 binwalk 查看前 64 字节。如果是 ELF 文件,说明是 Linux 系统;如果是纯二进制,可能是 MCU 固件。
  2. 搜字符串:在固件里搜索 FreeRTOS、uCOS、Linux version 等关键词。
  3. 找中断向量表:MCU 固件通常在起始地址有中断向量表,第一个 4 字节是栈指针,第二个 4 字节是复位向量。
  4. 分析外设基地址:根据芯片手册,找到 UART、I2C、SPI 的寄存器基地址,然后在固件里搜索这些地址。

举个例子:我在分析一个智能灯泡固件时,发现起始地址 0x08000000 处有标准的 Cortex-M 中断向量表。确认是 STM32 系列 MCU,跑的是 FreeRTOS。然后通过搜索 UART 寄存器地址,找到了调试输出函数,成功提取了日志信息。

嗯,这一章的内容就到这里。记住,嵌入式系统逆向分析,基础决定上限。芯片架构、操作系统、外设协议,这三块地基打牢了,后面分析固件升级机制、做性能调优,才能游刃有余。