2. 硬件基础入门:常见嵌入式芯片架构(ARM/MIPS/RISC-V)、外设接口(UART/SPI/I2C)、电路板基础识别
好,咱们正式开始啃硬件这块硬骨头。很多人觉得固件漏洞挖掘嘛,不就是逆向分析二进制文件?其实不然。你想想看,固件跑在芯片上,芯片焊在板子上,板子连着各种外设。如果你连芯片长什么样、怎么跟它说话都不知道,那漏洞挖掘就真成了“盲人摸象”。
我个人习惯,拿到一块陌生的板子,第一件事不是上电,而是先拿放大镜看一圈。嗯,这章我就带你走一遍这个流程。咱们从芯片架构、外设接口、到电路板识别,一步步来。
2.1 三大主流嵌入式芯片架构
嵌入式世界里,ARM、MIPS、RISC-V 三分天下。虽然现在 RISC-V 势头很猛,但 ARM 依然是绝对的老大。我当年做路由器固件分析时,MIPS 架构的芯片还遍地都是,现在 IoT 设备基本被 ARM Cortex 系列统治了。
2.1.1 ARM 架构
ARM 是精简指令集(RISC)的代表。它最大的特点是“低功耗、高性能”。你手里的手机、智能音箱、路由器,里面大概率是 ARM 核。
ARM 有多个系列,咱们做固件分析最常碰到的是:
- Cortex-M 系列:微控制器,比如 STM32、nRF52。跑裸机或 RTOS,没有 MMU(内存管理单元)。
- Cortex-A 系列:应用处理器,比如高通骁龙、全志 H3。跑 Linux/Android,有 MMU。
- Cortex-R 系列:实时处理器,汽车、工业控制用得多。
避坑指南:我曾经在分析一个智能门锁固件时,死活找不到入口函数。后来才发现它是 Cortex-M 架构,用的是 Thumb-2 指令集,反汇编工具默认设置成了 ARM 模式。嗯,这里要注意,ARM 和 Thumb 指令长度不一样,反汇编前一定要确认好。
ARM 的指令集有 32 位的 ARM 模式和 16/32 位混合的 Thumb/Thumb-2 模式。Cortex-M 系列只支持 Thumb-2,不支持 ARM 模式。这一点在做漏洞利用时特别关键——ROP gadget 的地址对齐方式完全不同。
2.1.2 MIPS 架构
MIPS 也是 RISC 架构,曾经在路由器、机顶盒市场占据半壁江山。虽然现在被 ARM 挤压得厉害,但存量设备依然巨大。我建议你至少要学会识别 MIPS 的固件。
MIPS 有几个特点:
- 延迟槽:分支指令后面的那条指令一定会被执行。这个特性让漏洞利用变得很蛋疼。
- 大端/小端:MIPS 既有大端(BE)也有小端(LE)。路由器芯片(比如 MT7620)通常是大端。
- 没有硬件除法指令:除法靠软件模拟,效率低。
个人经验:我在分析一个老款 TP-Link 路由器固件时,发现它的 Web 服务有个栈溢出漏洞。但 MIPS 的延迟槽让我构造 ROP 链时多花了三天时间。说白了,MIPS 的漏洞利用比 ARM 要复杂一些,新手可以先从 ARM 入手。
2.1.3 RISC-V 架构
RISC-V 是后起之秀,开源、模块化、可扩展。这几年在 AI 加速器、IoT 芯片上越来越常见。比如嘉楠科技的 K210、SiFive 的系列芯片。
RISC-V 的指令集是模块化的:
- RV32I/RV64I:基础整数指令集,必须实现。
- M 扩展:乘除法指令。
- F/D 扩展:单精度/双精度浮点。
- C 扩展:压缩指令(16 位指令)。
RISC-V 没有延迟槽,没有 ARM 的 Thumb 模式切换,设计上更干净。但正因为太新,工具链和调试环境还不够成熟。我去年分析一个 RISC-V 的 AI 摄像头固件时,GDB 的插件就踩了好几个坑。
2.2 外设接口:UART、SPI、I2C
芯片不是孤岛,它需要跟外界通信。UART、SPI、I2C 是嵌入式系统最常用的三种串行通信接口。做固件漏洞挖掘时,这些接口往往是突破口——比如通过 UART 拿到 shell,或者通过 SPI 读取 Flash 里的固件。
2.2.1 UART(通用异步收发传输器)
UART 是最简单的串口。它只需要两根线:TX(发送)和 RX(接收)。通信双方约定好波特率(比如 115200、57600),就能收发数据。
UART 的特点:
- 异步:没有时钟线,靠起始位和停止位同步。
- 全双工:可以同时收发。
- 常见用途:调试串口、控制台、GPS 模块。
实战技巧:拿到一块板子,先找板子上的排针或测试点。用万用表量电压——TX 引脚在空闲时通常是高电平(3.3V 或 1.8V)。我曾经在分析一个工业网关时,发现它的 UART 焊盘被涂了黑胶,用酒精擦掉后,接上 USB 转串口工具,直接拿到了 root shell。嗯,这算是固件挖掘里最爽的“捡漏”了。
2.2.2 SPI(串行外设接口)
SPI 是同步、全双工的接口。它需要四根线:
- SCLK:时钟线,由主机产生。
- MOSI:主机输出,从机输入。
- MISO:主机输入,从机输出。
- CS:片选线,低电平有效。
SPI 的速度比 UART 快得多,常用于连接 Flash 存储器、SD 卡、显示屏等。做固件提取时,SPI Flash 是主要目标。
避坑指南:我曾经用 SPI 夹子去读一个路由器上的 Flash,结果读出来的数据全是 0xFF。折腾了半天才发现,板子上的 Flash 是 1.8V 供电的,而我的夹子默认是 3.3V 电平。电平不匹配,芯片根本不会响应。所以,动手前一定要查清楚芯片的 datasheet。
2.2.3 I2C(集成电路总线)
I2C 是同步、半双工的接口。它只需要两根线:
- SCL:时钟线。
- SDA:数据线。
I2C 用 7 位或 10 位地址来寻址设备,一条总线上可以挂多个从机。速度比 SPI 慢,但连线少,常用于传感器、EEPROM、RTC 时钟等。
I2C 的通信协议稍微复杂一点:起始条件、从机地址、读写位、应答位、数据字节、停止条件。做固件分析时,如果发现芯片通过 I2C 跟一个 EEPROM 通信,那这个 EEPROM 里很可能存着密钥或配置信息。
2.3 电路板基础识别
拿到一块 PCB,怎么快速定位关键元件?我总结了一套“三板斧”流程。
2.3.1 看芯片丝印
芯片表面印着型号、批次、厂商 Logo。比如:
- STM32F103C8T6:意法半导体的 ARM Cortex-M3 芯片。
- MT7620A:联发科的路由器 SoC,MIPS 架构。
- GD25Q64C:兆易创新的 SPI Flash,8MB 容量。
把型号记下来,去网上搜 datasheet,就能知道芯片的架构、引脚定义、供电电压等关键信息。
2.3.2 找调试接口
板子上通常会有排针或焊盘,标注着:
- UART:TX、RX、GND、VCC(有时不标)。
- JTAG/SWD:TMS、TCK、TDI、TDO、GND、VCC。
- SPI:CS、CLK、MOSI、MISO、GND、VCC。
如果没有标注,可以用万用表或逻辑分析仪来盲测。比如 UART 的 TX 引脚在空闲时是持续的高电平,用示波器一看就知道。
2.3.3 识别电源和地
电源和地是电路板的基础。通常:
- 地(GND):大面积铜皮,通常接螺丝孔或屏蔽罩。
- 电源(VCC):电解电容的正极、稳压芯片的输出引脚。
- 滤波电容:芯片旁边的小电容(104、106),用于去耦。
用万用表的通断档,一端接螺丝孔(地),另一端去测各个引脚,就能快速找到 GND。然后测电压,找到 VCC。
警告:上电前一定要确认供电电压!我曾经见过一块板子,标注是 3.3V 供电,结果实际是 5V 的。如果直接接 3.3V,芯片可能不工作;如果接 5V 到 3.3V 的芯片上,那就直接冒烟了。嗯,别问我怎么知道的。
2.4 本章知识体系
下面这张图总结了本章的核心内容,你可以把它当作一个快速参考地图。
2.5 小结
这一章的内容比较基础,但很重要。说白了,硬件基础就是固件漏洞挖掘的“地图”和“钥匙”。你知道了芯片是什么架构,才能选对反汇编工具;你找到了 UART 接口,才能跟设备对话;你认出了 SPI Flash,才能把固件 dump 出来分析。
我个人建议,手边常备一块逻辑分析仪(几十块钱的就行)和一套可调电源。遇到不认识的板子,先拍照、量电压、找文档,别急着上电。我曾经因为心急,烧过一块价值两千块的开发板——嗯,从那以后,我养成了“先看后动”的习惯。
下一章,我们会深入固件提取的实战环节。到时候,你会用到今天学的这些知识。
公众号:蓝海资料掘金营,微信deep3321