Skip to content

Commit cead12a

Browse files
committed
Refactoring
1 parent c594536 commit cead12a

File tree

24 files changed

+330
-134
lines changed

24 files changed

+330
-134
lines changed

src/JavaScriptObfuscator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ import { CodeTransformer } from './enums/code-transformers/CodeTransformer';
2020
import { CodeTransformationStage } from './enums/code-transformers/CodeTransformationStage';
2121
import { LoggingMessage } from './enums/logger/LoggingMessage';
2222
import { NodeTransformer } from './enums/node-transformers/NodeTransformer';
23-
import { NodeTransformationStage } from './enums/node-transformers/NodeTransformationStage';
23+
import { NodeTransformationStage } from './enums/node-transformers/NodeTransformationStage';
24+
import { SourceMapSourcesMode } from './enums/source-map/SourceMapSourcesMode';
2425

2526
import { ecmaVersion } from './constants/EcmaVersion';
2627

2728
import { ASTParserFacade } from './ASTParserFacade';
2829
import { NodeGuards } from './node/NodeGuards';
2930
import { Utils } from './utils/Utils';
30-
import { SourceMapSourcesMode } from './enums/source-map/SourceMapSourcesMode';
3131

3232
@injectable()
3333
export class JavaScriptObfuscator implements IJavaScriptObfuscator {

src/analyzers/string-array-storage-analyzer/StringArrayStorageAnalyzer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ export class StringArrayStorageAnalyzer implements IStringArrayStorageAnalyzer {
4242
private readonly stringArrayStorage: IStringArrayStorage;
4343

4444
/**
45-
* @type {Map<ESTree.Literal, IStringArrayStorageItemData>}
45+
* @type {WeakMap<ESTree.Literal, IStringArrayStorageItemData>}
4646
*/
47-
private readonly stringArrayStorageData: Map<ESTree.Literal, IStringArrayStorageItemData> = new Map();
47+
private readonly stringArrayStorageData: WeakMap<ESTree.Literal, IStringArrayStorageItemData> = new WeakMap();
4848

4949
/**
5050
* @param {IStringArrayStorage} stringArrayStorage

src/container/modules/storages/StoragesModule.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ export const storagesModule: interfaces.ContainerModule = new ContainerModule((b
6969
const options: IOptions = context.container
7070
.get<IOptions>(ServiceIdentifiers.IOptions);
7171

72-
const storage: TControlFlowStorage = new constructor(randomGenerator, options);
72+
const storage: TControlFlowStorage = new constructor(
73+
randomGenerator,
74+
options
75+
);
7376

7477
storage.initialize();
7578

src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { initializable } from '../../../decorators/Initializable';
1717
import { AbstractCustomNode } from '../../AbstractCustomNode';
1818
import { NodeFactory } from '../../../node/NodeFactory';
1919
import { NodeGuards } from '../../../node/NodeGuards';
20-
import { NodeUtils } from '../../../node/NodeUtils';
2120

2221
@injectable()
2322
export class ControlFlowStorageNode extends AbstractCustomNode {
@@ -59,22 +58,25 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
5958
* @returns {TStatement[]}
6059
*/
6160
protected getNodeStructure (): TStatement[] {
62-
const propertyNodes: ESTree.Property[] = Array
63-
.from<[string, ICustomNode]>(this.controlFlowStorage.getStorage())
64-
.map(([key, value]: [string, ICustomNode]) => {
65-
const node: ESTree.Node = value.getNode()[0];
61+
const propertyNodes: ESTree.Property[] = [];
62+
const controlFlowStorageMap: Map<string, ICustomNode> = this.controlFlowStorage.getStorage();
6663

67-
if (!NodeGuards.isExpressionStatementNode(node)) {
68-
throw new Error('Function node for control flow storage object should be passed inside the `ExpressionStatement` node!');
69-
}
64+
for (const [key, value] of controlFlowStorageMap) {
65+
const node: ESTree.Node = value.getNode()[0];
7066

71-
return NodeFactory.propertyNode(
67+
if (!NodeGuards.isExpressionStatementNode(node)) {
68+
throw new Error('Function node for control flow storage object should be passed inside the `ExpressionStatement` node!');
69+
}
70+
71+
propertyNodes.push(
72+
NodeFactory.propertyNode(
7273
NodeFactory.identifierNode(key),
7374
node.expression
74-
);
75-
});
75+
)
76+
);
77+
}
7678

77-
let structure: ESTree.Node = NodeFactory.variableDeclarationNode(
79+
const structure: ESTree.Node = NodeFactory.variableDeclarationNode(
7880
[
7981
NodeFactory.variableDeclaratorNode(
8082
NodeFactory.identifierNode(this.controlFlowStorage.getStorageId()),
@@ -84,8 +86,6 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
8486
'const'
8587
);
8688

87-
structure = NodeUtils.parentizeAst(structure);
88-
8989
return [structure];
9090
}
9191
}

src/generators/identifier-names-generators/AbstractIdentifierNamesGenerator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ export abstract class AbstractIdentifierNamesGenerator implements IIdentifierNam
2727
protected readonly preservedNamesSet: Set<string> = new Set();
2828

2929
/**
30-
* @type {Map<TNodeWithLexicalScope, Set<string>>}
30+
* @type {WeakMap<TNodeWithLexicalScope, Set<string>>}
3131
*/
32-
protected readonly lexicalScopesPreservedNamesMap: Map<TNodeWithLexicalScope, Set<string>> = new Map();
32+
protected readonly lexicalScopesPreservedNamesMap: WeakMap<TNodeWithLexicalScope, Set<string>> = new WeakMap();
3333

3434
/**
3535
* @param {IRandomGenerator} randomGenerator

src/interfaces/node-transformers/control-flow-transformers/IControlFlowReplacer.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ import { TControlFlowStorage } from '../../../types/storages/TControlFlowStorage
44

55
export interface IControlFlowReplacer {
66
/**
7-
* @param node
8-
* @param parentNode
9-
* @param controlFlowStorage
10-
* @returns ESTree.Node
7+
* @param {Node} node
8+
* @param {Node} parentNode
9+
* @param {TControlFlowStorage} controlFlowStorage
10+
* @returns {Node}
1111
*/
1212
replace (
1313
node: ESTree.Node,
1414
parentNode: ESTree.Node,
1515
controlFlowStorage: TControlFlowStorage
1616
): ESTree.Node;
17+
18+
/**
19+
* @param {TControlFlowStorage} controlFlowStorage
20+
* @returns {string}
21+
*/
22+
generateStorageKey (controlFlowStorage: TControlFlowStorage): string;
1723
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { IInitializable } from '../IInitializable';
2+
3+
export interface IWeakMapStorage <K extends object, V> extends IInitializable {
4+
/**
5+
* @param {K} key
6+
* @returns {V | undefined}
7+
*/
8+
get (key: K): V | undefined;
9+
10+
/**
11+
* @param {K} key
12+
* @returns {V}
13+
*/
14+
getOrThrow (key: K): V;
15+
16+
/**
17+
* @returns {WeakMap<K, V>}
18+
*/
19+
getStorage (): WeakMap <K, V>;
20+
21+
/**
22+
* @returns string
23+
*/
24+
getStorageId (): string;
25+
26+
/**
27+
* @param {K} key
28+
* @returns {boolean}
29+
*/
30+
has (key: K): boolean;
31+
32+
/**
33+
* @param {K} key
34+
* @param {V} value
35+
*/
36+
set (key: K, value: V): void;
37+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { TNodeWithLexicalScopeStatements } from '../../../types/node/TNodeWithLexicalScopeStatements';
22
import { TStringArrayScopeCallsWrappersDataByEncoding } from '../../../types/node-transformers/string-array-transformers/TStringArrayScopeCallsWrappersDataByEncoding';
33

4-
import { IMapStorage } from '../IMapStorage';
4+
import { IWeakMapStorage } from '../IWeakMapStorage';
55

66
// eslint-disable-next-line @typescript-eslint/no-empty-interface
7-
export interface IStringArrayScopeCallsWrappersDataStorage extends IMapStorage<
7+
export interface IStringArrayScopeCallsWrappersDataStorage extends IWeakMapStorage<
88
TNodeWithLexicalScopeStatements,
99
TStringArrayScopeCallsWrappersDataByEncoding
1010
> {}

src/node-transformers/control-flow-transformers/BlockStatementControlFlowTransformer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ export class BlockStatementControlFlowTransformer extends AbstractNodeTransforme
101101
* @returns {IVisitor | null}
102102
*/
103103
public getVisitor (nodeTransformationStage: NodeTransformationStage): IVisitor | null {
104+
if (!this.options.controlFlowFlattening) {
105+
return null;
106+
}
107+
104108
switch (nodeTransformationStage) {
105109
case NodeTransformationStage.ControlFlowFlattening:
106110
return {

src/node-transformers/control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import * as ESTree from 'estree';
55

66
import { TControlFlowCustomNodeFactory } from '../../../types/container/custom-nodes/TControlFlowCustomNodeFactory';
77
import { TControlFlowStorage } from '../../../types/storages/TControlFlowStorage';
8+
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
89

910
import { IControlFlowReplacer } from '../../../interfaces/node-transformers/control-flow-transformers/IControlFlowReplacer';
1011
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
12+
import { IIdentifierNamesGenerator } from '../../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
1113
import { IOptions } from '../../../interfaces/options/IOptions';
1214
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
1315

@@ -18,6 +20,11 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
1820
*/
1921
protected readonly controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory;
2022

23+
/**
24+
* @type {IIdentifierNamesGenerator}
25+
*/
26+
protected readonly identifierNamesGenerator: IIdentifierNamesGenerator;
27+
2128
/**
2229
* @type {IOptions}
2330
*/
@@ -35,38 +42,39 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
3542

3643
/**
3744
* @param {TControlFlowCustomNodeFactory} controlFlowCustomNodeFactory
45+
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
3846
* @param {IRandomGenerator} randomGenerator
3947
* @param {IOptions} options
4048
*/
4149
public constructor (
4250
@inject(ServiceIdentifiers.Factory__IControlFlowCustomNode)
4351
controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory,
52+
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
53+
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
4454
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
4555
@inject(ServiceIdentifiers.IOptions) options: IOptions
4656
) {
4757
this.controlFlowCustomNodeFactory = controlFlowCustomNodeFactory;
58+
this.identifierNamesGenerator = identifierNamesGeneratorFactory(options);
4859
this.randomGenerator = randomGenerator;
4960
this.options = options;
5061
}
5162

5263
/**
53-
* @param {Map<string, Map<string, string[]>>} identifierDataByControlFlowStorageId
54-
* @param {string} controlFlowStorageId
55-
* @returns {Map<string, string[]>}
64+
* Generates storage key with length of 5 characters to prevent collisions and to guarantee that
65+
* these keys will be added to the string array storage
66+
*
67+
* @param {TControlFlowStorage} controlFlowStorage
68+
* @returns {string}
5669
*/
57-
protected static getStorageKeysByIdForCurrentStorage (
58-
identifierDataByControlFlowStorageId: Map<string, Map<string, string[]>>,
59-
controlFlowStorageId: string
60-
): Map<string, string[]> {
61-
let storageKeysById: Map<string, string[]>;
62-
63-
if (identifierDataByControlFlowStorageId.has(controlFlowStorageId)) {
64-
storageKeysById = <Map<string, string[]>>identifierDataByControlFlowStorageId.get(controlFlowStorageId);
65-
} else {
66-
storageKeysById = new Map <string, string[]>();
70+
public generateStorageKey (controlFlowStorage: TControlFlowStorage): string {
71+
const key: string = this.randomGenerator.getRandomString(5);
72+
73+
if (controlFlowStorage.has(key)) {
74+
return this.generateStorageKey(controlFlowStorage);
6775
}
6876

69-
return storageKeysById;
77+
return key;
7078
}
7179

7280
/**
@@ -83,28 +91,18 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
8391
usingExistingIdentifierChance: number
8492
): string {
8593
const controlFlowStorageId: string = controlFlowStorage.getStorageId();
86-
const storageKeysById: Map<string, string[]> = AbstractControlFlowReplacer
87-
.getStorageKeysByIdForCurrentStorage(this.replacerDataByControlFlowStorageId, controlFlowStorageId);
88-
const storageKeysForCurrentId: string[] | undefined = storageKeysById.get(replacerId);
89-
90-
if (
91-
this.randomGenerator.getMathRandom() < usingExistingIdentifierChance &&
92-
storageKeysForCurrentId &&
93-
storageKeysForCurrentId.length
94-
) {
95-
return this.randomGenerator.getRandomGenerator().pickone(storageKeysForCurrentId);
96-
}
94+
const storageKeysById: Map<string, string[]> = this.replacerDataByControlFlowStorageId.get(controlFlowStorageId)
95+
?? new Map <string, string[]>();
96+
const storageKeysForCurrentId: string[] | null = storageKeysById.get(replacerId) ?? null;
9797

98-
const generateStorageKey: (length: number) => string = (length: number) => {
99-
const key: string = this.randomGenerator.getRandomString(length);
98+
const shouldPickFromStorageKeysById = this.randomGenerator.getMathRandom() < usingExistingIdentifierChance
99+
&& storageKeysForCurrentId?.length;
100100

101-
if (controlFlowStorage.getStorage().has(key)) {
102-
return generateStorageKey(length);
103-
}
101+
if (shouldPickFromStorageKeysById) {
102+
return this.randomGenerator.getRandomGenerator().pickone(storageKeysForCurrentId);
103+
}
104104

105-
return key;
106-
};
107-
const storageKey: string = generateStorageKey(5);
105+
const storageKey: string = this.generateStorageKey(controlFlowStorage);
108106

109107
storageKeysById.set(replacerId, [storageKey]);
110108
this.replacerDataByControlFlowStorageId.set(controlFlowStorageId, storageKeysById);
@@ -116,8 +114,13 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
116114
/**
117115
* @param {Node} node
118116
* @param {Node} parentNode
117+
* @param {TNodeWithLexicalScope} controlFlowStorageLexicalScopeNode
119118
* @param {TControlFlowStorage} controlFlowStorage
120119
* @returns {Node}
121120
*/
122-
public abstract replace (node: ESTree.Node, parentNode: ESTree.Node, controlFlowStorage: TControlFlowStorage): ESTree.Node;
121+
public abstract replace (
122+
node: ESTree.Node,
123+
parentNode: ESTree.Node,
124+
controlFlowStorage: TControlFlowStorage
125+
): ESTree.Node;
123126
}

0 commit comments

Comments
 (0)