Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 154 additions & 35 deletions patcher
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,165 @@ export LANG=C
export LC_CTYPE=C
export LC_ALL=C

dpkg-deb -R $1 $2
# This variable is used as a command. Set it to either true or false. It's case-sensitive.
debug=false

mkdir $2 2> /dev/null
if [ $# -lt 2 ]; then
echo "Usage: $0 <deb> <output folder>"
exit 127
fi

for i in $2/Library/MobileSubstrate/DynamicLibraries/*dylib
do
sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null
sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null
sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' $i 2> /dev/null
sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null
ldid -S $i 2> /dev/null
done
dpkg-deb -R $1 $2 || exit $?
mkdir $2 2> /dev/null

for i in $2/usr/lib/*dylib
do
sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null
sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null
sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null
sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null
ldid -S $i 2> /dev/null
done
iOS12_usrlib=(
"FDRSealingMap.plist"
"bbmasks"
"dyld"
"libCRFSuite0.12.dylib"
"libDHCPServer.dylib"
"libMatch.dylib"
"libSystem.B_asan.dylib"
"libSystem.dylib"
"libSystem_asan.dylib"
"libarchive.dylib"
"libbsm.dylib"
"libbz2.1.0.5.dylib"
"libbz2.dylib"
"libc++.dylib"
"libc.dylib"
"libcharset.dylib"
"libcurses.dylib"
"libdbm.dylib"
"libdl.dylib"
"libeasyperf.dylib"
"libedit.2.dylib"
"libedit.3.0.dylib"
"libedit.dylib"
"libexslt.dylib"
"libextension.dylib"
"libform.dylib"
"libiconv.2.4.0.dylib"
"libiconv.dylib"
"libicucore.dylib"
"libinfo.dylib"
"libipsec.dylib"
"liblzma.dylib"
"libm.dylib"
"libmecab.dylib"
"libncurses.5.dylib"
"libncurses.dylib"
"libobjc-trampolines.dylib"
"libobjc.dylib"
"libpcap.dylib"
"libpmsample.dylib"
"libpoll.dylib"
"libproc.dylib"
"libpthread.dylib"
"libresolv.dylib"
"librpcsvc.dylib"
"libsandbox.dylib"
"libsqlite3.0.dylib"
"libstdc++.6.0.9.dylib"
"libstdc++.dylib"
"libtidy.dylib"
"libutil1.0.dylib"
"libxml2.dylib"
"libxslt.dylib"
"libz.1.1.3.dylib"
"libz.1.2.11.dylib"
"libz.1.2.5.dylib"
"libz.1.2.8.dylib"
"libz.dylib"
"log"
"system"
"updaters"
"xpc"
"libz.1.dylib"
"libxslt.1.dylib"
"libxml2.2.dylib"
"libutil.dylib"
"libtidy.A.dylib"
"libstdc++.6.dylib"
"libsqlite3.dylib"
"libsandbox.1.dylib"
"libresolv.9.dylib"
"libpcap.A.dylib"
"libobjc.A.dylib"
"libncurses.5.4.dylib"
"libmecab_em.dylib"
"liblzma.5.dylib"
"libipsec.A.dylib"
"libicucore.A.dylib"
"libiconv.2.dylib"
"libform.5.4.dylib"
"libexslt.0.dylib"
"libedit.3.dylib"
"libperfcheck.dylib"
"libcharset.1.0.0.dylib"
"libcharset.1.dylib"
"libc++.1.dylib"
"libbz2.1.0.dylib"
"libbsm.0.dylib"
"libarchive.2.dylib"
"libSystem.B.dylib"
"libMatch.1.dylib"
"libDHCPServer.A.dylib"
"libCRFSuite.dylib"
)

dylib_folders=(
"/Library/MobileSubstrate/DynamicLibraries"
"/usr/lib"
)

for i in $2/Library/PreferenceBundles/*/*
do
sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null
sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null
sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' $i 2> /dev/null
sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null
sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null
ldid -S $i 2> /dev/null
patch_file() {
[ -z "$1" ] && return
[ ! -f "$1" ] && return

# When link identity editor fails, it usually means the file is not a valid binary.
ldid -S "$1" 2> /dev/null || return

echo "Patching \"$file\""
sed -i "" 's/\/Library\//\/var\/LIB\//g' "$1" 2> /dev/null
sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' "$1" 2> /dev/null
sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' "$1" 2> /dev/null
sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' "$1" 2> /dev/null

# The trick:
# 1. Replace every "/usr/lib" with "/var/lib"
# 2. Iterate over iOS12_usrlib and revert the system libraries
# This way, we only need to hardcode the system libraries which will never change. We won't need to hardcode the libraries that are for jailbroken devices.
sed -i "" 's/\/usr\/lib\//\/var\/ulb\//g' "$1" 2> /dev/null
if [ $? -eq 0 ]; then
for usr_lib_system_file in "${iOS12_usrlib[@]}"; do
escaped_dot='\.'
escaped_file="${usr_lib_system_file//./${escaped_dot}}"
expression='s/\/var\/ulb\/'"${escaped_file}"'/\/usr\/lib\/'"${escaped_file}"'/g'
${debug} && echo ${expression}
sed -i "" "${expression}" "$1" 2> /dev/null
done
fi

# Sign the binary again, just in case
ldid -S "$1"
}

for folder in "${dylib_folders[@]}"; do
[ ! -d "$2${folder}" ] && continue
echo "[+] Patching files inside \"$2${folder}\"..."
for file in "$2${folder}/"*.dylib; do
patch_file "${file}"
done
done

echo "[+] Patching files inside \"$2/Library/PreferenceBundles\"..."
for file in "$2/Library/PreferenceBundles/"*/*; do
patch_file "${file}"
done

# not tested
<<'NOT_TESTED'

for i in $2/Applications/*.app
do
ldid -e $i > /tmp/_ENTS.plist 2> /dev/null
Expand All @@ -57,3 +174,5 @@ do
ldid -S/tmp/_ENTS.plist $2 2> /dev/null
fi
done

NOT_TESTED