本指南旨在帮助开发者了解和使用ArkGuard源码混淆功能,保护应用代码安全。通过启用源码混淆,开发者可以对ArkTS代码中的变量名、属性名、文件名等进行混淆处理,增加代码逆向难度,提升应用的安全性。文章将详细介绍如何在DevEco Studio中开启混淆、配置混淆规则、适配不同混淆场景,以及如何查看混淆效果和还原混淆后的报错堆栈。
系统已集成源码混淆功能,开发者可通过以下方式在DevEco Studio中启用。
开启混淆开关
在本模块build-profile.json5配置文件中的arkOptions.obfuscation.ruleOptions字段中,通过enable字段配置是否开启混淆。
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true, // 开启混淆开关。
"files": ["./obfuscation-rules.txt"] // 指定配置混淆规则文件, 在编译本模块时生效。
},
// ...
}
}, 配置混淆规则
打开混淆开关,仅开启默认混淆功能,默认混淆范围为局部变量和参数。如需开启更多混淆功能,请在files字段指定的混淆配置文件obfuscation-rules.txt中进行选项配置。需要注意的是,不同版本的DevEco Studio,obfuscation-rules.txt文件中的默认值可能会有所不同。
以DevEco Studio5.0.3.600及更高版本为例,混淆配置文件如下所示,该配置内容表示开启属性名称混淆、顶层作用域名称混淆、文件名混淆及导入导出名称混淆功能:
-enable-property-obfuscation -enable-toplevel-obfuscation -enable-filename-obfuscation -enable-export-obfuscation
开发者可以使用#在混淆规则文件中添加注释,每行以#开头的文本将被视为注释。使用方法如下:
# options: -enable-property-obfuscation -enable-toplevel-obfuscation -enable-filename-obfuscation # -enable-export-obfuscation -keep-property-name # whitelist for dynamic property names
混淆过程中涉及的所有配置文件详情,请参阅混淆配置文件。首次适配混淆时,建议参照配置混淆选项章节进行配置并执行混淆。
配置混淆保留选项
开启混淆后,代码中的方法、属性或路径被混淆。但是在程序运行时,如果访问未混淆的方法、属性或路径,可能导致功能不可用。因此需要根据不同的场景配置保留选项。关于保留选项的排查场景和配置方法,参考ArkGuard混淆保留选项。
排查场景和配置字段时,推荐使用混淆助手配置保留选项,快速识别需要配置的保留选项和白名单字段。
指定release编译
源码混淆仅支持release编译,不支持debug编译。开启混淆开关后,release编译会进行混淆,debug编译则不会。开发者可参考指定构建模式查看和修改构建模式。
release编译支持混淆,而debug编译不支持混淆。若要明确应用行为差异是否由混淆引起,应通过开启或关闭混淆开关进行排查,而不是仅通过切换编译模式。
下表简要总结了三种混淆配置文件的差异:
| 配置文件(示例) | 配置类型 | 是否可修改配置 | 是否影响本模块的混淆 | 是否影响其他模块的混淆 |
|---|---|---|---|---|
| obfuscation-rules.txt | 自定义 | 是 | 是 | 否 |
| consumer-rules.txt | 自定义 | 是 | 否 | 是 |
| obfuscation.txt | 编译产物 | 不涉及,构建HAR或HSP时自动生成。 | 不涉及 | 是 |
obfuscation-rules.txt
在HAP、HAR和HSP模块的build-profile.json5配置文件中,均包含arkOptions.obfuscation.ruleOptions.files字段,该字段用于指定当前模块在编译过程中所应用的混淆规则,新建工程时,系统默认会生成混淆规则文件obfuscation-rules.txt作为初始配置。
consumer-rules.txt
对于HAR和HSP模块,在build-profile.json5中额外有一个arkOptions.obfuscation.consumerFiles字段,用于指定当本包被依赖时,期望在当前编译流程生效的混淆规则,新建HAR或HSP模块时会创建默认文件consumer-rules.txt。它与obfuscation-rules.txt的区别是:obfuscation-rules.txt在编译本模块时生效,consumer-rules.txt在编译依赖本模块的其他模块时生效。
build-profile.json5配置示例:
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true, // 开启混淆开关。
"files": ["./obfuscation-rules.txt"] // 指定配置混淆规则文件, 在编译本模块时生效。
},
"consumerFiles": ["./consumer-rules.txt"] // 指定配置混淆规则文件, 在编译依赖本模块的其他模块时生效。
}
}, obfuscation.txt
不同于以上两种开发者可自行修改的配置文件,obfuscation.txt是在编译构建HAR或HSP时根据consumer-rules.txt和依赖模块的混淆规则文件自动生成的文件,它作为一种编译产物存在于发布的HAR或HSP包中。在其他应用依赖该发布包时,会合并其中的混淆规则应用于当前编译流程。obfuscation.txt内容的生成及合并逻辑请参考混淆规则合并策略。
针对三方库中obfuscation.txt文件,只有在模块的oh-package.json5文件中依赖三方库时,三方库中的obfuscation.txt文件才会生效。如果在工程的oh-package.json5文件中进行依赖,则三方库的obfuscation.txt文件不会生效。
若代码中存在静态定义、动态访问的情况,或动态定义、静态访问的情况,需要使用-keep-property-name保留属性名称。
// 静态定义,动态访问:属性名在对象定义时是静态的,但访问时通过动态构建属性名(通常使用字符串拼接)来访问
// ArkGuardAbility.ts
const obj001 = {
staticName: 'value' // 静态定义属性
};
const fieldName = 'static' + 'Name'; // 动态构建属性名,需使用-keep-property-name staticName来保留该属性名
console.info(obj001[fieldName]); // 使用方括号语法动态访问属性 // 动态定义,静态访问:属性名通过动态表达式在对象定义时确定,但访问时直接使用点语法(假设开发者知道属性名的结果)
// ArkGuardAbility.ts
const dynamicExpression = 'dynamicPropertyName';
const obj002 = {
[dynamicExpression]: 'value' // 动态定义属性
};
console.info(obj002.dynamicPropertyName);// 使用点语法静态访问属性,需使用-keep-property-name dynamicPropertyName来保留该属性名 若代码中使用点语法访问未在ArkTS/TS/JS代码中定义的字段,比如访问native实现的so库,字段固定的json文件与数据库等场景:
若构建HAR模块并发布给其他模块使用的场景,要在HAR模块中的consumer-rules.txt文件中将不能被二次混淆的属性使用-keep-property-name保留。consumer-rules.txt文件在构建HAR时会生成obfuscation.txt文件。此HAR被其它模块依赖时,DevEco Studio会解析obfuscation.txt文件,读取文件中的白名单。
验证应用功能,排查遗漏的场景。若应用出现功能异常,依据混淆后的报错栈从对应的中间产物中找到报错行的代码,排查需要配置的白名单并使用-keep-property-name进行保留。
混淆结束后,会在编译产物的build目录中生成混淆后的中间产物。开发者可以查看这些中间产物以确认混淆效果。同时,该目录中还会生成名称映射表和系统API白名单文件。
混淆后的文件目录:build/default/[...]/release/模块名。
混淆名称映射表及系统API白名单目录:build/default/[...]/release/obfuscation。

经过混淆的应用程序,代码名称会更改,导致crash时打印的报错栈难以理解。可使用DevEco Studio命令工具Command Line Tools中的hstack插件还原源码堆栈,进而分析问题。
请备份应用编译过程中生成的sourceMaps.map文件和混淆名称映射文件nameCache.json,反混淆工具需要这些文件。
如果使用自建在线平台或流水线构建应用,则会获取不到编译过程中生成的sourceMaps.map文件和混淆名称映射文件nameCache.json,可以使用本地编译生成的对应文件进行代替。
源代码映射信息文件:sourceMaps.map,该文件记录了压缩/转换后的代码到原始源代码之间的映射关系。
