diff --git a/Backup-TA.sh b/Backup-TA.sh new file mode 100755 index 0000000..a37a7a6 --- /dev/null +++ b/Backup-TA.sh @@ -0,0 +1,20 @@ +#!/bin/bash +VERSION="9.11" +path=`dirname $0` + +for i in scripts/*.sh ; do + if [ -r "$i" ]; then + . $i + fi +done + +cd $path +[ ! -d "tmpbak" ] && mkdir tmpbak > /dev/null 2>&1 +showLicense + +initialize +wakeDevice +pushBusyBox +hasRoot +showMenu +quit diff --git a/scripts/adb.sh b/scripts/adb.sh new file mode 100755 index 0000000..712ca74 --- /dev/null +++ b/scripts/adb.sh @@ -0,0 +1,5 @@ +function wakeDevice { + echo -n "Waiting for USB Debugging... " + $ADB wait-for-device > /dev/null + echo "OK" +} \ No newline at end of file diff --git a/scripts/android/adb_root_shell.linux b/scripts/android/adb_root_shell.linux new file mode 100644 index 0000000..e9b2abc --- /dev/null +++ b/scripts/android/adb_root_shell.linux @@ -0,0 +1 @@ +$ADB shell su -c "$BB $(< $ANDROID/$1)$2" diff --git a/scripts/android/adb_shell.linux b/scripts/android/adb_shell.linux new file mode 100644 index 0000000..a7e8b38 --- /dev/null +++ b/scripts/android/adb_shell.linux @@ -0,0 +1 @@ +$ADB shell $BB $(< $ANDROID/$1) diff --git a/scripts/android/check_su_binary b/scripts/android/check_su_binary new file mode 100644 index 0000000..ca2a4fe --- /dev/null +++ b/scripts/android/check_su_binary @@ -0,0 +1 @@ +which su diff --git a/scripts/android/list_partitions b/scripts/android/list_partitions new file mode 100644 index 0000000..6bef41d --- /dev/null +++ b/scripts/android/list_partitions @@ -0,0 +1 @@ +awk '{if (\$3<=9999 && match (\$4, \"mmcblk\")) printf \"%s\n\", \$4}' /proc/partitions diff --git a/scripts/android/readlink b/scripts/android/readlink new file mode 100644 index 0000000..cfcfdea --- /dev/null +++ b/scripts/android/readlink @@ -0,0 +1 @@ +readlink -n diff --git a/scripts/android/request_root b/scripts/android/request_root new file mode 100644 index 0000000..4d6e3df --- /dev/null +++ b/scripts/android/request_root @@ -0,0 +1 @@ +echo true diff --git a/scripts/android/search_operator_id b/scripts/android/search_operator_id new file mode 100644 index 0000000..b5955a9 --- /dev/null +++ b/scripts/android/search_operator_id @@ -0,0 +1 @@ +grep -s -m 1 -c 'OP_ID=' /dev/block/ diff --git a/scripts/android/search_operator_name b/scripts/android/search_operator_name new file mode 100644 index 0000000..1cabb1f --- /dev/null +++ b/scripts/android/search_operator_name @@ -0,0 +1 @@ +grep -s -m 1 -c 'OP_NAME=' /dev/block/ diff --git a/scripts/android/search_rooting_allowed b/scripts/android/search_rooting_allowed new file mode 100644 index 0000000..525fbb9 --- /dev/null +++ b/scripts/android/search_rooting_allowed @@ -0,0 +1 @@ +grep -s -m 1 -c 'ROOTING_ALLOWED=' /dev/block/ diff --git a/scripts/android/search_s1_boot b/scripts/android/search_s1_boot new file mode 100644 index 0000000..856d989 --- /dev/null +++ b/scripts/android/search_s1_boot @@ -0,0 +1 @@ +grep -s -m 1 -c 'S1_Boot' /dev/block/ diff --git a/scripts/android/search_s1_hwconf b/scripts/android/search_s1_hwconf new file mode 100644 index 0000000..e99a5a8 --- /dev/null +++ b/scripts/android/search_s1_hwconf @@ -0,0 +1 @@ +grep -s -m 1 -c 'S1_HWConf' /dev/block/ diff --git a/scripts/android/search_s1_loader b/scripts/android/search_s1_loader new file mode 100644 index 0000000..2b23730 --- /dev/null +++ b/scripts/android/search_s1_loader @@ -0,0 +1 @@ +grep -s -m 1 -c 'S1_Loader' /dev/block/ diff --git a/scripts/backup.sh b/scripts/backup.sh new file mode 100755 index 0000000..1764cff --- /dev/null +++ b/scripts/backup.sh @@ -0,0 +1,179 @@ +##################### +## BACKUP +##################### +function inspectPartition() { + part=$1 + echo " --- $part --- " + echo -n "Searching for Operator Identifier... " + if [[ "`. $ADB_ROOT_SHELL search_operator_id $part`" == *1* ]]; then + echo "+" + echo -n "Searching for Operator Name... " + if [[ "`. $ADB_ROOT_SHELL search_operator_name $part`" == *1* ]]; then + echo "+" + echo -n "Searching for Rooting Status... " + if [[ "`. $ADB_ROOT_SHELL search_rooting_allowed $part`" == *1* ]]; then + echo "+" + echo -n "Searching for S1 Boot... " + if [[ "`. $ADB_ROOT_SHELL search_s1_boot $part`" == *1* ]]; then + echo "+" + echo -n "Searching for S1 Loader... " + if [[ "`. $ADB_ROOT_SHELL search_s1_loader $part`" == *1* ]]; then + echo "+" + echo -n "Searching for S1 Hardware Configuration... " + if [[ "`. $ADB_ROOT_SHELL search_s1_hwconf $part`" == *1* ]]; then + echo "+" + return 0 + fi + fi + fi + fi + fi + fi + echo "-" + return 1 +} + +function backupTA { + echo + [ ! -d backup ] && mkdir backup > /dev/null 2>&1 + wakeDevice + echo + echo "=======================================" + echo " FIND TA PARTITION" + echo "=======================================" + partition=`. $ADB_ROOT_SHELL readlink $PARTITION_BY_NAME` + if [ "`$ADB shell su -c \"[ -b '$partition' ] && echo -n 1\"`" == "1" ]; then + echo "Partition found!" + else + echo "Partition not found by name." + echo + read -n1 -s -p "Do you want to perform an extensive search for the TA? Y/n" CHOICE + case $CHOICE in + [Nn]) onBackupCancelled ;; + esac + + echo + echo "=======================================" + echo " INSPECTING PARTITIONS" + echo "=======================================" + backup_taPartitionName= + while read partition; do + partition=$(echo "$partition" | tr -dc "[:alnum:]") + inspectPartition $partition + if [ "$?" == "0" ]; then + if [ "$backup_taPartitionName" == "" ]; then + backup_taPartitionName="/dev/block/$partition" + echo "Partition found^^!" + else + echo "*** More than one partition match the TA partition search criteria. ***" + echo "*** Therefore it is not possible to determine which one or ones to use. ***" + echo "*** Contact DevShaft @XDA-forums for support. ***" + onBackupCancelled + fi + fi + done < <(. $ADB_ROOT_SHELL list_partitions) + + if [ "$backup_taPartitionName" == "" ]; then + echo "*** No compatible TA partition found on your device. ***" + onBackupCancelled + fi + partition=$backup_taPartitionName + fi + + echo + echo "=======================================" + echo " BACKUP TA PARTITION" + echo "=======================================" + echo "Partition: $partition" + realSdCard=$($ADB shell su -c "$BB readlink -n /sdcard1") + currentPartitionMD5=$($ADB shell su -c "$BB md5sum $partition | $BB awk {'printf \\\$1'}") + $ADB shell su -c "$BB dd if=$partition of=$realSdCard/backupTA.img" + + echo + echo "=======================================" + echo " INTEGRITY CHECK" + echo "=======================================" + backupMD5=$($ADB shell su -c "$BB md5sum $realSdCard/backupTA.img | $BB awk {'printf \\\$1'}") + echo -n "Backup checksum matches partition checksum... " + if [ "$currentPartitionMD5" != "$backupMD5" ]; then + echo "FAILED" + onBackupFailed + else + echo "OK" + fi + + echo + echo "=======================================" + echo " PULL BACKUP FROM SDCARD" + echo "=======================================" + $ADB pull $realSdCard/backupTA.img tmpbak/TA.img || onBackupFailed + + echo + echo "=======================================" + echo " INTEGRITY CHECK" + echo "=======================================" + backupPulledMD5=$(md5sum tmpbak/TA.img | awk {'printf $1'}) + echo -n "Local backup checksum matches partition checksum... " + if [ "$currentPartitionMD5" != "$backupPulledMD5" ]; then + echo "FAILED" + onBackupFailed + else + echo "OK" + fi + + echo + echo "=======================================" + echo " PACKAGE BACKUP" + echo "=======================================" + $ADB get-serialno > tmpbak/TA.serial + echo $partition > tmpbak/TA.blk + echo $backupPulledMD5 > tmpbak/TA.md5 + echo $VERSION > tmpbak/TA.version + timestamp=$($ADB shell su -c \"$BB date +%Y%m%d.%H%M%S\") + echo $timestamp > tmpbak/TA.timestamp + cd tmpbak + zip ../backup/TA-backup-$timestamp.zip TA.img TA.md5 TA.blk TA.serial TA.timestamp TA.version || onBackupFailed + cd .. + exit_backup 1 +} + +##################### +## BACKUP CANCELLED +###################### +function onBackupCancelled { + exit_backup 2 +} + +##################### +## BACKUP FAILED +##################### +function onBackupFailed { + exit_backup 3 +} + +##################### +## EXIT BACKUP +##################### +function exit_backup () { + dispose $1 + echo + case $1 in + "1") echo "*** Backup successful. ***" ;; + "2") echo "*** Backup cancelled. ***" ;; + "3") echo "*** Backup failed. ***" ;; + esac + echo + read -n1 -s + exit $1 +} + +##################### +## DISPOSE BACKUP +##################### +function backup_dispose { + if [ "$1" == "1" ]; then + rm -rf tmpbak/backup_*.* > /dev/null 2>&1 + rm -rf tmpbak\TA.* > /dev/null 2>&1 + fi + $ADB shell rm /sdcard/backupTA.img > /dev/null 2>&1 +} diff --git a/scripts/busybox.sh b/scripts/busybox.sh new file mode 100755 index 0000000..781e081 --- /dev/null +++ b/scripts/busybox.sh @@ -0,0 +1,22 @@ +##################### +## PUSH BUSYBOX +##################### +function pushBusyBox { + echo -n "Pushing Backup TA Tools... " + $ADB push tools/busybox $BB > /dev/null 2>&1 + $ADB shell chmod 755 $BB > /dev/null 2>&1 + echo "OK" +} + +##################### +## REMOVE BUSYBOX +##################### +function removeBusyBox { + echo -n "Removing Backup TA Tools... " + $ADB shell rm $BB > /dev/null 2>&1 + echo "OK" +} + +function busybox_dispose { + removeBusyBox +} diff --git a/scripts/init.sh b/scripts/init.sh new file mode 100755 index 0000000..dbfc946 --- /dev/null +++ b/scripts/init.sh @@ -0,0 +1,61 @@ +#!/bin/bash +##################### +## INITIALIZE +##################### +function initialize { + clear + echo + echo "[ ———––––----------------------------------------------––––——— ]" + echo "[ Backup TA v$VERSION for Sony Xperia ]" + echo "[ ———––––----------------------------------------------––––——— ]" + echo "[ Initialization ]" + echo "[ ]" + echo "[ Make sure that you have USB Debugging enabled, you do ]" + echo "[ allow your computer ADB access by accepting its RSA key ]" + echo "[ (only needed for Android 4.2.2 or higher) and grant this ]" + echo "[ ADB process root permissions through superuser. ]" + echo "[ ———––––----------------------------------------------––––——— ]" + echo + PARTITION_BY_NAME="/dev/block/platform/msm_sdcc.1/by-name/TA" + BB="/data/local/tmp/busybox-backup-ta" + ADB="tools/adb.linux" + SCRIPTS="./scripts" + ANDROID="$SCRIPTS/android" + ADB_SHELL="$ANDROID/adb_shell.linux" + ADB_ROOT_SHELL="$ANDROID/adb_root_shell.linux" +} + +##################### +## DISPOSE +##################### +function dispose { + echo + echo "=======================================" + echo " CLEAN UP" + echo "=======================================" + partition= + choiceTextParam= + choice= + + backup_dispose + restore_dispose + convert_dispose + + [ -d "tmpbak" ] && rm -rf tmpbak + + busybox_dispose + + echo "=Killing ADB Daemon..." + $ADB kill-server > nul 2>&1 + + echo "OK" +} + +##################### +## QUIT +##################### +function quit { + dispose + echo + read -p "Press any key to exit" -n1 -s +} diff --git a/scripts/license.sh b/scripts/license.sh new file mode 100755 index 0000000..1b27f91 --- /dev/null +++ b/scripts/license.sh @@ -0,0 +1,38 @@ +#################### +## LICENSE +##################### +function showLicense { + clear + echo + echo "[ ———––––----------------------------------------------––––——— ]" + echo "[ Backup TA v$VERSION for Sony Xperia MIT License ]" + echo "[ ———––––----------------------------------------------––––——— ]" + echo "[ Copyright (C) 2013 DevShaft ]" + echo "[ ]" + echo "[ Permission is hereby granted, free of charge, ]" + echo "[ to any person obtaining a copy of this software ]" + echo "[ and associated documentation files (the \"Software\"), ]" + echo "[ to deal in the Software without restriction, ]" + echo "[ including without limitation the rights to use, ]" + echo "[ copy, modify, merge, publish, distribute, sublicense, ]" + echo "[ and/or sell copies of the Software, and to permit ]" + echo "[ persons to whom the Software is furnished to do so, ]" + echo "[ subject to the following conditions: ]" + echo "[ ]" + echo "[ The above copyright notice and this permission notice ]" + echo "[ shall be included in all copies or substantial portions ]" + echo "[ of the Software. ]" + echo "[ ]" + echo "[ THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY ]" + echo "[ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ]" + echo "[ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR ]" + echo "[ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS ]" + echo "[ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ]" + echo "[ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ]" + echo "[ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ]" + echo "[ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]" + echo "[ ———––––----------------------------------------------––––——— ]" + echo + read -n1 -s -t5 +# -p $'Press N to abort\n' ESC || exit && [ $ESC == 'N' ] && exit +} \ No newline at end of file diff --git a/scripts/menu.sh b/scripts/menu.sh new file mode 100644 index 0000000..4aec6ef --- /dev/null +++ b/scripts/menu.sh @@ -0,0 +1,142 @@ +##################### +## MENU +##################### +function showMenu { + while true; do + menu=('Backup' 'Restore' 'Restore dry-run' 'Convert TA.img' 'Quit') + menu_currentIndex=1 + menu_choices=1 + clear + echo + echo "[ ------------------------------------------------------------ ]" + echo "[ Backup TA v$VERSION for Sony Xperia ]" + echo "[ ------------------------------------------------------------ ]" + for el in "${menu[@]}"; do + echo "> $menu_currentIndex.$el " + let menu_currentIndex=menu_currentIndex+1 + done; + echo "[ ------------------------------------------------------------ ]" + + #%CHOICE% /c:!menu_choices! %CHOICE_TEXT_PARAM% "Please make your decision:" + read -n1 -s CHOICE + case $CHOICE in + "1") menu_1 && exit ;; + "2") menu_2 && exit ;; + "3") menu_3 && exit ;; + "4") menu_4 && exit ;; + "5") menu_5 && exit ;; + esac + done +} + +function menu_1 { + clear + echo + echo ======================================= + echo BACKUP + echo ======================================= + echo When you continue Backup TA will perform a backup of the TA partition. + echo First it will look for the TA partition by its name. When it can not + echo be found this way it will ask you to perform an extensive search. + echo The extensive search will inspect many of the partitions on your device, + echo in the hope to find it and continue with the backup process. + echo + echo "Do you want to continue? y/N" + + while true; do + read -n1 -s CHOICE + case $CHOICE in + [Yy]) + backupTA + ;; + *) + break + ;; + esac + done +} + +function menu_2 { + clear + echo + echo ======================================= + echo RESTORE + echo ======================================= + echo When you continue Backup TA will perform a restore of a TA partition + echo backup. There will be many integrity checks along the way to make sure + echo a restore will either complete successfully, revert when something goes + echo wrong while restoring or fail before the restore begins because of an + echo invalid backup. There is always a risk when writing to an important + echo partition like TA, but with these safeguards that risk is kept to an + echo absolute minimum. + echo + echo "Do you want to continue? y/N" + + while true; do + read -n1 -s CHOICE + case $CHOICE in + [Yy]) + restoreTA + ;; + *) + break + ;; + esac + done +} + +function menu_3 { + clear + echo + echo ======================================= + echo RESTORE DRY-RUN + echo ======================================= + echo When you continue Backup TA will perform the restore of a TA partition + echo in 'dry-run' mode. This mode performs the restore just like the regular + echo restore with the exception that it will not do an actual restore of the + echo backup to the device. It will however perform every integrity check, so + echo you can test beforehand if your backup is invalid or corrupted. + echo + echo "Do you want to continue? y/N" + + while true; do + read -n1 -s CHOICE + case $CHOICE in + [Yy]) + restoreTAdry + ;; + *) + break + ;; + esac + done +} + +function menu_4 { + clear + echo + echo ======================================= + echo CONVERT TA.IMG + echo ======================================= + echo When you continue Backup TA will ask you to copy your TA.img file to a location + echo and then convert this backup to make it compatible with the latest version + echo of Backup TA. + echo + echo "Do you want to continue? y/N" + + while true; do + read -n1 -s CHOICE + case $CHOICE in + [Yy]) + convertRawTA + ;; + *) + break + ;; + esac + done +} + +function menu_5 { + return 0 +} diff --git a/scripts/root.sh b/scripts/root.sh new file mode 100755 index 0000000..9c9670c --- /dev/null +++ b/scripts/root.sh @@ -0,0 +1,20 @@ +##################### +## ROOT CHECK +##################### +function hasRoot { + echo -n "Checking for SU binary..." + if [ "`. $ADB_SHELL check_su_binary`" == "" ]; then + echo "FAILED" + exit + else + echo "OK" + fi; + + echo -n "Requesting root permissions..." + if [[ "`. $ADB_ROOT_SHELL request_root`" == *true* ]]; then + echo "OK" + else + echo "FAILED" + exit + fi; +} diff --git a/tools/adb.linux b/tools/adb.linux new file mode 100755 index 0000000..aba34a6 Binary files /dev/null and b/tools/adb.linux differ diff --git a/tools/adb.mac b/tools/adb.mac new file mode 100755 index 0000000..3b154cb Binary files /dev/null and b/tools/adb.mac differ