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'; 23 24// Record all unobfuscated properties and reasons. 25export const historyUnobfuscatedPropMap: Map<string, string[]> = new Map<string, string[]>(); 26// Record all files and the unobfuscated names and reasons in the files. 27export const historyAllUnobfuscatedNamesMap: Map<string, Object> = new Map<string, Object>(); 28 29// Clear the map after one compilation is completed. 30export function clearHistoryUnobfuscatedMap(): void { 31 historyUnobfuscatedPropMap.clear(); 32 historyAllUnobfuscatedNamesMap.clear(); 33} 34 35export const printerConfig = { 36 // Print obfuscation time&memory usage of all files and obfuscation processes 37 mFilesPrinter: false, 38 // Print time&memory usage of a single file obfuscation in transform processes 39 mSingleFilePrinter: false, 40 // Print sum up time of transform processes during obfuscation 41 mSumPrinter: false, 42 // Output path of printer 43 mOutputPath: '', 44}; 45 46export function initObfuscationConfig(projectConfig: any, arkProjectConfig: any, printObfLogger: Function): void { 47 const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, true); 48 const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs(); 49 const isHarCompiled: boolean = projectConfig.compileHar; 50 if (mergedObConfig.options.disableObfuscation) { 51 blockPrinter(); 52 return; 53 } 54 55 if (mergedObConfig.options.enableFileNameObfuscation) { 56 const ohPackagePath = path.join(projectConfig.modulePath, 'oh-package.json5'); 57 const entryArray = arkProjectConfig.entryArrayForObf; 58 const reservedFileNamesInIDEconfig = collectResevedFileNameInIDEConfig( 59 ohPackagePath, 60 projectConfig, 61 arkProjectConfig.modulePathMap, 62 entryArray, 63 ); 64 mergedObConfig.reservedFileNames.push(...reservedFileNamesInIDEconfig); 65 } 66 arkProjectConfig.obfuscationMergedObConfig = mergedObConfig; 67 68 arkProjectConfig.arkObfuscator = initArkGuardConfig( 69 projectConfig.obfuscationOptions?.obfuscationCacheDir, 70 printObfLogger, 71 mergedObConfig, 72 isHarCompiled, 73 ); 74 arkProjectConfig.arkObfuscator.obfConfigResolver = obConfig; 75} 76 77function initArkGuardConfig( 78 obfuscationCacheDir: string | undefined, 79 printObfLogger: Function, 80 mergedObConfig: MergedConfig, 81 isHarCompiled: boolean, 82): ArkObfuscator { 83 const arkguardConfig: IOptions = { 84 mCompact: mergedObConfig.options.compact, 85 mDisableConsole: mergedObConfig.options.removeLog, 86 mSimplify: false, 87 mRemoveComments: true, 88 mNameObfuscation: { 89 mEnable: true, 90 mNameGeneratorType: 1, 91 mReservedNames: mergedObConfig.reservedNames, 92 mRenameProperties: mergedObConfig.options.enablePropertyObfuscation, 93 mReservedProperties: mergedObConfig.reservedPropertyNames, 94 mKeepStringProperty: !mergedObConfig.options.enableStringPropertyObfuscation, 95 mTopLevel: mergedObConfig.options.enableToplevelObfuscation, 96 mReservedToplevelNames: mergedObConfig.reservedGlobalNames, 97 mKeepParameterNames: mergedObConfig.options.keepParameterNames, 98 mUniversalReservedProperties: mergedObConfig.universalReservedPropertyNames, 99 mUniversalReservedToplevelNames: mergedObConfig.universalReservedGlobalNames, 100 mEnableAtKeep: mergedObConfig.options.enableAtKeep 101 }, 102 mUnobfuscationOption: { 103 mPrintKeptNames: mergedObConfig.options.printKeptNames, 104 mPrintPath: mergedObConfig.options.printKeptNamesPath 105 }, 106 mRemoveDeclarationComments: { 107 mEnable: mergedObConfig.options.removeComments, 108 mReservedComments: mergedObConfig.keepComments, 109 }, 110 mEnableSourceMap: true, 111 mEnableNameCache: true, 112 mRenameFileName: { 113 mEnable: mergedObConfig.options.enableFileNameObfuscation, 114 mNameGeneratorType: 1, 115 mReservedFileNames: mergedObConfig.reservedFileNames, 116 }, 117 mExportObfuscation: mergedObConfig.options.enableExportObfuscation, 118 mPerformancePrinter: printerConfig, 119 mKeepFileSourceCode: { 120 mKeepSourceOfPaths: new Set(), 121 mkeepFilesAndDependencies: new Set(), 122 }, 123 mStripLanguageDefaultWhitelist: mergedObConfig.options.stripLanguageDefault 124 }; 125 126 const arkObfuscator: ArkObfuscator = new ArkObfuscator(); 127 arkObfuscator.init(arkguardConfig, obfuscationCacheDir); 128 if (mergedObConfig.options.applyNameCache && mergedObConfig.options.applyNameCache.length > 0) { 129 readNameCache(mergedObConfig.options.applyNameCache, printObfLogger); 130 } else { 131 if (obfuscationCacheDir) { 132 const defaultNameCachePath: string = path.join(obfuscationCacheDir, 'nameCache.json'); 133 if (fs.existsSync(defaultNameCachePath)) { 134 readNameCache(defaultNameCachePath, printObfLogger); 135 } 136 } 137 } 138 if (mergedObConfig.options.printKeptNames && obfuscationCacheDir) { 139 const defaultUnobfuscationPath: string = path.join(obfuscationCacheDir, 'keptNames.json'); 140 if (fs.existsSync(defaultUnobfuscationPath)) { 141 readUnobfuscationContentCache(defaultUnobfuscationPath, printObfLogger); 142 } 143 } 144 return arkObfuscator; 145} 146 147function readUnobfuscationContentCache(defaultUnobfuscationPath: string, printObfLogger: Function): void { 148 try { 149 const unobfuscationContent = fs.readFileSync(defaultUnobfuscationPath, 'utf-8'); 150 const unobfuscationObj: { 151 keptReasons: Object; 152 keptNames: { 153 property: Object; 154 [key: string]: Object; 155 }; 156 } = JSON.parse(unobfuscationContent); 157 158 Object.keys(unobfuscationObj.keptNames.property).forEach((key) => { 159 historyUnobfuscatedPropMap.set(key, unobfuscationObj.keptNames.property[key]); 160 }); 161 162 const { property, ...rest } = unobfuscationObj.keptNames; 163 Object.keys(rest).forEach((key) => { 164 historyAllUnobfuscatedNamesMap.set(key, rest[key]); 165 }); 166 } catch (err) { 167 const errorInfo: string = `Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`; 168 const errorCodeInfo: HvigorErrorInfo = { 169 code: '10804003', 170 description: 'ArkTS compiler Error', 171 cause: `Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`, 172 position: defaultUnobfuscationPath, 173 solutions: [`Please check ${defaultUnobfuscationPath} as error message suggested.`], 174 }; 175 printObfLogger(errorInfo, errorCodeInfo, 'error'); 176 } 177} 178