Hacking RAM disks
来源:互联网 发布:软件测试培训ppt 编辑:程序博客网 时间:2024/06/05 05:42
生成包命令:
make_initramfs temp
hkbdm@ubuntu:~/temp/myjb42$ pwd
/home/hkbdm/temp/myjb42
hkbdm@ubuntu:~/temp/myjb42$ pwd
/home/hkbdm/temp/myjb42
./make_initramfs temp infile_name
To boot Linux, you only need two things:
Many O/S distributions, including Android, use a small RAM disk as the initial root filesystem and theinit program will enumerate the devices and typically mount other filesystems.
In previous kernel versions, the RAM disks were typically ext2 filesystems, but the current convention is to use the initramfs file format, which is essentially a cpio archive.
To speed the boot, the cpio archive is typically gzipped and when used with the U-Boot boot loader, wrapped with a U-Boot header containing a CRC by the mkimage tool.
In the course of working with an O/S that uses a RAM disk, you will often want to extract the content at least to examine it. You may also want to modify some of the contents and re-create it, but you can’t do this directly.
In this post, I’ll walk through the process of doing just that.
I’ll use the file uramdisk.img from the SD card tree of the images provided in the Freescale Android release R13.4-Beta release.release.
If you run file on the image, you’ll see it reported as a PPC/U-Boot image file:That’s because mkimage adds 64 bytes of header. We can use dd to strip it like so:As you can see, after stripping the 64-byte header, file identifies the image as a gzipped data.
If we unzip it, we’ll see that it’s a cpio archive and we can list its content:
- The Linux kernel itself, and
- A root filesystem with an init program of some sort.
Many O/S distributions, including Android, use a small RAM disk as the initial root filesystem and theinit program will enumerate the devices and typically mount other filesystems.
In previous kernel versions, the RAM disks were typically ext2 filesystems, but the current convention is to use the initramfs file format, which is essentially a cpio archive.
To speed the boot, the cpio archive is typically gzipped and when used with the U-Boot boot loader, wrapped with a U-Boot header containing a CRC by the mkimage tool.
In the course of working with an O/S that uses a RAM disk, you will often want to extract the content at least to examine it. You may also want to modify some of the contents and re-create it, but you can’t do this directly.
In this post, I’ll walk through the process of doing just that.
I’ll use the file uramdisk.img from the SD card tree of the images provided in the Freescale Android release R13.4-Beta release.release.
If you run file on the image, you’ll see it reported as a PPC/U-Boot image file:
1
2
~/$file uramdisk.img
uramdisk.img: u-boot/PPCBootimage
1
2
3
4
5
6
7
8
9
~$dd bs=1 skip=64if=uramdisk.img of=uramdisk-no-header.img
167778+0 recordsin
167778+0 records out
167778 bytes (168 kB) copied, 0.91557 s, 183 kB/s
~$ls -l uramdisk*
-rw-r--r-- 1 ericn ericn 167842 2012-09-07 12:21 uramdisk.img
-rw-r--r-- 1 ericn gitosis 167778 2012-09-07 12:25 uramdisk-no-header.img
~$file uramdisk-no-header.img
uramdisk-no-header.img:gzipcompressed data, from Unix
If we unzip it, we’ll see that it’s a cpio archive and we can list its content:
~$ zcat uramdisk-no-header.img > uramdisk-uncompressed.img~$ file uramdisk-uncompressed.img uramdisk-uncompressed.img: ASCII cpio archive (SVR4 with no CRC)~$ cpio -t < uramdisk-uncompressed.imgdatadefault.propdevinitinit.freescale.rcinit.freescale.usb.rcinit.goldfish.rcinit.rcprocsbinsbin/adbdsbin/ueventdsyssystemueventd.freescale.rcueventd.goldfish.rcueventd.rc551 blocks
You can extract them like so:
~$ mkdir myramdiskbash: ../uramdisk-uncompressed.img: No such file or directory~$ cd myramdisk/~/myramdisk$ sudo cpio -i --no-absolute-filenames < ../uramdisk-uncompressed.img551 blocks~/myramdisk$ lsdata init.freescale.rc proc ueventd.freescale.rcdefault.prop init.freescale.usb.rc sbin ueventd.goldfish.rcdev init.goldfish.rc sys ueventd.rcinit init.rc system~/myramdisk$ tail default.prop ## ADDITIONAL_DEFAULT_PROPERTIES#ro.secure=1ro.allow.mock.location=0ro.debuggable=0persist.sys.usb.config=mtp
If you edit that file, you can re-create the RAM disk using these steps:
~/myramdisk$ shopt -s dotglob~/myramdisk$ sudo find . | sudo cpio -H newc -o | gzip > ../uramdisk.cpio.gz551 blocks~/myramdisk$ mkimage -A arm -O linux -T ramdisk -n "Initial Ram Disk" \ -d ../uramdisk.cpio.gz ../uramdisk.img.newImage Name: Initial Ram DiskCreated: Fri Sep 7 12:47:00 2012Image Type: ARM Linux RAMDisk Image (gzip compressed)Data Size: 169051 Bytes = 165.09 kB = 0.16 MBLoad Address: 0x00000000Entry Point: 0x00000000
The last command is the mkimage U-Boot tool, which adds the 64-byte U-Boot header back onto the output.
I hoped this quick note helps you understand the basics of a RAM disk. We'll likely make use of this in future posts, and want it around for reference.
===========划分boot。img为内核,和文件系统的脚本============================================================
#!/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 The Pennsylvania State University# Systems and Internet Infrastructure Security Laboratory## Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at ## http://www.apache.org/licenses/LICENSE-2.0 ## Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License. #######################################################################use strict;use warnings;# Turn on print flushing$|++;######################################################################## Global Variables and Constantsmy $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 bytesuse constant UNSIGNED_SIZE => 4;# Parsed Valuesmy $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=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 thereprint "Writing $k_file ...";&dump_file($IMAGE_FN, $k_file, $k_offset, $KERNEL_SIZE);print " complete.\n";# The ramdisk is always thereprint "Writing $r_file ...";&dump_file($IMAGE_FN, $r_file, $r_offset, $RAMDISK_SIZE);print " complete.\n";# The Second stage bootloader is optionalunless ($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 */};=cutsub parse_header { my ($fn) = @_; my $buf = undef; open INF, $fn or die "Could not open $fn: $!\n"; binmode INF; # Read the Magic read(INF, $buf, BOOT_MAGIC_SIZE); unless ($buf eq 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 close INF; # 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;}sub dump_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"; binmode INF; binmode OUTF; 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"; close INF; close OUTF;}######################################################################## Configuration Subroutinessub parse_cmdline { unless ($#ARGV == 0) {die "Usage: $SCRIPT boot.img\n"; } $IMAGE_FN = $ARGV[0];}
------------------------------------- extract_initramfs -------------------------------------------------------使用方法:../extract_initramfs ur uramdisk.img temp ----------
#!/bin/shif [ $# -ne 2 ]; thenecho "Usage: $0 inFile outDir"exit -1 ;fiecho "input file: $1"echo "output dir: $2"if ! [ -f $1 ]; thenecho "$1 not found"exit -1 ;fiif [ -e $2 ]; thenecho "$2 exists" ;exit -1 ;fiinfile="$1"tmpfile=tmp_tempfiledd bs=1 skip=64 if=$infile of=uramdisk-no-header.imgzcat uramdisk-no-header.img > uramdisk-uncompressed.imgfile uramdisk-uncompressed.imgcpio -t < uramdisk-uncompressed.imgmkdir -p $2cd $2sudo cpio -i --no-absolute-filenames < ../uramdisk-uncompressed.imgecho "contents of $infile copied to $2"#rm -rf $tmpfile*
----------------------------------make_initramfs ------使用方法:./make_initramfs --------------- sudo ./make_initramfs temp/ ur.dd-----------------------------------------------
#!/bin/shif [ $# -ne 2 ]; thenecho "Usage: $0 inDir outFile"exit -1 ;fiecho "input dir: $1"echo "output file: $2"if ! [ -d $1 ]; thenecho "missing or invalid directory $1"exit -1 ;fiif [ -e $2 ]; thenecho "$2 exists" ;exit -1 ;fitouch $2 ;outfile=$2echo "output to $outfile"origdir=`pwd`cd $1 sudo find . | sudo cpio -H newc -o | gzip > ../$outfile.gzcd $origdirmkimage -A arm -O linux -T ramdisk -n "Initial Ram Disk" -d $outfile.gz $outfilerm -f $outfile.gzecho "$outfile created"
- Hacking RAM disks
- initramfs,一个新initial RAM disks模型
- initramfs 簡介,一個新的 initial RAM disks 的模型
- Introducing initramfs, a new model for initial RAM disks
- initramfs 简介,一个新的 initial RAM disks 模型
- Introducing initramfs, a new model for initial RAM disks
- initramfs 简介,一个新的 initial RAM disks 模型
- initramfs 简介,一个新的 initial RAM disks 模型
- initramfs 简介,一个新的 initial RAM disks 模型
- Introducing initramfs, a new model for initial RAM disks .
- initramfs 简介,一个新的 initial RAM disks 模型
- Introducing initramfs, a new model for initial RAM disks
- Introducing initramfs, a new model for initial RAM disks
- initramfs 简介,一个新的 initial RAM disks 模型
- initramfs 简介,一个新的 initial RAM disks 模型
- initramfs 简介,一个新的 initial RAM disks 模型
- Disks
- hacking
- Ubuntu 软件包管理详解
- Hadoop扫盲贴
- [HDU 3065]病毒侵袭持续中[AC自动机][模板题]
- UNIX网络编程卷二 笔记 读写锁和记录上锁
- java Web如何安装
- Hacking RAM disks
- UNIX网络编程卷二 笔记 Posix信号量
- 安卓学习之SQLite相关学习指南
- 使用google drive或者dropbox来搭载git仓库
- android 使用ViewFlow实现左右滑动
- Ubuntu下APACHE HTTPS安装和配置
- Oracle使用RMAN恢复控制文件实例
- 掌握好习惯才能掌握商战主动权
- Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead. Please use Android Tools