我想对8051固件二进制文件进行逆向工程,并且不确定从哪里开始。固件用于Real RTL8188EE无线卡。它位于这里:https://github.com/lwfinger/rtlwifi_new/tree/master/firmware/rtlwifi

我知道(认为吗?)它是8051,因为在整个Linux代码中有多个引用该芯片的。我已经从Linux代码中确定标头部分是前32个字节。

我该如何拆卸它?我已经通过偏移量为0x20(32位标头)的IdaPro运行了它,但是我得到了很多NOP,然后在Ida似乎正确解释指令的末尾出现了二进制垃圾。我运行了它,然后在网上找到了一个晦涩的反汇编工具d52v336,所以我删除了前32个字节。它始于许多NOP和一系列ORG。我将打印输出放在这里(https://pastebin.com/1M11wXiF)。代码的第一部分似乎以“ reti”和“ lcall X4204”开头。当我查找X4202时,是“ X4204 equ 4204h”,这使我感到困惑。也许这是代码的开始,但是我不确定。

我如何知道偏移量是否关闭?这是代码的真正开始吗?如果是这样,我该如何处理?糊涂了!

#1 楼

我最近开发了一个工具,使8051逆向工程中的早期内容变得更容易,称为at51,并将无耻地将这个答案用作展示。

首先,您希望图像正确对齐。
很少有8051固件对齐,并且对于此文件也是如此。
通过使用base子命令,您可以获得最有可能是文件加载位置的偏移量:

$ at51 base rtl8188efw.bin
Index by likeliness:
    1: 0x3fe0 with 139
    2: 0x2526 with 63
    3: 0x6a5 with 58


请注意,第一场比赛的得分是第二场比赛的得分的两倍以上,因此它可能加载为0x3fe0(由于32字节的标头,实际上加载在0x4000上)。 >
您现在可以使用同时支持8051的ghidra或radare2。
由于大多数8051固件都使用C51编译了此固件,因此您也可以使用libfind子命令可以在图像中找到标准库函数。
为此,您使用格式为C51 * .LIB的C51库文件(您可以通过下载C51试用版获得它们,因为没人会在互联网上打开的任何地方都留下一个名为C51L.LIB的文件。

无论如何,使用对齐的图像(例如,使用dd if=rtl8188efw.bin of=fw_aligned bs=$((0x3fe0)) seek=1)和库文件,都会得到一个

$ at51 libfind fw_aligned /path/to/lib/C51*.LIB
Address | Name                 | Description
0x42dd    (MAIN)                
0x44a9    ?C?IILDX              
0x44bf    ?C?LAND                long (32-bit) bitwise and
0x44cc    ?C?LOR                 long (32-bit) bitwise or
0x44d9    ?C?LLDXDATA            long (32-bit) load from xdata
0x44e5    ?C?LLDXDATA0           long (32-bit) load from xdata into r3-r0
0x44f1    ?C?OFFXADD            
0x44fd    ?C?PLDXDATA            general pointer load from xdata
0x4506    ?C?PSTXDATA            general pointer store to xdata
0x450f    ?C?CCASE              
0x4573    ?C_START              


现在您在一些函数开始处有一些偏移量,并且对其中一些函数进行了描述,这应该会有所帮助。
请注意,MAIN位于括号中,因为未找到

最后一件事是C51生成的固件通常包含一种结构,用于存储要在启动时初始化的内存位置的值。
使用kinit子命令来读取该结构。
由于它是在?C_START的开头以mov dptr, #0x45b8加载的,因此可以轻松找到该结构的偏移量。但是对于此固件映像,这似乎是实际已禁用(通过在该位置插入0)?
或者链接器搞砸了,并在结构之前而不是之后插入了0?
无论如何,如果他们没有将它清零(该结构实际​​上在它后面存在一个字节),您将得到

$ at51 kinit -o $((0x45b9)) fw_aligned
xdata[0x8197] = 0x00
xdata[0x8198] = 0x00
xdata[0x81a4] = 0x00
xdata[0x3457..0x3468] = [0x4a, 0x57, 0x36, 0x58, 0x29, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0]


最后一个似乎是垃圾,因为它包含8051代码,所以也许终止0确实在开始时意外着陆。

#2 楼

Radar2支持8051,如果您认为它是8051,则链接指向目录

没有ee文件,而我在radare2中运行过efw文件,这似乎是
反汇编

radare2 -AA -a 8051 firmware.bin

[0x00000000]> px 16
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x00000000  e188 1000 0800 0000 1025 2156 b02b 0000  .........%!V.+..
[0x00000000]> pd 1
            ;-- b:
            ;-- r4:
            ;-- r5:
            ;-- psw:
            ;-- r7:
/ (fcn) fcn.00000000 14
|   fcn.00000000 ();
\       ,=< 0x00000000  ~   e188           ajmp loc.00000788
[0x00000000]> s 0x788
[0x00000788]> pd 5
|- loc.00000788 9
|   loc.00000788 ();
|       |      ; JMP XREF from 0x00000000 (fcn.00000000)
|       |      ; JMP XREF from 0x00000782 (loc.00000788)
|       |      ; CALL XREF from 0x0000077a (loc.00000788)
|       `=< 0x00000788      80f0           sjmp loc.0000077a
            0x0000078a      e0             movx a, @dptr
/ (fcn) fcn.0000078b 27
|   fcn.0000078b ();
|              ; UNKNOWN XREF from 0x000006db (fcn.0000061c + 191)
|              ; CALL XREF from 0x000006db (fcn.0000061c + 191)
|           0x0000078b      75f003         mov b, #0x03                ; [0x100f0:1]=255
|           0x0000078e      a4             mul ab
|           0x0000078f      24fe           add a, #0xfe
[0x00000788]>


评论


原谅,我应该澄清一下。我正在rtl8188efw.bin。但是,任何人都应该工作。根据您对Intel 8051的了解,这看起来是程序的合法开始,而不是radare2解释另一个芯片的ROM?而且,我将研究radee2,这看起来很有希望。非常感谢!

–法汉·尤素福扎伊
18 Mar 5 '18 at 2:20

#3 楼

是的,这看起来像8051固件。

重置入口点是0x0000,在这种情况下,它会跳转到0x0788,并继续有效的8051代码。对地址0x4000以上的地址有很多调用,因此您可能缺少ROM代码。

以我的经验,radar2(aaaaa)的自动分析功能在8051上很难解决。我通常只运行aar可以获取所有交叉引用,然后按照我的需要手动标记代码。

我还配置了e asm.jmpsub=true以便进行更好的8051拆卸(一旦开始分配标志)。

请参阅有关使用radee2反转8051的更多信息,请访问此页面:
https://radare.gitbooks.io/radare2book/content/arch/8051.html