本篇是”手上有啥就搞啥“系列的第七篇,本来系列已完结,本篇是番(意)外篇,研究对象是电纸书,侧重点是固件提取和逆向。
内容主要包括:
- 0x00 缘起:一次偏离正轨的研究
- 0x01 站在巨人肩上:硬件信息
- 0x02 自己动手做:固件提取和逆向
- 0x03 做个总结:简单总结
- 0x04 写在最后:系列总结
- 0x05 参考资料:参考链接
往期回顾:
0x00缘起
此次研究纯属意外,而且离初衷越走越远。收拾东西的时候发现一个古董级电纸书 汉王N510,用是没法用了,就想把屏幕拆下来做个墨水屏电子相册。后来本着拆都拆了研究下电路板吧,又到芯片,再到固件,一步步”误入歧途“。
0x01 站在巨人肩上
如下简单给出墨水屏、Nand Flash和 处理器信息。
0x01 - 00 ED050SC3(LF)墨水屏
0x01 - 01HY27UF084G2B Flash DataSheet
0x01 - 02 Ingenic JZ4740 DataSheet
0x02 自己动手做
0x02 - 00 拆、拆、拆
拆机十分简单,主要目的是把屏幕拆下来:
屏幕型号是 ED050SC3,33 pin 墨水屏,之后主线应该是围绕驱动板、图像处理硬件和显示代码的开发,然而…
芯片是 Ingenic JZ4740 DataSheet,mipsel架构,Nand Flash 是 hynix HY27UF084G2B。
这里只把 Flash 吹下来提取固件:
0x02 - 01 固件提取
该Flash是TSOP48 封装,使用编程器选择正确的类型,读取固件,大小为 528M,与 DataSheet 中描述的存储结构相符。
0x02 - 03 固件分析
直到此刻都非常顺利,接下来只要运行 binwalk -e,快速搞定之后就能回去做正紧开发了,然而部分信息如下:
> binwalk Hynix HY27UF084G2B.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
384112 0x5DC70 U-Boot version string, "U-Boot 1.1.6 (Sep 10 2009 - 15:22:56)"
385504 0x5E1E0 CRC32 polynomial table, little endian
4194304 0x400000 uImage header, header size: 64 bytes, header CRC: 0xEB6E491A, created: 2010-04-02 03:17:58, image size: 1487278 bytes, Data Address: 0x80010000, Entry Point: 0x802800C0, data CRC: 0xB8409BA4, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: gzip, image name: "Linux-2.6.24.3"
4194368 0x400040 gzip compressed data, maximum compression, has original file name: "vmlinux.bin", from Unix, last modified: 2010-04-02 03:17:58
25495523 0x18507E3 MySQL MISAM index file Version 2
26059613 0x18DA35D MySQL MISAM compressed data file Version 9
26102424 0x18E4A98 MySQL MISAM index file Version 2
51828922 0x316D8BA MySQL ISAM compressed data file Version 7
52586619 0x322687B MySQL MISAM index file Version 4
54650826 0x341E7CA MySQL ISAM index file Version 4
55179998 0x349FADE MySQL MISAM index file Version 2
58751182 0x38078CE MySQL ISAM compressed data file Version 11
58751288 0x3807938 MySQL ISAM compressed data file Version 11
58964726 0x383BAF6 Copyright string: "Copyright DynaComware Corp. 2009DFPHeiHK-W5DFPHeiHK-W5DFPHeiHK-W5RegularVersion 1.00Trademark by DynaComware Corp."
59047936 0x3850000 JPEG image data, JFIF standard 1.02
59047966 0x385001E TIFF image data, big-endian, offset of first image directory: 8
59048268 0x385014C JPEG image data, JFIF standard 1.02
59050819 0x3850B43 JPEG image data, JFIF standard 1.02
59064320 0x3854000 JPEG image data, JFIF standard 1.02
59064350 0x385401E TIFF image data, big-endian, offset of first image directory: 8
59064652 0x385414C JPEG image data, JFIF standard 1.02
59069983 0x385561F JPEG image data, JFIF standard 1.02
59101184 0x385D000 JPEG image data, JFIF standard 1.02
59101214 0x385D01E TIFF image data, big-endian, offset of first image directory: 8
59101516 0x385D14C JPEG image data, JFIF standard 1.02
59104127 0x385DB7F JPEG image data, JFIF standard 1.02
59111992 0x385FA38 Copyright string: "Copyright (c) 1998 Hewlett-Packard Company"
59123712 0x3862800 JPEG image data, JFIF standard 1.02
59123742 0x386281E TIFF image data, big-endian, offset of first image directory: 8
59124044 0x386294C JPEG image data, JFIF standard 1.02
59128366 0x3863A2E JPEG image data, JFIF standard 1.02
59138192 0x3866090 Copyright string: "Copyright (c) 1998 Hewlett-Packard Company"
59172864 0x386E800 JPEG image data, JFIF standard 1.02
59172894 0x386E81E TIFF image data, big-endian, offset of first image directory: 8
59173196 0x386E94C JPEG image data, JFIF standard 1.02
59176220 0x386F51C JPEG image data, JFIF standard 1.02
59184759 0x3871677 Copyright string: "Copyright (c) 1998 Hewlett-Packard Company"
59199488 0x3875000 JPEG image data, JFIF standard 1.02
59199518 0x387501E TIFF image data, big-endian, offset of first image directory: 8
59199820 0x387514C JPEG image data, JFIF standard 1.02
59208025 0x3877159 JPEG image data, JFIF standard 1.02
59221479 0x387A5E7 Copyright string: "Copyright (c) 1998 Hewlett-Packard Company"
59322368 0x3893000 PDF document, version: "1.4"
59323055 0x38932AF Zlib compressed data, best compression
59662336 0x38E6000 JPEG image data, JFIF standard 1.01
59674624 0x38E9000 JPEG image data, JFIF standard 1.01
59756544 0x38FD000 JPEG image data, JFIF standard 1.02
......
92250582 0x57FA1D6 Unix path: /var/run/wvdial.%iface% -s 2
92264872 0x57FD9A8 Unix path: /etc/iproute2/rt_tables
92267112 0x57FE268 Unix path: /var/run/udhcpd.pid
92278136 0x5800D78 Unix path: /var/run/syslogd.pid
92288396 0x580358C Unix path: /dev/misc/rtc
92295543 0x5805177 POSIX tar archive (GNU), owner user name: " magic", owner group name: "not stat tar file"
自动解包没有任何结构被解出,手动寻址发现很多误报,除了 U-Boot和 uImage这种有头信息但解不开以外,唯一涨知识的点就是知道了 Hewlett-Packard是 惠普的全称。
当然解不开是正常的,因为是直接读取的 Flash,所以要手动去除 OOB,就是正常数据是512M,但每块都夹杂冗余信息,所以整体数据为 528M,具体结构如下:
Memory: 4096 blocks × 64 pages/block × 4 sectors/page × 512 Byte/sector = 512 MiB
Spare memory: 4096 blocks × 64 pages/block × 4 sectors/page × 16 Byte/sector = 16 MiB
Overall memory: 512 MiB + 16 MiB = 528 MiB
可以使用Flash工具,也可以简单写个脚本去除:
def fix_data(i, src_file, dst_file):
with open(src_file, "rb") as fpr:
with open(dst_file, "wb") as fpw:
while(i > 0):
fpw.write(fpr.read(0x800))
gap = fpr.read(0x40)
i = i - 0x800 - 0x40
if __name__ == '__main__':
total = int(sys.argv[3], 16)
src_file = sys.argv[1]
dst_file = sys.argv[2]
fix_data(total, src_file, dst_file)
此时再使用 binwalk 就可以解出 gzip 格式的 uImage,解压后是 vmlinux.bin,侧面说明之前的操作正确。
至于 binwalk识别的一长串后续信息,很多是误报,说明 rootfs很可能是 RTOS,使用 binwalk -A发现大量 mipsel指令也证明了这一点,这也是走入误区的开始。
精简过固件去掉其尾部的 0xff 后,按照猜测拖入IDA分析,虽然确实识别出很多指令和字符串,但载入地址毫无头绪,只能先回过头来看 vmlinux.bin。
不管从 binwalk 识别的信息,还是其名字本身都基本能确定这是 Linux 内核,说明该电纸书使用的是 Linux 系统,这与之前的 RTOS 相矛盾,但 rootfs却没有被识别出来,甚至任何有用的头信息也没有。
于是回到固件本身,搜索有用的字符串,先从Uboot着手:
得到了启动参数:
bootargs=mem=64M console=ttyS0,57600n8 ip=172.17.2.26 rootfstype=yaffs2 root=/dev/mtdblock2
bootcmd=nand read 0x80600000 0x400000 0x200000;bootm
bootdelay=3
baudrate=57600
loads_echo=1
ethaddr=00:2a:cc:2a:af:fe
ipaddr=172.17.3.30
serverip=172.17.3.113
autoload=n
bootfile="uImage"
从 bootargs很明显看出使用的是 Linux系统, rootfs使用 Yaffs2结构,存储在 mtdblock2中,固件结构很可能如下:
uboot 根据字符串和 Flash Block 也可以手动解开,但是 yaffs2 开始没有解开,重要原因是无法找到mtdblock2 的起始地址,而 bootcmd 中的 0x400000 读取地址显然也不是。此时就感慨拆早了,常规研究方法是找到动态调试接口,获取dmesg信息,这样很容易知道 mtdblock2地址。
从固件中找了几个包含 ELF头的结构,确实可以恢复出来,且还有符号:
说明确实是有文件结构的,并非通过调度实现。因为把 Flash 焊回去更麻烦,就从 yaffs2 出发,笔者前段时间刚用同样的方式分析过 UBI 结构,这里 yaffs2 没有压缩,直接通过链的形式存储在 Flash 中。搜索了 yaffs2 的 magic 信息,固件中无法找到,甚至想直接利用 unyaffs 遍历爆破,但是文件太大。
抱着试试看的心态真的找到了该电纸书差不多型号的固件包:
从名字和大小基本可以知道功能和启动顺序:
uboot → kernel → initramfs → application
因为型号有所区别,所以固件格式并不完全相同,其中最大的 application_upgrade是 yaffs2格式。
此处废话:ubi 和 yaffs2 等格式的 rootfs 解包思路一般两种
- 使用 unyaffs/ ubi_reader等工具直接解析结构
- 使用 nandsim模拟 Flash 后挂载
前者虽然比较容易,但是对工具要求高,从 Flash 读取的内容很可能报错,笔者在修改多处 ubi_reader 源码后果断放弃,选择修改固件数据并使用第二种 nandsim 的方式。但此处可以直接使用 unyaffs解包。
unyaffs通过 apt install 安装,可直接识别上述 application_upgrade 的 yaffs2 格式:
通过分析 application_upgrade 格式,在需要分析的固件中搜索以下字符串:
03 00 00 00 01 00 00 00 FF FF 00 00 00 00 00 00
只有一个,根据 Flash 结构去掉尾部 0xff 提取,同样使用 unyaffs 解析,但是报错:
> unyaffs -d test
Detect no layout(s)
这就很尴尬了,只能又回到修改源码打印结构的老路上…
还有个办法,就是对比两个文件的 Block 头结构,发现完全一致,但是第一个 Block 的结尾有明显区别:
提取的文件结构到 0x800 结束:
application_upgrade 到 0x8400 结束:
不由让人想到 0x40 字节的 OOB,于是直接从未处理的固件数据中找到 yaffs2 头并提取,成功获得 rootfs 数据:
这样全部需要的结构都提取完毕,接下来就可以分析
个 P 啊 ~
固件解包完毕就结束吧,毕竟不是主线任务。此时再回溯,发现解包过程就是:
去掉OOB,提取 Uboot,vmlinux.bin
原始文件找到 03 00 00 00 01 00 00 00 FF FF 00 00 00 00 00 00,提取数据使用 unyaffs 恢复 yaffs2 rootfs。
so easy,但是就像漏洞挖掘一样,指给你看可能就一句话,自己找就费劲了。
0x02 - 04 回归开发
开发是另一个专题了,篇幅有限这里简单提及。
使用EPDIY 方案,对该墨水屏是支持的:
因为开源需要自己设计,就在 JLC 找了个现成的 ESP32 集成方案,因为笔者并不专业,正在继续踩坑中…
0x03 做个总结
此次研究因诸多原因较为曲折,后期梳理发现其实非常简单,总结如下:
0x04 参考资料
https://maehw.wordpress.com/2017/04/07/dumping-a-nand-flash-part-1/
https://cloud.tencent.com/developer/article/1554403
opennoah.github.io/datasheet/JZ4740_ds.pdf
https://dubeyko.com/development/FileSystems/YAFFS/HowYaffsWorks.pdf
https://epdiy.readthedocs.io/en/latest/getting_started.html#use-with-esp-idf
https://github.com/vroland/epdiy
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)