Skip to content

Commit

Permalink
Update obfuscate your app to be more platform agnostic.
Browse files Browse the repository at this point in the history
  • Loading branch information
antfitch committed Feb 7, 2025
1 parent 1f84c1e commit 0ba5a45
Showing 1 changed file with 83 additions and 68 deletions.
151 changes: 83 additions & 68 deletions src/content/deployment/obfuscate.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,33 @@ 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][].**

[Code obfuscation]: https://en.wikipedia.org/wiki/Obfuscation_(software)
[release build]: /testing/build-modes#release

## Limitations
## Limitations and warnings {: #limitations}

Note that obfuscating your code does _not_
encrypt resources nor does it protect against
reverse engineering.
It only renames symbols with more obscure names.
**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][].

[release build]: /testing/build-modes#release
[Build and release a web app]: /deployment/web
[minified]: https://en.wikipedia.org/wiki/Minification_(programming)

## Supported targets

The following build targets
Expand All @@ -49,91 +58,97 @@ described on this page:
* `macos-framework`
* `windows`

:::note
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][].
:::

[Build and release a web app]: /deployment/web
[minified]: https://en.wikipedia.org/wiki/Minification_(programming)

## Obfuscate your app

To obfuscate your app, use the `flutter build` command
in release mode
with the `--obfuscate` and `--split-debug-info` options.
The `--split-debug-info` option specifies the directory
where Flutter outputs debug files.
In the case of obfuscation, it outputs a symbol map.
For example:
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.

```console
$ flutter build apk --obfuscate --split-debug-info=/<project-name>/<directory>
$ flutter build <build-target> -h
```
* `<build-target>`: The build target. For example,
`apk`.

Once you've obfuscated your binary, **save
the symbols file**. You need this if you later
want to de-obfuscate a stack trace.
## Obfuscate your app

:::tip
The `--split-debug-info` option can also be used without `--obfuscate`
to extract Dart program symbols, reducing code size.
To learn more about app size, see [Measuring your app's size][].
:::
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.

[Measuring your app's size]: /perf/app-size
1. Run the following command to obfuscate your app and
generate a SYMBOLS file:

For detailed information on these flags, run
the help command for your specific target, for example:
```console
$ flutter build <build-target> \
--obfuscate \
--split-debug-info=/<symbols-directory>
```

```console
$ flutter build apk -h
```
* `<build-target>`: The build target. For example,
`apk`.
* `<symbols-directory>`: The directory where the SYMBOLS
file should be placed. For example,
`out/android`.

If these flags are not listed in the output,
run `flutter --version` to check your version of Flutter.
1. Once you've obfuscated your binary, **backup
the SYMBOLS file**. You might need this if you lose
your original SYMBOLs file and you
want to de-obfuscate a stack trace.

## Read an obfuscated stack trace

To debug a stack trace created by an obfuscated app,
use the following steps to make it human readable:

1. Find the matching symbols file.
1. Find the matching SYMBOLS file.
For example, a crash from an Android arm64
device would need `app.android-arm64.symbols`.

1. Provide both the stack trace (stored in a file)
and the symbols file to the `flutter symbolize` command.
For example:
and the SYMBOLS file to the `flutter symbolize` command.

```console
$ flutter symbolize -i <stack trace file> -d out/android/app.android-arm64.symbols
$ flutter symbolize \
-i <stack-trace-file> \
-d <obfuscated-symbols-file>
```

For more information on the `symbolize` command,
* `<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 `symbolize` command,
run `flutter symbolize -h`.

## Read an obfuscated name

To make the name that an app obfuscated human readable,
use the following steps:
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`.

1. To save the name obfuscation map at app build time,
use `--extra-gen-snapshot-options=--save-obfuscation-map=/<your-path>`.
For example:
To generate an obfuscation map, use the following command:

```console
$ flutter build apk --obfuscate --split-debug-info=/<project-name>/<directory> --extra-gen-snapshot-options=--save-obfuscation-map=/<your-path>
```
```console
$ flutter build <build-target> \
--obfuscate \
--split-debug-info=/<symbols-directory> \
--extra-gen-snapshot-options=--save-obfuscation-map=/<obfuscation-map-file>
```

1. To recover the name, use the generated obfuscation map.
The obfuscation map is a flat JSON array with pairs of
original names and obfuscated names. For example,
`["MaterialApp", "ex", "Scaffold", "ey"]`, where `ex`
is the obfuscated name of `MaterialApp`.
* `<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`

## Caveat

Expand All @@ -145,9 +160,9 @@ eventually be an obfuscated binary.
For example, the following call to `expect()` won't
work in an obfuscated binary:

<?code-excerpt "lib/main.dart (Expect)"?>
```dart
expect(foo.runtimeType.toString(), equals('Foo'));
```
<?code-excerpt "lib/main.dart (Expect)"?>
```dart
expect(foo.runtimeType.toString(), equals('Foo'));
```

* Enum names are not obfuscated currently.

0 comments on commit 0ba5a45

Please sign in to comment.