【HarmonyOS NEXT】鸿蒙 代码混淆

代码混淆简介

针对工程源码的混淆可以降低工程被破解攻击的风险,缩短代码的类与成员的名称,减小应用的大小。

DevEco Studio提供代码混淆的能力并默认开启,API 10及以上版本的Stage模型、编译模式为release时自动进行代码混淆。

使用约束

  • 仅支持Stage工程
  • 编译模式为release
  • 模块及模块依赖的HAR均未配置关闭混淆的规则-disable-obfuscation

混淆范围

在应用工程中,代码混淆支持以下格式文件混淆,混淆后的缓存文件保存在模块目录下的build/[...]/release目录下。

  • ArkTS文件
  • TS文件
  • JS文件

开启代码混淆

代码混淆已经被集成了到SDK中,可以在DevEco Studio中很方便地使用。

代码混淆目前只提供名称混淆的能力(因为其它混淆能力会劣化性能)。 开启代码混淆可以混淆以下名称:

  • 参数名和局部变量名
  • 顶层作用域的名称
  • 属性名称

代码混淆默认使能对参数名和局部变量名的混淆。顶层作用域名称和属性名称的混淆是默认关闭的,因为默认打开可能会导致运行时错误。这些混淆功能通过混淆选项来开启它们。

创建一个新工程的时候,配置文件build-profile.json5中会自动生成以下内容:


"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": ["./obfuscation-rules.txt"],
}
}
}

创建一个新的library的时候,还会额外生成consumerFiles属性:


"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": ["./obfuscation-rules.txt"],
}
"consumerFiles": ["./consumer-rules.txt"]
}
}

混淆功能默认开启,若被关闭希望重新开启混淆需要满足条件: 属性ruleOptions.enable的值为true。

属性ruleOptions.files中指定的混淆配置文件会在构建HAP、HSP或HAR的时候生效。

属性consumerFiles中指定的混淆配置文件会在构建依赖这个library的模块时生效。 这些混淆配置文件的内容还会被合并到HAR包中的obfuscation.txt文件。

当构建HAP、HSP和HAR的时候,最终的混淆规则是当前构建模块的ruleOptions.files属性,依赖library的consumerFiles属性,以及依赖HAR包中的obfuscation.txt文件的合并。

如果构建的是HAR,HAR包中的obfuscation.txt是自身的consumerFiles属性, 依赖library的consumerFiles属性,以及依赖HAR包中的obfuscation.txt文件的合并。构建HAP、HSP不会生成obfuscation.txt。

混淆规则配置文件

在创建工程或library的时候,DevEco Studio会自动生成obfuscation-rules.txt和consumer-rules.txt文件,

但是它们默认不会包含任何混淆规则。混淆规则可以写到这些文件中,或者其它自定义文件,

然后将文件路径放到ruleOptions.files和consumerFiles中,如下面的例子所示。


"buildOption": {
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": ["./obfuscation-rules.txt", "./myrules.txt"], //myrules.txt放入配置文件build-profile.json5同级目录下
}
"consumerFiles": ["./consumer-rules.txt", "./my-consumer-rules.txt"]
}
}
}

配置混淆规则

混淆规则分为两种类型,一种是混淆选项,一种是保留选项;前者是提供顶层作用域名称、属性名称、文件名称等多种混淆功能配置开关,后者是提供各种混淆功能的白名单配置能力。

混淆选项

-disable-obfuscation

关闭所有混淆。如果使用这个选项,那么构建出来的HAP、HSP或HAR将不会被混淆。

-enable-property-obfuscation

