Skip to content

Instantly share code, notes, and snippets.

@eni9889
Last active May 23, 2022 20:56
Show Gist options
  • Save eni9889/eed5d58acfd6abe9bfe4c91f6f360df2 to your computer and use it in GitHub Desktop.
Save eni9889/eed5d58acfd6abe9bfe4c91f6f360df2 to your computer and use it in GitHub Desktop.
A simple bash script to sign an IPA
#!/bin/bash
# Use -gt 1 to consume two arguments per pass in the loop (e.g. each
# argument has a corresponding value to go with it).
# Use -gt 0 to consume one or more arguments per pass in the loop (e.g.
# some arguments don't have a corresponding value to go with it such
# as in the --default example).
# note: if this is set to -gt 0 the /etc/hosts part is not recognized ( may be a bug )
while [[ $# -gt 1 ]]
do
key="$1"
case $key in
-p|--profile)
PROVISIONING_PROFILE="$2"
shift # past argument
;;
-b|--bundle)
BUNDLE_ID="$2"
shift # past argument
;;
-n|--name)
DISPLAY_NAME="$2"
shift # past argument
;;
-k|--identity)
IDENTITY="$2"
shift # past argument
;;
-i|--input)
IPA_PATH="$2"
shift # past argument
;;
-o|--output)
FINAL_IPA_PATH="$2"
shift # past argument
;;
-l|--dylib)
DYLIB_PATH="$2"
shift # past argument
;;
--default)
DEFAULT=YES
;;
*)
# unknown option
;;
esac
shift # past argument or value
done
echo PROVISIONING_PROFILE = "${PROVISIONING_PROFILE}"
echo IDENTITY = "${IDENTITY}"
echo IPA_PATH = "${IPA_PATH}"
echo FINAL_IPA_PATH = "${FINAL_IPA_PATH}"
echo BUNDLE_ID = "${BUNDLE_ID}"
echo DYLIB_PATH = "${DYLIB_PATH}"
RANDOM=$(openssl rand -hex 12)
TMP_DIR="/tmp/$RANDOM"
TMP_IPA_PATH="$TMP_DIR/app.ipa"
EXTRACTED_IPA_PATH="$TMP_DIR/extracted_ipa"
rm -rf "$TMP_DIR"
rm -rf "$TMP_IPA_PATH"
rm -rf "$EXTRACTED_IPA_PATH"
mkdir -p "$TMP_DIR"
mkdir -p "$EXTRACTED_IPA_PATH"
cp -rf "$IPA_PATH" "$TMP_IPA_PATH"
IPA_PATH="$TMP_IPA_PATH"
echo TMP_DIR = "${TMP_DIR}"
echo EXTRACTED_IPA_PATH = "${EXTRACTED_IPA_PATH}"
echo "EXTRACT THE ORIGINAL IPA TO $EXTRACTED_IPA_PATH..."
unzip -oqq "$IPA_PATH" -d "$EXTRACTED_IPA_PATH"
APP_PATH=$(set -- "$EXTRACTED_IPA_PATH/Payload/"*.app; echo "$1")
HOOKED_EXECUTABLE=$(/usr/libexec/PlistBuddy -c "Print CFBundleExecutable" "$APP_PATH/Info.plist")
TEMP_PLIST="$TMP_DIR/temp.plist"
REAL_CODE_SIGN_ENTITLEMENTS="$TMP_DIR/app.entitlements"
echo APP_PATH = "${APP_PATH}"
echo HOOKED_EXECUTABLE = "${HOOKED_EXECUTABLE}"
echo REAL_CODE_SIGN_ENTITLEMENTS = "${REAL_CODE_SIGN_ENTITLEMENTS}"
echo TEMP_PLIST = "${TEMP_PLIST}"
rm -rf "$REAL_CODE_SIGN_ENTITLEMENTS"
rm -rf "$TEMP_PLIST"
rm -rf "$APP_PATH/PlugIns/"
rm -rf "$APP_PATH/_CodeSignature"
rm -rf "$APP_PATH/embedded.mobileprovision"
if [ ! -z "$BUNDLE_ID" ]
then
echo "SET BUNDLE ID TO: $BUNDLE_ID ..."
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID" "$APP_PATH/Info.plist"
fi
if [ ! -z "$DISPLAY_NAME" ]
then
echo "SET DISPLAY NAME TO: $DISPLAY_NAME ..."
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $DISPLAY_NAME" "$APP_PATH/Info.plist"
fi
if [ ! -z "$DYLIB_PATH" ]
then
echo "ADDING DYLIB: $DYLIB_PATH ..."
DYLIB_FILE_NAME=$(basename "$DYLIB_PATH")
cp -rf "$DYLIB_PATH" "$APP_PATH/$DYLIB_FILE_NAME"
~/Documents/insert_dylib --all-yes --inplace --overwrite "@executable_path/$DYLIB_FILE_NAME" "$APP_PATH/$HOOKED_EXECUTABLE"
fi
echo "SET TRANSPORT SECURITY TO ALLOW ALL"
/usr/libexec/PlistBuddy -c "Delete :NSAppTransportSecurity" -c "add :NSAppTransportSecurity dict" -c "add :NSAppTransportSecurity:NSAllowsArbitraryLoads bool true" "$APP_PATH/Info.plist"
echo "EMBED MOBILE PROVISIONING PROFILE ..."
cp -rf "$PROVISIONING_PROFILE" "$APP_PATH/embedded.mobileprovision"
echo "GENERATING ENTITLEMENTS ... "
security cms -D -i "$PROVISIONING_PROFILE" -o "$TEMP_PLIST"
/usr/libexec/PlistBuddy -c "Print Entitlements" "$TEMP_PLIST" -x > "$REAL_CODE_SIGN_ENTITLEMENTS"
echo "SIGN THE APP .."
#make sure we search for all Mach-O files and sign them
find "$APP_PATH" -type f -exec file '{}' \; | grep 'Mach-O' | cut -d: -f1 | while read line; do
echo "PROCESSING BINARY: $line"
/usr/bin/codesign --force --sign "${IDENTITY}" --entitlements "${REAL_CODE_SIGN_ENTITLEMENTS}" --timestamp=none "$line"
done
/usr/bin/codesign --force --sign "${IDENTITY}" --entitlements "${REAL_CODE_SIGN_ENTITLEMENTS}" --timestamp=none "$APP_PATH/Frameworks/"*
/usr/bin/codesign --force --sign "${IDENTITY}" --entitlements "${REAL_CODE_SIGN_ENTITLEMENTS}" --timestamp=none "$APP_PATH/PlugIns/"*
/usr/bin/codesign --force --sign "${IDENTITY}" --entitlements "${REAL_CODE_SIGN_ENTITLEMENTS}" --timestamp=none "$APP_PATH/"*.dylib
/usr/bin/codesign --force --sign "${IDENTITY}" --entitlements "${REAL_CODE_SIGN_ENTITLEMENTS}" --timestamp=none "$APP_PATH/$HOOKED_EXECUTABLE"
/usr/bin/codesign --force --sign "${IDENTITY}" --entitlements "${REAL_CODE_SIGN_ENTITLEMENTS}" --timestamp=none "$APP_PATH"
rm -rf $FINAL_IPA_PATH
echo "GENERATE FINAL IPA ..."
cd "$EXTRACTED_IPA_PATH"
/usr/bin/zip -r "$FINAL_IPA_PATH" Payload > /dev/null
/usr/bin/codesign --force --sign "${IDENTITY}" "$FINAL_IPA_PATH"
rm -rf "$TMP_DIR"
@eni9889
Copy link
Author

eni9889 commented Jul 6, 2017

Save this file to ~/Documents/sign_ipa

Then in terminal run chmod +x ~/Documents/sign_ipa

Then you can run security find-identity -v -p codesigning to list possible identities:

image

Then the command should looks something like the below commands.

If you want to change the bundle:

~/Documents/sign_ipa -p "/some/path/to/provisioning_profile.mobileprovision" -k "810359699...62525D19A366" -i "/path/to/some/app.ipa" -o "/path/to/some/app-signed.ipa" -b "com.some.bundle.id"

If you not:

~/Documents/sign_ipa -p "/some/path/to/provisioning_profile.mobileprovision" -k "810359699...62525D19A366" -i "/path/to/some/app.ipa" -o "/path/to/some/app-signed.ipa"

This is assuming you saved this file in ~/Documents/

@Dershowitz011
Copy link

This will result in a zip file which when extracted has a folder named payload. I get a \ marked file which I can't do anything. Do help. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment