Skip to content

Latest commit

 

History

History
55 lines (36 loc) · 2.04 KB

File metadata and controls

55 lines (36 loc) · 2.04 KB

blutter-macos

Patches and scripts to run blutter on macOS standalone Dart AOT binaries (dart compile exe).

Blutter supports Android libapp.so and iOS App.framework. This extends it to macOS standalones, where the snapshot is embedded as an LC_NOTE inside the outer binary rather than in a separate file.

See the write-up: machinecase.github.io/posts/dart-reverse-macos

How it works

dart compile exe produces a single Mach-O that contains the Dart VM runtime (what you see in Binary Ninja) and the compiled app snapshot (what you want to analyze) embedded as opaque data in an LC_NOTE named __dart_app_snap.

The scripts extract the inner Mach-O and wrap it in a synthetic ELF so blutter can parse it using its existing ELF code path.

Usage

# 1. Extract inner Mach-O and create ELF wrapper
python3 scripts/extract_snapshot.py ./binary /tmp/analysis/

# 2. Apply patches to blutter
cd /path/to/blutter
git apply /path/to/blutter-macos/patches/macos_standalone_aot.patch

# 3. Run blutter
python3 blutter.py \
    /tmp/analysis/dart_snapshot.so \
    /tmp/analysis/blutter_out \
    --dart-version 3.11.4_macos_arm64

# 4. Triage
grep "String:" /tmp/analysis/blutter_out/pp.txt | grep -v "dart:"

# 5. Import symbols into Binary Ninja
# Open inner.macho, then in Python Console:
exec(open('scripts/import_symbols_bn.py').read())

Patches

Four files in blutter need changes:

  • scripts/CMakeLists.txt — add macos as valid TARGET_OS with correct defines
  • dartvm_fetch_build.py — macOS standalone uses no-compressed-pointers
  • blutter/src/ElfHelper.cpp — detect ELF magic before Mach-O path, fix MH_MAGIC_64 case, uncomment mach_o.h include
  • blutter/src/Disassembler_arm64.h — move CSREG_DART_HEAP outside #ifdef DART_COMPRESSED_POINTERS

Tested

Dart 3.11.4, macOS ARM64 (Apple Silicon).

Credits