Browse Source

Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/289

sanex3339 6 years ago
parent
commit
a06b23af98

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 ===
+v0.18.0
+---
+* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/289
+
 v0.17.0
 ---
 * **Browser version**: Added browser version dist

File diff suppressed because it is too large
+ 0 - 0
dist/index.browser.js


File diff suppressed because it is too large
+ 0 - 0
dist/index.cli.js


File diff suppressed because it is too large
+ 0 - 0
dist/index.js


+ 12 - 12
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.17.0",
+  "version": "0.18.0-dev.1",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -21,11 +21,11 @@
   },
   "types": "index.d.ts",
   "dependencies": {
-    "@babel/runtime": "7.0.0-beta.51",
+    "@babel/runtime": "7.0.0-beta.53",
     "chalk": "2.4.1",
     "chance": "1.0.16",
     "class-validator": "0.8.5",
-    "commander": "2.15.1",
+    "commander": "2.16.0",
     "escodegen-wallaby": "1.6.18",
     "espree": "4.0.0",
     "estraverse": "4.2.0",
@@ -41,10 +41,10 @@
     "tslib": "1.9.3"
   },
   "devDependencies": {
-    "@babel/cli": "7.0.0-beta.51",
-    "@babel/core": "7.0.0-beta.51",
-    "@babel/plugin-transform-runtime": "7.0.0-beta.51",
-    "@babel/preset-env": "7.0.0-beta.51",
+    "@babel/cli": "7.0.0-beta.53",
+    "@babel/core": "7.0.0-beta.53",
+    "@babel/plugin-transform-runtime": "7.0.0-beta.53",
+    "@babel/preset-env": "7.0.0-beta.53",
     "@types/chai": "4.1.4",
     "@types/chance": "1.0.1",
     "@types/escodegen": "0.0.6",
@@ -52,9 +52,9 @@
     "@types/estree": "0.0.38",
     "@types/md5": "2.1.32",
     "@types/mkdirp": "0.5.2",
-    "@types/mocha": "5.2.3",
+    "@types/mocha": "5.2.4",
     "@types/multimatch": "2.1.2",
-    "@types/node": "10.3.6",
+    "@types/node": "10.5.2",
     "@types/rimraf": "2.0.2",
     "@types/sinon": "5.0.1",
     "@types/string-template": "1.0.2",
@@ -62,13 +62,13 @@
     "awesome-typescript-loader": "5.2.0",
     "babel-loader": "8.0.0-beta.3",
     "chai": "4.1.2",
-    "coveralls": "3.0.1",
+    "coveralls": "3.0.2",
     "istanbul": "1.1.0-alpha.1",
     "mocha": "5.2.0",
     "pjson": "1.0.9",
     "pre-commit": "1.2.2",
     "rimraf": "2.6.2",
-    "sinon": "6.0.1",
+    "sinon": "6.1.3",
     "threads": "0.12.0",
     "ts-node": "6.1.0",
     "tslint": "5.10.0",
@@ -77,7 +77,7 @@
     "tslint-microsoft-contrib": "5.0.3",
     "tslint-webpack-plugin": "1.2.2",
     "typescript": "2.9.2",
-    "webpack": "4.12.2",
+    "webpack": "4.16.0",
     "webpack-cli": "3.0.8",
     "webpack-node-externals": "1.7.2"
   },

+ 4 - 3
src/interfaces/utils/IEscapeSequenceEncoder.d.ts

@@ -1,7 +1,8 @@
 export interface IEscapeSequenceEncoder {
     /**
-     * @param string
-     * @param usingUnicodeEscapeSequence
+     * @param {string} string
+     * @param {boolean} encodeAllSymbols
+     * @returns {string}
      */
-    encode (string: string, usingUnicodeEscapeSequence: boolean): string;
+    encode (string: string, encodeAllSymbols: boolean): string;
 }

+ 51 - 7
src/node-transformers/converting-transformers/ObjectExpressionTransformer.ts

@@ -12,6 +12,7 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { NodeFactory } from '../../node/NodeFactory';
 import { NodeGuards } from '../../node/NodeGuards';
+import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
 
 /**
  * replaces:
@@ -23,14 +24,23 @@ import { NodeGuards } from '../../node/NodeGuards';
 @injectable()
 export class ObjectExpressionTransformer extends AbstractNodeTransformer {
     /**
+     * @type {IEscapeSequenceEncoder}
+     */
+    private readonly escapeSequenceEncoder: IEscapeSequenceEncoder;
+
+    /**
+     * @param {IEscapeSequenceEncoder} escapeSequenceEncoder
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
      */
     constructor (
+        @inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(randomGenerator, options);
+
+        this.escapeSequenceEncoder = escapeSequenceEncoder;
     }
 
     /**
@@ -61,19 +71,53 @@ export class ObjectExpressionTransformer extends AbstractNodeTransformer {
     public transformNode (objectExpressionNode: ESTree.ObjectExpression, parentNode: ESTree.Node): ESTree.Node {
         objectExpressionNode.properties
             .forEach((property: ESTree.Property) => {
-                if (property.computed || !property.key) {
+                if (!property.key) {
                     return;
                 }
 
-                if (property.shorthand) {
-                    property.shorthand = false;
-                }
-
-                if (NodeGuards.isIdentifierNode(property.key)) {
-                    property.key = NodeFactory.literalNode(property.key.name);
+                if (property.computed) {
+                    this.transformComputedProperty(property);
+                } else {
+                    this.transformBaseProperty(property);
                 }
             });
 
         return objectExpressionNode;
     }
+
+    /**
+     * @param {Property} property
+     */
+    private transformComputedProperty(property: ESTree.Property): void {
+        if (!NodeGuards.isLiteralNode(property.key) || !(typeof property.key.value === 'string')) {
+            return;
+        }
+
+        property.key = NodeFactory.literalNode(this.getPropertyKeyValue(property.key.value));
+    }
+
+    /**
+     * @param {Property} property
+     */
+    private transformBaseProperty(property: ESTree.Property): void {
+        if (property.shorthand) {
+            property.shorthand = false;
+        }
+
+        if (!NodeGuards.isIdentifierNode(property.key)) {
+            return;
+        }
+
+        property.key = NodeFactory.literalNode(this.getPropertyKeyValue(property.key.name));
+    }
+
+    /**
+     * @param {string} inputValue
+     * @returns {string}
+     */
+    private getPropertyKeyValue(inputValue: string): string {
+        return this.options.unicodeEscapeSequence
+            ? this.escapeSequenceEncoder.encode(inputValue, true)
+            : inputValue;
+    }
 }

