Cyber security

B(l)utter for Flutter App Reverse Engineering

B(l)utter is a Flutter mobile application reverse engineering tool designed to analyze compiled Dart Ahead-of-Time (AOT) code. It works by compiling components of the Dart runtime to help researchers inspect the contents of an Android application’s libapp.so library.

The tool currently supports Android applications and the libapp.so file for the ARM64 architecture workflow shown below. It is intended for recent Dart versions, so compatibility may vary with older Flutter applications and runtime builds.

B(l)utter Features

  • Dart AOT analysis: Helps inspect compiled Dart code from Flutter applications.
  • Symbol-aware assembly output: Generates assembly listings with symbols to support code analysis.
  • Object pool extraction: Produces detailed dumps of objects referenced by the compiled application.
  • Frida script template: Generates a JavaScript template that can support further dynamic analysis.
  • Dart version detection: Identifies the Dart runtime version used by the Flutter engine and selects the corresponding executable.
  • Automatic runtime compilation: Checks out and compiles the required Dart source when a matching Blutter executable is unavailable.

Environment Setup

B(l)utter uses the C++20 formatting library and requires a modern C++ compiler. The original project instructions recommend GCC 13 or later, or Clang 15 or later. Linux is a convenient development environment, although Windows and macOS setups are also documented.

Debian Unstable

Install the required build tools, Python dependencies, and development libraries:

sudo apt install python3-pyelftools python3-requests git cmake ninja-build \
    build-essential pkg-config libicu-dev libcapstone-dev

Make sure the installed compiler supports the required C++20 features before building the project.

Windows

Install the latest Microsoft C/C++ compiler and CMake tools. The project also requires the Capstone disassembly library and ICU. Run the environment initialization script from the project directory:

python scripts\init_env_win.py

After setup, open an x64 Native Tools or x64 Developer Command Prompt to build and run the project.

macOS Ventura

Install Xcode and the required development packages with Homebrew:

brew install llvm@15 cmake ninja pkg-config icu4c capstone
python3 -m pip install pyelftools requests

Confirm that the build uses the intended Clang version and can locate the installed ICU and Capstone libraries.

How to Use B(l)utter

First, extract the application’s native library directory from the APK. For the ARM64 workflow, locate the arm64-v8a directory, which should contain libapp.so and the relevant Flutter engine libraries.

Run B(l)utter with the extracted library directory and a destination for the generated files:

python3 blutter.py path/to/app/lib/arm64-v8a out_dir

The script detects the Dart version from the Flutter engine and invokes the matching Blutter executable. If an executable for that Dart version is missing, it attempts to retrieve and compile the corresponding Dart runtime source code. Initial runs can therefore take longer while the required components are built.

Understanding the Output Files

  • asm/: Contains assembly output for libapp.so, including symbols to make code analysis easier.
  • blutter_frida.js: Provides a Frida JavaScript template for further dynamic investigation of the target application.
  • objs.txt: Contains a complete nested dump of objects from the application’s object pool.
  • pp.txt: Lists Dart objects found in the object pool.

These artifacts can help researchers understand compiled Dart code, examine object references, and prepare follow-up analysis. Results depend on the target application’s architecture, Dart version, and build configuration.

Project Directory Structure

  • bin/: Stores Blutter executables organized by Dart version, operating system, and architecture.
  • Blutter/: Contains the main source code that is built against the Dart VM library.
  • build/: Holds generated build projects and intermediate files.
  • dartsdk/: Contains the checked-out Dart runtime source code.
  • external/: Stores third-party libraries used by the Windows build.
  • packages/: Contains static libraries associated with the Dart runtime.
  • scripts/: Includes Python scripts used to download, configure, or build Dart components.

The build/ and dartsdk/ directories may be removable after a successful build if you no longer need the intermediate files or runtime source checkout. Keep backups before deleting build artifacts you may need later.

Generate a Visual Studio Solution

Developers working on Windows can use the --vs-sln option to generate a Visual Studio solution for development:

python blutter.py path\to\lib\arm64-v8a build\vs --vs-sln

The generated project files can be opened in Visual Studio for debugging and further development.

For related security analysis techniques, see our guide to the forensic toolkit. Use B(l)utter only on applications you own or have explicit permission to examine, and handle extracted code and application data responsibly.

Cyber Defence

Recent Posts

What Is a Data Protection Platform and Why Your Organization Needs One

A data protection platform is a unified system that helps organizations discover, classify, monitor, and…

2 weeks ago

How Swiss Privacy Rules Affect AI Companies Under GDPR

AI companies operating in or around Switzerland face a compliance challenge that most legal teams…

2 weeks ago

Swiss FADP vs EU GDPR: Key Differences for AI and Data Privacy

Two major data privacy laws now govern how organizations handle personal data across Europe; the…

2 weeks ago

Kali Linux Commands Cheat Sheet: Complete Quick Reference

This cheat sheet covers the essential Kali Linux commands every pentester and ethical hacker uses…

1 month ago

What I Wish I Knew Before Learning Malware Analysis and Reverse Engineering

When I first started learning malware analysis and reverse engineering, I thought the hardest part…

2 months ago

git fetch vs git pull: How They Work and When to Use Each

Both git fetch and git pull talk to a remote repository, but they do very different things to your…

2 months ago