障碍
与分析固件相关的困难之一是固件二进制文件通常没有标准格式,并且不会像 ELF 或 PE 二进制文件那样以标准方式分离代码和数据。固件二进制文件中没有清晰可识别的分区,可以快速准确地识别和区分代码和数据,这对于反汇编是有问题的,因为诸如Capstone 之类的反汇编器(用于通过binwalk
何时使用--disasm
参数来识别以识别 CPU 架构)) 或Radare2将反汇编数据(例如 ASCII 字符串)作为操作码和操作数。
似乎就是这种情况UBLDM350.BIN
。如果binwalk -A
执行,我们看到 ARM 代码从偏移 0x130 到偏移 0x4224 的检测范围相当一致,范围为 16628 字节:
$ binwalk -A UBLDM350.BIN
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
304 0x130 ARM instructions, function prologue
792 0x318 ARM instructions, function prologue
1396 0x574 ARM instructions, function prologue
8008 0x1F48 ARM instructions, function prologue
9380 0x24A4 ARM instructions, function prologue
9880 0x2698 ARM instructions, function prologue
9908 0x26B4 ARM instructions, function prologue
10024 0x2728 ARM instructions, function prologue
10320 0x2850 ARM instructions, function prologue
13036 0x32EC ARM instructions, function prologue
13080 0x3318 ARM instructions, function prologue
13196 0x338C ARM instructions, function prologue
13548 0x34EC ARM instructions, function prologue
15912 0x3E28 ARM instructions, function prologue
16872 0x41E8 ARM instructions, function prologue
16932 0x4224 ARM instructions, function prologue
但是,当binwalk --disasm --verbose
运行打印反汇编指令时,反汇编代码的内存地址范围远小于这个(0x00
to 0xF5C
= 3932字节):
$ binwalk --disasm --verbose UBLDM350.BIN
Scan Time: 2017-05-07 10:56:43
Target File: /home/c/firmware/Philips/10FF2cme_pictureframe/PHILIPS.10FF2M/UBLDM350/UBLDM350.BIN
MD5 Checksum: 15b2dac3ce98d3308d9c6cf47e74eba7
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ARM executable code, 32-bit, little endian, at least 984 valid instructions
0 0x0 ldr r0, [pc, #0x124]
4 0x4 mcr p15, #0, r0, c9, c1, #0
8 0x8 mov r0, r0
12 0xC mrs r0, apsr
16 0x10 bic r0, r0, #0x1f
20 0x14 orr r0, r0, #0x11
24 0x18 msr cpsr_fc, r0
28 0x1C ldr sp, [pc, #0xf4]
32 0x20 ldr r0, [pc, #0xf4]
36 0x24 add sp, sp, r0
40 0x28 mrs r0, apsr
< snip >
3888 0xF30 lsl ip, ip, #0x16
3892 0xF34 lsr ip, ip, #0x16
3896 0xF38 strh ip, [sp, #0x16]
3900 0xF3C ldrh ip, [sp, #0x14]
3904 0xF40 ldr r0, [sp, #4]
3908 0xF44 ldrb r1, [ip, r0]
3912 0xF48 ldrb r2, [sp, #0x16]
3916 0xF4C eor r1, r2, r1
3920 0xF50 strb r1, [ip, r0]
3924 0xF54 mov r0, #0
3928 0xF58 add sp, sp, #0x1c
3932 0xF5C bx lr
为什么是这样?一条损坏的指令会导致 Capstone 在偏移后停止反汇编0xF5C
:
默认情况下,Capstone 在遇到损坏的指令时停止反汇编。大多数时候,原因是这是输入内部混杂的数据,Capstone不理解这个“奇怪”的代码也是可以理解的。
通常,建议您自己确定下一个代码的位置,然后从该位置继续反汇编。1
上面我们看到在 offset 处的指令后面确实有无效的指令0xF5C
。
以下部分数据被反汇编为代码:
00001ba0 bf f9 0a 1c 02 e0 d3 17 02 f0 92 fc 19 1c 10 1c |................|
00001bb0 70 bc 04 bc 10 47 c0 46 30 31 32 33 34 35 36 37 |p....G.F01234567|
00001bc0 38 39 61 62 63 64 65 66 30 31 32 33 34 35 36 37 |89abcdef01234567|
00001bd0 38 39 41 42 43 44 45 46 00 00 00 00 04 d0 4d e2 |89ABCDEF......M.|
00001be0 00 c0 a0 e3 00 c0 8d e5 00 c0 9d e5 2a 00 5c e3 |............*.\.|
由于没有头文件向内核程序加载器提供在内存中创建进程映像所需的信息,例如入口点和二进制布局信息,直接执行二进制文件可能会失败。
选项
1.独角兽
进一步调查的一个选项是使用Unicorn 引擎动态分析成功反汇编的代码。有关更多信息,请参阅此问答:
Unicorn 和 QEMU:示例用例以了解差异
2.设备处理器识别
如果您可以直接访问硬件,那么确定确切的处理器/微控制器可能会很有用,因为这将使您能够找到技术参考手册和数据表,其中将详细描述设备的内存布局和指令集架构. 内存布局的知识将有助于固件二进制文件的分析。
3. 十六进制转储分析
对十六进制转储的分析可能允许您手动识别固件的非代码部分。仅包含代码的部分可以被 Capstone、r2 或其他一些反汇编程序切出和反汇编。
4. 可视化
使用固件二进制文件的可视化binwalk -E
可以深入了解二进制文件的整体结构。熵图允许快速识别压缩或连续空字节区域。binvis.io也是二进制可视化的有用来源。
也可以看看:
从二进制文件中提取有用信息的方法
1.跳过数据模式