+ 106 - 30
test/functional-tests/node-transformers/converting-transformers/object-expression-transformer/ObjectExpressionTransformer.spec.ts

@@ -10,24 +10,50 @@ import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFac
 
 describe('ObjectExpressionTransformer', () => {
     describe('default behaviour', () => {
-        const regExp: RegExp = /var *test *= *\{'foo':0x0\};/;
+        describe('Variant #1: `unicodeEscapeSequence` option is disabled\'', () => {
+            const regExp: RegExp = /var *test *= *\{'foo':0x0\};/;
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/property-with-identifier-value.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        unicodeEscapeSequence: false
+                    }
+                );
+
+                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+            });
+
+            it('should replace object expression node `key` property with identifier value by property with literal value', () => {
+                assert.match(obfuscatedCode, regExp);
+            });
+        });
 
-        let obfuscatedCode: string;
+        describe('Variant #2: `unicodeEscapeSequence` option is enabled', () => {
+            const regExp: RegExp = /var *test *= *\{'\\x66\\x6f\\x6f':0x0\};/;
 
-        before(() => {
-            const code: string = readFileAsString(__dirname + '/fixtures/property-with-identifier-value.js');
-            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                code,
-                {
-                    ...NO_ADDITIONAL_NODES_PRESET
-                }
-            );
+            let obfuscatedCode: string;
 
-            obfuscatedCode = obfuscationResult.getObfuscatedCode();
-       });
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/property-with-identifier-value.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        unicodeEscapeSequence: true
+                    }
+                );
 
-        it('should replace object expression node `key` property with identifier value by property with literal value', () => {
-            assert.match(obfuscatedCode, regExp);
+                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+            });
+
+            it('should replace object expression node `key` property with identifier value by property with encoded literal value', () => {
+                assert.match(obfuscatedCode, regExp);
+            });
         });
     });
 
@@ -54,24 +80,74 @@ describe('ObjectExpressionTransformer', () => {
     });
 
     describe('computed property name', () => {
-        const regExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\[_0x[a-f0-9]{4,6}\]: *0x1\};/;
-
-        let obfuscatedCode: string;
-
-        before(() => {
-            const code: string = readFileAsString(__dirname + '/fixtures/computed-property-name.js');
-            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                code,
-                {
-                    ...NO_ADDITIONAL_NODES_PRESET
-                }
-            );
-
-            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+        describe('Variant #1: computed property name with identifier', () => {
+            const regExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\[_0x[a-f0-9]{4,6}\]: *0x1\};/;
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/computed-property-name-identifier.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET
+                    }
+                );
+
+                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+            });
+
+            it('should ignore computed property identifier', () => {
+                assert.match(obfuscatedCode, regExp);
+            });
         });
 
-        it('should ignore computed property identifier', () => {
-            assert.match(obfuscatedCode, regExp);
+        describe('Variant #2: computed property name with literal', () => {
+            describe('Variant #1: `unicodeEscapeSequence` option is disabled', () => {
+                const regExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\['foo'\]: *0x1\};/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/computed-property-name-literal.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            unicodeEscapeSequence: false
+                        }
+                    );
+
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                });
+
+                it('should ignore computed property identifier', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+
+            describe('Variant #2: `unicodeEscapeSequence` option is enabled', () => {
+                const regExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\['\\x66\\x6f\\x6f'\]: *0x1\};/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/computed-property-name-literal.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            unicodeEscapeSequence: true
+                        }
+                    );
+
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                });
+
+                it('should ignore computed property identifier', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
         });
     });
 

+ 0 - 0
test/functional-tests/node-transformers/converting-transformers/object-expression-transformer/fixtures/computed-property-name.js → test/functional-tests/node-transformers/converting-transformers/object-expression-transformer/fixtures/computed-property-name-identifier.js


+ 5 - 0
test/functional-tests/node-transformers/converting-transformers/object-expression-transformer/fixtures/computed-property-name-literal.js

@@ -0,0 +1,5 @@
+(function () {
+    var test = {
+        ['foo']: 1
+    };
+})();

File diff suppressed because it is too large
+ 468 - 463
yarn.lock


Some files were not shown because too many files changed in this diff