ReFlutter 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
pip3 install reflutter
Usage
impact@f:~$ reflutter main.apk
Please enter your Burp Suite IP:
SnapshotHash: 8ee4ef7a67df9845fba331734198a953
The resulting apk file: ./release.RE.apk
Please sign the apk file
Configure Burp Suite proxy server to listen on *:8083
Proxy Tab -> Options -> Proxy Listeners -> Edit -> Binding Tab
Then enable invisible proxying in Request Handling Tab
Support Invisible Proxying -> true
impact@f:~$ reflutter main.ipa
Traffic Interception
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. Next, you should configure the Proxy in BurpSuite -> Listener Proxy -> Options tab
8083
All interfaces
True
You don’t need to install any certificates. On an Android device, you don’t need root access as well. reFlutter also allows to bypass some of the flutter certificate pinning implementations.
The resulting apk must be aligned and signed. I use uber-apk-signer java -jar uber-apk-signer.jar --allowResign -a release.RE.apk
. To see which code is loaded through DartVM, you need to run the application on the device. reFlutter prints its output in logcat with the reflutter
tag
impact@f:~$ adb logcat -e reflutter | sed ‘s/.*DartVM//’ >> reflutter.txt
Code output
Library:’package:anyapp/navigation/DeepLinkImpl.dart’ Class: Navigation extends Object {
String* DeepUrl = anyapp://evil.com/ ;
Function ‘Navigation.’: constructor. (dynamic, dynamic, dynamic, dynamic) => NavigationInteractor {
}
Function ‘initDeepLinkHandle’:. (dynamic) => Future* {
}
Function ‘_navigateDeepLink@547106886’:. (dynamic, dynamic, {dynamic navigator}) => void {
}
}
Library:’package:anyapp/auth/navigation/AuthAccount.dart’ Class: AuthAccount extends Account {
PlainNotificationToken* _instance = sentinel;
Function ‘getAuthToken’:. (dynamic, dynamic, dynamic, dynamic) => Future> { } Function ‘checkEmail’:. (dynamic, dynamic) => Future> { } Function ‘validateRestoreCode’:. (dynamic, dynamic, dynamic) => Future> { } Function ‘sendSmsRestorePassword’:. (dynamic, dynamic) => Future<bool> {
}
}
Usage on iOS
Use the IPA file created after the execution of reflutter main.ipa
command. To see which code is loaded through DartVM, you need to run the application on the device. reFlutter prints its output in console logs in XCode with the reflutter
tag.
Build Engine
The engines are built using reFlutter in Github Actions to build the desired version, commits and snapshot hashes are used from this table. The hash of the snapshot is extracted from storage.googleapis.com/flutter_infra_release/flutter/<hash>/android-arm64-release/linux-x64.zip
Custom Build
If you would like to implement your own patches, manual Flutter code change is supported using specially crafted Docker
sudo docker pull ptswarm/reflutter
Linux, Windows
EXAMPLE BUILD ANDROID ARM64:
sudo docker run -e WAIT=300 -e x64=0 -e arm=0 -e HASH_PATCH= -e COMMIT= –rm -iv${PWD}:/t ptswarm/reflutter
FLAGS:
-e x64=0
-e arm=0
-e WAIT=300
-e HASH_PATCH=[Snapshot_Hash]
-e COMMIT=[Engine_commit]
If you are new to Bash scripting or Linux shell scripting, one of the most…
How Does a Firewall Work Step by Step? What Is a Firewall and How Does…
ROADTools is a powerful framework designed for exploring and interacting with Microsoft Azure Active Directory…
Microsoft 365 Groups (also known as M365 Groups or Unified Groups) are at the heart…
SeamlessPass is a specialized tool designed to leverage on-premises Active Directory Kerberos tickets to obtain…
PPLBlade is a powerful Protected Process Dumper designed to capture memory from target processes, hide…