Merge branch 'dev'

This commit is contained in:
sanex3339
2016-12-22 00:48:25 +03:00
70 changed files with 2065 additions and 1653 deletions
+1173 -975
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "0.9.0-dev.2",
"version": "0.9.0-dev.3",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
@@ -44,10 +44,9 @@
"@types/esprima": "2.1.33",
"@types/estraverse": "0.0.6",
"@types/estree": "0.0.34",
"@types/joi": "9.0.33",
"@types/lodash": "^4.14.43",
"@types/lodash": "^4.14.44",
"@types/mkdirp": "0.3.29",
"@types/mocha": "2.2.33",
"@types/mocha": "2.2.34",
"@types/node": "6.0.52",
"@types/sinon": "1.16.33",
"@types/string-template": "1.0.2",
@@ -63,6 +62,7 @@
"sinon": "2.0.0-pre.3",
"ts-node": "1.7.2",
"tslint": "4.1.1",
"tslint-loader": "^3.3.0",
"typescript": "2.1.4",
"webpack": "2.1.0-beta.27",
"webpack-node-externals": "1.5.4"
+17 -17
View File
@@ -59,6 +59,23 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
this.options = options;
}
/**
* @param sourceCode
* @returns {IObfuscationResult}
*/
public obfuscate (sourceCode: string): IObfuscationResult {
// parse AST tree
const astTree: ESTree.Program = esprima.parse(sourceCode, JavaScriptObfuscatorInternal.esprimaParams);
// obfuscate AST tree
const obfuscatedAstTree: ESTree.Program = this.obfuscator.obfuscateAstTree(astTree);
// generate code
const generatorOutput: IGeneratorOutput = this.generateCode(sourceCode, obfuscatedAstTree);
return this.getObfuscationResult(generatorOutput);
}
/**
* @param sourceCode
* @param astTree
@@ -94,21 +111,4 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
generatorOutput.map
);
}
/**
* @param sourceCode
* @returns {IObfuscationResult}
*/
public obfuscate (sourceCode: string): IObfuscationResult {
// parse AST tree
const astTree: ESTree.Program = esprima.parse(sourceCode, JavaScriptObfuscatorInternal.esprimaParams);
// obfuscate AST tree
const obfuscatedAstTree: ESTree.Program = this.obfuscator.obfuscateAstTree(astTree);
// generate code
const generatorOutput: IGeneratorOutput = this.generateCode(sourceCode, obfuscatedAstTree);
return this.getObfuscationResult(generatorOutput);
}
}
+2 -2
View File
@@ -89,8 +89,8 @@ export class Obfuscator implements IObfuscator {
constructor (
@inject(ServiceIdentifiers.IStackTraceAnalyzer) stackTraceAnalyzer: IStackTraceAnalyzer,
@inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
@inject(ServiceIdentifiers['IStorage<ICustomNodeGroup>']) customNodeGroupStorage: IStorage<ICustomNodeGroup>,
@inject(ServiceIdentifiers['Factory<INodeTransformer[]>']) nodeTransformersFactory: TNodeTransformersFactory,
@inject(ServiceIdentifiers.TCustomNodeGroupStorage) customNodeGroupStorage: IStorage<ICustomNodeGroup>,
@inject(ServiceIdentifiers.Factory__INodeTransformer) nodeTransformersFactory: TNodeTransformersFactory,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.stackTraceAnalyzer = stackTraceAnalyzer;
+1 -1
View File
@@ -28,7 +28,7 @@ export class SourceMapCorrector implements ISourceMapCorrector {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<IObfuscationResult>']) obfuscationResultFactory: TObfuscationResultFactory,
@inject(ServiceIdentifiers.Factory__IObfuscationResult) obfuscationResultFactory: TObfuscationResultFactory,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.obfuscationResultFactory = obfuscationResultFactory;
+1 -1
View File
@@ -60,7 +60,7 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
.inSingletonScope();
this.container
.bind<IObfuscationResult>(ServiceIdentifiers['Factory<IObfuscationResult>'])
.bind<IObfuscationResult>(ServiceIdentifiers.Factory__IObfuscationResult)
.toFactory<IObfuscationResult>((context: interfaces.Context) => {
return (obfuscatedCode: string, sourceMap: string) => {
const obfuscationResult: IObfuscationResult = context.container
+12 -12
View File
@@ -1,14 +1,13 @@
export const ServiceIdentifiers: any = {
'Factory<ICalleeDataExtractor>': Symbol('Factory<ICalleeDataExtractor>'),
'Factory<IControlFlowReplacer>': Symbol('Factory<IControlFlowReplacer>'),
'Factory<ICustomNode>': Symbol('Factory<ICustomNode>'),
'Factory<ICustomNodeGroup>': Symbol('Factory<ICustomNodeGroup>'),
'Factory<INodeTransformer[]>': Symbol('Factory<INodeTransformer[]>'),
'Factory<IObfuscationResult>': Symbol('Factory<IObfuscationResult>'),
'Factory<IObfuscatorReplacer>': Symbol('Factory<IObfuscatorReplacer>'),
'Factory<IStorage<ICustomNode>>': Symbol('Factory<IStorage<ICustomNode>>'),
Factory__ICalleeDataExtractor: Symbol('Factory<ICalleeDataExtractor>'),
Factory__IControlFlowReplacer: Symbol('Factory<IControlFlowReplacer>'),
Factory__ICustomNode: Symbol('Factory<ICustomNode>'),
Factory__ICustomNodeGroup: Symbol('Factory<ICustomNodeGroup>'),
Factory__INodeTransformer: Symbol('Factory<INodeTransformer[]>'),
Factory__IObfuscationResult: Symbol('Factory<IObfuscationResult>'),
Factory__IObfuscatorReplacer: Symbol('Factory<IObfuscatorReplacer>'),
Factory__TControlFlowStorage: Symbol('Factory<TControlFlowStorage>'),
ICalleeDataExtractor: Symbol('ICalleeDataExtractor'),
ICustomNode: Symbol('ICustomNode'),
ICustomNodeGroup: Symbol('ICustomNodeGroup'),
IControlFlowReplacer: Symbol('IControlFlowReplacer'),
IJavaScriptObfuscator: Symbol('IJavaScriptObfuscator'),
@@ -20,7 +19,8 @@ export const ServiceIdentifiers: any = {
IObfuscatorReplacer: Symbol('IObfuscatorReplacer'),
ISourceMapCorrector: Symbol('ISourceMapCorrector'),
IStackTraceAnalyzer: Symbol('IStackTraceAnalyzer'),
'IStorage<ICustomNode>': Symbol('IStorage<ICustomNode>'),
'IStorage<ICustomNodeGroup>': Symbol('IStorage<ICustomNodeGroup>'),
'IStorage<string>': Symbol('IStorage<string>')
Newable__ICustomNode: Symbol('Newable<ICustomNode>'),
Newable__TControlFlowStorage: Symbol('Newable<TControlFlowStorage>'),
TCustomNodeGroupStorage: Symbol('TCustomNodeGroupStorage'),
TStringArrayStorage: Symbol('TStringArrayStorage')
};
@@ -3,6 +3,7 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
import { ICustomNodeGroup } from '../../../interfaces/custom-nodes/ICustomNodeGroup';
import { IOptions } from '../../../interfaces/options/IOptions';
import { CustomNodes } from '../../../enums/container/CustomNodes';
import { CustomNodeGroups } from '../../../enums/container/CustomNodeGroups';
@@ -29,56 +30,56 @@ import { StringArrayRotateFunctionNode } from '../../../custom-nodes/string-arra
export const customNodesModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// custom nodes
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(BinaryExpressionFunctionNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(BinaryExpressionFunctionNode)
.whenTargetNamed(CustomNodes.BinaryExpressionFunctionNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(ControlFlowStorageCallNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(ControlFlowStorageCallNode)
.whenTargetNamed(CustomNodes.ControlFlowStorageCallNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(ControlFlowStorageNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(ControlFlowStorageNode)
.whenTargetNamed(CustomNodes.ControlFlowStorageNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(ConsoleOutputDisableExpressionNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(ConsoleOutputDisableExpressionNode)
.whenTargetNamed(CustomNodes.ConsoleOutputDisableExpressionNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(DebugProtectionFunctionCallNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(DebugProtectionFunctionCallNode)
.whenTargetNamed(CustomNodes.DebugProtectionFunctionCallNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(DebugProtectionFunctionIntervalNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(DebugProtectionFunctionIntervalNode)
.whenTargetNamed(CustomNodes.DebugProtectionFunctionIntervalNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(DebugProtectionFunctionNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(DebugProtectionFunctionNode)
.whenTargetNamed(CustomNodes.DebugProtectionFunctionNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(DomainLockNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(DomainLockNode)
.whenTargetNamed(CustomNodes.DomainLockNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(NodeCallsControllerFunctionNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(NodeCallsControllerFunctionNode)
.whenTargetNamed(CustomNodes.NodeCallsControllerFunctionNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(SelfDefendingUnicodeNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(SelfDefendingUnicodeNode)
.whenTargetNamed(CustomNodes.SelfDefendingUnicodeNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(StringArrayCallsWrapper)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringArrayCallsWrapper)
.whenTargetNamed(CustomNodes.StringArrayCallsWrapper);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(StringArrayNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringArrayNode)
.whenTargetNamed(CustomNodes.StringArrayNode);
bind<ICustomNode>(ServiceIdentifiers.ICustomNode)
.to(StringArrayRotateFunctionNode)
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringArrayRotateFunctionNode)
.whenTargetNamed(CustomNodes.StringArrayRotateFunctionNode);
// node groups
@@ -103,18 +104,35 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
.whenTargetNamed(CustomNodeGroups.StringArrayCustomNodeGroup);
// customNode factory
bind<ICustomNode>(ServiceIdentifiers['Factory<ICustomNode>'])
bind<ICustomNode>(ServiceIdentifiers.Factory__ICustomNode)
.toFactory<ICustomNode>((context: interfaces.Context) => {
const cache: Map <CustomNodes, interfaces.Newable<ICustomNode>> = new Map();
let cachedOptions: IOptions;
return (customNodeName: CustomNodes) => {
return context.container.getNamed<ICustomNode>(
ServiceIdentifiers.ICustomNode,
customNodeName
);
if (!cachedOptions) {
cachedOptions = context.container.get<IOptions>(ServiceIdentifiers.IOptions);
}
if (cache.has(customNodeName)) {
return new (<interfaces.Newable<ICustomNode>>cache.get(customNodeName));
}
const constructor: interfaces.Newable<ICustomNode> = context.container
.getNamed<interfaces.Newable<ICustomNode>>(
ServiceIdentifiers.Newable__ICustomNode,
customNodeName
);
cache.set(customNodeName, constructor);
return new constructor(cachedOptions);
};
});
// CustomNodeGroup factory
bind<ICustomNodeGroup>(ServiceIdentifiers['Factory<ICustomNodeGroup>'])
// customNodeGroup factory
bind<ICustomNodeGroup>(ServiceIdentifiers.Factory__ICustomNodeGroup)
.toFactory<ICustomNodeGroup>((context: interfaces.Context) => {
return (customNodeGroupName: CustomNodeGroups) => {
return context.container.getNamed<ICustomNodeGroup>(
@@ -12,7 +12,7 @@ export const nodeControlFlowTransformersModule: interfaces.ContainerModule = new
.to(BinaryExpressionControlFlowReplacer)
.whenTargetNamed(NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer);
bind<IControlFlowReplacer>(ServiceIdentifiers['Factory<IControlFlowReplacer>'])
bind<IControlFlowReplacer>(ServiceIdentifiers.Factory__IControlFlowReplacer)
.toFactory<IControlFlowReplacer>((context: interfaces.Context) => {
const cache: Map <NodeControlFlowReplacers, IControlFlowReplacer> = new Map();
@@ -27,7 +27,7 @@ export const nodeObfuscatorsModule: interfaces.ContainerModule = new ContainerMo
.to(StringLiteralReplacer)
.whenTargetNamed(NodeObfuscatorsReplacers.StringLiteralReplacer);
bind<IObfuscatorReplacer>(ServiceIdentifiers['Factory<IObfuscatorReplacer>'])
bind<IObfuscatorReplacer>(ServiceIdentifiers.Factory__IObfuscatorReplacer)
.toFactory<IObfuscatorReplacer>((context: interfaces.Context) => {
const cache: Map <NodeObfuscatorsReplacers, IObfuscatorReplacer> = new Map();
@@ -61,7 +61,7 @@ export const nodeTransformersModule: interfaces.ContainerModule = new ContainerM
.whenTargetNamed(NodeTransformers.VariableDeclarationObfuscator);
// node transformers factory
bind<INodeTransformer[]>(ServiceIdentifiers['Factory<INodeTransformer[]>'])
bind<INodeTransformer[]>(ServiceIdentifiers.Factory__INodeTransformer)
.toFactory<INodeTransformer[]>((context: interfaces.Context) => {
const cache: Map <NodeTransformers, INodeTransformer> = new Map();
@@ -30,7 +30,7 @@ export const stackTraceAnalyzerModule: interfaces.ContainerModule = new Containe
.whenTargetNamed(CalleeDataExtractors.ObjectExpressionCalleeDataExtractor);
// node transformers factory
bind<ICalleeDataExtractor>(ServiceIdentifiers['Factory<ICalleeDataExtractor>'])
bind<ICalleeDataExtractor>(ServiceIdentifiers.Factory__ICalleeDataExtractor)
.toFactory<ICalleeDataExtractor>((context: interfaces.Context) => {
const cache: Map <CalleeDataExtractors, ICalleeDataExtractor> = new Map();
@@ -1,9 +1,9 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
import { ICustomNodeGroup } from '../../../interfaces/custom-nodes/ICustomNodeGroup';
import { IStorage } from '../../../interfaces/storages/IStorage';
import { TControlFlowStorage } from '../../../types/storages/TControlFlowStorage';
import { TCustomNodeGroupStorage } from '../../../types/storages/TCustomNodeGroupStorage';
import { TStringArrayStorage } from '../../../types/storages/TStringArrayStorage';
import { ControlFlowStorage } from '../../../storages/control-flow/ControlFlowStorage';
import { CustomNodeGroupStorage } from '../../../storages/custom-node-group/CustomNodeGroupStorage';
@@ -11,22 +11,25 @@ import { StringArrayStorage } from '../../../storages/string-array/StringArraySt
export const storagesModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// storages
bind<IStorage<ICustomNodeGroup>>(ServiceIdentifiers['IStorage<ICustomNodeGroup>'])
bind<TCustomNodeGroupStorage>(ServiceIdentifiers.TCustomNodeGroupStorage)
.to(CustomNodeGroupStorage)
.inSingletonScope();
bind<IStorage<ICustomNode>>(ServiceIdentifiers['IStorage<ICustomNode>'])
.to(ControlFlowStorage);
bind<IStorage<string>>(ServiceIdentifiers['IStorage<string>'])
bind<TStringArrayStorage>(ServiceIdentifiers.TStringArrayStorage)
.to(StringArrayStorage)
.inSingletonScope();
bind<interfaces.Newable<TControlFlowStorage>>(ServiceIdentifiers.Newable__TControlFlowStorage)
.toConstructor(ControlFlowStorage);
// controlFlowStorage factory
bind<IStorage<ICustomNode>>(ServiceIdentifiers['Factory<IStorage<ICustomNode>>'])
.toFactory<IStorage<ICustomNode>>((context: interfaces.Context) => {
bind<TControlFlowStorage>(ServiceIdentifiers.Factory__TControlFlowStorage)
.toFactory<TControlFlowStorage>((context: interfaces.Context) => {
return () => {
return context.container.get<IStorage<ICustomNode>>(ServiceIdentifiers['IStorage<ICustomNode>']);
const constructor: interfaces.Newable<TControlFlowStorage> = context.container
.get<interfaces.Newable<TControlFlowStorage>>(ServiceIdentifiers.Newable__TControlFlowStorage);
return new constructor();
};
});
});
+21 -10
View File
@@ -9,6 +9,16 @@ import { NodeUtils } from '../node/NodeUtils';
@injectable()
export abstract class AbstractCustomNode implements ICustomNode {
/**
* @type {string}
*/
protected cachedCode: string;
/**
* @type {TStatement[]}
*/
protected cachedNode: TStatement[];
/**
* @type {IOptions}
*/
@@ -32,25 +42,26 @@ export abstract class AbstractCustomNode implements ICustomNode {
* @returns {string}
*/
public getCode (): string {
return NodeUtils.convertStructureToCode(this.getNode());
if (!this.cachedCode) {
this.cachedCode = NodeUtils.convertStructureToCode(this.getNode());
}
return this.cachedCode;
}
/**
* @returns {TStatement[]}
*/
public getNode (): TStatement[] {
return this.getNodeStructure();
if (!this.cachedNode) {
this.cachedNode = this.getNodeStructure();
}
return this.cachedNode;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
protected abstract getTemplate (): string;
protected abstract getNodeStructure (): TStatement[];
}
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { ConsoleOutputDisableExpressionTemplate } from '../../templates/custom-nodes/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate';
@@ -10,6 +12,7 @@ import { ConsoleOutputDisableExpressionTemplate } from '../../templates/custom-n
import { initializable } from '../../decorators/Initializable';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { NodeUtils } from '../../node/NodeUtils';
import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
@injectable()
@@ -36,6 +39,13 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
this.callsControllerFunctionName = callsControllerFunctionName;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
@@ -26,17 +26,17 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
*/
protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {Map<CustomNodes, ICustomNode>}
*/
@initializable()
protected customNodes: Map <CustomNodes, ICustomNode>;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {IObfuscationEventEmitter}
*/
@@ -48,7 +48,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -1,24 +1,25 @@
import { injectable, inject } from 'inversify';
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { BinaryOperator } from 'estree';
import { TStatement } from '../../../types/node/TStatement';
import { IOptions } from '../../../interfaces/options/IOptions';
import { initializable } from '../../../decorators/Initializable';
import { BinaryExpressionFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate';
import { AbstractCustomNode } from '../../AbstractCustomNode';
import { Nodes } from '../../../node/Nodes';
import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
@injectable()
export class BinaryExpressionFunctionNode extends AbstractCustomNode {
/**
* @type {string}
* @type {BinaryOperator}
*/
@initializable()
private operator: string;
private operator: BinaryOperator;
/**
* @param options
@@ -32,17 +33,31 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
/**
* @param operator
*/
public initialize (operator: string): void {
public initialize (operator: BinaryOperator): void {
this.operator = operator;
}
/**
* @returns {string}
* @returns {TStatement[]}
*/
protected getTemplate (): string {
return format(BinaryExpressionFunctionTemplate(), {
functionName: RandomGeneratorUtils.getRandomVariableName(1),
operator: this.operator
});
protected getNodeStructure (): TStatement[] {
return [
Nodes.getFunctionDeclarationNode(
RandomGeneratorUtils.getRandomVariableName(1),
[
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
],
Nodes.getBlockStatementNode([
Nodes.getReturnStatementNode(
Nodes.getBinaryExpressionNode(
this.operator,
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
)
)
])
)
];
}
}
@@ -1,15 +1,16 @@
import { injectable, inject } from 'inversify';
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { Expression } from 'estree';
import { TStatement } from '../../../types/node/TStatement';
import { IOptions } from '../../../interfaces/options/IOptions';
import { initializable } from '../../../decorators/Initializable';
import { ControlFlowStorageCallTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallTemplate';
import { AbstractCustomNode } from '../../AbstractCustomNode';
import { Nodes } from '../../../node/Nodes';
@injectable()
export class ControlFlowStorageCallNode extends AbstractCustomNode {
@@ -26,16 +27,16 @@ export class ControlFlowStorageCallNode extends AbstractCustomNode {
private controlFlowStorageName: string;
/**
* @type {string}
* @type {Expression}
*/
@initializable()
private leftValue: string;
private leftValue: Expression;
/**
* @type {string}
* @type {ESTree.Expression}
*/
@initializable()
private rightValue: string;
private rightValue: Expression;
/**
* @param options
@@ -55,8 +56,8 @@ export class ControlFlowStorageCallNode extends AbstractCustomNode {
public initialize (
controlFlowStorageName: string,
controlFlowStorageKey: string,
leftValue: string,
rightValue: string,
leftValue: Expression,
rightValue: Expression,
): void {
this.controlFlowStorageName = controlFlowStorageName;
this.controlFlowStorageKey = controlFlowStorageKey;
@@ -64,15 +65,20 @@ export class ControlFlowStorageCallNode extends AbstractCustomNode {
this.rightValue = rightValue;
}
/**
* @returns {string}
*/
protected getTemplate (): string {
return format(ControlFlowStorageCallTemplate(), {
controlFlowStorageKey: this.controlFlowStorageKey,
controlFlowStorageName: this.controlFlowStorageName,
leftValue: this.leftValue,
rightValue: this.rightValue
});
protected getNodeStructure (): TStatement[] {
return [
Nodes.getExpressionStatementNode(
Nodes.getCallExpressionNode(
Nodes.getMemberExpressionNode(
Nodes.getIdentifierNode(this.controlFlowStorageName),
Nodes.getIdentifierNode(this.controlFlowStorageKey)
),
[
this.leftValue,
this.rightValue
]
)
)
];
}
}
@@ -1,7 +1,9 @@
import { injectable, inject } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import * as ESTree from 'estree';
import { TStatement } from '../../types/node/TStatement';
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
import { IOptions } from '../../interfaces/options/IOptions';
@@ -9,9 +11,9 @@ import { IStorage } from '../../interfaces/storages/IStorage';
import { initializable } from '../../decorators/Initializable';
import { ControlFlowStorageTemplate } from '../../templates/custom-nodes/control-flow-storage-nodes/ControlFlowStorageTemplate';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { Nodes } from '../../node/Nodes';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class ControlFlowStorageNode extends AbstractCustomNode {
@@ -38,12 +40,27 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
}
/**
* @returns {string}
* @returns {TStatement[]}
*/
protected getTemplate (): string {
return format(ControlFlowStorageTemplate(), {
controlFlowStorage: this.controlFlowStorage.toString(),
controlFlowStorageName: this.controlFlowStorage.getStorageId()
});
protected getNodeStructure (): TStatement[] {
const structure: ESTree.Node = Nodes.getVariableDeclarationNode([
Nodes.getVariableDeclaratorNode(
Nodes.getIdentifierNode(this.controlFlowStorage.getStorageId()),
Nodes.getObjectExpressionNode(
Array
.from(this.controlFlowStorage.getStorage())
.map(([key, value]: [string, ICustomNode]) => {
return Nodes.getPropertyNode(
Nodes.getIdentifierNode(key),
<any>value.getNode()[0]
);
})
)
)
]);
NodeUtils.parentize(structure);
return [structure];
}
}
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { initializable } from '../../decorators/Initializable';
@@ -10,6 +12,7 @@ import { initializable } from '../../decorators/Initializable';
import { DebugProtectionFunctionCallTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
@@ -35,6 +38,13 @@ export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
this.debugProtectionFunctionName = debugProtectionFunctionName;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { initializable } from '../../decorators/Initializable';
@@ -10,6 +12,7 @@ import { initializable } from '../../decorators/Initializable';
import { DebugProtectionFunctionIntervalTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-interval-node/DebugProtectionFunctionIntervalTemplate';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
@@ -35,6 +38,13 @@ export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
this.debugProtectionFunctionName = debugProtectionFunctionName;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { initializable } from '../../decorators/Initializable';
@@ -10,6 +12,7 @@ import { initializable } from '../../decorators/Initializable';
import { DebugProtectionFunctionTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class DebugProtectionFunctionNode extends AbstractCustomNode {
@@ -35,6 +38,13 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode {
this.debugProtectionFunctionName = debugProtectionFunctionName;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
@@ -26,17 +26,17 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
*/
protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {Map<CustomNodes, ICustomNode>}
*/
@initializable()
protected customNodes: Map <CustomNodes, ICustomNode>;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {IObfuscationEventEmitter}
*/
@@ -48,7 +48,7 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { initializable } from '../../decorators/Initializable';
@@ -11,6 +13,7 @@ import { DomainLockNodeTemplate } from '../../templates/custom-nodes/domain-lock
import { AbstractCustomNode } from '../AbstractCustomNode';
import { CryptUtils } from '../../utils/CryptUtils';
import { NodeUtils } from '../../node/NodeUtils';
import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
@injectable()
@@ -37,12 +40,19 @@ export class DomainLockNode extends AbstractCustomNode {
this.callsControllerFunctionName = callsControllerFunctionName;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
protected getTemplate (): string {
let domainsString: string = this.options.domainLock.join(';'),
[hiddenDomainsString, diff]: string[] = CryptUtils.hideString(domainsString, domainsString.length * 3);
const domainsString: string = this.options.domainLock.join(';');
const [hiddenDomainsString, diff]: string[] = CryptUtils.hideString(domainsString, domainsString.length * 3);
return format(DomainLockNodeTemplate(), {
domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(),
@@ -26,17 +26,17 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
*/
protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {Map<CustomNodes, ICustomNode>}
*/
@initializable()
protected customNodes: Map <CustomNodes, ICustomNode>;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {IObfuscationEventEmitter}
*/
@@ -48,7 +48,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TObfuscationEvent } from '../../types/event-emitters/TObfuscationEvent';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
@@ -17,21 +18,22 @@ import { NO_CUSTOM_NODES_PRESET } from '../../options/presets/NoCustomNodes';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
/**
* @type {TObfuscationEvent}
*/
@initializable()
private appendEvent: TObfuscationEvent;
/**
* @type {string}
*/
@initializable()
protected callsControllerFunctionName: string;
/**
* @type {TObfuscationEvent}
*/
@initializable()
private appendEvent: TObfuscationEvent;
/**
* @param options
*/
@@ -50,6 +52,13 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
this.callsControllerFunctionName = callsControllerFunctionName;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { initializable } from '../../decorators/Initializable';
@@ -13,6 +15,7 @@ import { SelfDefendingTemplate } from '../../templates/custom-nodes/self-defendi
import { AbstractCustomNode } from '../AbstractCustomNode';
import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
import { NodeUtils } from '../../node/NodeUtils';
import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
@injectable()
@@ -39,6 +42,13 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
this.callsControllerFunctionName = callsControllerFunctionName;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
@@ -26,17 +26,17 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
*/
protected appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {Map<CustomNodes, ICustomNode>}
*/
@initializable()
protected customNodes: Map <CustomNodes, ICustomNode>;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {IObfuscationEventEmitter}
*/
@@ -48,7 +48,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IStorage } from '../../interfaces/storages/IStorage';
@@ -21,6 +23,7 @@ import { StringArrayRc4DecodeNodeTemplate } from '../../templates/custom-nodes/s
import { AbstractCustomNode } from '../AbstractCustomNode';
import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class StringArrayCallsWrapper extends AbstractCustomNode {
@@ -67,41 +70,10 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
}
/**
* @returns {string}
* @returns {TStatement[]}
*/
private getDecodeStringArrayTemplate (): string {
let decodeStringArrayTemplate: string = '',
selfDefendingCode: string = '';
if (this.options.selfDefending) {
selfDefendingCode = format(SelfDefendingTemplate(), {
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
stringArrayName: this.stringArrayName
});
}
switch (this.options.stringArrayEncoding) {
case StringArrayEncoding.base64:
decodeStringArrayTemplate = format(StringArrayBase64DecodeNodeTemplate(), {
atobPolyfill: AtobTemplate(),
selfDefendingCode,
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
});
break;
case StringArrayEncoding.rc4:
decodeStringArrayTemplate = format(StringArrayRc4DecodeNodeTemplate(), {
atobPolyfill: AtobTemplate(),
rc4Polyfill: Rc4Template(),
selfDefendingCode,
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
});
break;
}
return decodeStringArrayTemplate;
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
@@ -122,4 +94,42 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
}
).getObfuscatedCode();
}
/**
* @returns {string}
*/
private getDecodeStringArrayTemplate (): string {
let decodeStringArrayTemplate: string = '',
selfDefendingCode: string = '';
if (this.options.selfDefending) {
selfDefendingCode = format(SelfDefendingTemplate(), {
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
stringArrayName: this.stringArrayName
});
}
switch (this.options.stringArrayEncoding) {
case StringArrayEncoding.rc4:
decodeStringArrayTemplate = format(StringArrayRc4DecodeNodeTemplate(), {
atobPolyfill: AtobTemplate(),
rc4Polyfill: Rc4Template(),
selfDefendingCode,
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
});
break;
case StringArrayEncoding.base64:
decodeStringArrayTemplate = format(StringArrayBase64DecodeNodeTemplate(), {
atobPolyfill: AtobTemplate(),
selfDefendingCode,
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
});
break;
}
return decodeStringArrayTemplate;
}
}
@@ -13,6 +13,7 @@ import { initializable } from '../../decorators/Initializable';
import { StringArrayTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-node/StringArrayTemplate';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { NodeUtils } from '../../node/NodeUtils';
import { StringArrayStorage } from '../../storages/string-array/StringArrayStorage';
@injectable()
@@ -68,6 +69,13 @@ export class StringArrayNode extends AbstractCustomNode {
return super.getNode();
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as format from 'string-template';
import { TStatement } from '../../types/node/TStatement';
import { IOptions } from '../../interfaces/options/IOptions';
import { IStorage } from '../../interfaces/storages/IStorage';
@@ -15,6 +17,7 @@ import { StringArrayRotateFunctionTemplate } from '../../templates/custom-nodes/
import { AbstractCustomNode } from '../AbstractCustomNode';
import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
import { NodeUtils } from '../../node/NodeUtils';
import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
import { Utils } from '../../utils/Utils';
@@ -62,13 +65,21 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
this.stringArrayRotateValue = stringArrayRotateValue;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
return NodeUtils.convertCodeToStructure(this.getTemplate());
}
/**
* @returns {string}
*/
protected getTemplate (): string {
let code: string = '',
timesName: string = RandomGeneratorUtils.getRandomVariableName(),
whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
const timesName: string = RandomGeneratorUtils.getRandomVariableName();
const whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
let code: string = '';
if (this.options.selfDefending) {
code = format(SelfDefendingTemplate(), {
@@ -28,17 +28,17 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
*/
protected appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {Map<CustomNodes, ICustomNode>}
*/
@initializable()
protected customNodes: Map <CustomNodes, ICustomNode>;
/**
* @type {TCustomNodeFactory}
*/
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {IObfuscationEventEmitter}
*/
@@ -57,9 +57,9 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
@inject(ServiceIdentifiers['IStorage<string>']) stringArrayStorage: IStorage<string>,
@inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: IStorage<string>,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -108,7 +108,7 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
const stringArrayStorageId: string = this.stringArrayStorage.getStorageId();
const stringArrayName: string = `_${Utils.hexadecimalPrefix}${stringArrayStorageId}`;
const stringArrayCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${Utils.stringRotate(stringArrayStorageId, 2)}`;
const stringArrayCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${Utils.stringRotate(stringArrayStorageId, 1)}`;
let stringArrayRotateValue: number;
@@ -3,7 +3,6 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import * as _ from 'lodash';
import { TControlFlowReplacerFactory } from '../../types/container/TControlFlowReplacerFactory';
import { TControlFlowStorageFactory } from '../../types/container/TControlFlowStorageFactory';
@@ -50,9 +49,9 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
private controlFlowData: Map <ESTree.Node, IStorage<ICustomNode>> = new Map();
/**
* @type {TStatement[][]}
* @type {TNodeWithBlockStatement[]}
*/
private readonly controlFlowNodesList: TStatement[][] = [];
private readonly hostNodesWithControlFlowNode: TNodeWithBlockStatement[] = [];
/**
* @type {TControlFlowReplacerFactory}
@@ -76,9 +75,9 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<IStorage<ICustomNode>>']) controlFlowStorageFactory: TControlFlowStorageFactory,
@inject(ServiceIdentifiers['Factory<IControlFlowReplacer>']) controlFlowReplacerFactory: TControlFlowReplacerFactory,
@inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.Factory__TControlFlowStorage) controlFlowStorageFactory: TControlFlowStorageFactory,
@inject(ServiceIdentifiers.Factory__IControlFlowReplacer) controlFlowReplacerFactory: TControlFlowReplacerFactory,
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -112,27 +111,6 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
return RandomGeneratorUtils.getRandomGenerator().pickone(blockScopesOfNode);
}
/**
* @param hostNodeBody
* @param controlFlowNodesList
*/
private static removeOldControlFlowNodeFromHostNodeBody (
hostNodeBody: TStatement[],
controlFlowNodesList: TStatement[][]
): TStatement[] {
for (let controlFlowNode of controlFlowNodesList) {
const firstIndexOfNode: number = hostNodeBody.indexOf(controlFlowNode[0]);
if (firstIndexOfNode === -1) {
continue;
}
return _.difference(hostNodeBody, controlFlowNode);
}
return hostNodeBody;
}
/**
* @param functionNode
*/
@@ -151,32 +129,31 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
const controlFlowStorage: IStorage <ICustomNode> = this.controlFlowStorageFactory();
const hostNode: TNodeWithBlockStatement = FunctionControlFlowTransformer.getHostNode(functionNode);
if (!this.controlFlowData.has(hostNode)) {
this.controlFlowData.set(hostNode, controlFlowStorage);
} else {
hostNode.body = <ESTree.Statement[]>FunctionControlFlowTransformer
.removeOldControlFlowNodeFromHostNodeBody(hostNode.body, this.controlFlowNodesList);
if (this.controlFlowData.has(hostNode)) {
if (this.hostNodesWithControlFlowNode.indexOf(hostNode) !== -1) {
hostNode.body.shift();
}
const hostControlFlowStorage: IStorage<ICustomNode> = <IStorage<ICustomNode>>this.controlFlowData.get(hostNode);
controlFlowStorage.mergeWith(hostControlFlowStorage, true);
this.controlFlowData.set(hostNode, controlFlowStorage);
}
this.controlFlowData.set(hostNode, controlFlowStorage);
estraverse.replace(functionNode.body, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (!FunctionControlFlowTransformer.controlFlowReplacersMap.has(node.type)) {
return;
}
if (RandomGeneratorUtils.getRandomFloat(0, 1) > this.options.controlFlowFlatteningThreshold) {
return;
}
const controlFlowReplacerName: NodeControlFlowReplacers | undefined = FunctionControlFlowTransformer
const controlFlowReplacerName: NodeControlFlowReplacers = <NodeControlFlowReplacers>FunctionControlFlowTransformer
.controlFlowReplacersMap.get(node.type);
if (controlFlowReplacerName === undefined) {
return;
}
return {
...this.controlFlowReplacerFactory(controlFlowReplacerName)
.replace(node, parentNode, controlFlowStorage),
@@ -195,7 +172,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
const controlFlowStorageNode: TStatement[] = controlFlowStorageCustomNode.getNode();
this.controlFlowNodesList.push(controlFlowStorageNode);
NodeAppender.prependNode(hostNode, controlFlowStorageNode);
this.hostNodesWithControlFlowNode.push(hostNode);
}
}
@@ -13,7 +13,7 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
/**
* @type {IOptions}
*/
protected readonly options : IOptions;
protected readonly options: IOptions;
/**
* @param options
@@ -14,7 +14,6 @@ import { CustomNodes } from '../../../enums/container/CustomNodes';
import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
import { Node } from '../../../node/Node';
import { NodeUtils } from '../../../node/NodeUtils';
import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
@injectable()
@@ -39,7 +38,7 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -87,7 +86,8 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl
controlFlowStorageId
);
let storageKeysForCurrentOperator: string[] | undefined = storageKeysByBinaryOperator.get(binaryExpressionNode.operator);
const storageKeysForCurrentOperator: string[] | undefined = storageKeysByBinaryOperator.get(binaryExpressionNode.operator);
let storageKey: string;
if (
@@ -110,8 +110,8 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl
controlFlowStorageCallCustomNode.initialize(
controlFlowStorageId,
storageKey,
NodeUtils.convertStructureToCode([binaryExpressionNode.left]),
NodeUtils.convertStructureToCode([binaryExpressionNode.right])
binaryExpressionNode.left,
binaryExpressionNode.right
);
const statementNode: TStatement = controlFlowStorageCallCustomNode.getNode()[0];
@@ -36,7 +36,7 @@ export class CatchClauseObfuscator extends AbstractNodeTransformer {
* @param options
*/
constructor(
@inject(ServiceIdentifiers['Factory<IObfuscatorReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -39,7 +39,7 @@ export class FunctionDeclarationObfuscator extends AbstractNodeTransformer {
* @param options
*/
constructor(
@inject(ServiceIdentifiers['Factory<IObfuscatorReplacer>']) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -36,7 +36,7 @@ export class FunctionObfuscator extends AbstractNodeTransformer {
* @param options
*/
constructor(
@inject(ServiceIdentifiers['Factory<IObfuscatorReplacer>']) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -72,7 +72,7 @@ export class FunctionObfuscator extends AbstractNodeTransformer {
* @param nodeIdentifier
*/
private replaceFunctionParams (functionNode: ESTree.Function, nodeIdentifier: string): void {
let traverseVisitor: estraverse.Visitor = {
const traverseVisitor: estraverse.Visitor = {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (Node.isReplaceableIdentifierNode(node, parentNode)) {
const newNodeName: string = this.identifierReplacer.replace(node.name, nodeIdentifier);
@@ -44,7 +44,7 @@ export class LabeledStatementObfuscator extends AbstractNodeTransformer {
* @param options
*/
constructor(
@inject(ServiceIdentifiers['Factory<IObfuscatorReplacer>']) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -24,7 +24,7 @@ export class LiteralObfuscator extends AbstractNodeTransformer {
* @param options
*/
constructor(
@inject(ServiceIdentifiers['Factory<IObfuscatorReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -2,7 +2,6 @@ import { injectable, inject } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as escodegen from 'escodegen';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { IOptions } from '../../interfaces/options/IOptions';
@@ -26,7 +25,7 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
* @param options
*/
constructor(
@inject(ServiceIdentifiers['Factory<IObfuscatorReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -38,24 +37,18 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
* @param memberExpressionNode
*/
public transformNode (memberExpressionNode: ESTree.MemberExpression): void {
estraverse.traverse(memberExpressionNode.property, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (Node.isLiteralNode(node)) {
this.obfuscateLiteralProperty(node);
if (Node.isLiteralNode(memberExpressionNode.property)) {
memberExpressionNode.property = this.obfuscateLiteralProperty(memberExpressionNode.property);
}
return;
}
if (Node.isIdentifierNode(node)) {
if (memberExpressionNode.computed) {
return;
}
memberExpressionNode.computed = true;
this.obfuscateIdentifierProperty(node);
}
if (Node.isIdentifierNode(memberExpressionNode.property)) {
if (memberExpressionNode.computed) {
return;
}
});
memberExpressionNode.computed = true;
memberExpressionNode.property = this.obfuscateIdentifierProperty(memberExpressionNode.property);
}
}
/**
@@ -69,22 +62,18 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
* object[identifier] = 1;
*
* @param node
* @returns {ESTree.Literal}
*/
private obfuscateIdentifierProperty (node: ESTree.Identifier): void {
const nodeValue: string = node.name;
const literalNode: ESTree.Literal = {
raw: `'${nodeValue}'`,
'x-verbatim-property': {
content: this.stringLiteralReplacer.replace(nodeValue),
precedence: escodegen.Precedence.Primary
},
private obfuscateIdentifierProperty (node: ESTree.Identifier): ESTree.Literal {
return {
type: NodeType.Literal,
value: nodeValue
value: node.name,
raw: `'${node.name}'`,
'x-verbatim-property': {
content: this.stringLiteralReplacer.replace(node.name),
precedence: escodegen.Precedence.Primary
}
};
delete node.name;
Object.assign(node, literalNode);
}
/**
@@ -95,13 +84,16 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
* object[_0x23d45[25]] = 1;
*
* @param node
* @returns {ESTree.Literal}
*/
private obfuscateLiteralProperty (node: ESTree.Literal): void {
private obfuscateLiteralProperty (node: ESTree.Literal): ESTree.Literal {
if (typeof node.value === 'string' && !node['x-verbatim-property']) {
node['x-verbatim-property'] = {
content : this.stringLiteralReplacer.replace(node.value),
content: this.stringLiteralReplacer.replace(node.value),
precedence: escodegen.Precedence.Primary
};
}
return node;
}
}
@@ -21,22 +21,22 @@ import { Node } from '../../node/Node';
*/
@injectable()
export class MethodDefinitionObfuscator extends AbstractNodeTransformer {
/**
* @type {IObfuscatorReplacer}
*/
private readonly stringLiteralReplacer: IObfuscatorReplacer;
/**
* @type {string[]}
*/
private static readonly ignoredNames: string[] = ['constructor'];
/**
* @type {IObfuscatorReplacer}
*/
private readonly stringLiteralReplacer: IObfuscatorReplacer;
/**
* @param replacersFactory
* @param options
*/
constructor(
@inject(ServiceIdentifiers['Factory<IObfuscatorReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -40,7 +40,7 @@ export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
* @param options
*/
constructor(
@inject(ServiceIdentifiers['Factory<IObfuscatorReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscatorReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -9,7 +9,7 @@ export abstract class AbstractReplacer implements IObfuscatorReplacer {
/**
* @type {IOptions}
*/
protected readonly options : IOptions;
protected readonly options: IOptions;
/**
* @param options
@@ -41,8 +41,8 @@ export class StringLiteralReplacer extends AbstractReplacer {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['IStorage<ICustomNodeGroup>']) customNodeGroupStorage: IStorage<ICustomNodeGroup>,
@inject(ServiceIdentifiers['IStorage<string>']) stringArrayStorage: IStorage<string>,
@inject(ServiceIdentifiers.TCustomNodeGroupStorage) customNodeGroupStorage: IStorage<ICustomNodeGroup>,
@inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: IStorage<string>,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -65,7 +65,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
return this.replaceStringLiteralWithStringArrayCall(nodeValue);
}
return `'${Utils.stringToUnicodeEscapeSequence(nodeValue)}'`;
return `'${Utils.stringToUnicodeEscapeSequence(nodeValue, !this.options.unicodeEscapeSequence)}'`;
}
/**
@@ -76,21 +76,19 @@ export class StringLiteralReplacer extends AbstractReplacer {
let rc4Key: string = '';
switch (this.options.stringArrayEncoding) {
case StringArrayEncoding.base64:
value = CryptUtils.btoa(value);
break;
case StringArrayEncoding.rc4:
rc4Key = RandomGeneratorUtils.getRandomGenerator().pickone(StringLiteralReplacer.rc4Keys);
value = CryptUtils.btoa(CryptUtils.rc4(value, rc4Key));
break;
case StringArrayEncoding.base64:
value = CryptUtils.btoa(value);
break;
}
if (this.options.unicodeEscapeSequence) {
value = Utils.stringToUnicodeEscapeSequence(value);
}
value = Utils.stringToUnicodeEscapeSequence(value, !this.options.unicodeEscapeSequence);
const indexOfExistingValue: number = <number>this.stringArrayStorage.getKeyOf(value);
@@ -103,7 +101,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
this.stringArrayStorage.set(null, value);
}
const rotatedStringArrayStorageId: string = Utils.stringRotate(this.stringArrayStorage.getStorageId(), 2);
const rotatedStringArrayStorageId: string = Utils.stringRotate(this.stringArrayStorage.getStorageId(), 1);
const stringArrayStorageCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${rotatedStringArrayStorageId}`;
const hexadecimalIndex: string = `${Utils.hexadecimalPrefix}${Utils.decToHex(indexOfValue)}`;
+272
View File
@@ -0,0 +1,272 @@
import * as escodegen from 'escodegen';
import * as ESTree from 'estree';
import { TStatement } from '../types/node/TStatement';
import { NodeType } from '../enums/NodeType';
export class Nodes {
/**
* @param body
* @returns {ESTree.Program}
*/
public static getProgramNode (body: TStatement[] = []): ESTree.Program {
return {
type: NodeType.Program,
body,
sourceType: 'script',
obfuscated: false
};
}
/**
* @param operator
* @param left
* @param right
* @returns {ESTree.BinaryExpression}
*/
public static getBinaryExpressionNode (
operator: ESTree.BinaryOperator,
left: ESTree.Expression,
right: ESTree.Expression,
): ESTree.BinaryExpression {
return {
type: NodeType.BinaryExpression,
operator,
left,
right,
obfuscated: false
};
}
/**
* @param body
* @returns {ESTree.BlockStatement}
*/
public static getBlockStatementNode (body: ESTree.Statement[] = []): ESTree.BlockStatement {
return {
type: NodeType.BlockStatement,
body,
obfuscated: false
};
}
/**
* @param body
* @returns {ESTree.CatchClause}
*/
public static getCatchClauseNode (body: ESTree.Statement[] = []): ESTree.CatchClause {
return {
type: NodeType.CatchClause,
param: Nodes.getIdentifierNode('err'),
body: Nodes.getBlockStatementNode(body),
obfuscated: false
};
}
/**
* @param callee
* @param args
* @returns {ESTree.CallExpression}
*/
public static getCallExpressionNode (
callee: ESTree.Expression,
args: ESTree.Expression[] | ESTree.SpreadElement[] = []
): ESTree.CallExpression {
return {
type: NodeType.CallExpression,
callee,
arguments: args,
obfuscated: false
};
}
/**
* @param expression
* @returns {ESTree.ExpressionStatement}
*/
public static getExpressionStatementNode (expression: ESTree.Expression): ESTree.ExpressionStatement {
return {
type: NodeType.ExpressionStatement,
expression,
obfuscated: false
};
}
/**
* @param functionName
* @param params
* @param body
* @returns {ESTree.FunctionDeclaration}
*/
public static getFunctionDeclarationNode (
functionName: string,
params: ESTree.Identifier[],
body: ESTree.BlockStatement
): ESTree.FunctionDeclaration {
return {
type: NodeType.FunctionDeclaration,
id: Nodes.getIdentifierNode(functionName),
params,
body,
generator: false,
obfuscated: false
};
}
/**
* @param params
* @param body
* @returns {ESTree.FunctionExpression}
*/
public static getFunctionExpressionNode (
params: ESTree.Identifier[],
body: ESTree.BlockStatement
): ESTree.FunctionExpression {
return {
type: NodeType.FunctionExpression,
params,
body,
generator: false,
obfuscated: false
};
}
/**
* @param test
* @param consequent
* @returns {ESTree.IfStatement}
*/
public static getIfStatementNode (test: ESTree.Expression, consequent: ESTree.BlockStatement): ESTree.IfStatement {
return {
type: NodeType.IfStatement,
test,
consequent,
obfuscated: false
};
}
/**
* @param name
* @returns {ESTree.Identifier}
*/
public static getIdentifierNode (name: string): ESTree.Identifier {
return {
type: NodeType.Identifier,
name,
obfuscated: false
};
}
/**
* @param value
* @returns {ESTree.Literal}
*/
public static getLiteralNode (value: boolean|number|string): ESTree.Literal {
return {
type: NodeType.Literal,
value,
raw: `'${value}'`,
'x-verbatim-property': {
content: `'${value}'`,
precedence: escodegen.Precedence.Primary
},
obfuscated: false
};
}
/**
* @param object
* @param property
* @param computed
* @return {ESTree.MemberExpression}
*/
public static getMemberExpressionNode (
object: ESTree.Identifier,
property: ESTree.Identifier|ESTree.Literal,
computed: boolean = false
): ESTree.MemberExpression {
return {
type: NodeType.MemberExpression,
computed,
object,
property,
obfuscated: false
};
}
/**
* @param properties
* @return {ESTree.ObjectExpression}
*/
public static getObjectExpressionNode (properties: ESTree.Property[]): ESTree.ObjectExpression {
return {
type: NodeType.ObjectExpression,
properties,
obfuscated: false
};
}
/**
* @return {ESTree.Property}
*/
public static getPropertyNode (
key: ESTree.Expression,
value: ESTree.Expression | ESTree.Pattern,
computed: boolean = false
): ESTree.Property {
return {
type: NodeType.Property,
key,
value,
kind: 'init',
method: false,
shorthand: false,
computed,
obfuscated: false
};
}
/**
* @param argument
* @return {ReturnStatement}
*/
public static getReturnStatementNode (argument: ESTree.Expression): ESTree.ReturnStatement {
return {
type: NodeType.ReturnStatement,
argument,
obfuscated: false
};
}
/**
* @param declarations
* @param kind
* @returns {ESTree.VariableDeclaration}
*/
public static getVariableDeclarationNode (
declarations: ESTree.VariableDeclarator[] = [],
kind: 'var' | 'let' | 'const' = 'var'
): ESTree.VariableDeclaration {
return {
type: NodeType.VariableDeclaration,
declarations,
kind,
obfuscated: false
};
}
/**
* @param id
* @param init
* @returns {ESTree.VariableDeclarator}
*/
public static getVariableDeclaratorNode (id: ESTree.Identifier, init: any): ESTree.VariableDeclarator {
return {
type: NodeType.VariableDeclarator,
id,
init,
obfuscated: false
};
}
}
@@ -74,7 +74,7 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
private calleeDataExtractorsFactory: (calleeDataExtractorName: CalleeDataExtractors) => ICalleeDataExtractor;
constructor (
@inject(ServiceIdentifiers['Factory<ICalleeDataExtractor>']) calleeDataExtractorsFactory: TCalleeDataExtractorsFactory
@inject(ServiceIdentifiers.Factory__ICalleeDataExtractor) calleeDataExtractorsFactory: TCalleeDataExtractorsFactory
) {
this.calleeDataExtractorsFactory = calleeDataExtractorsFactory;
}
+1 -1
View File
@@ -47,7 +47,7 @@ export abstract class MapStorage <T> implements IStorage <T> {
* @returns {number}
*/
public getLength (): number {
return Array.from(this.storage).length;
return this.storage.size;
}
/**
@@ -8,18 +8,4 @@ export class ControlFlowStorage extends MapStorage <ICustomNode> {
this.initialize();
}
/**
* @returns {string}
*/
public toString (): string {
return Array
.from(this.storage)
.reduce((controlFlowStorageItems: string[], [key, value]: [string, ICustomNode]) => {
controlFlowStorageItems.push(`${key}: ${value.getCode()}`);
return controlFlowStorageItems;
}, [])
.join(',');
}
}
@@ -39,7 +39,7 @@ export class CustomNodeGroupStorage extends MapStorage <ICustomNodeGroup> {
* @param options
*/
constructor (
@inject(ServiceIdentifiers['Factory<ICustomNodeGroup>']) customNodeGroupFactory: TCustomNodeGroupFactory,
@inject(ServiceIdentifiers.Factory__ICustomNodeGroup) customNodeGroupFactory: TCustomNodeGroupFactory,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super();
@@ -66,4 +66,4 @@ export class CustomNodeGroupStorage extends MapStorage <ICustomNodeGroup> {
this.storage.set(customNodeGroupName, customNodeGroup);
});
}
}
}
@@ -36,4 +36,4 @@ export class StringArrayStorage extends ArrayStorage <string> {
return `'${value}'`;
}).toString();
}
}
}
@@ -1,10 +0,0 @@
/**
* @returns {string}
*/
export function BinaryExpressionFunctionTemplate (): string {
return `
function {functionName} (x, y) {
return x {operator} y;
}
`;
}
@@ -1,6 +0,0 @@
/**
* @returns {string}
*/
export function ControlFlowStorageCallTemplate (): string {
return '{controlFlowStorageName}.{controlFlowStorageKey}({leftValue}, {rightValue})';
}
@@ -1,8 +0,0 @@
/**
* @returns {string}
*/
export function ControlFlowStorageTemplate (): string {
return `
var {controlFlowStorageName} = { {controlFlowStorage} };
`;
}
+4
View File
@@ -0,0 +1,4 @@
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
import { IStorage } from '../../interfaces/storages/IStorage';
export type TControlFlowStorage = IStorage<ICustomNode>;
+4
View File
@@ -0,0 +1,4 @@
import { ICustomNodeGroup } from '../../interfaces/custom-nodes/ICustomNodeGroup';
import { IStorage } from '../../interfaces/storages/IStorage';
export type TCustomNodeGroupStorage = IStorage<ICustomNodeGroup>;
+3
View File
@@ -0,0 +1,3 @@
import { IStorage } from '../../interfaces/storages/IStorage';
export type TStringArrayStorage = IStorage<string>;
+17 -3
View File
@@ -98,7 +98,15 @@ export class Utils {
* @returns {string}
*/
public static stringRotate (string: string, times: number): string {
return Utils.arrayRotate(Array.from(string), times).join('');
if (!string) {
throw new ReferenceError(`Cannot rotate empty string.`);
}
for (let i: number = 0; i < times; i++) {
string = string[string.length - 1] + string.substring(0, string.length - 1);
}
return string;
}
/**
@@ -116,16 +124,22 @@ export class Utils {
/**
* @param string
* @param nonLatinAndNonDigitsOnly
* @returns {string}
*/
public static stringToUnicodeEscapeSequence (string: string): string {
public static stringToUnicodeEscapeSequence (string: string, nonLatinAndNonDigitsOnly: boolean = false): string {
const radix: number = 16;
const regexp: RegExp = new RegExp('[\x00-\x7F]');
const escapeRegExp: RegExp = new RegExp('[^a-zA-Z0-9]');
let prefix: string,
template: string;
return `${string.replace(/[\s\S]/g, (escape: string): string => {
if (nonLatinAndNonDigitsOnly && !escapeRegExp.test(escape)) {
return escape;
}
if (regexp.test(escape)) {
prefix = '\\x';
template = '0'.repeat(2);
@@ -133,7 +147,7 @@ export class Utils {
prefix = '\\u';
template = '0'.repeat(4);
}
return `${prefix}${(template + escape.charCodeAt(0).toString(radix)).slice(-template.length)}`;
})}`;
}
+2 -1
View File
@@ -84,7 +84,8 @@ if (!(<any>global)._babelPolyfill) {
{
compact: false,
controlFlowFlattening: true,
disableConsoleOutput: false
disableConsoleOutput: false,
unicodeEscapeSequence: false
}
).getObfuscatedCode();
@@ -0,0 +1 @@
var test = '\nreturn \n//# sourceURL= there can only be \'^\' and \'!\' markers in a subscription marble diagram.';
@@ -4,6 +4,8 @@ import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResul
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustomNodes';
import { readFileAsString } from '../../../helpers/readFileAsString';
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
describe('LiteralObfuscator', () => {
@@ -54,6 +56,33 @@ describe('LiteralObfuscator', () => {
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
});
it('should replace literal node value with raw value from unicode array if `unicodeEscapeSequence` and `stringArray` are disabled', () => {
let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
`var test = 'test';`,
{
...NO_CUSTOM_NODES_PRESET,
unicodeEscapeSequence: false
}
);
assert.match(
obfuscationResult.getObfuscatedCode(),
/^var *test *= *'test';/
);
});
it('should\'t throw an error when string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
assert.doesNotThrow(() => JavaScriptObfuscator.obfuscate(
readFileAsString('./test/fixtures/node-transformers/node-obfuscators/literal-obfuscator/literal-obfuscator-unicode-sequence.js'),
{
...NO_CUSTOM_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1,
unicodeEscapeSequence: false
}
));
});
it('shouldn\'t replace short literal node value with unicode array value', () => {
let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
`var test = 'te';`,
@@ -15,7 +15,7 @@ import { readFileAsString } from '../../helpers/readFileAsString';
import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade';
import { Node } from '../../../src/node/Node';
import { NodeMocks } from '../../mocks/NodeMocks';
import { Nodes } from '../../../src/node/Nodes';
import { NodeUtils } from '../../../src/node/NodeUtils';
/**
@@ -157,7 +157,7 @@ describe('StackTraceAnalyzer', () => {
expectedStackTraceData: IStackTraceData[];
it('should returns correct IStackTraceData - variant #1: basic-1', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/basic-1.js')
)
@@ -204,7 +204,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #2: basic-2', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/basic-2.js')
)
@@ -240,7 +240,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #3: deep conditions nesting', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/deep-conditions-nesting.js')
)
@@ -276,7 +276,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #4: call before declaration', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/call-before-declaration.js')
)
@@ -296,7 +296,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #5: call expression of object member #1', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/call-expression-of-object-member-1.js')
)
@@ -352,7 +352,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #5: call expression of object member #2', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/call-expression-of-object-member-2.js')
)
@@ -377,7 +377,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #6: no call expressions', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/no-call-expressions.js')
)
@@ -391,7 +391,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #7: only call expression', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/only-call-expression.js')
)
@@ -405,7 +405,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #8: self-invoking functions', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/self-invoking-functions.js')
)
@@ -437,7 +437,7 @@ describe('StackTraceAnalyzer', () => {
});
it('should returns correct IStackTraceData - variant #9: no recursion', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/stack-trace-analyzer/no-recursion.js')
)
-1
View File
@@ -15,7 +15,6 @@ import './unit-tests/decorators/Initializable.spec';
import './unit-tests/node/NodeAppender.spec';
import './unit-tests/node/NodeUtils.spec';
import './unit-tests/stack-trace-analyzer/StackTraceAnalyzer.spec';
import './unit-tests/storages/ControlFlowStorage.spec';
import './unit-tests/utils/CryptUtils.spec';
import './unit-tests/utils/RandomGeneratorUtils.spec';
import './unit-tests/utils/Utils.spec';
-194
View File
@@ -1,194 +0,0 @@
import * as escodegen from 'escodegen';
import * as ESTree from 'estree';
import { TStatement } from '../../src/types/node/TStatement';
import { NodeType } from '../../src/enums/NodeType';
export class NodeMocks {
/**
* @param bodyNodes
* @returns {ESTree.Program}
*/
public static getProgramNode (bodyNodes: TStatement[] = []): ESTree.Program {
return {
type: NodeType.Program,
body: bodyNodes,
sourceType: 'script',
obfuscated: false
};
}
/**
* @param bodyNodes
* @returns {ESTree.BlockStatement}
*/
public static getBlockStatementNode (bodyNodes: ESTree.Statement[] = []): ESTree.BlockStatement {
return {
type: NodeType.BlockStatement,
body: bodyNodes,
obfuscated: false
};
}
/**
* @param bodyNodes
* @returns {ESTree.CatchClause}
*/
public static getCatchClauseNode (bodyNodes: ESTree.Statement[] = []): ESTree.CatchClause {
return {
type: NodeType.CatchClause,
param: NodeMocks.getIdentifierNode('err'),
body: NodeMocks.getBlockStatementNode(bodyNodes),
obfuscated: false
};
}
/**
* @param callee
* @param args
* @returns {ESTree.CallExpression}
*/
public static getCallExpressionNode (
callee: ESTree.Expression,
args: ESTree.Expression[] | ESTree.SpreadElement[] = []
): ESTree.CallExpression {
return {
type: NodeType.CallExpression,
callee: callee,
arguments: args,
obfuscated: false
};
}
/**
* @param expression
* @returns {ESTree.ExpressionStatement}
*/
public static getExpressionStatementNode (
expression: ESTree.Expression = NodeMocks.getIdentifierNode()
): ESTree.ExpressionStatement {
return {
type: NodeType.ExpressionStatement,
expression: expression,
obfuscated: false
};
}
/**
* @param functionName
* @param blockStatementNode
* @param params
* @returns {ESTree.FunctionDeclaration}
*/
public static getFunctionDeclarationNode (
functionName: string,
blockStatementNode: ESTree.BlockStatement,
params: ESTree.Identifier[] = []
): ESTree.FunctionDeclaration {
return {
type: NodeType.FunctionDeclaration,
id: NodeMocks.getIdentifierNode(functionName),
params: params,
body: blockStatementNode,
generator: false,
obfuscated: false
};
}
/**
* @param blockStatementNode
* @returns {ESTree.IfStatement}
*/
public static getIfStatementNode (blockStatementNode: ESTree.BlockStatement): ESTree.IfStatement {
return {
type: 'IfStatement',
test: {
type: 'Literal',
value: true,
raw: 'true',
obfuscated: false
},
consequent: blockStatementNode,
obfuscated: false
};
}
/**
* @param identifierName
* @returns {ESTree.Identifier}
*/
public static getIdentifierNode (identifierName: string = 'identifier'): ESTree.Identifier {
return {
type: NodeType.Identifier,
name: identifierName,
obfuscated: false
};
}
/**
* @param value
* @returns {ESTree.Literal}
*/
public static getLiteralNode (value: boolean|number|string = 'value'): ESTree.Literal {
return {
type: NodeType.Literal,
value: value,
raw: `'${value}'`,
'x-verbatim-property': {
content: `'${value}'`,
precedence: escodegen.Precedence.Primary
},
obfuscated: false
};
}
/**
* @param object
* @param property
* @return {ESTree.MemberExpression}
*/
public static getMemberExpressionNode (
object: ESTree.Identifier,
property: ESTree.Identifier|ESTree.Literal
): ESTree.MemberExpression {
return {
type: NodeType.MemberExpression,
computed: false,
object: object,
property: property,
obfuscated: false
};
}
/**
* @param declarations
* @param kind
* @returns {ESTree.VariableDeclaration}
*/
public static getVariableDeclarationNode (
declarations: ESTree.VariableDeclarator[] = [],
kind: 'var' | 'let' | 'const' = 'var'
): ESTree.VariableDeclaration {
return {
type: NodeType.VariableDeclaration,
declarations: declarations,
kind: kind,
obfuscated: false
};
}
/**
* @param id
* @param init
* @returns {ESTree.VariableDeclarator}
*/
public static getVariableDeclaratorNode (id: ESTree.Identifier, init: any): ESTree.VariableDeclarator {
return {
type: NodeType.VariableDeclarator,
id: id,
init: init,
obfuscated: false
};
}
}
+16 -16
View File
@@ -14,7 +14,7 @@ import { readFileAsString } from '../../helpers/readFileAsString';
import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade';
import { NodeAppender } from '../../../src/node/NodeAppender';
import { NodeMocks } from '../../mocks/NodeMocks';
import { Nodes } from '../../../src/node/Nodes';
import { NodeUtils } from '../../../src/node/NodeUtils';
describe('NodeAppender', () => {
@@ -28,13 +28,13 @@ describe('NodeAppender', () => {
var test = 1;
`);
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node.js')
)
);
expectedAstTree = NodeMocks.getProgramNode(
expectedAstTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-expected.js')
)
@@ -68,13 +68,13 @@ describe('NodeAppender', () => {
});
it('should append node into first and deepest function call in calls trace - variant #1', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/variant-1.js')
)
);
expectedAstTree = NodeMocks.getProgramNode(
expectedAstTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/variant-1-expected.js')
)
@@ -87,13 +87,13 @@ describe('NodeAppender', () => {
});
it('should append node into first and deepest function call in calls trace - variant #2', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/variant-2.js')
)
);
expectedAstTree = NodeMocks.getProgramNode(
expectedAstTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/variant-2-expected.js')
)
@@ -109,7 +109,7 @@ describe('NodeAppender', () => {
let astTree: ESTree.Program;
beforeEach(() => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index.js')
@@ -118,7 +118,7 @@ describe('NodeAppender', () => {
});
it('should append node into deepest function call by specified index in calls trace - variant #1', () => {
expectedAstTree = NodeMocks.getProgramNode(
expectedAstTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index-variant-1-expected.js')
@@ -132,7 +132,7 @@ describe('NodeAppender', () => {
});
it('should append node into deepest function call by specified index in calls trace - variant #2', () => {
expectedAstTree = NodeMocks.getProgramNode(
expectedAstTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index-variant-2-expected.js')
@@ -146,12 +146,12 @@ describe('NodeAppender', () => {
});
it('should append node into deepest function call by specified index in calls trace - variant #3', () => {
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index-variant-3.js')
)
);
expectedAstTree = NodeMocks.getProgramNode(
expectedAstTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index-variant-3-expected.js')
)
@@ -193,13 +193,13 @@ describe('NodeAppender', () => {
var test = 1;
`);
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/insert-node-at-index.js')
)
);
expectedAstTree = NodeMocks.getProgramNode(
expectedAstTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/insert-node-at-index-expected.js')
)
@@ -226,13 +226,13 @@ describe('NodeAppender', () => {
var test = 1;
`);
astTree = NodeMocks.getProgramNode(
astTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/prepend-node.js')
)
);
expectedAstTree = NodeMocks.getProgramNode(
expectedAstTree = Nodes.getProgramNode(
NodeUtils.convertCodeToStructure(
readFileAsString('./test/fixtures/node-appender/prepend-node-expected.js')
)
+59 -44
View File
@@ -2,7 +2,7 @@ import * as ESTree from 'estree';
import { assert } from 'chai';
import { NodeMocks } from '../../mocks/NodeMocks';
import { Nodes } from '../../../src/node/Nodes';
import { NodeUtils } from '../../../src/node/NodeUtils';
describe('NodeUtils', () => {
@@ -11,10 +11,10 @@ describe('NodeUtils', () => {
expectedLiteralNode: any;
beforeEach(() => {
literalNode = NodeMocks.getLiteralNode();
literalNode = Nodes.getLiteralNode('value');
delete literalNode['x-verbatim-property'];
expectedLiteralNode = NodeMocks.getLiteralNode();
expectedLiteralNode = Nodes.getLiteralNode('value');
NodeUtils.addXVerbatimPropertyToLiterals(literalNode);
});
@@ -37,17 +37,17 @@ describe('NodeUtils', () => {
var abc = 'cde';
`;
identifierNode = NodeMocks.getIdentifierNode('abc');
identifierNode = Nodes.getIdentifierNode('abc');
literalNode = NodeMocks.getLiteralNode('cde');
literalNode = Nodes.getLiteralNode('cde');
variableDeclaratorNode = NodeMocks.getVariableDeclaratorNode(identifierNode, literalNode);
variableDeclaratorNode = Nodes.getVariableDeclaratorNode(identifierNode, literalNode);
variableDeclarationNode = NodeMocks.getVariableDeclarationNode([
variableDeclarationNode = Nodes.getVariableDeclarationNode([
variableDeclaratorNode
]);
programNode = NodeMocks.getProgramNode([
programNode = Nodes.getProgramNode([
variableDeclarationNode
]);
@@ -69,11 +69,11 @@ describe('NodeUtils', () => {
beforeEach(() => {
structure = [
NodeMocks.getProgramNode([
NodeMocks.getVariableDeclarationNode([
NodeMocks.getVariableDeclaratorNode(
NodeMocks.getIdentifierNode('abc'),
NodeMocks.getLiteralNode('cde')
Nodes.getProgramNode([
Nodes.getVariableDeclarationNode([
Nodes.getVariableDeclaratorNode(
Nodes.getIdentifierNode('abc'),
Nodes.getLiteralNode('cde')
)
])
])
@@ -92,10 +92,10 @@ describe('NodeUtils', () => {
expressionStatementNode2: ESTree.ExpressionStatement;
beforeEach(() => {
expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
expressionStatementNode1 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
expressionStatementNode2 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
blockStatementNode = NodeMocks.getBlockStatementNode([
blockStatementNode = Nodes.getBlockStatementNode([
expressionStatementNode1,
expressionStatementNode2
]);
@@ -128,31 +128,37 @@ describe('NodeUtils', () => {
programNode: ESTree.Program;
beforeEach(() => {
expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
expressionStatementNode3 = NodeMocks.getExpressionStatementNode();
expressionStatementNode1 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
expressionStatementNode2 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
expressionStatementNode3 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
ifStatementBlockStatementNode2 = NodeMocks.getBlockStatementNode([
ifStatementBlockStatementNode2 = Nodes.getBlockStatementNode([
expressionStatementNode2,
expressionStatementNode3
]);
ifStatementNode2 = NodeMocks.getIfStatementNode(ifStatementBlockStatementNode2);
ifStatementNode2 = Nodes.getIfStatementNode(
Nodes.getLiteralNode(true),
ifStatementBlockStatementNode2
);
ifStatementBlockStatementNode1 = NodeMocks.getBlockStatementNode([
ifStatementBlockStatementNode1 = Nodes.getBlockStatementNode([
ifStatementNode2
]);
ifStatementNode1 = NodeMocks.getIfStatementNode(ifStatementBlockStatementNode1);
ifStatementNode1 = Nodes.getIfStatementNode(
Nodes.getLiteralNode(true),
ifStatementBlockStatementNode1
);
functionDeclarationBlockStatementNode = NodeMocks.getBlockStatementNode([
functionDeclarationBlockStatementNode = Nodes.getBlockStatementNode([
expressionStatementNode1,
ifStatementNode1
]);
functionDeclarationNode = NodeMocks.getFunctionDeclarationNode('test', functionDeclarationBlockStatementNode);
functionDeclarationNode = Nodes.getFunctionDeclarationNode('test', [], functionDeclarationBlockStatementNode);
programNode = NodeMocks.getProgramNode([
programNode = Nodes.getProgramNode([
functionDeclarationNode
]);
@@ -203,37 +209,43 @@ describe('NodeUtils', () => {
programNode: ESTree.Program;
beforeEach(() => {
expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
expressionStatementNode3 = NodeMocks.getExpressionStatementNode();
expressionStatementNode1 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
expressionStatementNode2 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
expressionStatementNode3 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
ifStatementBlockStatementNode2 = NodeMocks.getBlockStatementNode([
ifStatementBlockStatementNode2 = Nodes.getBlockStatementNode([
expressionStatementNode3
]);
ifStatementNode2 = NodeMocks.getIfStatementNode(ifStatementBlockStatementNode2);
ifStatementNode2 = Nodes.getIfStatementNode(
Nodes.getLiteralNode(true),
ifStatementBlockStatementNode2
);
functionDeclarationBlockStatementNode2 = NodeMocks.getBlockStatementNode([
functionDeclarationBlockStatementNode2 = Nodes.getBlockStatementNode([
ifStatementNode2,
expressionStatementNode2
]);
functionDeclarationNode2 = NodeMocks.getFunctionDeclarationNode('test', functionDeclarationBlockStatementNode2);
functionDeclarationNode2 = Nodes.getFunctionDeclarationNode('test', [], functionDeclarationBlockStatementNode2);
ifStatementBlockStatementNode1 = NodeMocks.getBlockStatementNode([
ifStatementBlockStatementNode1 = Nodes.getBlockStatementNode([
functionDeclarationNode2
]);
ifStatementNode1 = NodeMocks.getIfStatementNode(ifStatementBlockStatementNode1);
ifStatementNode1 = Nodes.getIfStatementNode(
Nodes.getLiteralNode(true),
ifStatementBlockStatementNode1
);
functionDeclarationBlockStatementNode1 = NodeMocks.getBlockStatementNode([
functionDeclarationBlockStatementNode1 = Nodes.getBlockStatementNode([
expressionStatementNode1,
ifStatementNode1
]);
functionDeclarationNode1 = NodeMocks.getFunctionDeclarationNode('test', functionDeclarationBlockStatementNode1);
functionDeclarationNode1 = Nodes.getFunctionDeclarationNode('test', [], functionDeclarationBlockStatementNode1);
programNode = NodeMocks.getProgramNode([
programNode = Nodes.getProgramNode([
functionDeclarationNode1
]);
@@ -277,19 +289,22 @@ describe('NodeUtils', () => {
programNode: ESTree.Program;
beforeEach(() => {
expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
expressionStatementNode1 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
expressionStatementNode2 = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
ifStatementBlockStatementNode = NodeMocks.getBlockStatementNode([
ifStatementBlockStatementNode = Nodes.getBlockStatementNode([
expressionStatementNode1,
expressionStatementNode2
]);
ifStatementNode = NodeMocks.getIfStatementNode(ifStatementBlockStatementNode);
ifStatementNode = Nodes.getIfStatementNode(
Nodes.getLiteralNode(true),
ifStatementBlockStatementNode
);
});
it('should parentize given AST-tree with `ProgramNode` as root node', () => {
programNode = NodeMocks.getProgramNode([
programNode = Nodes.getProgramNode([
ifStatementNode
]);
@@ -303,7 +318,7 @@ describe('NodeUtils', () => {
});
it('should parentize given AST-tree', () => {
programNode = NodeMocks.getProgramNode([
programNode = Nodes.getProgramNode([
ifStatementNode
]);
programNode['parentNode'] = programNode;
@@ -1,42 +0,0 @@
import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
import { assert } from 'chai';
import { TCustomNodeFactory } from '../../../src/types/container/TCustomNodeFactory';
import { ICustomNode } from '../../../src/interfaces/custom-nodes/ICustomNode';
import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade';
import { IStorage } from '../../../src/interfaces/storages/IStorage';
import { CustomNodes } from '../../../src/enums/container/CustomNodes';
import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade';
describe('ControlFlowStorage', () => {
describe('toString (): string', () => {
it('should return correct ControlFlowStorage data after `.toString()` call', () => {
const key1: string = 'key1';
const key2: string = 'key2';
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade({
controlFlowFlattening: true
});
const customNodeFactory: TCustomNodeFactory = inversifyContainerFacade
.get<TCustomNodeFactory>(ServiceIdentifiers['Factory<ICustomNode>']);
const controlFlowStorage: IStorage <ICustomNode> = inversifyContainerFacade
.get<IStorage<ICustomNode>>(ServiceIdentifiers['IStorage<ICustomNode>']);
const controlFlowStorageCallNode1: ICustomNode = customNodeFactory(CustomNodes.ControlFlowStorageCallNode);
const controlFlowStorageCallNode2: ICustomNode = customNodeFactory(CustomNodes.ControlFlowStorageCallNode);
controlFlowStorageCallNode1.initialize('controlFlowStorageName', key1, 1, 2);
controlFlowStorageCallNode2.initialize('controlFlowStorageName', key2, 3, 4);
controlFlowStorage.set(key1, controlFlowStorageCallNode1);
controlFlowStorage.set(key2, controlFlowStorageCallNode2);
assert.equal(
controlFlowStorage.toString(),
`${key1}: ${controlFlowStorageCallNode1.getCode()},${key2}: ${controlFlowStorageCallNode2.getCode()}`
);
});
});
});
+8 -3
View File
@@ -111,11 +111,16 @@ describe('Utils', () => {
});
});
describe('stringToUnicodeEscapeSequence (string: string): string', () => {
let expected: string = '\\x73\\x74\\x72\\x69\\x6e\\x67';
describe('stringToUnicodeEscapeSequence (string: string, nonLatinAndNonDigitsOnly: boolean = false): string', () => {
const expected1: string = '\\x73\\x74\\x72\\x69\\x6e\\x67';
const expected2: string = 'abc\\x21\\u0434\\u0435';
it('should return a unicode escape sequence based on a given string', () => {
assert.equal(Utils.stringToUnicodeEscapeSequence('string'), expected);
assert.equal(Utils.stringToUnicodeEscapeSequence('string'), expected1);
});
it('should return a string where only non-digits and non-latin letters are escaped', () => {
assert.equal(Utils.stringToUnicodeEscapeSequence('abc!де', true), expected2);
});
});
});
+2 -2
View File
@@ -37,7 +37,7 @@
true,
{ "order": "fields-first" }
],
"new-parens": true,
"new-parens": false,
"no-angle-bracket-type-assertion": false,
"no-any": false,
"no-arg": true,
@@ -87,7 +87,7 @@
"quotemark": false,
"radix": true,
"semicolon": [true, "always"],
"switch-default": true,
"switch-default": false,
"trailing-comma": false,
"triple-equals": [
true,
+7 -1
View File
@@ -18,7 +18,13 @@ module.exports = {
target: 'node',
externals: [nodeExternals()],
module: {
loaders: [
rules: [
{
enforce: 'pre',
test: /\.ts$/,
loader: 'tslint-loader',
exclude: /(node_modules)/,
},
{
test: /\.ts(x?)$/,
loader: 'awesome-typescript-loader',