运行由 binwalk --disasm 标识为 ARM 可执行文件的二进制文件

逆向工程 二元分析 固件 手臂
2021-06-12 09:33:48

我有一个飞利浦 10FF2 相框,我正在尝试逆向工程。在飞利浦网站 ( http://download.p4c.philips.com/files/1/10ff2cme_00/10ff2cme_00_fus_aen.zip )的固件下载中,我可以找到一个名为的文件UBLDM350.bin,在分析时binwalk --disasm给我:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ARM executable code, 32-bit, little endian, at least 984 valid instructions

我的问题是如何获得有关此文件的更多信息?我尝试使用 qemu-arm 运行它,但失败了:

walterheck@walter-toshiba:~/projects/pictureframe/PHILIPS.10FF2M$ qemu-arm ./UBLDM350.BIN 
Error while loading ./UBLDM350.BIN: Permission denied

运行strings它给了我垃圾,只有一些可读的东西:

(null)
0123456789abcdef0123456789ABCDEF
...fail(%d)
NANDReadPage error(%d)
Error block(%d)
Magic switch failure(0x%X)
Bad block found(block=%d)
Move done.
Start boot from NAND
Ver = %s
UBLN1.05

我正在寻求有关下一步尝试的帮助。

3个回答

障碍

与分析固件相关的困难之一是固件二进制文件通常没有标准格式,并且不会像 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运行打印反汇编指令时,反汇编代码的内存地址范围远小于这个(0x00to 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

偏移量 0xf60 处的无效指令

上面我们看到在 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.跳过数据模式

为了补充 SYS_V 的好答案,这种“奇怪”的代码和数据混合实际上在 ARM 代码中很常见。

ARM 指令的大小是固定的(ARM 上为 4 个字节,THUMB 为 2 个字节)并且没有足够的空间来编码 32 位立即数。相反,ARM 编译器通常会做两件事——

  1. 他们在需要常量的函数指令之后直接放置 32 位立即数,并且

  2. 它们在函数中使用与 PC 相关的加载指令将这些常量放入寄存器中。

在 SYS_V 的反汇编中,地址0x00000F08指令0x00000F28都是 PC 相对负载。(虽然拆装是这里是有益的,显示所述计算的地址0x00000FF80x00000FFC,而不是示出[PC,offset])。

反汇编器也很有帮助,并在侧面用红色注释反汇编,显示将加载的直接常量的值。在这种情况下,加载的值分别0x01E100D40x01E100DC

通常会按照访问它们的函数的地址顺序查看存储在函数之后的立即数。因此,在这种情况下,该函数以 at 指令结束,0x00000F5C并且立即数常量似乎跨越了地址范围0x00000F60to 0x00000FFF,我通常希望以下函数从 address 开始0x00001000

知道了这一点,反汇编程序就可以识别这种模式并自动跳过相关数据。

您似乎有一个原始固件文件,而不是用户模式可执行文件。qemu-arm仅支持用户模式 ​​ARM Linux ELF 可执行文件。理论上您可以尝试全系统仿真器 ( qemu-system-arm),但不要指望它能够工作,除非 QEMU 明确支持底层硬件。也可以使用基于 QEMU 的Unicorn 模拟器,它更灵活一些,但您需要编写一些代码来加载文件并开始模拟;没有方便的即用型程序。