1# Common Issues with ArkGuard in Source Code Obfuscation 2 3## Troubleshooting Functional Issues 4 5### Procedure 61. Configure the **-disable-obfuscation** option in the **obfuscation-rules.txt** file to disable obfuscation, and check whether the issue is caused by obfuscation. 72. If the issue is related to obfuscation, review the documentation for the following options and understand when to configure trustlists to avoid issues: The following briefly describes the four retention options that are enabled by default. For details about the four retention options, see the complete description of the corresponding options. 8 1. [-enable-toplevel-obfuscation](source-obfuscation.md#-enable-toplevel-obfuscation): obfuscates top-level scope names. 9 10 2. [-enable-property-obfuscation](source-obfuscation.md#-enable-property-obfuscation): obfuscates property names. Use [-keep-property-name](source-obfuscation.md#-keep-property-name) to configure a trustlist for property names used in network calls, JSON field, dynamic accesses, and so library interfaces. 11 12 3. [-enable-export-obfuscation](source-obfuscation.md#-enable-export-obfuscation): obfuscates exported names. Generally, it is used together with **-enable-toplevel-obfuscation** and **-enable-property-obfuscation**. Use [-keep-global-name](source-obfuscation.md#-keep-global-name) to configure a trustlist for exported/imported interfaces. 13 14 4. [-enable-filename-obfuscation](source-obfuscation.md#-enable-filename-obfuscation): obfuscates file names. Use [-keep-file-name](source-obfuscation.md#-keep-file-name) to configure a trustlist for file paths and names in dynamically import or runtime loading scenarios. 153. If your issue matches any cases listed below, apply the suggested solutions. 164. If the issue is not covered, use a positive approach to identify the problem (remove specific configuration items if the corresponding functionality is not needed). 175. Analyze runtime crashes as follows: 18 1. Open the application runtime logs or click the **Crash** dialog box in DevEco Studio to find the crash stack. 19 20 2. The line numbers in the crash stack match the [compiled product](source-obfuscation-guide.md#viewing-obfuscation-effects), and method names might be obfuscated. Therefore, you are advised to check the compiled product based on the crash stack, analyze the names that cannot be obfuscated, and add them to the trustlist. 216. Analyze functional exceptions (for example, white screens) as follows: 22 1. Opening the application runtime logs: Select HiLog and search for logs directly related to the exceptions. 23 24 2. Locating the problematic code segment: Identify the specific code block causing the exceptions through log analysis. 25 26 3. Enhancing log output: Add log records for data fields in the suspected code segment. 27 28 4. Analyzing and identifying critical fields: Determine if the data exception is caused by obfuscation through the enhanced log output. 29 30 5. Configuring a trustlist for critical fields: Add fields that directly affect application functionality after obfuscation to the trustlist. 31 32#### Troubleshooting Unexpected Obfuscation Behavior 33If unexpected obfuscation behavior occurs, check whether certain obfuscation options are configured for the dependent local modules or third-party libraries. 34 35Example: 36 37If **-compact** is not configured for the current module, but the code in the obfuscated intermediate product is compressed into a single line, perform the following steps: 38 391. Check the **dependencies** field in the **oh-package.json5** file of the current module to identify dependencies. 402. Search for **-compact** in the obfuscation configuration file of the dependent modules or third-party libraries. 41 * Search for **-compact** in the **consumer-rules.txt** file in the local libraries. 42 * Search for **-compact** in all **obfuscation.txt** files in the project-level **oh_modules** directory. 43 44> **NOTE** 45> 46> You are not advised to configure the following options in the **consumer-rules.txt** file of third-party libraries. These options will take effect when obfuscation is enabled in the main module, potentially causing unexpected obfuscation results and even application crashes at runtime. If you find that the **obfuscation.txt** file of a third-party library includes these options, you are advised to contact the team that released the third-party library to remove these options and repackage and release the library. 47> -enable-property-obfuscation 48> -enable-string-property-obfuscation 49> -enable-toplevel-obfuscation 50> -remove-log 51> -compact 52 53## Property Obfuscation Issues 54 55### Database Field Errors When Property Name Obfuscation is Enabled 56 57**Symptom** 58 59The error message is "table Account has no column named a23 in 'INSET INTO Account(a23)'." 60 61**Possible Causes** 62 63The SQL statement uses database field names that are obfuscated, whereas the database expects the original names. 64 65**Solution** 66 67Use the **-keep-property-name** option to add the database fields to the trustlist. 68 69### Properties Obfuscated When Record<string, Object> Is Used as an Object Type 70 71**Symptom** 72 73When **Record<string, Object>** is used as an object type, properties like **linkSource** are obfuscated, causing the error. Example: 74 75``` 76// Before obfuscation: 77import { Want } from '@kit.AbilityKit'; 78let petalMapWant: Want = { 79 bundleName: 'com.example.myapplication', 80 uri: 'maps://', 81 parameters: { 82 linkSource: 'com.other.app' 83 } 84} 85``` 86 87``` 88// After obfuscation: 89import type Want from "@ohos:app.ability.Want"; 90let petalMapWant: Want = { 91 bundleName: 'com.example.myapplication', 92 uri: 'maps://', 93 parameters: { 94 i: 'com.other.app' 95 } 96}; 97``` 98 99**Possible Causes** 100 101In this example, the object's properties need to be passed to the system to load a specific page, so the property names should not be obfuscated. The type **Record<string, Object>** is a generic definition for an object with string keys and does not describe the internal structure or property types in detail. Therefore, the obfuscation tool cannot identify which properties should not be obfuscated, leading to the obfuscation of internal property names like **linkSource**. 102 103**Solution** 104 105Add the problematic property names to the property trustlist. The following is an example: 106 107``` 108-keep-property-name 109linkSource 110``` 111 112### Property Name Obfuscation Inconsistency Across Files 113 114**Symptom** 115 116The following obfuscation configuration is used: 117 118``` 119-enable-property-obfuscation 120-keep 121./file1.ts 122``` 123 124**file2.ts** imports an interface from **file1.ts**, and the interface contains object-type properties. As a result, these properties are retained in **file1.ts** but obfuscated in **file2.ts**, leading to function exceptions. Example: 125 126``` 127// Before obfuscation: 128// file1.ts 129export interface MyInfo { 130 age: number; 131 address: { 132 city1: string; 133 } 134} 135 136// file2.ts 137import { MyInfo } from './file1'; 138const person: MyInfo = { 139 age: 20, 140 address: { 141 city1: "shanghai" 142 } 143} 144``` 145 146``` 147// After obfuscation: 148// The code of file1.ts is retained. 149// file2.ts 150import { MyInfo } from './file1'; 151const person: MyInfo = { 152 age: 20, 153 address: { 154 i: "shanghai" 155 } 156} 157``` 158 159**Possible Causes** 160 161The **-keep** option retains the code in the **file1.ts** file, but properties within exported types (for example, **address**) are not automatically added to the trustlist. Therefore, these properties are obfuscated when being used in other files. 162 163**Solution** 164 165Solution 1: Define the property type using **interface** and export it. This will automatically add the property to the trustlist. Example: 166 167``` 168// file1.ts 169export interface AddressType { 170 city1: string; 171} 172export interface MyInfo { 173 age: number; 174 address: AddressType; 175} 176``` 177 178Solution 2: Use the **-keep-property-name** option to add properties within types that are not directly exported to the trustlist. Example: 179 180``` 181-keep-property-name 182city1 183``` 184 185### String Literal Property Names Obfuscated When -enable-string-property-obfuscation Is Not Configured 186 187**Symptom** 188 189``` 190// Before obfuscation: 191person["age"] = 22; 192``` 193 194``` 195// After obfuscation: 196person["b"] = 22; 197``` 198 199**Possible Causes** 200 201A dependent module may have enabled string property name obfuscation, affecting the main module. 202 203**Solution** 204 205Solution 1: Check whether any dependent modules have enabled string property name obfuscation. If yes, disable it. For details, see [Troubleshooting Unexpected Obfuscation Behavior](source-obfuscation-questions.md#troubleshooting-unexpected-obfuscation-behavior). 206 207Solution 2: If the problematic module cannot be identified, add the string literal property names to the trustlist directly. 208 209## Inconsistent Imported/Exported Names 210 211### Dynamic Import of a Class with Mismatched Obfuscation 212 213**Symptom** 214 215When **-enable-property-obfuscation** is not configured, dynamically importing a class results in the class being obfuscated during its definition, but not during the call, causing the error. 216 217``` 218// Before obfuscation: 219// file1.ts 220export class Test1 {} 221// file2.ts 222let mytest = (await import('./file1')).Test1; 223``` 224 225``` 226// After obfuscation: 227// file1.ts 228export class w1 {} 229// file2.ts 230let mytest = (await import('./file1')).Test1; 231``` 232 233**Possible Causes** 234 235The exported class **Test1** is a top-level domain name. When being dynamically used, it is a property. Because the **-enable-property-obfuscation** option is not configured, the class name is confused, but the property name is not. 236 237**Solution** 238 239Use **-keep-global-name** to add **Test1** to the trustlist. 240 241### Exported Method in Namespace with Mismatched Obfuscation 242 243**Symptom** 244 245When **-enable-property-obfuscation** is not configured, the definition of the method in the namespace is obfuscated, but not obfuscated during the call, causing the error. 246 247``` 248// Before obfuscation: 249//file1.ts 250export namespace ns1 { 251 export class person1 {} 252} 253//file2.ts 254import {ns1} from './file1'; 255let person1 = new ns1.person1(); 256``` 257 258``` 259// After obfuscation: 260//file1.ts 261export namespace a3 { 262 export class b2 {} 263} 264//file2.ts 265import {a3} from './file1'; 266let person1 = new a3.person1(); 267``` 268 269**Possible Causes** 270 271**person1** in the namespace is an exported element. When being called through **ns1.person1**, it is a property. Because the **-enable-property-obfuscation** option is not configured, the property name is not obfuscated during the call. 272 273**Solution** 274 275Solution 1: Configure the **-enable-property-obfuscation** option. 276Solution 2: Use the **-keep-global-name** option to add the methods exported from the namespace to the trustlist. 277 278## Inter-Module Dependency Issues 279 280### Incorrect Obfuscation of HSP Module Exports 281 282**Symptom** 283 284The exported interfaces of an HSP module are incorrectly obfuscated in the main module. 285 286``` 287// Before obfuscation: 288import { MyHspClass } from "myhsp"; 289new MyHspClass().myHspMethod(); 290``` 291 292``` 293// After obfuscation: 294import { t } from "@normalized:N&myhsp&&myhsp/Index&"; 295new t().a1(); 296``` 297 298**Possible Causes** 299 300When **-enable-export-obfuscation** and **-enable-toplevel-obfuscation** are configured, the following scenarios apply to method name obfuscation when the main module calls methods from other modules: 301 302| Main Module| Dependent Module| Imported/Exported Name Obfuscation| 303| ------- | ------- | ----------------------------| 304| HAP/HSP | HSP | The HSP and main module are independently compiled, resulting in inconsistent obfuscated names. Both need trustlist configurations.| 305| HAP/HSP | Local HAR| The local HAR is compiled together with the main module, resulting in consistent obfuscated names.| 306| HAP/HSP | Third-party library | Exported names and their properties in third-party libraries are collected into the trustlist, so they are not obfuscated during import/export.| 307 308**Solution** 309 310To enable other modules to correctly call the methods of the HSP module, add a trustlist. Since both the main module and the HSP module need consistent trustlist configurations, follow these steps: 311 3121. Add the trustlist to the obfuscation configuration file (for example, **hsp-white-list.txt**) of the HSP module. 3132. In the obfuscation configuration of other modules that depend on the HSP module, include this configuration file via the **files** field. 314This ensures consistent trustlist configurations and avoids redundant maintenance. The configuration method is shown in the figure below. 315 316 317 318### Singleton Function Exceptions and Interface Call Failures in HAP and HSP with a Shared Local Source Code HAR 319 320**Symptom** 321 322* If file name obfuscation is enabled, the following issue may occur: 323 * Singleton function exceptions: The reason is that the HAP and HSP modules execute independent build and obfuscation processes. The same file names in the shared local source code HAR may be obfuscated differently in the HAP and HSP packages. 324 * Interface call failures: The reason is that the HAP and HSP modules execute independent build and obfuscation processes. Different file names in the shared local source code HAR may be obfuscated to the same name in the HAP and HSP packages. 325* If **-enable-export-obfuscation** and **-enable-toplevel-obfuscation** are configured, the interface loading failures may occur at runtime. 326 327**Possible Causes** 328 329The HAP and HSP modules execute independent build and obfuscation processes, resulting in different obfuscated names for the interfaces exposed by the shared local source code HAR. 330 331**Solution** 332 333Solution 1: Change the shared local source code HAR to a [bytecode HAR](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-hvigor-build-har#section16598338112415). This prevents the HAR from being re-obfuscated when being depended upon. 334 335Solution 2: Build the shared local source code HAR in [release mode](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-hvigor-build-har#section19788284410). This ensures that file names and exported interfaces are not obfuscated when the HAR is depended upon.