sanex3339 8 лет назад
Родитель
Сommit
2a19c82d63

+ 0 - 3
README.md

@@ -25,9 +25,6 @@ Example of obfuscated code: [gist.github.com](https://gist.github.com/sanex3339/
 [![Build Status](https://travis-ci.org/javascript-obfuscator/javascript-obfuscator.svg?branch=master)](https://travis-ci.org/javascript-obfuscator/javascript-obfuscator)
 [![Coverage Status](https://coveralls.io/repos/github/javascript-obfuscator/javascript-obfuscator/badge.svg?branch=master)](https://coveralls.io/github/javascript-obfuscator/javascript-obfuscator?branch=master)
 
-[![Dependency Status](https://david-dm.org/javascript-obfuscator/javascript-obfuscator.svg)](https://david-dm.org/javascript-obfuscator/javascript-obfuscator)
-[![devDependency Status](https://david-dm.org/javascript-obfuscator/javascript-obfuscator/dev-status.svg)](https://david-dm.org/javascript-obfuscator/javascript-obfuscator#info=devDependencies)
-
 ## :warning: Important
 #####Obfuscate only the code that belongs to you. 
 

Разница между файлами не показана из-за своего большого размера
+ 151 - 140
dist/index.js


+ 7 - 7
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.9.0-dev.3",
+  "version": "0.9.0-dev.4",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -31,10 +31,10 @@
     "inversify": "^3.0.0-rc.2",
     "lodash": "^4.17.2",
     "mkdirp": "0.5.1",
-    "reflect-metadata": "^0.1.8",
-    "source-map-support": "0.4.6",
+    "reflect-metadata": "^0.1.9",
+    "source-map-support": "0.4.7",
     "string-template": "^1.0.0",
-    "tslib": "^1.2.0"
+    "tslib": "^1.4.0"
   },
   "devDependencies": {
     "@types/chai": "3.4.34",
@@ -55,16 +55,16 @@
     "babel-loader": "6.2.10",
     "babel-plugin-transform-runtime": "^6.15.0",
     "babel-preset-es2015": "6.18.0",
-    "chai": "3.5.0",
+    "chai": "4.0.0-canary.1",
     "coveralls": "2.11.15",
     "istanbul": "1.1.0-alpha.1",
     "mocha": "3.2.0",
-    "sinon": "2.0.0-pre.3",
+    "sinon": "2.0.0-pre.4",
     "ts-node": "1.7.2",
     "tslint": "4.1.1",
     "tslint-loader": "^3.3.0",
     "typescript": "2.1.4",
-    "webpack": "2.1.0-beta.27",
+    "webpack": "2.2.0-rc.2",
     "webpack-node-externals": "1.5.4"
   },
   "repository": {

+ 29 - 1
src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.ts

@@ -34,6 +34,11 @@ export class FunctionDeclarationObfuscator extends AbstractNodeTransformer {
      */
     private readonly identifierReplacer: IObfuscatorReplacerWithStorage;
 
+    /**
+     * @type {Map<ESTree.Node, ESTree.Identifier[]>}
+     */
+    private readonly replaceableIdentifiers: Map <ESTree.Node, ESTree.Identifier[]> = new Map();
+
     /**
      * @param nodeObfuscatorsReplacersFactory
      * @param options
@@ -79,12 +84,35 @@ export class FunctionDeclarationObfuscator extends AbstractNodeTransformer {
      * @param nodeIdentifier
      */
     private replaceFunctionName (scopeNode: ESTree.Node, nodeIdentifier: string): void {
+        let replaceableIdentifiersForCurrentScope: ESTree.Identifier[];
+
+        // check for cached identifiers for current scope node. If exist - loop through them.
+        if (this.replaceableIdentifiers.has(scopeNode)) {
+            replaceableIdentifiersForCurrentScope = <ESTree.Identifier[]>this.replaceableIdentifiers.get(scopeNode);
+
+            for (const replaceableIdentifier of replaceableIdentifiersForCurrentScope) {
+                replaceableIdentifier.name = this.identifierReplacer.replace(replaceableIdentifier.name, nodeIdentifier);
+            }
+
+            return;
+        }
+
+        replaceableIdentifiersForCurrentScope = [];
+
         estraverse.replace(scopeNode, {
             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;
+                    } else {
+                        replaceableIdentifiersForCurrentScope.push(node);
+                    }
                 }
             }
         });
+
+        this.replaceableIdentifiers.set(scopeNode, replaceableIdentifiersForCurrentScope);
     }
 }

+ 29 - 1
src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts

@@ -35,6 +35,11 @@ export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
      */
     private readonly identifierReplacer: IObfuscatorReplacerWithStorage;
 
+    /**
+     * @type {Map<ESTree.Node, ESTree.Identifier[]>}
+     */
+    private readonly replaceableIdentifiers: Map <ESTree.Node, ESTree.Identifier[]> = new Map();
+
     /**
      * @param replacersFactory
      * @param options
@@ -87,12 +92,35 @@ export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
      * @param nodeIdentifier
      */
     private replaceVariableNames (scopeNode: ESTree.Node, nodeIdentifier: string): void {
+        let replaceableIdentifiersForCurrentScope: ESTree.Identifier[];
+
+        // check for cached identifiers for current scope node. If exist - loop through them.
+        if (this.replaceableIdentifiers.has(scopeNode)) {
+            replaceableIdentifiersForCurrentScope = <ESTree.Identifier[]>this.replaceableIdentifiers.get(scopeNode);
+
+            for (const replaceableIdentifier of replaceableIdentifiersForCurrentScope) {
+                replaceableIdentifier.name = this.identifierReplacer.replace(replaceableIdentifier.name, nodeIdentifier);
+            }
+
+            return;
+        }
+
+        replaceableIdentifiersForCurrentScope = [];
+
         estraverse.replace(scopeNode, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
                 if (!node.obfuscated && 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;
+                    } else {
+                        replaceableIdentifiersForCurrentScope.push(node);
+                    }
                 }
             }
         });
+
+        this.replaceableIdentifiers.set(scopeNode, replaceableIdentifiersForCurrentScope);
     }
 }

+ 3 - 3
src/node-transformers/node-obfuscators/replacers/IdentifierReplacer.ts

@@ -29,13 +29,13 @@ export class IdentifierReplacer extends AbstractReplacer implements IObfuscatorR
      * @returns {string}
      */
     public replace (nodeValue: string, nodeIdentifier: string): string {
-        const obfuscatedIdentifierName: string|undefined = this.namesMap.get(`${nodeValue}-${nodeIdentifier}`);
+        const mapKey: string = `${nodeValue}-${nodeIdentifier}`;
 
-        if (!obfuscatedIdentifierName) {
+        if (!this.namesMap.has(mapKey)) {
             return nodeValue;
         }
 
-        return obfuscatedIdentifierName;
+        return <string>this.namesMap.get(mapKey);
     }
 
     /**

+ 26 - 3
src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts

@@ -25,6 +25,11 @@ export class StringLiteralReplacer extends AbstractReplacer {
     private static readonly rc4Keys: string[] = RandomGeneratorUtils.getRandomGenerator()
         .n(() => RandomGeneratorUtils.getRandomGenerator().string({length: 4}), 50);
 
+    /**
+     * @type {Map<string, string>}
+     */
+    private readonly stringLiteralCache: Map <string, string> = new Map();
+
     /**
      * @type {IStorage<ICustomNodeGroup>}
      */
@@ -61,11 +66,29 @@ export class StringLiteralReplacer extends AbstractReplacer {
             && RandomGeneratorUtils.getRandomFloat(0, 1) <= this.options.stringArrayThreshold
         );
 
+        let result: string;
+
         if (this.options.stringArray && replaceWithStringArrayFlag) {
-            return this.replaceStringLiteralWithStringArrayCall(nodeValue);
+            /**
+             * we can't use values from cache with `stringArrayEncoding: rc4`
+             * because rc4 key will be the same for same values
+             */
+            if (this.stringLiteralCache.has(nodeValue) && this.options.stringArrayEncoding !== StringArrayEncoding.rc4) {
+                return <string>this.stringLiteralCache.get(nodeValue);
+            }
+
+            result = this.replaceStringLiteralWithStringArrayCall(nodeValue);
+        } else {
+            if (this.stringLiteralCache.has(nodeValue)) {
+                return <string>this.stringLiteralCache.get(nodeValue);
+            }
+
+            result = `'${Utils.stringToUnicodeEscapeSequence(nodeValue, !this.options.unicodeEscapeSequence)}'`;
         }
 
-        return `'${Utils.stringToUnicodeEscapeSequence(nodeValue, !this.options.unicodeEscapeSequence)}'`;
+        this.stringLiteralCache.set(nodeValue, result);
+
+        return result;
     }
 
     /**
@@ -106,7 +129,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
         const hexadecimalIndex: string = `${Utils.hexadecimalPrefix}${Utils.decToHex(indexOfValue)}`;
 
         if (this.options.stringArrayEncoding === StringArrayEncoding.rc4) {
-            return `${stringArrayStorageCallsWrapperName}('${hexadecimalIndex}', '${Utils.stringToUnicodeEscapeSequence(rc4Key)}')`;
+            return `${stringArrayStorageCallsWrapperName}('${hexadecimalIndex}', '${Utils.stringToUnicodeEscapeSequence(rc4Key, !this.options.unicodeEscapeSequence)}')`;
         }
 
         return `${stringArrayStorageCallsWrapperName}('${hexadecimalIndex}')`;

+ 3 - 2
src/utils/Utils.ts

@@ -129,13 +129,14 @@ export class Utils {
      */
     public static stringToUnicodeEscapeSequence (string: string, nonLatinAndNonDigitsOnly: boolean = false): string {
         const radix: number = 16;
-        const regexp: RegExp = new RegExp('[\x00-\x7F]');
+        const replaceRegExp: RegExp = new RegExp('[\\s\\S]', 'g');
         const escapeRegExp: RegExp = new RegExp('[^a-zA-Z0-9]');
+        const regexp: RegExp = new RegExp('[\\x00-\\x7F]');
 
         let prefix: string,
             template: string;
 
-        return `${string.replace(/[\s\S]/g, (escape: string): string => {
+        return `${string.replace(replaceRegExp, (escape: string): string => {
             if (nonLatinAndNonDigitsOnly && !escapeRegExp.test(escape)) {
                 return escape;
             }

+ 1 - 2
test/dev/dev.ts

@@ -84,8 +84,7 @@ if (!(<any>global)._babelPolyfill) {
         {
             compact: false,
             controlFlowFlattening: true,
-            disableConsoleOutput: false,
-            unicodeEscapeSequence: false
+            disableConsoleOutput: false
         }
     ).getObfuscatedCode();
 

+ 3 - 0
webpack.config.js

@@ -53,5 +53,8 @@ module.exports = {
         filename: '[name].js',
         libraryTarget:  "commonjs2",
         library: "JavaScriptObfuscator"
+    },
+    stats: {
+        maxModules: 0
     }
 };

Некоторые файлы не были показаны из-за большого количества измененных файлов