关键字:反汇编、 内核
涉及工具: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源码编出来的文件。
file . *
boot.img: Android bootimg, kernel, ramdisk, page size: 2048, cmdline (console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0 androidbo)
dtbo.img: data
emmc_appsboot.mbn: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped
ipsm.img: Android sparse image, version: 1.0, Total of 393216 4096-byte output blocks in 22 input chunks.
license.img: Android sparse image, version: 1.0, Total of 4096 4096-byte output blocks in 8 input chunks.
mdtp.img: data
persist.img: Linux rev 1.0 ext4 filesystem data, UUID=d9a6bc78-9d91-4760-9f23-ea9d57708460 (extents) (large files) (huge files)
secure.img: Android sparse image, version: 1.0, Total of 4096 4096-byte output blocks in 8 input chunks.
splash.img: data
system.img: Android sparse image, version: 1.0, Total of 688640 4096-byte output blocks in 27 input chunks.
userdata.img: Android sparse image, version: 1.0, Total of 1324921 4096-byte output blocks in 30 input chunks.
vbmeta.img: data
vendor.img: Android sparse image, version: 1.0, Total of 192000 4096-byte output blocks in 17 input chunks.
从上面可以看出
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中的内核。
boot.img包含内核,根文件系统,设备树,cmdline。编译使用mkbootimg,解压使用unpackbootimg,GITHUB上不少该工具。
先用unpackbootimg boot.img解压
boot.img: Android bootimg, kernel, ramdisk, page size: 2048, cmdline (console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0 androidbo)
boot.img-base: ASCII text
boot.img-board: very short file (no magic)
boot.img-cmdline: ASCII text, with very long lines
boot.img-dtb: very short file (no magic)
boot.img-hash: ASCII text
boot.img-kerneloff: ASCII text
boot.img-oslevel: ASCII text
boot.img-osversion: ASCII text
boot.img-pagesize: ASCII text
boot.img-ramdisk.gz: gzip compressed data, from Unix
boot.img-ramdiskoff: ASCII text
boot.img-secondoff: ASCII text
boot.img-tagsoff: ASCII text
boot.img-zImage: gzip compressed data, max compression, from Unix
其中内核文件boot.img-zImage,根目录文件boot.img-ramdisk.gz,设备树在内核文件中,recovery的设备树是boot.img-dtb,cmdline是boot.img-cmdline。
得到的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文件结构。
https://blog.csdn.net/abc_12366/article/details/88205670
执行反汇编命令,解析vmlinux:
readelf -hlSVAI vmlinux(-r/s参数内容多,谨慎使用)
aarch64-linux-androidkernel-objdump -afphG vmlinux (-D/d/S/s/x参数内容太多,谨慎使用)
Linux下利用objdump查看文件空间地址分布 - jrglinux - 博客园
readelf -S vmlinux
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: AArch64
Version: 0x1
Entry point address: 0xffffff8008080000
Start of program headers: 64 (bytes into file)
Start of section headers: 273510912 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 4
Size of section headers: 64 (bytes)
Number of section headers: 42
Section header string table index: 39
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .head.text PROGBITS ffffff8008080000 00010000
0000000000001000 0000000000000000 AX 0 0 4096
[ 2] .text PROGBITS ffffff8008081000 00011000
00000000010c36d8 0000000000000008 AX 0 0 2048
[ 3] .rodata PROGBITS ffffff8009200000 01100000
00000000006afc25 0000000000000000 WA 0 0 1048576
[ 4] .eh_frame PROGBITS ffffff80098afc28 017afc28
0000000000000048 0000000000000000 A 0 0 8
[ 5] __bug_table PROGBITS ffffff80098afc70 017afc70
00000000000190e0 0000000000000000 A 0 0 4
[ 6] __ksymtab PROGBITS ffffff80098c8d50 017c8d50
0000000000016700 0000000000000000 A 0 0 8
[ 7] __ksymtab_gpl PROGBITS ffffff80098df450 017df450
0000000000010580 0000000000000000 A 0 0 8
[ 8] __kcrctab PROGBITS ffffff80098ef9d0 017ef9d0
000000000000b380 0000000000000000 A 0 0 8
[ 9] __kcrctab_gpl PROGBITS ffffff80098fad50 017fad50
00000000000082c0 0000000000000000 A 0 0 8
[10] __ksymtab_strings PROGBITS ffffff8009903010 01803010
000000000002ff08 0000000000000000 A 0 0 1
[11] __param PROGBITS ffffff8009932f18 01832f18
0000000000004f60 0000000000000000 A 0 0 8
[12] __modver PROGBITS ffffff8009937e78 01837e78
0000000000000188 0000000000000000 A 0 0 8
[13] __ex_table PROGBITS ffffff8009938000 01838000
0000000000004c48 0000000000000000 A 0 0 8
[14] .notes NOTE ffffff800993cc48 0183cc48
0000000000000024 0000000000000000 A 0 0 4
[15] .init.text PROGBITS ffffff8009940000 01840000
000000000007561c 0000000000000000 AX 0 0 16
[16] .exit.text PROGBITS ffffff80099b561c 018b561c
0000000000006654 0000000000000000 AX 0 0 4
[17] .init.data PROGBITS ffffff80099bbd00 018bbd00
0000000000114de8 0000000000000000 WA 0 0 256
[18] .data..percpu PROGBITS ffffff8009ad1000 019d1000
000000000000db28 0000000000000000 WA 0 0 128
[19] .altinstructions PROGBITS ffffff8009adeb28 019deb28
000000000001de8c 0000000000000000 A 0 0 1
[20] .altinstr_replace PROGBITS ffffff8009afc9b4 019fc9b4
000000000000a3b8 0000000000000000 AX 0 0 4
[21] .rela RELA ffffff8009b06d70 01a06d70
0000000000484d70 0000000000000018 A 0 0 8
[22] .data PROGBITS ffffff8009f90000 01e90000
0000000000237e08 0000000000000000 WA 0 0 4096
[23] .got.plt PROGBITS ffffff800a1c7e08 020c7e08
0000000000000018 0000000000000008 WA 0 0 8
[24] .bss_rtic PROGBITS ffffff800a1c8000 020c8000
0000000000001004 0000000000000000 WA 0 0 4096
[25] __clk_of_table_en PROGBITS ffffff800a1c9008 020c9008
00000000000000c8 0000000000000000 WA 0 0 8
[26] .mmuoff.data.writ PROGBITS ffffff800a1c9800 020c9800
0000000000000014 0000000000000000 WA 0 0 2048
[27] .mmuoff.data.read PROGBITS ffffff800a1ca000 020ca000
0000000000000008 0000000000000000 WA 0 0 8
[28] .pecoff_edata_pad PROGBITS ffffff800a1ca008 020ca008
00000000000001f8 0000000000000000 WA 0 0 1
[29] .bss NOBITS ffffff800a1cb000 020ca200
00000000009b6038 0000000000000000 WA 0 0 4096
[30] .comment PROGBITS 0000000000000000 020ca200
0000000000000027 0000000000000001 MS 0 0 1
[31] .debug_line PROGBITS 0000000000000000 020ca227
0000000000db311b 0000000000000000 0 0 1
[32] .debug_info PROGBITS 0000000000000000 02e7d342
000000000a65870b 0000000000000000 0 0 1
[33] .debug_abbrev PROGBITS 0000000000000000 0d4d5a4d
00000000003a8243 0000000000000000 0 0 1
[34] .debug_aranges PROGBITS 0000000000000000 0d87dc90
00000000000294e0 0000000000000000 0 0 16
[35] .debug_ranges PROGBITS 0000000000000000 0d8a7170
0000000000961e50 0000000000000000 0 0 16
[36] .debug_frame PROGBITS 0000000000000000 0e208fc0
000000000031e220 0000000000000000 0 0 8
[37] .debug_str PROGBITS 0000000000000000 0e5271e0
0000000000454737 0000000000000001 MS 0 0 1
[38] .debug_loc PROGBITS 0000000000000000 0e97b917
0000000001403166 0000000000000000 0 0 1
[39] .shstrtab STRTAB 0000000000000000 104d7021
00000000000001da 0000000000000000 0 0 1
[40] .symtab SYMTAB 0000000000000000 0fd7ea80
0000000000473820 0000000000000018 41 159880 8
[41] .strtab STRTAB 0000000000000000 101f22a0
00000000002e4d81 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000010000 0xffffff8008080000 0xffffff8008080000
0x00000000010c46d8 0x00000000010c46d8 R E 10000
LOAD 0x0000000001100000 0xffffff8009200000 0xffffff8009200000
0x0000000000fca200 0x0000000001981038 RWE 10000
NOTE 0x000000000183cc48 0xffffff800993cc48 0xffffff800993cc48
0x0000000000000024 0x0000000000000024 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
Section to Segment mapping:
Segment Sections...
00 .head.text .text
01 .rodata .eh_frame __bug_table __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __modver __ex_table .notes .init.text .exit.text .init.data .data..percpu .altinstructions .altinstr_replacement .rela .data .got.plt .bss_rtic __clk_of_table_end .mmuoff.data.write .mmuoff.data.read .pecoff_edata_padding .bss
02 .notes
03
No version information found in this file.
aarch64-linux-androidkernel-objdump -afp vmlinux
vmlinux: file format elf64-littleaarch64
vmlinux
architecture: aarch64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0xffffff8008080000
Program Header:
LOAD off 0x0000000000010000 vaddr 0xffffff8008080000 paddr 0xffffff8008080000 align 2**16
filesz 0x00000000010c46d8 memsz 0x00000000010c46d8 flags r-x
LOAD off 0x0000000001100000 vaddr 0xffffff8009200000 paddr 0xffffff8009200000 align 2**16
filesz 0x0000000000fca200 memsz 0x0000000001981038 flags rwx
NOTE off 0x000000000183cc48 vaddr 0xffffff800993cc48 paddr 0xffffff800993cc48 align 2**2
filesz 0x0000000000000024 memsz 0x0000000000000024 flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
private flags = 0:
Sections:
Idx Name Size VMA LMA File off Algn
0 .head.text 00001000 ffffff8008080000 ffffff8008080000 00010000 2**12
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .text 010c36d8 ffffff8008081000 ffffff8008081000 00011000 2**11
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 006afc25 ffffff8009200000 ffffff8009200000 01100000 2**20
CONTENTS, ALLOC, LOAD, DATA
3 .eh_frame 00000048 ffffff80098afc28 ffffff80098afc28 017afc28 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 __bug_table 000190e0 ffffff80098afc70 ffffff80098afc70 017afc70 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 __ksymtab 00016700 ffffff80098c8d50 ffffff80098c8d50 017c8d50 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 __ksymtab_gpl 00010580 ffffff80098df450 ffffff80098df450 017df450 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 __kcrctab 0000b380 ffffff80098ef9d0 ffffff80098ef9d0 017ef9d0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 __kcrctab_gpl 000082c0 ffffff80098fad50 ffffff80098fad50 017fad50 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 __ksymtab_strings 0002ff08 ffffff8009903010 ffffff8009903010 01803010 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 __param 00004f60 ffffff8009932f18 ffffff8009932f18 01832f18 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
11 __modver 00000188 ffffff8009937e78 ffffff8009937e78 01837e78 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
12 __ex_table 00004c48 ffffff8009938000 ffffff8009938000 01838000 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
13 .notes 00000024 ffffff800993cc48 ffffff800993cc48 0183cc48 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
14 .init.text 0007561c ffffff8009940000 ffffff8009940000 01840000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .exit.text 00006654 ffffff80099b561c ffffff80099b561c 018b561c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
16 .init.data 00114de8 ffffff80099bbd00 ffffff80099bbd00 018bbd00 2**8
CONTENTS, ALLOC, LOAD, DATA
17 .data..percpu 0000db28 ffffff8009ad1000 ffffff8009ad1000 019d1000 2**7
CONTENTS, ALLOC, LOAD, DATA
18 .altinstructions 0001de8c ffffff8009adeb28 ffffff8009adeb28 019deb28 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
19 .altinstr_replacement 0000a3b8 ffffff8009afc9b4 ffffff8009afc9b4 019fc9b4 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
20 .rela 00484d70 ffffff8009b06d70 ffffff8009b06d70 01a06d70 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
21 .data 00237e08 ffffff8009f90000 ffffff8009f90000 01e90000 2**12
CONTENTS, ALLOC, LOAD, DATA
22 .got.plt 00000018 ffffff800a1c7e08 ffffff800a1c7e08 020c7e08 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .bss_rtic 00001004 ffffff800a1c8000 ffffff800a1c8000 020c8000 2**12
CONTENTS, ALLOC, LOAD, DATA
24 __clk_of_table_end 000000c8 ffffff800a1c9008 ffffff800a1c9008 020c9008 2**3
CONTENTS, ALLOC, LOAD, DATA
25 .mmuoff.data.write 00000014 ffffff800a1c9800 ffffff800a1c9800 020c9800 2**11
CONTENTS, ALLOC, LOAD, DATA
26 .mmuoff.data.read 00000008 ffffff800a1ca000 ffffff800a1ca000 020ca000 2**3
CONTENTS, ALLOC, LOAD, DATA
27 .pecoff_edata_padding 000001f8 ffffff800a1ca008 ffffff800a1ca008 020ca008 2**0
CONTENTS, ALLOC, LOAD, DATA
28 .bss 009b6038 ffffff800a1cb000 ffffff800a1cb000 020ca200 2**12
ALLOC
29 .comment 00000027 0000000000000000 0000000000000000 020ca200 2**0
CONTENTS, READONLY
30 .debug_line 00db311b 0000000000000000 0000000000000000 020ca227 2**0
CONTENTS, READONLY, DEBUGGING
31 .debug_info 0a65870b 0000000000000000 0000000000000000 02e7d342 2**0
CONTENTS, READONLY, DEBUGGING
32 .debug_abbrev 003a8243 0000000000000000 0000000000000000 0d4d5a4d 2**0
CONTENTS, READONLY, DEBUGGING
33 .debug_aranges 000294e0 0000000000000000 0000000000000000 0d87dc90 2**4
CONTENTS, READONLY, DEBUGGING
34 .debug_ranges 00961e50 0000000000000000 0000000000000000 0d8a7170 2**4
CONTENTS, READONLY, DEBUGGING
35 .debug_frame 0031e220 0000000000000000 0000000000000000 0e208fc0 2**3
CONTENTS, READONLY, DEBUGGING
36 .debug_str 00454737 0000000000000000 0000000000000000 0e5271e0 2**0
CONTENTS, READONLY, DEBUGGING
37 .debug_loc 01403166 0000000000000000 0000000000000000 0e97b917 2**0
CONTENTS, READONLY, DEBUGGING
内容结构可以访问https://blog.csdn.net/abc_12366/article/details/88205670,为直观体现执行文件里面数据的意义,先找入口函数start_kernel()位置,下面博客有两种方法反汇编指定函数。
Linux下反汇编指定的函数_zuxi的博客-CSDN博客
kernel入口函数start_kernel()反汇编如下,可以对比源码中kernel/init/main.c的start_kernel()中内容。
nm -n vmlinux |grep -A1 "start_kernel"
ffffff8008095378 T secondary_start_kernel
ffffff8008095594 T __cpu_disable
--
ffffff80099408a8 T start_kernel
ffffff8009940cb4 t kernel_init_freeable
aarch64-linux-androidkernel-objdump -d vmlinux --start-address=0xffffff80099408a8 --stop-address=0xffffff8009940cb4
vmlinux: file format elf64-littleaarch64
Disassembly of section .init.text:
ffffff80099408a8 :
ffffff80099408a8: a9b97bfd stp x29, x30, [sp,#-112]!
ffffff80099408ac: f0003380 adrp x0, ffffff8009fb3000
ffffff80099408b0: 910003fd mov x29, sp
ffffff80099408b4: a90363f7 stp x23, x24, [sp,#48]
ffffff80099408b8: f00032f8 adrp x24, ffffff8009f9f000
ffffff80099408bc: 91120000 add x0, x0, #0x480
ffffff80099408c0: a90153f3 stp x19, x20, [sp,#16]
ffffff80099408c4: a9025bf5 stp x21, x22, [sp,#32]
ffffff80099408c8: f9460701 ldr x1, [x24,#3080]
ffffff80099408cc: f90037a1 str x1, [x29,#104]
ffffff80099408d0: f90023f9 str x25, [sp,#64]
ffffff80099408d4: 979dc255 bl ffffff80080b1228
ffffff80099408d8: 94000dc7 bl ffffff8009943ff4
ffffff80099408dc: 9400d951 bl ffffff8009976e20
ffffff80099408e0: 9400637a bl ffffff80099596c8
ffffff80099408e4: d50342df msr daifset, #0x2
ffffff80099408e8: f00032f6 adrp x22, ffffff8009f9f000
ffffff80099408ec: 97a1e434 bl ffffff80081b99bc
ffffff80099408f0: 52800020 mov w0, #0x1 // #1
ffffff80099408f4: f00003d4 adrp x20, ffffff80099bb000
ffffff80099408f8: 91340294 add x20, x20, #0xd00
ffffff80099408fc: d0004475 adrp x21, ffffff800a1ce000
ffffff8009940900: 393002c0 strb w0, [x22,#3072]
ffffff8009940904: 94003b72 bl ffffff800994f6cc
ffffff8009940908: 90ffc601 adrp x1, ffffff8009200000 <__start_rodata>
ffffff800994090c: 90ffe740 adrp x0, ffffff8009628000
ffffff8009940910: 91026021 add x1, x1, #0x98
ffffff8009940914: 910fc000 add x0, x0, #0x3f0
ffffff8009940918: 9120e294 add x20, x20, #0x838
ffffff800994091c: 910002b7 add x23, x21, #0x0
ffffff8009940920: 97a2c471 bl ffffff80081f1ae4
ffffff8009940924: aa1803f3 mov x19, x24
ffffff8009940928: 910163a0 add x0, x29, #0x58
ffffff800994092c: 94000dc7 bl ffffff8009944048
ffffff8009940930: 52800101 mov w1, #0x8 // #8
ffffff8009940934: 910183a0 add x0, x29, #0x60
ffffff8009940938: 97b63acb bl ffffff80086cf464
ffffff800994093c: f94033a1 ldr x1, [x29,#96]
ffffff8009940940: d2812e00 mov x0, #0x970 // #2416
ffffff8009940944: f2a00080 movk x0, #0x4, lsl #16
ffffff8009940948: ca000020 eor x0, x1, x0
ffffff800994094c: 9278dc01 and x1, x0, #0xffffffffffffff00
ffffff8009940950: f9060701 str x1, [x24,#3080]
ffffff8009940954: d5384102 mrs x2, sp_el0
ffffff8009940958: f9034441 str x1, [x2,#1672]
ffffff800994095c: f0003501 adrp x1, ffffff8009fe3000
ffffff8009940960: aa1403e0 mov x0, x20
ffffff8009940964: f9019c3f str xzr, [x1,#824]
ffffff8009940968: 97ad261e bl ffffff800848a1e0 <__efistub_strlen>
ffffff800994096c: d2800001 mov x1, #0x0 // #0
ffffff8009940970: d2800002 mov x2, #0x0 // #0
ffffff8009940974: d2800003 mov x3, #0x0 // #0
ffffff8009940978: 12800004 mov w4, #0xffffffff // #-1
ffffff800994097c: 91000400 add x0, x0, #0x1
ffffff8009940980: f9402fb8 ldr x24, [x29,#88]
ffffff8009940984: 94009058 bl ffffff8009964ae4
ffffff8009940988: f90016e0 str x0, [x23,#40]
ffffff800994098c: aa1403e0 mov x0, x20
ffffff8009940990: 97ad2614 bl ffffff800848a1e0 <__efistub_strlen>
ffffff8009940994: 91000400 add x0, x0, #0x1
ffffff8009940998: d2800001 mov x1, #0x0 // #0
ffffff800994099c: d2800002 mov x2, #0x0 // #0
ffffff80099409a0: d2800003 mov x3, #0x0 // #0
ffffff80099409a4: 12800004 mov w4, #0xffffffff // #-1
ffffff80099409a8: 9400904f bl ffffff8009964ae4
ffffff80099409ac: f9001ae0 str x0, [x23,#48]
ffffff80099409b0: aa1803e0 mov x0, x24
ffffff80099409b4: 97ad260b bl ffffff800848a1e0 <__efistub_strlen>
ffffff80099409b8: 91000400 add x0, x0, #0x1
ffffff80099409bc: d2800002 mov x2, #0x0 // #0
ffffff80099409c0: d2800003 mov x3, #0x0 // #0
ffffff80099409c4: 12800004 mov w4, #0xffffffff // #-1
ffffff80099409c8: d2800001 mov x1, #0x0 // #0
ffffff80099409cc: 94009046 bl ffffff8009964ae4
ffffff80099409d0: aa0003f9 mov x25, x0
ffffff80099409d4: f94016e0 ldr x0, [x23,#40]
ffffff80099409d8: aa1403e1 mov x1, x20
ffffff80099409dc: f9001ef9 str x25, [x23,#56]
ffffff80099409e0: 97ad5468 bl ffffff8008495b80
ffffff80099409e4: aa1803e1 mov x1, x24
ffffff80099409e8: aa1903e0 mov x0, x25
ffffff80099409ec: 97ad5465 bl ffffff8008495b80
ffffff80099409f0: 940060c6 bl ffffff8009958d08
ffffff80099409f4: 940083bf bl ffffff80099618f0
ffffff80099409f8: 94003b4d bl ffffff800994f72c
ffffff80099409fc: 9400128d bl ffffff8009945430
ffffff8009940a00: d2800000 mov x0, #0x0 // #0
ffffff8009940a04: d2800001 mov x1, #0x0 // #0
ffffff8009940a08: 97dfce2e bl ffffff80091342c0
ffffff8009940a0c: 940079c0 bl ffffff800995f10c
ffffff8009940a10: 90ffe740 adrp x0, ffffff8009628000
ffffff8009940a14: aa1403e1 mov x1, x20
ffffff8009940a18: 910fe000 add x0, x0, #0x3f8
ffffff8009940a1c: 97a2c432 bl ffffff80081f1ae4
ffffff8009940a20: 97ffff84 bl ffffff8009940830
ffffff8009940a24: d0ffff82 adrp x2, ffffff8009932000 <__kstrtab_sctp_for_each_endpoint+0x2>
ffffff8009940a28: f0ffffa3 adrp x3, ffffff8009937000 <__param_debug_mask+0x10>
ffffff8009940a2c: 913c6042 add x2, x2, #0xf18
ffffff8009940a30: 9139e063 add x3, x3, #0xe78
ffffff8009940a34: cb020063 sub x3, x3, x2
ffffff8009940a38: b202e7e0 mov x0, #0xcccccccccccccccc // #-3689348814741910324
ffffff8009940a3c: 9343fc63 asr x3, x3, #3
ffffff8009940a40: 12800004 mov w4, #0xffffffff // #-1
ffffff8009940a44: f9401ee1 ldr x1, [x23,#56]
ffffff8009940a48: 90000007 adrp x7, ffffff8009940000
ffffff8009940a4c: 1b030c03 madd w3, w0, w3, w3
ffffff8009940a50: 90ffe740 adrp x0, ffffff8009628000
ffffff8009940a54: 2a0403e5 mov w5, w4
ffffff8009940a58: 91106000 add x0, x0, #0x418
ffffff8009940a5c: d2800006 mov x6, #0x0 // #0
ffffff8009940a60: 911520e7 add x7, x7, #0x548
ffffff8009940a64: 979e7f22 bl ffffff80080e06ec
ffffff8009940a68: aa0003e1 mov x1, x0
ffffff8009940a6c: b4000060 cbz x0, ffffff8009940a78
ffffff8009940a70: b140041f cmn x0, #0x1, lsl #12
ffffff8009940a74: 54000fe9 b.ls ffffff8009940c70
ffffff8009940a78: 913002c1 add x1, x22, #0xc00
ffffff8009940a7c: 52800022 mov w2, #0x1 // #1
ffffff8009940a80: 52800000 mov w0, #0x0 // #0
ffffff8009940a84: 39000422 strb w2, [x1,#1]
ffffff8009940a88: 940055ce bl ffffff80099561c0
ffffff8009940a8c: 94003f3b bl ffffff8009950778
ffffff8009940a90: 94009ce4 bl ffffff8009967e20
ffffff8009940a94: 94003f98 bl ffffff80099508f4
ffffff8009940a98: 94000f39 bl ffffff800994477c
ffffff8009940a9c: 94001b11 bl ffffff80099476e0
ffffff8009940aa0: 940093c9 bl ffffff80099659c4
ffffff8009940aa4: 940083c2 bl ffffff80099619ac
ffffff8009940aa8: 94008a80 bl ffffff80099634a8
ffffff8009940aac: 94001bd1 bl ffffff80099479f0
ffffff8009940ab0: 94008b2b bl ffffff800996375c
ffffff8009940ab4: 9400d7da bl ffffff8009976a1c
ffffff8009940ab8: 940050bd bl ffffff8009954dac
ffffff8009940abc: 52800020 mov w0, #0x1 // #1
ffffff8009940ac0: 979ec496 bl ffffff80080f1d18
ffffff8009940ac4: d53b4220 mrs x0, daif
ffffff8009940ac8: 373800e0 tbnz w0, #7, ffffff8009940ae4
ffffff8009940acc: 90ffe740 adrp x0, ffffff8009628000
ffffff8009940ad0: 9110a000 add x0, x0, #0x428
ffffff8009940ad4: 97a2c404 bl ffffff80081f1ae4
ffffff8009940ad8: d4210000 brk #0x800
ffffff8009940adc: d50342df msr daifset, #0x2
ffffff8009940ae0: 97a1e3b7 bl ffffff80081b99bc
ffffff8009940ae4: 9400d7bc bl ffffff80099769d4
ffffff8009940ae8: 940058c2 bl ffffff8009956df0
ffffff8009940aec: 940069ff bl ffffff800995b2e8
ffffff8009940af0: 9400d7e7 bl ffffff8009976a8c
ffffff8009940af4: 940056bc bl ffffff80099565e4
ffffff8009940af8: 94000ca3 bl ffffff8009943d84
ffffff8009940afc: 94005ecb bl ffffff8009958628
ffffff8009940b00: 94005965 bl ffffff8009957094
ffffff8009940b04: 94005b64 bl ffffff8009957894
ffffff8009940b08: 94005bb9 bl ffffff80099579ec
ffffff8009940b0c: 94003b6b bl ffffff800994f8b8
ffffff8009940b10: 94005ccb bl ffffff8009957e3c
ffffff8009940b14: 94000eeb bl ffffff80099446c0
ffffff8009940b18: 94005f75 bl ffffff80099588ec
ffffff8009940b1c: 940075d5 bl ffffff800995e270
ffffff8009940b20: 97dfcdbb bl ffffff800913420c
ffffff8009940b24: 9400603f bl ffffff8009958c20
ffffff8009940b28: d53b4220 mrs x0, daif
ffffff8009940b2c: 373800a0 tbnz w0, #7, ffffff8009940b40
ffffff8009940b30: 90ffe740 adrp x0, ffffff8009628000
ffffff8009940b34: 91118000 add x0, x0, #0x460
ffffff8009940b38: 97a2c3eb bl ffffff80081f1ae4
ffffff8009940b3c: d4210000 brk #0x800
ffffff8009940b40: 393002df strb wzr, [x22,#3072]
ffffff8009940b44: 97a1e654 bl ffffff80081ba494
ffffff8009940b48: d50342ff msr daifclr, #0x2
ffffff8009940b4c: 910002b5 add x21, x21, #0x0
ffffff8009940b50: 940093e7 bl ffffff8009965aec
ffffff8009940b54: 9400ff6c bl ffffff8009980904
ffffff8009940b58: f9400ea1 ldr x1, [x21,#24]
ffffff8009940b5c: b40000a1 cbz x1, ffffff8009940b70
ffffff8009940b60: 90ffe740 adrp x0, ffffff8009628000
ffffff8009940b64: f94012a2 ldr x2, [x21,#32]
ffffff8009940b68: 91120000 add x0, x0, #0x480
ffffff8009940b6c: 97a2c21d bl ffffff80081f13e0
ffffff8009940b70: d0004474 adrp x20, ffffff800a1ce000
ffffff8009940b74: f9404281 ldr x1, [x20,#128]
ffffff8009940b78: b4000301 cbz x1, ffffff8009940bd8
ffffff8009940b7c: d0004460 adrp x0, ffffff800a1ce000
ffffff8009940b80: b9407400 ldr w0, [x0,#116]
ffffff8009940b84: 350002a0 cbnz w0, ffffff8009940bd8
ffffff8009940b88: 90fffb22 adrp x2, ffffff80098a4000
ffffff8009940b8c: d34c9421 ubfx x1, x1, #12, #26
ffffff8009940b90: d2dff7e0 mov x0, #0xffbf00000000 // #281195803836416
ffffff8009940b94: aa0003e4 mov x4, x0
ffffff8009940b98: f2ffffe0 movk x0, #0xffff, lsl #48
ffffff8009940b9c: f9418843 ldr x3, [x2,#784]
ffffff8009940ba0: aa011800 orr x0, x0, x1, lsl #6
ffffff8009940ba4: f00045e1 adrp x1, ffffff800a1ff000
ffffff8009940ba8: f2ffffe4 movk x4, #0xffff, lsl #48
ffffff8009940bac: 934cfc63 asr x3, x3, #12
ffffff8009940bb0: f9417c22 ldr x2, [x1,#760]
ffffff8009940bb4: cb031881 sub x1, x4, x3, lsl #6
ffffff8009940bb8: cb010001 sub x1, x0, x1
ffffff8009940bbc: 9346fc21 asr x1, x1, #6
ffffff8009940bc0: eb02003f cmp x1, x2
ffffff8009940bc4: 540000a2 b.cs ffffff8009940bd8
ffffff8009940bc8: 90ffe740 adrp x0, ffffff8009628000
ffffff8009940bcc: 91128000 add x0, x0, #0x4a0
ffffff8009940bd0: 97a2c3c5 bl ffffff80081f1ae4
ffffff8009940bd4: f900429f str xzr, [x20,#128]
ffffff8009940bd8: 94009abe bl ffffff80099676d0
ffffff8009940bdc: 9400d8bc bl ffffff8009976ecc
ffffff8009940be0: 94009572 bl ffffff80099661a8
ffffff8009940be4: 9400784f bl ffffff800995ed20
ffffff8009940be8: 900003e0 adrp x0, ffffff80099bc000
ffffff8009940bec: f9469c00 ldr x0, [x0,#3384]
ffffff8009940bf0: b4000040 cbz x0, ffffff8009940bf8
ffffff8009940bf4: d63f0000 blr x0
ffffff8009940bf8: 979ef6fc bl ffffff80080fe7e8
ffffff8009940bfc: 979d100e bl ffffff8008084c34
ffffff8009940c00: 94003eff bl ffffff80099507fc
ffffff8009940c04: 94008a5b bl ffffff8009963570
ffffff8009940c08: 97ffff27 bl ffffff80099408a4
ffffff8009940c0c: 94004043 bl ffffff8009950d18
ffffff8009940c10: 9400387c bl ffffff800994ee00
ffffff8009940c14: 940038b7 bl ffffff800994eef0
ffffff8009940c18: 9400a241 bl ffffff800996951c
ffffff8009940c1c: 9400caf5 bl ffffff80099737f0
ffffff8009940c20: 9400cb70 bl ffffff80099739e0
ffffff8009940c24: 94009ca1 bl ffffff8009967ea8
ffffff8009940c28: 94003d43 bl ffffff8009950134
ffffff8009940c2c: 940079d0 bl ffffff800995f36c
ffffff8009940c30: 9400a67e bl ffffff800996a628
ffffff8009940c34: 9400a227 bl ffffff80099694d0
ffffff8009940c38: 94006416 bl ffffff8009959c90
ffffff8009940c3c: 940062f3 bl ffffff8009959808
ffffff8009940c40: 94006629 bl ffffff800995a4e4
ffffff8009940c44: 97a16c44 bl ffffff800819bd54
ffffff8009940c48: f0003320 adrp x0, ffffff8009fa7000
ffffff8009940c4c: 910f8000 add x0, x0, #0x3e0
ffffff8009940c50: f940a000 ldr x0, [x0,#320]
ffffff8009940c54: 9400673f bl ffffff800995a950
ffffff8009940c58: 97dfca03 bl ffffff8009133464
ffffff8009940c5c: f94037a1 ldr x1, [x29,#104]
ffffff8009940c60: f9460660 ldr x0, [x19,#3080]
ffffff8009940c64: eb00003f cmp x1, x0
ffffff8009940c68: 540001a0 b.eq ffffff8009940c9c
ffffff8009940c6c: 979dcee3 bl ffffff80080b47f8 <__stack_chk_fail>
ffffff8009940c70: 12800004 mov w4, #0xffffffff // #-1
ffffff8009940c74: 90ffe740 adrp x0, ffffff8009628000
ffffff8009940c78: 90000007 adrp x7, ffffff8009940000
ffffff8009940c7c: d2800002 mov x2, #0x0 // #0
ffffff8009940c80: 52800003 mov w3, #0x0 // #0
ffffff8009940c84: 2a0403e5 mov w5, w4
ffffff8009940c88: d2800006 mov x6, #0x0 // #0
ffffff8009940c8c: 911c80e7 add x7, x7, #0x720
ffffff8009940c90: 91138000 add x0, x0, #0x4e0
ffffff8009940c94: 979e7e96 bl ffffff80080e06ec
ffffff8009940c98: 17ffff78 b ffffff8009940a78
ffffff8009940c9c: a94153f3 ldp x19, x20, [sp,#16]
ffffff8009940ca0: a9425bf5 ldp x21, x22, [sp,#32]
ffffff8009940ca4: a94363f7 ldp x23, x24, [sp,#48]
ffffff8009940ca8: f94023f9 ldr x25, [sp,#64]
ffffff8009940cac: a8c77bfd ldp x29, x30, [sp],#112
ffffff8009940cb0: d65f03c0 ret
真实数据位置偏移根据前面信息计算(NOTE off 0x000000000183cc48 vaddr 0xffffff800993cc48)
0x18408a8=0x99408a8-0x0x8100000
可以使用hexdump以16进制读取可执行文件,对比反汇编的机器码。
hexdump -s 0x18408a8 -n 1024 vmlinux
18408a8 7bfd a9b9 3380 f000 03fd 9100 63f7 a903
18408b8 32f8 f000 0000 9112 53f3 a901 5bf5 a902
18408c8 0701 f946 37a1 f900 23f9 f900 c255 979d
18408d8 0dc7 9400 d951 9400 637a 9400 42df d503
18408e8 32f6 f000 e434 97a1 0020 5280 03d4 f000
18408f8 0294 9134 4475 d000 02c0 3930 3b72 9400
1840908 c601 90ff e740 90ff 6021 9102 c000 910f
1840918 e294 9120 02b7 9100 c471 97a2 03f3 aa18
1840928 63a0 9101 0dc7 9400 0101 5280 83a0 9101
1840938 3acb 97b6 33a1 f940 2e00 d281 0080 f2a0
这里以反汇编方式找到boot.img中内核入口start_kernel代码的反汇编机器码位置,高手可以编辑它,重新打包,关掉相关安全验证(Verify Boot,DM-verity,回滚保护)刷到设备中。汇编是比较老的语言,但是是离机器最近的语言,玩软件破解和加密应该熟悉。就算不玩破解,知道点反汇编对于代码和程序的理解也会不同。下面是随便找的一个破解例子
Linux下使用objdump+vim+xxd进行反汇编并修改指令
unpackbootimg没看到设备树,对比编译出的Image.gz-dtb与Image.gz可以知道,mkbootimg把Image.gz-dtb(设备树)作为kernel制作boot.img的,设备树还在内核解包的zImage中。要获取设备树需要读取其中信息才可分离出来。GITHUB有从内核中解压设备树工具https://github.com/PabloCastellano/extract-dtb
python3 extract-dtb.py kernel
Dumped 00_kernel, start=0 end=12116314
Dumped 01_dtbdump_***.dtb, start=12116314 end=12393371
Dumped 02_dtbdump_xK`)+-;
pw_qK.dtb, start=12393371 end=12393544
Extracted 2 appended dtbs + kernel to dtb
dtc -O dts 01_dtbdump_***.dtb -o test0.dts
可以用dtc来分析源码编译出的设备树obj\KERNEL_OBJ\arch\arm64\boot\dts\***.dtb。
dtc -I dtb -O dts obj\KERNEL_OBJ\arch\arm64\boot\dts\***.dtb -o test1.dts
转换成dts格式后,文本编辑器可以直接读。也可比较boot.img解包出的dts、编译的dts两个文件,验证是否一致。
这样就看到根目录。
内核调试可以使用fastboot boot boot.img命令,boot.img不刷入分区,直接载入ram运行。还可以使用下面参数设置,同时注意下设备安全限制(AVB,防回滚)。
fastboot -h
-c Override kernel commandline.
-b, --base Specify a custom kernel base
address (default: 0x10000000).
--kernel-offset Specify a custom kernel offset.
(default: 0x00008000)
--ramdisk-offset Specify a custom ramdisk offset.
(default: 0x01000000)
--tags-offset Specify a custom tags offset.
(default: 0x00000100)
-n, --page-size Specify the nand page size
(default: 2048).
fastboot boot boot.img
fastboot -c "console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0 androidboot.hardware=qcom msm_rtb.filter=0x237 ehci-hcd.park=3 lpm_levels.sleep_disabled=0 androidboot.bootdevice=7824900.sdhci earlycon=msm_serial_dm,0x78af000 firmware_class.path=/vendor/firmware_mnt/image androidboot.usbconfigfs=true loop.max_part=7 buildvariant=user" -b 0x80000000 boot Z:\boot.img
bootloader镜像emmc_appsboot.mbn,与zImage一样,可以readelf解析,但不能objdump反汇编。所以我们对编译最后一步sectools.py签名前的文件lk_s.elf进行反汇编。
参照上面vmlinux反编译方式读出关键函数
aarch64-linux-androidkernel-objdump -d lk_s.elf --start-address=0x8f63f390 --stop-address=0x8f63f8b0
lk_s.elf: file format elf32-littlearm
Disassembly of section .text:
8f63f390 :
8f63f390: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr}
8f63f394: e28db020 add fp, sp, #32
8f63f398: e24dd024 sub sp, sp, #36 ; 0x24
8f63f39c: e3006980 movw r6, #2432 ; 0x980
8f63f3a0: e3486f76 movt r6, #36726 ; 0x8f76
8f63f3a4: e50be030 str lr, [fp, #-48] ; 0xffffffd0
8f63f3a8: e5963000 ldr r3, [r6]
8f63f3ac: e50b3028 str r3, [fp, #-40] ; 0xffffffd8
8f63f3b0: ebffd709 bl 8f634fdc
8f63f3b4: e3500000 cmp r0, #0
8f63f3b8: 0a00006f beq 8f63f57c
8f63f3bc: ebff4487 bl 8f6105e0
8f63f3c0: e30920d8 movw r2, #37080 ; 0x90d8
8f63f3c4: e30d33dc movw r3, #54236 ; 0xd3dc
8f63f3c8: e3482f75 movt r2, #36725 ; 0x8f75
8f63f3cc: e3483f74 movt r3, #36724 ; 0x8f74
*
*
*
LOAD off 0x00008000 vaddr 0x8f600000
0x47390=0x8f63f390 -0x8f600000+0x00008000
hexdump -s 0x47390 -n 1024 lk_s.elf
0047390 4ff0 e92d b020 e28d d024 e24d 6980 e300
00473a0 6f76 e348 e030 e50b 3000 e596 3028 e50b
00473b0 d709 ebff 0000 e350 006f 0a00 4487 ebff
00473c0 20d8 e309 33dc e30d 2f75 e348 3f74 e348
00473d0 1001 e240 0000 e582 1000 e583 424c ebff
00473e0 20c8 e309 33c8 e30d 2f75 e348 3f74 e348
00473f0 1001 e240 0000 e582 1000 e583 0a64 e300
0047400 0f71 e348 25f6 eb00 a00d e1a0 ff4f ebff
0047410 0a80 e300 0f71 e348 25f1 eb00 0c94 e309
0047420 0f72 e348 f3cb ebff 4239 ebff 3086 e280
0047430 7000 e1a0 3007 e3c3 0c80 e309 d003 e04d
这里机器码与反汇编码对应上了(android有相关签名验证链,一环套一环,无签名与许可不要尝试修改破解)
这个是开机画面镜像,生成工具是logo_gen.py,分析可以转多开机界面适配,多dtbo合入。
该镜像是设备树叠加层,官网有介绍,源码有mkdtimg工具制作和解析,该镜像只包含设备树叠加层,没有设备树,详细可以看看多开机界面适配,多dtbo合入。
高通源码直接复制而来,无法分析。
用于安全验证,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生成该镜像。
文件系统镜像
mkdir test;
mount persist.img test;
sudo chmod 777 test
system.img、userdata.img、vendor.img、persist.img都是sparse压缩文件系统镜像,目的是方便传输/刷机/存储等。想查看内容需先转换为raw格式。现在system和vendor后有追加哈希树。userdata加密后无法挂载。
simg2img system.img system_raw.img;
mkdir test;
mount system_raw.img test;
sudo chmod 777 test
super.img是几个只读分区的合并,file读取格式可能为data,android源码有lpunpack工具分解,提示无该命令可以先make lpunpack,
lpunpack super.img
查看服务器编译的system/vendor等sparse格式镜像时,如果挂载失败,可以尝试加只读参数才能来查看:
mount -o ro system_raw.img test;
该系列第二条线就是镜像分析,本博客主要以反汇编方式分析内核镜像。后面几个blog也会分析其他文件。
android刷机方式将分析nonAB的OTA包中system.dat转换、AB的OTA包中payload.bin的转换。
刷机相关的Android的安全中将分析vbmeta,以及avbtool使用。还有如何查看SELinux规则文件,单编SELinux规则文件。
正确的刷机观中分析gpt文件,NV备份。
多开机界面,多设备树叠加层中将分析splash.img和dtbo.img镜像。
如果还有需要解析的镜像,博友可以评论提。