Przeglądaj źródła

Fixed obfuscation of global variables and function names in some cases

sanex3339 8 lat temu
rodzic
commit
ac9c10a69a

+ 1 - 0
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

+ 9 - 8
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)) {

+ 9 - 8
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)) {

+ 13 - 9
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)) {

+ 51 - 49
test/dev/dev-runtime-performance.ts

@@ -14,62 +14,64 @@ if (!(<any>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));
             
-            console.log('тест', abc);
+            function test2 (abc) {
+                function test1 () {
+                  console.log('inside', abc.item);
+                }
+                
+                console.log('тест', abc);
+                
+                var abc = {};
+                
+                return abc.item = 15, test1();
+            };
             
-            var abc = {};
+            var regexptest = /version\\/(\\d+)/i;
+            console.log(regexptest);
             
-            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);
-        }
+            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;

+ 27 - 9
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)
         );

+ 2 - 2
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