How to obfuscate Flutter apps?

17,439

Solution 1

Obfuscation is needed - a flutter app knows its function names, which can be shown using Dart's StackTrace class. There's under-tested support for obfuscation. To enable it:


For Android:
Add to the file [ProjectRoot]/android/gradle.properties :

extra-gen-snapshot-options=--obfuscate

For iOS:
First, edit [FlutterRoot]/packages/flutter_tools/bin/xcode_backend.sh:
Locate the build aot call, and add a flag to it,

${extra_gen_snapshot_options_or_none}

defined as:

local extra_gen_snapshot_options_or_none=""
if [[ -n "$EXTRA_GEN_SNAPSHOT_OPTIONS" ]]; then
  extra_gen_snapshot_options_or_none="--extra-gen-snapshot-options=$EXTRA_GEN_SNAPSHOT_OPTIONS"
fi

To apply your changes, in [FlutterRoot], run

git commit -am "Enable obfuscation on iOS"  
flutter  

(Running "flutter" after the commit rebuilds flutter tools.)

Next, in your project, add following to [ProjectRoot]/ios/Flutter/Release.xcconfig file:

EXTRA_GEN_SNAPSHOT_OPTIONS=--obfuscate

PS: Haven't tried the --save-obfuscation-map flag mentioned at https://github.com/dart-lang/sdk/issues/30524
Again, obfuscation isn't very well tested, as mentioned by @mraleph.

Solution 2

AppBundle (recommended):

  • Without splitting:

    flutter build appbundle --obfuscate --split-debug-info=/<directory>
    
  • Splitting:

    flutter build appbundle --target-platform android-arm,android-arm64,android-x64 --obfuscate --split-debug-info=/<directory>
    

APK:

  • Without splitting:
    flutter build apk --obfuscate --split-debug-info=/<directory>
    
  • Splitting:

    flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi --obfuscate --split-debug-info=/<directory>
    

PS: About Splitting:
By default, fat apk contains arm v7, arm v8 and x64 which increases apk size, which you don't want to. So, when you split it, you have separate binaries which you can upload on the store and thus reducing the size of the apk that a user would need to download.

Solution 3

enter image description here https://flutter.dev/docs/deployment/obfuscateRefer this link for more info

Note: Flutter’s code obfuscation, Supported as of Flutter 1.16.2.

Solution 4

All the above answers are correct, but no answer tells you that we need to add a relative path or directory path while generating build.

Example using Relative Path:

flutter build apk --obfuscate --split-debug-info=./ProjectFolderName/debug
                                

Example using Folder Path:

flutter build apk --obfuscate --split-debug-info=/Users/apple/Desktop/items/debug

The above command will generate a build inside the given project directory, it will create a new folder called ProjectFolderName or 'debug' on the respective command, and there you can find the release build.

Solution 5

At the moment obfuscation is not directly exposed via the flutter CLI.

You can try to explicitly pass arguements to the gen_snapshot like this:

flutter build --extra-gen-snapshot-options=--obfuscate,--save-obfuscation-map=build/symbols.json --release

Note: that obfuscation support is not very well tested and might not work at the moment.

Share:
17,439

Related videos on Youtube

Ehud Banunu
Author by

Ehud Banunu

Updated on July 08, 2022

