How to obfuscate Flutter apps?
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
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.
Related videos on Youtube
Ehud Banunu
Updated on July 08, 2022Comments
-
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 almost 6 yearsWhy do you think you need obfuscatiin anyway? Dart is compiled to binary code.
-
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 almost 6 yearsI 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 almost 6 yearsI haven't found the discussion yet but github.com/dart-lang/sdk/issues/30524 might provide some hints.
-
Günter Zöchbauer almost 6 years
-
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 almost 6 yearsThe GitHub issue 30524 mentions some flags.
-
Ehud Banunu almost 6 years@GünterZöchbauer 30524 talks about Dart. I see no mention of the flutter build command.
-
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 about 5 years
-
-
Ehud Banunu almost 6 yearsDoes not work: Could not find an option named "extra-gen-snapshot-options".
-
Vyacheslav Egorov almost 6 yearsWhat about
flutter build aot --extra-gen-snapshot-options=...
? -
Ehud Banunu almost 6 years
flutter build aot
seems to respond to the flag, but where's the apk/ipa? -
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 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 almost 6 yearsI don't know about those parts of Flutter tooling.
-
sJy about 5 yearsDoes 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 over 4 yearsI 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 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 over 4 yearsthanks man, you're right I was looking the project folder, my mistake.
-
Justine Mackay over 4 yearsWhere 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-options=$EXTRA_GEN_SNAPSHOT_OPTIONS" fi
-
Ehud Banunu about 4 years@JustineMackay before the call to build aot .
-
Antonin GAVREL almost 4 yearsWhat do you mean by "splitting"?
-
Antonin GAVREL almost 4 yearsThank 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 almost 4 yearsNote that appbundle is recommended as size matters. It can tremendously reduce the size of your app.
-
CopsOnRoad about 3 yearsGreat! I didn't know about the iOS part, but even after adding
DART_OBFUSCATION=true
inRelease.xcconfig
file and doing a build, theGenerated.xcconfig
file still showsDART_OBFUSCATION=false
. Am I doing something wrong? -
Dmytro Rostopira about 3 years@CopsOnRoad
Generated.xcconfig
doesn't matter, because we reassigning it's value inRelease.xcconfig
after including generated one. However I didn't found a way to verify that it's actually working) -
fff about 3 yearsHi, is this the only way to obfuscate an .ipa?
-
Chris about 2 yearsThanks, using the relative path helped. I thought it would do that by default but no.
-
Lucas Aschenbach about 2 yearsThanks for the answer! How could I add the *.symbols to google play?