mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Merge remote-tracking branch 'origin/dev' into dev
Conflicts: package.json
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
Change Log
|
||||
===
|
||||
v0.8.2
|
||||
---
|
||||
* New option `seed` sets seed for random generator. This is useful for creating repeatable results.
|
||||
* IE8 runtime error fix.
|
||||
|
||||
v0.8.1
|
||||
---
|
||||
* `disableConsoleOutput` option now replaces `console.xxx` functions on empty function instead of infinity loop.
|
||||
|
||||
@@ -123,6 +123,7 @@ Following options available for the JS Obfuscator:
|
||||
disableConsoleOutput: true,
|
||||
reservedNames: [],
|
||||
rotateStringArray: true,
|
||||
seed: 0,
|
||||
selfDefending: true,
|
||||
sourceMap: false,
|
||||
sourceMapBaseUrl: '',
|
||||
@@ -131,7 +132,7 @@ Following options available for the JS Obfuscator:
|
||||
stringArray: true,
|
||||
stringArrayEncoding: false,
|
||||
stringArrayThreshold: 0.8,
|
||||
unicdeEscapeSequence: true
|
||||
unicodeEscapeSequence: true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -148,6 +149,7 @@ Following options available for the JS Obfuscator:
|
||||
--disableConsoleOutput <boolean>
|
||||
--reservedNames <list> (comma separated)
|
||||
--rotateStringArray <boolean>
|
||||
--seed <number>
|
||||
--selfDefending <boolean>
|
||||
--sourceMap <boolean>
|
||||
--sourceMapBaseUrl <string>
|
||||
@@ -218,6 +220,12 @@ Shift the `stringArray` array by a fixed and random (generated at the code obfus
|
||||
|
||||
This option is recommended if your original source code isn't small, as the helper function can attract attention.
|
||||
|
||||
### `seed`
|
||||
Type: `number` Default: `0`
|
||||
|
||||
This option sets seed for random generator. This is useful for creating repeatable results.
|
||||
|
||||
If seed is `0` - random generator will work without seed.
|
||||
|
||||
### `selfDefending`
|
||||
Type: `boolean` Default: `true`
|
||||
|
||||
Vendored
+1399
-715
File diff suppressed because it is too large
Load Diff
+11
-10
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "javascript-obfuscator",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.2",
|
||||
"description": "JavaScript obfuscator",
|
||||
"keywords": [
|
||||
"obfuscator",
|
||||
@@ -27,27 +27,28 @@
|
||||
"escodegen": "1.8.1",
|
||||
"esprima": "3.1.1",
|
||||
"estraverse": "4.2.0",
|
||||
"format-unicorn": "1.1.0",
|
||||
"is-equal": "^1.5.3",
|
||||
"mkdirp": "0.5.1",
|
||||
"source-map-support": "0.4.6"
|
||||
"source-map-support": "0.4.6",
|
||||
"string-template": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "3.4.34",
|
||||
"@types/chance": "0.7.31",
|
||||
"@types/commander": "2.3.30",
|
||||
"@types/commander": "2.3.31",
|
||||
"@types/escodegen": "0.0.6",
|
||||
"@types/esprima": "2.1.33",
|
||||
"@types/estraverse": "0.0.6",
|
||||
"@types/estree": "0.0.34",
|
||||
"@types/format-unicorn": "0.0.29",
|
||||
"@types/joi": "9.0.33",
|
||||
"@types/mkdirp": "0.3.29",
|
||||
"@types/mocha": "2.2.33",
|
||||
"@types/node": "6.0.47",
|
||||
"@types/sinon": "1.16.31",
|
||||
"@types/node": "6.0.49",
|
||||
"@types/sinon": "1.16.32",
|
||||
"@types/string-template": "^1.0.2",
|
||||
"awesome-typescript-loader": "2.2.4",
|
||||
"babel-cli": "6.18.0",
|
||||
"babel-loader": "6.2.7",
|
||||
"babel-loader": "6.2.8",
|
||||
"babel-preset-es2015": "6.18.0",
|
||||
"chai": "3.5.0",
|
||||
"coveralls": "2.11.15",
|
||||
@@ -55,9 +56,9 @@
|
||||
"mocha": "3.1.2",
|
||||
"sinon": "2.0.0-pre.3",
|
||||
"ts-node": "1.7.0",
|
||||
"tslint": "3.15.1",
|
||||
"tslint": "4.0.1",
|
||||
"typescript": "2.0.10",
|
||||
"webpack": "2.1.0-beta.25",
|
||||
"webpack": "2.1.0-beta.27",
|
||||
"webpack-node-externals": "1.5.4"
|
||||
},
|
||||
"repository": {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { IObfuscatorOptions } from './interfaces/IObfuscatorOptions';
|
||||
|
||||
import { JavaScriptObfuscatorCLI } from './cli/JavaScriptObfuscatorCLI';
|
||||
import { JavaScriptObfuscatorInternal } from './JavaScriptObfuscatorInternal';
|
||||
import { Options } from './options/Options';
|
||||
|
||||
export class JavaScriptObfuscator {
|
||||
/**
|
||||
@@ -11,14 +12,11 @@ export class JavaScriptObfuscator {
|
||||
* @returns {string}
|
||||
*/
|
||||
public static obfuscate (sourceCode: string, obfuscatorOptions: IObfuscatorOptions = {}): IObfuscationResult {
|
||||
let javaScriptObfuscator: JavaScriptObfuscatorInternal = new JavaScriptObfuscatorInternal(
|
||||
sourceCode,
|
||||
obfuscatorOptions
|
||||
const javaScriptObfuscator: JavaScriptObfuscatorInternal = new JavaScriptObfuscatorInternal(
|
||||
new Options(obfuscatorOptions)
|
||||
);
|
||||
|
||||
javaScriptObfuscator.obfuscate();
|
||||
|
||||
return javaScriptObfuscator.getObfuscationResult();
|
||||
return javaScriptObfuscator.obfuscate(sourceCode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,47 +2,43 @@ import * as esprima from 'esprima';
|
||||
import * as escodegen from 'escodegen';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { IObfuscatorOptions } from './interfaces/IObfuscatorOptions';
|
||||
import { Chance } from 'chance';
|
||||
|
||||
import { IGeneratorOutput } from './interfaces/IGeneratorOutput';
|
||||
import { IObfuscationResult } from './interfaces/IObfuscationResult';
|
||||
import { IOptions } from './interfaces/IOptions';
|
||||
|
||||
import { ObfuscationResult } from './ObfuscationResult';
|
||||
import { Obfuscator } from './Obfuscator';
|
||||
import { Options } from './options/Options';
|
||||
import { SourceMapCorrector } from './SourceMapCorrector';
|
||||
import { Utils } from './Utils';
|
||||
|
||||
export class JavaScriptObfuscatorInternal {
|
||||
/**
|
||||
* @type {GenerateOptions}
|
||||
*/
|
||||
private static escodegenParams: escodegen.GenerateOptions = {
|
||||
private static readonly escodegenParams: escodegen.GenerateOptions = {
|
||||
verbatim: 'x-verbatim-property',
|
||||
sourceMapWithCode: true
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {IGeneratorOutput}
|
||||
* @type {esprima.Options}
|
||||
*/
|
||||
private generatorOutput: IGeneratorOutput;
|
||||
private static readonly esprimaParams: esprima.Options = {
|
||||
loc: true
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
private options: IOptions;
|
||||
private readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @param options
|
||||
*/
|
||||
private sourceCode: string;
|
||||
|
||||
/**
|
||||
* @param sourceCode
|
||||
* @param obfuscatorOptions
|
||||
*/
|
||||
constructor (sourceCode: string, obfuscatorOptions: IObfuscatorOptions = {}) {
|
||||
this.sourceCode = sourceCode;
|
||||
this.options = new Options(obfuscatorOptions);
|
||||
constructor (options: IOptions) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +46,7 @@ export class JavaScriptObfuscatorInternal {
|
||||
* @param astTree
|
||||
* @param options
|
||||
*/
|
||||
private static generateCode (sourceCode: string, astTree: ESTree.Node, options: IOptions): IGeneratorOutput {
|
||||
private static generateCode (sourceCode: string, astTree: ESTree.Program, options: IOptions): IGeneratorOutput {
|
||||
const escodegenParams: escodegen.GenerateOptions = Object.assign(
|
||||
{},
|
||||
JavaScriptObfuscatorInternal.escodegenParams
|
||||
@@ -73,26 +69,37 @@ export class JavaScriptObfuscatorInternal {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param generatorOutput
|
||||
* @returns {IObfuscationResult}
|
||||
*/
|
||||
public getObfuscationResult (): IObfuscationResult {
|
||||
public getObfuscationResult (generatorOutput: IGeneratorOutput): IObfuscationResult {
|
||||
return new SourceMapCorrector(
|
||||
new ObfuscationResult(
|
||||
this.generatorOutput.code,
|
||||
this.generatorOutput.map
|
||||
generatorOutput.code,
|
||||
generatorOutput.map
|
||||
),
|
||||
this.options.sourceMapBaseUrl + this.options.sourceMapFileName,
|
||||
this.options.sourceMapMode
|
||||
).correct();
|
||||
}
|
||||
|
||||
public obfuscate (): void {
|
||||
let astTree: ESTree.Node = esprima.parse(this.sourceCode, {
|
||||
loc: true
|
||||
});
|
||||
/**
|
||||
* @param sourceCode
|
||||
* @returns {IObfuscationResult}
|
||||
*/
|
||||
public obfuscate (sourceCode: string): IObfuscationResult {
|
||||
if (this.options.seed !== 0) {
|
||||
Utils.setRandomGenerator(new Chance(this.options.seed));
|
||||
}
|
||||
|
||||
astTree = new Obfuscator(this.options).obfuscateNode(astTree);
|
||||
const astTree: ESTree.Program = esprima.parse(sourceCode, JavaScriptObfuscatorInternal.esprimaParams);
|
||||
const obfuscatedAstTree: ESTree.Program = new Obfuscator(this.options).obfuscateAstTree(astTree);
|
||||
const generatorOutput: IGeneratorOutput = JavaScriptObfuscatorInternal.generateCode(
|
||||
sourceCode,
|
||||
obfuscatedAstTree,
|
||||
this.options
|
||||
);
|
||||
|
||||
this.generatorOutput = JavaScriptObfuscatorInternal.generateCode(this.sourceCode, astTree, this.options);
|
||||
return this.getObfuscationResult(generatorOutput);
|
||||
}
|
||||
}
|
||||
|
||||
+57
-76
@@ -2,39 +2,34 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeGroup } from './types/TNodeGroup';
|
||||
import { TNodeObfuscator } from './types/TNodeObfuscator';
|
||||
import { TVisitorDirection } from './types/TVisitorDirection';
|
||||
|
||||
import { ICustomNode } from './interfaces/custom-nodes/ICustomNode';
|
||||
import { IObfuscator } from './interfaces/IObfuscator';
|
||||
import { IOptions } from './interfaces/IOptions';
|
||||
import { INodeTransformer } from './interfaces/INodeTransformer';
|
||||
import { INodeTransformersFactory } from './interfaces/INodeTransformersFactory';
|
||||
import { IStackTraceData } from './interfaces/stack-trace-analyzer/IStackTraceData';
|
||||
|
||||
import { AppendState } from './enums/AppendState';
|
||||
import { NodeType } from './enums/NodeType';
|
||||
import { VisitorDirection } from './enums/VisitorDirection';
|
||||
|
||||
import { CatchClauseObfuscator } from './node-obfuscators/CatchClauseObfuscator';
|
||||
import { ConsoleOutputNodesGroup } from './node-groups/ConsoleOutputNodesGroup';
|
||||
import { DebugProtectionNodesGroup } from './node-groups/DebugProtectionNodesGroup';
|
||||
import { DomainLockNodesGroup } from './node-groups/DomainLockNodesGroup';
|
||||
import { FunctionDeclarationObfuscator } from './node-obfuscators/FunctionDeclarationObfuscator';
|
||||
import { FunctionObfuscator } from './node-obfuscators/FunctionObfuscator';
|
||||
import { LabeledStatementObfuscator } from './node-obfuscators/LabeledStatementObfuscator';
|
||||
import { LiteralObfuscator } from './node-obfuscators/LiteralObfuscator';
|
||||
import { MemberExpressionObfuscator } from './node-obfuscators/MemberExpressionObfuscator';
|
||||
import { MethodDefinitionObfuscator } from './node-obfuscators/MethodDefinitionObfuscator';
|
||||
import { Node } from './node/Node';
|
||||
import { NodeControlFlowTransformersFactory } from './node-transformers/node-control-flow-transformers/factory/NodeControlFlowTransformersFactory';
|
||||
import { NodeObfuscatorsFactory } from './node-transformers/node-obfuscators/factory/NodeObfuscatorsFactory';
|
||||
import { NodeUtils } from './node/NodeUtils';
|
||||
import { ObjectExpressionObfuscator } from './node-obfuscators/ObjectExpressionObfuscator';
|
||||
import { SelfDefendingNodesGroup } from './node-groups/SelfDefendingNodesGroup';
|
||||
import { StackTraceAnalyzer } from './stack-trace-analyzer/StackTraceAnalyzer';
|
||||
import { StringArrayNodesGroup } from './node-groups/StringArrayNodesGroup';
|
||||
import { VariableDeclarationObfuscator } from './node-obfuscators/VariableDeclarationObfuscator';
|
||||
|
||||
export class Obfuscator implements IObfuscator {
|
||||
/**
|
||||
* @type {TNodeGroup[]}
|
||||
*/
|
||||
private static nodeGroups: TNodeGroup[] = [
|
||||
private static readonly nodeGroups: TNodeGroup[] = [
|
||||
DomainLockNodesGroup,
|
||||
SelfDefendingNodesGroup,
|
||||
ConsoleOutputNodesGroup,
|
||||
@@ -42,35 +37,15 @@ export class Obfuscator implements IObfuscator {
|
||||
StringArrayNodesGroup
|
||||
];
|
||||
|
||||
/**
|
||||
* @type {Map<string, TNodeObfuscator[]>}
|
||||
*/
|
||||
private static nodeObfuscators: Map <string, TNodeObfuscator[]> = new Map <string, TNodeObfuscator[]> ([
|
||||
[NodeType.ArrowFunctionExpression, [FunctionObfuscator]],
|
||||
[NodeType.ClassDeclaration, [FunctionDeclarationObfuscator]],
|
||||
[NodeType.CatchClause, [CatchClauseObfuscator]],
|
||||
[NodeType.FunctionDeclaration, [
|
||||
FunctionDeclarationObfuscator,
|
||||
FunctionObfuscator
|
||||
]],
|
||||
[NodeType.FunctionExpression, [FunctionObfuscator]],
|
||||
[NodeType.MemberExpression, [MemberExpressionObfuscator]],
|
||||
[NodeType.MethodDefinition, [MethodDefinitionObfuscator]],
|
||||
[NodeType.ObjectExpression, [ObjectExpressionObfuscator]],
|
||||
[NodeType.VariableDeclaration, [VariableDeclarationObfuscator]],
|
||||
[NodeType.LabeledStatement, [LabeledStatementObfuscator]],
|
||||
[NodeType.Literal, [LiteralObfuscator]]
|
||||
]);
|
||||
|
||||
/**
|
||||
* @type {Map<string, AbstractCustomNode>}
|
||||
*/
|
||||
private customNodes: Map <string, ICustomNode> = new Map <string, ICustomNode> ();
|
||||
private customNodes: Map <string, ICustomNode>;
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
private options: IOptions;
|
||||
private readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @param options
|
||||
@@ -80,34 +55,47 @@ export class Obfuscator implements IObfuscator {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @returns {ESTree.Node}
|
||||
* @param astTree
|
||||
* @returns {ESTree.Program}
|
||||
*/
|
||||
public obfuscateNode (node: ESTree.Program): ESTree.Node {
|
||||
if (Node.isProgramNode(node) && !node.body.length) {
|
||||
return node;
|
||||
public obfuscateAstTree (astTree: ESTree.Program): ESTree.Program {
|
||||
if (Node.isProgramNode(astTree) && !astTree.body.length) {
|
||||
return astTree;
|
||||
}
|
||||
|
||||
NodeUtils.parentize(node);
|
||||
NodeUtils.parentize(astTree);
|
||||
this.initializeCustomNodes(new StackTraceAnalyzer().analyze(astTree.body));
|
||||
|
||||
const stackTraceData: IStackTraceData[] = new StackTraceAnalyzer(node.body).analyze();
|
||||
// tasks before nodes transformation
|
||||
this.beforeTransform(astTree);
|
||||
|
||||
this.initializeCustomNodes(stackTraceData);
|
||||
// first pass: control flow flattening
|
||||
if (this.options.controlFlowFlattening) {
|
||||
this.transformAstTree(astTree, VisitorDirection.leave, new NodeControlFlowTransformersFactory(
|
||||
this.customNodes,
|
||||
this.options
|
||||
));
|
||||
}
|
||||
|
||||
this.beforeObfuscation(node);
|
||||
this.obfuscate(node);
|
||||
this.afterObfuscation(node);
|
||||
// second pass: nodes obfuscation
|
||||
this.transformAstTree(astTree, VisitorDirection.enter, new NodeObfuscatorsFactory(
|
||||
this.customNodes,
|
||||
this.options
|
||||
));
|
||||
|
||||
return node;
|
||||
// tasks after nodes transformation
|
||||
this.afterTransform(astTree);
|
||||
|
||||
return astTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param astTree
|
||||
*/
|
||||
private afterObfuscation (astTree: ESTree.Node): void {
|
||||
this.customNodes.forEach((node: ICustomNode) => {
|
||||
if (node.getAppendState() === AppendState.AfterObfuscation) {
|
||||
node.appendNode(astTree);
|
||||
private afterTransform (astTree: ESTree.Program): void {
|
||||
this.customNodes.forEach((customNode: ICustomNode) => {
|
||||
if (customNode.getAppendState() === AppendState.AfterObfuscation) {
|
||||
customNode.appendNode(astTree);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -115,10 +103,10 @@ export class Obfuscator implements IObfuscator {
|
||||
/**
|
||||
* @param astTree
|
||||
*/
|
||||
private beforeObfuscation (astTree: ESTree.Node): void {
|
||||
this.customNodes.forEach((node: ICustomNode) => {
|
||||
if (node.getAppendState() === AppendState.BeforeObfuscation) {
|
||||
node.appendNode(astTree);
|
||||
private beforeTransform (astTree: ESTree.Program): void {
|
||||
this.customNodes.forEach((customNode: ICustomNode) => {
|
||||
if (customNode.getAppendState() === AppendState.BeforeObfuscation) {
|
||||
customNode.appendNode(astTree);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -127,7 +115,7 @@ export class Obfuscator implements IObfuscator {
|
||||
* @param stackTraceData
|
||||
*/
|
||||
private initializeCustomNodes (stackTraceData: IStackTraceData[]): void {
|
||||
let customNodes: [string, ICustomNode][] = [];
|
||||
const customNodes: [string, ICustomNode][] = [];
|
||||
|
||||
Obfuscator.nodeGroups.forEach((nodeGroupConstructor: TNodeGroup) => {
|
||||
const nodeGroupNodes: Map <string, ICustomNode> | undefined = new nodeGroupConstructor(
|
||||
@@ -144,30 +132,23 @@ export class Obfuscator implements IObfuscator {
|
||||
this.customNodes = new Map <string, ICustomNode> (customNodes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param parentNode
|
||||
* @param astTree
|
||||
* @param direction
|
||||
* @param nodeTransformersFactory
|
||||
*/
|
||||
private initializeNodeObfuscators (node: ESTree.Node, parentNode: ESTree.Node): void {
|
||||
let nodeObfuscators: TNodeObfuscator[] | undefined = Obfuscator.nodeObfuscators.get(node.type);
|
||||
private transformAstTree (
|
||||
astTree: ESTree.Program,
|
||||
direction: TVisitorDirection,
|
||||
nodeTransformersFactory: INodeTransformersFactory
|
||||
): void {
|
||||
estraverse.traverse(astTree, {
|
||||
[direction]: (node: ESTree.Node, parentNode: ESTree.Node): void => {
|
||||
const nodeTransformers: INodeTransformer[] = nodeTransformersFactory.initializeNodeTransformers(node.type);
|
||||
|
||||
if (!nodeObfuscators) {
|
||||
return;
|
||||
}
|
||||
|
||||
nodeObfuscators.forEach((obfuscator: TNodeObfuscator) => {
|
||||
new obfuscator(this.customNodes, this.options).obfuscateNode(node, parentNode);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
*/
|
||||
private obfuscate (node: ESTree.Node): void {
|
||||
estraverse.traverse(node, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): void => {
|
||||
this.initializeNodeObfuscators(node, parentNode);
|
||||
nodeTransformers.forEach((nodeTransformer: INodeTransformer) => {
|
||||
nodeTransformer.transformNode(node, parentNode);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,22 +12,22 @@ export class SourceMapCorrector implements ISourceMapCorrector {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private obfuscatedCode: string;
|
||||
private readonly obfuscatedCode: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private sourceMap: string;
|
||||
private readonly sourceMap: string;
|
||||
|
||||
/**
|
||||
* @type {TSourceMapMode}
|
||||
*/
|
||||
private sourceMapMode: TSourceMapMode;
|
||||
private readonly sourceMapMode: TSourceMapMode;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private sourceMapUrl: string;
|
||||
private readonly sourceMapUrl: string;
|
||||
|
||||
/**
|
||||
* @param obfuscationResult
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import { Utils } from './Utils';
|
||||
|
||||
export class StringArray {
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
private array: string[] = [];
|
||||
|
||||
/**
|
||||
* @param value
|
||||
*/
|
||||
public addToArray (value: string): void {
|
||||
this.array.push(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public getArray (): string[] {
|
||||
return this.array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* @returns {number}
|
||||
*/
|
||||
public getIndexOf(value: string): number {
|
||||
return this.array.indexOf(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
public getLength (): number {
|
||||
return this.array.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rotationValue
|
||||
*/
|
||||
public rotateArray (rotationValue: number): void {
|
||||
this.array = Utils.arrayRotate(this.array, rotationValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public toString (): string {
|
||||
return this.array.map((value: string) => {
|
||||
return `'${value}'`;
|
||||
}).toString()
|
||||
}
|
||||
}
|
||||
+73
-13
@@ -2,11 +2,18 @@ import { Chance } from 'chance';
|
||||
|
||||
import { JSFuck } from './enums/JSFuck';
|
||||
|
||||
const isEqual = require('is-equal');
|
||||
|
||||
export class Utils {
|
||||
/**
|
||||
* @type {Chance.Chance}
|
||||
* @type {string}
|
||||
*/
|
||||
private static randomGenerator: Chance.Chance = new Chance();
|
||||
public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
/**
|
||||
* @type {Chance.Chance | Chance.SeededChance}
|
||||
*/
|
||||
private static randomGenerator: Chance.Chance | Chance.SeededChance = new Chance();
|
||||
|
||||
/**
|
||||
* @param array
|
||||
@@ -99,13 +106,44 @@ export class Utils {
|
||||
return domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param min
|
||||
* @param max
|
||||
* @returns {number}
|
||||
*/
|
||||
public static getRandomFloat (min: number, max: number): number {
|
||||
return Utils.getRandomGenerator().floating({
|
||||
min: min,
|
||||
max: max,
|
||||
fixed: 7
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Chance.Chance}
|
||||
*/
|
||||
public static getRandomGenerator (): Chance.Chance {
|
||||
const randomGenerator: Chance.Chance = Utils.randomGenerator;
|
||||
|
||||
if (!randomGenerator) {
|
||||
throw new Error(`\`randomGenerator\` static property is undefined`);
|
||||
}
|
||||
|
||||
return Utils.randomGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param min
|
||||
* @param max
|
||||
* @returns {number}
|
||||
*/
|
||||
public static getRandomInteger (min: number, max: number): number {
|
||||
return Utils.getRandomGenerator().integer({
|
||||
min: min,
|
||||
max: max
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param length
|
||||
* @returns {string}
|
||||
@@ -117,10 +155,7 @@ export class Utils {
|
||||
|
||||
return `${prefix}${(
|
||||
Utils.decToHex(
|
||||
Utils.getRandomGenerator().integer({
|
||||
min: rangeMinInteger,
|
||||
max: rangeMaxInteger
|
||||
})
|
||||
Utils.getRandomInteger(rangeMinInteger, rangeMaxInteger)
|
||||
)
|
||||
).substr(0, length)}`;
|
||||
}
|
||||
@@ -140,7 +175,7 @@ export class Utils {
|
||||
result: string = '';
|
||||
|
||||
while (i1 < s1.length || i2 < s2.length) {
|
||||
if (Math.random() < 0.5 && i2 < s2.length) {
|
||||
if (Utils.getRandomFloat(0, 1) < 0.5 && i2 < s2.length) {
|
||||
result += s2.charAt(++i2);
|
||||
} else {
|
||||
result += s1.charAt(++i1);
|
||||
@@ -150,13 +185,16 @@ export class Utils {
|
||||
return result;
|
||||
};
|
||||
|
||||
const customPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
const randomString: string = Utils.randomGenerator.string({
|
||||
length: length,
|
||||
pool: Utils.randomGeneratorPool
|
||||
});
|
||||
|
||||
let randomString: string = Utils.randomGenerator.string({length: length, pool: customPool}),
|
||||
randomStringDiff: string = randomString.replace(
|
||||
new RegExp('[' + escapeRegExp(str) + ']', 'g'),
|
||||
''),
|
||||
randomStringDiffArray: string[] = randomStringDiff.split('');
|
||||
let randomStringDiff: string = randomString.replace(
|
||||
new RegExp('[' + escapeRegExp(str) + ']', 'g'),
|
||||
'');
|
||||
|
||||
const randomStringDiffArray: string[] = randomStringDiff.split('');
|
||||
|
||||
Utils.randomGenerator.shuffle(randomStringDiffArray);
|
||||
randomStringDiff = randomStringDiffArray.join('');
|
||||
@@ -173,6 +211,21 @@ export class Utils {
|
||||
return number % 1 === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param map
|
||||
* @param value
|
||||
* @returns {any}
|
||||
*/
|
||||
public static mapGetFirstKeyOf(map: Map <any, any>, value: any): any {
|
||||
for (var [key, storageValue] of map) {
|
||||
if (isEqual(value, storageValue)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* RC4 symmetric cipher encryption/decryption
|
||||
* https://gist.github.com/farhadi/2185197
|
||||
@@ -213,6 +266,13 @@ export class Utils {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param randomGenerator
|
||||
*/
|
||||
public static setRandomGenerator (randomGenerator: Chance.Chance | Chance.SeededChance): void {
|
||||
Utils.randomGenerator = randomGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj
|
||||
* @returns {T}
|
||||
|
||||
+2
-2
@@ -10,14 +10,14 @@ export class CLIUtils {
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
private static availableInputExtensions: string[] = [
|
||||
private static readonly availableInputExtensions: string[] = [
|
||||
'.js'
|
||||
];
|
||||
|
||||
/**
|
||||
* @type {BufferEncoding}
|
||||
*/
|
||||
private static encoding: BufferEncoding = 'utf8';
|
||||
private static readonly encoding: BufferEncoding = 'utf8';
|
||||
|
||||
/**
|
||||
* @param outputPath
|
||||
|
||||
@@ -19,7 +19,7 @@ export class JavaScriptObfuscatorCLI {
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
private arguments: string[];
|
||||
private readonly arguments: string[];
|
||||
|
||||
/**
|
||||
* @type {commander.ICommand}
|
||||
@@ -69,7 +69,7 @@ export class JavaScriptObfuscatorCLI {
|
||||
* @returns {string}
|
||||
*/
|
||||
private static parseSourceMapMode (value: string): string {
|
||||
let availableMode: boolean = Object
|
||||
const availableMode: boolean = Object
|
||||
.keys(SourceMapMode)
|
||||
.some((key: string): boolean => {
|
||||
return SourceMapMode[key] === value;
|
||||
@@ -121,8 +121,8 @@ export class JavaScriptObfuscatorCLI {
|
||||
* @returns {IObfuscatorOptions}
|
||||
*/
|
||||
private buildOptions (): IObfuscatorOptions {
|
||||
let obfuscatorOptions: IObfuscatorOptions = {},
|
||||
availableOptions: string[] = Object.keys(DEFAULT_PRESET);
|
||||
const obfuscatorOptions: IObfuscatorOptions = {};
|
||||
const availableOptions: string[] = Object.keys(DEFAULT_PRESET);
|
||||
|
||||
for (const option in this.commands) {
|
||||
if (!this.commands.hasOwnProperty(option)) {
|
||||
@@ -145,12 +145,14 @@ export class JavaScriptObfuscatorCLI {
|
||||
.usage('<inputPath> [options]')
|
||||
.option('-o, --output <path>', 'Output path for obfuscated code')
|
||||
.option('--compact <boolean>', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean)
|
||||
.option('--controlFlowFlattening <boolean>', 'Enables control flow flattening', JavaScriptObfuscatorCLI.parseBoolean)
|
||||
.option('--debugProtection <boolean>', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean)
|
||||
.option('--debugProtectionInterval <boolean>', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean)
|
||||
.option('--disableConsoleOutput <boolean>', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean)
|
||||
.option('--domainLock <list>', 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)', (val: string) => val.split(','))
|
||||
.option('--reservedNames <list>', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', (val: string) => val.split(','))
|
||||
.option('--rotateStringArray <boolean>', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean)
|
||||
.option('--seed <number>', 'Sets seed for random generator. This is useful for creating repeatable results.', parseFloat)
|
||||
.option('--selfDefending <boolean>', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean)
|
||||
.option('--sourceMap <boolean>', 'Enables source map generation', JavaScriptObfuscatorCLI.parseBoolean)
|
||||
.option('--sourceMapBaseUrl <string>', 'Sets base url to the source map import url when `--sourceMapMode=separate`')
|
||||
@@ -179,8 +181,8 @@ export class JavaScriptObfuscatorCLI {
|
||||
}
|
||||
|
||||
private processData (): void {
|
||||
let options: IObfuscatorOptions = this.buildOptions(),
|
||||
outputCodePath: string = CLIUtils.getOutputCodePath((<any>this.commands).output, this.inputPath);
|
||||
const options: IObfuscatorOptions = this.buildOptions();
|
||||
const outputCodePath: string = CLIUtils.getOutputCodePath((<any>this.commands).output, this.inputPath);
|
||||
|
||||
if (options.sourceMap) {
|
||||
this.processDataWithSourceMap(outputCodePath, options);
|
||||
@@ -194,7 +196,7 @@ export class JavaScriptObfuscatorCLI {
|
||||
* @param options
|
||||
*/
|
||||
private processDataWithoutSourceMap (outputCodePath: string, options: IObfuscatorOptions): void {
|
||||
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(this.data, options).getObfuscatedCode();
|
||||
const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(this.data, options).getObfuscatedCode();
|
||||
|
||||
CLIUtils.writeFile(outputCodePath, obfuscatedCode);
|
||||
}
|
||||
@@ -204,7 +206,7 @@ export class JavaScriptObfuscatorCLI {
|
||||
* @param options
|
||||
*/
|
||||
private processDataWithSourceMap (outputCodePath: string, options: IObfuscatorOptions): void {
|
||||
let outputSourceMapPath: string = CLIUtils.getOutputSourceMapPath(
|
||||
const outputSourceMapPath: string = CLIUtils.getOutputSourceMapPath(
|
||||
outputCodePath,
|
||||
options.sourceMapFileName || ''
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { IOptions } from '../interfaces/IOptions';
|
||||
import { TStatement } from '../types/TStatement';
|
||||
|
||||
import { AppendState } from '../enums/AppendState';
|
||||
import { NodeUtils } from '../node/NodeUtils';
|
||||
|
||||
export abstract class AbstractCustomNode implements ICustomNode {
|
||||
/**
|
||||
@@ -15,7 +16,7 @@ export abstract class AbstractCustomNode implements ICustomNode {
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
protected options: IOptions;
|
||||
protected readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @param options
|
||||
@@ -36,6 +37,11 @@ export abstract class AbstractCustomNode implements ICustomNode {
|
||||
return this.appendState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public abstract getCode (): string;
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
@@ -53,5 +59,7 @@ export abstract class AbstractCustomNode implements ICustomNode {
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected abstract getNodeStructure (): TStatement[];
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return NodeUtils.convertCodeToStructure(this.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData';
|
||||
@@ -12,7 +11,6 @@ import { ConsoleOutputDisableExpressionTemplate } from '../../templates/custom-n
|
||||
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { Utils } from '../../Utils';
|
||||
|
||||
export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
|
||||
@@ -68,27 +66,12 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* JSCrush version of following code
|
||||
*
|
||||
* (function () {
|
||||
* var _console = []["filter"]["constructor"]("return this")().console;
|
||||
* var _function = function () {};
|
||||
*
|
||||
* _console.log = _function;
|
||||
* _console.info = _function;
|
||||
* _console.warn = _function;
|
||||
* _console.error = _function;
|
||||
* _console
|
||||
* })();
|
||||
*
|
||||
* @returns {TStatement[]}
|
||||
* @returns {string}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
ConsoleOutputDisableExpressionTemplate().formatUnicorn({
|
||||
consoleLogDisableFunctionName: Utils.getRandomVariableName(),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
})
|
||||
);
|
||||
public getCode (): string {
|
||||
return format(ConsoleOutputDisableExpressionTemplate(), {
|
||||
consoleLogDisableFunctionName: Utils.getRandomVariableName(),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
|
||||
|
||||
import { IOptions } from '../../../interfaces/IOptions';
|
||||
|
||||
import { AppendState } from '../../../enums/AppendState';
|
||||
|
||||
import { BinaryExpressionFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate';
|
||||
|
||||
import { AbstractCustomNode } from '../../AbstractCustomNode';
|
||||
import { Utils } from '../../../Utils';
|
||||
|
||||
export class BinaryExpressionFunctionNode extends AbstractCustomNode {
|
||||
/**
|
||||
* @type {AppendState}
|
||||
*/
|
||||
protected appendState: AppendState = AppendState.BeforeObfuscation;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private operator: string;
|
||||
|
||||
/**
|
||||
* @param operator
|
||||
* @param options
|
||||
*/
|
||||
constructor (operator: string, options: IOptions) {
|
||||
super(options);
|
||||
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockScopeNode
|
||||
*/
|
||||
public appendNode (blockScopeNode: TNodeWithBlockStatement): void {}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getCode (): string {
|
||||
return format(BinaryExpressionFunctionTemplate(), {
|
||||
functionName: Utils.getRandomVariableName(1),
|
||||
operator: this.operator
|
||||
});
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
|
||||
|
||||
import { IOptions } from '../../../interfaces/IOptions';
|
||||
|
||||
import { AppendState } from '../../../enums/AppendState';
|
||||
|
||||
import { ControlFlowStorageCallTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallTemplate';
|
||||
|
||||
import { AbstractCustomNode } from '../../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../../node/NodeAppender';
|
||||
|
||||
export class ControlFlowStorageCallNode extends AbstractCustomNode {
|
||||
/**
|
||||
* @type {AppendState}
|
||||
*/
|
||||
protected appendState: AppendState = AppendState.AfterObfuscation;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private controlFlowStorageKey: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private controlFlowStorageName: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private leftValue: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private rightValue: string;
|
||||
|
||||
/**
|
||||
* @param controlFlowStorageName
|
||||
* @param controlFlowStorageKey
|
||||
* @param leftValue
|
||||
* @param rightValue
|
||||
* @param options
|
||||
*/
|
||||
constructor (
|
||||
controlFlowStorageName: string,
|
||||
controlFlowStorageKey: string,
|
||||
leftValue: string,
|
||||
rightValue: string,
|
||||
options: IOptions
|
||||
) {
|
||||
super(options);
|
||||
|
||||
this.controlFlowStorageName = controlFlowStorageName;
|
||||
this.controlFlowStorageKey = controlFlowStorageKey;
|
||||
this.leftValue = leftValue;
|
||||
this.rightValue = rightValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockScopeNode
|
||||
*/
|
||||
public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
|
||||
NodeAppender.prependNode(blockScopeNode, this.getNode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getCode (): string {
|
||||
return format(ControlFlowStorageCallTemplate(), {
|
||||
controlFlowStorageKey: this.controlFlowStorageKey,
|
||||
controlFlowStorageName: this.controlFlowStorageName,
|
||||
leftValue: this.leftValue,
|
||||
rightValue: this.rightValue
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStorage } from '../../interfaces/IStorage';
|
||||
|
||||
import { AppendState } from '../../enums/AppendState';
|
||||
|
||||
import { ControlFlowStorageTemplate } from '../../templates/custom-nodes/control-flow-storage-nodes/ControlFlowStorageTemplate';
|
||||
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
|
||||
export class ControlFlowStorageNode extends AbstractCustomNode {
|
||||
/**
|
||||
* @type {AppendState}
|
||||
*/
|
||||
protected appendState: AppendState = AppendState.AfterObfuscation;
|
||||
|
||||
/**
|
||||
* @type {IStorage <ICustomNode>}
|
||||
*/
|
||||
private controlFlowStorage: IStorage <ICustomNode>;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private controlFlowStorageName: string;
|
||||
|
||||
/**
|
||||
* @param controlFlowStorage
|
||||
* @param controlFlowStorageName
|
||||
* @param options
|
||||
*/
|
||||
constructor (
|
||||
controlFlowStorage: IStorage <ICustomNode>,
|
||||
controlFlowStorageName: string,
|
||||
options: IOptions
|
||||
) {
|
||||
super(options);
|
||||
|
||||
this.controlFlowStorage = controlFlowStorage;
|
||||
this.controlFlowStorageName = controlFlowStorageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockScopeNode
|
||||
*/
|
||||
public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
|
||||
NodeAppender.prependNode(blockScopeNode, this.getNode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getCode (): string {
|
||||
return format(ControlFlowStorageTemplate(), {
|
||||
controlFlowStorage: this.controlFlowStorage.toString(),
|
||||
controlFlowStorageName: this.controlFlowStorageName
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
|
||||
@@ -11,7 +10,6 @@ import { DebugProtectionFunctionCallTemplate } from '../../templates/custom-node
|
||||
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
|
||||
/**
|
||||
@@ -42,13 +40,11 @@ export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
* @returns {string}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
DebugProtectionFunctionCallTemplate().formatUnicorn({
|
||||
debugProtectionFunctionName: this.debugProtectionFunctionName
|
||||
})
|
||||
);
|
||||
public getCode (): string {
|
||||
return format(DebugProtectionFunctionCallTemplate(), {
|
||||
debugProtectionFunctionName: this.debugProtectionFunctionName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
|
||||
@@ -11,7 +10,6 @@ import { DebugProtectionFunctionIntervalTemplate } from '../../templates/custom-
|
||||
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
|
||||
/**
|
||||
@@ -42,13 +40,11 @@ export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
* @returns {string}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
DebugProtectionFunctionIntervalTemplate().formatUnicorn({
|
||||
debugProtectionFunctionName: this.debugProtectionFunctionName
|
||||
})
|
||||
);
|
||||
public getCode (): string {
|
||||
return format(DebugProtectionFunctionIntervalTemplate(), {
|
||||
debugProtectionFunctionName: this.debugProtectionFunctionName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
|
||||
@@ -11,7 +10,6 @@ import { DebugProtectionFunctionTemplate } from '../../templates/custom-nodes/de
|
||||
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { Utils } from '../../Utils';
|
||||
|
||||
export class DebugProtectionFunctionNode extends AbstractCustomNode {
|
||||
@@ -40,10 +38,7 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode {
|
||||
*/
|
||||
public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
|
||||
let programBodyLength: number = blockScopeNode.body.length,
|
||||
randomIndex: number = Utils.getRandomGenerator().integer({
|
||||
min: 0,
|
||||
max: programBodyLength
|
||||
});
|
||||
randomIndex: number = Utils.getRandomInteger(0, programBodyLength);
|
||||
|
||||
NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), randomIndex);
|
||||
}
|
||||
@@ -51,20 +46,9 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode {
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getNodeIdentifier (): string {
|
||||
return this.debugProtectionFunctionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Found this trick in JScrambler
|
||||
*
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
DebugProtectionFunctionTemplate().formatUnicorn({
|
||||
debugProtectionFunctionName: this.debugProtectionFunctionName
|
||||
})
|
||||
);
|
||||
public getCode (): string {
|
||||
return format(DebugProtectionFunctionTemplate(), {
|
||||
debugProtectionFunctionName: this.debugProtectionFunctionName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData';
|
||||
@@ -12,7 +11,6 @@ import { DomainLockNodeTemplate } from '../../templates/custom-nodes/domain-lock
|
||||
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { Utils } from '../../Utils';
|
||||
|
||||
export class DomainLockNode extends AbstractCustomNode {
|
||||
@@ -68,19 +66,17 @@ export class DomainLockNode extends AbstractCustomNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
* @returns {string}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
public getCode (): string {
|
||||
let domainsString: string = this.options.domainLock.join(';'),
|
||||
[hiddenDomainsString, diff]: string[] = Utils.hideString(domainsString, domainsString.length * 3);
|
||||
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
DomainLockNodeTemplate().formatUnicorn({
|
||||
domainLockFunctionName: Utils.getRandomVariableName(),
|
||||
diff: diff,
|
||||
domains: hiddenDomainsString,
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
})
|
||||
);
|
||||
return format(DomainLockNodeTemplate(), {
|
||||
domainLockFunctionName: Utils.getRandomVariableName(),
|
||||
diff: diff,
|
||||
domains: hiddenDomainsString,
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData';
|
||||
@@ -15,7 +14,6 @@ import { NO_CUSTOM_NODES_PRESET } from '../../preset-options/NoCustomNodesPreset
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
|
||||
/**
|
||||
@@ -74,21 +72,22 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
* @returns {string}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
public getCode (): string {
|
||||
if (this.appendState === AppendState.AfterObfuscation) {
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
JavaScriptObfuscator.obfuscate(SingleNodeCallControllerTemplate().formatUnicorn({
|
||||
return JavaScriptObfuscator.obfuscate(
|
||||
format(SingleNodeCallControllerTemplate(), {
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
}), NO_CUSTOM_NODES_PRESET).getObfuscatedCode()
|
||||
);
|
||||
}),
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
seed: this.options.seed
|
||||
})
|
||||
).getObfuscatedCode();
|
||||
}
|
||||
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
SingleNodeCallControllerTemplate().formatUnicorn({
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
})
|
||||
);
|
||||
return format(SingleNodeCallControllerTemplate(), {
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData';
|
||||
@@ -13,7 +14,6 @@ import { SelfDefendingTemplate } from '../../templates/custom-nodes/self-defendi
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { Utils } from '../../Utils';
|
||||
|
||||
export class SelfDefendingUnicodeNode extends AbstractCustomNode {
|
||||
@@ -69,17 +69,17 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
* @returns {string}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
JavaScriptObfuscator.obfuscate(
|
||||
SelfDefendingTemplate().formatUnicorn({
|
||||
selfDefendingFunctionName: Utils.getRandomVariableName(),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
}),
|
||||
NO_CUSTOM_NODES_PRESET
|
||||
).getObfuscatedCode()
|
||||
);
|
||||
public getCode (): string {
|
||||
return JavaScriptObfuscator.obfuscate(
|
||||
format(SelfDefendingTemplate(), {
|
||||
selfDefendingFunctionName: Utils.getRandomVariableName(),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
}),
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
seed: this.options.seed
|
||||
})
|
||||
).getObfuscatedCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { ICustomNodeWithIdentifier } from '../../interfaces/custom-nodes/ICustomNodeWithIdentifier';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStorage } from '../../interfaces/IStorage';
|
||||
|
||||
import { AppendState } from '../../enums/AppendState';
|
||||
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
|
||||
@@ -20,19 +22,17 @@ import { StringArrayRc4DecodeNodeTemplate } from '../../templates/custom-nodes/s
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { StringArray } from '../../StringArray';
|
||||
|
||||
export class StringArrayCallsWrapper extends AbstractCustomNode {
|
||||
export class StringArrayCallsWrapper extends AbstractCustomNode implements ICustomNodeWithIdentifier {
|
||||
/**
|
||||
* @type {AppendState}
|
||||
*/
|
||||
protected appendState: AppendState = AppendState.AfterObfuscation;
|
||||
|
||||
/**
|
||||
* @type {StringArray}
|
||||
* @type {IStorage <string>}
|
||||
*/
|
||||
private stringArray: StringArray;
|
||||
private stringArray: IStorage <string>;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
@@ -53,7 +53,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
|
||||
constructor (
|
||||
stringArrayCallsWrapperName: string,
|
||||
stringArrayName: string,
|
||||
stringArray: StringArray,
|
||||
stringArray: IStorage <string>,
|
||||
options: IOptions
|
||||
) {
|
||||
super(options);
|
||||
@@ -74,6 +74,24 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
|
||||
NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getCode (): string {
|
||||
const decodeNodeTemplate: string = this.getDecodeStringArrayTemplate();
|
||||
|
||||
return JavaScriptObfuscator.obfuscate(
|
||||
format(StringArrayCallsWrapperTemplate(), {
|
||||
decodeNodeTemplate,
|
||||
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
|
||||
stringArrayName: this.stringArrayName
|
||||
}),
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
seed: this.options.seed
|
||||
})
|
||||
).getObfuscatedCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
@@ -96,7 +114,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
|
||||
selfDefendingCode: string = '';
|
||||
|
||||
if (this.options.selfDefending) {
|
||||
selfDefendingCode = SelfDefendingTemplate().formatUnicorn({
|
||||
selfDefendingCode = format(SelfDefendingTemplate(), {
|
||||
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
|
||||
stringArrayName: this.stringArrayName
|
||||
});
|
||||
@@ -104,7 +122,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
|
||||
|
||||
switch (this.options.stringArrayEncoding) {
|
||||
case StringArrayEncoding.base64:
|
||||
decodeStringArrayTemplate = StringArrayBase64DecodeNodeTemplate().formatUnicorn({
|
||||
decodeStringArrayTemplate = format(StringArrayBase64DecodeNodeTemplate(), {
|
||||
atobPolyfill: AtobTemplate(),
|
||||
selfDefendingCode,
|
||||
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
|
||||
@@ -113,7 +131,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
|
||||
break;
|
||||
|
||||
case StringArrayEncoding.rc4:
|
||||
decodeStringArrayTemplate = StringArrayRc4DecodeNodeTemplate().formatUnicorn({
|
||||
decodeStringArrayTemplate = format(StringArrayRc4DecodeNodeTemplate(), {
|
||||
atobPolyfill: AtobTemplate(),
|
||||
rc4Polyfill: Rc4Template(),
|
||||
selfDefendingCode,
|
||||
@@ -125,22 +143,4 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
|
||||
|
||||
return decodeStringArrayTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const decodeNodeTemplate: string = this.getDecodeStringArrayTemplate();
|
||||
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
JavaScriptObfuscator.obfuscate(
|
||||
StringArrayCallsWrapperTemplate().formatUnicorn({
|
||||
decodeNodeTemplate,
|
||||
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
|
||||
stringArrayName: this.stringArrayName
|
||||
}),
|
||||
NO_CUSTOM_NODES_PRESET
|
||||
).getObfuscatedCode()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { ICustomNodeWithData } from '../../interfaces/custom-nodes/ICustomNodeWithData';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStorage } from '../../interfaces/IStorage';
|
||||
|
||||
import { AppendState } from '../../enums/AppendState';
|
||||
|
||||
import { StringArray } from '../../StringArray';
|
||||
|
||||
import { StringArrayTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-node/StringArrayTemplate';
|
||||
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { StringArrayStorage } from '../../storages/string-array/StringArrayStorage';
|
||||
|
||||
export class StringArrayNode extends AbstractCustomNode {
|
||||
export class StringArrayNode extends AbstractCustomNode implements ICustomNodeWithData {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
@@ -27,9 +27,9 @@ export class StringArrayNode extends AbstractCustomNode {
|
||||
protected appendState: AppendState = AppendState.AfterObfuscation;
|
||||
|
||||
/**
|
||||
* @type {StringArray}
|
||||
* @type {IStorage <string>}
|
||||
*/
|
||||
private stringArray: StringArray;
|
||||
private stringArray: IStorage <string>;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
@@ -48,7 +48,7 @@ export class StringArrayNode extends AbstractCustomNode {
|
||||
* @param options
|
||||
*/
|
||||
constructor (
|
||||
stringArray: StringArray,
|
||||
stringArray: IStorage <string>,
|
||||
stringArrayName: string,
|
||||
stringArrayRotateValue: number = 0,
|
||||
options: IOptions
|
||||
@@ -74,14 +74,17 @@ export class StringArrayNode extends AbstractCustomNode {
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getNodeIdentifier (): string {
|
||||
return this.stringArrayName;
|
||||
public getCode (): string {
|
||||
return format(StringArrayTemplate(), {
|
||||
stringArrayName: this.stringArrayName,
|
||||
stringArray: this.stringArray.toString()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {StringArray}
|
||||
* @returns {IStorage <string>}
|
||||
*/
|
||||
public getNodeData (): StringArray {
|
||||
public getNodeData (): IStorage <string> {
|
||||
return this.stringArray;
|
||||
}
|
||||
|
||||
@@ -89,27 +92,8 @@ export class StringArrayNode extends AbstractCustomNode {
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
public getNode (): TStatement[] {
|
||||
this.stringArray.rotateArray(this.stringArrayRotateValue);
|
||||
(<StringArrayStorage>this.stringArray).rotateArray(this.stringArrayRotateValue);
|
||||
|
||||
return super.getNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data
|
||||
*/
|
||||
public updateNodeData (data: string): void {
|
||||
this.stringArray.addToArray(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
StringArrayTemplate().formatUnicorn({
|
||||
stringArrayName: this.stringArrayName,
|
||||
stringArray: this.stringArray.toString()
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStorage } from '../../interfaces/IStorage';
|
||||
|
||||
import { AppendState } from '../../enums/AppendState';
|
||||
|
||||
@@ -15,8 +15,6 @@ import { StringArrayRotateFunctionTemplate } from '../../templates/custom-nodes/
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { StringArray } from '../../StringArray';
|
||||
import { Utils } from '../../Utils';
|
||||
|
||||
export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
@@ -26,9 +24,9 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
protected appendState: AppendState = AppendState.AfterObfuscation;
|
||||
|
||||
/**
|
||||
* @type {StringArray}
|
||||
* @type {IStorage <string>}
|
||||
*/
|
||||
private stringArray: StringArray;
|
||||
private stringArray: IStorage <string>;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
@@ -48,7 +46,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
*/
|
||||
constructor (
|
||||
stringArrayName: string,
|
||||
stringArray: StringArray,
|
||||
stringArray: IStorage <string>,
|
||||
stringArrayRotateValue: number,
|
||||
options: IOptions
|
||||
) {
|
||||
@@ -71,22 +69,15 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
* @returns {string}
|
||||
*/
|
||||
public getNode (): TStatement[] {
|
||||
return super.getNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
public getCode (): string {
|
||||
let code: string = '',
|
||||
timesName: string = Utils.getRandomVariableName(),
|
||||
whileFunctionName: string = Utils.getRandomVariableName();
|
||||
|
||||
if (this.options.selfDefending) {
|
||||
code = SelfDefendingTemplate().formatUnicorn({
|
||||
code = format(SelfDefendingTemplate(), {
|
||||
timesName,
|
||||
whileFunctionName
|
||||
});
|
||||
@@ -94,17 +85,17 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
code = `${whileFunctionName}(++${timesName})`;
|
||||
}
|
||||
|
||||
return NodeUtils.convertCodeToStructure(
|
||||
JavaScriptObfuscator.obfuscate(
|
||||
StringArrayRotateFunctionTemplate().formatUnicorn({
|
||||
code,
|
||||
timesName,
|
||||
stringArrayName: this.stringArrayName,
|
||||
stringArrayRotateValue: Utils.decToHex(this.stringArrayRotateValue),
|
||||
whileFunctionName
|
||||
}),
|
||||
NO_CUSTOM_NODES_PRESET
|
||||
).getObfuscatedCode()
|
||||
);
|
||||
return JavaScriptObfuscator.obfuscate(
|
||||
format(StringArrayRotateFunctionTemplate(), {
|
||||
code,
|
||||
timesName,
|
||||
stringArrayName: this.stringArrayName,
|
||||
stringArrayRotateValue: Utils.decToHex(this.stringArrayRotateValue),
|
||||
whileFunctionName
|
||||
}),
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
seed: this.options.seed
|
||||
})
|
||||
).getObfuscatedCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
export const JSFuck: any = {
|
||||
Window: '[]["filter"]["constructor"]("return this")()',
|
||||
|
||||
False: '![]',
|
||||
True: '!![]',
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Utils } from '../Utils';
|
||||
|
||||
export const VisitorDirection: any = Utils.strEnumify({
|
||||
enter: 'enter',
|
||||
leave: 'leave'
|
||||
});
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { ICustomNode } from './custom-nodes/ICustomNode';
|
||||
import { IStorage } from './IStorage';
|
||||
|
||||
export interface IControlFlowReplacer {
|
||||
replace (
|
||||
node: ESTree.Node,
|
||||
parentNode: ESTree.Node,
|
||||
controlFlowStorage: IStorage <ICustomNode>,
|
||||
controlFlowStorageCustomNodeName: string
|
||||
): ICustomNode | undefined;
|
||||
}
|
||||
Vendored
-9
@@ -1,9 +0,0 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
export interface INodeObfuscator {
|
||||
/**
|
||||
* @param node
|
||||
* @param parentNode
|
||||
*/
|
||||
obfuscateNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
|
||||
}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
export interface INodeTransformer {
|
||||
transformNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { INodeTransformer } from './INodeTransformer';
|
||||
|
||||
export interface INodeTransformersFactory {
|
||||
initializeNodeTransformers (nodeType: string): INodeTransformer[];
|
||||
}
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
export interface IObfuscator {
|
||||
obfuscateNode (node: ESTree.Node): ESTree.Node;
|
||||
obfuscateAstTree (node: ESTree.Program): ESTree.Program;
|
||||
}
|
||||
|
||||
+2
@@ -3,12 +3,14 @@ import { TStringArrayEncoding } from '../types/TStringArrayEncoding';
|
||||
|
||||
export interface IObfuscatorOptions {
|
||||
compact?: boolean;
|
||||
controlFlowFlattening?: boolean;
|
||||
debugProtection?: boolean;
|
||||
debugProtectionInterval?: boolean;
|
||||
disableConsoleOutput?: boolean;
|
||||
domainLock?: string[];
|
||||
reservedNames?: string[];
|
||||
rotateStringArray?: boolean;
|
||||
seed?: number;
|
||||
selfDefending?: boolean;
|
||||
sourceMap?: boolean;
|
||||
sourceMapBaseUrl?: string;
|
||||
|
||||
Vendored
+2
@@ -3,12 +3,14 @@ import { TStringArrayEncoding } from '../types/TStringArrayEncoding';
|
||||
|
||||
export interface IOptions {
|
||||
readonly compact: boolean;
|
||||
readonly controlFlowFlattening: boolean;
|
||||
readonly debugProtection: boolean;
|
||||
readonly debugProtectionInterval: boolean;
|
||||
readonly disableConsoleOutput: boolean;
|
||||
readonly domainLock: string[];
|
||||
readonly reservedNames: string[];
|
||||
readonly rotateStringArray: boolean;
|
||||
readonly seed: number;
|
||||
readonly selfDefending: boolean;
|
||||
readonly sourceMap: boolean;
|
||||
readonly sourceMapBaseUrl: string;
|
||||
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
export interface IStorage <T> {
|
||||
get (key: string | number): T;
|
||||
getKeyOf (value: T): string | number | null;
|
||||
getLength (): number;
|
||||
getStorage (): any;
|
||||
set (key: string | number | null, value: T): void;
|
||||
toString (): string;
|
||||
}
|
||||
@@ -15,6 +15,11 @@ export interface ICustomNode {
|
||||
*/
|
||||
getAppendState (): AppendState;
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
getCode (): string;
|
||||
|
||||
/**
|
||||
* @returns ESTree.Node[]
|
||||
*/
|
||||
|
||||
@@ -5,9 +5,4 @@ export interface ICustomNodeWithData extends ICustomNode {
|
||||
* @returns any
|
||||
*/
|
||||
getNodeData (): any;
|
||||
|
||||
/**
|
||||
* @param data
|
||||
*/
|
||||
updateNodeData (data: any): void;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { IStackTraceData } from './IStackTraceData';
|
||||
|
||||
export interface IStackTraceAnalyzer {
|
||||
analyze (): IStackTraceData[];
|
||||
analyze (blockScopeBody: ESTree.Node[]): IStackTraceData[];
|
||||
}
|
||||
|
||||
@@ -9,17 +9,17 @@ export abstract class AbstractNodesGroup implements INodesGroup {
|
||||
/**
|
||||
* @type {AppendState}
|
||||
*/
|
||||
protected appendState: AppendState = AppendState.BeforeObfuscation;
|
||||
protected readonly appendState: AppendState = AppendState.BeforeObfuscation;
|
||||
|
||||
/**
|
||||
* @type {IStackTraceData[]}
|
||||
*/
|
||||
protected stackTraceData: IStackTraceData[];
|
||||
protected readonly stackTraceData: IStackTraceData[];
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
protected options: IOptions;
|
||||
protected readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @param stackTraceData
|
||||
|
||||
@@ -7,8 +7,9 @@ import { StringArrayNode } from '../custom-nodes/string-array-nodes/StringArrayN
|
||||
import { StringArrayRotateFunctionNode } from '../custom-nodes/string-array-nodes/StringArrayRotateFunctionNode';
|
||||
|
||||
import { AbstractNodesGroup } from './AbstractNodesGroup';
|
||||
import { StringArray } from '../StringArray';
|
||||
import { StringArrayStorage } from '../storages/string-array/StringArrayStorage';
|
||||
import { Utils } from '../Utils';
|
||||
import { IStorage } from '../interfaces/IStorage';
|
||||
|
||||
export class StringArrayNodesGroup extends AbstractNodesGroup {
|
||||
/**
|
||||
@@ -40,15 +41,12 @@ export class StringArrayNodesGroup extends AbstractNodesGroup {
|
||||
}
|
||||
|
||||
if (this.options.rotateStringArray) {
|
||||
this.stringArrayRotateValue = Utils.getRandomGenerator().integer({
|
||||
min: 100,
|
||||
max: 500
|
||||
});
|
||||
this.stringArrayRotateValue = Utils.getRandomInteger(100, 500);
|
||||
} else {
|
||||
this.stringArrayRotateValue = 0;
|
||||
}
|
||||
|
||||
const stringArray: StringArray = new StringArray();
|
||||
const stringArray: IStorage <string> = new StringArrayStorage();
|
||||
const stringArrayNode: ICustomNode = new StringArrayNode(
|
||||
stringArray,
|
||||
this.stringArrayName,
|
||||
|
||||
+6
-6
@@ -1,25 +1,25 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { INodeObfuscator } from '../interfaces/INodeObfuscator';
|
||||
import { INodeTransformer } from '../interfaces/INodeTransformer';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
|
||||
export abstract class AbstractNodeObfuscator implements INodeObfuscator {
|
||||
export abstract class AbstractNodeTransformer implements INodeTransformer {
|
||||
/**
|
||||
* @type Map <string, AbstractCustomNode>
|
||||
*/
|
||||
protected nodes: Map <string, ICustomNode>;
|
||||
protected readonly nodes: Map <string, ICustomNode>;
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
protected options: IOptions;
|
||||
protected readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
* @param options
|
||||
*/
|
||||
constructor(nodes: Map <string, ICustomNode>, options: IOptions) {
|
||||
constructor (nodes: Map <string, ICustomNode>, options: IOptions) {
|
||||
this.nodes = nodes;
|
||||
this.options = options;
|
||||
}
|
||||
@@ -28,5 +28,5 @@ export abstract class AbstractNodeObfuscator implements INodeObfuscator {
|
||||
* @param node
|
||||
* @param parentNode
|
||||
*/
|
||||
public abstract obfuscateNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
|
||||
public abstract transformNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { TNodeTransformer } from '../types/TNodeTransformer';
|
||||
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { INodeTransformer } from '../interfaces/INodeTransformer';
|
||||
import { INodeTransformersFactory } from '../interfaces/INodeTransformersFactory';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
|
||||
export abstract class AbstractNodeTransformersFactory implements INodeTransformersFactory {
|
||||
/**
|
||||
* @type {Map<string, TNodeTransformer[]>}
|
||||
*/
|
||||
protected abstract readonly nodeTransformers: Map <string, TNodeTransformer[]>;
|
||||
|
||||
/**
|
||||
* @type Map <string, AbstractCustomNode>
|
||||
*/
|
||||
protected readonly customNodes: Map <string, ICustomNode>;
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
protected readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @param customNodes
|
||||
* @param options
|
||||
*/
|
||||
constructor (customNodes: Map <string, ICustomNode>, options: IOptions) {
|
||||
this.customNodes = customNodes;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeType
|
||||
* @returns {INodeTransformer[]}
|
||||
*/
|
||||
public initializeNodeTransformers (nodeType: string): INodeTransformer[] {
|
||||
const nodeTransformers: TNodeTransformer[] = this.nodeTransformers.get(nodeType) || [];
|
||||
const instancesArray: INodeTransformer[] = [];
|
||||
|
||||
nodeTransformers.forEach((transformer: TNodeTransformer) => {
|
||||
instancesArray.push(
|
||||
new transformer(this.customNodes, this.options)
|
||||
);
|
||||
});
|
||||
|
||||
return instancesArray;
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TControlFlowReplacer } from '../../types/TControlFlowReplacer';
|
||||
import { TStatement } from '../../types/TStatement';
|
||||
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IStorage } from '../../interfaces/IStorage';
|
||||
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { BinaryExpressionControlFlowReplacer } from './control-flow-replacers/BinaryExpressionControlFlowReplacer';
|
||||
import { ControlFlowStorage } from '../../storages/control-flow/ControlFlowStorage';
|
||||
import { ControlFlowStorageNode } from '../../custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { Utils } from '../../Utils';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {Map <string, IReplacer>}
|
||||
*/
|
||||
private static readonly controlFlowReplacers: Map <string, TControlFlowReplacer> = new Map <string, TControlFlowReplacer> ([
|
||||
[NodeType.BinaryExpression, BinaryExpressionControlFlowReplacer]
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
* @param options
|
||||
*/
|
||||
constructor (nodes: Map <string, ICustomNode>, options: IOptions) {
|
||||
super(nodes, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param functionNode
|
||||
*/
|
||||
public transformNode (functionNode: ESTree.Function): void {
|
||||
this.changeFunctionBodyControlFlow(functionNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param functionNode
|
||||
*/
|
||||
private changeFunctionBodyControlFlow (functionNode: ESTree.Function): void {
|
||||
if (Node.isArrowFunctionExpressionNode(functionNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const controlFlowStorage: IStorage <ICustomNode> = new ControlFlowStorage();
|
||||
const controlFlowStorageCustomNodeName: string = Utils.getRandomVariableName(6);
|
||||
|
||||
console.log(NodeUtils.getNodeBlockScopeDepth(functionNode.body));
|
||||
|
||||
estraverse.replace(functionNode.body, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
|
||||
const controlFlowReplacer: TControlFlowReplacer | undefined = FunctionControlFlowTransformer
|
||||
.controlFlowReplacers.get(node.type);
|
||||
|
||||
if (!controlFlowReplacer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const controlFlowStorageCallCustomNode: ICustomNode | undefined = new controlFlowReplacer(
|
||||
this.nodes,
|
||||
this.options
|
||||
).replace(node, parentNode, controlFlowStorage, controlFlowStorageCustomNodeName);
|
||||
|
||||
if (!controlFlowStorageCallCustomNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// controlFlowStorageCallCustomNode will always have only one TStatement node,
|
||||
// so we can get it by index `0`
|
||||
// also we need to return `expression` property of `ExpressionStatement` node because bug:
|
||||
// https://github.com/estools/escodegen/issues/289
|
||||
const statementNode: TStatement | undefined = controlFlowStorageCallCustomNode.getNode()[0];
|
||||
|
||||
if (!statementNode || !Node.isExpressionStatementNode(statementNode)) {
|
||||
throw new Error(`\`controlFlowStorageCallCustomNode.getNode()\` should returns array with \`ExpressionStatement\` node`);
|
||||
}
|
||||
|
||||
return statementNode.expression;
|
||||
}
|
||||
});
|
||||
|
||||
const controlFlowStorageCustomNode: ICustomNode = new ControlFlowStorageNode(
|
||||
controlFlowStorage,
|
||||
controlFlowStorageCustomNodeName,
|
||||
this.options
|
||||
);
|
||||
|
||||
NodeAppender.prependNode(functionNode.body, controlFlowStorageCustomNode.getNode());
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { IControlFlowReplacer } from '../../../interfaces/IControlFlowReplacer';
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/IOptions';
|
||||
import { IStorage } from '../../../interfaces/IStorage';
|
||||
|
||||
import { Utils } from '../../../Utils';
|
||||
|
||||
export abstract class AbstractControlFlowReplacer implements IControlFlowReplacer {
|
||||
/**
|
||||
* @type Map <string, AbstractCustomNode>
|
||||
*/
|
||||
protected readonly nodes: Map <string, ICustomNode>;
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
protected readonly options : IOptions;
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
* @param options
|
||||
*/
|
||||
constructor (nodes: Map <string, ICustomNode>, options: IOptions) {
|
||||
this.nodes = nodes;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
protected static getStorageKey (): string {
|
||||
return Utils.getRandomGenerator().string({
|
||||
length: 3,
|
||||
pool: Utils.randomGeneratorPool
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param parentNode
|
||||
* @param controlFlowStorage
|
||||
* @param controlFlowStorageCustomNodeName
|
||||
* @returns {ICustomNode | undefined}
|
||||
*/
|
||||
public abstract replace (
|
||||
node: ESTree.Node,
|
||||
parentNode: ESTree.Node,
|
||||
controlFlowStorage: IStorage <ICustomNode>,
|
||||
controlFlowStorageCustomNodeName: string
|
||||
): ICustomNode | undefined;
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
import * as escodegen from 'escodegen';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IStorage } from '../../../interfaces/IStorage';
|
||||
|
||||
import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
|
||||
import { BinaryExpressionFunctionNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode';
|
||||
import { ControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode';
|
||||
|
||||
export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
|
||||
/**
|
||||
* @param expressionNode
|
||||
* @returns {string}
|
||||
*/
|
||||
private static getExpressionValue (expressionNode: ESTree.Expression): string {
|
||||
return escodegen.generate(expressionNode, {
|
||||
sourceMapWithCode: true
|
||||
}).code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param binaryExpressionNode
|
||||
* @param parentNode
|
||||
* @param controlFlowStorage
|
||||
* @param controlFlowStorageCustomNodeName
|
||||
* @returns {ICustomNode | undefined}
|
||||
*/
|
||||
public replace (
|
||||
binaryExpressionNode: ESTree.BinaryExpression,
|
||||
parentNode: ESTree.Node,
|
||||
controlFlowStorage: IStorage <ICustomNode>,
|
||||
controlFlowStorageCustomNodeName: string
|
||||
): ICustomNode | undefined {
|
||||
const key: string = AbstractControlFlowReplacer.getStorageKey();
|
||||
|
||||
controlFlowStorage.set(key, new BinaryExpressionFunctionNode(binaryExpressionNode.operator, this.options));
|
||||
|
||||
return new ControlFlowStorageCallNode(
|
||||
controlFlowStorageCustomNodeName,
|
||||
key,
|
||||
BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.left),
|
||||
BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.right),
|
||||
this.options
|
||||
);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { TNodeTransformer } from '../../../types/TNodeTransformer';
|
||||
|
||||
import { NodeType } from '../../../enums/NodeType';
|
||||
|
||||
import { FunctionControlFlowTransformer } from '../FunctionControlFlowTransformer';
|
||||
import { AbstractNodeTransformersFactory } from '../../AbstractNodeTransformersFactory';
|
||||
|
||||
export class NodeControlFlowTransformersFactory extends AbstractNodeTransformersFactory {
|
||||
/**
|
||||
* @type {Map<string, TNodeTransformer[]>}
|
||||
*/
|
||||
protected readonly nodeTransformers: Map <string, TNodeTransformer[]> = new Map <string, TNodeTransformer[]> ([
|
||||
[NodeType.FunctionDeclaration, [FunctionControlFlowTransformer]],
|
||||
[NodeType.FunctionExpression, [FunctionControlFlowTransformer]]
|
||||
]);
|
||||
}
|
||||
+10
-10
@@ -1,15 +1,15 @@
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { IdentifierReplacer } from './replacers/IdentifierReplacer';
|
||||
import { Node } from '../node/Node';
|
||||
import { NodeUtils } from '../node/NodeUtils';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -19,11 +19,11 @@ import { NodeUtils } from '../node/NodeUtils';
|
||||
* try {} catch (_0x12d45f) { console.log(_0x12d45f); };
|
||||
*
|
||||
*/
|
||||
export class CatchClauseObfuscator extends AbstractNodeObfuscator {
|
||||
export class CatchClauseObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {IdentifierReplacer}
|
||||
*/
|
||||
private identifierReplacer: IdentifierReplacer;
|
||||
private readonly identifierReplacer: IdentifierReplacer;
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
@@ -38,7 +38,7 @@ export class CatchClauseObfuscator extends AbstractNodeObfuscator {
|
||||
/**
|
||||
* @param catchClauseNode
|
||||
*/
|
||||
public obfuscateNode (catchClauseNode: ESTree.CatchClause): void {
|
||||
public transformNode (catchClauseNode: ESTree.CatchClause): void {
|
||||
this.storeCatchClauseParam(catchClauseNode);
|
||||
this.replaceCatchClauseParam(catchClauseNode);
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export class CatchClauseObfuscator extends AbstractNodeObfuscator {
|
||||
* @param catchClauseNode
|
||||
*/
|
||||
private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause): void {
|
||||
NodeUtils.typedReplace(catchClauseNode.param, NodeType.Identifier, {
|
||||
NodeUtils.typedTraverse(catchClauseNode.param, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name)
|
||||
});
|
||||
}
|
||||
+11
-11
@@ -1,17 +1,17 @@
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../types/TNodeWithBlockStatement';
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { IdentifierReplacer } from './replacers/IdentifierReplacer';
|
||||
import { Node } from '../node/Node';
|
||||
import { NodeUtils } from '../node/NodeUtils';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -22,11 +22,11 @@ import { NodeUtils } from '../node/NodeUtils';
|
||||
* function _0x12d45f () { //... };
|
||||
* _0x12d45f();
|
||||
*/
|
||||
export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator {
|
||||
export class FunctionDeclarationObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {IdentifierReplacer}
|
||||
*/
|
||||
private identifierReplacer: IdentifierReplacer;
|
||||
private readonly identifierReplacer: IdentifierReplacer;
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
@@ -42,7 +42,7 @@ export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator {
|
||||
* @param functionDeclarationNode
|
||||
* @param parentNode
|
||||
*/
|
||||
public obfuscateNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): void {
|
||||
public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): void {
|
||||
const blockScopeOfFunctionDeclarationNode: TNodeWithBlockStatement = NodeUtils
|
||||
.getBlockScopeOfNode(functionDeclarationNode);
|
||||
|
||||
@@ -58,7 +58,7 @@ export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator {
|
||||
* @param functionDeclarationNode
|
||||
*/
|
||||
private storeFunctionName (functionDeclarationNode: ESTree.FunctionDeclaration): void {
|
||||
NodeUtils.typedReplace(functionDeclarationNode.id, NodeType.Identifier, {
|
||||
NodeUtils.typedTraverse(functionDeclarationNode.id, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name)
|
||||
});
|
||||
}
|
||||
+13
-16
@@ -1,15 +1,15 @@
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { IdentifierReplacer } from './replacers/IdentifierReplacer';
|
||||
import { Node } from '../node/Node';
|
||||
import { NodeUtils } from '../node/NodeUtils';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -19,11 +19,11 @@ import { NodeUtils } from '../node/NodeUtils';
|
||||
* function foo (_0x12d45f) { return _0x12d45f; };
|
||||
*
|
||||
*/
|
||||
export class FunctionObfuscator extends AbstractNodeObfuscator {
|
||||
export class FunctionObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {IdentifierReplacer}
|
||||
*/
|
||||
private identifierReplacer: IdentifierReplacer;
|
||||
private readonly identifierReplacer: IdentifierReplacer;
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
@@ -38,7 +38,7 @@ export class FunctionObfuscator extends AbstractNodeObfuscator {
|
||||
/**
|
||||
* @param functionNode
|
||||
*/
|
||||
public obfuscateNode (functionNode: ESTree.Function): void {
|
||||
public transformNode (functionNode: ESTree.Function): void {
|
||||
this.storeFunctionParams(functionNode);
|
||||
this.replaceFunctionParams(functionNode);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export class FunctionObfuscator extends AbstractNodeObfuscator {
|
||||
private storeFunctionParams (functionNode: ESTree.Function): void {
|
||||
functionNode.params
|
||||
.forEach((paramsNode: ESTree.Node) => {
|
||||
NodeUtils.typedReplace(paramsNode, NodeType.Identifier, {
|
||||
NodeUtils.typedTraverse(paramsNode, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name)
|
||||
});
|
||||
});
|
||||
@@ -59,7 +59,7 @@ export class FunctionObfuscator extends AbstractNodeObfuscator {
|
||||
* @param functionNode
|
||||
*/
|
||||
private replaceFunctionParams (functionNode: ESTree.Function): void {
|
||||
let replaceVisitor: estraverse.Visitor = {
|
||||
let traverseVisitor: estraverse.Visitor = {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
|
||||
if (Node.isReplaceableIdentifierNode(node, parentNode)) {
|
||||
const newNodeName: string = this.identifierReplacer.replace(node.name);
|
||||
@@ -72,11 +72,8 @@ export class FunctionObfuscator extends AbstractNodeObfuscator {
|
||||
}
|
||||
};
|
||||
|
||||
functionNode.params
|
||||
.forEach((paramsNode: ESTree.Node) => {
|
||||
estraverse.replace(paramsNode, replaceVisitor);
|
||||
});
|
||||
functionNode.params.forEach((paramsNode: ESTree.Node) => estraverse.replace(paramsNode, traverseVisitor));
|
||||
|
||||
estraverse.replace(functionNode.body, replaceVisitor);
|
||||
estraverse.replace(functionNode.body, traverseVisitor);
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -1,15 +1,15 @@
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { IdentifierReplacer } from './replacers/IdentifierReplacer';
|
||||
import { Node } from '../node/Node';
|
||||
import { NodeUtils } from '../node/NodeUtils';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -27,11 +27,11 @@ import { NodeUtils } from '../node/NodeUtils';
|
||||
* }
|
||||
*
|
||||
*/
|
||||
export class LabeledStatementObfuscator extends AbstractNodeObfuscator {
|
||||
export class LabeledStatementObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {IdentifierReplacer}
|
||||
*/
|
||||
private identifierReplacer: IdentifierReplacer;
|
||||
private readonly identifierReplacer: IdentifierReplacer;
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
@@ -46,7 +46,7 @@ export class LabeledStatementObfuscator extends AbstractNodeObfuscator {
|
||||
/**
|
||||
* @param labeledStatementNode
|
||||
*/
|
||||
public obfuscateNode (labeledStatementNode: ESTree.LabeledStatement): void {
|
||||
public transformNode (labeledStatementNode: ESTree.LabeledStatement): void {
|
||||
this.storeLabeledStatementName(labeledStatementNode);
|
||||
this.replaceLabeledStatementName(labeledStatementNode);
|
||||
}
|
||||
@@ -55,7 +55,7 @@ export class LabeledStatementObfuscator extends AbstractNodeObfuscator {
|
||||
* @param labeledStatementNode
|
||||
*/
|
||||
private storeLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement): void {
|
||||
NodeUtils.typedReplace(labeledStatementNode.label, NodeType.Identifier, {
|
||||
NodeUtils.typedTraverse(labeledStatementNode.label, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name)
|
||||
});
|
||||
}
|
||||
+5
-5
@@ -1,18 +1,18 @@
|
||||
import * as escodegen from 'escodegen';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { BooleanLiteralReplacer } from './replacers/BooleanLiteralReplacer';
|
||||
import { Node } from '../node/Node';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NumberLiteralReplacer } from './replacers/NumberLiteralReplacer';
|
||||
import { StringLiteralReplacer } from './replacers/StringLiteralReplacer';
|
||||
|
||||
export class LiteralObfuscator extends AbstractNodeObfuscator {
|
||||
export class LiteralObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @param literalNode
|
||||
* @param parentNode
|
||||
*/
|
||||
public obfuscateNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void {
|
||||
public transformNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void {
|
||||
if (Node.isPropertyNode(parentNode) && parentNode.key === literalNode) {
|
||||
return;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ export class LiteralObfuscator extends AbstractNodeObfuscator {
|
||||
|
||||
case 'string':
|
||||
content = new StringLiteralReplacer(this.nodes, this.options)
|
||||
.replace(<string>literalNode.value);
|
||||
.replace(<string>literalNode.value);
|
||||
|
||||
break;
|
||||
|
||||
+16
-16
@@ -2,18 +2,18 @@ import * as escodegen from 'escodegen';
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { Node } from '../node/Node';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { Node } from '../../node/Node';
|
||||
import { StringLiteralReplacer } from './replacers/StringLiteralReplacer';
|
||||
|
||||
export class MemberExpressionObfuscator extends AbstractNodeObfuscator {
|
||||
export class MemberExpressionObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @param memberExpressionNode
|
||||
*/
|
||||
public obfuscateNode (memberExpressionNode: ESTree.MemberExpression): void {
|
||||
estraverse.replace(memberExpressionNode.property, {
|
||||
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);
|
||||
@@ -46,16 +46,16 @@ export class MemberExpressionObfuscator extends AbstractNodeObfuscator {
|
||||
* @param node
|
||||
*/
|
||||
private obfuscateIdentifierProperty (node: ESTree.Identifier): void {
|
||||
let nodeValue: string = node.name,
|
||||
literalNode: ESTree.Literal = {
|
||||
raw: `'${nodeValue}'`,
|
||||
'x-verbatim-property': {
|
||||
content : new StringLiteralReplacer(this.nodes, this.options).replace(nodeValue),
|
||||
precedence: escodegen.Precedence.Primary
|
||||
},
|
||||
type: NodeType.Literal,
|
||||
value: nodeValue
|
||||
};
|
||||
const nodeValue: string = node.name;
|
||||
const literalNode: ESTree.Literal = {
|
||||
raw: `'${nodeValue}'`,
|
||||
'x-verbatim-property': {
|
||||
content : new StringLiteralReplacer(this.nodes, this.options).replace(nodeValue),
|
||||
precedence: escodegen.Precedence.Primary
|
||||
},
|
||||
type: NodeType.Literal,
|
||||
value: nodeValue
|
||||
};
|
||||
|
||||
delete node.name;
|
||||
|
||||
+6
-6
@@ -1,9 +1,9 @@
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { Node } from '../node/Node';
|
||||
import { Utils } from '../Utils';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { Node } from '../../node/Node';
|
||||
import { Utils } from '../../Utils';
|
||||
import { StringLiteralReplacer } from './replacers/StringLiteralReplacer';
|
||||
|
||||
/**
|
||||
@@ -13,17 +13,17 @@ import { StringLiteralReplacer } from './replacers/StringLiteralReplacer';
|
||||
* on:
|
||||
* [_0x9a4e('0x0')] { //... };
|
||||
*/
|
||||
export class MethodDefinitionObfuscator extends AbstractNodeObfuscator {
|
||||
export class MethodDefinitionObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
private static ignoredNames: string[] = ['constructor'];
|
||||
private static readonly ignoredNames: string[] = ['constructor'];
|
||||
|
||||
/**
|
||||
* @param methodDefinitionNode
|
||||
* @param parentNode
|
||||
*/
|
||||
public obfuscateNode (methodDefinitionNode: ESTree.MethodDefinition, parentNode: ESTree.Node): void {
|
||||
public transformNode (methodDefinitionNode: ESTree.MethodDefinition, parentNode: ESTree.Node): void {
|
||||
this.replaceMethodName(methodDefinitionNode);
|
||||
}
|
||||
|
||||
+17
-17
@@ -2,11 +2,11 @@ import * as escodegen from 'escodegen';
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { Node } from '../node/Node';
|
||||
import { Utils } from '../Utils';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { Node } from '../../node/Node';
|
||||
import { Utils } from '../../Utils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -18,18 +18,18 @@ import { Utils } from '../Utils';
|
||||
* on:
|
||||
* var object = { '\u0050\u0053\u0045\u0055\u0044\u004f': 1 };
|
||||
*/
|
||||
export class ObjectExpressionObfuscator extends AbstractNodeObfuscator {
|
||||
export class ObjectExpressionObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @param objectExpressionNode
|
||||
*/
|
||||
public obfuscateNode (objectExpressionNode: ESTree.ObjectExpression): void {
|
||||
public transformNode (objectExpressionNode: ESTree.ObjectExpression): void {
|
||||
objectExpressionNode.properties
|
||||
.forEach((property: ESTree.Property) => {
|
||||
if (property.shorthand) {
|
||||
property.shorthand = false;
|
||||
}
|
||||
|
||||
estraverse.replace(property.key, {
|
||||
estraverse.traverse(property.key, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
|
||||
if (Node.isLiteralNode(node)) {
|
||||
this.obfuscateLiteralPropertyKey(node);
|
||||
@@ -61,16 +61,16 @@ export class ObjectExpressionObfuscator extends AbstractNodeObfuscator {
|
||||
* @param node
|
||||
*/
|
||||
private obfuscateIdentifierPropertyKey (node: ESTree.Identifier): void {
|
||||
let nodeValue: string = node.name,
|
||||
literalNode: ESTree.Literal = {
|
||||
raw: `'${nodeValue}'`,
|
||||
'x-verbatim-property': {
|
||||
content : `'${Utils.stringToUnicodeEscapeSequence(nodeValue)}'`,
|
||||
precedence: escodegen.Precedence.Primary
|
||||
},
|
||||
type: NodeType.Literal,
|
||||
value: nodeValue
|
||||
};
|
||||
const nodeValue: string = node.name;
|
||||
const literalNode: ESTree.Literal = {
|
||||
raw: `'${nodeValue}'`,
|
||||
'x-verbatim-property': {
|
||||
content : `'${Utils.stringToUnicodeEscapeSequence(nodeValue)}'`,
|
||||
precedence: escodegen.Precedence.Primary
|
||||
},
|
||||
type: NodeType.Literal,
|
||||
value: nodeValue
|
||||
};
|
||||
|
||||
delete node.name;
|
||||
|
||||
+11
-11
@@ -1,17 +1,17 @@
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../types/TNodeWithBlockStatement';
|
||||
import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
|
||||
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { IdentifierReplacer } from './replacers/IdentifierReplacer';
|
||||
import { Node } from '../node/Node';
|
||||
import { NodeUtils } from '../node/NodeUtils';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -23,11 +23,11 @@ import { NodeUtils } from '../node/NodeUtils';
|
||||
* _0x12d45f++;
|
||||
*
|
||||
*/
|
||||
export class VariableDeclarationObfuscator extends AbstractNodeObfuscator {
|
||||
export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {IdentifierReplacer}
|
||||
*/
|
||||
private identifierReplacer: IdentifierReplacer;
|
||||
private readonly identifierReplacer: IdentifierReplacer;
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
@@ -43,7 +43,7 @@ export class VariableDeclarationObfuscator extends AbstractNodeObfuscator {
|
||||
* @param variableDeclarationNode
|
||||
* @param parentNode
|
||||
*/
|
||||
public obfuscateNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void {
|
||||
public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void {
|
||||
const blockScopeOfVariableDeclarationNode: TNodeWithBlockStatement = NodeUtils
|
||||
.getBlockScopeOfNode(variableDeclarationNode);
|
||||
|
||||
@@ -65,7 +65,7 @@ export class VariableDeclarationObfuscator extends AbstractNodeObfuscator {
|
||||
private storeVariableNames (variableDeclarationNode: ESTree.VariableDeclaration): void {
|
||||
variableDeclarationNode.declarations
|
||||
.forEach((declarationNode: ESTree.VariableDeclarator) => {
|
||||
NodeUtils.typedReplace(declarationNode.id, NodeType.Identifier, {
|
||||
NodeUtils.typedTraverse(declarationNode.id, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name)
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { TNodeTransformer } from '../../../types/TNodeTransformer';
|
||||
|
||||
import { NodeType } from '../../../enums/NodeType';
|
||||
|
||||
import { CatchClauseObfuscator } from '../CatchClauseObfuscator';
|
||||
import { FunctionDeclarationObfuscator } from '../FunctionDeclarationObfuscator';
|
||||
import { FunctionObfuscator } from '../FunctionObfuscator';
|
||||
import { LabeledStatementObfuscator } from '../LabeledStatementObfuscator';
|
||||
import { LiteralObfuscator } from '../LiteralObfuscator';
|
||||
import { MemberExpressionObfuscator } from '../MemberExpressionObfuscator';
|
||||
import { MethodDefinitionObfuscator } from '../MethodDefinitionObfuscator';
|
||||
import { ObjectExpressionObfuscator } from '../ObjectExpressionObfuscator';
|
||||
import { VariableDeclarationObfuscator } from '../VariableDeclarationObfuscator';
|
||||
import { AbstractNodeTransformersFactory } from '../../AbstractNodeTransformersFactory';
|
||||
|
||||
export class NodeObfuscatorsFactory extends AbstractNodeTransformersFactory {
|
||||
/**
|
||||
* @type {Map<string, TNodeTransformer[]>}
|
||||
*/
|
||||
protected readonly nodeTransformers: Map <string, TNodeTransformer[]> = new Map <string, TNodeTransformer[]> ([
|
||||
[NodeType.ArrowFunctionExpression, [FunctionObfuscator]],
|
||||
[NodeType.ClassDeclaration, [FunctionDeclarationObfuscator]],
|
||||
[NodeType.CatchClause, [CatchClauseObfuscator]],
|
||||
[NodeType.FunctionDeclaration, [
|
||||
FunctionDeclarationObfuscator,
|
||||
FunctionObfuscator
|
||||
]],
|
||||
[NodeType.FunctionExpression, [FunctionObfuscator]],
|
||||
[NodeType.MemberExpression, [MemberExpressionObfuscator]],
|
||||
[NodeType.MethodDefinition, [MethodDefinitionObfuscator]],
|
||||
[NodeType.ObjectExpression, [ObjectExpressionObfuscator]],
|
||||
[NodeType.VariableDeclaration, [VariableDeclarationObfuscator]],
|
||||
[NodeType.LabeledStatement, [LabeledStatementObfuscator]],
|
||||
[NodeType.Literal, [LiteralObfuscator]]
|
||||
]);
|
||||
}
|
||||
+5
-5
@@ -1,17 +1,17 @@
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/IOptions';
|
||||
import { IReplacer } from '../../interfaces/IReplacer';
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/IOptions';
|
||||
import { IReplacer } from '../../../interfaces/IReplacer';
|
||||
|
||||
export abstract class AbstractReplacer implements IReplacer {
|
||||
/**
|
||||
* @type Map <string, AbstractCustomNode>
|
||||
*/
|
||||
protected nodes: Map <string, ICustomNode>;
|
||||
protected readonly nodes: Map <string, ICustomNode>;
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
protected options : IOptions;
|
||||
protected readonly options : IOptions;
|
||||
|
||||
/**
|
||||
* @param nodes
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { JSFuck } from '../../enums/JSFuck';
|
||||
import { JSFuck } from '../../../enums/JSFuck';
|
||||
|
||||
import { AbstractReplacer } from './AbstractReplacer';
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { AbstractReplacer } from './AbstractReplacer';
|
||||
import { Utils } from '../../Utils';
|
||||
import { Utils } from '../../../Utils';
|
||||
|
||||
export class IdentifierReplacer extends AbstractReplacer {
|
||||
/**
|
||||
* @type {Map<string, string>}
|
||||
*/
|
||||
private namesMap: Map<string, string> = new Map<string, string>();
|
||||
private readonly namesMap: Map<string, string> = new Map<string, string>();
|
||||
|
||||
/**
|
||||
* @param nodeValue
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { AbstractReplacer } from './AbstractReplacer';
|
||||
import { Utils } from '../../Utils';
|
||||
import { Utils } from '../../../Utils';
|
||||
|
||||
export class NumberLiteralReplacer extends AbstractReplacer {
|
||||
/**
|
||||
+17
-19
@@ -1,23 +1,23 @@
|
||||
import { TStringArrayCallsWrapper } from '../../types/custom-nodes/TStringArrayCallsWrapper';
|
||||
import { TStringArrayNode } from '../../types/custom-nodes/TStringArrayNode';
|
||||
import { ICustomNodeWithData } from '../../../interfaces/custom-nodes/ICustomNodeWithData';
|
||||
import { IStorage } from '../../../interfaces/IStorage';
|
||||
|
||||
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
|
||||
import { StringArrayEncoding } from '../../../enums/StringArrayEncoding';
|
||||
|
||||
import { AbstractReplacer } from './AbstractReplacer';
|
||||
import { NumberLiteralReplacer } from './NumberLiteralReplacer';
|
||||
import { StringArray } from '../../StringArray';
|
||||
import { Utils } from '../../Utils';
|
||||
import { Utils } from '../../../Utils';
|
||||
import { ICustomNodeWithIdentifier } from '../../../interfaces/custom-nodes/ICustomNodeWithIdentifier';
|
||||
|
||||
export class StringLiteralReplacer extends AbstractReplacer {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
private static minimumLengthForStringArray: number = 3;
|
||||
private static readonly minimumLengthForStringArray: number = 3;
|
||||
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
private static rc4Keys: string[] = Utils.getRandomGenerator()
|
||||
private static readonly rc4Keys: string[] = Utils.getRandomGenerator()
|
||||
.n(() => Utils.getRandomGenerator().string({length: 4}), 50);
|
||||
|
||||
/**
|
||||
@@ -27,7 +27,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
|
||||
public replace (nodeValue: string): string {
|
||||
const replaceWithStringArrayFlag: boolean = (
|
||||
nodeValue.length >= StringLiteralReplacer.minimumLengthForStringArray
|
||||
&& Math.random() <= this.options.stringArrayThreshold
|
||||
&& Utils.getRandomFloat(0, 1) <= this.options.stringArrayThreshold
|
||||
);
|
||||
|
||||
if (this.options.stringArray && replaceWithStringArrayFlag) {
|
||||
@@ -42,10 +42,10 @@ export class StringLiteralReplacer extends AbstractReplacer {
|
||||
* @returns {string}
|
||||
*/
|
||||
private replaceStringLiteralWithStringArrayCall (value: string): string {
|
||||
const stringArrayNode: TStringArrayNode = <TStringArrayNode>this.nodes.get('stringArrayNode');
|
||||
const stringArrayNode: ICustomNodeWithData = <ICustomNodeWithData>this.nodes.get('stringArrayNode');
|
||||
|
||||
if (!stringArrayNode) {
|
||||
throw new ReferenceError('`stringArrayNode` node is not found in Map with custom node.');
|
||||
throw new ReferenceError('`stringArrayNode` node is not found in Map with custom nodes.');
|
||||
}
|
||||
|
||||
let rc4Key: string = '';
|
||||
@@ -67,22 +67,20 @@ export class StringLiteralReplacer extends AbstractReplacer {
|
||||
value = Utils.stringToUnicodeEscapeSequence(value);
|
||||
}
|
||||
|
||||
let stringArray: StringArray = stringArrayNode.getNodeData(),
|
||||
indexOfExistingValue: number = stringArray.getIndexOf(value),
|
||||
indexOfValue: number,
|
||||
hexadecimalIndex: string;
|
||||
const stringArray: IStorage <string> = stringArrayNode.getNodeData();
|
||||
const indexOfExistingValue: number = <number>stringArray.getKeyOf(value);
|
||||
|
||||
let indexOfValue: number;
|
||||
|
||||
if (indexOfExistingValue >= 0) {
|
||||
indexOfValue = indexOfExistingValue;
|
||||
} else {
|
||||
indexOfValue = stringArray.getLength();
|
||||
stringArrayNode.updateNodeData(value);
|
||||
stringArray.set(null, value);
|
||||
}
|
||||
|
||||
hexadecimalIndex = new NumberLiteralReplacer(this.nodes, this.options)
|
||||
.replace(indexOfValue);
|
||||
|
||||
const stringArrayCallsWrapper: TStringArrayCallsWrapper = <TStringArrayCallsWrapper>this.nodes.get('stringArrayCallsWrapper');
|
||||
const stringArrayCallsWrapper: ICustomNodeWithIdentifier = <ICustomNodeWithIdentifier>this.nodes.get('stringArrayCallsWrapper');
|
||||
const hexadecimalIndex: string = new NumberLiteralReplacer(this.nodes, this.options).replace(indexOfValue);
|
||||
|
||||
if (!stringArrayCallsWrapper) {
|
||||
throw new ReferenceError('`stringArrayCallsWrapper` node is not found in Map with custom node.');
|
||||
@@ -101,10 +101,7 @@ export class NodeAppender {
|
||||
* @param stackTraceRootLength
|
||||
*/
|
||||
public static getRandomStackTraceIndex (stackTraceRootLength: number): number {
|
||||
return Utils.getRandomGenerator().integer({
|
||||
min: 0,
|
||||
max: Math.max(0, Math.round(stackTraceRootLength - 1))
|
||||
});
|
||||
return Utils.getRandomInteger(0, Math.max(0, Math.round(stackTraceRootLength - 1)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+26
-3
@@ -15,7 +15,7 @@ export class NodeUtils {
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
private static nodesWithBlockScope: string[] = [
|
||||
private static readonly nodesWithBlockScope: string[] = [
|
||||
NodeType.ArrowFunctionExpression,
|
||||
NodeType.FunctionDeclaration,
|
||||
NodeType.FunctionExpression,
|
||||
@@ -42,7 +42,7 @@ export class NodeUtils {
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
public static convertCodeToStructure (code: string): TStatement[] {
|
||||
let structure: ESTree.Program = esprima.parse(code);
|
||||
const structure: ESTree.Program = esprima.parse(code);
|
||||
|
||||
NodeUtils.addXVerbatimPropertyToLiterals(structure);
|
||||
NodeUtils.parentize(structure);
|
||||
@@ -73,7 +73,7 @@ export class NodeUtils {
|
||||
* @returns {ESTree.Node}
|
||||
*/
|
||||
public static getBlockScopeOfNode (node: ESTree.Node, depth: number = 0): TNodeWithBlockStatement {
|
||||
let parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
@@ -100,6 +100,29 @@ export class NodeUtils {
|
||||
return NodeUtils.getBlockScopeOfNode(parentNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param depth
|
||||
* @returns {number}
|
||||
*/
|
||||
public static getNodeBlockScopeDepth (node: ESTree.Node, depth: number = 0): number {
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
if (Node.isProgramNode(parentNode)) {
|
||||
return depth;
|
||||
}
|
||||
|
||||
if (Node.isBlockStatementNode(node)) {
|
||||
return NodeUtils.getNodeBlockScopeDepth(parentNode, ++depth);
|
||||
}
|
||||
|
||||
return NodeUtils.getNodeBlockScopeDepth(parentNode, depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
*/
|
||||
|
||||
+13
-1
@@ -41,6 +41,12 @@ export class Options implements IOptions {
|
||||
@IsBoolean()
|
||||
public readonly compact: boolean;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@IsBoolean()
|
||||
public readonly controlFlowFlattening: boolean;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@@ -85,6 +91,12 @@ export class Options implements IOptions {
|
||||
@IsBoolean()
|
||||
public readonly rotateStringArray: boolean;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
@IsNumber()
|
||||
public readonly seed: number;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@@ -152,7 +164,7 @@ export class Options implements IOptions {
|
||||
constructor (obfuscatorOptions: IObfuscatorOptions) {
|
||||
Object.assign(this, DEFAULT_PRESET, obfuscatorOptions);
|
||||
|
||||
let errors: ValidationError[] = validateSync(this, Options.validatorOptions);
|
||||
const errors: ValidationError[] = validateSync(this, Options.validatorOptions);
|
||||
|
||||
if (errors.length) {
|
||||
throw new ReferenceError(`Validation failed. errors:\n${ValidationErrorsFormatter.format(errors)}`);
|
||||
|
||||
@@ -9,7 +9,7 @@ export class OptionsNormalizer {
|
||||
/**
|
||||
* @type {IObfuscatorOptions}
|
||||
*/
|
||||
private static DISABLED_UNICODE_ARRAY_OPTIONS: IObfuscatorOptions = {
|
||||
private static readonly DISABLED_UNICODE_ARRAY_OPTIONS: IObfuscatorOptions = {
|
||||
rotateStringArray: false,
|
||||
stringArray: false,
|
||||
stringArrayEncoding: false,
|
||||
@@ -19,7 +19,7 @@ export class OptionsNormalizer {
|
||||
/**
|
||||
* @type {IObfuscatorOptions}
|
||||
*/
|
||||
private static SELF_DEFENDING_OPTIONS: IObfuscatorOptions = {
|
||||
private static readonly SELF_DEFENDING_OPTIONS: IObfuscatorOptions = {
|
||||
compact: true,
|
||||
selfDefending: true
|
||||
};
|
||||
@@ -27,14 +27,14 @@ export class OptionsNormalizer {
|
||||
/**
|
||||
* @type {IObfuscatorOptions}
|
||||
*/
|
||||
private static UNICODE_ARRAY_ENCODING_OPTIONS: IObfuscatorOptions = {
|
||||
private static readonly UNICODE_ARRAY_ENCODING_OPTIONS: IObfuscatorOptions = {
|
||||
stringArrayEncoding: 'base64'
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {TOptionsNormalizerRule[]}
|
||||
*/
|
||||
private static normalizerRules: TOptionsNormalizerRule[] = [
|
||||
private static readonly normalizerRules: TOptionsNormalizerRule[] = [
|
||||
OptionsNormalizer.domainLockRule,
|
||||
OptionsNormalizer.selfDefendingRule,
|
||||
OptionsNormalizer.sourceMapBaseUrlRule,
|
||||
@@ -64,7 +64,7 @@ export class OptionsNormalizer {
|
||||
*/
|
||||
private static domainLockRule (options: IOptions): IOptions {
|
||||
if (options.domainLock.length) {
|
||||
let normalizedDomains: string[] = [];
|
||||
const normalizedDomains: string[] = [];
|
||||
|
||||
for (const domain of options.domainLock) {
|
||||
normalizedDomains.push(Utils.extractDomainFromUrl(domain));
|
||||
@@ -95,7 +95,7 @@ export class OptionsNormalizer {
|
||||
* @returns {IOptions}
|
||||
*/
|
||||
private static sourceMapBaseUrlRule (options: IOptions): IOptions {
|
||||
let sourceMapBaseUrl: string = options.sourceMapBaseUrl;
|
||||
const sourceMapBaseUrl: string = options.sourceMapBaseUrl;
|
||||
|
||||
if (!options.sourceMapFileName) {
|
||||
Object.assign(options, {
|
||||
|
||||
@@ -6,7 +6,7 @@ export class ValidationErrorsFormatter {
|
||||
* @returns {string}
|
||||
*/
|
||||
public static format (validationErrors: ValidationError[]): string {
|
||||
let errorsArray: string[] = [];
|
||||
const errorsArray: string[] = [];
|
||||
|
||||
for (const error of validationErrors) {
|
||||
errorsArray.push(ValidationErrorsFormatter.formatError(error));
|
||||
@@ -20,8 +20,9 @@ export class ValidationErrorsFormatter {
|
||||
* @returns {string}
|
||||
*/
|
||||
private static formatError (validationError: ValidationError): string {
|
||||
let errorString: string = `\`${validationError.property}\` errors:\n`,
|
||||
constraints: {[type: string]: string} = validationError.constraints;
|
||||
const constraints: {[type: string]: string} = validationError.constraints;
|
||||
|
||||
let errorString: string = `\`${validationError.property}\` errors:\n`;
|
||||
|
||||
for (const constraint in constraints) {
|
||||
if (!constraints.hasOwnProperty(constraint)) {
|
||||
|
||||
@@ -4,12 +4,14 @@ import { SourceMapMode } from '../enums/SourceMapMode';
|
||||
|
||||
export const DEFAULT_PRESET: IObfuscatorOptions = Object.freeze({
|
||||
compact: true,
|
||||
controlFlowFlattening: false,
|
||||
debugProtection: false,
|
||||
debugProtectionInterval: false,
|
||||
disableConsoleOutput: true,
|
||||
domainLock: [],
|
||||
reservedNames: [],
|
||||
rotateStringArray: true,
|
||||
seed: 0,
|
||||
selfDefending: true,
|
||||
sourceMap: false,
|
||||
sourceMapBaseUrl: '',
|
||||
|
||||
@@ -4,12 +4,14 @@ import { SourceMapMode } from '../enums/SourceMapMode';
|
||||
|
||||
export const NO_CUSTOM_NODES_PRESET: IObfuscatorOptions = Object.freeze({
|
||||
compact: true,
|
||||
controlFlowFlattening: false,
|
||||
debugProtection: false,
|
||||
debugProtectionInterval: false,
|
||||
disableConsoleOutput: false,
|
||||
domainLock: [],
|
||||
reservedNames: [],
|
||||
rotateStringArray: false,
|
||||
seed: 0,
|
||||
selfDefending: false,
|
||||
sourceMap: false,
|
||||
sourceMapBaseUrl: '',
|
||||
|
||||
@@ -51,34 +51,22 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
private static limitThresholdActivationLength: number = 25;
|
||||
private static readonly limitThresholdActivationLength: number = 25;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
private static limitThreshold: number = 0.002;
|
||||
|
||||
/**
|
||||
* @type {ESTree.Node[]}
|
||||
*/
|
||||
private blockScopeBody: ESTree.Node[];
|
||||
private static readonly limitThreshold: number = 0.002;
|
||||
|
||||
/**
|
||||
* @type {Map<string, TCalleeDataExtractor>}
|
||||
*/
|
||||
private calleeDataExtractors: Map <string, TCalleeDataExtractor> = new Map <string, TCalleeDataExtractor> ([
|
||||
private readonly calleeDataExtractors: Map <string, TCalleeDataExtractor> = new Map <string, TCalleeDataExtractor> ([
|
||||
[NodeType.FunctionDeclaration, FunctionDeclarationCalleeDataExtractor],
|
||||
[NodeType.FunctionExpression, FunctionExpressionCalleeDataExtractor],
|
||||
[NodeType.ObjectExpression, ObjectExpressionCalleeDataExtractor]
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param blockScopeBody
|
||||
*/
|
||||
constructor (blockScopeBody: ESTree.Node[]) {
|
||||
this.blockScopeBody = blockScopeBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockScopeBodyLength
|
||||
* @returns {number}
|
||||
@@ -103,10 +91,11 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockScopeBody
|
||||
* @returns {IStackTraceData[]}
|
||||
*/
|
||||
public analyze (): IStackTraceData[] {
|
||||
return this.analyzeRecursive(this.blockScopeBody);
|
||||
public analyze (blockScopeBody: ESTree.Node[]): IStackTraceData[] {
|
||||
return this.analyzeRecursive(blockScopeBody);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +111,7 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
|
||||
index < blockScopeBodyLength;
|
||||
index++
|
||||
) {
|
||||
let rootNode: ESTree.Node = blockScopeBody[index];
|
||||
const rootNode: ESTree.Node = blockScopeBody[index];
|
||||
|
||||
if (index > limitIndex) {
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { IStorage } from '../interfaces/IStorage';
|
||||
|
||||
export abstract class ArrayStorage <T> implements IStorage <T> {
|
||||
/**
|
||||
* @type {T[]}
|
||||
*/
|
||||
protected storage: T[] = [];
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @returns {T}
|
||||
*/
|
||||
public get (key: number): T {
|
||||
const value: T | undefined = this.storage[key];
|
||||
|
||||
if (!value) {
|
||||
throw new Error(`No value found in array storage with key \`${key}\``);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* @returns {string | number}
|
||||
*/
|
||||
public getKeyOf (value: T): string | number {
|
||||
return this.storage.indexOf(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
public getLength (): number {
|
||||
return this.storage.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {T[]}
|
||||
*/
|
||||
public getStorage (): T[] {
|
||||
return this.storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public set (key: string | null, value: T): void {
|
||||
this.storage.push(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { IStorage } from '../interfaces/IStorage';
|
||||
|
||||
import { Utils } from '../Utils';
|
||||
|
||||
export abstract class MapStorage <T> implements IStorage <T> {
|
||||
/**
|
||||
* @type {Map <string | number, T>}
|
||||
*/
|
||||
protected storage: Map <string | number, T> = new Map <string | number, T> ();
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @returns {T}
|
||||
*/
|
||||
public get (key: string | number): T {
|
||||
const value: T | undefined = this.storage.get(key);
|
||||
|
||||
if (!value) {
|
||||
throw new Error(`No value found in map storage with key \`${key}\``);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* @returns {string | number | null}
|
||||
*/
|
||||
public getKeyOf (value: T): string | number | null {
|
||||
return Utils.mapGetFirstKeyOf(this.storage, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
public getLength (): number {
|
||||
return Array.from(this.storage).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Map <string | number, T>}
|
||||
*/
|
||||
public getStorage (): Map <string | number, T> {
|
||||
return this.storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public set (key: string | number, value: T): void {
|
||||
this.storage.set(key, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
|
||||
import { MapStorage } from '../MapStorage';
|
||||
|
||||
export class ControlFlowStorage extends MapStorage <ICustomNode> {
|
||||
/**
|
||||
* @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(',');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ArrayStorage } from '../ArrayStorage';
|
||||
import { Utils } from '../../Utils';
|
||||
|
||||
export class StringArrayStorage extends ArrayStorage <string> {
|
||||
/**
|
||||
* @param rotationValue
|
||||
*/
|
||||
public rotateArray (rotationValue: number): void {
|
||||
this.storage = Utils.arrayRotate(this.storage, rotationValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public toString (): string {
|
||||
return this.storage.map((value: string) => {
|
||||
return `'${value}'`;
|
||||
}).toString();
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
export function BinaryExpressionFunctionTemplate (): string {
|
||||
return `
|
||||
function {functionName} (x, y) {
|
||||
return x {operator} y;
|
||||
}
|
||||
`;
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
export function ControlFlowStorageCallTemplate (): string {
|
||||
return '{controlFlowStorageName}.{controlFlowStorageKey}({leftValue}, {rightValue})';
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
export function ControlFlowStorageTemplate (): string {
|
||||
return `
|
||||
var {controlFlowStorageName} = { {controlFlowStorage} };
|
||||
`;
|
||||
}
|
||||
+1
-3
@@ -1,5 +1,3 @@
|
||||
import { Utils } from '../../../../Utils';
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
@@ -10,7 +8,7 @@ export function DebugProtectionFunctionTemplate (): string {
|
||||
if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
|
||||
(function () {}.constructor('debugger')());
|
||||
} else {
|
||||
[].filter.constructor(${Utils.stringToJSFuck('debugger')})();
|
||||
(function () {}.constructor('debugger')());
|
||||
}
|
||||
|
||||
debuggerProtection(++counter);
|
||||
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import { IControlFlowReplacer } from '../interfaces/IControlFlowReplacer';
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
|
||||
export type TControlFlowReplacer = (new (nodes: Map <string, ICustomNode>, options: IOptions) => IControlFlowReplacer);
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { INodeObfuscator } from '../interfaces/INodeObfuscator';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
|
||||
export type TNodeObfuscator = (new (nodes: Map <string, ICustomNode>, options: IOptions) => INodeObfuscator);
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { INodeTransformer } from '../interfaces/INodeTransformer';
|
||||
import { IOptions } from '../interfaces/IOptions';
|
||||
|
||||
export type TNodeTransformer = (new (nodes: Map <string, ICustomNode>, options: IOptions) => INodeTransformer);
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
export type TVisitorDirection = 'enter' | 'leave';
|
||||
@@ -1,3 +0,0 @@
|
||||
import { ICustomNodeWithIdentifier } from '../../interfaces/custom-nodes/ICustomNodeWithIdentifier';
|
||||
|
||||
export type TStringArrayCallsWrapper = ICustomNodeWithIdentifier;
|
||||
@@ -1,4 +0,0 @@
|
||||
import { ICustomNodeWithData } from '../../interfaces/custom-nodes/ICustomNodeWithData';
|
||||
import { ICustomNodeWithIdentifier } from '../../interfaces/custom-nodes/ICustomNodeWithIdentifier';
|
||||
|
||||
export type TStringArrayNode = ICustomNodeWithData & ICustomNodeWithIdentifier;
|
||||
+13
-63
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
if (!(<any>global)._babelPolyfill) {
|
||||
require('babel-polyfill');
|
||||
@@ -7,72 +8,21 @@ if (!(<any>global)._babelPolyfill) {
|
||||
(function () {
|
||||
const JavaScriptObfuscator: any = require("../../index");
|
||||
|
||||
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
||||
`
|
||||
(function(){
|
||||
var result = 1,
|
||||
term1 = 0,
|
||||
term2 = 1,
|
||||
i = 1;
|
||||
while(i < 10)
|
||||
{
|
||||
var test = 10;
|
||||
result = term1 + term2;
|
||||
console.log(result);
|
||||
term1 = term2;
|
||||
term2 = result;
|
||||
i++;
|
||||
}
|
||||
|
||||
console.log(test);
|
||||
|
||||
var test = function (test) {
|
||||
console.log(test);
|
||||
|
||||
if (true) {
|
||||
var test = 5
|
||||
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(`
|
||||
(function(){
|
||||
function t () {
|
||||
return function () {
|
||||
var t = 1 * 2;
|
||||
}
|
||||
}
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
console.log(test(1));
|
||||
|
||||
function test2 (abc) {
|
||||
function test1 () {
|
||||
console.log('inside', abc.item);
|
||||
}
|
||||
|
||||
console.log('тест', abc);
|
||||
|
||||
var abc = {};
|
||||
|
||||
return abc.item = 15, test1();
|
||||
};
|
||||
|
||||
var regexptest = /version\\/(\\d+)/i;
|
||||
console.log(regexptest);
|
||||
|
||||
test2(22);
|
||||
console.log(105.4);
|
||||
console.log(true, false);
|
||||
|
||||
var sA = 'shorthand1';
|
||||
var sB = 'shorthand2';
|
||||
|
||||
console.log({sA, sB});
|
||||
|
||||
try {
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
})();
|
||||
var s = 1 - 3;
|
||||
})();
|
||||
`,
|
||||
{
|
||||
disableConsoleOutput: false,
|
||||
selfDefending: true,
|
||||
stringArrayEncoding: 'rc4'
|
||||
}
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
controlFlowFlattening: true,
|
||||
disableConsoleOutput: false
|
||||
})
|
||||
).getObfuscatedCode();
|
||||
|
||||
console.log(obfuscatedCode);
|
||||
|
||||
Vendored
+1
-1
@@ -6371,7 +6371,7 @@
|
||||
/* 42 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
// to indexed object, toObject with fallback for non-array-like ES3 strings
|
||||
// to indexed object, toString with fallback for non-array-like ES3 strings
|
||||
var IObject = __webpack_require__(118)
|
||||
, defined = __webpack_require__(59);
|
||||
module.exports = function(it){
|
||||
|
||||
@@ -3,6 +3,7 @@ import { IObfuscationResult } from '../../src/interfaces/IObfuscationResult';
|
||||
import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscator';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset';
|
||||
import { readFileAsString } from '../helpers/readFileAsString';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
@@ -125,5 +126,40 @@ describe('JavaScriptObfuscator', () => {
|
||||
assert.match(obfuscatedCode2, pattern1);
|
||||
assert.match(obfuscatedCode2, pattern2);
|
||||
});
|
||||
|
||||
it('should returns same code every time with same `seed`', () => {
|
||||
const code: string = readFileAsString('./test/fixtures/sample.js');
|
||||
const seed: number = 12345;
|
||||
|
||||
const obfuscationResult1: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code, { seed: seed }
|
||||
);
|
||||
const obfuscationResult2: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code, { seed: seed }
|
||||
);
|
||||
|
||||
assert.equal(obfuscationResult1.getObfuscatedCode(), obfuscationResult2.getObfuscatedCode());
|
||||
});
|
||||
|
||||
it('should returns different code with different `seed` option value', () => {
|
||||
const code: string = readFileAsString('./test/fixtures/sample.js');
|
||||
|
||||
const obfuscationResult1: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code, { seed: 12345 }
|
||||
);
|
||||
const obfuscationResult2: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code, { seed: 12346 }
|
||||
);
|
||||
|
||||
const obfuscationResult3: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code, { seed: 0 }
|
||||
);
|
||||
const obfuscationResult4: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code, { seed: 0 }
|
||||
);
|
||||
|
||||
assert.notEqual(obfuscationResult1.getObfuscatedCode(), obfuscationResult2.getObfuscatedCode());
|
||||
assert.notEqual(obfuscationResult3.getObfuscatedCode(), obfuscationResult4.getObfuscatedCode());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,8 @@ import { JavaScriptObfuscatorInternal } from '../../src/JavaScriptObfuscatorInte
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { Options } from '../../src/options/Options';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
describe('JavaScriptObfuscatorInternal', () => {
|
||||
@@ -14,16 +16,15 @@ describe('JavaScriptObfuscatorInternal', () => {
|
||||
|
||||
it('should link obfuscated code with source map', () => {
|
||||
javaScriptObfuscator = new JavaScriptObfuscatorInternal(
|
||||
`var test = 1;`,
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
sourceMap: true,
|
||||
sourceMapFileName: sourceMapUrl
|
||||
})
|
||||
new Options(
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
sourceMap: true,
|
||||
sourceMapFileName: sourceMapUrl
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
javaScriptObfuscator.obfuscate();
|
||||
|
||||
obfuscationResult = javaScriptObfuscator.getObfuscationResult();
|
||||
obfuscationResult = javaScriptObfuscator.obfuscate('var test = 1;');
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
@@ -36,17 +37,16 @@ describe('JavaScriptObfuscatorInternal', () => {
|
||||
let sourceMapBaseUrl: string = 'http://localhost:9000';
|
||||
|
||||
javaScriptObfuscator = new JavaScriptObfuscatorInternal(
|
||||
`var test = 1;`,
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
sourceMap: true,
|
||||
sourceMapBaseUrl: sourceMapBaseUrl,
|
||||
sourceMapFileName: sourceMapUrl
|
||||
})
|
||||
new Options(
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
|
||||
sourceMap: true,
|
||||
sourceMapBaseUrl: sourceMapBaseUrl,
|
||||
sourceMapFileName: sourceMapUrl
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
javaScriptObfuscator.obfuscate();
|
||||
|
||||
obfuscationResult = javaScriptObfuscator.getObfuscationResult();
|
||||
obfuscationResult = javaScriptObfuscator.obfuscate('var test = 1;');
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
|
||||
+8
-6
@@ -1,17 +1,19 @@
|
||||
import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
|
||||
import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { readFileAsString } from '../../helpers/readFileAsString';
|
||||
import { readFileAsString } from '../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
describe('CatchClauseObfuscator', () => {
|
||||
describe('obfuscateNode (catchClauseNode: ESTree.CatchClause): void', () => {
|
||||
describe('changeControlFlow (catchClauseNode: ESTree.CatchClause): void', () => {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString('./test/fixtures/node-obfuscators/catch-clause-obfuscator/catch-clause-obfuscator.js'),
|
||||
readFileAsString(
|
||||
'./test/fixtures/node-transformers/node-obfuscators/catch-clause-obfuscator/catch-clause-obfuscator.js'
|
||||
),
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET)
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
|
||||
import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
+8
-6
@@ -1,17 +1,19 @@
|
||||
import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
|
||||
import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { readFileAsString } from '../../helpers/readFileAsString';
|
||||
import { readFileAsString } from '../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
describe('LabeledStatementObfuscator', () => {
|
||||
describe('obfuscateNode (labeledStatementNode: ESTree.LabeledStatement): void', () => {
|
||||
describe('changeControlFlow (labeledStatementNode: ESTree.LabeledStatement): void', () => {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString('./test/fixtures/node-obfuscators/labeled-statement-obfuscator/labeled-statement-obfuscator.js'),
|
||||
readFileAsString(
|
||||
'./test/fixtures/node-transformers/node-obfuscators/labeled-statement-obfuscator/labeled-statement-obfuscator.js'
|
||||
),
|
||||
Object.assign({}, NO_CUSTOM_NODES_PRESET)
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
|
||||
import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
|
||||
import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
|
||||
import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
|
||||
import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
|
||||
import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset';
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
const assert: Chai.AssertStatic = require('chai').assert;
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../../../src/types/TNodeWithBlockStatement';
|
||||
|
||||
import { IStackTraceAnalyzer } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer';
|
||||
import { IStackTraceData } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceData';
|
||||
|
||||
import { readFileAsString } from '../../helpers/readFileAsString';
|
||||
@@ -145,6 +146,8 @@ function getObjectFunctionExpressionByName (astTree: ESTree.Node, objectName: st
|
||||
|
||||
describe('StackTraceAnalyzer', () => {
|
||||
describe('extract (): IStackTraceData[]', () => {
|
||||
const stackTraceAnalyzer: IStackTraceAnalyzer = new StackTraceAnalyzer();
|
||||
|
||||
let astTree: TNodeWithBlockStatement,
|
||||
stackTraceData: IStackTraceData[],
|
||||
expectedStackTraceData: IStackTraceData[];
|
||||
@@ -191,7 +194,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
}
|
||||
];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -227,7 +230,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
}
|
||||
];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -263,7 +266,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
}
|
||||
];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -283,7 +286,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
}
|
||||
];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -339,7 +342,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
}
|
||||
];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -364,7 +367,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
},
|
||||
];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -378,7 +381,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
|
||||
expectedStackTraceData = [];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -392,7 +395,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
|
||||
expectedStackTraceData = [];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -424,7 +427,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
}
|
||||
];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
@@ -444,7 +447,7 @@ describe('StackTraceAnalyzer', () => {
|
||||
}
|
||||
];
|
||||
|
||||
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
|
||||
stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
|
||||
|
||||
assert.deepEqual(stackTraceData, expectedStackTraceData);
|
||||
});
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import 'format-unicorn';
|
||||
import * as format from 'string-template';
|
||||
|
||||
import { DomainLockNodeTemplate } from '../../../../../src/templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate';
|
||||
|
||||
@@ -14,7 +14,7 @@ const assert: Chai.AssertStatic = require('chai').assert;
|
||||
* @returns {Function}
|
||||
*/
|
||||
function getFunctionFromTemplate (templateData: any, callsControllerFunctionName: string, currentDomain: string) {
|
||||
let domainLockTemplate: string = DomainLockNodeTemplate().formatUnicorn(templateData);
|
||||
let domainLockTemplate: string = format(DomainLockNodeTemplate(), templateData);
|
||||
|
||||
return Function(`
|
||||
document = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user