TP-LINK VxWorks系统路由器固件升级文件格式(二)
由 李晓岚 在 2014年03月15日发表
在TP-LINK VxWorks系统路由器固件升级文件格式(一)中,我们从固件升级文件中提取出了各个分区文件,其中包含名为web-res的分区文件,不过其中的内容还是无法理解。所以这次将对web-res分区文件内容深入探究。
首先使用binwalk对其进行扫描,没有发现任何文件特征,binwalk无能为力。
tplink-vxworks-based-firmware.git$ ls -l web-res -rw------- 1 root root 522361 Jan 26 13:54 web-res tplink-vxworks-based-firmware.git$ hd web-res | head 00000000 00 07 f8 70 00 00 00 00 00 5d 00 80 00 00 91 36 |...p.....].....6| 00000010 30 00 00 00 00 00 00 27 95 e8 30 10 07 00 06 10 |0......'..0.....| 00000020 58 12 85 15 4c b3 bb a9 7a f1 0e 92 a9 25 17 fb |X...L...z....%..| 00000030 3a 61 ca cb e0 47 a2 fa e0 20 29 c1 73 1c 6c 47 |:a...G... ).s.lG| 00000040 e9 58 aa 08 cf 7b a7 b9 df 45 e3 31 a9 9e c5 85 |.X...{...E.1....| 00000050 98 99 2d 7c de 3b be 5e dd 0d 74 54 c1 63 5c 06 |..-|.;.^..tT.c\.| 00000060 34 49 3f 0e 23 84 9d 6c 0e 13 47 c5 10 12 e1 57 |4I?.#..l..G....W| 00000070 23 bc 9d cc 0d de d6 41 4a 65 b6 a7 f8 d5 54 af |#......AJe....T.| 00000080 1f 76 35 9d 4b 00 cc d4 fb 42 18 2c 6a 96 2d e5 |.v5.K....B.,j.-.| 00000090 08 59 1f bb cc 71 fa 26 cb d0 d8 86 88 6e af 8c |.Y...q.&.....n..|
仔细观察后发现,如果将文件的头四个字节当做大端的32位整型来看,0x0007f870 == 522352
,同文件大小522361
相比,仅仅相差9。于是可以假定其值代表后面数据的大小,文件由9个字节的文件头和实际数据组成。但后面数据的格式还是未知。
从名字web-res来看,里面存储的内容应该是一些web相关的资源文件,html,css和js等,这些文件都是纯文本。但数据完全看不出任何合理的字符串,估计是被加密或压缩过的。加密的可能性一般不大,可以先考虑压缩。数据的第一个字节0x5D
看起来像默认属性的lzma压缩流,用lzma解压来碰碰运气吧。
tplink-vxworks-based-firmware.git$ dd if=web-res of=web-res.dat.lzma bs=1 skip=9 522352+0 records in 522352+0 records out 522352 bytes (522 kB) copied, 0.901332 s, 580 kB/s tplink-vxworks-based-firmware.git$ lzmainfo web-res.dat.lzma web-res.dat.lzma Uncompressed size: 3 MB (3159697 bytes) Dictionary size: 0 MB (2^15 bytes) Literal context bits (lc): 3 Literal pos bits (lp): 0 Number of pos bits (pb): 2 tplink-vxworks-based-firmware.git$ lzma -d -v web-res.dat.lzma web-res.dat.lzma (1/1) 99.9 % 510.1 KiB / 3,085.6 KiB = 0.165 lzma: web-res.dat.lzma: Compressed data is corrupt 99.9 % 510.1 KiB / 3,085.6 KiB = 0.165
尝试用lzma命令行工具解压失败了,但看起来99.9%的数据已经解压成功了,深入检查后发现,原来是正常的压缩数据后,还有部分尾数据,不属于lzma压缩流,所以导致lzma命令失败。知道了原因就很容易解决啦。使用python的lzma包来解压并忽略尾数据,成功解压。源代码decompress-web-res.py。
tplink-vxworks-based-firmware.git$ ./decompress-web-res.py web-res Decompressed data length: 3159697 Unused data length: 1 Decompressed data saved to "web-res.decompressed". tplink-vxworks-based-firmware.git$ hd web-res.decompressed | head 00000000 4f 57 4f 57 4f 57 4f 57 4f 57 4f 57 4f 57 4f 57 |OWOWOWOWOWOWOWOW| * 00000020 00 00 00 01 00 00 00 f8 2f 72 63 5f 66 69 6c 65 |......../rc_file| 00000030 73 79 73 2f 64 6f 63 2f 64 79 6e 61 66 6f 72 6d |sys/doc/dynaform| 00000040 2f 63 6f 6d 6d 6f 6e 2e 6a 73 00 00 00 00 00 00 |/common.js......| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000060 00 00 00 00 00 00 00 00 00 00 bb 07 00 00 49 c8 |..............I.| 00000070 00 00 00 00 2f 72 63 5f 66 69 6c 65 73 79 73 2f |..../rc_filesys/| 00000080 64 6f 63 2f 64 79 6e 61 66 6f 72 6d 2f 6d 61 69 |doc/dynaform/mai| 00000090 6e 2e 63 73 73 00 00 00 00 00 00 00 00 00 00 00 |n.css...........|
解压后的文件中,已经可以看到有意义的字符串了。开头部分的字符串看起来像是文件名,如何从中提取这些文件呢?文件开头的“OWOWOWOW...”像是magic string,google之,发现这篇文章Mystery File System和其UPDATE #3中引用的Solving a Little Mystery。综合上述两篇文章中的信息,web-res.decompressed中的文件系统(姑且称之为ow2fs,相对Mystery File System中的owfs而言)的header和entry可以如此定义(大端字节序):
struct ow2fs_header{ char magic[32]; // 'OWOWOWOWOW...' uint32_t unknown; uint32_t file_count; } struct ow2fs_entry{ char file_path[0x40]; uint32_t file_size; uint32_t file_offset; uint32_t unknown; }
ow2fs与owfs相比,有如下差异:
- magic字符串为大写“OW”,而非小写。
- header少了一个uint32_t的字段。
- entry中的文件名变成了文件路径,可能包含文件夹,最大长度变大成64。
- entry中多了一个uint32_t的未知字段,其值均为0。
知道了ow2fs的结构,我们就可以写段程序,提取其中的所有文件了,源代码unow2fs。
tplink-vxworks-based-firmware.git$ ./unow2fs.py web-res.decompressed out | head Extract 248 files into out... /rc_filesys/doc/dynaform/common.js (47879) at 0x49c8...Successful /rc_filesys/doc/dynaform/main.css (25599) at 0x104d0...Successful /rc_filesys/doc/dynaform/menu.js (13551) at 0x168d0...Successful /rc_filesys/doc/dynaform/extra.js (57444) at 0x19dc0...Successful /rc_filesys/doc/frames/product.htm (881) at 0x27e24...Successful /rc_filesys/doc/localization/str_menu.js (2238) at 0x28198...Successful /rc_filesys/doc/localization/char_set.js (0) at 0x28a58...Successful /rc_filesys/doc/dynaform/tab.js (15495) at 0x28a58...Successful /rc_filesys/doc/dynaform/bwCtrlVerify.js (59979) at 0x2c6e0...Successful
查看这些提取的js,css和htm文件,都完好无损。至此,web-res的结构我们已经完全分析清楚了。
comments powered by Disqus