From ac9c10a69aaaa0dfca9d6861e8365b64650f04cc Mon Sep 17 00:00:00 2001 From: sanex3339 Date: Wed, 9 Nov 2016 00:47:55 +0300 Subject: [PATCH] Fixed obfuscation of global variables and function names in some cases --- CHANGELOG.md | 1 + dist/index.js | 17 +-- .../FunctionDeclarationObfuscator.ts | 17 +-- .../VariableDeclarationObfuscator.ts | 22 ++-- test/dev/dev-runtime-performance.ts | 104 +++++++++--------- .../VariableDeclarationObfuscator.spec.ts | 36 ++++-- .../FunctionDeclarationObfuscator.spec.ts | 4 +- 7 files changed, 114 insertions(+), 87 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bff20cd3..58b56357 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ v0.8.0 * New option `domainLock` locks the obfuscated source code so it only runs on specific domains and/or sub-domains. * New option `sourceMapBaseUrl` sets base url to the source map import url when `sourceMapMode: 'separate'`. * Custom nodes like `selfDefendingNode` or `consoleOutputNode` now inserted into deepest stack trace function call. +* Fixed obfuscation of global variables and function names in some cases * Rewrite of many custom nodes. v0.7.3 diff --git a/dist/index.js b/dist/index.js index 11280627..ba7b9448 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2908,11 +2908,12 @@ var FunctionDeclarationObfuscator = function (_AbstractNodeObfuscat) { _createClass(FunctionDeclarationObfuscator, [{ key: 'obfuscateNode', value: function obfuscateNode(functionDeclarationNode, parentNode) { - if (parentNode.type === NodeType_1.NodeType.Program) { + var blockScopeOfFunctionDeclarationNode = NodeUtils_1.NodeUtils.getBlockScopeOfNode(functionDeclarationNode); + if (blockScopeOfFunctionDeclarationNode.type === NodeType_1.NodeType.Program) { return; } this.storeFunctionName(functionDeclarationNode); - this.replaceFunctionName(functionDeclarationNode); + this.replaceFunctionName(blockScopeOfFunctionDeclarationNode); } }, { key: 'storeFunctionName', @@ -2927,10 +2928,9 @@ var FunctionDeclarationObfuscator = function (_AbstractNodeObfuscat) { } }, { key: 'replaceFunctionName', - value: function replaceFunctionName(functionDeclarationNode) { + value: function replaceFunctionName(scopeNode) { var _this3 = this; - var scopeNode = NodeUtils_1.NodeUtils.getBlockScopeOfNode(functionDeclarationNode); estraverse.replace(scopeNode, { enter: function enter(node, parentNode) { if (Node_1.Node.isReplaceableIdentifierNode(node, parentNode)) { @@ -3361,11 +3361,13 @@ var VariableDeclarationObfuscator = function (_AbstractNodeObfuscat) { _createClass(VariableDeclarationObfuscator, [{ key: 'obfuscateNode', value: function obfuscateNode(variableDeclarationNode, parentNode) { - if (parentNode.type === NodeType_1.NodeType.Program) { + var blockScopeOfVariableDeclarationNode = NodeUtils_1.NodeUtils.getBlockScopeOfNode(variableDeclarationNode); + if (blockScopeOfVariableDeclarationNode.type === NodeType_1.NodeType.Program) { return; } + var scopeNode = variableDeclarationNode.kind === 'var' ? blockScopeOfVariableDeclarationNode : parentNode; this.storeVariableNames(variableDeclarationNode); - this.replaceVariableNames(variableDeclarationNode, parentNode); + this.replaceVariableNames(scopeNode); } }, { key: 'storeVariableNames', @@ -3382,10 +3384,9 @@ var VariableDeclarationObfuscator = function (_AbstractNodeObfuscat) { } }, { key: 'replaceVariableNames', - value: function replaceVariableNames(variableDeclarationNode, variableParentNode) { + value: function replaceVariableNames(scopeNode) { var _this3 = this; - var scopeNode = variableDeclarationNode.kind === 'var' ? NodeUtils_1.NodeUtils.getBlockScopeOfNode(variableDeclarationNode) : variableParentNode; estraverse.replace(scopeNode, { enter: function enter(node, parentNode) { if (!node.obfuscated && Node_1.Node.isReplaceableIdentifierNode(node, parentNode)) { diff --git a/src/node-obfuscators/FunctionDeclarationObfuscator.ts b/src/node-obfuscators/FunctionDeclarationObfuscator.ts index b7cf5f2d..84bbed41 100644 --- a/src/node-obfuscators/FunctionDeclarationObfuscator.ts +++ b/src/node-obfuscators/FunctionDeclarationObfuscator.ts @@ -1,6 +1,8 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; +import { TNodeWithBlockStatement } from '../types/TNodeWithBlockStatement'; + import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../interfaces/IOptions'; @@ -41,12 +43,15 @@ export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator { * @param parentNode */ public obfuscateNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): void { - if (parentNode.type === NodeType.Program) { + const blockScopeOfFunctionDeclarationNode: TNodeWithBlockStatement = NodeUtils + .getBlockScopeOfNode(functionDeclarationNode); + + if (blockScopeOfFunctionDeclarationNode.type === NodeType.Program) { return; } this.storeFunctionName(functionDeclarationNode); - this.replaceFunctionName(functionDeclarationNode); + this.replaceFunctionName(blockScopeOfFunctionDeclarationNode); } /** @@ -59,13 +64,9 @@ export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator { } /** - * @param functionDeclarationNode + * @param scopeNode */ - private replaceFunctionName (functionDeclarationNode: ESTree.FunctionDeclaration): void { - let scopeNode: ESTree.Node = NodeUtils.getBlockScopeOfNode( - functionDeclarationNode - ); - + private replaceFunctionName (scopeNode: ESTree.Node): void { estraverse.replace(scopeNode, { enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { if (Node.isReplaceableIdentifierNode(node, parentNode)) { diff --git a/src/node-obfuscators/VariableDeclarationObfuscator.ts b/src/node-obfuscators/VariableDeclarationObfuscator.ts index 891d1a9d..4ebc7a2a 100644 --- a/src/node-obfuscators/VariableDeclarationObfuscator.ts +++ b/src/node-obfuscators/VariableDeclarationObfuscator.ts @@ -1,6 +1,8 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; +import { TNodeWithBlockStatement } from '../types/TNodeWithBlockStatement'; + import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../interfaces/IOptions'; @@ -42,12 +44,19 @@ export class VariableDeclarationObfuscator extends AbstractNodeObfuscator { * @param parentNode */ public obfuscateNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void { - if (parentNode.type === NodeType.Program) { + const blockScopeOfVariableDeclarationNode: TNodeWithBlockStatement = NodeUtils + .getBlockScopeOfNode(variableDeclarationNode); + + if (blockScopeOfVariableDeclarationNode.type === NodeType.Program) { return; } + const scopeNode: ESTree.Node = variableDeclarationNode.kind === 'var' + ? blockScopeOfVariableDeclarationNode + : parentNode; + this.storeVariableNames(variableDeclarationNode); - this.replaceVariableNames(variableDeclarationNode, parentNode); + this.replaceVariableNames(scopeNode); } /** @@ -63,14 +72,9 @@ export class VariableDeclarationObfuscator extends AbstractNodeObfuscator { } /** - * @param variableDeclarationNode - * @param variableParentNode + * @param scopeNode */ - private replaceVariableNames (variableDeclarationNode: ESTree.VariableDeclaration, variableParentNode: ESTree.Node): void { - let scopeNode: ESTree.Node = variableDeclarationNode.kind === 'var' ? NodeUtils.getBlockScopeOfNode( - variableDeclarationNode - ) : variableParentNode; - + private replaceVariableNames (scopeNode: ESTree.Node): void { estraverse.replace(scopeNode, { enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { if (!node.obfuscated && Node.isReplaceableIdentifierNode(node, parentNode)) { diff --git a/test/dev/dev-runtime-performance.ts b/test/dev/dev-runtime-performance.ts index 9e903b71..271b9c5b 100644 --- a/test/dev/dev-runtime-performance.ts +++ b/test/dev/dev-runtime-performance.ts @@ -14,62 +14,64 @@ if (!(global)._babelPolyfill) { console.log = function () {}; ${String(` - 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) { + (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); - if (true) { - var test = 5 + var test = function (test) { + console.log(test); + + if (true) { + var test = 5 + } + + return test; } - return test; - } - - console.log(test(1)); - - function test2 (abc) { - function test1 () { - console.log('inside', abc.item); + 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); } - - 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); - } + })(); `).repeat(1000)} console.log = log; diff --git a/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts b/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts index 74fa0e2e..28fd2333 100644 --- a/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts +++ b/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts @@ -22,11 +22,10 @@ describe('VariableDeclarationObfuscator', () => { assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/); }); - it('should obfuscate variable call (`identifier` node) outside of block scope of node in which this variable was declared with `var` kind', () => { + it('should not obfuscate `variableDeclaration` node if parent block scope node is `Program` node', () => { let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( ` - if (true) - { + if (true) { var test = 10; } @@ -35,18 +34,37 @@ describe('VariableDeclarationObfuscator', () => { Object.assign({}, NO_CUSTOM_NODES_PRESET) ); + assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *0xa;/); + assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(test\);/); + }); + + it('should obfuscate variable call (`identifier` node) outside of block scope of node in which this variable was declared with `var` kind', () => { + let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + ` + (function () { + if (true) { + var test = 10; + } + + console.log(test); + })(); + `, + Object.assign({}, NO_CUSTOM_NODES_PRESET) + ); + assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/); }); it('should not obfuscate variable call (`identifier` node) outside of block scope of node in which this variable was declared with `let` kind', () => { let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( ` - if (true) - { - let test = 10; - } - - console.log(test); + (function () { + if (true) { + let test = 10; + } + + console.log(test); + })(); `, Object.assign({}, NO_CUSTOM_NODES_PRESET) ); diff --git a/test/unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec.ts b/test/unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec.ts index e9394226..eb0fb824 100644 --- a/test/unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec.ts +++ b/test/unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec.ts @@ -34,7 +34,7 @@ describe('FunctionDeclarationObfuscator', () => { ); }); - describe('if `functionDeclaration` node parent node is not a Program node', () => { + describe('if `functionDeclaration` node parent block scope is not a Program node', () => { let blockStatementNode: ESTree.BlockStatement, functionDeclarationParentNode: ESTree.FunctionDeclaration; @@ -74,7 +74,7 @@ describe('FunctionDeclarationObfuscator', () => { }); }); - describe('if `functionDeclaration` node parent node is a Program node', () => { + describe('if `functionDeclaration` node parent block scope node is a Program node', () => { beforeEach(() => { programNode = NodeMocks.getProgramNode([ functionDeclarationNode