forked from jotaki/Extract-Kernel-Initramfs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unpack-initramfs
executable file
·198 lines (161 loc) · 7.08 KB
/
unpack-initramfs
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/bin/bash
# This is an update version of the script found at
# http://forum.xda-developers.com/wiki/index.php?title=Extract_initramfs_from_zImage
#
# The problem with that script is that the gzip magic number occasionally occur
# naturally, meaning that some non-compressed files get uncompressed.
DEBUG=
TEMP_DIR=/tmp
KERNEL_FILE=kernel
KERNEL_GZIP_FILE=kernel.gz
INITRAMFS_FILE=initramfs.cpio
INITRAMFS_DIR=initramfs_root
# DO NOT MODIFY BELOW THIS LINE
[ -z $1 ] && exit 1 || zImage=$1
[ ! -e $1 ] && exit 1
#GET CURRENT DIR
CURRENT_DIR=`pwd`
function pre_clean()
{
[ -z $DEBUG ] || echo "-D- Function: pre_clean()"
[ -e $INITRAMFS_FILE ] && ( [ -z $DEBUG ] || echo "-D- Deleting $INITRAMFS_FILE"; rm -f $INITRAMFS_FILE )
[ -e $INITRAMFS_DIR ] && ( [ -z $DEBUG ] || echo "-D- Deleting $INITRAMFS_DIR"; rm -rf $INITRAMFS_DIR )
[ -z $DEBUG ] || echo
}
function ungzip_kernel()
{
#========================================================
# find start of gziped kernel object in the zImage file:
#========================================================
[ -z $DEBUG ] || echo "-D- Function: ungzip_kernel()"
pos=`grep -P -a -b -m 1 --only-matching '\x1F\x8B\x08' $zImage | cut -f 1 -d :`
echo "-I- Extracting gzip'd kernel image from file: $zImage (start = $pos)"
if [ ! -z $pos ]; then
dd if=$zImage of=$TEMP_DIR/$KERNEL_GZIP_FILE bs=1 skip=$pos 2>/dev/null >/dev/null
gunzip -qf $TEMP_DIR/$KERNEL_GZIP_FILE
else
echo "-E- Compressed kernel image not found"; exit 1
fi
[ -z $DEBUG ] || echo
}
function search_cpio()
{
#========================================================
# Determine cpio compression type:
#========================================================
[ -z $DEBUG ] || echo "-D- Function: search_cpio()"
for x in gzip bzip lzma none; do
case $x in
bzip)
csig='\x{31}\x{41}\x{59}\x{26}\x{53}\x{59}'
ucmd='bunzip2 -q'
fext='.bz2'
;;
gzip)
csig='\x1F\x8B\x08'
ucmd='gunzip -q'
fext='.gz'
;;
lzma)
csig='\x{5D}\x{00}\x..\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}'
ucmd='unlzma -q'
fext='.lzma'
;;
none)
csig='070701'
ucmd=
fext=
;;
esac
#========================================================================
# Search for compressed cpio archive
#========================================================================
search=`grep -P -a -b -m 1 --only-matching $csig $TEMP_DIR/$KERNEL_FILE | cut -f 1 -d : | head -1`
pos=${search:-0}
if [ ${pos} -gt 0 ]; then
if [ ${pos} -le ${cpio_compressed_start:-0} ] || [ -z $cpio_compressed_start ];then
cpio_compressed_start=$pos
compression_name=$x
compression_signature=$csig
uncompress_cmd=$ucmd
file_ext=$fext
[ -z $DEBUG ] || echo "-D- Checking for compression type: $compression_name | signature: $compression_signature | in file: $TEMP_DIR/$KERNEL_FILE | offset = $pos"
fi
fi
done
[ $compression_name = "bzip" ] && cpio_compressed_start=$((cpio_compressed_start - 4))
echo "-I- CPIO compression type detected = $compression_name | offset = $cpio_compressed_start"
[ -z $DEBUG ] || echo
}
function extract_cpio()
{
[ -z $DEBUG ] || echo "-D- Function: extract_cpio()"
if [ ! $compression_name = "none" ]; then
echo "-I- Extracting $compression_name'd compressed CPIO image from kernel image (offset = $cpio_compressed_start)"
[ -z $DEBUG ] || echo "-D- dd if=$TEMP_DIR/$KERNEL_FILE of=$TEMP_DIR/$INITRAMFS_FILE$file_ext bs=1 skip=$cpio_compressed_start; $uncompress_cmd $TEMP_DIR/$INITRAMFS_FILE$file_ext"
dd if=$TEMP_DIR/$KERNEL_FILE of=$TEMP_DIR/$INITRAMFS_FILE$file_ext bs=1 skip=$cpio_compressed_start 2>/dev/null >/dev/null
$uncompress_cmd -q $TEMP_DIR/$INITRAMFS_FILE$file_ext
else
echo "-I- Extracting non-compressed CPIO image from kernel image (offset = $cpio_compressed_start)"
[ -z $DEBUG ] || echo "-D- dd if=$TEMP_DIR/$KERNEL_FILE of=$TEMP_DIR/${INITRAMFS_FILE}${file_ext} bs=1 skip=$cpio_compressed_start 2>/dev/null >/dev/null"
dd if=$TEMP_DIR/$KERNEL_FILE of=$TEMP_DIR/${INITRAMFS_FILE}${file_ext} bs=1 skip=$cpio_compressed_start 2>/dev/null >/dev/null
fi
[ -z $DEBUG ] || echo
}
function uncompress_cpio()
{
#==========================================================================
# find start and end of the "cpio" initramfs image inside the kernel object:
# ASCII cpio header starts with '070701'
# The end of the cpio archive is marked with an empty file named TRAILER!!!
#==========================================================================
[ -z $DEBUG ] || echo "-D- Function: uncompress_cpio()"
if [ ! $compress_type = "none" ]; then
start=`grep -a -b -m 1 --only-matching '070701' $TEMP_DIR/$INITRAMFS_FILE | head -1 | cut -f 1 -d :`
end=`grep -a -b -m 1 --only-matching 'TRAILER!!!' $TEMP_DIR/$INITRAMFS_FILE | head -1 | cut -f 1 -d :`
if [ ! -z $start ] || [ ! -z $end ]; then
#11 bytes = length of TRAILER!!! zero terminated string, fixes premature end of file warning in CPIO
end=$((end + 14))
[ -z $DEBUG ] || echo "-D- Kernel start = $start"
[ -z $DEBUG ] || echo "-D- Kernel end = $end"
count=$((end - start))
if (($count < 0)); then
echo "-E- Couldn't match start/end of the initramfs image."
exit 1
fi
echo "-I- Extracting initramfs image from file: $inputfile (start = $start, end = $end)"
dd if=$TEMP_DIR/$INITRAMFS_FILE of=$CURRENT_DIR/$INITRAMFS_FILE bs=1 skip=$start count=$count 2>/dev/null >/dev/null
INITRAMFS_FILE=$CURRENT_DIR/$INITRAMFS_FILE
else
echo "-E- No CPIO image found in $inputfile."
fi
else
echo "-I- CPIO already uncompressed."
fi
[ -z $DEBUG ] || echo
}
function expand_cpio_archive()
{
[ -z $DEBUG ] || echo "-D- Function: expand_cpio_archive()"
echo "-I- Expanding CPIO archive: $INITRAMFS_FILE to $INITRAMFS_DIR."
if [ -e $TEMP_DIR/$INITRAMFS_FILE ]; then
mkdir $INITRAMFS_DIR
cd $INITRAMFS_DIR
cpio --quiet -i --make-directories --preserve-modification-time --no-absolute-filenames -F $TEMP_DIR/$INITRAMFS_FILE 2>/dev/null
fi
[ -z $DEBUG ] || echo
}
function clean_up()
{
[ -z $DEBUG ] || echo "-D- Deleting $TEMP_DIR/$KERNEL_FILE"; rm -f $TEMP_DIR/$KERNEL_FILE
[ -z $DEBUG ] || echo "-D- Deleting $TEMP_DIR/$INITRAMFS_FILE"; rm -f $TEMP_DIR/$INITRAMFS_FILE
[ -z $DEBUG ] || echo "-D- Deleting $TEMP_DIR/$INITRAMFS_FILE$file_ext"; rm -f $TEMP_DIR/$INITRAMFS_FILE$file_ext
}
reset
pre_clean
ungzip_kernel
search_cpio
extract_cpio
uncompress_cpio
expand_cpio_archive
clean_up