开启属性混淆。 如果使用这个选项,那么所有的属性名都会被混淆,除了下面场景:

  • 被import/export直接导入或导出的类、对象的属性名不会被混淆。例如下面例子中的属性名data不会被混淆。

    
    export class MyClass {
    data: string;
    }
  • ArkUI组件中的属性名不会被混淆。例如下面例子中的message和data不会被混淆。

    
    @Component struct MyExample {
    @State message: string = "hello";
    data: number[] = [];
    ...
    }
  • 被保留选项指定的属性名不会被混淆。

  • SDK API列表中的属性名不会被混淆。SDK API列表是构建时从SDK中自动提取出来的一个名称列表,其缓存文件为systemApiCache.json,路径为工程目录下build/cache/{...}/release/obfuscation中

  • 在Native API场景中,so库对应的d.ts文件中声明的API不会被混淆。

  • 字符串字面量属性名不会被混淆。例如下面例子中的"name"和"age"不会被混淆。

    
    let person = {"name": "abc"};
    person["age"] = 22;

    如果想混淆字符串字面量属性名,需要在该选项的基础上再使用-enable-string-property-obfuscation选项。例如

    
    -enable-property-obfuscation
    -enable-string-property-obfuscation

    注意

    1. 如果代码里面有字符串属性名包含特殊字符(除了a-z, A-Z, 0-9, _之外的字符),例如let obj = {"\n": 123, "": 4, " ": 5},建议不要开启-enable-string-property-obfuscation选项,因为可能无法通过保留选项来指定保留这些名字。

    2. SDK API的属性白名单中不包含声明文件中使用的字符串常量值,例如示例中的字符串'ohos.want.action.home'未包含在属性白名单中

    
    // SDK API文件@ohos.app.ability.wantConstant片段:
    export enum Params {
    ACTION_HOME = 'ohos.want.action.home'
    }
    // 开发者源码示例:
    let params = obj['ohos.want.action.home'];

    因此在开启了-enable-string-property-obfuscation选项时,如果想保留代码中使用的SDK API字符串常量的属性不被混淆,例如obj['ohos.want.action.home'], 那么需要使用keep选项保留。

-enable-toplevel-obfuscation

开启顶层作用域名称混淆。如果使用这个选项,那么所有的顶层作用域的名称都会被混淆,除了下面场景:

  • 被import/export的名称不会被混淆。
  • 当前文件找不到声明的名称不会被混淆。
  • 被保留选项指定的顶层作用域名称不会被混淆。
  • SDK API列表中的顶层作用域名称不会被混淆。

-enable-filename-obfuscation

开启文件/文件夹名称混淆。如果使用这个选项,那么所有的文件/文件夹名称都会被混淆,除了下面场景:

  • oh-package.json5文件中'main'、'types'字段配置的文件/文件夹名称不会被混淆。
  • 模块内module.json5文件中'srcEntry'字段配置的文件/文件夹名称不会被混淆。
  • 被-keep-file-name指定的文件/文件夹名称不会被混淆。
  • 非ECMAScript模块引用方式(ECMAScript模块示例:import {foo} from './filename')
  • 非路径引用方式,例如例子中的json5不会被混淆 import module from 'json5'

注意

由于系统会在应用运行时加载某些指定的文件,针对这类文件,开发者需要手动在[-keep-file-name]选项中配置相应的白名单,防止指定文件被混淆,导致运行失败。

上述需要手动配置白名单的情况,包括但不限于以下场景:

  • 当模块中包含Ability组件时。用户需要将src/main/module.json5中,'abilities'字段下所有'srcEntry'对应的路径配置到白名单中。
  • 当模块中包含Worker多线程服务时,用户需要将build-profiles.json5中,'buildOption'-'sourceOption'-'workers'字段下所有的路径配置到白名单中。

-enable-export-obfuscation

开启直接导入或导出的类或对象的名称和属性名混淆。如果使用这个选项,那么模块中的直接导入或导出的名称都会被混淆,除了下面场景:

  • 远程HAR(真实路径在oh_modules中的包)中导出的类或对象的名称和属性名不会被混淆。
  • 被保留选项指定的名称与属性名不会被混淆。
  • SDK API列表中的名称不会被混淆。

注意

  1. 混淆导入或导出的类中属性名称需要同时开启-enable-property-obfuscation与-enable-export-obfuscation选项。

  2. 编译HSP时,如果开启-enable-export-obfuscation选项,需要在模块中的混淆配置文件obfuscation-rules.txt中保留对外暴露的接口。

  3. HAP/HSP/HAR依赖HSP场景下,编译时如果开启-enable-export-obfuscation选项,需要在模块中的混淆配置文件obfuscation-rules.txt中保留HSP导入的接口。

    
    // 代码示例(HSP中入口文件Index.ets):
    export { add, customApiName } from './src/main/ets/utils/Calc'
    
    // 保留接口名称配置示例:
    // HSP以及依赖此HSP的模块中obfuscation-rules.txt文件配置:
    keep-global-name
    add
    customApiName

-compact

去除不必要的空格符和所有的换行符。如果使用这个选项,那么所有代码会被压缩到一行。

注意

release模式构建的应用栈信息仅包含代码行号,不包含列号,因此compact功能开启后无法依据报错栈中的行号定位到源码具体位置。

-remove-log

删除以下场景中对 console.*语句的调用,要求console.*语句返回值未被调用。

  1. 文件顶层的调用
  2. 代码块Block中的调用
  3. 模块Module中的调用
  4. switch语句中的调用

-print-namecache filepath

