mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Merge branch 'dev'
This commit is contained in:
Vendored
+1173
-975
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -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"
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
) {
|
||||
|
||||
+27
-12
@@ -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')
|
||||
)
|
||||
)
|
||||
])
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
+25
-19
@@ -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;
|
||||
|
||||
|
||||
+17
-40
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
protected readonly options : IOptions;
|
||||
protected readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @param options
|
||||
|
||||
+5
-5
@@ -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)}`;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
export function BinaryExpressionFunctionTemplate (): string {
|
||||
return `
|
||||
function {functionName} (x, y) {
|
||||
return x {operator} y;
|
||||
}
|
||||
`;
|
||||
}
|
||||
-6
@@ -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
@@ -0,0 +1,4 @@
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IStorage } from '../../interfaces/storages/IStorage';
|
||||
|
||||
export type TControlFlowStorage = IStorage<ICustomNode>;
|
||||
@@ -0,0 +1,4 @@
|
||||
import { ICustomNodeGroup } from '../../interfaces/custom-nodes/ICustomNodeGroup';
|
||||
import { IStorage } from '../../interfaces/storages/IStorage';
|
||||
|
||||
export type TCustomNodeGroupStorage = IStorage<ICustomNodeGroup>;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { IStorage } from '../../interfaces/storages/IStorage';
|
||||
|
||||
export type TStringArrayStorage = IStorage<string>;
|
||||
+17
-3
@@ -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
@@ -84,7 +84,8 @@ if (!(<any>global)._babelPolyfill) {
|
||||
{
|
||||
compact: false,
|
||||
controlFlowFlattening: true,
|
||||
disableConsoleOutput: false
|
||||
disableConsoleOutput: false,
|
||||
unicodeEscapeSequence: false
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
|
||||
+1
@@ -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')
|
||||
)
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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')
|
||||
)
|
||||
|
||||
@@ -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()}`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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
@@ -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
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user