Comments

  • Ehud Banunu
    Ehud Banunu almost 2 years

    Flutter's wiki mentions obfuscation is an opt-in in release mode.
    And yet, the flutter build command has no relevant option - see:
    flutter help -v build apk

    Am I missing something here?
    Did they make obfuscation the default?
    Is obfuscation even relevant for flutter?

    Any pointers on this would be very appreciated.

    • Günter Zöchbauer
      Günter Zöchbauer almost 6 years
      Why do you think you need obfuscatiin anyway? Dart is compiled to binary code.
    • Ehud Banunu
      Ehud Banunu almost 6 years
      @GünterZöchbauer Does this assure me no variable/method/type names are exposed? And that my code is hard enough to reverse-compile? I come from a C# background, excuse my ignorance...
    • Günter Zöchbauer
      Günter Zöchbauer almost 6 years
      I asked mraleph about why they added the obfuscation funtionality and he mentioned that some things might be recoverable - don't remember details. I'll try to find the disvussion.
    • Günter Zöchbauer
      Günter Zöchbauer almost 6 years
      I haven't found the discussion yet but github.com/dart-lang/sdk/issues/30524 might provide some hints.
    • Günter Zöchbauer
      Günter Zöchbauer almost 6 years
    • Ehud Banunu
      Ehud Banunu almost 6 years
      @GünterZöchbauer OK, in gitter mraleph explains there are still function names by default, and that there's support for aot obfuscation. Where's the flag to enable obfuscation? There's no documentation in flutter help -v build aot...
    • Günter Zöchbauer
      Günter Zöchbauer almost 6 years
      The GitHub issue 30524 mentions some flags.
    • Ehud Banunu
      Ehud Banunu almost 6 years
      @GünterZöchbauer 30524 talks about Dart. I see no mention of the flutter build command.
    • stackunderflow
      stackunderflow about 5 years
      @GünterZöchbauer sir do you have any link to your resource that saying the dart is directly compiled to binary code?
    • Günter Zöchbauer
      Günter Zöchbauer about 5 years
  • Ehud Banunu
    Ehud Banunu almost 6 years
    Does not work: Could not find an option named "extra-gen-snapshot-options".
  • Vyacheslav Egorov
    Vyacheslav Egorov almost 6 years
    What about flutter build aot --extra-gen-snapshot-options=...?
  • Ehud Banunu
    Ehud Banunu almost 6 years
    flutter build aot seems to respond to the flag, but where's the apk/ipa?
  • Vyacheslav Egorov
    Vyacheslav Egorov almost 6 years
    flutter build aot unfortunately does not build APK, I looked at the code and currently it does not seem like you have a way to build ipk and also pass these flags. You would have to edit flutter_tools sources.
  • Ehud Banunu
    Ehud Banunu almost 6 years
    @mraleph I managed setting the extra-gen-snapshot-options flag via Gradle's gradle.properties, and got a working & obfuscated apk. What's the equivalent for this in iOS?
  • Vyacheslav Egorov
    Vyacheslav Egorov almost 6 years
    I don't know about those parts of Flutter tooling.
  • sJy
    sJy about 5 years
    Does this current obfuscation technique make it hard for reverse engineering the code or is there any additional steps which we can follow to make it difficult for reverse engineering?
  • i6x86
    i6x86 over 4 years
    I can't find xcode_backend.sh where is that file located, /packages doesn't exists on this location too. The only /packages folder is located on /ios/Flutter/App.framework/flutter_assets/packages but it doesn't contain flutter_tools.
  • Ehud Banunu
    Ehud Banunu over 4 years
    @i6x86 I believe you are looking under your own project by mistake - xcode_backend.sh resides in your Flutter install location. (Either that or Flutter changed since I answered. Either way, please let me know)
  • i6x86
    i6x86 over 4 years
    thanks man, you're right I was looking the project folder, my mistake.
  • Justine Mackay
    Justine Mackay over 4 years
    Where to define this? local extra_gen_snapshot_options_or_none="" if [[ -n "$EXTRA_GEN_SNAPSHOT_OPTIONS" ]]; then extra_gen_snapshot_options_or_none="--extra-gen-snapshot-opt‌​ions=$EXTRA_GEN_SNAP‌​SHOT_OPTIONS" fi
  • Ehud Banunu
    Ehud Banunu about 4 years
    @JustineMackay before the call to build aot .
  • Antonin GAVREL
    Antonin GAVREL almost 4 years
    What do you mean by "splitting"?
  • Antonin GAVREL
    Antonin GAVREL almost 4 years
    Thank you, I read it right after asking in the official documentation flutter.dev/docs/deployment/obfuscate, it will still be helpful for people who limit themselves to this page! You may want to edit your answer to add this precision.
  • Antonin GAVREL
    Antonin GAVREL almost 4 years
    Note that appbundle is recommended as size matters. It can tremendously reduce the size of your app.
  • CopsOnRoad
    CopsOnRoad about 3 years
    Great! I didn't know about the iOS part, but even after adding DART_OBFUSCATION=true in Release.xcconfig file and doing a build, the Generated.xcconfig file still shows DART_OBFUSCATION=false. Am I doing something wrong?
  • Dmytro Rostopira
    Dmytro Rostopira about 3 years
    @CopsOnRoad Generated.xcconfig doesn't matter, because we reassigning it's value in Release.xcconfig after including generated one. However I didn't found a way to verify that it's actually working)
  • fff
    fff about 3 years
    Hi, is this the only way to obfuscate an .ipa?
  • Chris
    Chris about 2 years
    Thanks, using the relative path helped. I thought it would do that by default but no.
  • Lucas Aschenbach
    Lucas Aschenbach about 2 years
    Thanks for the answer! How could I add the *.symbols to google play?