如何将 ARM Cortex-M0 .hex 文件反编译为 C++?

逆向工程 手臂 反编译
2021-06-29 07:37:49

源文件为 intel 32 位 .hex 格式,它是为新唐 NUC220LE3AE 构建的。我想将它反编译为 C++,或者至少是汇编。我有一些汇编经验,但主要是 MIPS,那是几年前的 - 所以高级代码是首选。

.hex 文件链接:http ://www.3fvape.com/images/3fvape-blog-img/20150806-4384-xcubeII-upgrade/SMOK_X_CUBE_II_firmware_v1.07.hex

它所在的设备是 SMOK Xcube 2(电子烟盒模组)。

我的目标是添加一个选项来根据雾化器温度控制 LED 颜色。

我进行了搜索,但找不到适用的操作方法。

2个回答

简短的回答:你不能。

至少,不要期望一个可读、可编译的 C 源代码。在这个网站的其他地方有讨论为什么,所以我不会详细介绍。

另外,请注意没有简单的演练或操作方法。你需要试验,也需要一些经验。

为了让您开始,您可能会:

  • 将 .hex 文件转换为原始二进制文件,例如使用Hex2bin
  • 将该二进制文件与可重定向的反编译器一起使用,选择“原始机器代码”和“ARM+Thumb”作为架构
  • 如果可重定向反编译器的结果不令人满意(它对我来说效果不佳,我上次尝试过),您可能想尝试在线反汇编器以获取汇编代码
  • 当然,终极工具是IDA,但是免费版不能处理ARM,而且价格对于业余项目来说可能有点高。

radare2 直接支持这些 ihex 文件

请注意,在我的原始答案中,radare2 中的命令使用开关 -b32 SYS_V 评论说它应该是 -b16 并发布了一个答案,其中包含详细信息如何从我的答案结束到有形结果这里是该线程的链接如何从 bin 文件中找到有用的信息

:\>ls -l
total 172
-rw-rw-rw-  1 Admin 0 172401 2016-01-01 00:44 SMOK_X_CUBE_II_firmware_v1.07.hex

:\>rahash2 -a md5 SMOK_X_CUBE_II_firmware_v1.07.hex
SMOK_X_CUBE_II_firmware_v1.07.hex:0x00000000-0x0002a170 md5: 351660a42b846d19e35f54f75530e2d9

:\>radare2 -A -a arm -b 32 ihex://SMOK_X_CUBE_II_firmware_v1.07.hex
Function too big at 0xa50e54
Function too big at 0xfe25a2ac
Function too big at 0x1648234
Function too big at 0x13ed738
[0x00000000]> s 0xc1
[0x000000c1]> pd 10
|          0x000000c1    4885460c       mcrreq p5, 4, r8, r6, c8
|          0x000000c5    f070fc00       ldrshteq r7, [ip], 0
|          0x000000c9    480047e9       stmdb r7, {r3, r6} ^
|          0x000000cd    1b0000e8       stmda r0, {r0, r1, r3, r4}
|          0x000000d1    0e002004       strteq r0, [r0], -0xe
|          0x000000d5    48804704       strbeq r8, [r7], -0x48
|          0x000000d9    480047fe       cdp2 p0, 4, c0, c7, c8, 2
|          0x000000dd    e7fee7fe       cdp2 p14, 0xe, c15, c7, c7, 7
|          0x000000e1    e7fee7fe       cdp2 p14, 0xe, c15, c7, c7, 7
|          0x000000e5    e7fee75d       stclpl p14, c15, [r7, 0x39c]!
[0x000000c1]>

如果您想知道radare2 如何在地址0xxxxc1 处获得4885460c 然后进一步阅读

intel 似乎已经发布了 ihex 文件格式的规格我从 microsym 那里拿到了一个名为 intelhex.pdf 的 pdf 不知道是否有任何最新版本可用 这是我第一次刷 ihex 或 arm

Hexadecimal Object File Format Specification Revision A January 6, 1988

