欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]boot.img逆向分析

[原创]boot.img逆向分析

目的:
需要能够对boot.img文件中的zImage内核逻辑修改,比如adb reboot edl中将edl关键字修改为其他字符。
zImage中的内核是经过压缩的,所以需要找到提取内核压缩文件的方法以及重新生成zImage的方法。
研究前提:
以高通平台的手机作为研究基础;
zImage生成过程研究:
 
我们用此图说明一下zImage的产生过程。首先顶层vmlinux是ELF格式的可执行文件,必须将其二进制化生成Image后才可以被bootloader引导。为了实现压缩的内核映像,arch/arm/boot/compressed/Makefile又将这个非压缩映像Image做gzip压缩,生成了piggy.gzip。但要实现在启动时自解压,必须将这个piggy.gzip转化为.o文件,并同初始化程序head.o和自解压程序misc.o一同链接,生成arch/arm/boot/compressed/vmlinux。最后arch/arm/boot/Makefile将这个ELF格式的arch/arm/boot/compressed/vmlinux二进制化得到可被bootloader引导的映像文件zImage。
逆向分析方案的研究过程:
从zImage生成过程可知,piggy.gz生成了piggy.o,查看编译脚本$(obj)/piggy.$(suffix_y).o:arch/arm/boot/compressed/ piggy.gzip.o,其实是arch/arm/boot/Image经过gzip压缩后(piggy.gzip),再借助piggy.gzip.S一起编译出的ELF可链接文件。其中的原理可以看看piggy.gzip.S源码。
.section .piggydata,#alloc
.globl input_data
input_data:
.incbin "arch/arm/boot/compressed/piggy.gzip"
.globl input_data_end
input_data_end:
可以看到piggy.gzip是被作为input_data生成在了piggy.o,保持原样没有改动。
piggy.o再经过lds生成了vmlinux,再经过objcopy由elf格式转换到了bin格式,这一过程中piggy.gzip这部分数据也没有被改写。
所以从zImage中是可以提取出piggy.gzip文件的,那么怎么提取呢?
我们通过一套项目代码环境,编译获得piggy.gzip,piggy.gzip.o,vmlinux,然后比较这几个文件确定出生成piggy.gzip的头和尾,头是“1f 8b 08 00 00 00 00 00 02 03”,尾部是“a0 53 d6 f1 b0 4a fe 00”,那么头和尾有通用性么?
 
我们多次修改代码,得到多次的结果,再比较piggy.gzip的头和尾,发现头部是一样的,但尾部差异很大,唯一可以确认的是尾部出现在倒数第四行。
对于头部的规律也通过源码进行了确认, \kernel\lib\decompress_inflate.c
 
在解压缩的代码中有一段代码注释,gzip header是一个10字节的头。
所以我们搜索一下“1f 8b 08 00 00 00 00 00 02 03”,可以找到piggy.gzip的头。
对于尾部的规律有一个重要的特性,gzip格式最后的四个字节,是文件压缩前的大小,存放格式是小端模式。所以我们查找尾部的规律是在zImage文件的倒数第四行,查找怀疑是文件大小的四个字节,然后将头尾间数据保存下来,windows下用7z工具解压并查看解压后文件的大小,换算成16进制验证截取的尾部是否正确。
正确的解压缩内核后我们就可以通过IDA等工具进行逆向分析和修改了,这里不是本文重点不再深入说明。
方案步骤如下:
1.  从boot.img得到zImage。可以通过如linux下 unpackbooting等工具获得zImage,命令是./unpackbootimg  -i boot.img 。
2.  从zImage提取出压缩的内核文件。内核提取的方法见上面的描述。命令可以使用
dd if=输入文件名 of=输出文件名 bs=1 skip=1000 count=2000,指令含义是将输入文件的前1000个字节跳过,截取之后的2000个字节并输出到文件。
3.  对压缩文件进行解压。可以在windows下使用7z工具直接解压。
4.  将解压后的文件中的edl修改为其他字符。
5.  压缩文件。根据编译脚本,命令是“cat 文件名 | gzip –n –f -9 > 压缩后文件名”。
6.  将压缩后的文件插入到提取出来的位置,生成zImage。
7.  重新打包生成boot.img。可以通过如linux下mkbooting等工具。命令是
./mkbootimg  --kernel ./boot.img-zImage --ramdisk ./boot.img-ramdisk.gz --cmdline "XXXXXXXXX" --base 0x00000000 --pagesize 2048 --dt ./boot.img-dt.gz --tags_offset 1E00000 --output ./boot.img,其中—cmdline,--base,--pagesize,-- tags_offset参数需要替换成第1步解包时的参数。

 
验证:
在高通平台红米2手机上测试通过。
Mtk平台说明
逆向分析方案与高通平台一致,可以按照高通平台的方法操作,但有一点要注意,最后需要将原boot.img的前64个字节复制到制作的boot.img中。
在mt6735平台android 5.0项目上验证通过。
遗留问题
修改再压缩后的文件一定要与未修改前的压缩文件大小一致,目前没有找到可以自由修改的方法。
新浪博客:http://blog.sina.com.cn/u/3119174327

上传的附件 1.PNG
2.PNG
3.PNG
4.PNG

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功