• 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 {
17  factory,
18  isStructDeclaration,
19  setParentRecursive,
20  visitEachChild,
21  isConstructorDeclaration,
22  isSourceFile,
23  getOriginalNode
24} from 'typescript';
25
26import type {
27  ClassElement,
28  Node,
29  SourceFile,
30  TransformationContext,
31  Transformer,
32  TransformerFactory
33} from 'typescript';
34
35import type {TransformPlugin} from '../TransformPlugin';
36import {TransformerOrder} from '../TransformPlugin';
37import type {IOptions} from '../../configs/IOptions';
38import {NodeUtils} from '../../utils/NodeUtils';
39import {ArkObfuscator, performancePrinter} from '../../ArkObfuscator';
40import { EventList, endSingleFileEvent, startSingleFileEvent } from '../../utils/PrinterUtils';
41import {MemoryDottingDefine} from '../../utils/MemoryDottingDefine';
42
43namespace secharmony {
44  export let transformerPlugin: TransformPlugin = {
45    'name': 'VirtualConstructorTransformerFactory',
46    'order': TransformerOrder.VIRTUAL_CONSTRUCTOR_TRANSFORMER,
47    'createTransformerFactory': (option: IOptions) => virtualConstructorTransformerFactory,
48  };
49}
50
51function virtualConstructorTransformerFactory(context: TransformationContext): Transformer<Node> {
52  return (node: SourceFile) => virtualConstructorTransformer(node, context);
53}
54
55function virtualConstructorTransformer(node: SourceFile, context: TransformationContext): Node {
56  if (!NodeUtils.isDETSFile(node)) {
57    return node;
58  }
59
60  const recordInfo = ArkObfuscator.recordStage(MemoryDottingDefine.VIRTUAL_OBFUSCATION);
61  startSingleFileEvent(EventList.VIRTUAL_CONSTRUCTOR_OBFUSCATION, performancePrinter.timeSumPrinter);
62  let astWithoutVirtualConstructor = removeVirtualConstructor(node, context);
63  let parentNodes = setParentRecursive(astWithoutVirtualConstructor, true);
64  endSingleFileEvent(EventList.VIRTUAL_CONSTRUCTOR_OBFUSCATION, performancePrinter.timeSumPrinter);
65  ArkObfuscator.stopRecordStage(recordInfo);
66  return parentNodes;
67}
68
69function removeVirtualConstructor(node: Node, context: TransformationContext): Node {
70  if (isStructDeclaration(node)) {
71    const tempStructMembers: ClassElement[] = node.members.filter((member) => !isVirtualConstructor(member));
72    const structMembersWithoutVirtualConstructor = factory.createNodeArray(tempStructMembers);
73
74    return factory.updateStructDeclaration(node, node.modifiers, node.name, node.typeParameters, node.heritageClauses,
75      structMembersWithoutVirtualConstructor);
76  }
77  return visitEachChild(node, (childNode) => removeVirtualConstructor(childNode, context), context);
78}
79
80function isVirtualConstructor(node: Node): boolean {
81  const originalNode = getOriginalNode(node);
82  //@ts-ignore
83  return isConstructorDeclaration(originalNode) && originalNode.virtual;
84}
85
86export = secharmony;
87