基于文件中的描述

似乎 ihex 文件中的每一行都以 a 开头,colon :
然后是一个字节 = 记录长度,
然后是两个字节 = 加载偏移量,
然后是一个字节 =
行中最后一个字节的记录类型= 校验和

以上每个都是十六进制对,即文件中的 BYTE E8 将是 0x45 0x38

3A 31 30 30 30 30 30 30 30 45 38 30 45 30 30 :10000000E80E00

该文件由 3833 行组成,其中 3830 行的记录长度为 0x10

wc SMOK_X_CUBE_II_firmware_v1.07.hex
  3833   3833 172401 SMOK_X_CUBE_II_firmware_v1.07.hex

grep -ivn :10 SMOK_X_CUBE_II_firmware_v1.07.hex
1::020000040000FA
3832::04000005000000C136
3833::00000001FF

剖析第一行

line1 data size   = 0x02 
load offset       = 0x0000
record type is    = 0x04  (extended linear address 32 bit format)

它保持原样直到遇到另一个记录 04 让我们检查文件是否包含另一个记录 04

:\>grep -in :......04 SMOK_X_CUBE_II_firmware_v1.07.hex
1::020000040000FA

只有一行 最后一行 3833 表示文件结束record type 0x01
最后一行表示起始线性地址record type 0x05 和 EIP = 0xc1 校验和匹配(100 - (0xc1 + 0x05 + 0x04 ) ) == 0x36

这样留下 3830 行作为代码数据 xx

基于以上细节,我们可以雕刻字节

first , last . last but one从输入文件中删除
sed substitute前九个字符和最后两个字符的行和rip off the line endings \r\n.

sed s/:........//g < in | sed s/..$//g | tr -d  "\r\n" > out

让我们看看 sed 魔法是否有效我们应该每行有 32 个字符,如果它可以连接成一个大字符串

:\>wc out
     0      1 122560 out

:\>set /a 32*3830
122560

让我们将十六进制对转换为二进制

rax2 -s < out > bin 

这不起作用,因为它应该为我们提供一半的输入大小,但它高于那个大小,反转rax2 -S < bin > is_original 也不会让我们返回原始输入

对于radare 的开发人员,如果您阅读本文,您可以检查rax2 -s 是否在Windows 中正常工作,如果输入是文件,它似乎受到unix / windows 行结束怪癖的困扰(Windows 似乎在使用重定向时将二进制0x0A 转换为0x0d 0x0a操作员

:\>rax2 -s < out > bin

:\>wc bin
  616  4126 61896 bin

:\>set /a 61896 * 2
123792

让我们煮一个 python unhexlify

:\>cat makebin.py
import binascii
fp = open("out","rb")
fo = open("bin","wb")
buff = fp.read()
fo.write(binascii.unhexlify(buff))
fp.close()
fo.close()
:\>python makebin.py

:\>wc *
   616   4126  61280 bin
  3830   3830 172350 in
     6     14    139 makebin.py
     0      1 122560 out
   616   4126  61896 rax2bin
  5068  12097 418225 total

:\>set /a 61280*2
122560
:\>

python似乎为我们提供了正确的字节

让我们问问radare2 122560 的大小是否合适

[0x000000c1]> if
file     ihex://SMOK_X_CUBE_II_firmware_v1.07.hex
fd       2357404
size     0xef60
blksz    0x0
mode     r--
block    0x100
format   any

[0x000000c1]> !rax2 0xef60*2
122560
[0x000000c1]>

它似乎同意让 xxd 看看我们是否在正确的偏移量处钓到了正确的字节

:\>xxd -g 4 -l 32 -s 0xc1 bin
00000c1: 4885460c f070fc00 480047e9 1b0000e8  H.F..p..H.G.....
00000d1: 0e002004 48804704 480047fe e7fee7fe  .. .H.G.H.G.....

现在看起来我们可以尝试开始理解助记符(谷歌似乎对 mccreq 不太了解我不知道 arm 所以从这里开始祝你好运