Mapping of the obfuscated keys (or questions) used by iOS's MobileGestalt to the de-obfuscated, easier-to-understand ones. To obfuscate a key, Apple calculates the base64 of MGCopyAnswer{theKey}, truncates the last two characters and calculates the MD5 from the resulting string.
It is our job to de-obfuscate them all.
The keys are currently based on iOS 26.2.
There are a few certain patterns of the key names, which can be useful for de-obfuscation.
- Kebab case
some-key-namehas-xxxsupports-xxx
- Pascal case of
DeviceSupportsXXX(common) - Pascal case of
XXXCapability(common)FrontFacing(Camera)XXXCapabilityRearFacing(Camera)XXXCapability
- Pascal case of
SupportsXXX - Pascal case of
HasXXX - Pascal case of
IsXXX - Pascal case of
XXXData(usually come alongside another key withoutDatasuffix in it)
There are also keys which are obfuscated the same way but are not considered as MobileGestalt keys. That is, you can't use MGCopyAnswer to get the value of the key. Instead, they are used for retrieving the value from the IODeviceTree, in an obfuscated manner. These keys are mostly in the kebab case, having their pascal case equivalent which is actually used by MGCopyAnswer. In the mapping files, these keys are marked with a comment // non-gestalt-key.
# Clone the repository
git clone https://github.com/PoomSmart/MGKeys.git
cd MGKeys
# Install dependencies (optional, for development)
pip3 install -r requirements.txtAll scripts support --help flags for detailed usage information. Run any script with --help to see available options and examples.
Use discover-version.sh to automate downloading an IPSW, extracting libMobileGestalt.dylib, and running discovery:
./discover-version.sh <DEVICE> <VERSION_OR_BUILD> [ARCH] [--remote-extract]
# Examples
./discover-version.sh iPhone15,2 16.5
./discover-version.sh iPhone15,2 20F66 --remote-extractTo extract hashes for version tracking without running discovery or updating mappings:
./extract-version-hashes.sh <DEVICE> <VERSION_OR_BUILD> [ARCH] [--remote-extract]
# Examples
./extract-version-hashes.sh iPhone15,2 18.0
./extract-version-hashes.sh iPhone13,1 17.4 arm64e --remote-extractThis script:
- Downloads/extracts the IPSW and
libMobileGestalt.dylib - Generates
versions/version-XX.txtwith extracted hashes - Does NOT run discovery or update mapping files
- Useful for populating version history and key tracking
For manual key discovery from an extracted dylib:
# Run discovery with default architecture (arm64e)
./discover.sh
# Specify architecture
./discover.sh --arch arm64
# See all options
./discover.sh --helpIf you have hints about unknown keys (from keys_desc.py):
# Attempt to guess all unknown keys
python3 guess_keys.py
# Target a specific key with verbose output
python3 guess_keys.py --key <OBFUSCATED_KEY> --verbose
# See all options
python3 guess_keys.py --helpExtract keys from IODeviceTree properties:
# 1. Dump DeviceTree to JSON
./dump-dtree.sh <path/to/ipsw_or_dtree>
# Or from remote IPSW
./dump-dtree.sh -d <DEVICE> -v <VERSION>
# 2. Recover keys from the JSON
python3 recover_from_dtree.py
# See all options
./dump-dtree.sh --help
python3 recover_from_dtree.py --helpUse hashcat to brute-force unknown obfuscated keys:
# 1. Prepare hashcat input files
python3 gen_md5.py # Generate MD5 hashes from all-hashes.txt
python3 gen_mapping.py # Generate potfile for known keys
# 2. Run hashcat with appropriate attack mode
# See hashcat documentation for advanced usage and attack modes
# 3. After recovery, update deobfuscated.py with discovered keysThe workflow generates:
md5hashes.txt- MD5 hashes of all obfuscated keys for hashcat inputpotfile- Known key mappings in hashcat potfile format for reference
# Install dependencies
pip3 install -r requirements.txt
# Run all tests
pytest
# Run with coverage
pytest --cov=. test_*.py
# Run specific test file
pytest test_obfuscate.py -vThe Python scripts include comprehensive type hints:
# Install mypy (included in requirements.txt)
pip3 install -r requirements.txt
# Run type checker
mypy *.pyAll scripts support --help for detailed usage. Features:
- Python scripts (
*.py): Type hints, pathlib, argparse, comprehensive error handling - Shell scripts (
*.sh): Help messages, prerequisite checks, input validation - Tests (
test_*.py): Comprehensive unit tests for core logic - Shared library (
lib-ipsw-extract.sh): Common IPSW extraction functions used by discovery scripts
Run any script with --help to see available options and examples.
- Jonathan Levin
- Timac
- Siguza
- Elias Limneos
- PoomSmart
- JackoPlane