https://www.guardsquare.com/ixguard
Proprietary mobile iOS code obfuscation tool to make it difficult to disassemble your .ipa.
This protects against intellectual property theft and credential harvesting of things like API keys that may be embedded in applications.
Get the installer from iXGuard and then run the .pkg to install to the / root filesystem:
sudo installer -pkg "iXGuard_4_12_4_stable_arm_64.pkg" -target /http://127.0.0.1:8998/index.html
Unfortunately the documentation is not public but installed and loaded locally using a local python webapp when you install the iXguard pkg.
The installer runs this command in the foreground in a new terminal:
ixguard-docsThis is just a shell script /Library/iXGuard/scripts/ixguard-docs that calls:
#!/usr/bin/env sh
SCRIPT_PATH=`readlink -f "${BASH_SOURCE:-$0}"`
SCRIPT_DIR=`dirname $SCRIPT_PATH`
xcrun python3 $SCRIPT_DIR/../python/server.py &> /dev/nullThis is equivalent to this, because server.py does not have a shebang header line:
python3 /Library/iXGuard/python/server.pyThen you can open the docs at this link (should open automatically in default browser):
http://127.0.0.1:8998/index.html
This self-hosted doc site is made using MKDocs Material theme.
HariSekhon/Templates - ixguard.yaml:
license:
- "./ixguard-license.txt"
debug:
verbosity: info
autoconfigure: false
protection:
enabled: true
names:
enabled: false
arithmetic-operations:
enabled: true
control-flow:
enabled: true
data:
enabled: true
code-integrity:
enabled: false
environment-integrity:
enabled: false
resources:
enabled: false
export:
embed-bitcode: falseThis is neccessary to build an IPA with both bitcode and machine code that iXGuard can later run on.
You can activate it with the -toolchain com.guardsquare.ixguard argument to xcodebuild, eg:
xcodebuild archive \
-workspace "$APP".xcworkspace \
-scheme SIT \
-configuration SIT \
-archivePath "$ARCHIVE_PATH" \
-toolchain com.guardsquare.ixguard \
-quietor just set this environment variable before running xcodebuild or Fastlane:
export TOOLCHAINS="com.guardsquare.ixguard"If you get this error message, it's caused by
xcodebuild -exportArchivebreaks with:
error: exportArchive: Rsync failed
Then you need to skip creating the archive and instead run ixguard on the .xcarchive instead.
ixguard --config ixguard.yaml --local --force -o ./build/MyApp-Guarded.xcarchive ./build/MyApp.xcarchiveAnd then run the xcodebuild -exportArchive afterwards.
NAME=MyAppotool -l "$NAME.xcarchive//Products/Applications/$NAME.app/$NAME" | grep -A2 __LLVMor
NAME=MyAppunzip "$NAME.ipa"otool -l "Payload/$NAME.app/$NAME" | grep -A2 __LLVMIf the output shows a __LLVM section, like this, then bitcode is included:
sectname __LLVM
segname __TEXT
The IPA file size will also be larger than it would otherwise.
NAME=MyAppixguard --config ixguard.yaml --local --force -o "./build/$NAME-Guarded.xcarchive" "./build/$NAME.xcarchive"And then run the xcodebuild -exportArchive afterwards.
See the Fastlane template.
or
IPA="MyApp.ipa"Create a variable name for the new output IPA to be the same as the original except with -hardened.ipa suffix, eg.
-> MyApp-hardened.ipa:
HARDENED_IPA="${IPA_PATH%.ipa}-hardened.ipa"Run ixguard on the .ipa archive to generate a new hardened ipa:
ixguard --config "$IXGUARD_CONFIG" --local -o "$HARDENED_IPA" "$IPA_PATH"This takes several minutes to run and generates MyApp-hardened.ipa.
The --local switch skips checking for updates and prevents the build breaking with this error if your wifi is down:
Generating usage statistics failed: Network error.
Failed to check for updates due to a network issue. Use the -local flag to run ixguard without checking for updates.
An ixguard.log file will be created at the root of the git repo containing logs and a statistics block like this:
STATISTICS:
-----------
Name Obfuscation:
-----------------
- Symbols hidden: 36228
- Symbols obfuscated: 116398
- Entities renamed: 16226
- Entities skipped because they are part of the SDK: 565571
- Entities skipped because of blacklist: 11410
- Entities skipped because they were used in reflection: 12
Arithmetic Obfuscation:
-----------------------
- Functions skipped because they were not whitelisted: 37888
Control Flow Obfuscation:
-------------------------
- Dlsymified calls to this function: 0
- Skipped due to not linked: 6
- Skipped due to not being externally linked: 36680
- Functions not obfuscated because they were not whitelisted: 31327
- Function locations reordered: 38044
- Global locations reordered: 177554
Integrity:
----------
Asset Encryption:
-----------------
- Resources skipped because they were not whitelisted: 896iXGuard will more than double your build time:
[01:36:09]: 🎉 Built with ixGuard toolchain and exported hardened IPA successfully!
+------------------------------------------------------------------------------------+
| fastlane summary |
+------+---------------------------------------------------------------+-------------+
| Step | Action | Time (in s) |
+------+---------------------------------------------------------------+-------------+
| 1 | opt_out_usage | 0 |
| 2 | default_platform | 0 |
| 3 | setup_ci | 0 |
| 4 | get_build_number | 0 |
| 5 | git_branch | 0 |
| 6 | last_git_tag | 0 |
| 7 | ensure_git_branch | 0 |
| 8 | build_app | 546 |
| 9 | cd .. && ixguard --config ixguard.yaml --local --force -o "./ | 725 |
| 10 | build_app | 75 |
+------+---------------------------------------------------------------+-------------+
[01:36:09]: fastlane.tools just saved you 22 minutes! 🎉
Check your resulting .ipa using Mac Binary Debugging tools like:
https://www.guardsquare.com/blog/continuously-protecting-your-ios-project-in-a-cloud-based-ci
curl https://downloads.guardsquare.com/cli/latest_macos_amd64 -sL |
tar -x &&
sudo mv -i guardsquare /usr/local/bin/You need an SSH key which has been uploaded to the iXGuard portal to authenticate this download:
guardsquare --ssh-agent download ixguard -o ixguard.pkgsudo installer -pkg ixguard.pkgThen put your license file and ixguard.yml config to your CI/CD, the former via secret injection,
the latter can be committed to Git.