#!/bin/sh

#################################################
# Rerootifier Ultimate v2
#################################################

export TMPDIR=/var/mobile/.Rerootifier

set +e

LOGFILE=/var/mobile/rerootifier.log

exec > "$LOGFILE" 2>&1

#################################################
# Dependencies
#################################################

check_bin() {

	if ! type "$1" >/dev/null 2>&1; then

		echo "[ERROR] Missing dependency: $1"
		exit 1

	fi
}

for BIN in \
dpkg-deb \
file \
ldid \
install_name_tool \
jtool2 \
strings \
grep \
awk \
sed
do
	check_bin "$BIN"
done

#################################################
# Input
#################################################

if [ -z "$1" ]; then
	echo "Usage: rerootifier package.deb"
	exit 1
fi

INPUT="$1"

if ! file "$INPUT" | grep -q "Debian binary package"; then
	echo "[ERROR] Invalid deb file"
	exit 1
fi

#################################################
# Setup
#################################################

mkdir -p /var/mobile/.Rerootifier

OLD="$(mktemp -d /var/mobile/.Rerootifier/tmp.old.XXXX)"
NEW="$(mktemp -d /var/mobile/.Rerootifier/tmp.new.XXXX)"

echo "[*] Extracting"

dpkg-deb -R "$INPUT" "$OLD"

#################################################
# Detect package type
#################################################

ROOTLESS=0

if [ -d "$OLD/var/jb" ]; then
	ROOTLESS=1
fi

if [ "$ROOTLESS" = "0" ]; then
	echo "[!] Hybrid/rootful package detected"
	echo "[*] Continuing anyway"
fi

#################################################
# Copy DEBIAN
#################################################

cp -a "$OLD/DEBIAN" "$NEW"

#################################################
# Fix architecture
#################################################

sed \
's|iphoneos-arm64|iphoneos-arm|g' \
"$OLD/DEBIAN/control" \
> "$NEW/DEBIAN/control"

#################################################
# Move filesystem
#################################################

echo "[*] Rebuilding filesystem"

if [ -d "$OLD/var/jb" ]; then

	cp -a "$OLD/var/jb/"* "$NEW/"

fi

#################################################
# Keep existing rootful dirs
#################################################

for DIR in \
Library \
usr \
Applications
do

	if [ -d "$OLD/$DIR" ]; then

		cp -a "$OLD/$DIR" "$NEW/"

	fi

done

#################################################
# Restore DynamicLibraries
#################################################

if [ -d "$NEW/usr/lib/TweakInject" ]; then

	echo "[*] Restoring DynamicLibraries"

	mkdir -p \
	"$NEW/Library/MobileSubstrate"

	mv \
	"$NEW/usr/lib/TweakInject" \
	"$NEW/Library/MobileSubstrate/DynamicLibraries"

fi

#################################################
# Fake compatibility paths
#################################################

mkdir -p "$NEW/var/LIY"

ln -s /Library "$NEW/var/LIY/Library"
ln -s /usr "$NEW/var/LIY/usr"

#################################################
# Binary patching
#################################################

echo "[*] Patching binaries"

find "$NEW" -type f | while read -r FILE; do

	if file -ib "$FILE" | grep -q "x-mach-binary"; then

		echo ""
		echo "================================"
		echo "$FILE"
		echo "================================"

		#################################################
		# Detect architecture
		#################################################

		ARCH=arm64

		jtool2 -h "$FILE" | grep arm64e >/dev/null 2>&1

		if [ $? -eq 0 ]; then
			ARCH=arm64e
		fi

		echo "[*] ARCH: $ARCH"

		#################################################
		# Detect Swift
		#################################################

		strings "$FILE" | grep "libswift" >/dev/null 2>&1

		SWIFT=0

		if [ $? -eq 0 ]; then

			SWIFT=1

			echo "[*] Swift tweak detected"

		fi

		#################################################
		# Linked libs
		#################################################

		ARCH=$ARCH jtool2 -L "$FILE" \
		> /tmp/reroot_libs.txt 2>/dev/null

		cat /tmp/reroot_libs.txt | while read -r LINE; do

			LIB=$(echo "$LINE" | awk '{print $1}')

			echo "$LIB" | grep "^/var/jb" >/dev/null 2>&1

			if [ $? -eq 0 ]; then

				NEWLIB=$(echo "$LIB" | sed 's#/var/jb##')

				echo "[*] Patching:"
				echo "$LIB"
				echo "->"
				echo "$NEWLIB"

				install_name_tool \
				-change \
				"$LIB" \
				"$NEWLIB" \
				"$FILE" || true

			fi

		done

		#################################################
		# Remove rootless rpaths
		#################################################

		otool -l "$FILE" | grep "/var/jb/usr/lib" >/dev/null 2>&1

		if [ $? -eq 0 ]; then

			install_name_tool \
			-delete_rpath \
			"/var/jb/usr/lib" \
			"$FILE"

		fi

		#################################################
		# Add rootful rpaths
		#################################################

		install_name_tool \
		-add_rpath "/usr/lib" \
		"$FILE" || true

		install_name_tool \
		-add_rpath "/Library/Frameworks" \
		"$FILE" || true

		#################################################
		# Swift tweaks
		#################################################

		if [ "$SWIFT" = "1" ]; then

			install_name_tool \
			-add_rpath "@loader_path/Frameworks" \
			"$FILE" || true

			install_name_tool \
			-add_rpath "@executable_path/Frameworks" \
			"$FILE" || true

		fi

		#################################################
		# Common patches
		#################################################

		install_name_tool \
		-change \
		@rpath/libimagepicker.dylib \
		/usr/lib/libimagepicker.dylib \
		"$FILE" || true

		install_name_tool \
		-change \
		/var/jb/Library/Frameworks/Cephei.framework/Cephei \
		/Library/Frameworks/Cephei.framework/Cephei \
		"$FILE" || true

		#################################################
		# Detect hardcoded paths
		#################################################

		strings "$FILE" | grep "/var/jb" >/dev/null 2>&1

		if [ $? -eq 0 ]; then

			echo "[WARNING] Hardcoded rootless paths remain"

		fi

		#################################################
		# Sign
		#################################################

		ldid -Hsha256 -s "$FILE"

	fi

done

#################################################
# Cleanup
#################################################

rm -rf "$NEW/var/jb"

#################################################
# Build package
#################################################

PKG=$(awk -F': ' '/^Package:/ {print $2}' "$NEW/DEBIAN/control" | tr -d '\r')
VER=$(awk -F': ' '/^Version:/ {print $2}' "$NEW/DEBIAN/control" | tr -d '\r')
ARC=$(awk -F': ' '/^Architecture:/ {print $2}' "$NEW/DEBIAN/control" | tr -d '\r')

OUTPUT="/var/mobile/.Rerootifier/${PKG}_${VER}_${ARC}.deb"

echo ""
echo "[*] Building:"
echo "$OUTPUT"

dpkg-deb -Zzstd -b "$NEW" "$OUTPUT"

#################################################
# Done
#################################################

echo ""
echo "[*] Cleaning"

rm -rf "$OLD"
rm -rf "$NEW"

echo ""
echo "================================"
echo "DONE"
echo "================================"
echo ""
echo "$OUTPUT"
echo ""
echo "Log:"
echo "$LOGFILE"
