Git Product home page Git Product logo

reflutter's Introduction

Twitter

stars workflow

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;
  • contains minor changes for successfull compilation;
  • if you would like to implement your own patches, there is manual Flutter code change is supported using specially crafted Dockerfile

Supported engines

  • Android: arm64, arm32;
  • iOS: arm64;
  • Release: Stable, Beta

Install

# Linux, Windows, MacOS
pip3 install reflutter

Usage

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

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

  • Add port: 8083
  • Bind to address: All interfaces
  • Request handling: Support invisible proxying = 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.

Usage on Android

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. Note that you must manually find what _kDartIsolateSnapshotInstructions (ex. 0xB000 ) equals to using a binary search. reFlutter writes the dump to the root folder of the application and sets 777 permissions to the file and folder. You can pull the file with adb command

impact@f:~$ adb -d shell "cat /data/data/<PACKAGE_NAME>/dump.dart" > dump.dart
file contents
Library:'package:anyapp/navigation/DeepLinkImpl.dart' Class: Navigation extends Object {  

String* DeepUrl = anyapp://evil.com/ ;

 Function 'Navigation.': constructor. (dynamic, dynamic, dynamic, dynamic) => NavigationInteractor { 
  
              Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000009270
  
                   }
    
 Function 'initDeepLinkHandle':. (dynamic) => Future<void>* { 
  
              Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000412fe8
  
                   }
    
 Function '_navigateDeepLink@547106886':. (dynamic, dynamic, {dynamic navigator}) => void { 
  
              Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000002638
  
                   }
 
       }
 
Library:'package:anyapp/auth/navigation/AuthAccount.dart' Class: AuthAccount extends Account {

PlainNotificationToken* _instance = sentinel;
 
 Function 'getAuthToken':. (dynamic, dynamic, dynamic, dynamic) => Future<AccessToken*>* { 
  
               Code Offset: _kDartIsolateSnapshotInstructions + 0x00000000003ee548
  
                   }
  
 Function 'checkEmail':. (dynamic, dynamic) => Future<bool*>* { 
  
               Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000448a08
   
                   }

 Function 'validateRestoreCode':. (dynamic, dynamic, dynamic) => Future<bool*>* { 
  
               Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000412c34
   
                   }

 Function 'sendSmsRestorePassword':. (dynamic, dynamic) => Future<bool*>* { 
  
               Code Offset: _kDartIsolateSnapshotInstructions + 0x00000000003efb88
  
                   }
       }

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.

To Do

  • Display absolute code offset for functions;
  • Extract more strings and fields;
  • Add socket patch;
  • Extend engine support to Debug using Fork and Github Actions;
  • Improve detection of App.framework and libapp.so inside zip archive

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

release

gif

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=<Snapshot_Hash> -e COMMIT=<Engine_commit> --rm -iv${PWD}:/t ptswarm/reflutter

FLAGS:
    -e x64=0                         <disables building for x64 archiitechture, use to reduce building time>
    -e arm=0                         <disables building for arm archiitechture, use to reduce building time>
    -e WAIT=300                      <the amount of time in seconds you need to edit source code>
    -e HASH_PATCH=[Snapshot_Hash]    <here you need to specify snapshot hash which matches the engine_commit line of enginehash.csv table best. It is used for proper patch search in reFlutter and for successfull compilation>
    -e COMMIT=[Engine_commit]        <here you specify commit for your engine version, take it from enginehash.csv table or from flutter/engine repo>

reflutter's People

Contributors

impact-i avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reflutter's Issues

Docker usage/explanation/example

This project is awesome! I'd like to do some libflutter.so patching myself, but I'm not sure what the correct procedure is.

I've got the Docker container set up, and it seems like the code I want to edit is in /customEngine, but it's unclear to me how to proceed. Is there an explanation of your original patching technique (for dumping the Dart classes, etc.)? Or are there any plans to expand the Docker usage explanation?

Edit: So apparently the Docker container automatically builds libflutter after the wait time specified in the docker run command. The resulting libflutter builds will be in the directory (on the host machine) where you ran docker run.

Android Application crash after the modification of this tool

Hi, this project is quite awesome!
I have tried some android app built with flutter, but they just crashed without any log tagged with "reflutter" after I modified them using this tool. Surely I have use uber-apk-signer mentioned in the guide to align and sign the apk.

