Skip to content

Commit

Permalink
added using Substitute as an option
Browse files Browse the repository at this point in the history
  • Loading branch information
syto203 committed Feb 23, 2021
1 parent 61a1999 commit 299cce6
Show file tree
Hide file tree
Showing 10 changed files with 565 additions and 15 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module/bin/update
module/lib/CydiaSubstrate*.framework

addons/*/.theos
addons/*/obj
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ To begin developing your first jailed tweak, head over to [Installation](https:/

* Works with the latest and greatest
- iOS 8 and up
with your choice of:
- CydiaSubstrate.framework (instead of the outdated libsubstrate.dylib)
OR
- Latest [Substitute](https://apt.bingner.com/info/com.ex.substitute/.)
* Functions as a module, so it plugs in to Theos. This means you can always use the latest version of Theos with it
* Colored terminal output (see [Example output](#example-output))
* Uses `make package install` instead of a shell script --- just like in jailbroken tweaks
Expand Down
72 changes: 58 additions & 14 deletions install
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,71 @@ SUBSTRATE="lib/CydiaSubstrate_$SUBSTRATE_VERSION.framework"

[ -d "$THEOS" ] || error "\"$THEOS\" is not a directory. Aborting…"

# Install Substrate
if [[ ! -d module/$SUBSTRATE ]]; then
echo "Downloading CydiaSubstrate.framework ($SUBSTRATE_VERSION)…"
curl -#Lo substrate.deb "http://apt.saurik.com/debs/mobilesubstrate_${SUBSTRATE_VERSION}_iphoneos-arm.deb"
ar -x substrate.deb data.tar.lzma
tar --lzma --strip-components 3 -xf data.tar.lzma "$SUBSTRATE_PATH"
rm -rf substrate.deb data.tar.lzma
# remove any older copies of Substrate before moving the new one into place
rm -rf module/lib/CydiaSubstrate*.framework
mv CydiaSubstrate.framework "module/$SUBSTRATE"
echo "Successfully installed CydiaSubstrate.framework"
fi
plutil -convert binary1 "module/$SUBSTRATE/Info.plist" || true
rm -rf "module/$SUBSTRATE/Libraries" "module/$SUBSTRATE/Commands"
echo -e "\n*Choose: \n 1) Install CydiaSubstrate.\nOR \n 2) Install Substitute. \n\nEnter a Number: "
read CHOICE;
if [ "$CHOICE" -eq 1 ]; then
# Install Substrate
if [[ ! -d module/$SUBSTRATE ]]; then
echo "Downloading CydiaSubstrate.framework ($SUBSTRATE_VERSION)…"
curl -#Lo substrate.deb "http://apt.saurik.com/debs/mobilesubstrate_${SUBSTRATE_VERSION}_iphoneos-arm.deb"
ar -x substrate.deb data.tar.lzma
tar --lzma --strip-components 3 -xf data.tar.lzma "$SUBSTRATE_PATH"
rm -rf substrate.deb data.tar.lzma
# remove any older copies of Substrate and Substitute before moving the new one into place
rm -rf module/lib/CydiaSubstrate*.framework
rm -f module/lib/libsubstitute.dylib
rm -f module/lib/libsubstitute.0.dylib
mv CydiaSubstrate.framework "module/$SUBSTRATE"
echo "Successfully installed CydiaSubstrate.framework"
fi
plutil -convert binary1 "module/$SUBSTRATE/Info.plist" || true
rm -rf "module/$SUBSTRATE/Libraries" "module/$SUBSTRATE/Commands"

elif [ "$CHOICE" -eq 2 ]; then
# find 'com.ex.substitute' | list last one | using "sed" remove everything before '<a href=\" ' , remove everything after the first ' "> '
LATEST_SUBSTITUTE="$(wget -q -O - https://apt.bingner.com/debs/1443.00 | grep 'com.ex.substitute' | tail -1 | sed -e 's/.*\<a href=\"//' -e 's/\"\>.*//')"
SUBSTITUTE_PATH="./usr/lib/libsubstitute.dylib"
if [ -z "${LATEST_SUBSTITUTE}" ]; then
LATEST_SUBSTITUTE=com.ex.substitute_2.0.7_iphoneos-arm.deb
fi

# Install Substitute
if [[ ! -d module/$SUBSTITUTE_PATH ]]; then
echo "Downloading Substitute ($LATEST_SUBSTITUTE)…"
curl -#Lo substitute.deb "https://apt.bingner.com/debs/1443.00/${LATEST_SUBSTITUTE}"
ar -x substitute.deb data.tar.lzma
tar --lzma --strip-components 2 -xf data.tar.lzma "$SUBSTITUTE_PATH"
rm -rf substitute.deb data.tar.lzma
# thinning the binary to remove arm64e
lipo -thin arm64 -output libsubstitute.dylib libsubstitute.dylib
# change LC_ID to run from rpath
install_name_tool -id "@rpath/libsubstitute.0.dylib" libsubstitute.dylib
# remove any older copies of Substrate before moving the new one into place
rm -rf module/lib/CydiaSubstrate${SUBSTRATE_VERSION}.framework
rm -f module/lib/libsubstitute.dylib
rm -f module/lib/libsubstitute.0.dylib
cp libsubstitute.dylib "module/lib/"
cp libsubstitute.dylib "module/lib/libsubstitute.0.dylib"
rm libsubstitute.dylib
# mv CydiaSubstrate_stub.framework "module/lib/CydiaSubstrate.framework"
echo "Successfully installed Substitute"
fi
fi
# Install module
ln -fs "$PWD/update" "module/bin/update"
mkdir -p "$MODULE_PATH"
rm -rf "$MODULE_PATH"/*
cp -a module/* "$MODULE_PATH"
if [ "$CHOICE" -eq 1 ]; then
mv "$MODULE_PATH/$SUBSTRATE" "$MODULE_PATH/lib/CydiaSubstrate.framework"
rm "${MODULE_PATH}bin/ipa_substitute.sh"
rm "${MODULE_PATH}common_substitute.mk"
elif [ "$CHOICE" -eq 2 ]; then
rm "${MODULE_PATH}bin/ipa.sh"
mv "${MODULE_PATH}bin/ipa_substitute.sh" "${MODULE_PATH}bin/ipa.sh"
rm "${MODULE_PATH}common.mk"
mv "${MODULE_PATH}common_substitute.mk" "${MODULE_PATH}common.mk"
fi
echo "*" > "$MODULE_PATH/.gitignore"
echo "Successfully installed module."

Expand Down
125 changes: 125 additions & 0 deletions module/bin/ipa_substitute.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/bin/bash

source "$STAGE"

function copy {
rsync -a "$@" --exclude _MTN --exclude .git --exclude .svn --exclude .DS_Store --exclude ._*
}

if [[ -d $RESOURCES_DIR ]]; then
log 2 "Copying resources"
copy "$RESOURCES_DIR"/ "$appdir" --exclude "/Info.plist"
fi

function change_bundle_id {
bundle_id=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$1")
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID${bundle_id#$app_bundle_id}" "$1"
}

if [[ -n $BUNDLE_ID ]]; then
log 2 "Setting bundle ID"
export -f change_bundle_id
export app_bundle_id
find "$appdir" -name "*.appex" -print0 | xargs -I {} -0 bash -c "change_bundle_id '{}/Info.plist'"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID" "$info_plist"
fi

if [[ -n $DISPLAY_NAME ]]; then
log 2 "Setting display name"
/usr/libexec/PlistBuddy -c "Add :CFBundleDisplayName string" "$info_plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $DISPLAY_NAME" "$info_plist"
fi

if [[ -f $RESOURCES_DIR/Info.plist ]]; then
log 2 "Merging Info.plist"
copy "$RESOURCES_DIR/Info.plist" "$STAGING_DIR"
/usr/libexec/PlistBuddy -c "Merge $info_plist" "$STAGING_DIR/Info.plist"
mv "$STAGING_DIR/Info.plist" "$appdir"
fi

log 2 "Copying dependencies"
inject_files=("$DYLIB" $INJECT_DYLIBS)
copy_files=($EMBED_FRAMEWORKS $EMBED_LIBRARIES)
[[ $USE_CYCRIPT = 1 ]] && inject_files+=("$CYCRIPT")
[[ $USE_FLEX = 1 ]] && inject_files+=("$FLEX")
[[ $USE_OVERLAY = 1 ]] && inject_files+=("$OVERLAY")
[[ $GENERATOR == "MobileSubstrate" ]] && copy_files+=("$SUBSTRATE" "$LIBSUBSTRATE" "$LIBSUBSTRATE0")

full_copy_path="$appdir/$COPY_PATH"
mkdir -p "$full_copy_path"
for file in "${inject_files[@]}" "${copy_files[@]}"; do
copy "$file" "$full_copy_path"
done

log 3 "Injecting dependencies"
app_binary="$appdir/$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "$info_plist")"
install_name_tool -add_rpath "@executable_path/$COPY_PATH" "$app_binary"
for file in "${inject_files[@]}"; do
filename=$(basename "$file")
install_name_tool -change "$STUB_SUBSTRATE_INSTALL_PATH" "$SUBSTRATE_INSTALL_PATH" "$full_copy_path/$filename"
"$INSERT_DYLIB" --inplace --all-yes "@rpath/$(basename "$file")" "$app_binary"
if [[ $? != 0 ]]; then
error "Failed to inject $filename into $app"
fi
done

chmod +x "$app_binary"

if [[ $_CODESIGN_IPA = 1 ]]; then
log 4 "Signing $app"

if [[ ! -r $PROFILE ]]; then
bundleprofile=$(grep -Fl "<string>iOS Team Provisioning Profile: $PROFILE</string>" ~/Library/MobileDevice/Provisioning\ Profiles/* | head -1)
if [[ ! -r $bundleprofile ]]; then
error "Could not find profile '$PROFILE'"
fi
PROFILE="$bundleprofile"
fi

if [[ $_EMBED_PROFILE = 1 ]]; then
copy "$PROFILE" "$appdir/embedded.mobileprovision"
fi

security cms -Di "$PROFILE" -o "$PROFILE_FILE"
if [[ $? != 0 ]]; then
error "Failed to generate entitlements"
fi

if [[ -n $DEV_CERT_NAME ]]; then
codesign_name=$(security find-certificate -c "$DEV_CERT_NAME" login.keychain | grep alis | cut -f4 -d\" | cut -f1 -d\")
else
# http://maniak-dobrii.com/extracting-stuff-from-provisioning-profile/
codesign_name=$(/usr/libexec/PlistBuddy -c "Print :DeveloperCertificates:0" "$PROFILE_FILE" | openssl x509 -noout -inform DER -subject | sed -E 's/^.*CN=([^\/]*)\/.*$/\1/')
fi
if [[ -z $codesign_name ]]; then
error "Failed to get codesign name"
fi

/usr/libexec/PlistBuddy -x -c "Print :Entitlements" "$PROFILE_FILE" > "$ENTITLEMENTS"
if [[ $? != 0 ]]; then
error "Failed to generate entitlements"
fi

find "$appdir" \( -name "*.framework" -or -name "*.dylib" -or -name "*.appex" \) -not -path "*.framework/*" -print0 | xargs -0 codesign --entitlements "$ENTITLEMENTS" -fs "$codesign_name"
if [[ $? != 0 ]]; then
error "Codesign failed"
fi

codesign -fs "$codesign_name" --entitlements "$ENTITLEMENTS" "$appdir"
if [[ $? != 0 ]]; then
error "Failed to sign $app"
fi
fi

cd "$STAGING_DIR"
if [[ "${OUTPUT_NAME##*.}" = "app" ]]; then
cp -a "$appdir" "$PACKAGES_DIR/$OUTPUT_NAME"
else
log 4 "Repacking $app"
zip -yqr$COMPRESSION "$OUTPUT_NAME" Payload/
if [[ $? != 0 ]]; then
error "Failed to repack $app"
fi
rm -rf "$PACKAGES_DIR"/*.ipa "$PACKAGES_DIR"/*.app
mv "$OUTPUT_NAME" "$PACKAGES_DIR/"
fi
70 changes: 70 additions & 0 deletions module/common_substitute.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Module paths
THEOS_JAILED_PATH := $(THEOS_MODULE_PATH)/jailed
THEOS_JAILED_BIN := $(THEOS_JAILED_PATH)/bin
THEOS_JAILED_LIB := $(THEOS_JAILED_PATH)/lib

# Shell scripts
export MESSAGES := $(THEOS_JAILED_BIN)/messages.sh
export STAGE := $(THEOS_JAILED_BIN)/stage.sh
export INSERT_DYLIB := $(THEOS_JAILED_BIN)/insert_dylib
export INFO_TEMPLATE := $(THEOS_JAILED_BIN)/info.txt
export INFO_SCRIPT := $(THEOS_JAILED_BIN)/info.sh
export IPA_SCRIPT := $(THEOS_JAILED_BIN)/ipa.sh
export EXO_SCRIPT := $(THEOS_JAILED_BIN)/exo.sh
export INSTALL_SCRIPT := $(THEOS_JAILED_BIN)/install.sh
export UPDATE_SCRIPT := $(THEOS_JAILED_BIN)/update

# Directories
export RESOURCES_DIR ?= Resources
export STAGING_DIR = $(THEOS_STAGING_DIR)
export PACKAGES_DIR = $(THEOS_PROJECT_DIR)/$(THEOS_PACKAGE_DIR)

# Resources
export COPY_PATH ?= Frameworks
export IPA ?= $(strip $($(TWEAK_NAME)_IPA))
export DYLIB ?= $(THEOS_OBJ_DIR)/$(TWEAK_NAME).dylib
export INJECT_DYLIBS = $($(TWEAK_NAME)_INJECT_DYLIBS)
export OUTPUT_NAME ?= $(TWEAK_NAME)$(_THEOS_INTERNAL_PACKAGE_VERSION)-syto203-iOS14.ipa
export EMBED_FRAMEWORKS = $(strip $($(TWEAK_NAME)_EMBED_FRAMEWORKS))
export EMBED_LIBRARIES = $(strip $($(TWEAK_NAME)_EMBED_LIBRARIES))

# Codesigning
export PROFILE ?= *
export PROFILE_FILE = $(STAGING_DIR)/profile.plist
export ENTITLEMENTS = $(STAGING_DIR)/entitlements.plist
export _CODESIGN_IPA = $(call __theos_bool,$(or $(CODESIGN_IPA),$(_THEOS_TRUE)))
export _EMBED_PROFILE = $(call __theos_bool,$(or $(EMBED_PROFILE),$(_THEOS_TRUE)))

# Cycript
export USE_CYCRIPT = $(call __theos_bool,$(or $($(TWEAK_NAME)_USE_CYCRIPT),$(DEBUG)))
export CYCRIPT ?= $(THEOS_JAILED_LIB)/Cycript.dylib

# FLEX
export USE_FLEX = $(call __theos_bool,$($(TWEAK_NAME)_USE_FLEX))
export FLEX ?= $(THEOS_JAILED_LIB)/FLEX.dylib

# Overlay
export USE_OVERLAY = $(call __theos_bool,$($(TWEAK_NAME)_USE_OVERLAY))
export OVERLAY ?= $(THEOS_JAILED_LIB)/Overlay.dylib

# # CydiaSubstrate
# export GENERATOR = $(or $($(TWEAK_NAME)_LOGOS_DEFAULT_GENERATOR),$(LOGOS_DEFAULT_GENERATOR),$(_THEOS_TARGET_LOGOS_DEFAULT_GENERATOR),MobileSubstrate)
# export SUBSTRATE ?= $(THEOS_JAILED_LIB)/CydiaSubstrate.framework
# export STUB_SUBSTRATE_INSTALL_PATH = /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate
# export SUBSTRATE_INSTALL_PATH = @rpath/CydiaSubstrate.framework/CydiaSubstrate

# LibSubstitute
export GENERATOR = $(or $($(TWEAK_NAME)_LOGOS_DEFAULT_GENERATOR),$(LOGOS_DEFAULT_GENERATOR),$(_THEOS_TARGET_LOGOS_DEFAULT_GENERATOR),MobileSubstrate)
export SUBSTRATE ?= $(THEOS_JAILED_LIB)/CydiaSubstrate.framework
export LIBSUBSTRATE = $(THEOS_JAILED_LIB)/libsubstitute.dylib
export LIBSUBSTRATE0 = $(THEOS_JAILED_LIB)/libsubstitute.0.dylib
export STUB_SUBSTRATE_INSTALL_PATH = /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate
export SUBSTRATE_INSTALL_PATH = @rpath/CydiaSubstrate.framework/CydiaSubstrate

# Extensify Exo
export EXO_STAGING_DIR = $(STAGING_DIR)/$(TWEAK_NAME)
export EXO_RESOURCES_DIR = $(EXO_STAGING_DIR)/ExoResources
export EXO_OUTPUT_NAME = $(TWEAK_NAME)$(_THEOS_INTERNAL_PACKAGE_VERSION).zip

# Miscellaneous
export TWEAK_NAME BUNDLE_ID DEV_CERT_NAME DISPLAY_NAME PRINT_FORMAT_MAKING PRINT_FORMAT_STAGE PRINT_FORMAT_ERROR _THEOS_VERBOSE _THEOS_RSYNC_EXCLUDE_COMMANDLINE
Binary file not shown.
Loading

0 comments on commit 299cce6

Please sign in to comment.