mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Merge branch 'dev'
# Conflicts: # package.json
This commit is contained in:
@@ -1,5 +1,17 @@
|
||||
Change Log
|
||||
===
|
||||
v0.8.6
|
||||
---
|
||||
* additional fixes for https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
|
||||
|
||||
v0.8.5
|
||||
---
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
|
||||
|
||||
v0.8.4
|
||||
---
|
||||
* fixed https://github.com/javascript-obfuscator/webpack-obfuscator/issues/13
|
||||
|
||||
v0.8.3
|
||||
---
|
||||
* `selfDefending` option now disabled by default.
|
||||
|
||||
@@ -298,7 +298,7 @@ If checked, an interval is used to force the debug mode on the Console tab, maki
|
||||
### `disableConsoleOutput`
|
||||
Type: `boolean` Default: `true`
|
||||
|
||||
Disables the use of `console.log`, `console.info`, `console.error` and `console.warn` by replacing them with empty functions. This makes the use of the debugger harder.
|
||||
Disables the use of `console.log`, `console.info`, `console.error`, `console.warn`, `console.debug`, `console.exception` and `console.trace` by replacing them with empty functions. This makes the use of the debugger harder.
|
||||
|
||||
### `domainLock`
|
||||
Type: `string[]` Default: `[]`
|
||||
|
||||
Vendored
+732
-763
File diff suppressed because it is too large
Load Diff
+17
-17
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "javascript-obfuscator",
|
||||
"version": "0.9.0-dev.9",
|
||||
"version": "0.9.0-dev.10",
|
||||
"description": "JavaScript obfuscator",
|
||||
"keywords": [
|
||||
"obfuscator",
|
||||
@@ -20,21 +20,21 @@
|
||||
"javascript-obfuscator": "./bin/javascript-obfuscator.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.20.0",
|
||||
"babel-runtime": "^6.20.0",
|
||||
"babel-polyfill": "6.20.0",
|
||||
"babel-runtime": "6.20.0",
|
||||
"chance": "1.0.4",
|
||||
"class-validator": "0.6.6",
|
||||
"class-validator": "0.6.8",
|
||||
"commander": "2.9.0",
|
||||
"escodegen": "1.8.1",
|
||||
"esprima": "3.1.3",
|
||||
"estraverse": "4.2.0",
|
||||
"inversify": "^3.0.0-rc.4",
|
||||
"lodash": "^4.17.4",
|
||||
"inversify": "3.0.0-rc.4",
|
||||
"lodash": "4.17.4",
|
||||
"mkdirp": "0.5.1",
|
||||
"reflect-metadata": "^0.1.9",
|
||||
"reflect-metadata": "0.1.9",
|
||||
"source-map-support": "0.4.8",
|
||||
"string-template": "^1.0.0",
|
||||
"tslib": "^1.5.0"
|
||||
"string-template": "1.0.0",
|
||||
"tslib": "1.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "3.4.34",
|
||||
@@ -44,16 +44,16 @@
|
||||
"@types/esprima": "2.1.33",
|
||||
"@types/estraverse": "0.0.6",
|
||||
"@types/estree": "0.0.34",
|
||||
"@types/lodash": "^4.14.45",
|
||||
"@types/lodash": "4.14.48",
|
||||
"@types/mkdirp": "0.3.29",
|
||||
"@types/mocha": "2.2.35",
|
||||
"@types/node": "6.0.57",
|
||||
"@types/mocha": "2.2.37",
|
||||
"@types/node": "6.0.59",
|
||||
"@types/sinon": "1.16.34",
|
||||
"@types/string-template": "1.0.2",
|
||||
"awesome-typescript-loader": "3.0.0-beta.17",
|
||||
"awesome-typescript-loader": "3.0.0-beta.18",
|
||||
"babel-cli": "6.18.0",
|
||||
"babel-loader": "6.2.10",
|
||||
"babel-plugin-transform-runtime": "^6.15.0",
|
||||
"babel-plugin-transform-runtime": "6.15.0",
|
||||
"babel-preset-es2015": "6.18.0",
|
||||
"chai": "4.0.0-canary.1",
|
||||
"coveralls": "2.11.15",
|
||||
@@ -61,10 +61,10 @@
|
||||
"mocha": "3.2.0",
|
||||
"sinon": "2.0.0-pre.4",
|
||||
"ts-node": "2.0.0",
|
||||
"tslint": "4.2.0",
|
||||
"tslint-loader": "^3.3.0",
|
||||
"tslint": "4.3.1",
|
||||
"tslint-loader": "3.3.0",
|
||||
"typescript": "2.1.4",
|
||||
"webpack": "2.2.0-rc.2",
|
||||
"webpack": "2.2.0-rc.3",
|
||||
"webpack-node-externals": "1.5.4"
|
||||
},
|
||||
"repository": {
|
||||
|
||||
@@ -51,7 +51,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
|
||||
*/
|
||||
protected getTemplate (): string {
|
||||
return format(ConsoleOutputDisableExpressionTemplate(), {
|
||||
consoleLogDisableFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
|
||||
consoleLogDisableFunctionName: RandomGeneratorUtils.getRandomVariableName(6),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
|
||||
|
||||
const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNodes.ConsoleOutputDisableExpressionNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
|
||||
|
||||
@@ -43,7 +43,7 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const structure: TStatement = Nodes.getFunctionDeclarationNode(
|
||||
RandomGeneratorUtils.getRandomVariableName(1, true, false),
|
||||
RandomGeneratorUtils.getRandomString(3),
|
||||
[
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
|
||||
@@ -51,7 +51,7 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
|
||||
}
|
||||
|
||||
const structure: TStatement = Nodes.getFunctionDeclarationNode(
|
||||
RandomGeneratorUtils.getRandomVariableName(1, true, false),
|
||||
RandomGeneratorUtils.getRandomString(3),
|
||||
[
|
||||
calleeIdentifier,
|
||||
...params
|
||||
|
||||
@@ -43,7 +43,7 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode {
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const structure: TStatement = Nodes.getFunctionDeclarationNode(
|
||||
RandomGeneratorUtils.getRandomVariableName(1, true, false),
|
||||
RandomGeneratorUtils.getRandomString(3),
|
||||
[
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
|
||||
@@ -89,7 +89,7 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const debugProtectionFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
const debugProtectionFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
|
||||
|
||||
const debugProtectionFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.DebugProtectionFunctionNode);
|
||||
const debugProtectionFunctionCallNode: ICustomNode = this.customNodeFactory(CustomNodes.DebugProtectionFunctionCallNode);
|
||||
|
||||
@@ -55,7 +55,7 @@ export class DomainLockNode extends AbstractCustomNode {
|
||||
const [hiddenDomainsString, diff]: string[] = CryptUtils.hideString(domainsString, domainsString.length * 3);
|
||||
|
||||
return format(DomainLockNodeTemplate(), {
|
||||
domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
|
||||
domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(6),
|
||||
diff: diff,
|
||||
domains: hiddenDomainsString,
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
|
||||
@@ -96,7 +96,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
|
||||
|
||||
const domainLockNode: ICustomNode = this.customNodeFactory(CustomNodes.DomainLockNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
|
||||
|
||||
@@ -55,7 +55,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
|
||||
protected getTemplate (): string {
|
||||
return JavaScriptObfuscator.obfuscate(
|
||||
format(SelfDefendingTemplate(), {
|
||||
selfDefendingFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
|
||||
selfDefendingFunctionName: RandomGeneratorUtils.getRandomVariableName(6),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
}),
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
|
||||
|
||||
const selfDefendingUnicodeNode: ICustomNode = this.customNodeFactory(CustomNodes.SelfDefendingUnicodeNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
|
||||
|
||||
@@ -76,8 +76,8 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
* @returns {string}
|
||||
*/
|
||||
protected getTemplate (): string {
|
||||
const timesName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
const whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
const timesName: string = RandomGeneratorUtils.getRandomVariableName(6);
|
||||
const whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
|
||||
|
||||
let code: string = '';
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -6,5 +6,5 @@ declare module 'escodegen' {
|
||||
* @param options
|
||||
* @returns IGeneratorOutput
|
||||
*/
|
||||
export function generate(ast: any, options?: GenerateOptions): IGeneratorOutput;
|
||||
export function generate (ast: any, options?: GenerateOptions): IGeneratorOutput;
|
||||
}
|
||||
|
||||
+3
-3
@@ -62,14 +62,14 @@ export class BlockStatementControlFlowTransformer extends AbstractNodeTransforme
|
||||
}
|
||||
|
||||
const blockStatementBody: ESTree.Statement[] = blockStatementNode.body;
|
||||
const originalKeys: number[] = [...Array(blockStatementBody.length).keys()];
|
||||
const shuffledKeys: number[] = Utils.arrayShuffle(originalKeys);
|
||||
const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key));
|
||||
|
||||
if (blockStatementBody.length <= 4) {
|
||||
return blockStatementNode;
|
||||
}
|
||||
|
||||
const originalKeys: number[] = [...Array(blockStatementBody.length).keys()];
|
||||
const shuffledKeys: number[] = Utils.arrayShuffle(originalKeys);
|
||||
const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key));
|
||||
const blockStatementControlFlowFlatteningCustomNode: ICustomNode = this.customNodeFactory(
|
||||
CustomNodes.BlockStatementControlFlowFlatteningNode
|
||||
);
|
||||
|
||||
@@ -9,11 +9,9 @@ import { IObfuscationReplacer } from '../../interfaces/node-transformers/IObfusc
|
||||
import { IObfuscationReplacerWithStorage } from '../../interfaces/node-transformers/IObfuscationReplacerWithStorage';
|
||||
|
||||
import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscationReplacers';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -34,7 +32,7 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
|
||||
* @param replacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
@@ -61,9 +59,9 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
|
||||
* @param nodeIdentifier
|
||||
*/
|
||||
private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause, nodeIdentifier: number): void {
|
||||
NodeUtils.typedTraverse(catchClauseNode.param, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
|
||||
});
|
||||
if (Node.isIdentifierNode(catchClauseNode.param)) {
|
||||
this.identifierReplacer.storeNames(catchClauseNode.param.name, nodeIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +72,12 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
|
||||
estraverse.replace(catchClauseNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
|
||||
if (Node.isReplaceableIdentifierNode(node, parentNode)) {
|
||||
node.name = this.identifierReplacer.replace(node.name, nodeIdentifier);
|
||||
const newNodeName: string = this.identifierReplacer.replace(node.name, nodeIdentifier);
|
||||
|
||||
if (node.name !== newNodeName) {
|
||||
node.name = newNodeName;
|
||||
node.obfuscated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @param nodeObfuscatorsReplacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
@@ -76,9 +76,7 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @param nodeIdentifier
|
||||
*/
|
||||
private storeFunctionName (functionDeclarationNode: ESTree.FunctionDeclaration, nodeIdentifier: number): void {
|
||||
NodeUtils.typedTraverse(functionDeclarationNode.id, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
|
||||
});
|
||||
this.identifierReplacer.storeNames(functionDeclarationNode.id.name, nodeIdentifier);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,11 +9,9 @@ import { IObfuscationReplacer } from '../../interfaces/node-transformers/IObfusc
|
||||
import { IObfuscationReplacerWithStorage } from '../../interfaces/node-transformers/IObfuscationReplacerWithStorage';
|
||||
|
||||
import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscationReplacers';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -34,7 +32,7 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
* @param nodeObfuscatorsReplacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
@@ -63,9 +61,9 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
private storeFunctionParams (functionNode: ESTree.Function, nodeIdentifier: number): void {
|
||||
functionNode.params
|
||||
.forEach((paramsNode: ESTree.Node) => {
|
||||
NodeUtils.typedTraverse(paramsNode, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
|
||||
});
|
||||
if (Node.isIdentifierNode(paramsNode)) {
|
||||
this.identifierReplacer.storeNames(paramsNode.name, nodeIdentifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,9 @@ import { IObfuscationReplacer } from '../../interfaces/node-transformers/IObfusc
|
||||
import { IObfuscationReplacerWithStorage } from '../../interfaces/node-transformers/IObfuscationReplacerWithStorage';
|
||||
|
||||
import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscationReplacers';
|
||||
import { NodeType } from '../../enums/NodeType';
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { Node } from '../../node/Node';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -42,7 +40,7 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer {
|
||||
* @param nodeObfuscatorsReplacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
@@ -69,9 +67,7 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer {
|
||||
* @param nodeIdentifier
|
||||
*/
|
||||
private storeLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement, nodeIdentifier: number): void {
|
||||
NodeUtils.typedTraverse(labeledStatementNode.label, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
|
||||
});
|
||||
this.identifierReplacer.storeNames(labeledStatementNode.label.name, nodeIdentifier);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,7 @@ export class LiteralTransformer extends AbstractNodeTransformer {
|
||||
* @param replacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
|
||||
@@ -23,7 +23,7 @@ export class MemberExpressionTransformer extends AbstractNodeTransformer {
|
||||
* @param replacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
|
||||
@@ -37,7 +37,7 @@ export class MethodDefinitionTransformer extends AbstractNodeTransformer {
|
||||
* @param replacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
|
||||
@@ -27,7 +27,7 @@ export class ObjectExpressionTransformer extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
super(options);
|
||||
|
||||
@@ -27,7 +27,7 @@ export class TemplateLiteralTransformer extends AbstractNodeTransformer {
|
||||
* @param replacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
|
||||
@@ -43,7 +43,7 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @param replacersFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor(
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
@@ -83,9 +83,9 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
private storeVariableNames (variableDeclarationNode: ESTree.VariableDeclaration, nodeIdentifier: number): void {
|
||||
variableDeclarationNode.declarations
|
||||
.forEach((declarationNode: ESTree.VariableDeclarator) => {
|
||||
NodeUtils.typedTraverse(declarationNode.id, NodeType.Identifier, {
|
||||
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
|
||||
});
|
||||
if (Node.isIdentifierNode(declarationNode.id)) {
|
||||
this.identifierReplacer.storeNames(declarationNode.id.name, nodeIdentifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ export class IdentifierReplacer extends AbstractReplacer implements IObfuscation
|
||||
*/
|
||||
public storeNames (nodeName: string, nodeIdentifier: number): void {
|
||||
if (!this.isReservedName(nodeName)) {
|
||||
this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, RandomGeneratorUtils.getRandomVariableName(6, true, true));
|
||||
this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, RandomGeneratorUtils.getRandomVariableName(6));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-20
@@ -1,24 +1,10 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockStatement } from '../types/node/TNodeWithBlockStatement';
|
||||
import { TStatement } from '../types/node/TStatement';
|
||||
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
|
||||
export class Node {
|
||||
/**
|
||||
* @param bodyNode
|
||||
* @returns ESTree.Program
|
||||
*/
|
||||
public static getProgramNode (bodyNode: TStatement[]): ESTree.Program {
|
||||
return {
|
||||
'type': NodeType.Program,
|
||||
'body': bodyNode,
|
||||
'sourceType': 'script',
|
||||
'obfuscated': false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @returns {boolean}
|
||||
@@ -109,9 +95,7 @@ export class Node {
|
||||
const parentNodeIsContinueStatementNode: boolean = Node.isContinueStatementNode(parentNode) && parentNode.label === node;
|
||||
const parentNodeIsBreakStatementNode: boolean = Node.isBreakStatementNode(parentNode) && parentNode.label === node;
|
||||
|
||||
return parentNodeIsLabeledStatementNode ||
|
||||
parentNodeIsContinueStatementNode ||
|
||||
parentNodeIsBreakStatementNode;
|
||||
return parentNodeIsLabeledStatementNode || parentNodeIsContinueStatementNode || parentNodeIsBreakStatementNode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,9 +165,7 @@ export class Node {
|
||||
parentNode.property === node
|
||||
);
|
||||
|
||||
return !parentNodeIsPropertyNode &&
|
||||
!parentNodeIsMemberExpressionNode &&
|
||||
!Node.isLabelIdentifierNode(node, parentNode);
|
||||
return !parentNodeIsPropertyNode && !parentNodeIsMemberExpressionNode && !Node.isLabelIdentifierNode(node, parentNode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+19
-18
@@ -9,6 +9,7 @@ import { TStatement } from '../types/node/TStatement';
|
||||
import { NodeType } from '../enums/NodeType';
|
||||
|
||||
import { Node } from './Node';
|
||||
import { Nodes } from './Nodes';
|
||||
|
||||
export class NodeUtils {
|
||||
/**
|
||||
@@ -23,20 +24,20 @@ export class NodeUtils {
|
||||
];
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param astTree
|
||||
* @return {T}
|
||||
*/
|
||||
public static addXVerbatimPropertyToLiterals <T extends ESTree.Node> (node: T): T {
|
||||
NodeUtils.typedReplace(node, NodeType.Literal, {
|
||||
leave: (node: ESTree.Literal) => {
|
||||
node['x-verbatim-property'] = {
|
||||
content : node.raw,
|
||||
public static addXVerbatimPropertyToLiterals <T extends ESTree.Node> (astTree: T): T {
|
||||
NodeUtils.typedReplace(astTree, NodeType.Literal, {
|
||||
leave: (literalNode: ESTree.Literal) => {
|
||||
literalNode['x-verbatim-property'] = {
|
||||
content : literalNode.raw,
|
||||
precedence: escodegen.Precedence.Primary
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return node;
|
||||
return astTree;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,13 +153,13 @@ export class NodeUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param astTree
|
||||
* @return {T}
|
||||
*/
|
||||
public static parentize <T extends ESTree.Node> (node: T): T {
|
||||
public static parentize <T extends ESTree.Node> (astTree: T): T {
|
||||
let isRootNode: boolean = true;
|
||||
|
||||
estraverse.traverse(node, {
|
||||
estraverse.traverse(astTree, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
|
||||
let value: ESTree.Node;
|
||||
|
||||
@@ -166,7 +167,7 @@ export class NodeUtils {
|
||||
if (node.type === NodeType.Program) {
|
||||
value = node;
|
||||
} else {
|
||||
value = Node.getProgramNode(<TStatement[]>[node]);
|
||||
value = Nodes.getProgramNode(<TStatement[]>[node]);
|
||||
value.parentNode = value;
|
||||
}
|
||||
|
||||
@@ -180,35 +181,35 @@ export class NodeUtils {
|
||||
}
|
||||
});
|
||||
|
||||
return node;
|
||||
return astTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param astTree
|
||||
* @param nodeType
|
||||
* @param visitor
|
||||
*/
|
||||
public static typedReplace (
|
||||
node: ESTree.Node,
|
||||
astTree: ESTree.Node,
|
||||
nodeType: string,
|
||||
visitor: {enter?: (node: ESTree.Node) => void, leave?: (node: ESTree.Node) => void},
|
||||
): void {
|
||||
NodeUtils.typedTraverse(node, nodeType, visitor, 'replace');
|
||||
NodeUtils.typedTraverse(astTree, nodeType, visitor, 'replace');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param astTree
|
||||
* @param nodeType
|
||||
* @param visitor
|
||||
* @param traverseType
|
||||
*/
|
||||
public static typedTraverse (
|
||||
node: ESTree.Node,
|
||||
astTree: ESTree.Node,
|
||||
nodeType: string,
|
||||
visitor: estraverse.Visitor,
|
||||
traverseType: string = 'traverse'
|
||||
): void {
|
||||
(<any>estraverse)[traverseType](node, {
|
||||
(<any>estraverse)[traverseType](astTree, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
|
||||
if (node.type === nodeType && visitor.enter) {
|
||||
return visitor.enter(node, parentNode);
|
||||
|
||||
+3
-3
@@ -37,14 +37,14 @@ export class FunctionDeclarationCalleeDataExtractor extends AbstractCalleeDataEx
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param targetNode
|
||||
* @param name
|
||||
* @returns {ESTree.BlockStatement|null}
|
||||
*/
|
||||
private getCalleeBlockStatement (node: ESTree.Node, name: string): ESTree.BlockStatement|null {
|
||||
private getCalleeBlockStatement (targetNode: ESTree.Node, name: string): ESTree.BlockStatement|null {
|
||||
let calleeBlockStatement: ESTree.BlockStatement|null = null;
|
||||
|
||||
estraverse.traverse(node, {
|
||||
estraverse.traverse(targetNode, {
|
||||
enter: (node: ESTree.Node): any => {
|
||||
if (Node.isFunctionDeclarationNode(node) && node.id.name === name) {
|
||||
calleeBlockStatement = node.body;
|
||||
|
||||
+3
-3
@@ -41,14 +41,14 @@ export class FunctionExpressionCalleeDataExtractor extends AbstractCalleeDataExt
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param targetNode
|
||||
* @param name
|
||||
* @returns {ESTree.BlockStatement|null}
|
||||
*/
|
||||
private getCalleeBlockStatement (node: ESTree.Node, name: string): ESTree.BlockStatement|null {
|
||||
private getCalleeBlockStatement (targetNode: ESTree.Node, name: string): ESTree.BlockStatement|null {
|
||||
let calleeBlockStatement: ESTree.BlockStatement|null = null;
|
||||
|
||||
estraverse.traverse(node, {
|
||||
estraverse.traverse(targetNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
|
||||
if (
|
||||
Node.isFunctionExpressionNode(node) &&
|
||||
|
||||
+3
-3
@@ -85,12 +85,12 @@ export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtra
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param targetNode
|
||||
* @param objectMembersCallsChain
|
||||
* @returns {ESTree.BlockStatement|null}
|
||||
*/
|
||||
private getCalleeBlockStatement (
|
||||
node: ESTree.Node,
|
||||
targetNode: ESTree.Node,
|
||||
objectMembersCallsChain: TObjectMembersCallsChain
|
||||
): ESTree.BlockStatement|null {
|
||||
const objectName: string|number|undefined = objectMembersCallsChain.shift();
|
||||
@@ -101,7 +101,7 @@ export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtra
|
||||
|
||||
let calleeBlockStatement: ESTree.BlockStatement|null = null;
|
||||
|
||||
estraverse.traverse(node, {
|
||||
estraverse.traverse(targetNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
|
||||
if (
|
||||
Node.isVariableDeclaratorNode(node) &&
|
||||
|
||||
@@ -18,7 +18,7 @@ export class StringArrayStorage extends ArrayStorage <string> {
|
||||
public initialize (...args: any[]): void {
|
||||
super.initialize(args);
|
||||
|
||||
this.storageId = RandomGeneratorUtils.getRandomVariableName(4, false, false);
|
||||
this.storageId = RandomGeneratorUtils.getRandomString(4, RandomGeneratorUtils.randomGeneratorPoolHexadecimal);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+23
-4
@@ -9,10 +9,29 @@ export function ConsoleOutputDisableExpressionTemplate (): string {
|
||||
var func = function () {};
|
||||
var that = getGlobal();
|
||||
|
||||
that.console.log = func;
|
||||
that.console.error = func;
|
||||
that.console.warn = func;
|
||||
that.console.info = func;
|
||||
if (!that.console) {
|
||||
that.console = (function (func){
|
||||
var c = {};
|
||||
|
||||
c.log = func;
|
||||
c.warn = func;
|
||||
c.debug = func;
|
||||
c.info = func;
|
||||
c.error = func;
|
||||
c.exception = func;
|
||||
c.trace = func;
|
||||
|
||||
return c;
|
||||
})(func);
|
||||
} else {
|
||||
that.console.log = func;
|
||||
that.console.warn = func;
|
||||
that.console.debug = func;
|
||||
that.console.info = func;
|
||||
that.console.error = func;
|
||||
that.console.exception = func;
|
||||
that.console.trace = func;
|
||||
}
|
||||
});
|
||||
|
||||
{consoleLogDisableFunctionName}();
|
||||
|
||||
@@ -38,7 +38,7 @@ export class CryptUtils {
|
||||
* @param length
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public static hideString(str: string, length: number): [string, string] {
|
||||
public static hideString (str: string, length: number): [string, string] {
|
||||
const escapeRegExp: (s: string) => string = (s: string) =>
|
||||
s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
|
||||
|
||||
@@ -8,6 +8,11 @@ export class RandomGeneratorUtils {
|
||||
*/
|
||||
public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
public static readonly randomGeneratorPoolHexadecimal: string = 'abcdef0123456789';
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@@ -87,12 +92,10 @@ export class RandomGeneratorUtils {
|
||||
|
||||
/**
|
||||
* @param length
|
||||
* @param withPrefix
|
||||
* @param unique
|
||||
* @returns {string}
|
||||
*/
|
||||
public static getRandomVariableName (length: number, withPrefix: boolean, unique: boolean): string {
|
||||
const prefix: string = withPrefix ? `_${Utils.hexadecimalPrefix}` : '';
|
||||
public static getRandomVariableName (length: number): string {
|
||||
const prefix: string = `_${Utils.hexadecimalPrefix}`;
|
||||
const rangeMinInteger: number = 10000;
|
||||
const rangeMaxInteger: number = 99999999;
|
||||
const randomVariableName: string = `${prefix}${(
|
||||
@@ -101,8 +104,8 @@ export class RandomGeneratorUtils {
|
||||
)
|
||||
).substr(0, length)}`;
|
||||
|
||||
if (unique && RandomGeneratorUtils.randomVariableNameSet.has(randomVariableName)) {
|
||||
return RandomGeneratorUtils.getRandomVariableName(length, withPrefix, unique);
|
||||
if (RandomGeneratorUtils.randomVariableNameSet.has(randomVariableName)) {
|
||||
return RandomGeneratorUtils.getRandomVariableName(length);
|
||||
}
|
||||
|
||||
RandomGeneratorUtils.randomVariableNameSet.add(randomVariableName);
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import { readFileAsString } from '../../../helpers/readFileAsString';
|
||||
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
|
||||
|
||||
describe('ConsoleOutputDisableExpressionNode', () => {
|
||||
const regExp = /(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*)*'\]\['(\\x[a-f0-9]*)*'\] *= *_0x([a-z0-9]){4,6};){4}/;
|
||||
const regExp = /(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*)*'\]\['(\\x[a-f0-9]*)*'\] *= *_0x([a-f0-9]){4,6};){4}/;
|
||||
|
||||
it('should correctly append `ConsoleOutputDisableExpressionNode` custom node into the obfuscated code if `disableConsoleOutput` option is set', () => {
|
||||
let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('DomainLockNode', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var _0x([a-z0-9]){4,6} *= *new RegExp/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var _0x([a-f0-9]){4,6} *= *new RegExp/);
|
||||
});
|
||||
|
||||
it('should\'t append `DomainLockNode` custom node into the obfuscated code if `domainLock` option is not set', () => {
|
||||
@@ -30,6 +30,6 @@ describe('DomainLockNode', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.notMatch(obfuscationResult.getObfuscatedCode(), /var _0x([a-z0-9]){4,6} *= *new RegExp/);
|
||||
assert.notMatch(obfuscationResult.getObfuscatedCode(), /var _0x([a-f0-9]){4,6} *= *new RegExp/);
|
||||
});
|
||||
});
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ describe('StringArrayCallsWrapper', () => {
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
/_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6} *- *0x0\;/
|
||||
/_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6} *- *0x0\;/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('StringArrayNode', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /^var _0x([a-z0-9]){4} *= *\[/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /^var _0x([a-f0-9]){4} *= *\[/);
|
||||
});
|
||||
|
||||
it('should\'t append `StringArrayNode` custom node into the obfuscated code if `stringArray` option is not set', () => {
|
||||
@@ -31,6 +31,6 @@ describe('StringArrayNode', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.notMatch(obfuscationResult.getObfuscatedCode(), /^var _0x([a-z0-9]){4} *= *\[/);
|
||||
assert.notMatch(obfuscationResult.getObfuscatedCode(), /^var _0x([a-f0-9]){4} *= *\[/);
|
||||
});
|
||||
});
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ describe('StringArrayRotateFunctionNode', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /while *\(-- *_0x([a-z0-9]){4,6}\) *\{/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /while *\(-- *_0x([a-f0-9]){4,6}\) *\{/);
|
||||
});
|
||||
|
||||
it('should\'t append `StringArrayRotateFunctionNode` custom node into the obfuscated code if `rotateStringArray` option is not set', () => {
|
||||
@@ -34,6 +34,6 @@ describe('StringArrayRotateFunctionNode', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.notMatch(obfuscationResult.getObfuscatedCode(), /while *\(-- *_0x([a-z0-9]){4,6}\) *\{/);
|
||||
assert.notMatch(obfuscationResult.getObfuscatedCode(), /while *\(-- *_0x([a-f0-9]){4,6}\) *\{/);
|
||||
});
|
||||
});
|
||||
|
||||
+8
-8
@@ -28,11 +28,11 @@ describe('BlockStatementControlFlowTransformer', () => {
|
||||
const statementRegExp4: RegExp = /console\['log'\]\(0x4\);/;
|
||||
const statementRegExp5: RegExp = /console\['log'\]\(0x5\);/;
|
||||
|
||||
const switchCaseRegExp: RegExp = /switch *\(_0x([a-z0-9]){4,6}\[_0x([a-z0-9]){4,6}\+\+\]\) *\{/;
|
||||
const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
|
||||
const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
|
||||
const switchCaseLength: number = obfuscatedCode.match(switchCaseLengthRegExp)!.length;
|
||||
|
||||
const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-z0-9]){4,6} *= *'(.*?)'/;
|
||||
const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *'(.*?)'/;
|
||||
const switchCaseMapMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(switchCaseMapRegExp);
|
||||
const switchCaseMapMatch: string = switchCaseMapMatches[1];
|
||||
const switchCaseMap: string[] = switchCaseMapMatch.replace(/\\x7c/g, '|').split('|').sort();
|
||||
@@ -73,11 +73,11 @@ describe('BlockStatementControlFlowTransformer', () => {
|
||||
const statementRegExp4: RegExp = /console\['log'\]\(0x4\);/;
|
||||
const statementRegExp5: RegExp = /console\['log'\]\(0x5\);/;
|
||||
|
||||
const switchCaseRegExp: RegExp = /switch *\(_0x([a-z0-9]){4,6}\[_0x([a-z0-9]){4,6}\+\+\]\) *\{/;
|
||||
const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
|
||||
const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
|
||||
const switchCaseLength: number = obfuscatedCode.match(switchCaseLengthRegExp)!.length;
|
||||
|
||||
const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-z0-9]){4,6} *= *'(.*?)'/;
|
||||
const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *'(.*?)'/;
|
||||
const switchCaseMapMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(switchCaseMapRegExp);
|
||||
const switchCaseMapMatch: string = switchCaseMapMatches[1];
|
||||
const switchCaseMap: string[] = switchCaseMapMatch.replace(/\\x7c/g, '|').split('|').sort();
|
||||
@@ -129,7 +129,7 @@ describe('BlockStatementControlFlowTransformer', () => {
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *const *_0x([a-z0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *const *_0x([a-f0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
|
||||
|
||||
it('shouldn\'t transform block statement if block statement contain variable declaration with `const` kind', () => {
|
||||
assert.match(obfuscatedCode, statementRegExp);
|
||||
@@ -147,7 +147,7 @@ describe('BlockStatementControlFlowTransformer', () => {
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *let *_0x([a-z0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *let *_0x([a-f0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
|
||||
|
||||
it('shouldn\'t transform block statement if block statement contain variable declaration with `let` kind', () => {
|
||||
assert.match(obfuscatedCode, statementRegExp);
|
||||
@@ -201,7 +201,7 @@ describe('BlockStatementControlFlowTransformer', () => {
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-z0-9]){4,6} *\( *\) *\{ *\} *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-f0-9]){4,6} *\( *\) *\{ *\} *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
|
||||
|
||||
it('shouldn\'t transform block statement if block statement contain function declaration', () => {
|
||||
assert.match(obfuscatedCode, statementRegExp);
|
||||
@@ -221,7 +221,7 @@ describe('BlockStatementControlFlowTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
const regExp1: RegExp = /switch *\(_0x([a-z0-9]){4,6}\[_0x([a-z0-9]){4,6}\+\+\]\) *\{/g;
|
||||
const regExp1: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/g;
|
||||
const regExp2: RegExp = /\(function *\( *\) *\{ *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/g;
|
||||
const transformedStatementMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp1)!.length;
|
||||
const untouchedStatementMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp2)!.length;
|
||||
|
||||
+3
-3
@@ -20,7 +20,7 @@ describe('BinaryExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(0x1, *0x2\);/;
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(0x1, *0x2\);/;
|
||||
|
||||
it('should replace binary expression node by call to control flow storage node', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
|
||||
@@ -47,8 +47,8 @@ describe('BinaryExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x1, *0x2\);/;
|
||||
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x2, *0x3\);/;
|
||||
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x1, *0x2\);/;
|
||||
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x2, *0x3\);/;
|
||||
|
||||
const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
|
||||
const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
|
||||
|
||||
+4
-4
@@ -20,7 +20,7 @@ describe('CallExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(_0x([a-z0-9]){4,6}, *0x1, *0x2\);/;
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
|
||||
|
||||
it('should replace call expression node by call to control flow storage node', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
|
||||
@@ -47,8 +47,8 @@ describe('CallExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-z0-9]){4,6}, *0x1, *0x2\);/;
|
||||
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-z0-9]){4,6}, *0x2, *0x3\);/;
|
||||
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
|
||||
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-f0-9]){4,6}, *0x2, *0x3\);/;
|
||||
|
||||
const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
|
||||
const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
|
||||
@@ -80,7 +80,7 @@ describe('CallExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['\\x73\\x75\\x6d'\]\(0x1, *0x2\);/;
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\\x73\\x75\\x6d'\]\(0x1, *0x2\);/;
|
||||
|
||||
it('shouldn\'t replace call expression node by call to control flow storage node if call expression callee is member expression node', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
|
||||
|
||||
+5
-5
@@ -20,7 +20,7 @@ describe('LogicalExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!!\[\], *!\[\]\);/;
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!!\[\], *!\[\]\);/;
|
||||
|
||||
it('should replace logical expression node by call to control flow storage node', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
|
||||
@@ -47,8 +47,8 @@ describe('LogicalExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!!\[\], *!\[\]\);/;
|
||||
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!\[\], *!!\[\]\);/;
|
||||
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!!\[\], *!\[\]\);/;
|
||||
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!\[\], *!!\[\]\);/;
|
||||
|
||||
const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
|
||||
const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
|
||||
@@ -80,7 +80,7 @@ describe('LogicalExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!_0x([a-z0-9]){4,6}, *!_0x([a-z0-9]){4,6}\);/;
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!_0x([a-f0-9]){4,6}, *!_0x([a-f0-9]){4,6}\);/;
|
||||
|
||||
it('should replace logical expression node with unary expression by call to control flow storage node', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
|
||||
@@ -97,7 +97,7 @@ describe('LogicalExpressionControlFlowReplacer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const regExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\[_0x([a-z0-9]){4,6}\] *&& *!\[\];/;
|
||||
const regExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\] *&& *!\[\];/;
|
||||
|
||||
it('shouldn\'t replace prohibited expression nodes', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
|
||||
|
||||
describe('FunctionControlFlowTransformer', () => {
|
||||
const variableMatch: string = '_0x([a-z0-9]){4,6}';
|
||||
const variableMatch: string = '_0x([a-f0-9]){4,6}';
|
||||
const rootControlFlowStorageNodeMatch: string = `` +
|
||||
`var *${variableMatch} *= *\\{` +
|
||||
`'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
@@ -171,7 +171,7 @@ describe('FunctionControlFlowTransformer', () => {
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageMatch: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
|
||||
const regexp: RegExp = /var *_0x([a-z0-9]){4,6} *= *0x1 *\+ *0x2;/;
|
||||
const regexp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1 *\+ *0x2;/;
|
||||
|
||||
it('shouldn\'t add `control flow storage` node to the obfuscated code when threshold is 0', () => {
|
||||
assert.match(obfuscatedCode, regexp);
|
||||
|
||||
+20
-2
@@ -17,8 +17,8 @@ describe('CatchClauseTransformer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const paramNameRegExp: RegExp = /catch *\((_0x([a-z0-9]){4,6})\) *\{/;
|
||||
const bodyParamNameRegExp: RegExp = /console\['\\x6c\\x6f\\x67'\]\((_0x([a-z0-9]){4,6})\);/;
|
||||
const paramNameRegExp: RegExp = /catch *\((_0x([a-f0-9]){4,6})\) *\{/;
|
||||
const bodyParamNameRegExp: RegExp = /console\['\\x6c\\x6f\\x67'\]\((_0x([a-f0-9]){4,6})\);/;
|
||||
|
||||
it('should transform catch clause node', () => {
|
||||
assert.match(obfuscatedCode, paramNameRegExp);
|
||||
@@ -37,4 +37,22 @@ describe('CatchClauseTransformer', () => {
|
||||
assert.equal(firstMatch, secondMatch);
|
||||
});
|
||||
});
|
||||
|
||||
describe('object pattern as parameter', () => {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(__dirname + '/fixtures/object-pattern-as-parameter.js'),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
|
||||
it('shouldn\'t transform function parameter object pattern identifier', () => {
|
||||
const functionParameterMatch: RegExp = /\} *catch *\(\{ *name *\}\) *\{/;
|
||||
const functionBodyMatch: RegExp = /return *name;/;
|
||||
|
||||
assert.match(obfuscatedCode, functionParameterMatch);
|
||||
assert.match(obfuscatedCode, functionBodyMatch);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
(function () {
|
||||
try {
|
||||
|
||||
} catch ({ name }) {
|
||||
return name;
|
||||
}
|
||||
})();
|
||||
+2
-2
@@ -32,9 +32,9 @@ describe('FunctionDeclarationTransformer', () => {
|
||||
|
||||
it('should transform function name if `functionDeclaration` parent block scope is not a `ProgramNode`', () => {
|
||||
const functionNameIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/function *_0x[a-z0-9]{4,6} *\(\) *\{/);
|
||||
.match(/function *_0x[a-f0-9]{4,6} *\(\) *\{/);
|
||||
const functionCallIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/_0x[a-z0-9]{4,6} *\( *\);/);
|
||||
.match(/_0x[a-f0-9]{4,6} *\( *\);/);
|
||||
|
||||
const functionParamIdentifierName: string = (<RegExpMatchArray>functionNameIdentifierMatch)[1];
|
||||
const functionBodyIdentifierName: string = (<RegExpMatchArray>functionCallIdentifierMatch)[1];
|
||||
|
||||
+20
-2
@@ -20,9 +20,9 @@ describe('FunctionTransformer', () => {
|
||||
|
||||
it('should correct transform both function parameter identifier and function body identifier with same name', () => {
|
||||
const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/var _0x[a-z0-9]{4,6} *= *function *\((_0x[a-z0-9]{4,6})\) *\{/);
|
||||
.match(/var _0x[a-f0-9]{4,6} *= *function *\((_0x[a-f0-9]{4,6})\) *\{/);
|
||||
const functionBodyIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-z0-9]{4,6})\)/);
|
||||
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
|
||||
|
||||
const functionParamIdentifierName: string = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
|
||||
const functionBodyIdentifierName: string = (<RegExpMatchArray>functionBodyIdentifierMatch)[1];
|
||||
@@ -34,4 +34,22 @@ describe('FunctionTransformer', () => {
|
||||
assert.equal(/variable *= *0x6;/.test(obfuscatedCode), true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('object pattern as parameter', () => {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(__dirname + '/fixtures/object-pattern-as-parameter.js'),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
|
||||
it('shouldn\'t transform function parameter object pattern identifier', () => {
|
||||
const functionParameterMatch: RegExp = /function *\(\{ *bar *\}\) *\{/;
|
||||
const functionBodyMatch: RegExp = /return *bar;/;
|
||||
|
||||
assert.match(obfuscatedCode, functionParameterMatch);
|
||||
assert.match(obfuscatedCode, functionBodyMatch);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
(function () {
|
||||
var test = function ({ bar }) {
|
||||
return bar;
|
||||
}
|
||||
})();
|
||||
+3
-3
@@ -17,9 +17,9 @@ describe('LabeledStatementTransformer', () => {
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const labeledStatementRegExp: RegExp = /(_0x([a-z0-9]){4,6}): *\{/;
|
||||
const continueStatementRegExp: RegExp = /continue *(_0x([a-z0-9]){4,6});/;
|
||||
const breakStatementRegExp: RegExp = /break *(_0x([a-z0-9]){4,6});/;
|
||||
const labeledStatementRegExp: RegExp = /(_0x([a-f0-9]){4,6}): *\{/;
|
||||
const continueStatementRegExp: RegExp = /continue *(_0x([a-f0-9]){4,6});/;
|
||||
const breakStatementRegExp: RegExp = /break *(_0x([a-f0-9]){4,6});/;
|
||||
|
||||
it('should transform `labeledStatement` identifier', () => {
|
||||
assert.match(obfuscatedCode, labeledStatementRegExp);
|
||||
|
||||
+10
-10
@@ -33,9 +33,9 @@ describe('LiteralTransformer', () => {
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
/^var *_0x([a-z0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
|
||||
/^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
|
||||
);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
|
||||
});
|
||||
|
||||
it('should create only one item in string array for same literal node values', () => {
|
||||
@@ -50,9 +50,9 @@ describe('LiteralTransformer', () => {
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
/^var *_0x([a-z0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
|
||||
/^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
|
||||
);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
|
||||
});
|
||||
|
||||
it('should replace literal node value with raw value from string array if `unicodeEscapeSequence` is disabled', () => {
|
||||
@@ -68,9 +68,9 @@ describe('LiteralTransformer', () => {
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
/^var *_0x([a-z0-9]){4} *= *\['test'\];/
|
||||
/^var *_0x([a-f0-9]){4} *= *\['test'\];/
|
||||
);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
|
||||
});
|
||||
|
||||
it('should replace literal node value with raw value from string array if `unicodeEscapeSequence` and `stringArray` are disabled', () => {
|
||||
@@ -126,9 +126,9 @@ describe('LiteralTransformer', () => {
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
/^var *_0x([a-z0-9]){4} *= *\['\\x64\\x47\\x56\\x7a\\x64\\x41\\x3d\\x3d'\];/
|
||||
/^var *_0x([a-f0-9]){4} *= *\['\\x64\\x47\\x56\\x7a\\x64\\x41\\x3d\\x3d'\];/
|
||||
);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
|
||||
});
|
||||
|
||||
it('should replace literal node value with value from string array encoded using rc4', () => {
|
||||
@@ -144,7 +144,7 @@ describe('LiteralTransformer', () => {
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
/var *test *= *_0x([a-z0-9]){4}\('0x0', '(\\x[a-f0-9]*){4}'\);/
|
||||
/var *test *= *_0x([a-f0-9]){4}\('0x0', '(\\x[a-f0-9]*){4}'\);/
|
||||
);
|
||||
});
|
||||
|
||||
@@ -161,7 +161,7 @@ describe('LiteralTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
const regExp1: RegExp = /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/g;
|
||||
const regExp1: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/g;
|
||||
const regExp2: RegExp = /var *test *= *'\\x74\\x65\\x73\\x74';/g;
|
||||
const stringArrayMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp1)!.length;
|
||||
const noStringArrayMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp2)!.length;
|
||||
|
||||
+4
-4
@@ -31,8 +31,8 @@ describe('MemberExpressionTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *console\[_0x([a-z0-9]){4}\('0x0'\)\];/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-f0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *console\[_0x([a-f0-9]){4}\('0x0'\)\];/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -47,8 +47,8 @@ describe('MemberExpressionTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *console\[_0x([a-z0-9]){4}\('0x0'\)\];/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-f0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *console\[_0x([a-f0-9]){4}\('0x0'\)\];/);
|
||||
});
|
||||
|
||||
it('should ignore square brackets call with identifier value', () => {
|
||||
|
||||
+2
-2
@@ -32,8 +32,8 @@ describe('MethodDefinitionTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4} *= *\['\\x62\\x61\\x72'\];/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /\[_0x([a-z0-9]){4}\('0x0'\)\]\(\)\{\}/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-f0-9]){4} *= *\['\\x62\\x61\\x72'\];/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /\[_0x([a-f0-9]){4}\('0x0'\)\]\(\)\{\}/);
|
||||
});
|
||||
|
||||
it('should not transform method definition node with `constructor` key', () => {
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ describe('ObjectExpressionTransformer', () => {
|
||||
|
||||
assert.match(
|
||||
obfuscationResult.getObfuscatedCode(),
|
||||
/var *_0x[a-z0-9]{4,6} *= *\{'\\x61': *_0x[a-z0-9]{4,6}\, *'\\x62': *_0x[a-z0-9]{4,6}\};/
|
||||
/var *_0x[a-f0-9]{4,6} *= *\{'\\x61': *_0x[a-f0-9]{4,6}\, *'\\x62': *_0x[a-f0-9]{4,6}\};/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
+98
-37
@@ -17,8 +17,8 @@ describe('VariableDeclarationTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4,6} *= *'\\x61\\x62\\x63';/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-f0-9]){4,6} *= *'\\x61\\x62\\x63';/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
|
||||
});
|
||||
|
||||
it('should not transform `variableDeclaration` node if parent block scope node is `Program` node', () => {
|
||||
@@ -41,7 +41,7 @@ describe('VariableDeclarationTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
|
||||
});
|
||||
|
||||
it('should not transform variable call (`identifier` node) outside of block scope of node in which this variable was declared with `let` kind', () => {
|
||||
@@ -68,57 +68,100 @@ describe('VariableDeclarationTransformer', () => {
|
||||
});
|
||||
|
||||
it('should transform variable call (`identifier` node) before variable declaration if this call is inside function body', () => {
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\['\\x69\\x74\\x65\\x6d'\]\);/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\['\\x69\\x74\\x65\\x6d'\]\);/);
|
||||
});
|
||||
|
||||
it('should not transform variable call (`identifier` node) before variable declaration', () => {
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`variable calls before variable declaration when function param has the same name as variables name`, () => {
|
||||
let obfuscationResult: IObfuscationResult,
|
||||
functionParamIdentifierName: string|null,
|
||||
innerFunctionParamIdentifierName: string|null,
|
||||
constructorIdentifierName: string|null,
|
||||
objectIdentifierName: string|null,
|
||||
variableDeclarationIdentifierName: string|null;
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(__dirname + '/fixtures/variable-call-before-variable-declaration-2.js'),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
|
||||
beforeEach(() => {
|
||||
obfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(__dirname + '/fixtures/variable-call-before-variable-declaration-2.js'),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET
|
||||
}
|
||||
);
|
||||
const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/function *_0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\,(_0x[a-f0-9]{4,6})\) *\{/);
|
||||
const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/);
|
||||
const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
|
||||
const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/return\{'\\x74':(_0x[a-f0-9]{4,6})\}/);
|
||||
const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/var *(_0x[a-f0-9]{4,6});/);
|
||||
|
||||
const outerFunctionParamIdentifierName: string|null = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
|
||||
const innerFunctionParamIdentifierName: string|null = (<RegExpMatchArray>innerFunctionParamIdentifierMatch)[1];
|
||||
const constructorIdentifierName: string|null = (<RegExpMatchArray>constructorIdentifierMatch)[1];
|
||||
const objectIdentifierName: string|null = (<RegExpMatchArray>objectIdentifierMatch)[1];
|
||||
const variableDeclarationIdentifierName: string|null = (<RegExpMatchArray>variableDeclarationIdentifierMatch)[1];
|
||||
|
||||
it('should\'t name variables inside inner function with names from outer function params', () => {
|
||||
assert.notEqual(outerFunctionParamIdentifierName, constructorIdentifierName);
|
||||
assert.notEqual(outerFunctionParamIdentifierName, innerFunctionParamIdentifierName);
|
||||
});
|
||||
|
||||
it('should correct transform variables inside function body', () => {
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/function *_0x[a-z0-9]{4,6} *\((_0x[a-z0-9]{4,6})\,(_0x[a-z0-9]{4,6})\) *\{/);
|
||||
const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/function _0x[a-z0-9]{4,6} *\((_0x[a-z0-9]{4,6})\) *\{/);
|
||||
const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-z0-9]{4,6})\)/);
|
||||
const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/return\{'\\x74':(_0x[a-z0-9]{4,6})\}/);
|
||||
const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/var *(_0x[a-z0-9]{4,6});/);
|
||||
it('should correct transform variables inside outer function body', () => {
|
||||
assert.equal(outerFunctionParamIdentifierName, objectIdentifierName);
|
||||
assert.equal(outerFunctionParamIdentifierName, variableDeclarationIdentifierName);
|
||||
});
|
||||
|
||||
functionParamIdentifierName = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
|
||||
innerFunctionParamIdentifierName = (<RegExpMatchArray>innerFunctionParamIdentifierMatch)[1];
|
||||
constructorIdentifierName = (<RegExpMatchArray>constructorIdentifierMatch)[1];
|
||||
objectIdentifierName = (<RegExpMatchArray>objectIdentifierMatch)[1];
|
||||
variableDeclarationIdentifierName = (<RegExpMatchArray>variableDeclarationIdentifierMatch)[1];
|
||||
it('should correct transform variables inside inner function body', () => {
|
||||
assert.equal(innerFunctionParamIdentifierName, constructorIdentifierName);
|
||||
});
|
||||
|
||||
it('should keep equal names after transformation for variables with same names', () => {
|
||||
assert.equal(variableDeclarationIdentifierName, objectIdentifierName);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`variable calls before variable declaration when catch clause param has the same name as variables name`, () => {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(__dirname + '/fixtures/variable-call-before-variable-declaration-3.js'),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
|
||||
const catchClauseParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/catch *\((_0x[a-f0-9]{4,6})\) *\{/);
|
||||
const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/);
|
||||
const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
|
||||
const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/return\{'\\x74':(_0x[a-f0-9]{4,6})\}/);
|
||||
const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
|
||||
.match(/var *(_0x[a-f0-9]{4,6});/);
|
||||
|
||||
const functionParamIdentifierName: string|null = (<RegExpMatchArray>catchClauseParamIdentifierMatch)[1];
|
||||
const innerFunctionParamIdentifierName: string|null = (<RegExpMatchArray>innerFunctionParamIdentifierMatch)[1];
|
||||
const constructorIdentifierName: string|null = (<RegExpMatchArray>constructorIdentifierMatch)[1];
|
||||
const objectIdentifierName: string|null = (<RegExpMatchArray>objectIdentifierMatch)[1];
|
||||
const variableDeclarationIdentifierName: string|null = (<RegExpMatchArray>variableDeclarationIdentifierMatch)[1];
|
||||
|
||||
it('should\'t name variables inside inner function with names from catch clause param', () => {
|
||||
assert.notEqual(functionParamIdentifierName, constructorIdentifierName);
|
||||
assert.notEqual(functionParamIdentifierName, innerFunctionParamIdentifierName);
|
||||
});
|
||||
|
||||
it('should correct transform variables inside catch clause body', () => {
|
||||
assert.equal(functionParamIdentifierName, objectIdentifierName);
|
||||
assert.equal(functionParamIdentifierName, variableDeclarationIdentifierName);
|
||||
});
|
||||
|
||||
it('should correct transform variables inside inner function body', () => {
|
||||
assert.equal(innerFunctionParamIdentifierName, constructorIdentifierName);
|
||||
});
|
||||
|
||||
it('should keep equal names after transformation for variables with same names', () => {
|
||||
assert.equal(variableDeclarationIdentifierName, objectIdentifierName);
|
||||
});
|
||||
});
|
||||
@@ -132,7 +175,7 @@ describe('VariableDeclarationTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var _0x([a-z0-9]){4,6} *= *\{'\\x74\\x65\\x73\\x74/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /var _0x([a-f0-9]){4,6} *= *\{'\\x74\\x65\\x73\\x74/);
|
||||
});
|
||||
|
||||
it('shouldn\'t replace computed member expression identifier', () => {
|
||||
@@ -143,7 +186,25 @@ describe('VariableDeclarationTransformer', () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /_0x([a-z0-9]){4,6}\['\\x74\\x65\\x73\\x74'\]/);
|
||||
assert.match(obfuscationResult.getObfuscatedCode(), /_0x([a-f0-9]){4,6}\['\\x74\\x65\\x73\\x74'\]/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('object pattern as variable declarator', () => {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(__dirname + '/fixtures/object-pattern.js'),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
|
||||
it('shouldn\'t transform object pattern variable declarator', () => {
|
||||
const objectPatternVariableDeclarator: RegExp = /var *\{ *bar *\} *= *\{ *'\\x62\\x61\\x72' *: *'\\x66\\x6f\\x6f' *\};/;
|
||||
const variableUsageMatch: RegExp = /console\['\\x6c\\x6f\\x67'\]\(bar\);/;
|
||||
|
||||
assert.match(obfuscatedCode, objectPatternVariableDeclarator);
|
||||
assert.match(obfuscatedCode, variableUsageMatch);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
(function () {
|
||||
var { bar } = { bar: 'foo' };
|
||||
console.log(bar);
|
||||
})();
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
(function () {
|
||||
try {
|
||||
|
||||
} catch (t) {
|
||||
return function () {
|
||||
function baz (t) {
|
||||
console.log(t);
|
||||
}
|
||||
|
||||
return {t: t};
|
||||
var t;
|
||||
}();
|
||||
}
|
||||
})();
|
||||
@@ -5,8 +5,8 @@ import { RandomGeneratorUtils } from '../../../../src/utils/RandomGeneratorUtils
|
||||
describe('RandomGeneratorUtils', () => {
|
||||
describe('getRandomVariableName (length: number = 6): string', () => {
|
||||
it('should return a string of given length with random variable name', () => {
|
||||
assert.match(RandomGeneratorUtils.getRandomVariableName(4, true, false), /^_0x(\w){4}$/);
|
||||
assert.match(RandomGeneratorUtils.getRandomVariableName(6, true, true), /^_0x(\w){4,6}$/);
|
||||
assert.match(RandomGeneratorUtils.getRandomVariableName(4), /^_0x(\w){4}$/);
|
||||
assert.match(RandomGeneratorUtils.getRandomVariableName(6), /^_0x(\w){4,6}$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+5
-1
@@ -29,6 +29,7 @@
|
||||
true,
|
||||
"always-prefix"
|
||||
],
|
||||
"import-spacing": true,
|
||||
"jsdoc-format": true,
|
||||
"label-position": true,
|
||||
"max-line-length": false,
|
||||
@@ -66,7 +67,7 @@
|
||||
"no-parameter-properties": true,
|
||||
"no-reference": true,
|
||||
"no-require-imports": false,
|
||||
"no-shadowed-variable": false,
|
||||
"no-shadowed-variable": true,
|
||||
"no-string-literal": true,
|
||||
"no-string-throw": true,
|
||||
"no-switch-case-fall-through": false,
|
||||
@@ -89,6 +90,7 @@
|
||||
"quotemark": false,
|
||||
"radix": true,
|
||||
"semicolon": [true, "always"],
|
||||
"space-before-function-paren": true,
|
||||
"switch-default": false,
|
||||
"trailing-comma": false,
|
||||
"triple-equals": [
|
||||
@@ -122,6 +124,8 @@
|
||||
"variable-declaration": "space"
|
||||
}
|
||||
],
|
||||
"typeof-compare": true,
|
||||
"unified-signatures": true,
|
||||
"use-isnan": true,
|
||||
"variable-name": false,
|
||||
"whitespace": [
|
||||
|
||||
Reference in New Issue
Block a user