• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Using ArkGuard for Bytecode Obfuscation
2
3> **NOTE**
4>
5> When releasing a version, to prevent subsequent code modifications from affecting production issue analysis and troubleshooting, you are advised to back up all files in the **build/default/cache/default/default@XXXCompileArkTS/esmodule/release/obfuscation** directory locally. If possible, you can directly back up the entire **release** directory.
6
7## Enabling Bytecode Obfuscation
8
9### How to Use
10
11Bytecode obfuscation has been integrated into the system and can be enabled for use in DevEco Studio.
12
13* Enabling the obfuscation switch
14
15    To enable obfuscation, set the **enable** field to **true** under **arkOptions.obfuscation.ruleOptions** in the **build-profile.json5** file of your module.
16
17    ```txt
18    "arkOptions": {
19        "obfuscation": {
20            "ruleOptions": {
21                "enable": true,
22                "files": ["./obfuscation-rules.txt"],
23            }
24        }
25    }
26    ```
27
28    To configure obfuscation options, manually edit the **obfuscation-rules.txt** file specified in the **files** field. Enable the following obfuscation options:
29
30    ```txt
31    -enable-bytecode-obfuscation # Activates bytecode obfuscation when enabled.
32    -enable-bytecode-obfuscation-debugging  # Controls debug output. If this option is enabled, obfuscation logs are generated. By default, this option is disabled.
33    ```
34
35    > **NOTE**
36    >
37    > Bytecode HAR files will not be re-obfuscated during integration.
38
39* Configuring obfuscation rules
40
41    Enabling the bytecode obfuscation switch activates the default settings, which include obfuscation of functions and classes that are not in the top-level scope. To enable additional obfuscation features, customize the **obfuscation-rules.txt** file specified in the **files** field. Note that the default values in this file may vary across different versions of DevEco Studio.
42
43    For example, in DevEco Studio of version 5.0.3.600 and later, the obfuscation configuration file is as follows, which indicates that property name obfuscation, top-level scope name obfuscation, file name obfuscation, and imported/exported name obfuscation are enabled.
44
45    ```txt
46    -enable-property-obfuscation
47    -enable-toplevel-obfuscation
48    -enable-filename-obfuscation
49    -enable-export-obfuscation
50    ```
51
52    You can also add comments to the obfuscation rule file by prefixing lines with the # symbol. For example:
53
54    ```txt
55    # options:
56    -enable-property-obfuscation
57    -enable-toplevel-obfuscation
58    -enable-filename-obfuscation
59    # -enable-export-obfuscation
60    -keep-property-name # white list for dynamic property names
61    ```
62
63    For details about how to configure obfuscation options, see [Obfuscation Configuration Guidelines](#obfuscation-configuration-guidelines). For details about all configuration files involved in obfuscation, see [Obfuscation Configuration Files](#obfuscation-configuration-files).
64
65    > **NOTE**
66    >
67    > By default, obfuscation is disabled for new projects. If you want to enable obfuscation, set the **ruleOptions.enable** field in the **build-profile.json5** file of the module to **true**. If required, enable the **-enable-bytecode-obfuscation** and **-enable-bytecode-obfuscation-debugging** options in the **obfuscation-rules.txt** file. By default, the following four recommended obfuscation options are enabled in the **obfuscation-rules.txt** file:** -enable-property-obfuscation**, **-enable-toplevel-obfuscation**, **-enable-filename-obfuscation**, and **-enable-export-obfuscation**. You can customize the obfuscation settings as needed.
68
69* Specifying release compilation
70
71    Currently, bytecode obfuscation is supported only for release builds, not for debug builds. This means that obfuscation will only be applied when a module is compiled in release mode, not in debug mode. You can view and modify the build mode by referring to [Specifying a Build Mode](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-hvigor-compilation-options-customizing-guide#section192461528194916).
72
73    > **NOTE**
74    >
75    > The differences between release and debug builds extend beyond obfuscation. To determine whether application behavior differences are due to obfuscation, you should enable or disable the obfuscation switch rather than simply switching between release and debug builds.
76
77### Obfuscation Configuration Files
78
79* `obfuscation-rules.txt`
80
81    For HAP, HAR, and HSP modules, the **arkOptions.obfuscation.ruleOptions.files** field in the **build-profile.json5** file specifies obfuscation rules applied during module compilation. A default **obfuscation-rules.txt** file is created when a new project is set up.
82
83* `consumer-rules.txt`
84
85    For HAR and HSP modules, an additional **arkOptions.obfuscation.consumerFiles** field is available in the **build-profile.json5** file. This field specifies obfuscation rules that should be applied when this package is depended upon in other modules. A default **consumer-rules.txt** file is created when a new HAR or HSP module is set up. The key difference between **consumer-rules.txt** and **obfuscation-rules.txt** is as follows: **obfuscation-rules.txt** applies to the compilation of the current module, whereas **consumer-rules.txt** applies to the compilation of other modules that depend on the current module.
86
87    ```txt
88    "arkOptions": {
89        "obfuscation": {
90            "ruleOptions": {
91                "enable": true,
92                "files": ["./obfuscation-rules.txt"],
93        }
94        "consumerFiles": ["./consumer-rules.txt"]
95        }
96    }
97    ```
98
99* `obfuscation.txt`
100
101    Unlike the above two files, **obfuscation.txt** is automatically generated based on **consumer-rules.txt** and the obfuscation rules of dependent modules during HAR or HSP compilation. It exists as a compilation product within the released HAR or HSP package and used to apply obfuscation rules when other applications use this package. For details about the generation and logic of **obfuscation.txt**, see [Obfuscation Rule Merging Strategies](bytecode-obfuscation.md#obfuscation-rule-merging-strategies).
102
103    > **NOTE**
104    >
105    > For third-party libraries, the **obfuscation.txt** file only takes effect when the module's **oh-package.json5** file depends on the library. If the dependency is specified in the project's **oh-package.json5** file, the **obfuscation.txt** file in the third-party library will not take effect.
106
107The following table summarizes the differences between these configuration files.
108
109| Configuration File| Configuration Type|  Modifiable |  Affects Obfuscation of This Module |  Affects Obfuscation of Other Modules |
110| --- | --- | --- | --- | --- |
111| obfuscation-rules.txt | Customizable | Yes| Yes| No|
112| consumer-rules.txt    | Customizable | Yes| No| Yes|
113| obfuscation.txt       | Compilation product| Not applicable (automatically generated during HAR or HSP compilation)| Not applicable| Yes|
114
115### Obfuscation Configuration Guidelines
116
1171. When **-enable-toplevel-obfuscation** is configured, access to global variables using **globalThis** fails. To rectify the fault, use **-keep-global-name** to retain the global variable name.
1182. After the preceding option is enabled, configure **-enable-property-obfuscation**,
119    1. If the code statically defines properties but dynamically accesses them (or vice versa), use **-keep-property-name** to retain the property names. Example:
120
121        ```ts
122        // Static definition, dynamic access: The property name is static during object definition, but is accessed by dynamically constructing the property name (usually using string concatenation).
123        const obj = {
124        staticName: value  // Static definition
125        };
126        const fieldName = 'static' + 'Name';  // Dynamic construction of the property name
127        console.log(obj[fieldName]);  // Use square bracket notation to dynamically access the property.
128        ```
129
130        ```ts
131        // Dynamic definition, static access: The property name is determined during object definition through a dynamic expression, but is statically accessed using dot notation (assuming that you know the result of the property name).
132        const obj = {
133        [dynamicExpression]: value  // Dynamic definition
134        };
135        console.log(obj.dynamicPropertyName);  // Use dot notation to statically access the property.
136        ```
137
138    2. If the code uses dot notation to access fields not defined in ArkTS/TS/JS code (for example, native so libraries, fixed JSON files, or database fields):
139        1. For API calls to so libraries (for example, **import testNapi from 'library.so'; testNapi.foo();**), use **-keep-property-name** to retain the property name **foo**.
140        2. For fields in JSON files, use **-keep-property-name** to retain the JSON field names.
141        3. For database-related fields, use **-keep-property-name** to retain the database field names.
142    3. When building a HAR module for use by other modules, use **-keep-property-name** in the **consumer-rules.txt** file of the HAR module to retain properties that should not be re-obfuscated. The **consumer-rules.txt** file generates the **obfuscation.txt** file during HAR compilation. When the HAR module is depended upon by other modules, DevEco Studio parses the **obfuscation.txt** file to read the trustlist.
143    4. Verify application functionality and identify any missed scenarios. If the application functionality is abnormal, find the code of the error line in the corresponding [intermediate products](#viewing-obfuscation-effects) based on the obfuscated error stack, identify the necessary trustlist configurations, and use **-keep-property-name** to retain them.
144
1453. After the preceding adaptations are successful, configure **-enable-export-obfuscation**, and perform adaptation in the following scenarios:
146    1. For HSP modules that provide interfaces and properties to other modules, use **-keep-global-name** to retain the interface names and **-keep-property-name** to retain the property names in exposed classes/interfaces.
147    2. When building HAR modules for use by other modules, use **-keep-global-name** to retain interface names and **-keep-property-name** to retain the property names in exposed classes/interfaces in the **obfuscation-rules.txt** file.
148    3. For API calls to so libraries (for example, **import { napiA } from 'library.so'**), use **-keep-global-name** to retain the so interface name **napiA**.
149    4. Verify application functionality and interface call functionality when the module is depended upon, and identify any missed scenarios. If the application functionality is abnormal, find the code of the error line in the corresponding [intermediate products](#viewing-obfuscation-effects) based on the obfuscated error stack, identify the necessary trustlist configurations, and retain them.
1504. After the preceding adaptations are successful, configure **-enable-filename-obfuscation**, and perform adaptation in the following scenarios:
151    1. If the code contains dynamic import statements (for example, `const path = './filePath';  import (path)`), use **-keep-file-name filePath** to retain the file path.
152    2. If the application has a [routerMap configuration](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/module-configuration-file#routermap) that describes routing information, use **-keep-file-name** to retain the page's source file path, which is specified by **pageSourceFile** field in the routing information.
153    3. If the code uses **ohmUrl** for page navigation (for example, `router.pushUrl({url: '@bundle:com.example.routerPage/Library/Index'})`), use **-keep-file-name** to retain the path.
154    4. Verify application functionality and identify any missed scenarios. If the application function is abnormal and the error stack contains obfuscated paths, you can query the original path in the **build/default/[...]/release/obfuscation/nameCache.json** file within the module and then locate the source code file. You can also use the [hstack plugin](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-command-line-hstack) to trigger automatic deobfuscation of error stacks. After locating the paths to retain, use **-keep-file-name** to retain them.
155
156## Remarks
157
158Currently, custom obfuscation plugins are not supported in the hvigor build process.
159
160## Viewing Obfuscation Effects
161
162After obfuscation is complete, intermediate products are generated. You can find the obfuscated intermediate products in the **build** directory of the compilation output, as well as the name mapping file and system API trustlist files.
163
164* Directory of the name mapping file and system API trustlist file: build/default/[...]/release/obfuscation
165* The name mapping file, named **nameCache.json**, records the mappings between bytecode names and names after obfuscation.
166* The system API trustlist file, named **systemApiCache.json**, records the APIs and property names that will not be obfuscated.
167* **obf** directory: contains the obfuscated **modules.abc** and **modules.pa** files. (The **modules.pa** file is generated when -**enable-bytecode-obfuscation-debugging** is enabled.)
168* **origin** directory: contains the original **modules.abc** file before obfuscation.
169* Configuration file: **config.json**, which records the obfuscation configuration items and trustlist.
170
171![bytecode-build-product](figures/bytecode-build-product.png)
172
173## Deobfuscating Error Stacks
174
175In applications that have undergone obfuscation, code names are changed, making the error stacks printed during crashes harder to understand because they do not match the source code exactly. You can use the [hstack plugin](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-command-line-hstack) in Command Line Tools of DevEco Studio to deobfuscate the source code stack and analyze issues.
176The deobfuscation tool requires the **sourceMaps.json** file and the obfuscation name mapping file **nameCache.json** generated during compilation. Be sure to back them up locally. Back up the **release** directory if possible to facilitate fault locating and analysis.
177
178![bytecode-obfuscation-product](figures/bytecode-obfuscation-product.png)
179