android镜像分析
Contents
涉及工具:
mkbootimg、 unpackbootimg、 gzip、 readelf、objdump、simg2img、mount、extract-dtb.py、dt、cpio
概览
1、Android bootimg kernel(boot.img)
1.1、内核boot.img-zImage分析
1.2、设备树
1.3、根目录
2、emmc_appsboot.mbn:
3、splash.img:
4、dtbo.img:
5、mdtp.img:
6、vbmeta.img:
7、Linux rev 1.0 ext4 filesystem data(persist.img)
8、Android sparse image(system.img、userdata.img、vendor.img):
9、Super.img :
详细介绍
上篇日志分析可以看到开机流程中需要使用很多分区,这些分区在eMMC中占用不同的空间,其占用信息存储于分区表(GPT)中。高通智能机分区表详细解析_rockly89的博客-CSDN博客_fsc分区里面是比较全的分区描述,android P以后才有的vbmeta用于验证、dtbo是设备树叠加层。下面是dev下block节点读的信息。
这个博客主要研究刷机到底刷进去的是什么。
MP镜像不管,只分析android的镜像。
查看Android源码编出来的文件。
Android sparse image(稀疏)格式最多,这种格式可以理解文件系统的一种压缩格式,查看需解压。(差分升级如果包括该类镜像,不要用这种格式直接做差分diff)
Linux rev 1.0 ext4 filesystem data,是一种文件系统格式,也是Android sparse image(稀疏)格式的解压,可直接挂载查看。
data,数据类型,该类型实际是未识别的类型,其中splash.img和vbmeta.img未识别,我们后面再分析。(实际电子设备上存储的所有东西都可认为是data)
Android bootimg kernel格式最复杂,主要包含cmdline,设备树,内核,文件系统。由google的andorid源码工具mkbootimg制作,本blog大部分篇幅介绍的是boot.img镜像解析和反汇编。
ELF 32-bit LSB executable,是执行文件类型,其实boot.img镜像中内核可以当作执行文件,为了理解执行文件,将反汇编emmc_appsboot.mbn和boot.img中的内核。
1、Android bootimg kernel(boot.img)
boot.img包含内核,根文件系统,设备树,cmdline。编译使用mkbootimg,解压使用unpackbootimg,GITHUB上不少该工具。
先用 unpackbootimg boot.img 解压
|
|
其中内核文件boot.img-zImage,根目录文件boot.img-ramdisk.gz,设备树在内核文件中,recovery的设备树是boot.img-dtb,cmdline是boot.img-cmdline。
1.1、内核boot.img-zImage分析
重命名
|
|
解压
|
|
得到的zImage是MS-DOS executable, MZ for MS-DOS格式文件, Beyong Compare对比可以看到zImage就是源码编译出的obj\KERNEL_OBJ\arch\arm64\boot\zImage,它是vmlinux通过编译工具objcopy去掉调试信息后的二进制文件。
源码编译时是使用工具mpgen.py。
可以访问linux kernel编译产生的vmlinux Image zImage之间的关系_潘振杰的博客-CSDN博客_kernel编译完后只有vmlinux查看kernel怎么生成的。(与android的boot.img稍有不同)
这里要对内核反汇编,相关知识比较弱的建议先看下相关blog并动手尝试,下面两个博客有不少分析可执行文件的工具。
- 逆向与反汇编工具 - mull - 博客园
- ELF文件-逆向工具_ToTHotSpur的博客-CSDN博客_elf 逆向
描述了ELF文件结构。
执行反汇编命令,解析vmlinux:
|
|
Linux下利用objdump查看文件空间地址分布
|
|
真实数据位置偏移根据前面信息计算(NOTE off 0x000000000183cc48 vaddr 0xffffff800993cc48) 0x18408a8=0x99408a8-0x0x8100000
可以使用hexdump以16进制读取可执行文件,对比反汇编的机器码。
|
|
这里以反汇编方式找到boot.img中内核入口start_kernel代码的反汇编机器码位置,高手可以编辑它,重新打包,关掉相关安全验证(Verify Boot,DM-verity,回滚保护)刷到设备中。
汇编是比较老的语言,但是是离机器最近的语言,玩软件破解和加密应该熟悉。就算不玩破解,知道点反汇编对于代码和程序的理解也会不同。
下面是随便找的一个破解例子
Linux下使用objdump+vim+xxd进行反汇编并修改指令
1.2、设备树
unpackbootimg没看到设备树,对比编译出的Image.gz-dtb与Image.gz可以知道,mkbootimg把Image.gz-dtb(设备树)作为kernel制作boot.img的,设备树还在内核解包的zImage中。要获取设备树需要读取其中信息才可分离出来。GITHUB有从内核中解压设备树工具https://github.com/PabloCastellano/extract-dtb
|
|
可以用dtc来分析源码编译出的设备树obj\KERNEL_OBJ\arch\arm64\boot\dts***.dtb。
|
|
转换成dts格式后,文本编辑器可以直接读。也可比较boot.img解包出的dts、编译的dts两个文件,验证是否一致。
1.3、根目录
解压缩
|
|
解包。
|
|
这样就看到根目录。
内核调试可以使用fastboot boot boot.img命令,boot.img不刷入分区,直接载入ram运行。还可以使用下面参数设置,同时注意下设备安全限制(AVB,防回滚)。
|
|
2、emmc_appsboot.mbn:
bootloader镜像emmc_appsboot.mbn,与zImage一样,可以readelf解析,但不能objdump反汇编。所以我们对编译最后一步sectools.py签名前的文件lk_s.elf进行反汇编。
参照上面vmlinux反编译方式读出关键函数<aboot_init>机器码位置。
|
|
这里机器码与反汇编码对应上了(android有相关签名验证链,一环套一环,无签名与许可不要尝试修改破解)
3、splash.img:
这个是开机画面镜像,生成工具是logo_gen.py,分析可以转多开机界面适配,多dtbo合入。
4、dtbo.img:
该镜像是设备树叠加层,官网有介绍,源码有mkdtimg工具制作和解析,该镜像只包含设备树叠加层,没有设备树,详细可以看看多开机界面适配,多dtbo合入。
5、mdtp.img:
高通源码直接复制而来,无法分析。
6、vbmeta.img:
用于安全验证,bootloader验证vbmeta的签名,再用vbmeta的key以及hash值验证dtbo/boot/system/vendor。
里面格式数据可以访问
https://android.googlesource.com/platform/external/avb/+/master/README.md#The-VBMeta-struct
后面的blog刷机相关的Android的安全中会用avbtool生成该镜像。
7、Linux rev 1.0 ext4 filesystem data(persist.img)
文件系统镜像
|
|
8、Android sparse image(system.img、userdata.img、vendor.img):
system.img、userdata.img、vendor.img、persist.img都是sparse压缩文件系统镜像,目的是方便传输/刷机/存储等。想查看内容需先转换为raw格式。
现在system和vendor后有追加哈希树。userdata加密后无法挂载。
|
|
9、Super.img :
super.img是几个只读分区的合并,file读取格式可能为data,android源码有lpunpack工具分解,提示无该命令可以先make lpunpack,
|
|
查看服务器编译的system/vendor等sparse格式镜像时,如果挂载失败,可以尝试加只读参数才能来查看:
|
|
该系列第二条线就是镜像分析,本博客主要以反汇编方式分析内核镜像。
后面几个blog也会分析其他文件。
android刷机方式将分析nonAB的OTA包中system.dat转换、AB的OTA包中payload.bin的转换。
刷机相关的Android的安全中将分析vbmeta,以及avbtool使用。还有如何查看SELinux规则文件,单编SELinux规则文件。
正确的刷机观中分析gpt文件,NV备份。
多开机界面,多设备树叠加层中将分析splash.img和dtbo.img镜像。
Author 软件开发大郭
LastMod 2023-02-17