混淆 Dart 代码
什么是代码混淆?
#代码混淆 是修改应用二进制文件的过程,使其更难被人理解。混淆会隐藏编译后的 Dart 代码中的函数和类名,用另一个符号替换每个符号,从而使攻击者难以对您的专有应用进行逆向工程。
局限性和警告
#Flutter 的代码混淆仅在 发布版本 中有效。
混淆您的代码不会加密资源,也不会防止逆向工程。它只会用更晦涩的名称重命名符号。
Web 应用不支持混淆。Web 应用可以被 最小化,这提供了类似的结果。构建 Flutter Web 应用的发布版本时,Web 编译器会最小化该应用。要了解更多信息,请参阅 构建和发布 Web 应用。
支持的目标
#以下构建目标支持本页所述的混淆过程
aar
apk
appbundle
ios
ios-framework
ipa
linux
macos
macos-framework
windows
有关构建目标的命令选项的详细信息,请运行以下命令。输出中应列出 --obfuscate
和 --split-debug-info
选项。如果未列出,则需要安装更新版本的 Flutter 才能混淆您的代码。
flutter build <build-target> -h
<build-target>
:构建目标。例如apk
。
混淆您的应用
#要混淆您的应用并创建符号映射,请使用带有 --obfuscate
和 --split-debug-info
选项的发布模式下的 flutter build
命令。如果您将来想调试混淆后的应用,则需要符号映射。
运行以下命令混淆您的应用并生成 SYMBOLS 文件
flutter build <build-target> \ --obfuscate \ --split-debug-info=/<symbols-directory>
<build-target>
:构建目标。例如apk
。<symbols-directory>
:应放置 SYMBOLS 文件的目录。例如out/android
。
混淆二进制文件后,请备份 SYMBOLS 文件。如果您丢失了原始 SYMBOLS 文件并想解混淆堆栈跟踪,您可能会用到它。
读取混淆后的堆栈跟踪
#要调试由混淆后的应用生成的堆栈跟踪,请使用以下步骤将其转换为人类可读的格式
找到匹配的 SYMBOLS 文件。例如,来自 Android arm64 设备的崩溃需要
app.android-arm64.symbols
。将堆栈跟踪(存储在文件中)和 SYMBOLS 文件一起提供给
flutter symbolize
命令。flutter symbolize \ -i <stack-trace-file> \ -d <obfuscated-symbols-file>
<stack-trace-file>
:堆栈跟踪的文件路径。例如???
。<obfuscated-symbols-file>
:包含混淆符号的符号文件的文件路径。例如out/android/app.android-arm64.symbols
。
有关
symbolize
命令的更多信息,请运行flutter symbolize -h
。
读取混淆后的名称
#您可以生成一个包含混淆映射的 JSON 文件。混淆映射是一个 JSON 数组,其中包含原始名称和混淆名称的对。例如 ["MaterialApp", "ex", "Scaffold", "ey"]
,其中 ex
是 MaterialApp
的混淆名称。
要生成混淆映射,请使用以下命令
flutter build <build-target> \
--obfuscate \
--split-debug-info=/<symbols-directory> \
--extra-gen-snapshot-options=--save-obfuscation-map=/<obfuscation-map-file>
<build-target>
:构建目标。例如apk
。<symbols-directory>
:应放置符号的目录。例如out/android
<obfuscation-map-file>
:应放置 JSON 混淆映射的文件路径。例如out/android/map.json
注意事项
#在编码最终将成为混淆二进制文件的应用时,请注意以下事项。
依赖于匹配特定类、函数或库名称的代码将失败。例如,以下对
expect()
的调用在混淆的二进制文件中将不起作用dartexpect(foo.runtimeType.toString(), equals('Foo'));
枚举名称目前不进行混淆。