From c2e4723f83cb7bb898feb2ca9cf385141720440f Mon Sep 17 00:00:00 2001 From: HappyZ Date: Wed, 25 Jul 2018 18:54:42 -0700 Subject: [PATCH] unpacker --- fw_updater_packer_unpacker/.gitignore | 4 +- .../start_eufwupdater.sh | 128 ++++++++++++++++++ fw_updater_packer_unpacker/unpacker.sh | 125 +++++++++++++++++ 3 files changed, 255 insertions(+), 2 deletions(-) create mode 100755 fw_updater_packer_unpacker/start_eufwupdater.sh create mode 100755 fw_updater_packer_unpacker/unpacker.sh diff --git a/fw_updater_packer_unpacker/.gitignore b/fw_updater_packer_unpacker/.gitignore index 425855a..aa041d6 100644 --- a/fw_updater_packer_unpacker/.gitignore +++ b/fw_updater_packer_unpacker/.gitignore @@ -1,4 +1,4 @@ *.pkg test/ -key1 -key2 \ No newline at end of file +key.private +key.pub \ No newline at end of file diff --git a/fw_updater_packer_unpacker/start_eufwupdater.sh b/fw_updater_packer_unpacker/start_eufwupdater.sh new file mode 100755 index 0000000..a62bdb1 --- /dev/null +++ b/fw_updater_packer_unpacker/start_eufwupdater.sh @@ -0,0 +1,128 @@ +#!/bin/sh + +# $1 update package +# $2 output directory +# $3 pub key to verify sig +# $4 pri key to decrypt data key + +SIG_FILE="$2/sig.dat" +AES256_KEY="$2/aes256.key" +IV="$2/iv" + +ANIM_SIG_FILE="$2/anim_sig.dat" +ANIM_PID=0 + + +epd_cmd() +{ + epd_fb_test $@ >/dev/null 2>&1 +} + + +######################################## +# file header check +######################################## +HEAD_MARK=`head -c 4 $1` +if [ $HEAD_MARK != "DPUP" ] +then + echo "Invalid file" + exit 0 +fi + + +DATA_OFFSET=`dd if=$1 bs=4 skip=1 count=1 2>/dev/null | od -A n -t d4 -v` +BODY_SIZE=`dd if=$1 bs=4 skip=2 count=1 2>/dev/null | od -A n -t d4 -v` +######################################## +# start animation for package check +######################################## +ANIM_HEADER_OFFSET=$(( $DATA_OFFSET + $BODY_SIZE )) +if [ -z "$ANIM_HEADER_OFFSET" ] +then + ANIM_HEADER_OFFSET=0 +fi +ANIM_HEADER_SIZE=`dd if=$1 bs=1 skip=$ANIM_HEADER_OFFSET count=4 2>/dev/null | od -A n -t d4 -v` +if [ -z "$ANIM_HEADER_SIZE" ] +then + ANIM_HEADER_SIZE=0 +fi +ANIM_ARCH_SIZE=`dd if=$1 bs=1 skip=$(($ANIM_HEADER_OFFSET + 4)) count=4 2>/dev/null | od -A n -t d4 -v` +ANIM_SIG_SIZE=`dd if=$1 bs=1 skip=$(($ANIM_HEADER_OFFSET + 8)) count=4 2>/dev/null | od -A n -t d4 -v` +dd if=$1 of=$ANIM_SIG_FILE bs=1 skip=$(($ANIM_HEADER_OFFSET + 12)) count=$(($ANIM_SIG_SIZE)) 2>/dev/null +ANIM_ARCH_OFFSET=$(($ANIM_HEADER_OFFSET + $ANIM_HEADER_SIZE)) +dd if=$1 bs=$ANIM_ARCH_OFFSET skip=1 2>/dev/null | head -c $(($ANIM_ARCH_SIZE)) | openssl dgst -sha256 -verify $3 -signature $ANIM_SIG_FILE 1>/dev/null +if [ $? -eq 0 ] +then + start_prepare_animation.sh $1 $2 $ANIM_ARCH_OFFSET $(($ANIM_ARCH_SIZE)) & + ANIM_PID=$! +fi + + + +######################################## +# extract sig +######################################## +SIG_SIZE=`dd if=$1 bs=4 skip=4 count=1 2>/dev/null | od -A n -t d4 -v` +dd if=$1 of=$SIG_FILE bs=1 skip=20 count=$(($SIG_SIZE)) 2>/dev/null + + +######################################## +# verify sig +######################################## +dd if=$1 bs=$(($DATA_OFFSET)) skip=1 2>/dev/null | head -c $(($BODY_SIZE)) | openssl dgst -sha256 -verify $3 -signature $SIG_FILE 1>/dev/null +if [ $? -ne 0 ] +then + echo "Verify failed." + exit 0 +fi + + +######################################## +# decrypt data key +######################################## +ENC_KEY_OFFSET=$((20 + $SIG_SIZE)) +PAD_SIZE=$((16 - $SIG_SIZE % 16 )) +if [ $PAD_SIZE -ne 16 ] +then + ENC_KEY_OFFSET=$(( $ENC_KEY_OFFSET + $PAD_SIZE )) +fi + +ENC_KEY_SIZE=`dd if=$1 bs=1 skip=${ENC_KEY_OFFSET} count=4 2>/dev/null | od -A n -t d4 -v` +ENC_KEY_OFFSET=$(( $ENC_KEY_OFFSET + 4 )) +dd if=$1 bs=1 skip=${ENC_KEY_OFFSET} count=$(($ENC_KEY_SIZE)) 2>/dev/null | openssl rsautl -decrypt -inkey $4 > ${AES256_KEY} + + +######################################## +# extract iv +######################################## +IV_OFFSET=$(($ENC_KEY_OFFSET + $ENC_KEY_SIZE)) +dd if=$1 of=$IV bs=1 skip=${IV_OFFSET} count=32 2>/dev/null + + +######################################## +# decrypt data and extract directory tree +######################################## +dd if=$1 bs=$(($DATA_OFFSET)) skip=1 2>/dev/null | head -c $(($BODY_SIZE)) | openssl enc -d -aes-256-cbc -K `cat ${AES256_KEY}` -iv `cat ${IV}` | tar -xz -C $2 + + +######################################## +# stop animation for package check +######################################## +if [ $ANIM_PID -ne 0 ] +then + kill $ANIM_PID + epd_cmd gray DU PART 0 + epd_cmd wait 300000 +fi + + +######################################## +# start updater +######################################## +if [ -f ${2}/FwUpdater/eufwupdater.sh ] +then + ${2}/FwUpdater/eufwupdater.sh + exit $? # tentative +else + echo "Invalid archive (No updater script)." + exit 0 +fi \ No newline at end of file diff --git a/fw_updater_packer_unpacker/unpacker.sh b/fw_updater_packer_unpacker/unpacker.sh new file mode 100755 index 0000000..f4c895a --- /dev/null +++ b/fw_updater_packer_unpacker/unpacker.sh @@ -0,0 +1,125 @@ +#!/bin/sh + +# Unpacker for DPT pkg +# HappyZ +# Thanks to anonymous contributer somewhere on earth + +# PKG FILE FORMAT +# byte 1--4: DPUP - file recognizer +# byte 5--8: data offset location A +# byte 9--12: total data content size D +# byte 13--16: nothing +# byte 17--20: sigfile size B +# byte 21--(20+B): sigfile data +# byte (21+(-B%16)%16)--(25+(-B%16)%16): encrypted data aes key size (BE) C +# byte (+1)--(+C): encrypted data aes key bytes +# byte (+1)--(+32): initial vector --- up till now bytes shall equal to A +# byte (A+1)--(A+D): encrypted data +# byte (+1)--(+4): animation header size E +# byte (+1)--(+4): animation data size F +# byte (+1)--(+4): animation sigfile size G +# byte (+1)--(+(-G%16)%16): animation sigfile --- here bytes shall be A+D+E +# byte (A+D+E+1)--(A+D+E+F): animation data + +# zipped data format +# FwUpdater +# |- boot.img +# |- boot.img.md5 +# |- system.img +# |- system.img.md5 +# |- eufwupdater.sh +# |- ... + + +# params +PKGFILE=$1 # pkg file +OUTDIR=$2 # output folder +SHA256KEY="./key.pub" +DATAKEY_D="./key.private" + +# predefined outputs +SIGFILE="$OUTDIR/signature" +AESFILE="$OUTDIR/aes.key" +IVFILE="$OUTDIR/init_vector" +SIGFILE_ANIM="$OUTDIR/signature_animation" + +# commands +ODUMP="od -A n -t d4 -v" + + +# check if output folder does not exist, make one +if [[ ! -d $OUTDIR ]]; then + mkdir $OUTDIR; +fi +if [[ ! -d $OUTDIR ]]; then # check again + echo "! Err: looks like we cannot create this folder" + exit 0 +fi + +echo "* file header check.." +if [ $(head -c 4 $PKGFILE) != "DPUP" ]; then + echo "! Err: this seems to be an invalid pkg" + exit 0 +fi + +echo "* getting data block size" +OFFSET_DATA=`dd if=$PKGFILE bs=4 skip=1 count=1 2>/dev/null | $ODUMP` +DATA_SIZE=`dd if=$PKGFILE bs=4 skip=2 count=1 2>/dev/null | $ODUMP` + +echo "* extract signature.." +SIG_SIZE=`dd if=$PKGFILE bs=4 skip=4 count=1 2>/dev/null | $ODUMP` +dd if=$PKGFILE of=$SIGFILE bs=1 skip=20 count=$((SIG_SIZE)) 2>/dev/null + +echo "* verify data with signature.." +dd if=$PKGFILE bs=$((OFFSET_DATA)) skip=1 2>/dev/null | head -c $((DATA_SIZE)) | openssl dgst -sha256 -verify $SHA256KEY -signature $SIGFILE 1>/dev/null +if [ $? -ne 0 ]; then + echo "! Err: failed to verify data with provided signature" + exit 0 +fi + +echo "* get encrypted data aes key.." +OFFSET_DATAKEY_E=$((20 + SIG_SIZE + ((-(SIG_SIZE % 16)) % 16))) +DATAKEY_E_SIZE=`dd if=$PKGFILE bs=1 skip=$OFFSET_DATAKEY_E count=4 2>/dev/null | $ODUMP` +OFFSET_DATAKEY_E=$((OFFSET_DATAKEY_E + 4)) +echo "** decrypt it via $DATAKEY_D" +dd if=$PKGFILE bs=1 skip=$OFFSET_DATAKEY_E count=$((DATAKEY_E_SIZE)) 2>/dev/null | openssl rsautl -decrypt -inkey $DATAKEY_D > $AESFILE + +echo "* extract 32-byte initial vector.." +OFFSET_IV=$((OFFSET_DATAKEY_E + DATAKEY_E_SIZE)) +dd if=$PKGFILE of=$IVFILE bs=1 skip=$OFFSET_IV count=32 2>/dev/null + +echo "* decrypt data to zipped tar.." +dd if=$PKGFILE bs=$((OFFSET_DATA)) skip=1 2>/dev/null | head -c $((DATA_SIZE)) | openssl enc -d -aes-256-cbc -K `cat $AESFILE` -iv `cat $IVFILE` > $OUTDIR/decrypted_pkg.tar.gz + +echo "* unzip data.." +tar -xzf $OUTDIR/decrypted_pkg.tar.gz -C $OUTDIR + +echo "* checking if animation data followed by.." +OFFSET_ANIM_HEADER=$((OFFSET_DATA + DATA_SIZE)) +ANIM_HEADER_SIZE=`dd if=$PKGFILE bs=1 skip=$OFFSET_ANIM_HEADER count=4 2>/dev/null | $ODUMP` +if [ -z "$ANIM_HEADER_SIZE" ]; then + ANIM_HEADER_SIZE=0 +fi +if [[ $((ANIM_HEADER_SIZE)) -gt 0 ]]; then + echo "** found animation block, getting animation data size.." + ANIM_DATA_SIZE=`dd if=$PKGFILE bs=1 skip=$((OFFSET_ANIM_HEADER + 4)) count=4 2>/dev/null | $ODUMP` + + echo "** get animation signature.." + ANIM_SIG_SIZE=`dd if=$PKGFILE bs=1 skip=$((OFFSET_ANIM_HEADER + 8)) count=4 2>/dev/null | $ODUMP` + dd if=$PKGFILE of=$SIGFILE_ANIM bs=1 skip=$((OFFSET_ANIM_HEADER + 12)) count=$(($ANIM_SIG_SIZE)) 2>/dev/null + + echo "** verify animation data with signature.." + OFFSET_ANIM_DATA=$((OFFSET_ANIM_HEADER + ANIM_HEADER_SIZE)) + dd if=$PKGFILE bs=$((OFFSET_ANIM_DATA)) skip=1 2>/dev/null | head -c $((ANIM_DATA_SIZE)) | openssl dgst -sha256 -verify $SHA256KEY -signature $SIGFILE_ANIM + if [ $? -ne 0 ]; then + echo "! Err: failed to verify animation data with provided signature" + exit 0 + fi + + echo "** dump animation data to zipped tar.." + dd if=$PKGFILE bs=$((OFFSET_ANIM_DATA)) skip=1 2>/dev/null > $OUTDIR/decrypted_animation_pkg.tar.gz + + echo "** unzip the tar.." + tar -xzf $OUTDIR/decrypted_animation_pkg.tar.gz -C $OUTDIR +fi +