Auto detection of prevailing kind of variables

This commit is contained in:
sanex3339
2020-01-09 01:30:34 +03:00
parent f355309628
commit 3a1cc4e4f5
87 changed files with 25021 additions and 225 deletions
+12178 -1
View File
File diff suppressed because one or more lines are too long
+11586 -1
View File
File diff suppressed because one or more lines are too long
@@ -0,0 +1,61 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { IArrayUtils } from '../../interfaces/utils/IArrayUtils';
import { IPrevailingKindOfVariablesAnalyzer } from '../../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { NodeGuards } from '../../node/NodeGuards';
@injectable()
export class PrevailingKindOfVariablesAnalyzer implements IPrevailingKindOfVariablesAnalyzer {
/**
* @type {ESTree.VariableDeclaration['kind']}
*/
private static readonly defaultKindOfVariables: ESTree.VariableDeclaration['kind'] = 'var';
/**
* @type {IArrayUtils}
*/
private readonly arrayUtils: IArrayUtils;
/**
* @type {ESTree.VariableDeclaration['kind']}
*/
private prevailingKindOfVariables: ESTree.VariableDeclaration['kind'] = PrevailingKindOfVariablesAnalyzer.defaultKindOfVariables;
constructor (
@inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils
) {
this.arrayUtils = arrayUtils;
}
/**
* @param {Program} astTree
*/
public analyze (astTree: ESTree.Program): void {
const variableKinds: ESTree.VariableDeclaration['kind'][] = [];
estraverse.traverse(astTree, {
enter: (node: ESTree.Node): estraverse.VisitorOption | void => {
if (!NodeGuards.isVariableDeclarationNode(node)) {
return;
}
variableKinds.push(node.kind);
}
});
this.prevailingKindOfVariables = this.arrayUtils.findMostOccurringElement(variableKinds)
|| PrevailingKindOfVariablesAnalyzer.defaultKindOfVariables;
}
/**
* @returns {VariableDeclaration["kind"]}
*/
public getPrevailingKind (): ESTree.VariableDeclaration['kind'] {
return this.prevailingKindOfVariables;
}
}
+2
View File
@@ -35,10 +35,12 @@ export enum ServiceIdentifiers {
IOptions = 'IOptions',
IOptionsNormalizer = 'IOptionsNormalizer',
IObfuscatingReplacer = 'IObfuscatingReplacer',
IPrevailingKindOfVariablesAnalyzer = 'IPrevailingKindOfVariablesAnalyzer',
IPropertiesExtractor = 'IPropertiesExtractor',
IRandomGenerator = 'IRandomGenerator',
ISourceCode = 'ISourceCode',
ISourceMapCorrector = 'ISourceMapCorrector',
ITemplateFormatter = 'ITemplateFormatter',
ITransformersRunner = 'ITransformersRunner',
Newable__ICustomNode = 'Newable<ICustomNode>',
Newable__TControlFlowStorage = 'Newable<TControlFlowStorage>',
@@ -4,12 +4,14 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { ICalleeDataExtractor } from '../../../interfaces/analyzers/calls-graph-analyzer/ICalleeDataExtractor';
import { ICallsGraphAnalyzer } from '../../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphAnalyzer';
import { IPrevailingKindOfVariablesAnalyzer } from '../../../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { CalleeDataExtractor } from '../../../enums/analyzers/calls-graph-analyzer/CalleeDataExtractor';
import { CallsGraphAnalyzer } from '../../../analyzers/calls-graph-analyzer/CallsGraphAnalyzer';
import { FunctionDeclarationCalleeDataExtractor } from '../../../analyzers/calls-graph-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor';
import { FunctionExpressionCalleeDataExtractor } from '../../../analyzers/calls-graph-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor';
import { ObjectExpressionCalleeDataExtractor } from '../../../analyzers/calls-graph-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor';
import { PrevailingKindOfVariablesAnalyzer } from '../../../analyzers/prevailing-kind-of-variables-analyzer/PrevailingKindOfVariablesAnalyzer';
export const analyzersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// calls graph analyzer
@@ -17,6 +19,11 @@ export const analyzersModule: interfaces.ContainerModule = new ContainerModule((
.to(CallsGraphAnalyzer)
.inSingletonScope();
// prevailing kind of variables analyzer
bind<IPrevailingKindOfVariablesAnalyzer>(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer)
.to(PrevailingKindOfVariablesAnalyzer)
.inSingletonScope();
// callee data extractors
bind<ICalleeDataExtractor>(ServiceIdentifiers.ICalleeDataExtractor)
.to(FunctionDeclarationCalleeDataExtractor)
@@ -160,7 +160,9 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
.getConstructorFactory<ControlFlowCustomNode, ICustomNode>(
ServiceIdentifiers.Newable__ICustomNode,
ServiceIdentifiers.Factory__IIdentifierNamesGenerator,
ServiceIdentifiers.ITemplateFormatter,
ServiceIdentifiers.IRandomGenerator,
ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer,
ServiceIdentifiers.IOptions
));
@@ -170,6 +172,7 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
.getConstructorFactory<DeadCodeInjectionCustomNode, ICustomNode>(
ServiceIdentifiers.Newable__ICustomNode,
ServiceIdentifiers.Factory__IIdentifierNamesGenerator,
ServiceIdentifiers.ITemplateFormatter,
ServiceIdentifiers.IRandomGenerator,
ServiceIdentifiers.IOptions
));
@@ -180,7 +183,9 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
.getConstructorFactory<ObjectExpressionKeysTransformerCustomNode, ICustomNode>(
ServiceIdentifiers.Newable__ICustomNode,
ServiceIdentifiers.Factory__IIdentifierNamesGenerator,
ServiceIdentifiers.ITemplateFormatter,
ServiceIdentifiers.IRandomGenerator,
ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer,
ServiceIdentifiers.IOptions
));
@@ -7,6 +7,7 @@ import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenc
import { ILevelledTopologicalSorter } from '../../../interfaces/utils/ILevelledTopologicalSorter';
import { INodeTransformerNamesGroupsBuilder } from '../../../interfaces/utils/INodeTransformerNamesGroupsBuilder';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../../interfaces/utils/ITemplateFormatter';
import { ArrayUtils } from '../../../utils/ArrayUtils';
import { CryptUtils } from '../../../utils/CryptUtils';
@@ -14,6 +15,7 @@ import { EscapeSequenceEncoder } from '../../../utils/EscapeSequenceEncoder';
import { LevelledTopologicalSorter } from '../../../utils/LevelledTopologicalSorter';
import { NodeTransformerNamesGroupsBuilder } from '../../../utils/NodeTransformerNamesGroupsBuilder';
import { RandomGenerator } from '../../../utils/RandomGenerator';
import { TemplateFormatter } from '../../../utils/TemplateFormatter';
export const utilsModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// array utils
@@ -44,4 +46,9 @@ export const utilsModule: interfaces.ContainerModule = new ContainerModule((bind
bind<INodeTransformerNamesGroupsBuilder>(ServiceIdentifiers.INodeTransformerNamesGroupsBuilder)
.to(NodeTransformerNamesGroupsBuilder)
.inSingletonScope();
// template formatter
bind<ITemplateFormatter>(ServiceIdentifiers.ITemplateFormatter)
.to(TemplateFormatter)
.inSingletonScope();
});
+10 -1
View File
@@ -8,6 +8,7 @@ import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
import { IIdentifierNamesGenerator } from '../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
import { IOptions } from '../interfaces/options/IOptions';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../interfaces/utils/ITemplateFormatter';
import { GlobalVariableTemplate1 } from '../templates/GlobalVariableTemplate1';
import { GlobalVariableTemplate2 } from '../templates/GlobalVariableTemplate2';
@@ -42,18 +43,26 @@ export abstract class AbstractCustomNode implements ICustomNode {
*/
protected readonly randomGenerator: IRandomGenerator;
/**
* @type {ITemplateFormatter}
*/
protected readonly templateFormatter: ITemplateFormatter;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
protected constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.identifierNamesGenerator = identifierNamesGeneratorFactory(options);
this.templateFormatter = templateFormatter;
this.randomGenerator = randomGenerator;
this.options = options;
}
@@ -1,13 +1,12 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
@@ -29,16 +28,18 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -63,7 +64,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
? this.getGlobalVariableTemplate()
: GlobalVariableNoEvalTemplate();
return format(ConsoleOutputDisableExpressionTemplate(), {
return this.templateFormatter.format(ConsoleOutputDisableExpressionTemplate(), {
consoleLogDisableFunctionName: this.identifierNamesGenerator.generate(),
globalVariableTemplate,
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
@@ -8,6 +8,7 @@ import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -25,16 +26,18 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -7,7 +7,9 @@ import { TIdentifierNamesGeneratorFactory } from '../../types/container/generato
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IPrevailingKindOfVariablesAnalyzer } from '../../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -30,6 +32,11 @@ export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode
@initializable()
private originalKeysIndexesInShuffledArray!: number[];
/**
* @type {ESTree.VariableDeclaration['kind']}
*/
private readonly prevailingKindOfVariables: ESTree.VariableDeclaration['kind'];
/**
* @type {number[]}
*/
@@ -38,16 +45,23 @@ export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
* @param {IPrevailingKindOfVariablesAnalyzer} prevailingKindOfVariablesAnalyzer
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
@inject(ServiceIdentifiers.IOptions) options: IOptions,
@inject(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer)
prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer,
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
this.prevailingKindOfVariables = prevailingKindOfVariablesAnalyzer.getPrevailingKind();
}
/**
@@ -72,26 +86,29 @@ export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode
const controllerIdentifierName: string = this.randomGenerator.getRandomString(6);
const indexIdentifierName: string = this.randomGenerator.getRandomString(6);
const structure: ESTree.BlockStatement = NodeFactory.blockStatementNode([
NodeFactory.variableDeclarationNode([
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode(controllerIdentifierName),
NodeFactory.callExpressionNode(
NodeFactory.memberExpressionNode(
NodeFactory.literalNode(
this.originalKeysIndexesInShuffledArray.join('|')
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode(controllerIdentifierName),
NodeFactory.callExpressionNode(
NodeFactory.memberExpressionNode(
NodeFactory.literalNode(
this.originalKeysIndexesInShuffledArray.join('|')
),
NodeFactory.identifierNode('split')
),
NodeFactory.identifierNode('split')
),
[
NodeFactory.literalNode('|')
]
[
NodeFactory.literalNode('|')
]
)
),
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode(indexIdentifierName),
NodeFactory.literalNode(0)
)
),
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode(indexIdentifierName),
NodeFactory.literalNode(0)
)
]),
],
this.prevailingKindOfVariables
),
NodeFactory.whileStatementNode(
NodeFactory.literalNode(true),
NodeFactory.blockStatementNode([
@@ -8,6 +8,7 @@ import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -25,16 +26,18 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -8,6 +8,7 @@ import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -25,16 +26,18 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -6,6 +6,7 @@ import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -22,16 +23,18 @@ export class StringLiteralNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -12,6 +12,7 @@ import { TStatement } from '../../../types/node/TStatement';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from "../../../interfaces/utils/IRandomGenerator";
import { ITemplateFormatter } from '../../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../../decorators/Initializable';
@@ -47,16 +48,18 @@ export class CallExpressionControlFlowStorageCallNode extends AbstractCustomNode
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -9,7 +9,9 @@ import { TStatement } from '../../../types/node/TStatement';
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IPrevailingKindOfVariablesAnalyzer } from '../../../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../../decorators/Initializable';
@@ -26,18 +28,30 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
@initializable()
private controlFlowStorage!: TControlFlowStorage;
/**
* @type {ESTree.VariableDeclaration['kind']}
*/
private readonly prevailingKindOfVariables: ESTree.VariableDeclaration['kind'];
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
* @param {IPrevailingKindOfVariablesAnalyzer} prevailingKindOfVariablesAnalyzer
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
@inject(ServiceIdentifiers.IOptions) options: IOptions,
@inject(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer)
prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
this.prevailingKindOfVariables = prevailingKindOfVariablesAnalyzer.getPrevailingKind();
}
/**
@@ -66,12 +80,15 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
);
});
let structure: ESTree.Node = NodeFactory.variableDeclarationNode([
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode(this.controlFlowStorage.getStorageId()),
NodeFactory.objectExpressionNode(propertyNodes)
)
]);
let structure: ESTree.Node = NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode(this.controlFlowStorage.getStorageId()),
NodeFactory.objectExpressionNode(propertyNodes)
)
],
this.prevailingKindOfVariables
);
structure = NodeUtils.parentizeAst(structure);
@@ -8,6 +8,7 @@ import { TStatement } from '../../../types/node/TStatement';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../../decorators/Initializable';
@@ -43,16 +44,18 @@ export class ExpressionWithOperatorControlFlowStorageCallNode extends AbstractCu
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -6,6 +6,7 @@ import { TStatement } from '../../../types/node/TStatement';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../../decorators/Initializable';
@@ -29,16 +30,18 @@ export class StringLiteralControlFlowStorageCallNode extends AbstractCustomNode
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -8,6 +8,7 @@ import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -31,16 +32,18 @@ export class BlockStatementDeadCodeInjectionNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -1,13 +1,12 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -32,16 +31,18 @@ export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -64,7 +65,7 @@ export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
* @returns {string}
*/
protected getTemplate (): string {
return format(DebugProtectionFunctionCallTemplate(), {
return this.templateFormatter.format(DebugProtectionFunctionCallTemplate(), {
debugProtectionFunctionName: this.debugProtectionFunctionName,
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
});
@@ -1,13 +1,12 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -26,16 +25,18 @@ export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -56,7 +57,7 @@ export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
* @returns {string}
*/
protected getTemplate (): string {
return format(DebugProtectionFunctionIntervalTemplate(), {
return this.templateFormatter.format(DebugProtectionFunctionIntervalTemplate(), {
debugProtectionFunctionName: this.debugProtectionFunctionName
});
}
@@ -1,13 +1,12 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
@@ -30,16 +29,18 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -64,7 +65,7 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode {
? DebuggerTemplate()
: DebuggerTemplateNoEval();
return format(DebugProtectionFunctionTemplate(), {
return this.templateFormatter.format(DebugProtectionFunctionTemplate(), {
debuggerTemplate,
debugProtectionFunctionName: this.debugProtectionFunctionName
});
@@ -1,14 +1,13 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICryptUtils } from '../../interfaces/utils/ICryptUtils';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
@@ -35,6 +34,7 @@ export class DomainLockNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {ICryptUtils} cryptUtils
* @param {IOptions} options
@@ -42,11 +42,12 @@ export class DomainLockNode extends AbstractCustomNode {
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.ICryptUtils) cryptUtils: ICryptUtils,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
this.cryptUtils = cryptUtils;
}
@@ -78,7 +79,7 @@ export class DomainLockNode extends AbstractCustomNode {
? this.getGlobalVariableTemplate()
: GlobalVariableNoEvalTemplate();
return format(DomainLockNodeTemplate(), {
return this.templateFormatter.format(DomainLockNodeTemplate(), {
domainLockFunctionName: this.identifierNamesGenerator.generate(),
diff: diff,
domains: hiddenDomainsString,
@@ -1,8 +1,6 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
@@ -20,6 +18,7 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../options/presets/NoCustomNodes'
import { AbstractCustomNode } from '../AbstractCustomNode';
import { JavaScriptObfuscator } from '../../JavaScriptObfuscatorFacade';
import { NodeUtils } from '../../node/NodeUtils';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
@injectable()
export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
@@ -37,16 +36,18 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -71,7 +72,7 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
protected getTemplate (): string {
if (this.appendEvent === ObfuscationEvent.AfterObfuscation) {
return JavaScriptObfuscator.obfuscate(
format(SingleNodeCallControllerTemplate(), {
this.templateFormatter.format(SingleNodeCallControllerTemplate(), {
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
}),
{
@@ -83,7 +84,7 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
).getObfuscatedCode();
}
return format(SingleNodeCallControllerTemplate(), {
return this.templateFormatter.format(SingleNodeCallControllerTemplate(), {
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
});
}
@@ -1,29 +1,45 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as ESTree from 'estree';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IPrevailingKindOfVariablesAnalyzer } from '../../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { NodeFactory } from '../../node/NodeFactory';
@injectable()
export class BasePropertiesExtractorObjectExpressionHostNode extends AbstractCustomNode {
/**
* @type {ESTree.VariableDeclaration['kind']}
*/
private readonly prevailingKindOfVariables: ESTree.VariableDeclaration['kind'];
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
* @param {IPrevailingKindOfVariablesAnalyzer} prevailingKindOfVariablesAnalyzer
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
@inject(ServiceIdentifiers.IOptions) options: IOptions,
@inject(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer)
prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer,
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
this.prevailingKindOfVariables = prevailingKindOfVariablesAnalyzer.getPrevailingKind();
}
public initialize (): void {}
@@ -32,14 +48,17 @@ export class BasePropertiesExtractorObjectExpressionHostNode extends AbstractCus
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
const structure: TStatement = NodeFactory.variableDeclarationNode([
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode(
this.identifierNamesGenerator.generate()
),
NodeFactory.objectExpressionNode([])
)
]);
const structure: TStatement = NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode(
this.identifierNamesGenerator.generate()
),
NodeFactory.objectExpressionNode([])
)
],
this.prevailingKindOfVariables
);
return [structure];
}
@@ -1,14 +1,13 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -35,6 +34,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IEscapeSequenceEncoder} escapeSequenceEncoder
* @param {IOptions} options
@@ -42,11 +42,12 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
this.escapeSequenceEncoder = escapeSequenceEncoder;
}
@@ -70,7 +71,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
*/
protected getTemplate (): string {
return JavaScriptObfuscator.obfuscate(
format(SelfDefendingTemplate(this.escapeSequenceEncoder), {
this.templateFormatter.format(SelfDefendingTemplate(this.escapeSequenceEncoder), {
selfDefendingFunctionName: this.identifierNamesGenerator.generate(),
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
}),
@@ -1,14 +1,13 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
@@ -50,6 +49,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IEscapeSequenceEncoder} escapeSequenceEncoder
* @param {IOptions} options
@@ -57,11 +57,12 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
this.escapeSequenceEncoder = escapeSequenceEncoder;
}
@@ -92,7 +93,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
const decodeNodeTemplate: string = this.getDecodeStringArrayTemplate();
return JavaScriptObfuscator.obfuscate(
format(StringArrayCallsWrapperTemplate(), {
this.templateFormatter.format(StringArrayCallsWrapperTemplate(), {
decodeNodeTemplate,
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
stringArrayName: this.stringArrayName
@@ -113,13 +114,13 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.BrowserNoEval
? this.getGlobalVariableTemplate()
: GlobalVariableNoEvalTemplate();
const atobPolyfill: string = format(AtobTemplate(), { globalVariableTemplate });
const atobPolyfill: string = this.templateFormatter.format(AtobTemplate(), { globalVariableTemplate });
let decodeStringArrayTemplate: string = '';
let selfDefendingCode: string = '';
if (this.options.selfDefending) {
selfDefendingCode = format(
selfDefendingCode = this.templateFormatter.format(
SelfDefendingTemplate(
this.randomGenerator,
this.escapeSequenceEncoder
@@ -133,7 +134,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
switch (this.options.stringArrayEncoding) {
case StringArrayEncoding.Rc4:
decodeStringArrayTemplate = format(
decodeStringArrayTemplate = this.templateFormatter.format(
StringArrayRc4DecodeNodeTemplate(this.randomGenerator),
{
atobPolyfill,
@@ -146,7 +147,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
break;
case StringArrayEncoding.Base64:
decodeStringArrayTemplate = format(
decodeStringArrayTemplate = this.templateFormatter.format(
StringArrayBase64DecodeNodeTemplate(this.randomGenerator),
{
atobPolyfill,
@@ -1,14 +1,13 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { TStringArrayStorage } from '../../types/storages/TStringArrayStorage';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -40,16 +39,18 @@ export class StringArrayNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
}
/**
@@ -87,7 +88,7 @@ export class StringArrayNode extends AbstractCustomNode {
* @returns {string}
*/
protected getTemplate (): string {
return format(StringArrayTemplate(), {
return this.templateFormatter.format(StringArrayTemplate(), {
stringArrayName: this.stringArrayName,
stringArray: this.stringArrayStorage.toString()
});
@@ -1,14 +1,13 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import format from 'string-template';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ITemplateFormatter } from '../../interfaces/utils/ITemplateFormatter';
import { initializable } from '../../decorators/Initializable';
@@ -43,6 +42,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ITemplateFormatter} templateFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IEscapeSequenceEncoder} escapeSequenceEncoder
* @param {IOptions} options
@@ -50,11 +50,12 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ITemplateFormatter) templateFormatter: ITemplateFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
super(identifierNamesGeneratorFactory, templateFormatter, randomGenerator, options);
this.escapeSequenceEncoder = escapeSequenceEncoder;
}
@@ -88,7 +89,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
let code: string = '';
if (this.options.selfDefending) {
code = format(SelfDefendingTemplate(this.escapeSequenceEncoder), {
code = this.templateFormatter.format(SelfDefendingTemplate(this.escapeSequenceEncoder), {
timesName,
whileFunctionName
});
@@ -97,7 +98,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
}
return JavaScriptObfuscator.obfuscate(
format(StringArrayRotateFunctionTemplate(), {
this.templateFormatter.format(StringArrayRotateFunctionTemplate(), {
code,
timesName,
stringArrayName: this.stringArrayName,
+2 -2
View File
@@ -3,7 +3,7 @@ import * as ESTree from 'estree';
export interface IAnalyzer <T> {
/**
* @param {Program} astTree
* @returns {T[]}
* @returns {T}
*/
analyze (astTree: ESTree.Program): T[];
analyze (astTree: ESTree.Program): T;
}
@@ -3,7 +3,7 @@ import * as ESTree from 'estree';
import { IAnalyzer } from '../IAnalyzer';
import { ICallsGraphData } from './ICallsGraphData';
export interface ICallsGraphAnalyzer extends IAnalyzer<ICallsGraphData> {
export interface ICallsGraphAnalyzer extends IAnalyzer<ICallsGraphData[]> {
/**
* @param {Program} astTree
* @returns {ICallsGraphData[]}
@@ -0,0 +1,15 @@
import * as ESTree from 'estree';
import { IAnalyzer } from '../IAnalyzer';
export interface IPrevailingKindOfVariablesAnalyzer extends IAnalyzer<void> {
/**
* @param {Program} astTree
*/
analyze (astTree: ESTree.Program): void;
/**
* @returns {ESTree.VariableDeclaration['kind']}
*/
getPrevailingKind (): ESTree.VariableDeclaration['kind'];
}
+6
View File
@@ -5,6 +5,12 @@ export interface IArrayUtils {
*/
createWithRange (length: number): number[];
/**
* @param {T[]} array
* @returns {T | null}
*/
findMostOccurringElement <T extends string | number> (array: T[]): T | null;
/**
* @param array
* @param times
+13
View File
@@ -0,0 +1,13 @@
import { TObject } from '../../types/TObject';
export interface ITemplateFormatter {
/**
* @param {string} template
* @param {TMapping} mapping
* @returns {string}
*/
format <TMapping extends TObject> (
template: string,
mapping: TMapping
): string;
}
@@ -11,6 +11,7 @@ import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ICallsGraphAnalyzer } from '../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphAnalyzer';
import { ICallsGraphData } from '../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphData';
import { IPrevailingKindOfVariablesAnalyzer } from '../../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
import { ObfuscationEvent } from '../../enums/event-emitters/ObfuscationEvent';
@@ -44,8 +45,14 @@ export class CustomNodesTransformer extends AbstractNodeTransformer {
*/
private callsGraphData: ICallsGraphData[] = [];
/**
* @type {IPrevailingKindOfVariablesAnalyzer}
*/
private readonly prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer;
/**
* @param {ICallsGraphAnalyzer} callsGraphAnalyzer
* @param {IPrevailingKindOfVariablesAnalyzer} prevailingKindOfVariablesAnalyzer
* @param {IObfuscationEventEmitter} obfuscationEventEmitter
* @param {TCustomNodeGroupStorage} customNodeGroupStorage
* @param {IRandomGenerator} randomGenerator
@@ -53,6 +60,8 @@ export class CustomNodesTransformer extends AbstractNodeTransformer {
*/
constructor (
@inject(ServiceIdentifiers.ICallsGraphAnalyzer) callsGraphAnalyzer: ICallsGraphAnalyzer,
@inject(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer)
prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer,
@inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
@inject(ServiceIdentifiers.TCustomNodeGroupStorage) customNodeGroupStorage: TCustomNodeGroupStorage,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@@ -61,6 +70,7 @@ export class CustomNodesTransformer extends AbstractNodeTransformer {
super(randomGenerator, options);
this.callsGraphAnalyzer = callsGraphAnalyzer;
this.prevailingKindOfVariablesAnalyzer = prevailingKindOfVariablesAnalyzer;
this.obfuscationEventEmitter = obfuscationEventEmitter;
this.customNodeGroupStorage = customNodeGroupStorage;
}
@@ -103,6 +113,7 @@ export class CustomNodesTransformer extends AbstractNodeTransformer {
*/
public analyzeNode (node: ESTree.Program, parentNode: ESTree.Node | null): void {
this.callsGraphData = this.callsGraphAnalyzer.analyze(node);
this.prevailingKindOfVariablesAnalyzer.analyze(node);
}
/**
+4 -1
View File
@@ -33,7 +33,10 @@ export class NodeUtils {
* @returns {Statement[]}
*/
public static convertCodeToStructure (code: string): ESTree.Statement[] {
const structure: ESTree.Program = espree.parse(code, { sourceType: 'script' });
const structure: ESTree.Program = espree.parse(code, {
ecmaVersion: 10,
sourceType: 'script'
});
estraverse.replace(structure, {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node => {
+7 -5
View File
@@ -6,21 +6,23 @@ export function AtobTemplate (): string {
(function () {
{globalVariableTemplate}
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
that.atob || (
that.atob = function(input) {
var str = String(input).replace(/=+$/, '');
const str = String(input).replace(/=+$/, '');
let output = '';
for (
var bc = 0, bs, buffer, idx = 0, output = '';
let bc = 0, bs, buffer, idx = 0;
buffer = str.charAt(idx++);
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
buffer = chars.indexOf(buffer);
}
return output;
});
return output;
}
);
})();
`;
}
@@ -3,7 +3,7 @@
*/
export function GlobalVariableNoEvalTemplate (): string {
return `
var that = (typeof window !== 'undefined'
const that = (typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
+2 -2
View File
@@ -3,10 +3,10 @@
*/
export function GlobalVariableTemplate1 (): string {
return `
var that;
let that;
try {
var getGlobal = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
const getGlobal = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
that = getGlobal();
} catch (e) {
+3 -3
View File
@@ -3,8 +3,8 @@
*/
export function GlobalVariableTemplate2 (): string {
return `
var getGlobal = function () {
var globalObject;
const getGlobal = function () {
let globalObject;
try {
globalObject = Function('return (function() ' + '{}.constructor("return this")( )' + ');')();
@@ -14,6 +14,6 @@ export function GlobalVariableTemplate2 (): string {
return globalObject;
};
var that = getGlobal();
const that = getGlobal();
`;
}
+7 -5
View File
@@ -3,18 +3,20 @@
*/
export function Rc4Template (): string {
return `
var rc4 = function (str, key) {
var s = [], j = 0, x, res = '', newStr = '';
const rc4 = function (str, key) {
let s = [], j = 0, x, res = '', newStr = '';
str = atob(str);
for (var k = 0, length = str.length; k < length; k++) {
for (let k = 0, length = str.length; k < length; k++) {
newStr += '%' + ('00' + str.charCodeAt(k).toString(16)).slice(-2);
}
str = decodeURIComponent(newStr);
let i;
for (var i = 0; i < 256; i++) {
for (i = 0; i < 256; i++) {
s[i] = i;
}
@@ -28,7 +30,7 @@ export function Rc4Template (): string {
i = 0;
j = 0;
for (var y = 0; y < str.length; y++) {
for (let y = 0; y < str.length; y++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
x = s[i];
@@ -3,13 +3,13 @@
*/
export function SingleNodeCallControllerTemplate (): string {
return `
var {singleNodeCallControllerFunctionName} = (function(){
var firstCall = true;
const {singleNodeCallControllerFunctionName} = (function(){
let firstCall = true;
return function (context, fn){
var rfn = firstCall ? function(){
const rfn = firstCall ? function(){
if(fn){
var res = fn.apply(context, arguments);
const res = fn.apply(context, arguments);
fn = null;
return res;
}
@@ -3,14 +3,14 @@
*/
export function ConsoleOutputDisableExpressionTemplate (): string {
return `
var {consoleLogDisableFunctionName} = {singleNodeCallControllerFunctionName}(this, function () {
var func = function () {};
const {consoleLogDisableFunctionName} = {singleNodeCallControllerFunctionName}(this, function () {
const func = function () {};
{globalVariableTemplate}
if (!that.console) {
that.console = (function (func){
var c = {};
const c = {};
c.log = func;
c.warn = func;
@@ -4,18 +4,21 @@
export function DebugProtectionFunctionCallTemplate (): string {
return `
(function () {
{singleNodeCallControllerFunctionName}(this, function () {
var regExp1 = new RegExp('function *\\\\( *\\\\)');
var regExp2 = new RegExp('\\\\+\\\\+ *\\(?:[a-zA-Z_$][0-9a-zA-Z_$]*\\)', 'i');
var result = {debugProtectionFunctionName}('init');
if (!regExp1.test(result + 'chain') || !regExp2.test(result + 'input')) {
result('0');
} else {
{debugProtectionFunctionName}();
{singleNodeCallControllerFunctionName}(
this,
function () {
const regExp1 = new RegExp('function *\\\\( *\\\\)');
const regExp2 = new RegExp('\\\\+\\\\+ *\\(?:[a-zA-Z_$][0-9a-zA-Z_$]*\\)', 'i');
const result = {debugProtectionFunctionName}('init');
if (!regExp1.test(result + 'chain') || !regExp2.test(result + 'input')) {
result('0');
} else {
{debugProtectionFunctionName}();
}
}
})();
)();
})();
`;
}
@@ -4,7 +4,7 @@
export function DebuggerTemplateNoEval (): string {
return `
if (typeof counter === 'string') {
var func = function () {
const func = function () {
while (true) {}
};
@@ -3,17 +3,17 @@
*/
export function DomainLockNodeTemplate (): string {
return `
var {domainLockFunctionName} = {singleNodeCallControllerFunctionName}(this, function () {
const {domainLockFunctionName} = {singleNodeCallControllerFunctionName}(this, function () {
{globalVariableTemplate}
var func = function () {
const func = function () {
return {
key: 'item',
value: 'attribute',
getAttribute: function () {
for (var i = 0; i < 1000; i--) {
var isPositive = i > 0;
for (let i = 0; i < 1000; i--) {
const isPositive = i > 0;
switch (isPositive) {
case true:
@@ -26,14 +26,14 @@ export function DomainLockNodeTemplate (): string {
};
};
var regExp = new RegExp("[{diff}]", "g");
var domains = "{domains}".replace(regExp, "").split(";");
var document;
var domain;
var location;
var hostname;
const regExp = new RegExp("[{diff}]", "g");
const domains = "{domains}".replace(regExp, "").split(";");
let document;
let domain;
let location;
let hostname;
for (var d in that) {
for (let d in that) {
if (d.length == 8 && d.charCodeAt(7) == 116 && d.charCodeAt(5) == 101 && d.charCodeAt(3) == 117 && d.charCodeAt(0) == 100) {
document = d;
@@ -41,7 +41,7 @@ export function DomainLockNodeTemplate (): string {
}
}
for (var d1 in that[document]) {
for (let d1 in that[document]) {
if (d1.length == 6 && d1.charCodeAt(5) == 110 && d1.charCodeAt(0) == 100) {
domain = d1;
@@ -50,7 +50,7 @@ export function DomainLockNodeTemplate (): string {
}
if (!("~" > domain)) {
for (var d2 in that[document]) {
for (let d2 in that[document]) {
if (d2.length == 8 && d2.charCodeAt(7) == 110 && d2.charCodeAt(0) == 108) {
location = d2;
@@ -58,7 +58,7 @@ export function DomainLockNodeTemplate (): string {
}
}
for (var d3 in that[document][location]) {
for (let d3 in that[document][location]) {
if (d3.length == 8 && d3.charCodeAt(7) == 101 && d3.charCodeAt(0) == 104) {
hostname = d3;
@@ -71,21 +71,21 @@ export function DomainLockNodeTemplate (): string {
return;
}
var documentDomain = that[document][domain];
var documentLocationHostName = !!that[document][location] && that[document][location][hostname];
var currentDomain = documentDomain || documentLocationHostName;
const documentDomain = that[document][domain];
const documentLocationHostName = !!that[document][location] && that[document][location][hostname];
const currentDomain = documentDomain || documentLocationHostName;
if (!currentDomain) {
return;
}
var ok = false;
let ok = false;
for (var i = 0; i < domains.length; i++) {
var domain = domains[i];
var position = currentDomain.length - domain.length;
var lastIndex = currentDomain.indexOf(domain, position);
var endsWith = lastIndex !== -1 && lastIndex === position;
for (let i = 0; i < domains.length; i++) {
const domain = domains[i];
const position = currentDomain.length - domain.length;
const lastIndex = currentDomain.indexOf(domain, position);
const endsWith = lastIndex !== -1 && lastIndex === position;
if (endsWith) {
if (currentDomain.length == domain.length || domain.indexOf(".") === 0) {
@@ -9,38 +9,38 @@ import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenc
*/
export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEncoder): string {
return `
var {selfDefendingFunctionName} = {singleNodeCallControllerFunctionName}(this, function () {
var func1 = function(){return 'dev';},
const {selfDefendingFunctionName} = {singleNodeCallControllerFunctionName}(this, function () {
const func1 = function(){return 'dev';},
func2 = function () {
return 'window';
};
var test1 = function () {
var regExp = new RegExp('${
const test1 = function () {
const regExp = new RegExp('${
escapeSequenceEncoder.encode(`\\w+ *\\(\\) *{\\w+ *['|"].+['|"];? *}`, true)
}');
return !regExp.test(func1.toString());
};
var test2 = function () {
var regExp = new RegExp('${
const test2 = function () {
const regExp = new RegExp('${
escapeSequenceEncoder.encode(`(\\\\[x|u](\\w){2,4})+`, true)
}');
return regExp.test(func2.toString());
};
var recursiveFunc1 = function (string) {
var i = ~-1 >> 1 + 255 % 0;
const recursiveFunc1 = function (string) {
const i = ~-1 >> 1 + 255 % 0;
if (string.indexOf('i' === i)) {
recursiveFunc2(string)
}
};
var recursiveFunc2 = function (string) {
var i = ~-4 >> 1 + 255 % 0;
const recursiveFunc2 = function (string) {
const i = ~-4 >> 1 + 255 % 0;
if (string.indexOf((true+"")[3]) !== i) {
recursiveFunc1(string)
@@ -23,7 +23,7 @@ export function SelfDefendingTemplate (
const stateResultIdentifier: string = randomGenerator.getRandomString(identifierLength);
return `
var StatesClass = function (${rc4BytesIdentifier}) {
const StatesClass = function (${rc4BytesIdentifier}) {
this.${rc4BytesIdentifier} = ${rc4BytesIdentifier};
this.${statesIdentifier} = [1, 0, 0];
this.${newStateIdentifier} = function(){return 'newState';};
@@ -36,8 +36,8 @@ export function SelfDefendingTemplate (
};
StatesClass.prototype.${checkStateIdentifier} = function () {
var regExp = new RegExp(this.${firstStateIdentifier} + this.${secondStateIdentifier});
var expression = regExp.test(this.${newStateIdentifier}.toString())
const regExp = new RegExp(this.${firstStateIdentifier} + this.${secondStateIdentifier});
const expression = regExp.test(this.${newStateIdentifier}.toString())
? --this.${statesIdentifier}[1]
: --this.${statesIdentifier}[0];
@@ -53,7 +53,7 @@ export function SelfDefendingTemplate (
};
StatesClass.prototype.${getStateIdentifier} = function (${rc4BytesIdentifier}) {
for (var i = 0, len = this.${statesIdentifier}.length; i < len; i++) {
for (let i = 0, len = this.${statesIdentifier}.length; i < len; i++) {
this.${statesIdentifier}.push(Math.round(Math.random()));
len = this.${statesIdentifier}.length;
}
@@ -18,10 +18,10 @@ export function StringArrayBase64DecodeNodeTemplate (
{atobPolyfill}
{stringArrayCallsWrapperName}.${base64DecodeFunctionIdentifier} = function (str) {
var string = atob(str);
var newStringChars = [];
const string = atob(str);
let newStringChars = [];
for (var i = 0, length = string.length; i < length; i++) {
for (let i = 0, length = string.length; i < length; i++) {
newStringChars += '%' + ('00' + string.charCodeAt(i).toString(16)).slice(-2);
}
@@ -33,7 +33,7 @@ export function StringArrayBase64DecodeNodeTemplate (
{stringArrayCallsWrapperName}.${initializedIdentifier} = true;
}
var cachedValue = {stringArrayCallsWrapperName}.${dataIdentifier}[index];
const cachedValue = {stringArrayCallsWrapperName}.${dataIdentifier}[index];
if (cachedValue === undefined) {
{selfDefendingCode}
@@ -3,10 +3,10 @@
*/
export function StringArrayCallsWrapperTemplate (): string {
return `
var {stringArrayCallsWrapperName} = function (index, key) {
const {stringArrayCallsWrapperName} = function (index, key) {
index = index - 0;
var value = {stringArrayName}[index];
let value = {stringArrayName}[index];
{decodeNodeTemplate}
@@ -26,7 +26,7 @@ export function StringArrayRc4DecodeNodeTemplate (
{stringArrayCallsWrapperName}.${initializedIdentifier} = true;
}
var cachedValue = {stringArrayCallsWrapperName}.${dataIdentifier}[index];
const cachedValue = {stringArrayCallsWrapperName}.${dataIdentifier}[index];
if (cachedValue === undefined) {
if ({stringArrayCallsWrapperName}.${onceIdentifier} === undefined) {
@@ -3,6 +3,6 @@
*/
export function StringArrayTemplate (): string {
return `
var {stringArrayName} = [{stringArray}];
const {stringArrayName} = [{stringArray}];
`;
}
@@ -8,8 +8,8 @@ import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenc
*/
export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEncoder): string {
return `
var selfDefendingFunc = function () {
var object = {
const selfDefendingFunc = function () {
const object = {
data: {
key: 'cookie',
value: 'timeout'
@@ -17,16 +17,15 @@ export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEnc
setCookie: function (options, name, value, document) {
document = document || {};
var updatedCookie = name + "=" + value;
var i = 0;
let updatedCookie = name + "=" + value;
let i = 0;
for (var i = 0, len = options.length; i < len; i++) {
var propName = options[i];
for (let i = 0, len = options.length; i < len; i++) {
const propName = options[i];
updatedCookie += "; " + propName;
var propValue = options[propName];
const propValue = options[propName];
options.push(propValue);
len = options.length;
@@ -41,11 +40,11 @@ export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEnc
removeCookie: function(){return 'dev';},
getCookie: function (document, name) {
document = document || function (value) { return value };
var matches = document(new RegExp(
const matches = document(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
var func = function (param1, param2) {
const func = function (param1, param2) {
param1(++param2);
};
@@ -55,8 +54,8 @@ export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEnc
}
};
var test1 = function () {
var regExp = new RegExp('${
const test1 = function () {
const regExp = new RegExp('${
escapeSequenceEncoder.encode(`\\w+ *\\(\\) *{\\w+ *['|"].+['|"];? *}`, true)
}');
@@ -65,8 +64,8 @@ export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEnc
object['updateCookie'] = test1;
var cookie = '';
var result = object['updateCookie']();
let cookie = '';
const result = object['updateCookie']();
if (!result) {
object['setCookie'](['*'], 'counter', 1);
@@ -4,7 +4,7 @@
export function StringArrayRotateFunctionTemplate (): string {
return `
(function (array, {timesName}) {
var {whileFunctionName} = function (times) {
const {whileFunctionName} = function (times) {
while (--times) {
array['push'](array['shift']());
}
+31
View File
@@ -34,6 +34,37 @@ export class ArrayUtils implements IArrayUtils {
return range;
}
/**
* @param {T[]} array
* @returns {T | null}
*/
public findMostOccurringElement <T extends string | number> (array: T[]): T | null {
const arrayLength: number = array.length;
if (!arrayLength) {
return null;
}
const elementsMap: Partial<{[key in T]: number}> = {};
let mostOccurringElement: T = array[0];
let mostOccurringElementCount: number = 1;
for (const element of array) {
const currentElementCount: number = elementsMap[element] ?? 0;
const updatedElementCount: number = currentElementCount + 1;
if (updatedElementCount > mostOccurringElementCount) {
mostOccurringElement = element;
mostOccurringElementCount = updatedElementCount;
}
elementsMap[element] = updatedElementCount;
}
return mostOccurringElement;
}
/**
* @param {T[]} array
* @param {number} times
+53
View File
@@ -0,0 +1,53 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import * as ESTree from 'estree';
import format from 'string-template';
import { TObject } from '../types/TObject';
import { IPrevailingKindOfVariablesAnalyzer } from '../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { ITemplateFormatter } from '../interfaces/utils/ITemplateFormatter';
@injectable()
export class TemplateFormatter implements ITemplateFormatter {
/**
* @type {IPrevailingKindOfVariablesAnalyzer}
*/
private readonly prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer;
/**
* @param {IPrevailingKindOfVariablesAnalyzer} prevailingKindOfVariablesAnalyzer
*/
constructor (
@inject(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer)
prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer,
) {
this.prevailingKindOfVariablesAnalyzer = prevailingKindOfVariablesAnalyzer;
}
public format <TMapping extends TObject> (
template: string,
mapping: TMapping
): string {
const formattedTemplate: string = format(template, mapping);
const prevailingKindOfVariables: ESTree.VariableDeclaration['kind'] =
this.prevailingKindOfVariablesAnalyzer.getPrevailingKind();
return this.replaceKindOfVariablesToPrevailingKind(formattedTemplate, prevailingKindOfVariables);
}
/**
* @param {string} template
* @param {ESTree.VariableDeclaration['kind']} prevailingKindOfVariables
* @returns {string}
*/
private replaceKindOfVariablesToPrevailingKind (
template: string,
prevailingKindOfVariables: ESTree.VariableDeclaration['kind']
): string {
return prevailingKindOfVariables === 'var'
? template.replace(/(?<!\w)(?:let|const)(?!\w)/g, prevailingKindOfVariables)
: template;
}
}
+4 -7
View File
@@ -7,16 +7,13 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
(function () {
var a = 'a', b = 'b';
({[a]: a, [b]: b} = {a: 1, b: 2});
console.log(a, b);
})();
var foo = 'abcd'
var bar = 'abcde'
`,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
stringArray: true,
stringArrayThreshold: 1
}
).getObfuscatedCode();
@@ -15,6 +15,7 @@ import { IdentifierNamesGenerator } from '../../../src/enums/generators/identifi
import { buildLargeCode } from '../../helpers/buildLargeCode';
import { getRegExpMatch } from '../../helpers/getRegExpMatch';
import { readFileAsString } from '../../helpers/readFileAsString';
import { TInputOptions } from '../../../src/types/options/TInputOptions';
describe('JavaScriptObfuscator', () => {
describe('obfuscate', () => {
@@ -710,5 +711,92 @@ describe('JavaScriptObfuscator', () => {
assert.equal(areCollisionsExists, false);
});
});
describe('Prevailing kind of variables', () => {
const baseParams: TInputOptions = {
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
deadCodeInjection: true,
deadCodeInjectionThreshold: 1,
debugProtection: true,
debugProtectionInterval: true,
disableConsoleOutput: false,
rotateStringArray: true,
selfDefending: true,
stringArray: true,
stringArrayThreshold: 1,
transformObjectKeys: true,
unicodeEscapeSequence: false
};
describe('`var` kind', function () {
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-var.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
...baseParams,
stringArrayEncoding: StringArrayEncoding.Rc4
}
).getObfuscatedCode();
});
it('does not break on run', () => {
assert.doesNotThrow(() => eval(obfuscatedCode));
});
});
describe('`const` kind', function () {
describe('Variant #1: StringArrayEncoding: rc4', () => {
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
...baseParams,
stringArrayEncoding: StringArrayEncoding.Rc4
}
).getObfuscatedCode();
});
it('does not break on run', () => {
assert.doesNotThrow(() => eval(obfuscatedCode));
});
});
describe('Variant #2: StringArrayEncoding: base64', () => {
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
...baseParams,
stringArrayEncoding: StringArrayEncoding.Rc4
}
).getObfuscatedCode();
});
it('does not break on run', () => {
assert.doesNotThrow(() => eval(obfuscatedCode));
});
});
});
});
});
});
@@ -0,0 +1,5 @@
function test() {
const foo = 'foo';
return foo;
}
test();
@@ -0,0 +1,5 @@
function test() {
var foo = 'foo';
return foo;
}
test();
@@ -650,5 +650,85 @@ describe('BlockStatementControlFlowTransformer', function () {
assert.match(obfuscatedCode, returnStatementRegExp);
});
});
describe('Prevailing kind of variables', () => {
describe('`var` kind', () => {
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-var.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1
}
).getObfuscatedCode();
});
describe('switch-case map', () => {
const switchCaseMapVariableRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *_0x(?:[a-f0-9]){4,6}\['.*'\]\['split'\]\('\|'\)/;
const switchCaseMapStringRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *\{'.*' *: *'(.*)'\};/;
const expectedSwitchCasesSequence: string[] = ['0', '1', '2', '3', '4'];
let switchCaseMap: string[];
before(() => {
const switchCaseMapMatch: string = getRegExpMatch(obfuscatedCode, switchCaseMapStringRegExp);
switchCaseMap = switchCaseMapMatch.split('|').sort();
});
it('should create switch-case map variable', () => {
assert.match(obfuscatedCode, switchCaseMapVariableRegExp);
});
it('should create valid switch-case map variable with order of switch cases sequence', () => {
assert.deepEqual(switchCaseMap, expectedSwitchCasesSequence);
});
});
});
describe('`const` kind', () => {
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1
}
).getObfuscatedCode();
});
describe('switch-case map', () => {
const switchCaseMapVariableRegExp: RegExp = /const *_0x(?:[a-f0-9]){4,6} *= *_0x(?:[a-f0-9]){4,6}\['.*'\]\['split'\]\('\|'\)/;
const switchCaseMapStringRegExp: RegExp = /const *_0x(?:[a-f0-9]){4,6} *= *\{'.*' *: *'(.*)'\};/;
const expectedSwitchCasesSequence: string[] = ['0', '1', '2', '3', '4'];
let switchCaseMap: string[];
before(() => {
const switchCaseMapMatch: string = getRegExpMatch(obfuscatedCode, switchCaseMapStringRegExp);
switchCaseMap = switchCaseMapMatch.split('|').sort();
});
it('should create switch-case map variable', () => {
assert.match(obfuscatedCode, switchCaseMapVariableRegExp);
});
it('should create valid switch-case map variable with order of switch cases sequence', () => {
assert.deepEqual(switchCaseMap, expectedSwitchCasesSequence);
});
});
});
});
});
});
@@ -0,0 +1,9 @@
const test = 0;
(function () {
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
})();
@@ -0,0 +1,9 @@
var test = 0;
(function () {
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
})();
@@ -268,5 +268,53 @@ describe('FunctionControlFlowTransformer', function () {
});
});
});
describe('prevailing kind of variables', () => {
describe('Variant #1 - `var` kind', () => {
const regexp: RegExp = new RegExp(`var *${variableMatch} *= *\\{`);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-1.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1
}
).getObfuscatedCode();
});
it('should add `control flow storage` node to the obfuscated code', () => {
assert.match(obfuscatedCode, regexp);
});
});
describe('Variant #2 - `const` kind', () => {
const regexp: RegExp = new RegExp(`const *${variableMatch} *= *\\{`);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-2.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1
}
).getObfuscatedCode();
});
it('should add `control flow storage` node to the obfuscated code', () => {
assert.match(obfuscatedCode, regexp);
});
});
});
});
});
@@ -316,7 +316,7 @@ describe('ObjectExpressionKeysTransformer', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'foo';` +
`const *${variableMatch} *= *${variableMatch}, *` +
`var *${variableMatch} *= *${variableMatch}, *` +
`${variableMatch} *= *${variableMatch}\\['foo'];` +
``;
const regExp: RegExp = new RegExp(match);
@@ -344,7 +344,7 @@ describe('ObjectExpressionKeysTransformer', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'foo';` +
`const *${variableMatch} *= *${variableMatch}, *` +
`var *${variableMatch} *= *${variableMatch}, *` +
`${variableMatch} *= *\\[${variableMatch}\\['foo']];` +
``;
const regExp: RegExp = new RegExp(match);
@@ -959,7 +959,7 @@ describe('ObjectExpressionKeysTransformer', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['bar'] *= *'bar';` +
`const *${variableMatch} *= *{}, *` +
`var *${variableMatch} *= *{}, *` +
`${variableMatch} *= *${variableMatch}, *` +
`${variableMatch} *= *${variableMatch}\\['bar']; *` +
`${variableMatch}\\['foo'] *= *'foo';` +
@@ -988,6 +988,62 @@ describe('ObjectExpressionKeysTransformer', () => {
});
});
describe('prevailing kind of variables', () => {
describe('Variant #1: `var` kind`', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`${variableMatch}\\['baz'] *= *'bark';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-1.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2: `const` kind`', () => {
const match: string = `` +
`const *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`${variableMatch}\\['baz'] *= *'bark';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-2.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
describe('Ignore transformation', () => {
describe('Variant #1: disabled option', () => {
const match: string = `` +
@@ -0,0 +1,6 @@
(function(){
var object = {
foo: 'bar',
baz: 'bark'
};
})();
@@ -0,0 +1,6 @@
(function(){
const object = {
foo: 'bar',
baz: 'bark'
};
})();
@@ -1,5 +1,5 @@
(function () {
const object1 = {foo: 'foo'},
var object1 = {foo: 'foo'},
object2 = {bar: 'bar'},
variable = object2.bar;
console.log(variable);
@@ -1,4 +1,4 @@
(function () {
const object = {foo: 'foo'},
var object = {foo: 'foo'},
variable = object.foo;
})();
@@ -1,4 +1,4 @@
(function () {
const object = {foo: 'foo'},
var object = {foo: 'foo'},
variable = [object.foo];
})();
@@ -1,10 +1,10 @@
import { assert } from 'chai';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../../src/options/presets/NoCustomNodes';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
import { readFileAsString } from '../../../../../../helpers/readFileAsString';
import { readFileAsString } from '../../../../../helpers/readFileAsString';
import { JavaScriptObfuscator } from '../../../../../../../src/JavaScriptObfuscatorFacade';
import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
describe('BaseIdentifierObfuscatingReplacer', () => {
describe('Base rule', () => {
@@ -10,8 +10,6 @@ import { ObfuscationTarget } from '../../../../src/enums/ObfuscationTarget';
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
async function spawnThread(obfuscatedCode: string, threadCallback: Function, timeoutCallback: Function): Promise<void> {
const evaluationWorker = await spawn(new Worker('./workers/evaluation-worker'));
@@ -4,20 +4,25 @@ import format from 'string-template';
import { assert } from 'chai';
import { ServiceIdentifiers } from '../../../../src/container/ServiceIdentifiers';
import { ServiceIdentifiers } from '../../../../../src/container/ServiceIdentifiers';
import { ICryptUtils } from '../../../../src/interfaces/utils/ICryptUtils';
import { IInversifyContainerFacade } from '../../../../src/interfaces/container/IInversifyContainerFacade';
import { IRandomGenerator } from '../../../../src/interfaces/utils/IRandomGenerator';
import { ICryptUtils } from '../../../../../src/interfaces/utils/ICryptUtils';
import { IInversifyContainerFacade } from '../../../../../src/interfaces/container/IInversifyContainerFacade';
import { IObfuscatedCode } from '../../../../../src/interfaces/source-code/IObfuscatedCode';
import { IRandomGenerator } from '../../../../../src/interfaces/utils/IRandomGenerator';
import { AtobTemplate } from '../../../../src/templates/AtobTemplate';
import { GlobalVariableTemplate1 } from '../../../../src/templates/GlobalVariableTemplate1';
import { Rc4Template } from '../../../../src/templates/Rc4Template';
import { StringArrayBase64DecodeNodeTemplate } from '../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate';
import { StringArrayCallsWrapperTemplate } from '../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
import { StringArrayRc4DecodeNodeTemplate } from '../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate';
import { AtobTemplate } from '../../../../../src/templates/AtobTemplate';
import { GlobalVariableTemplate1 } from '../../../../../src/templates/GlobalVariableTemplate1';
import { Rc4Template } from '../../../../../src/templates/Rc4Template';
import { StringArrayBase64DecodeNodeTemplate } from '../../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate';
import { StringArrayCallsWrapperTemplate } from '../../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
import { StringArrayRc4DecodeNodeTemplate } from '../../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate';
import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { InversifyContainerFacade } from '../../../../../src/container/InversifyContainerFacade';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { readFileAsString } from '../../../../helpers/readFileAsString';
describe('StringArrayCallsWrapperNodeTemplate', () => {
const stringArrayName: string = 'stringArrayName';
@@ -111,4 +116,52 @@ describe('StringArrayCallsWrapperNodeTemplate', () => {
assert.deepEqual(decodedValue, expectedDecodedValue);
});
});
describe('Prevailing kind of variables', () => {
describe('`var` kind', () => {
let obfuscatedCode: string,
stringArrayCallsWrapperRegExp: RegExp = /var (_0x(\w){4}) *= *function/;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-var.js');
const obfuscatedCodeObject: IObfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1
}
);
obfuscatedCode = obfuscatedCodeObject.getObfuscatedCode();
});
it('Should return correct variable kind for string array calls wrapper', () => {
assert.match(obfuscatedCode, stringArrayCallsWrapperRegExp);
});
});
describe('`const` kind', () => {
let obfuscatedCode: string,
stringArrayCallsWrapperRegExp: RegExp = /const (_0x(\w){4}) *= *function/;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
const obfuscatedCodeObject: IObfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1
}
);
obfuscatedCode = obfuscatedCodeObject.getObfuscatedCode();
});
it('Should return correct variable kind for string array calls wrapper', () => {
assert.match(obfuscatedCode, stringArrayCallsWrapperRegExp);
});
});
});
});
@@ -0,0 +1,62 @@
import 'reflect-metadata';
import { assert } from 'chai';
import { IObfuscatedCode } from '../../../../../src/interfaces/source-code/IObfuscatedCode';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { readFileAsString } from '../../../../helpers/readFileAsString';
describe('StringArrayRotateFunctionTemplate', () => {
describe('Prevailing kind of variables', () => {
describe('`var` kind', () => {
let obfuscatedCode: string,
stringArrayRotateFunctionRegExp: RegExp = /function\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}\){var _0x([a-f0-9]){4,6} *= *function/;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-var.js');
const obfuscatedCodeObject: IObfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1,
rotateStringArray: true
}
);
obfuscatedCode = obfuscatedCodeObject.getObfuscatedCode();
});
it('Should return correct variable kind for string array rotate function', () => {
assert.match(obfuscatedCode, stringArrayRotateFunctionRegExp);
});
});
describe('`const` kind', () => {
let obfuscatedCode: string,
stringArrayRotateFunctionRegExp: RegExp = /function\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}\){const _0x([a-f0-9]){4,6} *= *function/;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
const obfuscatedCodeObject: IObfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1,
rotateStringArray: true
}
);
obfuscatedCode = obfuscatedCodeObject.getObfuscatedCode();
});
it('Should return correct variable kind for string array rotate function', () => {
assert.match(obfuscatedCode, stringArrayRotateFunctionRegExp);
});
});
});
});
@@ -0,0 +1,60 @@
import 'reflect-metadata';
import { assert } from 'chai';
import { IObfuscatedCode } from '../../../../../src/interfaces/source-code/IObfuscatedCode';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { readFileAsString } from '../../../../helpers/readFileAsString';
describe('StringArrayTemplate', () => {
describe('Prevailing kind of variables', () => {
describe('`var` kind', () => {
let obfuscatedCode: string,
stringArrayRegExp: RegExp = /var (_0x(\w){4}) *= *\['.*'];/;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-var.js');
const obfuscatedCodeObject: IObfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1
}
);
obfuscatedCode = obfuscatedCodeObject.getObfuscatedCode();
});
it('Should return correct variable kind for string array', () => {
assert.match(obfuscatedCode, stringArrayRegExp);
});
});
describe('`const` kind', () => {
let obfuscatedCode: string,
stringArrayRegExp: RegExp = /const (_0x(\w){4}) *= *\['.*'];/;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
const obfuscatedCodeObject: IObfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1
}
);
obfuscatedCode = obfuscatedCodeObject.getObfuscatedCode();
});
it('Should return correct variable kind for string array', () => {
assert.match(obfuscatedCode, stringArrayRegExp);
});
});
});
});
+5 -2
View File
@@ -6,6 +6,7 @@ require('source-map-support').install();
* Unit tests
*/
import './unit-tests/analyzers/calls-graph-analyzer/CallsGraphAnalyzer.spec';
import './unit-tests/analyzers/prevailing-kind-of-variables-analyzer/PrevailingKindOfVariablesAnalyzer.spec';
import './unit-tests/cli/sanitizers/ArraySanitizer.spec';
import './unit-tests/cli/sanitizers/BooleanSanitizer.spec';
import './unit-tests/cli/sanitizers/IdentifierNamesGeneratorSanitizer.spec';
@@ -75,7 +76,7 @@ import './functional-tests/node-transformers/obfuscating-transformers/function-t
import './functional-tests/node-transformers/obfuscating-transformers/impot-declaration-transformer/ImportDeclarationTransformer.spec';
import './functional-tests/node-transformers/obfuscating-transformers/labeled-statement-transformer/LabeledStatementTransformer.spec';
import './functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec';
import './functional-tests/node-transformers/obfuscating-transformers/literal-transformer/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.spec';
import './functional-tests/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.spec';
import './functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec';
import './functional-tests/node-transformers/preparing-transformers/eval-call-expression-transformer/EvalCallExpressionTransformer.spec';
import './functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec';
@@ -86,7 +87,9 @@ import './functional-tests/options/OptionsNormalizer.spec';
import './functional-tests/templates/debug-protection-nodes/DebugProtectionFunctionCallTemplate.spec';
import './functional-tests/templates/domain-lock-nodes/DomainLockNodeTemplate.spec';
import './functional-tests/templates/GlobalVariableNoEvalTemplate.spec';
import './functional-tests/templates/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec';
import './functional-tests/templates/string-array-nodes/string-array-template/StringArrayTemplate.spec';
import './functional-tests/templates/string-array-nodes/string-array-calls-wrapper-node-template/StringArrayCallsWrapperNodeTemplate.spec';
import './functional-tests/templates/string-array-nodes/string-array-rotate-function-template/StringArrayRotateFunctionTemplate.spec';
/**
* Performance tests
@@ -0,0 +1,172 @@
import 'reflect-metadata';
import { assert } from 'chai';
import * as ESTree from 'estree';
import { ServiceIdentifiers } from '../../../../src/container/ServiceIdentifiers';
import { IInversifyContainerFacade } from '../../../../src/interfaces/container/IInversifyContainerFacade';
import { IPrevailingKindOfVariablesAnalyzer } from '../../../../src/interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
import { NodeFactory } from '../../../../src/node/NodeFactory';
describe('PrevailingKindOfVariablesAnalyzer', () => {
let prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer;
before(() => {
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
inversifyContainerFacade.load('', '', {});
prevailingKindOfVariablesAnalyzer = inversifyContainerFacade
.get<IPrevailingKindOfVariablesAnalyzer>(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer);
});
describe('analyze', () => {
let prevailingKindOfVariables: ESTree.VariableDeclaration['kind'];
describe('Prevailing `var` kind', () => {
const expectedPrevailingKind: ESTree.VariableDeclaration['kind'] = 'var';
before(() => {
const astTree: ESTree.Program = NodeFactory.programNode([
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('foo'),
null
)
],
'var'
),
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('bar'),
null
)
],
'const'
),
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('baz'),
null
)
],
'var'
)
]);
prevailingKindOfVariablesAnalyzer.analyze(astTree);
prevailingKindOfVariables = prevailingKindOfVariablesAnalyzer.getPrevailingKind();
});
it('should return correct prevailing kind of variables', () => {
assert.equal(prevailingKindOfVariables, expectedPrevailingKind);
});
});
describe('Prevailing `let` kind', () => {
const expectedPrevailingKind: ESTree.VariableDeclaration['kind'] = 'let';
before(() => {
const astTree: ESTree.Program = NodeFactory.programNode([
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('foo'),
null
)
],
'let'
),
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('bar'),
null
)
],
'var'
),
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('baz'),
null
)
],
'let'
)
]);
prevailingKindOfVariablesAnalyzer.analyze(astTree);
prevailingKindOfVariables = prevailingKindOfVariablesAnalyzer.getPrevailingKind();
});
it('should return correct prevailing kind of variables', () => {
assert.equal(prevailingKindOfVariables, expectedPrevailingKind);
});
});
describe('Prevailing `const` kind', () => {
const expectedPrevailingKind: ESTree.VariableDeclaration['kind'] = 'const';
before(() => {
const astTree: ESTree.Program = NodeFactory.programNode([
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('foo'),
null
)
],
'let'
),
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('bar'),
null
)
],
'const'
),
NodeFactory.variableDeclarationNode(
[
NodeFactory.variableDeclaratorNode(
NodeFactory.identifierNode('baz'),
null
)
],
'const'
)
]);
prevailingKindOfVariablesAnalyzer.analyze(astTree);
prevailingKindOfVariables = prevailingKindOfVariablesAnalyzer.getPrevailingKind();
});
it('should return correct prevailing kind of variables', () => {
assert.equal(prevailingKindOfVariables, expectedPrevailingKind);
});
});
describe('No variables', () => {
const expectedPrevailingKind: ESTree.VariableDeclaration['kind'] = 'var';
before(() => {
const astTree: ESTree.Program = NodeFactory.programNode();
prevailingKindOfVariablesAnalyzer.analyze(astTree);
prevailingKindOfVariables = prevailingKindOfVariablesAnalyzer.getPrevailingKind();
});
it('should return correct prevailing kind of variables', () => {
assert.equal(prevailingKindOfVariables, expectedPrevailingKind);
});
});
});
});
+49
View File
@@ -1,3 +1,5 @@
import 'reflect-metadata';
import { assert } from 'chai';
import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
@@ -64,6 +66,53 @@ describe('ArrayUtils', () => {
});
});
describe('findMostOccurringElement', () => {
describe('empty array', () => {
const array: string[] = [];
const expectedMostOccurringElement: null = null;
let mostOccurringElement: string | null;
before(() => {
mostOccurringElement = arrayUtils.findMostOccurringElement(array);
});
it('should return null if array is empty', () => {
assert.equal(mostOccurringElement, expectedMostOccurringElement);
});
});
describe('one elements is most occurring', () => {
const array: string[] = ['foo', 'bar', 'bar', 'baz', 'bar', 'foo'];
const expectedMostOccurringElement: string = 'bar';
let mostOccurringElement: string | null;
before(() => {
mostOccurringElement = arrayUtils.findMostOccurringElement(array);
});
it('should return most occurring element', () => {
assert.equal(mostOccurringElement, expectedMostOccurringElement);
});
});
describe('few elements are most occurring', () => {
const array: string[] = ['foo', 'bar', 'bar', 'baz', 'bar'];
const expectedMostOccurringElement: string = 'bar';
let mostOccurringElement: string | null;
before(() => {
mostOccurringElement = arrayUtils.findMostOccurringElement(array);
});
it('should return first most occurring element', () => {
assert.equal(mostOccurringElement, expectedMostOccurringElement);
});
});
});
describe('rotate', () => {
let array: number[],
rotatedArray: number[];