1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import fs from 'fs'; 17import path from 'path'; 18 19import { ArkObfuscator, blockPrinter, renameIdentifierModule } from '../ArkObfuscator'; 20import { collectResevedFileNameInIDEConfig, MergedConfig, ObConfigResolver, readNameCache } from './ConfigResolver'; 21import { type IOptions } from '../configs/IOptions'; 22import type { HvigorErrorInfo } from '../common/type'; 23import { blockTimeAndMemPrinter, getObfuscationCacheDir } from '../utils/PrinterTimeAndMemUtils'; 24 25// Record all unobfuscated properties and reasons. 26export const historyUnobfuscatedPropMap: Map<string, string[]> = new Map<string, string[]>(); 27// Record all files and the unobfuscated names and reasons in the files. 28export const historyAllUnobfuscatedNamesMap: Map<string, Object> = new Map<string, Object>(); 29 30// Clear the map after one compilation is completed. 31export function clearHistoryUnobfuscatedMap(): void { 32 historyUnobfuscatedPropMap.clear(); 33 historyAllUnobfuscatedNamesMap.clear(); 34} 35 36export const printerConfig = { 37 // Print obfuscation time&memory usage of all files and obfuscation processes 38 mFilesPrinter: false, 39 // Print time&memory usage of a single file obfuscation in transform processes 40 mSingleFilePrinter: false, 41 // Print sum up time of transform processes during obfuscation 42 mSumPrinter: false, 43 // Output path of printer 44 mOutputPath: '', 45}; 46 47export const printerTimeAndMemDataConfig = { 48 // The switch for printing obfuscation performance data and memory data 49 mTimeAndMemPrinter: false, 50 // Print more obfuscation time data to obtain more detailed time performance data 51 mMoreTimePrint: false, 52}; 53 54 55export function initObfuscationConfig(projectConfig: any, arkProjectConfig: any, printObfLogger: Function): void { 56 const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, true); 57 let mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs(); 58 if (arkProjectConfig.allowEtsAnnotations) { 59 mergedObConfig.options.enableEtsAnnotation = arkProjectConfig.allowEtsAnnotations; 60 } 61 const isHarCompiled: boolean = projectConfig.compileHar; 62 if (mergedObConfig.options.disableObfuscation) { 63 blockPrinter(); 64 blockTimeAndMemPrinter(); 65 return; 66 } 67 getObfuscationCacheDir(projectConfig); 68 /** 69 * Only one of bytecode obfuscation and source code obfuscation will take effect. 70 * Enabling bytecode obfuscation is to obfuscate declaration files when compile bytecode har. 71 */ 72 const isBytecodeObfEnabled = mergedObConfig.options.bytecodeObf.enable; 73 arkProjectConfig.isBytecodeObfEnabled = isBytecodeObfEnabled; 74 arkProjectConfig.isArkguardEnabled = !isBytecodeObfEnabled; 75 76 if (mergedObConfig.options.enableFileNameObfuscation) { 77 const ohPackagePath = path.join(projectConfig.modulePath, 'oh-package.json5'); 78 const entryArray = arkProjectConfig.entryArrayForObf; 79 const reservedFileNamesInIDEconfig = collectResevedFileNameInIDEConfig( 80 ohPackagePath, 81 projectConfig, 82 arkProjectConfig.modulePathMap, 83 entryArray, 84 ); 85 mergedObConfig.reservedFileNames.push(...reservedFileNamesInIDEconfig); 86 } 87 arkProjectConfig.obfuscationMergedObConfig = mergedObConfig; 88 89 arkProjectConfig.arkObfuscator = initArkGuardConfig( 90 projectConfig.obfuscationOptions?.obfuscationCacheDir, 91 printObfLogger, 92 mergedObConfig, 93 isHarCompiled, 94 ); 95 arkProjectConfig.arkObfuscator.obfConfigResolver = obConfig; 96} 97 98function initArkGuardConfig( 99 obfuscationCacheDir: string | undefined, 100 printObfLogger: Function, 101 mergedObConfig: MergedConfig, 102 isHarCompiled: boolean, 103): ArkObfuscator { 104 const arkguardConfig: IOptions = { 105 mCompact: mergedObConfig.options.compact, 106 mDisableConsole: mergedObConfig.options.removeLog, 107 mSimplify: false, 108 mRemoveComments: true, 109 mNameObfuscation: { 110 mEnable: true, 111 mNameGeneratorType: 1, 112 mReservedNames: mergedObConfig.reservedNames, 113 mRenameProperties: mergedObConfig.options.enablePropertyObfuscation, 114 mReservedProperties: mergedObConfig.reservedPropertyNames, 115 mKeepStringProperty: !mergedObConfig.options.enableStringPropertyObfuscation, 116 mTopLevel: mergedObConfig.options.enableToplevelObfuscation, 117 mReservedToplevelNames: mergedObConfig.reservedGlobalNames, 118 mKeepParameterNames: mergedObConfig.options.keepParameterNames, 119 mUniversalReservedProperties: mergedObConfig.universalReservedPropertyNames, 120 mUniversalReservedToplevelNames: mergedObConfig.universalReservedGlobalNames, 121 mEnableAtKeep: mergedObConfig.options.enableAtKeep 122 }, 123 mUnobfuscationOption: { 124 mPrintKeptNames: mergedObConfig.options.printKeptNames, 125 mPrintPath: mergedObConfig.options.printKeptNamesPath 126 }, 127 mRemoveDeclarationComments: { 128 mEnable: mergedObConfig.options.removeComments, 129 mReservedComments: mergedObConfig.keepComments, 130 }, 131 mEnableSourceMap: true, 132 mEnableNameCache: true, 133 mRenameFileName: { 134 mEnable: mergedObConfig.options.enableFileNameObfuscation, 135 mNameGeneratorType: 1, 136 mReservedFileNames: mergedObConfig.reservedFileNames, 137 }, 138 mExportObfuscation: mergedObConfig.options.enableExportObfuscation, 139 mPerformancePrinter: printerConfig, 140 mKeepFileSourceCode: { 141 mKeepSourceOfPaths: new Set(), 142 mkeepFilesAndDependencies: new Set(), 143 }, 144 mStripLanguageDefaultWhitelist: mergedObConfig.options.stripLanguageDefault, 145 mAllowEtsAnnotations: mergedObConfig.options.enableEtsAnnotation, 146 }; 147 148 const arkObfuscator: ArkObfuscator = new ArkObfuscator(); 149 arkObfuscator.init(arkguardConfig, obfuscationCacheDir); 150 if (mergedObConfig.options.applyNameCache && mergedObConfig.options.applyNameCache.length > 0) { 151 readNameCache(mergedObConfig.options.applyNameCache, printObfLogger); 152 } else { 153 if (obfuscationCacheDir) { 154 const defaultNameCachePath: string = path.join(obfuscationCacheDir, 'nameCache.json'); 155 if (fs.existsSync(defaultNameCachePath)) { 156 readNameCache(defaultNameCachePath, printObfLogger); 157 } 158 } 159 } 160 if (mergedObConfig.options.printKeptNames && obfuscationCacheDir) { 161 const defaultUnobfuscationPath: string = path.join(obfuscationCacheDir, 'keptNames.json'); 162 if (fs.existsSync(defaultUnobfuscationPath)) { 163 readUnobfuscationContentCache(defaultUnobfuscationPath, printObfLogger); 164 } 165 } 166 return arkObfuscator; 167} 168 169function readUnobfuscationContentCache(defaultUnobfuscationPath: string, printObfLogger: Function): void { 170 try { 171 const unobfuscationContent = fs.readFileSync(defaultUnobfuscationPath, 'utf-8'); 172 const unobfuscationObj: { 173 keptReasons: Object; 174 keptNames: { 175 property: Object; 176 [key: string]: Object; 177 }; 178 } = JSON.parse(unobfuscationContent); 179 180 Object.keys(unobfuscationObj.keptNames.property).forEach((key) => { 181 historyUnobfuscatedPropMap.set(key, unobfuscationObj.keptNames.property[key]); 182 }); 183 184 const { property, ...rest } = unobfuscationObj.keptNames; 185 Object.keys(rest).forEach((key) => { 186 historyAllUnobfuscatedNamesMap.set(key, rest[key]); 187 }); 188 } catch (err) { 189 const errorInfo: string = `Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`; 190 const errorCodeInfo: HvigorErrorInfo = { 191 code: '10804003', 192 description: 'ArkTS compiler Error', 193 cause: `Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`, 194 position: defaultUnobfuscationPath, 195 solutions: [`Please check ${defaultUnobfuscationPath} as error message suggested.`], 196 }; 197 printObfLogger(errorInfo, errorCodeInfo, 'error'); 198 } 199} 200