Using ArkGuard for Bytecode Obfuscation
NOTE
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.
Enabling Bytecode Obfuscation
Constraints
Bytecode obfuscation and source code obfuscation cannot be enabled at the same time. After bytecode obfuscation is enabled, source code obfuscation is automatically disabled.
How to Use
Since API version 20, the bytecode obfuscation capability has been integrated into the system. You can enable it in DevEco Studio as follows:
-
Enabling the obfuscation switch To enable obfuscation, set the
enablefield to true underarkOptions.obfuscation.ruleOptionsin thebuild-profile.json5file of your module."arkOptions": { "obfuscation": { "ruleOptions": { "enable": true, // Enable the obfuscation switch. "files": ["./obfuscation-rules.txt"] // Specify the obfuscation rule file, which takes effect when the current module is compiled. }, // ... } },To configure obfuscation options, manually edit the
obfuscation-rules.txtfile specified in the files field. Enable the following obfuscation options:-enable-bytecode-obfuscation # Activates bytecode obfuscation when enabled. -enable-bytecode-obfuscation-debugging # Controls debug output. If this option is enabled, obfuscation logs are generated. By default, this option is disabled.NOTE
Bytecode HAR files will not be re-obfuscated during integration.
-
Configuring obfuscation rules 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.txtfile specified in thefilesfield. Note that the default values in this file may vary across different versions of DevEco Studio. 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.-enable-property-obfuscation -enable-toplevel-obfuscation -enable-filename-obfuscation -enable-export-obfuscationYou can also add comments to the obfuscation rule file by prefixing lines with the
#symbol. For example:# options: -enable-property-obfuscation -enable-toplevel-obfuscation -enable-filename-obfuscation # -enable-export-obfuscation -keep-property-name # white list for dynamic property namesFor details about how to configure obfuscation options, see Obfuscation Configuration Guidelines. For details about all configuration files involved in obfuscation, see Obfuscation Configuration Files.
NOTE
By default, obfuscation is disabled for new projects. If you want to enable obfuscation, set the
ruleOptions.enablefield in thebuild-profile.json5file of the module totrue. If required, enable the-enable-bytecode-obfuscationand-enable-bytecode-obfuscation-debuggingoptions in theobfuscation-rules.txtfile. By default, the following four recommended obfuscation options are enabled in theobfuscation-rules.txtfile:-enable-property-obfuscation,-enable-toplevel-obfuscation,-enable-filename-obfuscation, and-enable-export-obfuscation. You can customize the obfuscation settings as needed. -
Specifying release compilation 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.
NOTE
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.
Obfuscation Configuration Files
-
obfuscation-rules.txtFor HAP, HAR, and HSP modules, thearkOptions.obfuscation.ruleOptions.filesfield in thebuild-profile.json5file specifies obfuscation rules applied during module compilation. A defaultobfuscation-rules.txtfile is created when a new project is set up. -
consumer-rules.txtFor HAR and HSP modules, an additionalarkOptions.obfuscation.consumerFilesfield is available in thebuild-profile.json5file. This field specifies obfuscation rules that should be applied when this package is depended upon in other modules. A defaultconsumer-rules.txtfile is created when a new HAR or HSP module is set up. The key difference betweenconsumer-rules.txtandobfuscation-rules.txtis as follows:obfuscation-rules.txtapplies to the compilation of the current module, whereasconsumer-rules.txtapplies to the compilation of other modules that depend on the current module."arkOptions": { "obfuscation": { "ruleOptions": { "enable": true, // Enable the obfuscation switch. "files": ["./obfuscation-rules.txt"] // Specify the obfuscation rule file, which takes effect when the current module is compiled. }, "consumerFiles": ["./consumer-rules.txt"] // Specify the obfuscation rule file, which takes effect when other modules that depend on the current module are compiled. } }, -
obfuscation.txtUnlike the above two files,obfuscation.txtis automatically generated based onconsumer-rules.txtand 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 ofobfuscation.txt, see Obfuscation Rule Merging Strategies.NOTE
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.
The following table summarizes the differences between these configuration files.
| Configuration File | Configuration Type | Modifiable | Affects Obfuscation of This Module | Affects Obfuscation of Other Modules |
|---|---|---|---|---|
| obfuscation-rules.txt | Customizable | Yes | Yes | No |
| consumer-rules.txt | Customizable | Yes | No | Yes |
| obfuscation.txt | Compilation product | Not applicable (automatically generated during HAR or HSP compilation) | Not applicable | Yes |
Obfuscation Configuration Guidelines
-
When
-enable-toplevel-obfuscationis configured, access to global variables using globalThis fails. To rectify the fault, use-keep-global-nameto retain the global variable name. -
After the preceding option is enabled, configure
-enable-property-obfuscation.-
If the code statically defines properties but dynamically accesses them (or vice versa), use
-keep-property-nameto retain the property names. Example:// file.ts // 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). const obj001 = { staticName: 5 // Static definition }; const fieldName = 'static' + 'Name'; // Dynamic construction of the property name console.info(obj001[fieldName]); // Use square bracket notation to dynamically access the property.// file.ts // 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). const obj002 = { ['dynamic' + 'Name']: 5 // Dynamic definition }; console.info(obj002.dynamicName + '');// Use dot notation to statically access the property. -
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):
- For API calls to so libraries (for example,
import testNapi from 'library.so'andtestNapi.foo()), use-keep-property-nameto retain the property name foo. - For fields in JSON files, use
-keep-property-nameto retain the JSON field names. - For database-related fields, use
-keep-property-nameto retain the database field names.
- For API calls to so libraries (for example,
-
When building a HAR module for use by other modules, use
-keep-property-namein 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. -
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 based on the obfuscated error stack, identify the necessary trustlist configurations, and use
-keep-property-nameto retain them.
-
-
After the preceding adaptations are successful, configure
-enable-export-obfuscation, and perform adaptation in the following scenarios:- For HSP modules that provide interfaces and properties to other modules, use
-keep-global-nameto retain the interface names and-keep-property-nameto retain the property names in exposed classes/interfaces. - When building HAR modules for use by other modules, use
-keep-global-nameto retain interface names and-keep-property-nameto retain the property names in exposed classes/interfaces in the obfuscation-rules.txt file. - For API calls to so libraries (for example,
import { napiA } from 'library.so'), use-keep-global-nameto retain the so interface name napiA. - 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 based on the obfuscated error stack, identify the necessary trustlist configurations, and retain them.
- For HSP modules that provide interfaces and properties to other modules, use
-
After the preceding adaptations are successful, configure
-enable-filename-obfuscation, and perform adaptation in the following scenarios:- If the code contains dynamic import statements (for example,
const path = './filePath'; import (path)), use-keep-file-nameto retain the file path. - If the application has a routerMap configuration that describes routing information, use
-keep-file-nameto retain the page's source file path, which is specified by pageSourceFile field in the routing information. - If the code uses ohmUrl for page navigation (for example,
router.pushUrl({url: '@bundle:com.example.routerPage/Library/Index'})), use-keep-file-nameto retain the path. - 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.jsonfile within the module and then locate the source code file. You can also use the hstack plugin to trigger automatic deobfuscation of error stacks. After locating the paths to retain, use-keep-file-nameto retain them.
- If the code contains dynamic import statements (for example,
Remarks
- Currently, custom obfuscation plugins are not supported in the hvigor build process.
Viewing Obfuscation Effects
After 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.
- Directory of the name mapping file and system API trustlist file:
build/default/[...]/release/obfuscation - The name mapping file, named
nameCache.json, records the mappings between bytecode names and names after obfuscation. - The system API trustlist file, named
systemApiCache.json, records the APIs and property names that will not be obfuscated. - obf directory: contains the obfuscated modules.abc and modules.pa files. (The modules.pa file is generated when
-enable-bytecode-obfuscation-debuggingis enabled.) - origin directory: contains the original modules.abc file before obfuscation.
- Configuration file:
config.json, which records the obfuscation configuration items and trustlist.

Deobfuscating Error Stacks
In 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 in Command Line Tools of DevEco Studio to deobfuscate the source code stack and analyze issues. The 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 for fault locating and analysis.
