编写 Android 内核模块的尝试(三)

这一节的内容实际上与程序编写毫无关系,主要是记录如何修改 Android 设备的引导分区,对其映像进行手术式操作,把编译出的模块的 SHA1 值添加到 Moto X Pro 的白名单里并使之生效。

简要概括起来,和一台 Android 移动设备的引导分区/内核打交道,想要分析它或者修改它,相关的工作有这么几个。
1、如果有现成的 ROM,需要把 boot 分区的映像从中提取出来(这个工作一般较为简单,在这儿不多说);
2、如果没有现成的 ROM,可以通过 dd 命令将 boot 分区(查看 /dev/block/platform/msm_sdcc.1/by-name/ 下的信息)的内容转储出来,前提是设备已经被 root;
3、无论以上哪种方法,假定获得的映像文件名字为 boot.img 的话,进一步可以把它拆解为压缩后的内核(通常命名为 zImage)以及引导时的内存盘映像(通常命名为 initrd.img)两个部分;
4、zImage 就是通常说到的内核了,不过它也是由几个部分粘合而成的。最开头是解压后面的被压缩的真正的内核的代码;接着就是压缩过的内核代码(也称作 piggy.gz),后面通常还有一些其它的零碎;如果有逆向分析的需要,那就需要进一步拆解它;
5、initrd.img 是系统引导时早期的根文件系统;如果有修改此文件系统上的文件的需求,要能对它进行拆解和重制;
6、把修改后的引导分区映像刷回到设备中去。

自动化操作 boot.img 的工具(解包或者重打包),既可以使用 apt 就能直接安装的 abootimg,也可以使用需要搜索一下才能找到的 AIK(Android Image Kitchen),后者会顺便把 initrd.img 也解开,如果有对根文件系统进行修改的需求,就会便捷一些,而且重打包也很方便。

如果要对 zImage 进行更进一步的剖析,则可以寻求 repack-zImage.sh 脚本的帮助,它能够把解压代码、piggy.gz 等分离开来(如果要从 zImage 中提取内核所包含的符号版本,则可以寻求 extract-symvers.py 的帮助)。

有了这些工具,使得修改 Moto X Pro 的白名单成了一项简单的工作。先把原始的 boot 分区 dd 到 /data/local/tmp/boot.img,用 adb pull 到 Linux,使用 AIK 解开,修改 ramdisk 下的 module_hashes 文件,把我们的 .ko 内核模块的 SHA1 值添加到其中,注意到原有的内容是经过排序的,所以加入新内容的时候也保持了有序的状态。再用 AIK 重打包,adb push 到 /data/local/tmp 后用 dd 刷入引导分区。刷分区的方法,视情况而定,也许是 fastboot 就能搞定,也许需要厂商的工具(如三星的 Odin)支持,也许 dd 就足矣。

白名单生效后,依次来了一个好消息、两个坏消息。第一个好消息是模块貌似真的被加载了,insmod 命令没有打印出任何错误信息,一个坏消息是手机立刻重启,数次尝试均是如此。最后一个坏消息,是在隔天才发现的,手机卡插入后设备不识别了,一直保持处于无 SIM 卡状态。

最后有必要补充一下手工从 zImage 中把真正的内核解压出来的方法。使用十六进制编辑工具打开 zImage,查找 gzip 流的起始标识 1F 8B 08,找到后把它们之前的数据全部删掉,文件另存为 .gz,然后用 gunzip 直接解压即可。事实上,被删除掉的就是 ROM 里自己进行解压的那部分代码,而且 .gz 的文件尾部也还有不属于 gzip 数据的内容,只不过会被 gunzip 自动抛弃掉不予处理。

打赏 赞(0)
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注