将名称缓存保存到指定的文件路径。名称缓存包含名称混淆前后的映射。

注意

每次全量构建工程时都会生成新的namecache.json文件,因此您每次发布新版本时都要注意保存一个该文件的副本。

-apply-namecache filepath

复用指定的名称缓存文件。名字将会被混淆成缓存映射对应的名字,如果没有对应,将会被混淆成新的随机段名字。

该选项应该在增量编译场景中被使用。

默认情况下,DevEco Studio会在临时的缓存目录中保存缓存文件,并且在增量编译场景中自动应用该缓存文件。

缓存目录:build/cache/{...}/release/obfuscation

-remove-comments

删除文件中的所有注释,包括单行、多行,及JsDoc注释。以下场景除外:

声明文件中,在-keep-comments中配置的类、方法、struct、枚举等名称上方的JsDoc注释。

注意

编译生成的源码文件中的注释默认会被全部删除,不支持配置保留。

保留选项

-keep-property-name [,identifiers,...]

指定想保留的属性名,支持使用名称类通配符。例如下面的例子:


-keep-property-name
age
firstName
lastName

注意

该选项在开启-enable-property-obfuscation时生效

哪些属性名应该被保留?

为了保障混淆的正确性,建议保留所有不通过点语法访问的属性。

例子:


var obj = {x0: 0, x1: 0, x2: 0};
for (var i = 0; i <= 2; i++) {
console.log(obj['x' + i]); // x0, x1, x2 应该被保留
}

Object.defineProperty(obj, 'y', {}); // y 应该被保留
console.log(obj.y);

obj.s = 0;
let key = 's';
console.log(obj[key]); // s 应该被保留

obj.u = 0;
console.log(obj.u); // u 可以被正确地混淆

obj.t = 0;
console.log(obj['t']); // 在开启字符串字面量属性名混淆时t和't'会被正确地混淆,但是建议保留

obj['v'] = 0;
console.log(obj['v']); // 在开启字符串字面量属性名混淆时'v'会被正确地混淆,但是建议保留

对于间接导出的场景,例如export MyClass和let a = MyClass; export {a};,如果不想混淆它们的属性名,那么需要使用保留选项来保留这些属性名。另外,对于直接导出的类或对象的属性的属性名,例如下面例子中的name和age, 如果不想混淆它们,那么也需要使用保留选项来保留这些属性名。


export class MyClass {
person = {name: "123", age: 100};
}

没有在so库的d.ts文件中声明的API(例如示例中的foo),如果要在ArkTS/TS/JS文件中使用需手动保留API名称。


import testNapi from 'library.so'
testNapi.foo()

使用到的json文件中的字段,需要手动保留。


const jsonData = ('./1.json')
let jsonStr = JSON.parse(jsonData)
let jsonObj = jsonStr.jsonProperty // jsonProperty 需要保留

使用到的数据库相关的字段,需要手动保留。


const dataToInsert = {
value1: 'example1', // value1 需要保留
};

-keep-global-name [,identifiers,...]

指定要保留的顶层作用域的名称,支持使用名称类通配符。例如,


-keep-global-name
Person
printPersonName

哪些顶层作用域的名称应该被保留?

在Javascript中全局变量是globalThis的属性。如果在代码中使用globalThis去访问全局变量,那么该变量名应该被保留。

示例:


var a = 0;
console.log(globalThis.a); // a 应该被保留

function foo(){}
globalThis.foo(); // foo 应该被保留

var c = 0;
console.log(c); // c 可以被正确地混淆

function bar(){}
bar(); // bar 可以被正确地混淆

class MyClass {}
let d = new MyClass(); // MyClass 可以被正确地混淆

-keep-file-name [,identifiers,...]

指定要保留的文件/文件夹的名称(不需要写文件后缀),支持使用名称类通配符。例如,


-keep-file-name
index
entry

哪些文件名应该被保留?


const module1 = require('./file1') // ArkTS不支持CommonJS语法,这种路径引用应该被保留
const moduleName = './file2'
const module2 = import(moduleName) // 动态引用方式无法识别moduleName是否是路径,应该被保留

-keep-comments [,identifiers,...]

保留声明文件中元素上方的JsDoc注释,支持使用名称类通配符。例如想保留声明文件中Human类上方的JsDoc注释,可进行以下配置:


-keep-comments
Human

注意

  1. 该选项在开启-remove-comments时生效
  2. 当声明文件中某个元素名称被混淆时,该元素上方的JsDoc注释无法通过-keep-comments保留。例如当在-keep-comments中配置了exportClass时,如果下面的类名被混淆,其JsDoc注释无法被保留:

