binwalk 提取bootimg_boot.img、ramdisk.img解包、打包

这是一个Perl脚本,用于解析由mkbootimg创建的Android boot图像。它遵循bootimg.h中定义的格式,将boot.img拆分为kernel、ramdisk(gzip压缩)和second stage(如果存在,也为gzip压缩)文件。脚本读取boot.img的头部信息,包括页大小、内核大小、ramdisk大小和second stage大小,并相应地写入单独的文件。
摘要由CSDN通过智能技术生成

#!/usr/bin/perl

######################################################################

#

# File : split_bootimg.pl

# Author(s) : William Enck

# 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

#

# Copyright (c) 2008 William Enck

#

######################################################################

usestrict;usewarnings;#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 | 1page** +-----------------+

** | 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=cutmy $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 */};=cutsubparse_header {my ($fn) = @_;my $buf = undef;open INF, $fn or die "Could not open $fn: $!\n";binmodeINF;#Read the Magic

read(INF, $buf,BOOT_MAGIC_SIZE);unless ($bufeq BOOT_MAGIC) {die "Android Magic not found in $fn. Giving up.\n";

}#Read kernel size and address (assume little-endian)

read(INF, $buf, UNSIGNED_SIZE * 2);my ($k_size, $k_addr) = unpack("VV", $buf);#Read ramdisk size and address (assume little-endian)

read(INF, $buf, UNSIGNED_SIZE * 2);my ($r_size, $r_addr) = unpack("VV", $buf);#Read second size and address (assume little-endian)

read(INF, $buf, UNSIGNED_SIZE * 2);my ($s_size, $s_addr) = unpack("VV", $buf);#Ignore tags_addr

read(INF, $buf,UNSIGNED_SIZE);#get the page size (assume little-endian)

read(INF, $buf,UNSIGNED_SIZE);my ($p_size) = unpack("V", $buf);#Ignore unused

read(INF, $buf, UNSIGNED_SIZE * 2);#Read the name (board name)

read(INF, $buf,BOOT_NAME_SIZE);my $name = $buf;#Read the command line

read(INF, $buf,BOOT_ARGS_SIZE);my $cmdline = $buf;#Ignore the id

read(INF, $buf, UNSIGNED_SIZE * 8);#Close the file

closeINF;#Print important values

printf "Page size: %d (0x%08x)\n", $p_size, $p_size;printf "Kernel size: %d (0x%08x)\n", $k_size, $k_size;printf "Ramdisk size: %d (0x%08x)\n", $r_size, $r_size;printf "Second size: %d (0x%08x)\n", $s_size, $s_size;printf "Board name: $name\n";printf "Command line: $cmdline\n";#Save the values

$PAGE_SIZE = $p_size;$KERNEL_SIZE = $k_size;$RAMDISK_SIZE = $r_size;$SECOND_SIZE = $s_size;

}subdump_file {my ($infn, $outfn, $offset, $size) = @_;my $buf = undef;open INF, $infn or die "Could not open $infn: $!\n";open OUTF, ">$outfn" or die "Could not open $outfn: $!\n";binmodeINF;binmodeOUTF;seek(INF, $offset, 0) or die "Could not seek in $infn: $!\n";read(INF, $buf, $size) or die "Could not read $infn: $!\n";print OUTF $buf or die "Could not write $outfn: $!\n";closeINF;closeOUTF;

}######################################################################

## Configuration Subroutines

subparse_cmdline {unless ($#ARGV == 0) {

die "Usage: $SCRIPT boot.img\n";

}$IMAGE_FN = $ARGV[0];

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值