Quantcast
Channel: xda-developers - Android Software and Hacking General [Developers Only]
Viewing all articles
Browse latest Browse all 3614

[DEV][TEMPLATE] Complete Shell Script Flashable Zip Replacement + Signing [SCRIPT]

$
0
0
Complete Shell Script Flashable Zip EDIFY/update-binary Replacement + Zip Signing Documentation

Background Information


First truly done by Chainfire for his SuperSU zips, the typical update-binary in flashable zips may be replaced by a shell script and the recovery will run this instead. This requires only a recovery correctly provisioned with busybox (virtually all), and makes zips universal for architecture by not requiring a compiled update-binary. This is especially useful now that Android has expanded from arm, x86, mips, to also include arm64, x64 and mips64. Chainfire has also provided a special method for signing these zips which includes a workaround to allow the busybox unzip to extract them correctly, which I will document as well.


Usage Notes

I have built on Chainfire's work extensively to try and make a fairly complete EDIFY script feature replacement using shell functions. Now users and developers may use the following script as a base script and add their commands to the end, similar to scripting for EDIFY, but not have to worry about figuring the basics out themselves, and still have all the power of shell available.

In addition to the shell script update-binary, you should still include an updater-script, but since it isn't being parsed we just make it contain a dummy comment, shown below. Both files should have LF line endings (use Notepad2 or Notepad++ in Windows) since they are Linux shell files. Also worth noting is the maximum amount for show and set_progress is 1.34; there is no obvious reason for this, it's just been shown through testing to be the actual amount that fills the progress bar. I've made ch_con_recursive match the functionality of set_perm_recursive, so you may set a different context for directories and files. Lastly, as a caveat, to use package_extract_dir, the zip path needs to mirror the device path from root, e.g. system/etc/permissions/.

If you're unclear on the use of any of the EDIFY analogous shell functions, please refer to the EDIFY xda Wiki page for some short explanations.


Script Files

/META-INF/com/google/android/updater-script:
Code:

# Dummy file; update-binary is a shell script.
/META-INF/com/google/android/update-binary:
Code:

#!/sbin/sh
# ROM Patcher: Recovery Flashable Zip
# osm0sis @ xda-developers

OUTFD=/proc/self/fd/$2;
ZIP="$3";
DIR=`dirname "$ZIP"`;

ui_print() {
  until [ ! "$1" ]; do
    echo -e "ui_print $1\nui_print" > $OUTFD;
    shift;
  done;
}
show_progress() { echo "progress $1 $2" > $OUTFD; }
set_progress() { echo "set_progress $1" > $OUTFD; }

#sleep <seconds> exists in shell

is_substring() {
  case "$2" in
    *$1*) echo 1;;
    *) echo 0;;
  esac;
}
#less_than_int(x, y) {} is unneeded since a if [ $x -lt $y ] comparison may be done directly
#greater than int(x, y) {} is unneeded since a if [ $x -gt $y ] comparison may be done directly

#format(fs_type, partition_type, device, fs_size, mountpoint) {} is unneeded since specific format/wipe commands may be run directly
#mount <partition> exists in shell
unmount() { umount $1; }
is_mounted() {
  case `mount` in
      *$1*) echo 1;;
      *) echo 0;;
  esac;
}

write_raw_image() { dd if=$1 of=$2; }
#write_firmware_image() {} is a manufacturer command to apply further OEM update zips with hboot/uboot functions, so can't be duplicated

package_extract_file() { unzip -o "$ZIP" "$1" -p > "$2"; }
package_extract_dir() { unzip -o "$ZIP" "$1/*" -d /; }

delete() { rm -f $*; }
delete_recursive() { rm -rf $*; }

symlink() {
  links=$(echo $* | awk '{ print substr($0, index($0,$2)) }');
  ln -s $1 $links;
}