/*
* @class exportClass
*/
export class exportClass {}

-keep-dts filepath

保留指定路径的.d.ts文件中的名称。这里的文件路径可以是一个目录,这种情况下目录中所有.d.ts文件中的名称都会被保留。

如果在构建HAR时使用了这个选项,那么文件中的名称会被合并到最后的obfuscation.txt文件中。

-keep path

保留指定路径中的所有名称(例如变量名、类名、属性名等)不被混淆。这个路径可以是文件与文件夹,若是文件夹,则文件夹下的文件及子文件夹中文件都不混淆。

路径仅支持相对路径,./与../为相对于混淆配置文件所在目录,支持使用路径类通配符。

 
  1. -keep
  2. ./src/main/ets/fileName.ts // fileName.ts中的名称不混淆
  3. ../folder // folder目录下文件及子文件夹中的名称都不混淆
  4. ../oh_modules/json5 // 引用的三方库json5里所有文件中的名称都不混淆

注:该功能不影响文件名混淆-enable-filename-obfuscation的功能

保留选项支持的通配符

名称类通配符

名称类通配符使用方式如下:

通配符含义示例
?匹配任意单个字符"AB?"能匹配"ABC"等,但不能匹配"AB"
*匹配任意数量的任意字符"*AB*"能匹配"AB"、"aABb"、"cAB"、"ABc"等

使用示例

保留所有以a开头的属性名称:


-keep-property-name
a*

保留所有单个字符的属性名称:


-keep-property-name
?

保留所有属性名称:


-keep-property-name
*

路径类通配符

路径类通配符使用方式如下:

通配符含义示例
?匹配任意单个字符,除了路径分隔符/"../a?"能匹配"../ab"等,但不能匹配"../a/"
*匹配任意数量的任意字符,除了路径分隔符/"../a*/c"能匹配"../ab/c",但不能匹配"../ab/d/s/c"
**匹配任意数量的任意字符"../a**/c"能匹配"../ab/c",也能匹配"../ab/d/s/c"
!表示非,只能写在某个路径最前端,用来排除用户配置的白名单中已有的某种情况"!../a/b/c.ets"表示除"../a/b/c.ets"以外

使用示例

表示路径../a/b/中所有文件夹(不包含子文件夹)中的c.ets文件不会被混淆:


-keep
../a/b/*/c.ets

表示路径../a/b/中所有文件夹(包含子文件夹)中的c.ets文件不会被混淆:


-keep
../a/b/**/c.ets

表示路径../a/b/中,除了c.ets文件以外的其它文件都不会被混淆。其中,!不可单独使用,只能用来排除白名单中已有的情况:


-keep
../a/b/
!../a/b/c.ets

表示路径../a/中的所有文件(不包含子文件夹)不会被混淆:


