diff --git a/index.js b/index.js index 879f57db..a3fa20a1 100644 --- a/index.js +++ b/index.js @@ -5,14 +5,20 @@ class JavaScriptObfuscator { static obfuscate(sourceCode, options) { let astTree = esprima.parse(sourceCode), obfuscator = new Obfuscator_1.Obfuscator(options); obfuscator.obfuscateNode(astTree); - return JavaScriptObfuscator.generateCode(astTree); + return JavaScriptObfuscator.generateCode(astTree, options); } - static generateCode(astTree) { - return escodegen.generate(astTree, JavaScriptObfuscator.escodegenParams); + static generateCode(astTree, options) { + let escodegenParams = Object.assign({}, JavaScriptObfuscator.escodegenParams); + if (options.compact !== undefined) { + escodegenParams.format.compact = options.compact; + } + return escodegen.generate(astTree, escodegenParams); } } JavaScriptObfuscator.escodegenParams = { - format: {}, + format: { + compact: true + }, verbatim: 'x-verbatim-property' }; exports.JavaScriptObfuscator = JavaScriptObfuscator; diff --git a/src/Obfuscator.js b/src/Obfuscator.js index b84fc044..45cdcbc2 100644 --- a/src/Obfuscator.js +++ b/src/Obfuscator.js @@ -37,7 +37,7 @@ class Obfuscator { } obfuscateNode(node) { if (this.options['rotateUnicodeArray']) { - this.setNodesGroup('unicodeArrayNodesGroup', new UnicodeArrayNodesGroup_1.UnicodeArrayNodesGroup(node)); + this.setNodesGroup(new UnicodeArrayNodesGroup_1.UnicodeArrayNodesGroup(node)); } else { this.setNode('unicodeArrayNode', new UnicodeArrayNode_1.UnicodeArrayNode(node, Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH))); @@ -52,7 +52,7 @@ class Obfuscator { setNode(nodeName, node) { this.nodes.set(nodeName, node); } - setNodesGroup(groupName, nodesGroup) { + setNodesGroup(nodesGroup) { let nodes = nodesGroup.getNodes(); nodes.forEach((node, key) => { this.nodes.set(key, node); diff --git a/src/node-obfuscators/VariableDeclarationObfuscator.js b/src/node-obfuscators/VariableDeclarationObfuscator.js index f023c533..5fdc0360 100644 --- a/src/node-obfuscators/VariableDeclarationObfuscator.js +++ b/src/node-obfuscators/VariableDeclarationObfuscator.js @@ -1,12 +1,12 @@ "use strict"; const NodeObfuscator_1 = require('./NodeObfuscator'); -const Utils_1 = require('../Utils'); const NodeUtils_1 = require("../NodeUtils"); +const Utils_1 = require('../Utils'); let estraverse = require('estraverse'); class VariableDeclarationObfuscator extends NodeObfuscator_1.NodeObfuscator { constructor(...args) { super(...args); - this.variableName = new Map(); + this.variableNames = new Map(); } obfuscateNode(variableDeclarationNode, parentNode) { if (parentNode.type === 'Program') { @@ -24,8 +24,8 @@ class VariableDeclarationObfuscator extends NodeObfuscator_1.NodeObfuscator { } estraverse.replace(node.id, { enter: (node) => { - this.variableName.set(node.name, Utils_1.Utils.getRandomVariableName()); - node.name = this.variableName.get(node.name); + this.variableNames.set(node.name, Utils_1.Utils.getRandomVariableName()); + node.name = this.variableNames.get(node.name); } }); } @@ -33,16 +33,36 @@ class VariableDeclarationObfuscator extends NodeObfuscator_1.NodeObfuscator { }); } replaceVariableCalls(variableDeclarationNode, variableParentNode) { - let scopeNode, statementNode; + let scopeNode; if (variableDeclarationNode.kind === 'var') { scopeNode = NodeUtils_1.NodeUtils.getNodeScope(variableDeclarationNode); } else { scopeNode = variableParentNode; } + let isNodeAfterVariableDeclaratorFlag = false, isNodeBeforeVariableDeclaratorFlag = true, functionParentScope, functionNextNode, functionIndex = -1; estraverse.replace(scopeNode, { enter: (node, parentNode) => { - this.replaceNodeIdentifierByNewValue(node, parentNode, this.variableName); + if (node.parentNode && (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression')) { + functionParentScope = NodeUtils_1.NodeUtils.getNodeScope(node); + functionIndex = functionParentScope.body.indexOf(node); + if (functionIndex >= 0) { + functionNextNode = functionParentScope.body[functionIndex + 1]; + } + isNodeAfterVariableDeclaratorFlag = true; + } + if (functionNextNode && isNodeBeforeVariableDeclaratorFlag && node === functionNextNode) { + isNodeAfterVariableDeclaratorFlag = false; + functionNextNode = undefined; + functionIndex = -1; + } + if (node === variableDeclarationNode) { + isNodeAfterVariableDeclaratorFlag = true; + isNodeBeforeVariableDeclaratorFlag = false; + } + if (isNodeAfterVariableDeclaratorFlag) { + this.replaceNodeIdentifierByNewValue(node, parentNode, this.variableNames); + } } }); } diff --git a/src/node-obfuscators/VariableDeclarationObfuscator.ts b/src/node-obfuscators/VariableDeclarationObfuscator.ts index 40e408b8..27fb99ac 100644 --- a/src/node-obfuscators/VariableDeclarationObfuscator.ts +++ b/src/node-obfuscators/VariableDeclarationObfuscator.ts @@ -18,7 +18,7 @@ export class VariableDeclarationObfuscator extends NodeObfuscator { /** * @type {Map} */ - private variableName: Map = new Map (); + private variableNames: Map = new Map (); /** * @param variableDeclarationNode @@ -46,8 +46,8 @@ export class VariableDeclarationObfuscator extends NodeObfuscator { estraverse.replace(node.id, { enter: (node) => { - this.variableName.set(node.name, Utils.getRandomVariableName()); - node.name = this.variableName.get(node.name); + this.variableNames.set(node.name, Utils.getRandomVariableName()); + node.name = this.variableNames.get(node.name); } }); } @@ -60,8 +60,7 @@ export class VariableDeclarationObfuscator extends NodeObfuscator { * @param variableParentNode */ private replaceVariableCalls (variableDeclarationNode: any, variableParentNode: any): void { - let scopeNode: any, - statementNode: any; + let scopeNode: any; if (variableDeclarationNode.kind === 'var') { scopeNode = NodeUtils.getNodeScope( @@ -71,9 +70,42 @@ export class VariableDeclarationObfuscator extends NodeObfuscator { scopeNode = variableParentNode; } + let isNodeAfterVariableDeclaratorFlag: boolean = false, + isNodeBeforeVariableDeclaratorFlag: boolean = true, + functionParentScope: any, + functionNextNode: any, + functionIndex: number = -1; + estraverse.replace(scopeNode, { enter: (node, parentNode) => { - this.replaceNodeIdentifierByNewValue(node, parentNode, this.variableName); + if (node.parentNode && (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression')) { + functionParentScope = NodeUtils.getNodeScope( + node + ); + + functionIndex = functionParentScope.body.indexOf(node); + + if (functionIndex >= 0) { + functionNextNode = functionParentScope.body[functionIndex + 1]; + } + + isNodeAfterVariableDeclaratorFlag = true; + } + + if (functionNextNode && isNodeBeforeVariableDeclaratorFlag && node === functionNextNode) { + isNodeAfterVariableDeclaratorFlag = false; + functionNextNode = undefined; + functionIndex = -1; + } + + if (node === variableDeclarationNode) { + isNodeAfterVariableDeclaratorFlag = true; + isNodeBeforeVariableDeclaratorFlag = false; + } + + if (isNodeAfterVariableDeclaratorFlag) { + this.replaceNodeIdentifierByNewValue(node, parentNode, this.variableNames); + } } }); } diff --git a/tests/dev-test.js b/tests/dev-test.js index 7690c733..7ab801df 100644 --- a/tests/dev-test.js +++ b/tests/dev-test.js @@ -16,6 +16,32 @@ var obfuscatedCode = JavaScriptObfuscator.obfuscate(` } console.log(test); + + var test = function (test) { + console.log(test); + + if (true) { + var test = 5 + } + + return test; + } + + console.log(test(1)); + + function test2 (abc) { + function test1 () { + console.log('inside', abc.item); + } + + console.log('between', abc); + + var abc = {}; + + return abc.item = 15, test1(); + }; + + test2(22); })(); `, { rotateUnicodeArray: false diff --git a/tests/dev-test.ts b/tests/dev-test.ts index a8467ba5..adbd31c9 100644 --- a/tests/dev-test.ts +++ b/tests/dev-test.ts @@ -18,6 +18,32 @@ var obfuscatedCode = JavaScriptObfuscator.obfuscate( } console.log(test); + + var test = function (test) { + console.log(test); + + if (true) { + var test = 5 + } + + return test; + } + + console.log(test(1)); + + function test2 (abc) { + function test1 () { + console.log('inside', abc.item); + } + + console.log('between', abc); + + var abc = {}; + + return abc.item = 15, test1(); + }; + + test2(22); })(); `, {