set_perm() {
  files=$(echo $* | awk '{ print substr($0, index($0,$4)) }');
  for i in $files; do
    chown $1.$2 $i; chown $1:$2 $i;
    chmod $3 $i;
  done;
}
set_perm_recursive() {
  dirs=$(echo $* | awk '{ print substr($0, index($0,$5)) }');
  for i in $dirs; do
    chown -R $1.$2 $i; chown -R $1:$2 $i;
    find "$i" -type d -exec chmod $3 {} +;
    find "$i" -type f -exec chmod $4 {} +;
  done;
}

ch_con() {
  LD_LIBRARY_PATH=/system/lib /system/toolbox chcon u:object_r:$1:s0 $2;
  LD_LIBRARY_PATH=/system/lib /system/bin/toolbox chcon u:object_r:$1:s0 $2;
  chcon u:object_r:$1:s0 $2;
}
ch_con_recursive() {
  dirs=$(echo $* | awk '{ print substr($0, index($0,$3)) }');
  for i in $dirs; do
    find "$i" -type d -exec LD_LIBRARY_PATH=/system/lib /system/toolbox chcon u:object_r:$1:s0 {} +;
    find "$i" -type d -exec LD_LIBRARY_PATH=/system/lib /system/bin/toolbox chcon u:object_r:$1:s0 {} +;
    find "$i" -type d -exec chcon u:object_r:$1:s0 '{}' +;
    find "$i" -type f -exec LD_LIBRARY_PATH=/system/lib /system/toolbox chcon u:object_r:$2:s0 {} +;
    find "$i" -type f -exec LD_LIBRARY_PATH=/system/lib /system/bin/toolbox chcon u:object_r:$2:s0 {} +;
    find "$i" -type f -exec chcon u:object_r:$2:s0 '{}' +;
  done;
}
restore_con() {
  LD_LIBRARY_PATH=/system/lib /system/toolbox restorecon -R $*;
  LD_LIBRARY_PATH=/system/lib /system/bin/toolbox restorecon -R $*;
  restorecon -R $*;
}

file_getprop() { grep "^$2" "$1" | cut -d= -f2; }
getprop() { test -e /sbin/getprop && /sbin/getprop $1 || file_getprop /default.prop $1; }

sha1_check() {
  sum=$(sha1sum $1 | awk '{ print $1 }');
  if [ ! "$2" -o $(is_substring $sum "$*") == 1 ]; then
    echo $sum;
  fi;
}

#apply_patch(srcfile, tgtfile, tgtsha1, tgtsize, sha1_1, patch_1, ...) {} not possible without external bspatch binaries
#apply_patch_check(file, [sha1_1, ...]) {} not possible without external bspatch binaries
#apply_patch_space(bytes) {} not possible without external bspatch binaries

#run_program(program) {} is unneeded since programs may be run directly

abort() { ui_print "$*"; exit 1; }
assert() {
  until [ ! "$1" ]; do
    $1;
    test $? == 1 && abort "assert failed($1)";
    shift;
  done;
}

backup_files() {
  until [ ! "$1" ]; do
    test ! -e "$1.bak" && cp -pf "$1" "$1.bak";
    shift;
  done;
}
restore_files() {
  until [ ! "$1" ]; do
    mv -f "${1}.bak" "$1";
    shift;
  done;
}

Enjoy!
Questions, comments and feedback welcome.



Credits & Thanks: Chainfire for the original and ongoing legwork in his SuperSU zips; Modding.MyMind and TKruzze for being my partners in crime pushing the shell script as update-binary concept forward, helping to rewrite and improve the replacement functions, and iron out the zip signing process.

Disclaimer: Naturally, you take all the responsibility for what happens to your device when you start messing around with things.


XDA:DevDB Information
Shell Script Flashable Zip Documentation, Tool/Utility for the Android General

Contributors
osm0sis

Version Information
Status: Beta

Created 2014-11-09
Last Updated 2014-11-09

Viewing all articles
Browse latest Browse all 3614

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>