• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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