Skip to content

Instantly share code, notes, and snippets.

@thefloweringash
Created March 13, 2013 16:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thefloweringash/5153679 to your computer and use it in GitHub Desktop.
Save thefloweringash/5153679 to your computer and use it in GitHub Desktop.
#!/bin/bash
# pull apart a bzImage compressed with xz (or gzip),
# and put it back together in a format that pv-grub understands
# useful when your kernel is compressed but your pv-grub doesn't
# recognise it, for example rescue64 from system rescue cd.
# the result is *not* a bootable kernel outside of pv-grub
# worksforme on OS X, YMMV
read_u8() {
dd if=$1 bs=1 skip=$(( $2 )) count=1 2>/dev/null | od -An -tu1 | grep -Eo '[0-9]+'
}
read_u32() {
dd if=$1 bs=1 skip=$(( $2 )) count=4 2>/dev/null | od -An -tu4 | grep -Eo '[0-9]+'
}
write_u32() {
perl -e "print pack 'L',$3" | dd of=$1 bs=1 seek=$(( $2 )) count=4 conv=notrunc
}
set -x
setup_size=$(read_u8 $1 0x1f1)
payload_offset=$(read_u32 $1 0x248)
payload_length=$(read_u32 $1 0x24c)
inner_pos=$(( ($setup_size + 1) * 512 ))
head -c $(( $inner_pos )) $1 > $1.header
tail -c+$(( $inner_pos + 1 )) $1 > $1.inner
head -c $(( $payload_offset )) $1.inner > $1.preamble
tail -c+$(( $payload_offset + 1 )) $1.inner | head -c $(( $payload_length )) > $1.payload
tail -c+$(( $payload_offset + $payload_length + 1)) $1.inner > $1.trailer
recons_sha=$(cat $1.header $1.preamble $1.payload $1.trailer | openssl sha1)
expected_ssh=$(openssl sha1 < $1)
if [ $recons_sha != $expected_ssh ]; then
echo "INVALID DECOMPOSITION"
fi
if file $1.payload | grep -q 'xz compressed data'; then
head -c $(($payload_length - 4)) $1.payload | unxz > $1.payload.extracted
elif file $1.payload | grep -q 'gzip compressed data'; then
gunzip < $1.payload > $1.payload.extracted
fi
gzip < $1.payload.extracted > $1.payload.gz
payload_expand_len=$(stat -f %z $1.payload.extracted)
cat $1.header $1.payload.gz > $1.gz
write_u32 $1.gz 0x248 0
write_u32 $1.gz 0x24c $(( $(stat -f %z $1.payload.gz) ))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment