| title | Obfuscate Dart code |
|---|---|
| description | How to remove function and class names from your Dart binary. |
Code obfuscation is the process of modifying an app's binary to make it harder for humans to understand. Obfuscation hides function and class names in your compiled Dart code, replacing each symbol with another symbol, making it difficult for an attacker to reverse engineer your proprietary app.
Flutter's code obfuscation works only on a release build.
:::warning It is a poor security practice to store secrets in an app. :::
Obfuscating your code does not encrypt resources nor does it protect against reverse engineering. It only renames symbols with more obscure names.
Web apps don't support obfuscation. A web app can be minified, which provides a similar result. When you build a release version of a Flutter web app, the web compiler minifies the app. To learn more, see Build and release a web app.
The following build targets support the obfuscation process described on this page:
aarapkappbundleiosios-frameworkipalinuxmacosmacos-frameworkwindows
For detailed information about the command line options
available for a build target, run the following
command. The --obfuscate and --split-debug-info options should
be listed in the output. If they aren't, you'll need to
install a newer version of Flutter to obfuscate your code.
$ flutter build <build-target> -h<build-target>: The build target. For example,apk.
To obfuscate your app and create a symbol map, use the
flutter build command in release mode
with the --obfuscate and --split-debug-info options.
If you want to debug your obfuscated
app in the future, you will need the symbol map.
-
Run the following command to obfuscate your app and generate a SYMBOLS file:
$ flutter build <build-target> \ --obfuscate \ --split-debug-info=/<symbols-directory>
<build-target>: The build target. For example,apk.<symbols-directory>: The directory where the SYMBOLS file should be placed. For example,out/android.
:::note On Windows x64, the build generates a PDB file (
app.windows-x64.pdb) instead of a SYMBOLS file. ::: -
Once you've obfuscated your binary, backup the SYMBOLS file (or the PDB file on Windows x64). You might need this if you lose your original SYMBOLS file (or PDB file) and you want to de-obfuscate a stack trace.
To debug a stack trace created by an obfuscated app, use the following steps to make it human readable:
:::note
On Windows x64, --split-debug-info generates a PDB file
instead of a SYMBOLS file,
and the flutter symbolize command doesn't support
PDB files. To read a stack trace from an obfuscated
Windows x64 build, load the PDB file in a Windows
debugger such as WinDbg.
:::
-
Find the matching SYMBOLS file. For example, a crash from an Android arm64 device would need
app.android-arm64.symbols. -
Provide both the stack trace (stored in a file) and the SYMBOLS file to the
flutter symbolizecommand.$ flutter symbolize \ -i <stack-trace-file> \ -d <obfuscated-symbols-file>
<stack-trace-file>: The file path for the stacktrace. For example,???.<obfuscated-symbols-file>: The file path for the symbols file that contains the obfuscated symbols. For example,out/android/app.android-arm64.symbols.
For more information about the
symbolizecommand, runflutter symbolize -h.
You can generate a JSON file that contains
an obfuscation map. An obfuscation map is a JSON array with
pairs of original names and obfuscated names. For example,
["MaterialApp", "ex", "Scaffold", "ey"], where
ex is the obfuscated name of MaterialApp.
To generate an obfuscation map, use the following command:
$ flutter build <build-target> \
--obfuscate \
--split-debug-info=/<symbols-directory> \
--extra-gen-snapshot-options=--save-obfuscation-map=/<obfuscation-map-file><build-target>: The build target. For example,apk.<symbols-directory>: The directory where the symbols should be placed. For example,out/android<obfuscation-map-file>: The file path where the JSON obfuscation map should be placed. For example,out/android/map.json
Be aware of the following when coding an app that will eventually be an obfuscated binary.
-
Code that relies on matching specific class, function, or library names will fail. For example, the following call to
expect()won't work in an obfuscated binary:expect(foo.runtimeType.toString(), equals('Foo'));
-
Enum names are not obfuscated currently.