The Mac App Analysis Platform (maap) consists of four distinct tools: appxtractor, appdater, appstaller and appnalyser. In combination with mas-crawl, the first three tools can be run in an infinite loop to automatically identify, download and process new apps and updates on macOS.
# Clone the repository
$ git clone https://github.com/0xbf00/maap.git
$ cd maap/
# Install requirements
$ pip3 install -r requirements.txt
# Initialize external / helper tools.
# Note: This downloads prebuilt macOS binaries
$ cd extern/
$ make
$ cd ..The appxtractor tool summarises installed applications, extracting useful information from the app into an output folder. It organises and groups these results by bundle identifier and version number, such that calling appxtractor with updated apps does not overwrite any existing data.
All extractors are located in extractors/ and extend the AbstractExtractor class. Please refer to the source code for more information. Currently, there are extractors for
dependencies: Creates JSON file listing the dependencies of an appexecutable: Saves the main executable for an appinfo: Extracts theInfo.plistfile for an appinternet_access_policy: Extracts the Internet Access Policy, if it exists.itunes_metadata: Uses the iTunes API to extract up-to-date metadata for the appmanifest: Generates a file containing the file name, file size and hash of every file in the app bundlexpc_services: Saves main executable andInfo.plistfor embedded XPC services
To use appxtractor, refer to its --help output. Generally, you'd invoke it as follows
$ ./appxtractor.py -i /path/to/app_folder -o /output_dirResults under /output_dir have this structure:
$ tree /output_dir
/output_dir
├── com.apple.dt.Xcode # Bundle ID of app
│ └── 11.3.1 # Version of app
│ ├── Info.plist
│ ├── dependencies.json
│ ├── executable.bin
│ ├── itunes_metadata.json
│ ├── manifest.json
│ └── xpc_services
│ ├── com.apple.dt.IDESceneKitEditor.Bakery
│ │ ├── Info.plist
│ │ └── executable.bin
│ ├── com.apple.dt.Xcode.LicenseAgreementXPCService
│ │ ├── Info.plist
│ │ └── executable.bin
│ ├── com.apple.dt.Xcode.PlaygroundLiveViewHost
│ │ ├── Info.plist
│ │ └── executable.bin
│ ├── com.apple.dt.Xcode.PlaygroundStub-macosx
│ │ ├── Info.plist
│ │ └── executable.bin
│ ├── com.apple.dt.Xcode.SymbolicateXPCService
│ │ ├── Info.plist
│ │ └── executable.bin
│ ├── com.apple.dt.Xcode.XcodeSelectXPCService
│ │ ├── Info.plist
│ │ └── executable.bin
│ └── com.apple.dt.XcodeMacLocationSimulation
│ ├── Info.plist
│ └── executable.bin
...By comparing all previously seen versions (those that appxtractor processed) with an up-to-date iTunes metadata dump obtained using mas-crawl, appdater identifies apps that can be updated and apps that are free and not yet part of the dataset.
Use it as follows:
$ ./appdater.py \
--results /path/to/appxtractor_files \
--itunes-dump /path/to/recent_itunes_dump.jsonlines \
--output /path/to/basenameIts output files can be fed to appstaller, which then installs these apps and updates automatically.
Uses a modified version of the mas tool to install a list of apps. Usage:
$ ./appstaller.py --new-apps /path/to/new_apps_file --updates /path/to/updates_fileThe appnalyser tool starts the target app and verifies that static (entitlements) and dynamic (runtime) sandboxing information agree. In addition, it checks whether the app can access camera or microphone and, if so, whether it has the required entitlements. Consider using asctl instead nowadays.