第二讲【手把手教你破解威联通固件】
接下来,就可以展开tgz文件包,研究固件的详细内容了。展开后从如下截屏可以看到很多的固件文件。现在来判断所有这些固件的文件是做什么的,还为时过早。但有两个文件的用途,根据经验是可以确定无疑的。一个是bzImage,另一是initrd.boot。" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
下面我来解释一下这两个文件:在linux系统中,vmlinux(vmlinuz)是一个包含linux kernel的静态连结的执行档,档案型态可能是linux接受的执行档格式之一(ELF、COFF或a.out),vmlinuz是一种统称,有两种具体的表现形式zImage和bzImage。bzimage和zImage的区别在于本身的大小,以及加载到内存时的地址不同,zImage在0~640KB,而bzImage则在1M以上的位置。随着 linux Kernel 的成长,核心的内容日益增加超越了原本的限制大小。 bzImage (big zImage) 格式则为了克服此缺点开始发展,利用将核心切割成不连续的记忆体区块来克服大小限制。bzImage 格式仍然是以zlib 演算法来做压缩,虽然有一些广泛的误解就是因为以bz- 为开头,而让人误以为是使用bzip2 压缩方式(bzip2 套件所带的工具程式通常是以bz- 为开头的,例如bzless, bzcat ...)。bzImage 档案是一个特殊的格式,包含了 bootsect.o + setup.o + misc.o + piggy.o 串接。 piggy.o 包含了一个 gzip 格式的 vmlinux 档案(可以参看 arch/i386/boot/下的 compressed/Makefile piggy.o)initrd文件是Linux初始RAM磁盘文件。初始RAM磁盘(initrd)是在实际根文件系统可用之前挂载到系统中的一个初始根文件系统[9]。initrd 与内核绑定在一起,并作为内核引导过程的一部分进行加载。内核然后会将这个 initrd 文件作为其两阶段引导过程的一部分来加载模块,这样才能稍后使用真正的文件系统,并挂载实际的根文件系统。initrd 中包含了实现这个目标所需要的目录和可执行程序的最小集合,例如将内核模块加载到内核中所使用的 insmod 工具。在桌面或服务器 Linux 系统中,initrd 是一个临时的文件系统。其生存周期很短,只会用作到真实文件系统的一个桥梁。在没有存储设备的嵌入式系统中,initrd 是永久的根文件系统。有了这两个文件我们就可以做个启动盘试一试了。至少可以建立一个最小系统,作为进一步破解固件的基础。思索与分析:现在我们要用bzImage,initrd.boot这两个文件做一个启动盘。但我们需要大约了解威联通DOM的结构是什么样的。我可以用SSH登陆威联通TS288设备,然后用fdisk -l命令查一查。但同时我也会在网上查一查。我发现了一篇日文的文章“QNAPの基本構造について”[10]一下让我对威联通系统结构有了深入的了解。大大加快了破解固件的速度。部分截屏如下:" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
接下来我就开始创建一个威联通的启动盘了。启动盘接结构和原理与我在【老骥伏枥-鸡年大礼包】[11]中创建黑群晖启动盘是一样的, 那篇文章有非常详细的介绍。这里就不赘述了。有兴趣的坛友请参看我的那篇文章。这次我做的黑威联通启动盘,从原理到风格都与黑群晖启动盘一致。有意思的是,去年【鸡年大礼包】做的是黑群晖启动盘。今年【狗年大礼包】做的是黑威联通启动盘。而且风格一致,像是系列作品。我的威联通启动盘接结构截图如下:" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
我的启动盘与威联通DOM稍有不同。我放大了sd?1分区,因为威联通启动用的是旧的grub 0.97,而我打算用更新版的GRUB2。另外我还要引进Tiny Core Linux[1],做系统救援,和启动创建工具母盘。我还做了一个sd?7分区,作为备用。其中的?表示linux 的udev设备加载时分配的a-z字符。把GRUB2; Tiny Core文件拷贝到sd?1分区中。编辑修改grub.cfg文件。其它分区sd?2至sd?7全部放空。把固件包中的相关文件拷贝到sd?2分区中。一共是如下十个文件:bzImagebzImage.cksuminitrd.bootinitrd.boot.cksumqpkg.tarqpkg.tar.cksumrootfs2.bzrootfs2.bz.cksumrootfs_ext.tgzrootfs_ext.tgz.cksum你可能会问,你如何知道要拷贝这十个文件呢?这是得益于那篇日文的文章。做逆向工程破解固件时,除了自己的经验外,借助互联网吸取他人的经验会取得事半功倍的效果。破解固件的启动盘就这样制作完成了。马上启动一下试一试。嘿嘿,很快控制台就出现了如下的截图登录界面:" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
显然,破解威联通固件并不是那么简单。威联通固件哪会只设一个坑,迈过去就是一马平川呢。不过这也是一个好兆头。证明了固件的最小系统已经成功建立起来了。既然有登录界面,那我就就用威联通的默认用户:admin,和默认密码:admin登录一下试一试。哈哈,可以成功登录系统。截图如下:" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
接下来我要介绍一下威联通内核的启动过程。 这也是从那篇日文文章[10]上读来的。所以我才会说,它大大加快了我的破解固件的速度。威联通启动最小系统内核后1.按照/etc/inittab中所述执行以下两个进程null :: sysinit:/sbin/hwclock - hctosys:: sysinit:/etc/init.d/rcS2.根据/etc/init.d/rcS的描述(/etc/rcS_init.d/S20init_check),在/etc/rcS_init.d /下执行每一个名字从S?开始的脚本。它的脚本代码如下截图:" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
3.执行/etc/rcS_init.d/S20init_check并开始时安装各种设备。mount -t proc /proc /procmkdir -p /dev/ptsmount -t devpts devpts /dev/ptsmount -o remount,rw /mkdir /sysmount -t sysfs sysfs/sys[ -d /tmp ] || mkdir /tmpmount -t tmpfs tmpfs /tmp -o size=32M4.从Model_Name.conf和BOOT.conf中加载Model名称和体系结构。#Model_Name是Makefile中的INTERNAL_MODEL,TS-879U和TS-879都是TS-879Model_Name =`cat /etc/default_config/Model_Name.conf 2> /dev/null`#BOOT_CONF是平台类型,TS-879是TS-NASX 86BOOT_CONF =`/ bin / cat /etc/default_config/BOOT.conf 2> /dev/null`if [“x $ {Model_Name}”=“xTS - 230”] || [“x $ {Model_Name}”=“xHS - 200”]; then /bin/echo s35390a 0x30> /sys/class /i2c-dev /i2c-3 /device /new_devicefi※可以用cat命令查看一下:Model_Name.conf和BOOT.conf来确定设备的model和cpu类型。#cat /etc/default_config/Model_Name.confTS-869#cat /etc/default_config/BOOT.confTS-NASX 865.装载USB设备(与USB stick文件系统安装分开) 74 [$?= 0] || /bin/echo“mount usbfs failed。”6.使用hal_app命令展开DOM的第二个分区上的rootfs2.gz。#从启动分区中提取rootfs2.gz/sbin/hal_app --boot作为一个特定的进程,在/mnt/boot_disk/上挂载DOM的第二个分区。之后,将/mnt/boot_disk/boot/rootfs2.bz的内容扩展为解压“tar jxf /mnt/ boot_disk/boot/rootfs2.bz -C /”※rootfs2.bz的内容是这样的,会为根目录中的/home;/lib;/usr添加更多的系统所需的程序。drwxr-xr-x 4 admin administ 4096 Apr 10 04:37 home/drwxr-xr-x 3 admin administ 4096 Apr 10 04:23 lib/drwxr-xr-x 8 admin administ 4096 Apr 10 04:32 usr/这条信息很重要,它给了我明确的暗示。/sbin/hal_app这段程序很有可能就是破解威联通固件的第二个坑。显然,/sbin/hal_app是与硬件有关联的。为需要破解它才能实现从DOM的第二个分区上提取,并展开rootfs2.gz。让我们先暂时记住这个坑,继续完成启动过程的介绍。7.挂载根(HDA_ROOT),ext_root,和swap。用一个名为storage_util的命令,它所做的事情已经超出了猜测的范围。我很抱歉我认为/mnt/HDA_ROOT和/mnt/ext和swap是在从脚本编写方法思考之后安装的。/bin/echo“mount HDD system root ...”/bin/echo "mount HDD system root..."# parse the out put and find count/sbin/storage_util --sys_startup# mount/dev/md9 on /mnt/HDA_ROOT type ext3 (rw,data=ordered)/dev/md13 on /mnt/ext type ext3 (rw,data=ordered)# cat /proc/swapsFilename Type Size Used Priority/dev/md256 partition 530108 0 -1这条信息也很重要,它是不是另一个坑,现在还不能确定。让我们先暂时做个标记,视破解的情况而定。8.使用sys_startup_p2选项激活LVM并挂载cachedev设备。#run hal_daemon,check_lan_port.sh is implement by load_lan_module.sh and hal_util_net.c/sbin/daemon_mgr hal_daemon start "/sbin/hal_daemon -f"/sbin/storage_util --sys_startup_p2由于NASYUN的篇幅限制,请继续看楼下,【手把手教你破解威联通固件】, 精彩继续!
威联通内核的启动过程介绍完了,我先尝试在最小系统内核上执行/sbin/hal_app --help试一试。哇噢,威联通没有防备这一点,给我列出了sbin/hal_app的全部功能的说明。这段程序的功能太多了,截屏都有困难。我截下一小部分,这部分截屏反应出了sbin/hal_app中三个有关于硬件相关的启动功能,这些功能可以断定是第二个坑。必须改写才能破解固件。
" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
思索与分析:
我要开始用IDA Pro工具对/sbin/hal_app这段程序做个静态分析了。看看是否可以直接修改这个二进制文件。分析的过程是一个见仁见智的过程,经验,技术,个人的好恶,都会影响分析的结果。我就不赘述了。我分析后的结论(不一定正确)是这个直接修改麻烦并且容易引发bug,造成系统不稳定。于是我又想了另一个办法,做一个/sbin/hal_app1模拟上述三个有关于硬件相关的启动功能,替代/sbin/hal_app的这三个功能。这样做有优点也优缺点。优点是简单易行,缺点是要补丁所有相关的用到这个功能的脚本文件。为此我先用 如下三个命令搜索了一下有多少脚本文件需要修改:
- grep -d recurse "get_boot_pd" *
- grep -d recurse "get_boot_pd_part" *
- grep -d recurse "boot" *
复制代码
搜索的结果是,如果采用后者的方法,将会有十个脚本文件需要补丁。根据我的经验,我认为这是可行的方案。于是我决定采用后者的方法。创建一个/sbin/hal_app1程序,模拟sbin/hal_app的三个功能。具体的编程技巧这里就不一一讲述了。在我的教学演示盘中有源代码。有兴趣的读者可以自行阅读分析。
编程完成后,对所有的脚本文件打好补丁,再生成重新破解固件的启动盘。启动一下试试看。
疑???启动后控制台黑屏了。什么情况???难道我什么的方没有考虑周到吗?
没有办法,只能接上com1的ttyS0端口,查看一下启动过程的log看看发生了什么问题。
修改grub.cfg文件,打开ttyS0端口:
linux /boot/bzImage root=/dev/ram0 rw console=ttyS0,115200n8
再启动一下试试看。这次看到在控制台黑屏以后,ttyS0上出现了登录界面。截屏如下:
" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
用威联通的默认用户:admin,和默认密码:admin登录,是成功的。
试着用SSH连接IP地址进行登录,是也成功的。
也就是说,系统已经启动了sshd服务。SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。这个sshd服务很有用。我们可以通过它,连接远程终端,拷贝文件等等。
试试用 chvt 1 命令切换当前控制台。哈哈,也是成功的。
这里还给出了model名,和IP地址,显然我的思路是对的,也是可行的。到此我已经成功地破解了威联通固件的第二个坑。
噢,我明白为什么了。威联通的硬件一般没有显示终端tty0控制台,所有启动成功后,它要把登录界面切换给ttyS0终端。这就是为什我的控制台出现黑屏了。这是启动成功的信号啊。
接下来下载及安装Qfinder或使用浏览器访问给出的IP地址,看看破解固件是否成功了呢?
哎呀,总是显示无法检测到硬盘。
" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
看来还有第三个坑。啊,“革命尚未成功,同志还需努力!”
对于解决这个问题,我先从web的前台查起。我发现是
http://192.168.56.101:8080/cgi-bin/quick/quick.cgi?todo=get_diskinfo执行后发出的无法检测到硬盘出错信息。执行后该程序返回一个xml格式的信息,确实是找不到Storage。看来问题不在web的前台,还是系统的后台破解没有完全。我还是老办法,去网上查一查看。嘿,威联通官方论坛也有人遇到这个问题。
读了读这些文章,都提到"Check the /etc/enclosure_0.conf to see if all host disks are all detected."[12] 。于是我用SSH远程终端连接到当前已破解的固件,查看/etc/enclosure_0.conf这个文件。但我的破解系统上没有这个文件。根据参考文献[12] 的解释。威联通系统支持硬盘热拔插。热拔插一般是SATA控制器。SCSI,IDE等控制器是不支持热拔插的。而该文件enclosure_0.conf应该是热拔插硬盘时自动生成的。
思索与分析:
为了找出这第三个坑在哪,我从朋友的威联通TS288上提取了enclosure_0.conf,直接上载到我的破解系统的/etc/enclosure_0.conf。我的想法是模拟一下热拔插。哇!奇迹发生了,浏览器直接跳转到了安装界面。截图如下:
" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
沿着这个界面安装下去,居然能成功安装威联通。截图如下:
" lazyloaded="true" _load="1" style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal; border: 0px; cursor: pointer;">
但不能重新启动机器。一旦重启机器,又会出现无法检测到硬盘。看来这是启动威联通破解系统的最后一个坑了。顿时让我信心倍增。参考文献[12] 还提到,如果有这个文件/etc/enclosure_0.conf,接下来应该执行storage_util --sys_startup命令。通过对enclosure_0.conf进行健全性检查并自动汇编md9。我又翻看了一下usr/bin/md_checker脚本。于是觉得执行一下storage_util --sys_startup命令试一试。这一试,我发现它把/etc/enclosure_0.conf给删除了。这给了我一个启示。这第三个坑一定与storage_util --sys_startup命令有关。
老办法,还得用IDA Pro工具对storage_util这段程序做个分析。分析程序,看反汇编语言的枯燥的细节就不赘述了。结论是,这段程序要读取/etc/model.conf中的 [System Disk ?] session 中的DEV_BUS=BxxDxxFx 的liunx pci总线的硬件描述信息。这是一种嵌入式linux典型的硬件绑定方法。这种伎俩是瞒不过像我这样既精通软件,又懂硬件人的火眼金睛。
PCI总线和设备树是X86硬件体系内很重要的组成部分,几乎所有的外围硬件都以这样或那样的形式连接到PCI设备树上。虽然Intel为了方便各种IP的接入而提出IOSF总线,但是其主体接口(primary interface)还依然是PCIe形式。我们下面分成两部分介绍PCI和他的继承者PCIe(PCI express):第一部分是历史沿革和硬件架构;第二部分是软件界面和UEFI中的PCI/PCIe。
自PC在1981年被IBM发明以来,主板上都有扩展槽用于扩充计算机功能。现在最常见的扩展槽是PCIe插槽,实际上在你看不见的计算机主板芯片内部,各种硬件控制模块大部分也是以PCIe设备的形式挂载到了一颗或者几颗PCI/PCIe设备树上。固件和操作系统正是通过枚举设备树们才能发现绝大多数即插即用(PNP)设备的[13][14]。关于PCI更详细的情况,请参看【老狼】的相关文章。不要揣测老狼是我在其它论坛的笔名。这里引用钱钟书老先生的一句名言“鸡蛋好吃何必去知道那个鸡下的?”
问题找出来了,解决起来就很容易了。查一下我试验用机器的PCI参数。手工编辑一下/etc/model.conf文件。重新生成initrd.boot初始RAM磁盘,启动再试。成功!
至此:整个破解威联通固件全部完成。这一讲,详细介绍了从下载官方发布的固件开始的每一个步骤和遇到问题如何去思考,如何做实验。“思索与分析” 章节,详细描述了我的思考过程。这部分最难写,因为它与经验密切相关。而经验需要一个积累的过程。下一讲,我将要讲解:教学演示黑威联通启动工具母盘的使用方法。
由于NASYUN的篇幅限制,请看楼下,第三讲 【教学演示黑威联通启动工具母盘的使用方法】,精彩继续!