Kaynağa Gözat

Merge pull request #842 from javascript-obfuscator/string-array-storage-invalid-cache-fix

Fixed runtime errors in large obfuscated code when both `rc4` and `ba…
Timofey Kachalov 4 yıl önce
ebeveyn
işleme
e7fb615cba

+ 2 - 1
CHANGELOG.md

@@ -1,7 +1,8 @@
 Change Log
 
-v2.10.0
+v2.9.5
 ---
+* Fixed runtime errors in large obfuscated code when both `rc4` and `base64` encodings are enabled
 * Some internal refactoring related to node append events
 
 v2.9.4

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/index.browser.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/index.cli.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/index.js


+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "2.10.0",
+  "version": "2.9.5",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -87,7 +87,7 @@
     "ts-node": "9.1.1",
     "typescript": "4.1.3",
     "webpack": "5.11.0",
-    "webpack-cli": "4.2.0",
+    "webpack-cli": "4.3.0",
     "webpack-node-externals": "2.5.2"
   },
   "repository": {

+ 7 - 5
src/storages/string-array-transformers/StringArrayStorage.ts

@@ -18,7 +18,7 @@ import { StringArrayEncoding } from '../../enums/node-transformers/string-array-
 import { MapStorage } from '../MapStorage';
 
 @injectable()
-export class StringArrayStorage extends MapStorage <string, IStringArrayStorageItemData> implements IStringArrayStorage {
+export class StringArrayStorage extends MapStorage <`${string}-${TStringArrayEncoding}`, IStringArrayStorageItemData> implements IStringArrayStorage {
     /**
      * @type {number}
      */
@@ -227,9 +227,9 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
         this.storage = new Map(
             this.arrayUtils
                 .shuffle(Array.from(this.storage.entries()))
-                .map<[string, IStringArrayStorageItemData]>(
+                .map<[`${string}-${TStringArrayEncoding}`, IStringArrayStorageItemData]>(
                     (
-                        [value, stringArrayStorageItemData]: [string, IStringArrayStorageItemData],
+                        [value, stringArrayStorageItemData],
                         index: number
                     ) => {
                         stringArrayStorageItemData.index = index;
@@ -250,7 +250,9 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
      */
     private getOrSetIfDoesNotExist (value: string): IStringArrayStorageItemData {
         const { encodedValue, encoding, decodeKey }: IEncodedValue = this.getEncodedValue(value);
-        const storedStringArrayStorageItemData: IStringArrayStorageItemData | undefined = this.storage.get(encodedValue);
+
+        const cacheKey = <`${string}-${TStringArrayEncoding}`>`${encodedValue}-${encoding}`;
+        const storedStringArrayStorageItemData: IStringArrayStorageItemData | undefined = this.storage.get(cacheKey);
 
         if (storedStringArrayStorageItemData) {
             return storedStringArrayStorageItemData;
@@ -264,7 +266,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
             index: this.getLength()
         };
 
-        this.storage.set(encodedValue, stringArrayStorageItemData);
+        this.storage.set(cacheKey, stringArrayStorageItemData);
 
         return stringArrayStorageItemData;
     }

+ 1 - 1
test/runtime-tests/JavaScriptObfuscatorRuntime.spec.ts

@@ -34,7 +34,7 @@ describe('JavaScriptObfuscator runtime eval', function () {
         rotateStringArray: true,
         selfDefending: true,
         splitStrings: true,
-        splitStringsChunkLength: 1,
+        splitStringsChunkLength: 3,
         stringArray: true,
         stringArrayEncoding: [
             StringArrayEncoding.None,

+ 48 - 7
test/unit-tests/storages/string-array-transformers/string-array/StringArrayStorage.spec.ts

@@ -8,6 +8,7 @@ import { TInputOptions } from '../../../../../src/types/options/TInputOptions';
 
 import { IInversifyContainerFacade } from '../../../../../src/interfaces/container/IInversifyContainerFacade';
 import { IStringArrayStorage } from '../../../../../src/interfaces/storages/string-array-transformers/IStringArrayStorage';
+import { IStringArrayStorageItemData } from '../../../../../src/interfaces/storages/string-array-transformers/IStringArrayStorageItem';
 
 import { StringArrayEncoding } from '../../../../../src/enums/node-transformers/string-array-transformers/StringArrayEncoding';
 
@@ -35,21 +36,23 @@ const getStorageInstance = (options: TInputOptions = {}): IStringArrayStorage =>
     return storage;
 };
 
-const getEncodedValue = (stringArrayStorage: IStringArrayStorage, value: string, decodeKey: string): string => {
+const getStringArrayStorageItemData = (
+    stringArrayStorage: IStringArrayStorage,
+    value: string,
+    decodeKeys: string[]
+): IStringArrayStorageItemData | undefined => {
     (<any>stringArrayStorage).rc4Keys = [
         'foo',
-        decodeKey
+        ...decodeKeys
     ];
 
-    return stringArrayStorage.get(value)?.encodedValue ?? '';
+    return stringArrayStorage.get(value);
 };
 
 describe('StringArrayStorage', () => {
     describe('rc4 encoded value collision fix', () => {
         const samplesCount: number = 100;
 
-        let firstEncodedValue: string;
-        let secondEncodedValue: string;
         let isCollisionHappened: boolean = false;
 
         before(() => {
@@ -58,8 +61,8 @@ describe('StringArrayStorage', () => {
             });
 
             for (let i = 0; i < samplesCount; i++) {
-                firstEncodedValue = getEncodedValue(stringArrayStorage, '_15', 'CRDL');
-                secondEncodedValue = getEncodedValue(stringArrayStorage, '_12', 'q9mB');
+                const {encodedValue: firstEncodedValue} = getStringArrayStorageItemData(stringArrayStorage, '_15', ['CRDL']) || {};
+                const {encodedValue: secondEncodedValue} = getStringArrayStorageItemData(stringArrayStorage, '_12', ['q9mB']) || {};
 
                 if (firstEncodedValue === secondEncodedValue) {
                     isCollisionHappened = true;
@@ -72,4 +75,42 @@ describe('StringArrayStorage', () => {
             assert.equal(isCollisionHappened, false);
         });
     });
+
+    describe('Cache key collision when rc4 and base64 encoded values for different input strings are the same', () => {
+        const samplesCount: number = 100;
+
+        let isCollisionHappened: boolean = false;
+
+        before(() => {
+            const stringArrayStorage: IStringArrayStorage = getStorageInstance({
+                stringArrayEncoding: [
+                    StringArrayEncoding.Base64,
+                    StringArrayEncoding.Rc4
+                ]
+            });
+
+            for (let i = 0; i < samplesCount; i++) {
+                const {
+                    encodedValue: firstEncodedValue,
+                    encoding: firstEncodedValueEncoding
+                } = getStringArrayStorageItemData(stringArrayStorage, 'zxL', ['&Jfx', '[lR4']) || {};
+                const {
+                    encodedValue: secondEncodedValue,
+                    encoding: secondEncodedValueEncoding
+                } = getStringArrayStorageItemData(stringArrayStorage, 'omC', ['&Jfx', '[lR4']) || {};
+
+                if (
+                    firstEncodedValue === secondEncodedValue
+                    && firstEncodedValueEncoding === secondEncodedValueEncoding
+                ) {
+                    isCollisionHappened = true;
+                    break;
+                }
+            }
+        });
+
+        it('should not make a cache key collision between different encoded input strings', () => {
+            assert.equal(isCollisionHappened, false);
+        });
+    });
 });

+ 27 - 70
yarn.lock

@@ -268,6 +268,11 @@
     lodash "^4.17.13"
     to-fast-properties "^2.0.0"
 
+"@discoveryjs/json-ext@^0.5.0":
+  version "0.5.2"
+  resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752"
+  integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==
+
 "@eslint/eslintrc@^0.2.2":
   version "0.2.2"
   resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.2.tgz#d01fc791e2fc33e88a29d6f3dc7e93d0cd784b76"
@@ -800,17 +805,17 @@
     "@webassemblyjs/wast-parser" "1.9.1"
     "@xtuc/long" "4.2.2"
 
-"@webpack-cli/info@^1.1.0":
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.1.0.tgz#c596d5bc48418b39df00c5ed7341bf0f102dbff1"
-  integrity sha512-uNWSdaYHc+f3LdIZNwhdhkjjLDDl3jP2+XBqAq9H8DjrJUvlOKdP8TNruy1yEaDfgpAIgbSAN7pye4FEHg9tYQ==
+"@webpack-cli/info@^1.2.0":
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.2.0.tgz#6051d6adf3618df664f4945a2b76355c00f83f0d"
+  integrity sha512-+wA8lBKopgKmN76BSGJVJby5ZXDlsrO6p/nm7fUBsHznRNWB/ozotJP7Yfcz8JPfqeG2LxwYlTH2u6D9a/0XAw==
   dependencies:
     envinfo "^7.7.3"
 
-"@webpack-cli/serve@^1.1.0":
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.1.0.tgz#13ad38f89b6e53d1133bac0006a128217a6ebf92"
-  integrity sha512-7RfnMXCpJ/NThrhq4gYQYILB18xWyoQcBey81oIyVbmgbc6m5ZHHyFK+DyH7pLHJf0p14MxL4mTsoPAgBSTpIg==
+"@webpack-cli/serve@^1.2.0":
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.2.0.tgz#8cb2c1e95426f5caed1f3bf9d7ccf3ea41d85f52"
+  integrity sha512-jI3P7jMp/AXDSPkM+ClwRcJZbxnlvNC8bVZBmyRr4scMMZ4p5WQcXkw3Q+Hc7RQekomJlBMN+UQGliT4hhG8Vw==
 
 "@xtuc/ieee754@^1.2.0":
   version "1.2.0"
@@ -972,11 +977,6 @@ argparse@^1.0.7:
   dependencies:
     sprintf-js "~1.0.2"
 
-array-back@^4.0.0, array-back@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.1.tgz#9b80312935a52062e1a233a9c7abeb5481b30e90"
-  integrity sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==
-
 array-differ@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b"
@@ -1204,7 +1204,7 @@ [email protected], chalk@^4.1.0:
     ansi-styles "^4.1.0"
     supports-color "^7.1.0"
 
-chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.2:
+chalk@^2.0.0, chalk@^2.3.0:
   version "2.4.2"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
   integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -1344,16 +1344,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
   dependencies:
     delayed-stream "~1.0.0"
 
-command-line-usage@^6.1.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.0.tgz#f28376a3da3361ff3d36cfd31c3c22c9a64c7cb6"
-  integrity sha512-Ew1clU4pkUeo6AFVDFxCbnN7GIZfXl48HIOQeFQnkO3oOqvpI7wdqtLRwv9iOCZ/7A+z4csVZeiDdEcj8g6Wiw==
-  dependencies:
-    array-back "^4.0.0"
-    chalk "^2.4.2"
-    table-layout "^1.0.0"
-    typical "^5.2.0"
-
 [email protected]:
   version "6.2.1"
   resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
@@ -1543,11 +1533,6 @@ deep-eql@^3.0.1:
   dependencies:
     type-detect "^4.0.0"
 
-deep-extend@~0.6.0:
-  version "0.6.0"
-  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
-  integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
-
 deep-is@^0.1.3, deep-is@~0.1.3:
   version "0.1.3"
   resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
@@ -2104,6 +2089,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
   integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
 
+fastest-levenshtein@^1.0.12:
+  version "1.0.12"
+  resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
+  integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
+
 fastq@^1.6.0:
   version "1.8.0"
   resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
@@ -2873,11 +2863,6 @@ lcov-parse@^1.0.0:
   resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0"
   integrity sha1-6w1GtUER68VhrLTECO+TY73I9+A=
 
-leven@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
-  integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
-
 levn@^0.4.1:
   version "0.4.1"
   resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
@@ -3727,11 +3712,6 @@ rechoir@^0.7.0:
   dependencies:
     resolve "^1.9.0"
 
-reduce-flatten@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27"
-  integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==
-
 [email protected]:
   version "0.1.13"
   resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
@@ -4239,16 +4219,6 @@ symbol-observable@^1.1.0:
   resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
   integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
 
-table-layout@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.1.tgz#8411181ee951278ad0638aea2f779a9ce42894f9"
-  integrity sha512-dEquqYNJiGwY7iPfZ3wbXDI944iqanTSchrACLL2nOB+1r+h1Nzu2eH+DuPPvWvm5Ry7iAPeFlgEtP5bIp5U7Q==
-  dependencies:
-    array-back "^4.0.1"
-    deep-extend "~0.6.0"
-    typical "^5.2.0"
-    wordwrapjs "^4.0.0"
-
 table@^6.0.4:
   version "6.0.4"
   resolved "https://registry.yarnpkg.com/table/-/table-6.0.4.tgz#c523dd182177e926c723eb20e1b341238188aa0d"
@@ -4456,11 +4426,6 @@ [email protected]:
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
   integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
 
-typical@^5.0.0, typical@^5.2.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066"
-  integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==
-
 universalify@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
@@ -4535,21 +4500,21 @@ watchpack@^2.0.0:
     glob-to-regexp "^0.4.1"
     graceful-fs "^4.1.2"
 
-webpack-cli@4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.2.0.tgz#10a09030ad2bd4d8b0f78322fba6ea43ec56aaaa"
-  integrity sha512-EIl3k88vaF4fSxWSgtAQR+VwicfLMTZ9amQtqS4o+TDPW9HGaEpbFBbAZ4A3ZOT5SOnMxNOzROsSTPiE8tBJPA==
+webpack-cli@4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.3.0.tgz#e39303bf9f8002de122903e97029f3443d0f9174"
+  integrity sha512-gve+BBKrzMPTOYDjupzV8JchUznhVWMKtWM1hFIQWi6XoeLvGNoQwkrtMWVb+aJ437GgCKdta7sIn10v621pKA==
   dependencies:
-    "@webpack-cli/info" "^1.1.0"
-    "@webpack-cli/serve" "^1.1.0"
+    "@discoveryjs/json-ext" "^0.5.0"
+    "@webpack-cli/info" "^1.2.0"
+    "@webpack-cli/serve" "^1.2.0"
     colorette "^1.2.1"
-    command-line-usage "^6.1.0"
     commander "^6.2.0"
     enquirer "^2.3.6"
     execa "^4.1.0"
+    fastest-levenshtein "^1.0.12"
     import-local "^3.0.2"
     interpret "^2.2.0"
-    leven "^3.1.0"
     rechoir "^0.7.0"
     v8-compile-cache "^2.2.0"
     webpack-merge "^4.2.2"
@@ -4654,14 +4619,6 @@ word-wrap@^1.2.3, word-wrap@~1.2.3:
   resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
   integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
 
-wordwrapjs@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.0.tgz#9aa9394155993476e831ba8e59fb5795ebde6800"
-  integrity sha512-Svqw723a3R34KvsMgpjFBYCgNOSdcW3mQFK4wIfhGQhtaFVOJmdYoXgi63ne3dTlWgatVcUc7t4HtQ/+bUVIzQ==
-  dependencies:
-    reduce-flatten "^2.0.0"
-    typical "^5.0.0"
-
 [email protected]:
   version "6.0.2"
   resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.0.2.tgz#e241b43d8d033f1beb52c7851069456039d1d438"

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor