HarmonyOS代码混淆

在鸿蒙(HarmonyOS)开发中,代码混淆的主要目的是保护代码不被反编译,提升应用的安全性。

从DevEco Studio版本:4.0 Beta1开始hvigor插件提供代码混淆功能。

因此我将deveco studio从3.1release升级到了5.0release

运行hello world

关注左侧项目目录,高版本的项目在./entry/src下有obfuscation-rules.txt,新建工程时,每个模块下都有obfuscation-rules.txt文件,混淆开启时会加载obfuscation-rules.txt中的配置,完成指定的混淆功能。

混淆开启条件如下:

  • 工程为Stage模型
  • 在Release编译模式下
  • 模块build-profile.json5文件中开启混淆配置

满足上述开启混淆条件后,选择目标模块点击Build -> Make Module选项开始编译。

如果你的工程或者模块是Static Library,那么该工程或模块是一个HAR。

HAR类型有如下两种构造方式:

DevEco Studio在Debug模式构建HAR,直接将源码打包

DevEco Studio在Release模式构建HAR,会对代码进行编译、混淆及压缩处理

若需要对发布的HAR代码资产进行保护时,建议在release模式下开启混淆能力。

编译选项

上述编译过程中混淆开启的是默认配置,仅混淆了局部变量。若想混淆更多名称,需要在模块中的混淆配置文件obfuscation-rules.txt添加混淆选项。

详情参考文档中心

混淆规则合并策略

工程的主模块(一般为entry)会依赖工程中的其他模块,同时也可能依赖一些远程har包,这使得我们在编译工程时难以弄清工程中的每个模块是按什么混淆配置进行混淆的。

实际上,当我们编译整个工程时会加载主模块的obfuscation-rules.txt、依赖的HAR中consumer-rules.txt和远程HAR包的obfuscation.txt三类混淆配置文件,进行规则合并获取此次编译过程的混淆规则。

HAR模块的build-profile.json5中consumerFiles配置了共享混淆配置文件,该文件生效条件:

  • HAR模块被依赖
  • HAR模块开启混淆

调试

经过混淆工具处理后的代码名称会发生更改,这可能会使运行时crash堆栈日志难以理解,因为堆栈与源代码不完全一致。如果未保留调试信息,就可能会出现因行号及名称更改无法定位问题的情况。此外,开启-enable-property-obfuscation、-enable-toplevel-obfuscation等选项,代码混淆可能会引发运行时crash或者是功能性错误,需要开发人员还原报错堆栈来排查定位哪些名称与属性需要配置白名单来保障功能正常。

函数调用栈还原

程序出现运行时crash会打印报错堆栈,堆栈行号及名称对应于编译及混淆后的缓存文件。开发人员可使用DevEco Studio命令工具Command Line Tools中的hstack插件来还原为源码堆栈。如需支持对应用的堆栈进行还原,需要确保保留足够的信息以进行还原。应用每次编译时都会生成sourceMaps.map,其中存储源代码与编译代码对应位置映射的信息。若开启混淆还会生成nameCache.json文件,其中存储源代码与混淆代码对应名称映射的信息。

DevEco Studio会将sourceMaps.map文件保存在build/default/cache/default/default@CompileArkTS/esmodule/release目录中,将nameCache.json文件保存在build/default/cache/default/default@CompileArkTS/esmodule/release/obfuscation目录中。Hstack插件读取sourceMaps.map文件中的位置映射关系与nameCache.json混淆名称映射关系实现将release应用crash堆栈还原为源码对应堆栈,详情请查看hstack使用指导

反混淆工具hstack

hstack需要将Node.js配置到环境变量中,详细使用说明请参考hstack

报错解决办法【HarmonyOS NEXT】鸿蒙 代码混淆_鸿蒙 混淆-CSDN博客

实例

分布式通讯录-HarmonyOS NEXT-Codelabs-华为开发者联盟 (huawei.com)

进行混淆操作后,查看混淆后的代码,以ListPageViewModel.ets为例,这个文件在混淆之后生成了ListPageViewModel.ts和ListPageViewModel.protobin

下面展示ListPageViewModel.ets和ListPageViewModel.ts

很明显观察到这个方法里的一个局部变量被重命名了context=>q30

生成hap无误

疑问:能否用arkanalyzer对混淆编译之后的文件进行数据流和控制流分析?

let files: ArkFile[] = projectScene.getFiles();
let fileNames: string[] = files.map(file => file.getName());
console.log(fileNames[98]);
let classes: ArkClass[] = files[98].getClasses();
let classNames: string[] = classes.map(cls => cls.getName());
console.log(classNames);

类名不变,读取不变

Def-use chain

for (const arkFile of projectScene.getFiles()) {
    for (const arkClass of arkFile.getClasses()) {
        for (const arkMethod of arkClass.getMethods()) {
            if (arkMethod.getName() == 'startAbility') {
                continue;
            }
            console.log('*** arkMethod: ', arkMethod.getName());

            const body = arkMethod.getBody();
            if (body) {
                const cfg = body.getCfg();
                cfg.buildDefUseChain();
                for (const chain of cfg.getDefUseChains()){
                    console.log("variable: "+chain.value.toString()+", def: "+chain.def.toString()+", use: "+chain.use.toString());
                }
            } else {
                console.warn("Warning: 'getBody()' returned undefined.");
            }
        }
    }
}

名称有变化,说明混淆有影响

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值