Improve the patcher for converting rootful packages to rootless on iOS


#Xinamine Rootless Patcher v1.4 Source Code

set -e

if ! type dpkg-deb >/dev/null 2>&1; then
	echo "Please install 'dpkg-deb'."
fi

if ! type file >/dev/null 2>&1; then
	echo "Please install 'file' from Bingner or Procursus."
fi

if ! type otool >/dev/null 2>&1; then
	echo "Please install 'odcctools'."
fi

if ! ldid 2>&1 | grep -q 'sha1\|sha2'; then
	echo "Please install 'ldid' (must have -H option)."
fi

LDID="ldid -Hsha256"

OLD="$(mktemp -qd)"
NEW="$(mktemp -qd)"

if [ ! -d "$OLD" ] || [ ! -d "$NEW" ]; then
	echo "Creating temporary directories failed."
    exit 1;
fi

### Script start

dpkg-deb -R "$1" "$OLD"

if [ -d "$OLD/var/jb" ]; then
    echo "Deb already rootless. Skipping and exiting cleanly."
    rm -rf "$OLD" "$NEW"
    exit 0;
fi

mkdir -p "$NEW"/var/jb
cp -a "$OLD"/DEBIAN "$NEW"
#sed -i '/^Package: / s/$/rootless/' "$OLD"/DEBIAN/control
sed -i '/^Name: / s/$/ (Xinafied-rootless)/' "$OLD"/DEBIAN/control
sed 's|iphoneos-arm|iphoneos-arm64|' < "$OLD"/DEBIAN/control > "$NEW"/DEBIAN/control

rm -rf "$OLD"/DEBIAN
mv -f "$OLD"/.* "$OLD"/* "$NEW"/var/jb >/dev/null 2>&1 || true

#### Overall Patching Start

find "$NEW" -type f | while read -r file; do
  if file -ib "$file" | grep -q "x-mach-binary; charset=binary"; then
#    echo "$file"
    INSTALL_NAME=$(otool -D "$file" | grep -v -e ":$" -e "^Archive :" | head -n1)
    otool -L "$file" | tail -n +2 | grep -e /System | grep /Library/'[^/]'\*.dylib | cut -d' ' -f1 | tr -d "[:blank:]" > "$OLD"/._lib_cache
    if [ -n "$INSTALL_NAME" ]; then
        install_name_tool -id @rpath/"$(basename "$INSTALL_NAME")" "$file" >/dev/null 2>&1
    fi
    if otool -L "$file" | grep -q CydiaSubstrate; then
        install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @rpath/libsubstrate.dylib "$file" >/dev/null 2>&1
    fi
    if [ -f "$OLD"/._lib_cache ]; then
        cat "$OLD"/._lib_cache | while read line; do
            install_name_tool -change "$line" @rpath/"$(basename "$line")" "$file" >/dev/null 2>&1
        done
    fi
    install_name_tool -add_rpath "/var/jb/Library/Frameworks" "$file" >/dev/null 2>&1
    install_name_tool -add_rpath "/var/jb/usr/lib" "$file" >/dev/null 2>&1

### Xina Patching Start
    #XinaPatch Binaries
    sed -i 's#\x00/Library/MobileSub#\x00/var/LIY/MobileSub#g' "$file"
    sed -i 's#\x00/Library/Sn#\x00/var/LIY/Sn#g' "$file"
    sed -i 's#\x00/Library/Th#\x00/var/LIY/Th#g' "$file"
    sed -i 's#\x00/Library/Application Support#\x00/var/LIY/Application Support#g' "$file"
    sed -i 's#\x00/Library/LaunchD#\x00/var/LIY/LaunchD#g' "$file"
    sed -i 's#\x00/Library/PreferenceB#\x00/var/LIY/PreferenceB#g' "$file"
    sed -i 's#\x00/Library/PreferenceL#\x00/var/LIY/PreferenceL#g' "$file"
    sed -i 's#\x00/Library/Frameworks#\x00/var/LIY/Frameworks#g' "$file"
    sed -i 's#\x00/bin/sh#\x00/var/sh#g' "$file"
    sed -i 's#\x00/usr/lib#\x00/var/lib#g' "$file"
    sed -i 's#\x00/usr/bin#\x00/var/bin#g' "$file"
    #Revert Exceptions
    sed -i 's#\x00/var/lib/libobjc.A.dylib#\x00/usr/lib/libobjc.A.dylib#g' "$file"
    sed -i 's#\x00/var/lib/libc++.1.dylib#\x00/usr/lib/libc++.1.dylib#g' "$file"
    sed -i 's#\x00/var/lib/libSystem.B.dylib#\x00/usr/lib/libSystem.B.dylib#g' "$file"
    sed -i 's#\x00/var/lib/libstdc++.6.dylib#\x00/usr/lib/libstdc++.6.dylib#g' "$file"
    sed -i 's#\x00/var/lib/libMobileGestalt.dylib#\x00/usr/lib/libMobileGestalt.dylib#g' "$file"
    ldid -S "$file"
  #Patch .plist files
  elif basename "$file" | grep -q ".plist"; then
    sed -i 's#>/Applications/#>/var/jb/Applications/#g' "$file"
    sed -i 's#>/Library/i#>/var/LIY/i#g' "$file"
    sed -i 's#>/usr/share/#>/var/share/#g' "$file"
    sed -i 's#>/usr/bin/#>/var/bin/#g' "$file"
    sed -i 's#>/usr/lib/#>/var/lib/#g' "$file"
    sed -i 's#>/usr/sbin/#>/var/sbin/#g' "$file"
    sed -i 's#>/usr/libexec/#>/var/libexec/#g' "$file"
    sed -i 's#>/usr/#>/var/jb/usr/#g' "$file"
    sed -i 's#>/etc/#>/var/etc/#g' "$file"
    sed -i 's#>/bin/#>/var/bin/#g' "$file"
    sed -i 's#>/Library/#>/var/LIY/#g' "$file"
  fi
done

#Patch /DEBIAN preinst, postinst, prerm, postrm
find "$NEW"/DEBIAN -type f | while read -r file; do
  if basename "$file" | grep -q "preinst\|postinst\|prerm\|postrm"; then
    sed -i 's# /Applications/# /var/jb/Applications/#g' "$file"
    sed -i 's# /Library/i# /var/LIY/i#g' "$file"
    sed -i 's# /usr/share/# /var/share/#g' "$file"
    sed -i 's# /usr/bin/# /var/bin/#g' "$file"
    sed -i 's# /usr/lib/# /var/lib/#g' "$file"
    sed -i 's# /usr/sbin/# /var/sbin/#g' "$file"
    sed -i 's# /usr/libexec/# /var/libexec/#g' "$file"
    sed -i 's# /usr/# /var/jb/usr/#g' "$file"
    sed -i 's# /etc/# /var/etc/#g' "$file"
    sed -i 's# /bin/# /var/bin/#g' "$file"
    sed -i 's# /Library/# /var/LIY/#g' "$file"
  fi
done
### Xina Patching End

#### Overall Patching End

dpkg-deb -b "$NEW" "$(pwd)"/"$(grep Package: "$NEW"/DEBIAN/control | cut -f2 -d ' ')"_"$(grep Version: "$NEW"/DEBIAN/control | cut -f2 -d ' ')"_"$(grep Architecture: "$NEW"/DEBIAN/control | cut -f2 -d ' ')".deb >/dev/null 2>&1

### Script end

### Cleaning up
rm -rf "$OLD" "$NEW"

/var/jb/basebin/jbctl rebuild_trustcache >/dev/null 2>&1