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