【转载】boot.img与recovery.img的解包

来源:互联网 发布:互联网大数据时代 编辑:程序博客网 时间:2024/05/12 14:08
boot.img与recovery.img的结构很相似,都是kernel加上一个根文件系统。所以是可以用同一个工具(脚本)来分解,下面以分解boot.img为例分析如下:
1, cat /dev/block/mtdblock0 > /sdcard/boot.img
    不同的机型可能对应着不同的分区,需要先核实
2, split_bootimg.pl boot.img
    这个脚本是高手写的,可以用来解包boot.img或recovery.img,输出为kernel和ramdisk
 
3, gunzip -c boot.img-ramdisk.gz | cpio -i
     将解包出来的ramdisk部分再解出整个根文件系统
其中split_bootimg.pl的源码如下,能够分解出来是因为recovery.img的header有足够的信息,保证分解过程可以逆向的把它的根文件系统正确的解压出来。
[vb] view
plaincopy


    #!/usr/bin/perl  
    ######################################################################  
    #  
    #   File          : split_bootimg.pl  
    #   Author(s)     : William Enck <enck@cse.psu.edu>  
    #   Description   : Split appart an Android boot image created   
    #                   with mkbootimg. The format can be found in  
    #                   android-src/system/core/mkbootimg/bootimg.h  
    #  
    #                   Thanks to alansj on xda-developers.com for   
    #                   identifying the format in bootimg.h and   
    #                   describing initial instructions for splitting  
    #                   the boot.img file.  
    #  
    #   Last Modified : Tue Dec  2 23:36:25 EST 2008  
    #   By            : William Enck <enck@cse.psu.edu>  
    #  
    #   Copyright (c) 2008 William Enck  
    #  
    ######################################################################  
      
    use strict;  
    use warnings;  
     
    # Turn on print flushing  
    $|++;  
     
    ######################################################################  
    ## Global Variables and Constants  
      
    my $SCRIPT = __FILE__;  
    my $IMAGE_FN = undef;  
     
    # Constants (from bootimg.h)  
    use constant BOOT_MAGIC => 'ANDROID!';  
    use constant BOOT_MAGIC_SIZE => 8;  
    use constant BOOT_NAME_SIZE => 16;  
    use constant BOOT_ARGS_SIZE => 512;  
     
    # Unsigned integers are 4 bytes  
    use constant UNSIGNED_SIZE => 4;  
     
    # Parsed Values  
    my $PAGE_SIZE = undef;  
    my $KERNEL_SIZE = undef;  
    my $RAMDISK_SIZE = undef;  
    my $SECOND_SIZE = undef;  
     
    ######################################################################  
    ## Main Code  
      
    &parse_cmdline();  
    &parse_header($IMAGE_FN);  
      
    =format (from bootimg.h)  
    ** +-----------------+  
    ** | boot header     | 1 page  
    ** +-----------------+  
    ** | kernel          | n pages  
    ** +-----------------+  
    ** | ramdisk         | m pages  
    ** +-----------------+  
    ** | second stage    | o pages  
    ** +-----------------+  
    **  
    ** n = (kernel_size + page_size - 1) / page_size  
    ** m = (ramdisk_size + page_size - 1) / page_size  
    ** o = (second_size + page_size - 1) / page_size  
    =cut  
      
    my $n = int(($KERNEL_SIZE + $PAGE_SIZE - 1) / $PAGE_SIZE);  
    my $m = int(($RAMDISK_SIZE + $PAGE_SIZE - 1) / $PAGE_SIZE);  
    my $o = int(($SECOND_SIZE + $PAGE_SIZE - 1) / $PAGE_SIZE);  
      
    my $k_offset = $PAGE_SIZE;  
    my $r_offset = $k_offset + ($n * $PAGE_SIZE);  
    my $s_offset = $r_offset + ($m * $PAGE_SIZE);  
      
    (my $base = $IMAGE_FN) =~ s/.*\/(.*)$/$1/;  
    my $k_file = $base . "-kernel";  
    my $r_file = $base . "-ramdisk.gz";  
    my $s_file = $base . "-second.gz";  
     
    # The kernel is always there  
    print "Writing $k_file ...";  
    &dump_file($IMAGE_FN, $k_file, $k_offset, $KERNEL_SIZE);  
    print " complete.\n";  
     
    # The ramdisk is always there  
    print "Writing $r_file ...";  
    &dump_file($IMAGE_FN, $r_file, $r_offset, $RAMDISK_SIZE);  
    print " complete.\n";  
     
    # The Second stage bootloader is optional  
    unless ($SECOND_SIZE == 0) {  
        print "Writing $s_file ...";  
        &dump_file($IMAGE_FN, $s_file, $s_offset, $SECOND_SIZE);  
        print " complete.\n";  
    }  
         
    ######################################################################  
    ## Supporting Subroutines  
      
    =header_format (from bootimg.h)  
    struct boot_img_hdr  
    {  
        unsigned char magic[BOOT_MAGIC_SIZE];  
      
        unsigned kernel_size;  /* size in bytes */  
        unsigned kernel_addr;  /* physical load addr */  
      
        unsigned ramdisk_size; /* size in bytes */  
        unsigned ramdisk_addr; /* physical load addr */  
      
        unsigned second_size;  /* size in bytes */  
        unsigned second_addr;  /* physical load addr */  
      
        unsigned tags_addr;    /* physical addr for kernel tags */  
        unsigned page_size;    /* flash page size we assume */  
        unsigned unused[2];    /* future expansion: should be 0 */  
      
        unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */  
      
        unsigned char cmdline[BOOT_ARGS_SIZE];  
      
        unsigned id[8]; /* timestamp / checksum / sha1 / etc */  
    };  
    =cut  
    sub parse_header {  
        my ($fn) = @_;  

        my $buf = undef;  


      

0 0