Skip to content

PoomSmart/MGKeys

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MGKeys

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.

Patterns

There are a few certain patterns of the key names, which can be useful for de-obfuscation.

  • Kebab case some-key-name
    • has-xxx
    • supports-xxx
  • Pascal case of DeviceSupportsXXX (common)
  • Pascal case of XXXCapability (common)
    • FrontFacing(Camera)XXXCapability
    • RearFacing(Camera)XXXCapability
  • Pascal case of SupportsXXX
  • Pascal case of HasXXX
  • Pascal case of IsXXX
  • Pascal case of XXXData (usually come alongside another key without Data suffix in it)

Non-Gestalt Keys

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.

Getting Started

Installation

# Clone the repository
git clone https://github.com/PoomSmart/MGKeys.git
cd MGKeys

# Install dependencies (optional, for development)
pip3 install -r requirements.txt

Usage

All scripts support --help flags for detailed usage information. Run any script with --help to see available options and examples.

Automated Discovery

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-extract

Version Hash Extraction

To 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-extract

This script:

  • Downloads/extracts the IPSW and libMobileGestalt.dylib
  • Generates versions/version-XX.txt with extracted hashes
  • Does NOT run discovery or update mapping files
  • Useful for populating version history and key tracking

Manual Discovery

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 --help

Advanced Recovery Methods

Guessing Keys from Hints

If 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 --help

Recovering from DeviceTree

Extract 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 --help

Hashcat-based Recovery

Use 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 keys

The workflow generates:

  • md5hashes.txt - MD5 hashes of all obfuscated keys for hashcat input
  • potfile - Known key mappings in hashcat potfile format for reference

Development

Running Tests

# 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 -v

Type Checking

The Python scripts include comprehensive type hints:

# Install mypy (included in requirements.txt)
pip3 install -r requirements.txt

# Run type checker
mypy *.py

Script Reference

All 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.

Credits (Keys De-obfuscation)

Further Readings