Here are some apps using flutter I found in github to test this tool, do I make something wrong about the usage of this tool?
Moss: https://github.com/Sky24n/Moss/releases/tag/v1.0.0
Pixez: https://github.com/Notsfsssf/pixez-flutter/releases/tag/0.7.6

Thanks for your time to read this!

[INFO] Syslog::PrintErr

Hi,

I wanted to let you know that while testing reFlutter (with @alximw) on Android 9/10 on an x86/x64 emulator, we realised that the call to Syslog::PrintErr was leading to a crash. The reason for the crash has been detailed here and a fix has already been released by the Dart maintainers. Sadly their policy is to update only the latest branch. An idea to avoid the bug in new and old releases would be to rely on OS::PrintErr instead.

What is Burp Suite IP?

Morning, trying to figure out the usage of your tool.
I found it very useful and wish you all the best in further app improvements.

Only one issue I've found is:
The example usage of the tool is quite difficult to understand for the users that didn't work with Burp Suite.

For example:
What IP should I insert here:
Please enter your Burp Suite IP:

I've tried:

  • 127.0.0.1
  • My Android Emulator's IP: 10.0.2.15
  • My Mac's Local IP: 192.168.*.*

The reason why am I asking about that is:
When I run:
adb logcat -e reflutter | sed 's/.*DartVM//' >> reflutter.txt
and launch the signed apk file:
release.RE-aligned-debugSigned.apk on my Emulator I don't see any logs in reflutter.txt;

What did I do wrong?

Thank you

Don't strip symbols

First of all: Great project, thank you very much! ❤️

I'm using Frida to hook some functions in libflutter.so. In productive Flutter-based Android apps the symbols are missing, so you have to manually find the functions you want to hook in Ghidra. I was hoping that reflutter would not strip libflutter.so, but I just noticed that the symbols are also missing.

Since you compile it, you should be able to control the stripping. Could you disable it? This would make reverse-engineering a lot easier and I don't see any disadvantages.

Thanks!

This engine is currently not supported on some apk

Hello,
I got this error when trying to run:
reflutter app.apk

Engine SnapshotHash: e7ad14f921786dbf76b9add4b0a5c950

 This engine is currently not supported.
 Most likely this flutter application uses the Debug version engine which you need to build manually using Docker at the moment.
 More details: https://github.com/ptswarm/reFlutter

What can I do about this situation?

crashed on startup

SnapshotHash: d56742caf7b3b3f4bd2df93a9bbb5503
appname: Stepn
Platform: ios
version: 14.8

Here is what I did:

Extracted the IPA from the jailbroken iOS device [Damp original file with crackerXI]
Used the command reflutter app.ipa and entered my laptop's local IP
Got the modified IPA file. Installed it in the iOS device using AppSync Unified
While opening the application, it crashes on startup/ does not startup at all

Demo: real HTTP Proxy, instead of destination socket rewrite

Hi, thx for the great project. I was working on a use case, where Flutter has to be forced to use a real HTTP proxy (instead of silently redirecting to a transparent proxy).

I want to share my patch for info, maybe sbdy could use it (targets Dart's HttpClient implementation, enforces proxy and prevents overwriting it via findProxy setter):
20211112_161915

Here's a short Twitter thread, showing it applied to a target app:
https://twitter.com/mame82/status/1459157357989187592

iOS application crashes on startup

Hi, Thank you for providing such an awesome project.

I tried to intercept the flutter based iOS applications however, after installation of the modified IPA file, the application crashes on launch.
Here is what I did:

  • Extracted the IPA from the jailbroken iOS device [Tried using the original IPA as well]
  • Used the command reflutter app.ipa and entered my laptop's local IP
  • Got the modified IPA file. Installed it in the iOS device using AppSync Unified
  • While opening the application, it crashes on startup/ does not startup at all

NOT CLEAR

hey,

T
Screenshot from 2021-10-12 09-30-32
his is not working for me, & I don't know & or am not able to get steps to do this clearly.

please add steps to do from start.

thankyou

App can't connect to Internet

Everythning seems to work, i reproduced the app using reflutter main.apk, and signed the apk.

I can intercept the first request, but the app is stuck on the first screen (waiting for a response from server before continuing)
I can see some code in the reflutter.txt file, but it's not enough since I can't access the rest of the app.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.