-keep
../a/*

表示路径../a/下的所有文件夹(包含子文件夹)中的所有文件不会被混淆:


-keep
../a/**

表示模块内的所有文件不会被混淆:


-keep
./**

注意

(1)以上选项,不支持配置通配符*、?、!作其它含义使用。

例如:

class A {
'*'= 1
}

-keep-property-name
*

此时*表示匹配任意数量的任意字符,配置效果为所有属性名称都不混淆,而不是只有*属性不被混淆。

(2)-keep选项中只允许使用/路径格式,不支持\或\\。

注释

可以使用#在混淆规则文件中进行注释。每行以#开头的文本会被当做是注释,例如下面的例子:


# white list for MainAbility.ets
-keep-global-name
MyComponent
GlobalFunction

-keep-property-name # white list for dynamic property names
firstName
lastName
age

构建HAR时,注释不会被合并到最后的obfuscation.txt文件中。

混淆规则合并策略

一个工程中经常会有许多混淆规则文件,这些文件来自于:

  • 主工程的ruleOptions.files (这里主工程指的是正在构建的工程)
  • 本地依赖的library中的consumerFiles选项中指定的文件
  • 远程依赖的HAR包中的obfuscate.txt文件

当构建主工程的时候,这些文件中的混淆规则会按照下面的合并策略(伪代码)进行合并:


let `listRules` 表示上面提到的所有混淆规则文件的列表
let finalRule = {
disableObfuscation: false,
enablePropertyObfuscation: false,
enableToplevelObfuscation: false,
compact: false,
removeLog: false,
keepPropertyName: [],
keepGlobalName: [],
keepDts: [],
printNamecache: string,
applyNamecache: string
}
for each file in `listRules`:
for each option in file:
switch(option) {
case -disable-obfuscation:
finalRule.disableObfuscation = true;
continue;
case -enable-property-obfuscation:
finalRule.enablePropertyObfuscation = true;
continue;
case -enable-toplevel-obfuscation:
finalRule.enableToplevelObfuscation = true;
continue;
case -compact:
finalRule.compact = true;
continue;
case -remove-log:
finalRule.removeLog = true;
continue;
case -print-namecache:
finalRule.printNamecache = #{指定的路径名};
continue;
case -apply-namecache:
finalRule.applyNamecache = #{指定的路径名};
continue;
case -keep-property-name:
finalRule.keepPropertyName.push(#{指定的名称});
continue;
case -keep-global-name:
finalRule.keepGlobalName.push(#{指定的名称});
continue;
case -keep-dts:
finalRule.keepDts.push(#{指定的路径});
continue;
}
end-for
end-for

最后使用的混淆规则来自于对象finalRule。

如果构建的是HAR,那么最终的obfuscate.txt文件内容来自于主工程和本地依赖的library的consumerFiles选项,

以及依赖的HAR的obfuscate.txt文件的合并。合并策略和上面一样,除了以下的不同:

  • -keep-dts选项会被转换成-keep-global-name和-keep-property-name。
  • -print-namecache和apply-namecache选项会被忽略,不会出现在最后的obfuscate.txt文件中。

报错栈还原

经过混淆的应用程序中代码名称会发生更改,crash时打印的报错栈更难以理解,因为报错栈与源码不完全一致。开发人员可使用DevEco Studio命令工具Command Line Tools中的hstack插件来还原源码堆栈。

说明

  • 目前不支持在hvigor构建流程中插入自定义混淆插件
  • 混淆的HAR包被模块依赖,若模块开启混淆,则HAR包会被二次混淆
  • DevEco Studio右上角Product选项,将其中Build Mode选择release,可开启release编译模式

FAQ

混淆各功能上线SDK版本

混淆选项功能描述最低版本号
-disable-obfuscation关闭混淆4.0.9.2
-enable-property-obfuscation属性混淆4.0.9.2
-enable-string-property-obfuscation字符串字面量属性名混淆4.0.9.2
-enable-toplevel-obfuscation顶层作用域名称混淆4.0.9.2
-enable-filename-obfuscation

HAR包文件/文件夹名称混淆

HAP/HSP文件/文件夹名称混淆

4.1.5.3

5.0.0.19

-enable-export-obfuscation向外导入或导出的名称混淆4.1.5.3
-compact去除不必要的空格符和所有的换行符4.0.9.2
-remove-log删除特定场景中的console.*4.0.9.2
-print-namecache将名称缓存保存到指定的文件路径4.0.9.2
-apply-namecache复用指定的名称缓存文件4.0.9.2
-remove-comments删除文件中所有注释4.1.5.3
-keep-property-name保留属性名4.0.9.2
-keep-global-name保留顶层作用域的名称4.0.9.2
-keep-file-name

保留HAR包的文件/文件夹的名称

保留HAP/HSP包的文件/文件夹的名称

4.1.5.3

5.0.0.19

-keep-dts保留指定路径的.d.ts文件中的名称4.0.9.2
-keep-comments保留声明文件中元素上方的JsDoc注释4.1.5.3
-keep保留指定路径中的所有名称5.0.0.18
通配符名称类和路径类的保留选项支持通配符5.0.0.24

如何查看混淆效果

开发人员可以在编译产物build目录中找到混淆后的文件,以及混淆生成的名称映射表及系统API白名单文件。

  • 混淆后的文件目录:build/[...]/release/模块名

  • 混淆名称映射表及系统API白名单目录:build/[...]/release/obfuscation

    • 名称映射表文件:nameCache.json,该文件记录了源码名称混淆的映射关系。
    • 系统API白名单文件:systemApiCache.json,该文件记录了SDK中的接口与属性名称,与其重名的源码不会被混淆。

如何排查功能异常

  1. 先在obfuscation-rules.txt配置-disable-obfuscation选项关闭混淆,确认问题是否由混淆引起。
  2. 若确认是开启混淆后功能出现异常,建议查看混淆构建产物分析代码逻辑,寻找代码异常原因。
  3. 若是白名单未配置导致的错误,请在配置文件中使用保留选项来配置白名单。

常见报错案例

开启-enable-property-obfuscation选项可能出现的问题

案例一:报错内容为 Cannot read property 'xxx' of undefined

 
  1. // 混淆前
  2. const jsonData = ('./1.json')
  3. let jsonStr = JSON.parse(jsonData)
  4. let jsonObj = jsonStr.jsonProperty
  5. // 混淆后
  6. const jsonData = ('./1.json')
  7. let jsonStr = JSON.parse(jsonData)
  8. let jsonObj = jsonStr.i

开启属性混淆后,"jsonProperty" 被混淆成随机字符 "i",但json文件中为原始名称,从而导致值为undefined。

解决方案: 使用-keep-property-name选项将json文件里的字段配置到白名单。

案例二:使用了数据库相关的字段,开启属性混淆后,出现报错

报错内容为 table Account has no column named a23 in 'INSET INTO Account(a23)'

代码里使用了数据库字段,混淆时该SQL语句中字段名称被混淆,但数据库中字段为原始名称,从而导致报错。

解决方案: 使用-keep-property-name选项将使用到的数据库字段配置到白名单。

开启-enable-export-obfuscation和-enable-toplevel-obfuscation选项可能出现的问题

当开启这两个选项时,主模块调用其他模块方法时涉及的方法名称混淆情况如下:

主模块依赖模块导入与导出的名称混淆情况
HAP/HSPHSPHSP和主模块是独立编译的,混淆后名称会不一致,因此都需要配置白名单
HAP/HSP本地HAR本地HAR与主模块一起编译,混淆后名称一致
HAP/HSP三方库三方库中导出的名称及其属性会被收集到白名单,因此导入和导出时都不会被混淆

HSP需要将给其他模块用的方法配置到白名单中。因为主模块里也需要配置相同的白名单,所以推荐将HSP配置了白名单的混淆文件(假设名称为hsp-white-list.txt)添加到依赖它的模块的混淆配置项里,即下图files字段里。

案例一:动态导入某个类,类定义的地方被混淆,导入类名时却没有混淆,导致报错


// 混淆前
export class Test1 {}

let mytest = (await import('./file')).Test1

// 混淆后
export class w1 {}

let mytest = (await import('./file')).Test1

导出的类 "Test1" 是一个顶层作用域名,当 "Test1" 被动态使用时,它是一个属性。因为没有开启-enable-property-obfuscation选项,所以名称混淆了,但属性没有混淆。

解决方案: 使用-keep-global-name选项将 "Test1" 配置到白名单。

案例二:在使用namespace中的方法时,该方法定义的地方被混淆了,但使用的地方却没有被混淆,导致报错


// 混淆前
export namespace ns1 {
export class person1 {}
}

import {ns1} from './file1'
let person1 = new ns1.person1()

// 混淆后
export namespace a3 {
export class b2 {}
}

import {a3} from './file1'
let person1 = new a3.person1()

namespace里的 "person1" 属于顶层作用域的class名称,通过 "ns1.person1" 来调用时,它是属于一个属性,由于未开启属性混淆,所以在使用它时没有被混淆。

解决方案:

  1. 开启-enable-property-obfuscation选项。
  2. 将namespace里导出的方法使用-keep-global-name选项添加到白名单。

案例三:使用了declare global,混淆后报语法错误


// 混淆前
declare global {
var age : string
}

// 混淆后
declare a2 {
var b2 : string
}

报错内容为 SyntaxError: Unexpected token

解决方案: 使用-keep-global-name选项将__global配置到白名单中。

未开启-enable-string-property-obfuscation混淆选项,字符串字面量属性名却被混淆,导致字符串字面量属性名的值为undefined


person["age"] = 22; // 混淆前

person["b"] = 22; // 混淆后

解决方案:

  1. 确认是否有依赖的HAR包开启了字符串属性名混淆,若开启了,则会影响主工程,需将其关闭。
  2. 若不能关闭-enable-string-property-obfuscation选项,将属性名配置到白名单中。
  3. 若依赖HAR包未开启字符串属性名混淆,同时SDK版本小于4.1.5.3,请更新SDK。

开启-enable-filename-obfuscation选项后,可能会出现的问题

案例一:报错为 Error Failed to get a resolved OhmUrl for 'D:code/MyApplication/f12/library1/pages/d.ets' imported by 'undefined'

工程的目录结构如下图所示,模块library1的外层还有目录 "directory",开启文件名混淆后,"directory" 被混淆为f12,导致路径找不到。

解决方案:

  1. 如果工程的目录结构和报错内容都相似,请将SDK更新至最低5.0.0.26版本。
  2. 使用-keep-file-name将模块外层的目录名 "directory" 配置到白名单中。

案例二:报错为 Cannot find module 'ets/appability/AppAbility' which is application Entry Point

由于系统会在应用运行时加载ability文件,用户需要手动配置相应的白名单,防止指定文件被混淆,导致运行失败。

解决方案: 使用-keep-file-name选项,将src/main/module.json5文件中,'srcEntry'字段所对应的路径配置到白名单中。


-keep-file-name
appability
AppAbility

使用-keep-global-name选项配置白名单时,可能会出现的问题

报错内容为 Cannot read properties of undefined (reading 'has')

解决方案: 将SDK更新至最低4.1.6.3版本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/790748.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MD5加密和注册页面的编写

MD5加密 1.导入包 npm install --save ts-md5 2.使用方式 import { Md5 } from ts-md5; //md5加密后的密码 const md5PwdMd5.hashStr("123456").toUpperCase(); 遇见的问题及用到的技术 注册页面 register.vue代码 <template><div class"wappe…

GBPC5010-ASEMI逆变箱专用GBPC5010

编辑&#xff1a;ll GBPC5010-ASEMI逆变箱专用GBPC5010 型号&#xff1a;GBPC5010 品牌&#xff1a;ASEMI 封装&#xff1a;GBPC-4 批号&#xff1a;2024 现货&#xff1a;50000 最大重复峰值反向电压&#xff1a;1000V 最大正向平均整流电流(Vdss)&#xff1a;50A 功…

越南语是一门什么样的语言?如何学好越南语?

越南语是一种南亚语系越芒语族的语言&#xff0c;具有丰富的汉语借词&#xff0c;尤其在抽象概念的表达上&#xff0c;汉越词汇占有很大比例。作为一种声调语言&#xff0c;越南语拥有六个声调&#xff0c;这使得其发音具有音乐性和节奏感。它是一种孤立语&#xff0c;依赖于语…

Xshell配置ssh免密码登录(密钥登陆)

文章目录 一、Xshell登陆步骤 一、Xshell登陆步骤 1.生成客户端的公钥私钥 2.生成公钥文件 3.生成私钥文件 4.将公钥传输进要登录的服务器中 5.修改公钥文件名为authorized_keys (authorized_keys是用于存储公钥的特殊文件,如果已经有了这份文件,可以在末尾追加) 6.连…

芋道源码 yudao-cloud 文档,视频,开发指南如何看全部

进入官网后可以看到相关内容 但是后端手册开始就看不了了 必须加入知识知识星球才行&#xff0c;很烦 闲**鱼搜索用户 水城打坐的藤壶 找到这个链接 这下大家都懂了吧 现在就可以看到看不到的内容了 在线文档的弹窗可技术去除&#xff0c;很简单 直接起飞哈 包括更新sq…

LIO-SAM编译ubuntu20.04 Noetic

一、下载 mkdir -p ~/lio_sam_ws/src cd ~/lio_sam_ws/src git clone https://github.com/TixiaoShan/LIO-SAM.git cd ..二、编译&&解决报错 catkin_make报错如下 解决方案&#xff1a; 第一步&#xff1a; sudo add-apt-repository ppa:borglab/gtsam-release-4…

2.快速搭建 SpringBoot hello world

环境要求&#xff1a; Spring Boot 2.6.1 需要Java 8&#xff0c;并且与Java 15&#xff08;包括&#xff09;兼容。 还需要Spring Framework 5.2.10.RELEASE或 更高版本。 注意&#xff1a;Spring Boot 3.0版本以上就需要 Java 8以上了&#xff0c;即不能再使用 Java8版本了。…

数据存储方案选择:ES、HBase、Redis、MySQL与MongoDB的应用场景分析

一、概述 1.1 背景 在当今数据驱动的时代&#xff0c;选择合适的数据存储技术对于构建高效、可靠的信息系统至关重要。随着数据量的爆炸式增长和处理需求的多样化&#xff0c;市场上涌现出了各种数据存储解决方案&#xff0c;每种技术都有其独特的优势和适用场景。Elasticsear…

单词间隔重复算法

间隔重复算法 理论背景 遗忘曲线是一种描述记忆遗忘率的模型&#xff0c;艾宾浩斯在其著作《记忆&#xff1a;实验心理学的贡献》中首次详细描述了遗忘曲线&#xff0c;他使用了一些无意义的字母组合作为记忆对象&#xff0c;通过在不同的时间间隔后检查记忆的遗忘程度&#…

ArcGis将同一图层的多个面要素合并为一个面要素

这里写自定义目录标题 1.加载面要素的shp数据 2.点击菜单栏的地理处理–融合&#xff0c;如下所示&#xff1a; 3.将shp面要素输入&#xff0c;并设置输出&#xff0c;点击确定即可合并。合并后的属性表就只有一个数据了。

钡铼网关: 轻松实现PLC与OPC UA服务器的双向通信

在当今工业4.0的大潮下&#xff0c;实现不同设备、系统之间的高效通信和数据交换已大势所趋&#xff01;PLC与OPC UA服务器的对接&#xff0c;对于打造智能工厂具有重要意义&#xff0c;本文将深入探讨钡铼技术的网关如何实现这一过程&#xff0c;为用户提供快速且低成本的解决…

godis源码分析——Redis协议解析器

前言 redis这个目录下的所有代码就是为了一个事情&#xff0c;就是适配redis。 流程 redis下的基本流程 源码 在redis/client/client.go 主要是客户端处理 package clientconst (created iotarunningclosed )type B struct {data chan stringticker *time.Ticker }// …

【基于R语言群体遗传学】-16-中性检验Tajima‘s D及连锁不平衡 linkage disequilibrium (LD)

Tajimas D Test 已经开发了几种中性检验&#xff0c;用于识别模型假设的潜在偏差。在这里&#xff0c;我们将说明一种有影响力的中性检验&#xff0c;即Tajimas D&#xff08;Tajima 1989&#xff09;。Tajimas D通过比较数据集中的两个&#x1d703; 4N&#x1d707;估计值来…

【栈和队列】

目录 一、栈1.1、栈的基本概念1.2、栈的基本操作1.3、栈的顺序存储实现1.3.1、顺序栈的定义1.3.2、顺序栈的初始化1.3.3、顺序栈的入栈和出栈1.3.4、读取栈顶元素1.3.5、共享栈&#xff08;即两个栈共享同一片空间&#xff09; 1.4、栈的链式存储实现1.4.1、链栈的定义1.4.2、链…

Spring Boot 高级配置:如何轻松定义和读取自定义配置

目录 1. 环境准备 2. 读取配置数据 2.1 使用 Value注解 2.2 Environment对象 2.3.2.3 自定义对象 这篇博客我们将深入探讨如何在Spring Boot应用中有效地定义和读取自定义配置。掌握这一技巧对于任何希望优化和维护其应用配置的开发者来说都是至关重要的。我们将从基础开始…

昆法尔The Quinfall在Steam上怎么搜索 Steam上叫什么名字

昆法尔The Quinfall是一款全新的MMORPG&#xff0c;在中世纪的深处&#xff0c;参与独特的战斗和沉浸式的故事&#xff0c;有几十个不同的职业。而游戏中的战斗系统更是丰富多彩&#xff0c;无论是陆地激战、海上鏖战还是城堡围攻&#xff0c;都能让玩家感受到前所未有的刺激和…

BJT交流分析+共发射极(CE)放大器+单片机的中断系统(中断的产生背景+使用中断重写秒表程序+中断优先级)

2024-7-10&#xff0c;星期三&#xff0c;16:58&#xff0c;天气&#xff1a;阴&#xff0c;心情&#xff1a;晴。今天终于阴天啦&#xff0c;有点风凉快一点了&#xff0c;不然真要受不了了&#xff0c;然后没有什么特殊的事情发生&#xff0c;继续学习啦&#xff0c;加油加油…

blender 纹理绘制-贴花方式

贴画绘制-1分钟blender_哔哩哔哩_bilibili小鸡老师的【Blender风格化角色入门教程】偏重雕刻建模https://www.cctalk.com/m/group/90420100小鸡老师最新的【风格化角色全流程进阶教程】偏重绑定。早鸟价进行中&#xff01;欢迎试听https://www.cctalk.com/m/group/90698829, 视…

2024年PMP考试备考经验分享

PMP是项目管理领域最重要的认证之一,本身是IT行业比较流行的证书&#xff0c;近几年在临床试验领域也渐渐流行起来&#xff0c;是我周围临床项PM几乎人手一个的证书。 考试时间&#xff1a;PMP认证考试形式为180道选择题&#xff0c;考试时间为3小时50分。 考试计划&#xff…

政安晨【零基础玩转各类开源AI项目】基于Ubuntu系统部署MuseV (踩完了所有的坑):基于视觉条件并行去噪的无限长度和高保真虚拟人视频生成

目录 下载项目 创建虚拟环境 启动虚拟环境&执行项目依赖 基于DOCKER的尝试 A. 安装引擎 B. 下载桌面安装包 C. 安装桌面包 用Docker运行MuseV 1. 拉取镜像 ​编辑 2. 运行Docker镜像 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收…