首先需要搞到boot.img,网络上流传的方法是通过/proc/mtd 在获取需要的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 > ./adb shell > su > cat /proc/ mtddev: size erasesize namemtd0: 00700000 00020000 "boot" mtd1: 07 c20000 00020000 "cache" mtd2: 00700000 00020000 "recovery" mtd3: 00140000 00020000 "splash" mtd4: 00700000 00020000 "FOTA_STO" mtd5: 09e80000 00020000 "system" mtd6: 0 a4e0000 00020000 "userdata" mtd7: 00080000 00020000 "misc" mtd8: 00180000 00020000 "persist"
但是在Nexus4, Android 4.4.4 已经找不到这个文件了
1 2 3 > cat /proc /mtdcat: /proc /mtd: No such file or directory
但是还是有方法可以获取到需要的信息。
1 2 3 4 5 6 > mount..... /dev/block/platform/msm_sdcc.1/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0 /dev/block/platform/msm_sdcc.1/by-name/cache /cache ext4 rw,seclabel,nosuid,nodev,noatime,data=ordered 0 0 .....
可以看到大致上面的输出(上面的输出省略了部分内容),从输出中可以看出 /dev/block/platform/msm_sdcc.1/by-name 是一个比较有意思的路径,有by-name 的信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 > ls /dev/block /platform/msm_sdcc.1 /by -name /lrwxrwxrwx root root 2014-06-30 20:50 DDR -> /dev/block /mmcblk0p24lrwxrwxrwx root root 2014-06-30 20:50 aboot -> /dev/block /mmcblk0p12lrwxrwxrwx root root 2014-06-30 20:50 abootb -> /dev/block /mmcblk0p15lrwxrwxrwx root root 2014-06-30 20:50 boot -> /dev/block /mmcblk0p6lrwxrwxrwx root root 2014-06-30 20:50 cache -> /dev/block /mmcblk0p22lrwxrwxrwx root root 2014-06-30 20:50 grow -> /dev/block /mmcblk0p25lrwxrwxrwx root root 2014-06-30 20:50 m9kefs1 -> /dev/block /mmcblk0p8lrwxrwxrwx root root 2014-06-30 20:50 m9kefs2 -> /dev/block /mmcblk0p9lrwxrwxrwx root root 2014-06-30 20:50 m9kefs3 -> /dev/block /mmcblk0p10lrwxrwxrwx root root 2014-06-30 20:50 metadata -> /dev/block /mmcblk0p18lrwxrwxrwx root root 2014-06-30 20:50 misc -> /dev/block /mmcblk0p19lrwxrwxrwx root root 2014-06-30 20:50 modem -> /dev/block /mmcblk0p1lrwxrwxrwx root root 2014-06-30 20:50 persist -> /dev/block /mmcblk0p20lrwxrwxrwx root root 2014-06-30 20:50 recovery -> /dev/block /mmcblk0p7lrwxrwxrwx root root 2014-06-30 20:50 rpm -> /dev/block /mmcblk0p11lrwxrwxrwx root root 2014-06-30 20:50 rpmb -> /dev/block /mmcblk0p16lrwxrwxrwx root root 2014-06-30 20:50 sbl1 -> /dev/block /mmcblk0p2lrwxrwxrwx root root 2014-06-30 20:50 sbl2 -> /dev/block /mmcblk0p3lrwxrwxrwx root root 2014-06-30 20:50 sbl2b -> /dev/block /mmcblk0p13lrwxrwxrwx root root 2014-06-30 20:50 sbl3 -> /dev/block /mmcblk0p4lrwxrwxrwx root root 2014-06-30 20:50 sbl3b -> /dev/block /mmcblk0p14lrwxrwxrwx root root 2014-06-30 20:50 system -> /dev/block /mmcblk0p21lrwxrwxrwx root root 2014-06-30 20:50 tz -> /dev/block /mmcblk0p5lrwxrwxrwx root root 2014-06-30 20:50 tzb -> /dev/block /mmcblk0p17lrwxrwxrwx root root 2014-06-30 20:50 userdata -> /dev/block /mmcblk0p23
哈哈,一清二楚。
1 2 3 4 5 6 7 > dd if =/dev/block/mmcblk0p6 of=/sdcard/boot.img bs=4096 5632+0 records in 5632+0 records out 23068672 bytes transferred in 2.398 secs (9619963 bytes/sec) >./adb pull /sdcard/boot.img /tmp/boot.img 4270 KB/s (23068672 bytes in 5.275s)
boot.img 主要由两部分组成,kernel 和 ramdisk,下面使用010editor来写一个模版,解析boot.img。从Android的源码可以知道boot.img的结构 app/aboot/bootimg.h
1 2 3 4 5 6 7 8 9 10 11 +-----------------+ | boot header | 1 page +-----------------+ | kernel | n pages +-----------------+ | ramdisk | m pages +-----------------+ | second stage | o pages +-----------------+ | device tree | p pages +-----------------+
boot header 的结构定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 struct boot_img_hdr { unsigned char magic[BOOT_MAGIC_SIZE]; unsigned kernel_size; unsigned kernel_addr; unsigned ramdisk_size; unsigned ramdisk_addr; unsigned second_size; unsigned second_addr; unsigned tags_addr; unsigned page_size; unsigned dt_size; unsigned unused; unsigned char name[BOOT_NAME_SIZE]; unsigned char cmdline[BOOT_ARGS_SIZE]; unsigned id[8 ]; };
010editor 模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #define BOOT_MAGIC_SIZE 8 #define BOOT_NAME_SIZE 16 #define BOOT_ARGS_SIZE 512 typedef struct boot_img_hdr { char magic[BOOT_MAGIC_SIZE]; uint kernel_size; uint kernel_addr; uint ramdisk_size; uint ramdisk_addr; uint second_size; uint second_addr; uint tags_addr; uint page_size; uint dt_size; uint unused; ubyte name[BOOT_NAME_SIZE]; ubyte cmdline[BOOT_ARGS_SIZE]; uint id[8 ]; }BOOT_IMG_HDR;typedef struct boot_hdr { BOOT_IMG_HDR header; ubyte unused[header.page_size - sizeof (header)]; }HEADER; LittleEndian(); HEADER header_section; local uint page_size = header_section.header.page_size; local uint kernel_size = header_section.header.kernel_size; local uint ramdisk_size = header_section.header.ramdisk_size; local uint second_size = header_section.header.second_size; Printf("page_size: %x\nkernel_size: %x\nramdisk_size: %x\nsecond_size: %x\n" , page_size, kernel_size, ramdisk_size, second_size); local uint n = (kernel_size + page_size - 1 ) / page_size; local uint m = (ramdisk_size + page_size - 1 ) / page_size; local uint o = (second_size + page_size - 1 ) / page_size;typedef struct kernel { ubyte kernel_data[kernel_size]; ubyte unused[n * page_size - kernel_size]; }KERNEL; KERNEL kernel_section;typedef struct ramdisk { ubyte ramdisk_data[ramdisk_size]; ubyte unused[m * page_size - ramdisk_size]; }RAMDISK; RAMDISK ramdisk_section;typedef struct second { ubyte second_data[second_size]; ubyte unused[o * page_size - second_size]; }SECOND; SECOND second_section;