
Patches Flutter engine libraries to enable runtime reverse engineering, traffic interception, and SSL pinning bypass for Android and iOS apps without root or certificate installation.

Read more on the blog: https://swarm.ptsecurity.com/fork-bomb-for-flutter/
This framework helps with Flutter apps reverse engineering using the patched version of the Flutter library which is already compiled and ready for app repacking. This library has snapshot deserialization process modified to allow you perform dynamic analysis in a convenient way.
Key features:
socket.cc is patched for traffic monitoring and interception;dart.cc is modified to print classes, functions and some fields;Dockerfile.# Linux, Windows, MacOS
pip3 install reflutter==0.8.6
impact@f:~$ reflutter main.apk
Please enter your Burp Suite IP: <input_ip>
SnapshotHash: 8ee4ef7a67df9845fba331734198a953
The resulting apk file: ./release.RE.apk
Please sign the apk file
impact@f:~$ reflutter main.ipa
Options:
-p, --patch-dump — dump mode: patch the engine to emit dump.dart (classes/methods/offsets) on start, and print a frida.js hint instead of the proxy instructions.-n, --no-interact — never prompt for a Burp IP (implies 127.0.0.1); useful for old engines in CI.-b <Snapshot_Hash>, --build-engine — engine build mode: print the engine commit for a snapshot hash and (when run inside a flutter/flutter checkout) apply the reFlutter source patches. See scripts/local-release.You need to specify the IP of your Burp Suite Proxy Server located in the same network where the device with the Flutter application is. Then configure the Proxy in BurpSuite -> Listener Proxy -> Options tab:
8083All interfacesTrue
No certificate installation or root access is required for Android. reFlutter also allows bypassing some of the Flutter certificate pinning implementations.
⚠️ Note: Engines up to and including Flutter 3.24.x (snapshot hash
80a49c7111088100a233b2ae788e1f48) still carry the hardcoded proxy IP and get patched in place. Starting with 3.27.x the hardcoded IP is gone — configure the proxy directly on the device instead.
Use ADB to configure the device’s proxy:
adb -s <device> shell "settings put global http_proxy <proxy_ip:port>"
Sign, align, and install the APK. Optionally configure TunProxy to route traffic through Burp Suite.
Sign and install the IPA. Configure Potatso to use your Burp Suite proxy server.
The resulting apk must be aligned and signed. A recommended tool is uber-apk-signer:
java -jar uber-apk-signer.jar --allowResign -a release.RE.apk
Run the app on a device. Determine _kDartIsolateSnapshotInstructions via binary search. reFlutter writes the dump file to the app's root folder and sets 777 permissions. Retrieve it using:
adb -d shell "cat /data/data/<PACKAGE_NAME>/dump.dart" > dump.dart
Library:'package:anyapp/navigation/DeepLinkImpl.dart' Class: Navigation extends Object {
String* DeepUrl = anyapp://evil.com/ ;
...
After running reflutter main.ipa, execute the app on device. The dump file path is printed to Xcode console logs:
Current working dir: /private/var/mobile/Containers/Data/Application/<UUID>/dump.dart
Retrieve the file from the device.

frida-tools==13.7.1
frida==16.7.19
Use dump offsets in the Frida script:
frida -U -f <package> -l frida.js
To find _kDartIsolateSnapshotInstructions:
readelf -Ws libapp.so
Look for the Value field.
App.framework and libapp.so inside zip archiveEngines are built with scripts/local-release (macOS; builds v2 + v3 for iOS and Android arm64/arm/x64, verifies every patch landed, and uploads the release assets) based on data in enginehash.csv. The engine commit for a snapshot hash is resolved via reflutter -b <Snapshot_Hash>. Snapshot hash is retrieved from:
https://storage.googleapis.com/flutter_infra_release/flutter/<hash>/android-arm64-release/linux-x64.zip
Manual Flutter code patching is supported using Docker:
git clone https://github.com/Impact-I/reFlutter && cd reFlutter
docker build -t reflutter -f Dockerfile .
Run with:
docker run -it -v "$(pwd):/t" -e HASH_PATCH=<Snapshot_Hash> -e COMMIT=<Engine_commit> reflutter
Example:
docker run -it -v "$(pwd):/t" -e HASH_PATCH=aa64af18e7d086041ac127cc4bc50c5e -e COMMIT=d44b5a94c976fbb65815374f61ab5392a220b084 reflutter
docker run -e WAIT=300 -e x64=0 -e arm=0 -e HASH_PATCH=<Snapshot_Hash> -e COMMIT=<Engine_commit> --rm -iv${PWD}:/t reflutter
Flags:
-e x64=0: disables x64 build-e arm64=0: disables arm64 build-e arm=0: disables arm32 build-e WAIT=300: time in seconds to modify source before build-e HASH_PATCH: snapshot hash from enginehash.csv-e COMMIT: engine commit hash