Skip to content

feat: add Flutter app instrumentation with reflutter#7

Open
luca-regne wants to merge 4 commits intomainfrom
feat/flutter-instrumentation
Open

feat: add Flutter app instrumentation with reflutter#7
luca-regne wants to merge 4 commits intomainfrom
feat/flutter-instrumentation

Conversation

@luca-regne
Copy link
Owner

Summary

Implements automated Flutter app instrumentation using reFlutter for Dart code dumping, replicating the flutter_setup.sh bash script functionality with native Python integration.

Commands

batuta flutter patch <package|apk>

Full instrumentation workflow:

  1. Pull APK from device (or use local file)
  2. Auto-merge if split APK detected
  3. Validate Flutter framework (unless --force)
  4. Patch with reflutter
  5. Sign with debug keystore
  6. Uninstall original app
  7. Install patched APK
  8. Auto-start app (or --wait for manual start)
  9. Dump Dart code to <package>_dump.dart
  10. Format as JSON if valid

batuta flutter dump <package>

Extract Dart code from already-instrumented app.

Files Changed

File Purpose
src/batuta/models/flutter.py FlutterPatchResult, DumpResult models
src/batuta/core/reflutter.py ReflutterPatcher business logic
src/batuta/cli/flutter.py CLI commands
src/batuta/exceptions.py Add FlutterError, ReflutterError, DartDumpError
src/batuta/utils/deps.py Add reflutter to tool hints
src/batuta/utils/process.py Add cwd parameter to run_tool()
README.md Add Flutter instrumentation section
AGENTS.md Update command reference

Example Usage

# Full workflow: patch installed Flutter app and dump code
batuta flutter patch com.example.flutter.app

# Patch local APK file
batuta flutter patch app.apk --output ./analysis

# Skip auto-dump (install only)
batuta flutter patch com.example.app --skip-dump

# Wait for manual app start instead of auto-launch
batuta flutter patch com.example.app --wait

# Force patching without Flutter validation
batuta flutter patch com.example.app --force

# Dump code from already-patched app
batuta flutter dump com.example.flutter.app

Requirements

  • reflutter installed: pip install reflutter
  • Rooted Android device for code dumping
  • apktool, apksigner, keytool, zipalign for signing

Key Features

  • ✅ Non-interactive by default (auto-start with monkey)
  • ✅ Fail-fast Flutter validation (with --force override)
  • ✅ Auto-merge split APKs before patching
  • ✅ Clean temp files, keep only final artifacts
  • ✅ JSON output for scripting (--json)
  • ✅ Uses existing apksigner (no uber-apk-signer dependency)
  • ✅ Comprehensive error handling with typed exceptions

Testing

  • ✅ All linting (ruff) passes
  • ✅ Type checking (mypy) passes
  • ✅ CLI help renders correctly
  • ✅ Commands integrate with existing batuta architecture

Implement batuta flutter commands to automate Flutter app analysis with
reflutter for Dart code dumping. This replicates the flutter_setup.sh bash
script functionality in Python with better integration into batuta.

Features:
- batuta flutter patch <package|apk> - Full workflow: pull, patch, install, dump
- batuta flutter dump <package> - Extract Dart code from instrumented app
- Auto-merge split APKs before patching
- Flutter framework validation (with --force to skip)
- Auto-start app via monkey or interactive --wait mode
- JSON formatting for dump output

Changes:
- Add FlutterPatchResult and DumpResult Pydantic models
- Add FlutterError, ReflutterError, DartDumpError exceptions
- Implement ReflutterPatcher class with patch_and_install workflow
- Add reflutter to tool dependency hints
- Add cwd parameter to run_tool() for working directory support
- Update README with Flutter instrumentation section
- Update AGENTS.md command reference

Requirements:
- reflutter installed (pip install reflutter)
- Rooted Android device for code dumping
- apktool, apksigner, keytool, zipalign for signing
Update check_tool() to properly detect apksigner and zipalign from
Android SDK build-tools directory using existing android_sdk helpers,
instead of only checking PATH.

This allows flutter commands to work even when Android SDK tools
are not in PATH (typical macOS/Linux setup).
Move package name extraction logic from ReflutterPatcher to utils/apk.py
to make it reusable across the codebase.

Changes:
- Add get_package_name() function in utils/apk.py
- Use multiple methods: aapt, pyaxmlparser, filename heuristic
- Update ReflutterPatcher to use centralized function
- Remove duplicate package extraction code

This allows other modules (like APKPatcher or future commands) to easily
extract package names from APK files using the same reliable logic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant