Просмотр исходного кода

Merge pull request #941 from javascript-obfuscator/improved-calls-wrapper-template

Improved `stringArray` calls wrapper templates
Timofey Kachalov 3 лет назад
Родитель
Сommit
08aad1b706
17 измененных файлов с 98 добавлено и 69 удалено
  1. 4 0
      CHANGELOG.md
  2. 0 0
      dist/index.browser.js
  3. 0 0
      dist/index.cli.js
  4. 0 0
      dist/index.js
  5. 1 1
      package.json
  6. 2 1
      src/custom-code-helpers/string-array/StringArrayCallsWrapperBase64CodeHelper.ts
  7. 9 0
      src/custom-code-helpers/string-array/StringArrayCallsWrapperCodeHelper.ts
  8. 6 2
      src/custom-code-helpers/string-array/StringArrayCallsWrapperRc4CodeHelper.ts
  9. 1 1
      src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/Rc4Template.ts
  10. 5 6
      src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayBase64DecodeTemplate.ts
  11. 14 7
      src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayCallsWrapperTemplate.ts
  12. 5 6
      src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayRC4DecodeTemplate.ts
  13. 8 30
      test/dev/dev.ts
  14. 3 2
      test/functional-tests/custom-code-helpers/string-array/StringArrayCallsWrapperCodeHelper.spec.ts
  15. 18 2
      test/functional-tests/custom-code-helpers/string-array/templates/string-array-calls-wrapper-node-template/StringArrayCallsWrapperTemplate.spec.ts
  16. 20 10
      test/functional-tests/generators/identifier-names-generators/dictionary-identifier-names-generator/DictionaryIdentifierNamesGenerator.spec.ts
  17. 2 1
      test/functional-tests/generators/identifier-names-generators/dictionary-identifier-names-generator/fixtures/string-array-storage-name-conflict-1.js

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 
+v2.15.4
+---
+* Improved `stringArray` calls wrapper code
+
 v2.15.3
 ---
 * Slightly improved integration between `deadCodeInjection` and `stringArrayWrappersChainedCalls` options

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


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


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


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "2.15.3",
+  "version": "2.15.4",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",

+ 2 - 1
src/custom-code-helpers/string-array/StringArrayCallsWrapperBase64CodeHelper.ts

@@ -26,7 +26,8 @@ export class StringArrayCallsWrapperBase64CodeHelper extends StringArrayCallsWra
                 atobFunctionName,
                 selfDefendingCode,
                 stringArrayName: this.stringArrayName,
-                stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
+                stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
+                stringArrayCacheName: this.stringArrayCacheName
             }
         );
     }

+ 9 - 0
src/custom-code-helpers/string-array/StringArrayCallsWrapperCodeHelper.ts

@@ -38,6 +38,12 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
     @initializable()
     protected stringArrayCallsWrapperName!: string;
 
+    /**
+     * @type {string}
+     */
+    @initializable()
+    protected stringArrayCacheName!: string;
+
     /**
      * @type {IEscapeSequenceEncoder}
      */
@@ -84,6 +90,8 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
         this.stringArrayName = stringArrayName;
         this.stringArrayCallsWrapperName = stringArrayCallsWrapperName;
         this.indexShiftAmount = indexShiftAmount;
+
+        this.stringArrayCacheName = this.randomGenerator.getRandomString(6);
     }
 
     /**
@@ -107,6 +115,7 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
                 decodeCodeHelperTemplate,
                 stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
                 stringArrayName: this.stringArrayName,
+                stringArrayCacheName: this.stringArrayCacheName,
                 indexShiftAmount: this.indexShiftAmount
             }),
             {

+ 6 - 2
src/custom-code-helpers/string-array/StringArrayCallsWrapperRc4CodeHelper.ts

@@ -13,12 +13,14 @@ export class StringArrayCallsWrapperRc4CodeHelper extends StringArrayCallsWrappe
      */
     protected override getDecodeStringArrayTemplate (): string {
         const atobFunctionName: string = this.randomGenerator.getRandomString(6);
+        const rc4FunctionName: string = this.randomGenerator.getRandomString(6);
 
         const atobPolyfill: string = this.customCodeHelperFormatter.formatTemplate(AtobTemplate(), {
             atobFunctionName
         });
         const rc4Polyfill: string = this.customCodeHelperFormatter.formatTemplate(Rc4Template(), {
-            atobFunctionName
+            atobFunctionName,
+            rc4FunctionName
         });
 
         const selfDefendingCode: string = this.getSelfDefendingTemplate();
@@ -27,10 +29,12 @@ export class StringArrayCallsWrapperRc4CodeHelper extends StringArrayCallsWrappe
             StringArrayRC4DecodeTemplate(this.randomGenerator),
             {
                 atobPolyfill,
+                rc4FunctionName,
                 rc4Polyfill,
                 selfDefendingCode,
                 stringArrayName: this.stringArrayName,
-                stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
+                stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
+                stringArrayCacheName: this.stringArrayCacheName
             }
         );
     }

+ 1 - 1
src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/Rc4Template.ts

@@ -3,7 +3,7 @@
  */
 export function Rc4Template (): string {
     return `
-        const rc4 = function (str, key) {
+        const {rc4FunctionName} = function (str, key) {
             let s = [], j = 0, x, res = '', newStr = '';
            
             str = {atobFunctionName}(str);

+ 5 - 6
src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayBase64DecodeTemplate.ts

@@ -11,7 +11,6 @@ export function StringArrayBase64DecodeTemplate (
     const identifierLength: number = 6;
     const initializedIdentifier: string = randomGenerator.getRandomString(identifierLength);
     const base64DecodeFunctionIdentifier: string = randomGenerator.getRandomString(identifierLength);
-    const dataIdentifier: string = randomGenerator.getRandomString(identifierLength);
 
     return `
         if ({stringArrayCallsWrapperName}.${initializedIdentifier} === undefined) {
@@ -28,20 +27,20 @@ export function StringArrayBase64DecodeTemplate (
                 return decodeURIComponent(newStringChars);
             };
             
-            {stringArrayCallsWrapperName}.${dataIdentifier} = {};
+            {stringArrayCacheName} = arguments;
             
             {stringArrayCallsWrapperName}.${initializedIdentifier} = true;
         }
                   
         const firstValue = {stringArrayName}[0];
         const cacheKey = index + firstValue;
-        const cachedValue = {stringArrayCallsWrapperName}.${dataIdentifier}[cacheKey];
-                        
-        if (cachedValue === undefined) {
+        const cachedValue = {stringArrayCacheName}[cacheKey];
+        
+        if (!cachedValue) {
             {selfDefendingCode}
             
             value = {stringArrayCallsWrapperName}.${base64DecodeFunctionIdentifier}(value);
-            {stringArrayCallsWrapperName}.${dataIdentifier}[cacheKey] = value;
+            {stringArrayCacheName}[cacheKey] = value;
         } else {
             value = cachedValue;
         }

+ 14 - 7
src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayCallsWrapperTemplate.ts

@@ -1,16 +1,23 @@
 /**
+ * The first parameter of the outer stringArrayCallsWrapperName function will be used as an initial index
+ * and later as a cache variable that will be captured by the inner function
+ *
  * @returns {string}
  */
 export function StringArrayCallsWrapperTemplate (): string {
     return `
-         function {stringArrayCallsWrapperName} (index, key) {
-            index = index - {indexShiftAmount};
+        function {stringArrayCallsWrapperName} ({stringArrayCacheName}, key) {
+            {stringArrayCallsWrapperName} = function (index, key) {
+                index = index - {indexShiftAmount};
+                
+                let value = {stringArrayName}[index];
+                
+                {decodeCodeHelperTemplate}
             
-            let value = {stringArrayName}[index];
-            
-            {decodeCodeHelperTemplate}
-        
-            return value;
+                return value;
+            };
+         
+            return {stringArrayCallsWrapperName}({stringArrayCacheName}, key);
         }
     `;
 }

+ 5 - 6
src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/StringArrayRC4DecodeTemplate.ts

@@ -11,7 +11,6 @@ export function StringArrayRC4DecodeTemplate (
     const identifierLength: number = 6;
     const initializedIdentifier: string = randomGenerator.getRandomString(identifierLength);
     const rc4Identifier: string = randomGenerator.getRandomString(identifierLength);
-    const dataIdentifier: string = randomGenerator.getRandomString(identifierLength);
     const onceIdentifier: string = randomGenerator.getRandomString(identifierLength);
 
     return `
@@ -19,18 +18,18 @@ export function StringArrayRC4DecodeTemplate (
             {atobPolyfill}
             
             {rc4Polyfill}
-            {stringArrayCallsWrapperName}.${rc4Identifier} = rc4;
+            {stringArrayCallsWrapperName}.${rc4Identifier} = {rc4FunctionName};
             
-            {stringArrayCallsWrapperName}.${dataIdentifier} = {};
+            {stringArrayCacheName} = arguments;
             
             {stringArrayCallsWrapperName}.${initializedIdentifier} = true;
         }
   
         const firstValue = {stringArrayName}[0];
         const cacheKey = index + firstValue;
-        const cachedValue = {stringArrayCallsWrapperName}.${dataIdentifier}[cacheKey];
+        const cachedValue = {stringArrayCacheName}[cacheKey];
 
-        if (cachedValue === undefined) {
+        if (!cachedValue) {
             if ({stringArrayCallsWrapperName}.${onceIdentifier} === undefined) {
                 {selfDefendingCode}
                 
@@ -38,7 +37,7 @@ export function StringArrayRC4DecodeTemplate (
             }
             
             value = {stringArrayCallsWrapperName}.${rc4Identifier}(value, key);
-            {stringArrayCallsWrapperName}.${dataIdentifier}[cacheKey] = value;
+            {stringArrayCacheName}[cacheKey] = value;
         } else {
             value = cachedValue;
         }

+ 8 - 30
test/dev/dev.ts

@@ -1,46 +1,24 @@
 'use strict';
 
+import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNodes';
+
 (function () {
     const JavaScriptObfuscator: any = require('../../index');
 
     let obfuscationResult = JavaScriptObfuscator.obfuscate(
         `
-            (function(){
-                if (true) {
-                    var foo = function () {
-                        console.log('abc');
-                    };
-                    var bar = function () {
-                        console.log('def');
-                    };
-                    var baz = function () {
-                        console.log('ghi');
-                    };
-                    var bark = function () {
-                        console.log('jkl');
-                    };
-                    var hawk = function () {
-                        console.log('mno');
-                    };
-            
-                    foo();
-                    bar();
-                    baz();
-                    bark();
-                    hawk();
-                }
-            })();
+            console.log('foo');
+            console.log('bar');
+            console.log('bar');
         `,
         {
+            ...NO_ADDITIONAL_NODES_PRESET,
             compact: false,
             simplify: false,
             stringArray: true,
             stringArrayThreshold: 1,
-            stringArrayWrappersChainedCalls: true,
-            deadCodeInjection: true,
-            deadCodeInjectionThreshold: 1,
-            identifierNamesGenerator: 'mangled',
-            seed: 1
+            stringArrayEncoding: ['base64'],
+            identifierNamesGenerator: 'mangled'
         }
     );
 

+ 3 - 2
test/functional-tests/custom-code-helpers/string-array/StringArrayCallsWrapperCodeHelper.spec.ts

@@ -56,8 +56,9 @@ describe('StringArrayCallsWrapperCodeHelper', () => {
     describe('Preserve string array name', () => {
         const callsWrapperRegExp: RegExp = new RegExp(`` +
             `function *b *\\(c, *d\\) *{ *` +
-            `c *= *c *- *0x0; *` +
-            `var e *= *a\\[c]; *` +
+                `b *= *function *\\(e, *f\\) *{` +
+                    `e *= *e *- *0x0; *` +
+                    `var g *= *a\\[e]; *` +
         ``);
 
         let obfuscatedCode: string;

+ 18 - 2
test/functional-tests/custom-code-helpers/string-array/templates/string-array-calls-wrapper-node-template/StringArrayCallsWrapperTemplate.spec.ts

@@ -27,7 +27,9 @@ import { swapLettersCase } from '../../../../../helpers/swapLettersCase';
 describe('StringArrayCallsWrapperTemplate', () => {
     const stringArrayName: string = 'stringArrayName';
     const stringArrayCallsWrapperName: string = 'stringArrayCallsWrapperName';
+    const stringArrayCacheName: string = 'stringArrayCache';
     const atobFunctionName: string = 'atob';
+    const rc4FunctionName: string = 'rc4';
 
     let cryptUtilsSwappedAlphabet: ICryptUtilsStringArray,
         randomGenerator: IRandomGenerator;
@@ -62,12 +64,14 @@ describe('StringArrayCallsWrapperTemplate', () => {
                         atobPolyfill,
                         atobFunctionName,
                         selfDefendingCode: '',
+                        stringArrayCacheName,
                         stringArrayCallsWrapperName
                     }
                 );
                 const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
                     decodeCodeHelperTemplate: atobDecodeTemplate,
                     indexShiftAmount,
+                    stringArrayCacheName,
                     stringArrayCallsWrapperName,
                     stringArrayName
                 });
@@ -105,12 +109,14 @@ describe('StringArrayCallsWrapperTemplate', () => {
                         atobPolyfill,
                         atobFunctionName,
                         selfDefendingCode: '',
+                        stringArrayCacheName,
                         stringArrayCallsWrapperName
                     }
                 );
                 const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
                     decodeCodeHelperTemplate: atobDecodeTemplate,
                     indexShiftAmount,
+                    stringArrayCacheName,
                     stringArrayCallsWrapperName,
                     stringArrayName
                 });
@@ -146,12 +152,14 @@ describe('StringArrayCallsWrapperTemplate', () => {
                         atobPolyfill,
                         atobFunctionName,
                         selfDefendingCode: '',
+                        stringArrayCacheName,
                         stringArrayCallsWrapperName
                     }
                 );
                 const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
                     decodeCodeHelperTemplate: atobDecodeTemplate,
                     indexShiftAmount,
+                    stringArrayCacheName,
                     stringArrayCallsWrapperName,
                     stringArrayName
                 });
@@ -190,20 +198,24 @@ describe('StringArrayCallsWrapperTemplate', () => {
                     atobFunctionName
                 });
                 const rc4Polyfill = format(Rc4Template(), {
-                    atobFunctionName
+                    atobFunctionName,
+                    rc4FunctionName
                 });
                 const rc4decodeCodeHelperTemplate: string = format(
                     StringArrayRC4DecodeTemplate(randomGenerator),
                     {
                         atobPolyfill,
                         rc4Polyfill,
+                        rc4FunctionName,
                         selfDefendingCode: '',
+                        stringArrayCacheName,
                         stringArrayCallsWrapperName
                     }
                 );
                 const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
                     decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
                     indexShiftAmount,
+                    stringArrayCacheName,
                     stringArrayCallsWrapperName,
                     stringArrayName
                 });
@@ -237,20 +249,24 @@ describe('StringArrayCallsWrapperTemplate', () => {
                     atobFunctionName
                 });
                 const rc4Polyfill = format(Rc4Template(), {
-                    atobFunctionName
+                    atobFunctionName,
+                    rc4FunctionName
                 });
                 const rc4decodeCodeHelperTemplate: string = format(
                     StringArrayRC4DecodeTemplate(randomGenerator),
                     {
                         atobPolyfill,
                         rc4Polyfill,
+                        rc4FunctionName,
                         selfDefendingCode: '',
+                        stringArrayCacheName,
                         stringArrayCallsWrapperName
                     }
                 );
                 const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), {
                     decodeCodeHelperTemplate: rc4decodeCodeHelperTemplate,
                     indexShiftAmount,
+                    stringArrayCacheName,
                     stringArrayCallsWrapperName,
                     stringArrayName
                 });

+ 20 - 10
test/functional-tests/generators/identifier-names-generators/dictionary-identifier-names-generator/DictionaryIdentifierNamesGenerator.spec.ts

@@ -13,8 +13,9 @@ describe('DictionaryIdentifierNamesGenerator', () => {
     describe('generateWithPrefix', () => {
         describe('Variant #1: should not generate same name for string array as existing name in code', () => {
             describe('Variant #1: `renameGlobals` option is disabled', () => {
-                const stringArrayStorageRegExp: RegExp = /const a[aB] *= *\['abc'];/;
-                const variableDeclarationIdentifierNameRegExp: RegExp = /const ab *= *a[abAB]\(0x0\);/;
+                const stringArrayStorageRegExp: RegExp = /const a[cABC] *= *\['_aa', *'_ab'];/;
+                const variableDeclarationIdentifierNameRegExp1: RegExp = /const aa *= *a[cABC]\(0x0\);/;
+                const variableDeclarationIdentifierNameRegExp2: RegExp = /const ab *= *a[cABC]\(0x1\);/;
 
                 let obfuscatedCode: string;
 
@@ -26,7 +27,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                         {
                             ...NO_ADDITIONAL_NODES_PRESET,
                             identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
-                            identifiersDictionary: ['a', 'b'],
+                            identifiersDictionary: ['a', 'b', 'c'],
                             identifiersPrefix: 'a',
                             transformObjectKeys: true,
                             stringArray: true,
@@ -39,14 +40,19 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                     assert.match(obfuscatedCode, stringArrayStorageRegExp);
                 });
 
-                it('Match #2: should keep identifier name for last variable declaration', () => {
-                    assert.match(obfuscatedCode, variableDeclarationIdentifierNameRegExp);
+                it('Match #2: should keep identifier name for existing variable declaration', () => {
+                    assert.match(obfuscatedCode, variableDeclarationIdentifierNameRegExp1);
+                });
+
+                it('Match #3: should keep identifier name for existing variable declaration', () => {
+                    assert.match(obfuscatedCode, variableDeclarationIdentifierNameRegExp2);
                 });
             });
 
             describe('Variant #2: `renameGlobals` option is enabled', () => {
-                const stringArrayStorageRegExp: RegExp = /const a[aB] *= *\['abc'];/;
-                const lastVariableDeclarationIdentifierNameRegExp: RegExp = /const a[AB] *= *a[AB]\(0x0\);/;
+                const stringArrayStorageRegExp: RegExp = /const a[cABC] *= *\['_aa', *'_ab'];/;
+                const lastVariableDeclarationIdentifierNameRegExp1: RegExp = /const a[cABC] *= *a[cABC]\(0x0\);/;
+                const lastVariableDeclarationIdentifierNameRegExp2: RegExp = /const a[cABC] *= *a[cABC]\(0x1\);/;
 
                 let obfuscatedCode: string;
 
@@ -58,7 +64,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                         {
                             ...NO_ADDITIONAL_NODES_PRESET,
                             identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
-                            identifiersDictionary: ['a', 'b'],
+                            identifiersDictionary: ['a', 'b', 'c'],
                             identifiersPrefix: 'a',
                             renameGlobals: true,
                             transformObjectKeys: true,
@@ -72,8 +78,12 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                     assert.match(obfuscatedCode, stringArrayStorageRegExp);
                 });
 
-                it('Match #2: should keep identifier name for last variable declaration', () => {
-                    assert.match(obfuscatedCode, lastVariableDeclarationIdentifierNameRegExp);
+                it('Match #2: should keep identifier name for existing variable declaration', () => {
+                    assert.match(obfuscatedCode, lastVariableDeclarationIdentifierNameRegExp1);
+                });
+
+                it('Match #3: should keep identifier name for existing variable declaration', () => {
+                    assert.match(obfuscatedCode, lastVariableDeclarationIdentifierNameRegExp2);
                 });
             });
         });

+ 2 - 1
test/functional-tests/generators/identifier-names-generators/dictionary-identifier-names-generator/fixtures/string-array-storage-name-conflict-1.js

@@ -1 +1,2 @@
-const ab = 'abc';
+const aa = '_aa';
+const ab = '_ab';

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