Sfoglia il codice sorgente

Improved update of previous mangled character

sanex 4 anni fa
parent
commit
5a833d1057

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


+ 56 - 0
src/generators/identifier-names-generators/MangledIdentifierNamesGenerator.ts

@@ -59,6 +59,58 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
         super(randomGenerator, options);
     }
 
+    /**
+     * @param {string} nextName
+     * @param {string} prevName
+     * @returns {boolean}
+     */
+    public static isIncrementedMangledName (nextName: string, prevName: string): boolean {
+        if (nextName === prevName) {
+            return false;
+        }
+
+        const nextNameLength: number = nextName.length;
+        const prevNameLength: number = prevName.length;
+
+        if (nextNameLength !== prevNameLength) {
+            return nextNameLength > prevNameLength;
+        }
+
+        for (let i: number = 0; i < nextNameLength; i++) {
+            const nextNameCharacter: string = nextName[i];
+            const prevNameCharacter: string = prevName[i];
+
+            if (nextNameCharacter === prevNameCharacter) {
+                continue;
+            }
+
+            const isUpperCaseNextNameCharacter: boolean = MangledIdentifierNamesGenerator.isUpperCaseCharacter(nextNameCharacter);
+            const isUpperCasePrevNameCharacter: boolean = MangledIdentifierNamesGenerator.isUpperCaseCharacter(prevNameCharacter);
+
+            if (
+                isUpperCaseNextNameCharacter
+                && !isUpperCasePrevNameCharacter
+            ) {
+                return true;
+            } else if (
+                !isUpperCaseNextNameCharacter
+                && isUpperCasePrevNameCharacter
+            ) {
+                return false;
+            }
+        }
+
+        return nextName > prevName;
+    }
+
+    /**
+     * @param {string} character
+     * @returns {boolean}
+     */
+    private static isUpperCaseCharacter (string: string): boolean {
+        return /^[A-Z]*$/.test(string);
+    }
+
     /**
      * Generates next name based on a global previous mangled name
      * We can ignore nameLength parameter here, it hasn't sense with this generator
@@ -144,6 +196,10 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
      * @param {string} name
      */
     protected updatePreviousMangledName (name: string): void {
+        if (!MangledIdentifierNamesGenerator.isIncrementedMangledName(name, this.previousMangledName)) {
+            return;
+        }
+
         this.previousMangledName = name;
     }
 

+ 18 - 8
test/dev/dev.ts

@@ -13,23 +13,33 @@ import { IdentifierNamesGenerator } from '../../src/enums/generators/identifier-
             function test (a, b) {
                 const bar = 'bbb';
                 
-                return a + b;
+                function test1 (a, b) {
+                    const baz = 'ccc';
+                    
+                    function test2 (a, b) {
+                        const bark = 'ddd';
+                        
+                        return bark;
+                    }
+                    
+                    return baz + test2();
+                }
+                
+                return bar + test1();
             }
             
-            function test1 (a, b) {
-                const bar = 'bbb';
+            function test3 (a, b) {
+                const hawk = 'eee';
                 
-                return a + b;
+                return hawk;
             }
             
-            test();
-            
-            var baz = 5;
+            foo + test() + test3();
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,
             compact: false,
-            identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
+            identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
             renameGlobals: true,
             stringArray: true,
             stringArrayThreshold: 1,

+ 172 - 42
test/functional-tests/node-transformers/string-array-transformers/string-array-transformer/StringArrayTransformer.spec.ts

@@ -257,28 +257,34 @@ describe('StringArrayTransformer', function () {
 
         describe('Variant #5: `stringArrayWrappersChainedCalls` option is enabled', () => {
             describe('Variant #1: correct chained calls', () => {
-                describe('Variant #1: base', () => {
+                describe('Variant #1: `Mangled` identifier names generator', () => {
                     const stringArrayCallRegExp: RegExp = new RegExp(
-                        'const h *= *b;' +
-                        'const foo *= *h\\(\'0x0\'\\);' +
-                        'function test\\( *\\) *{' +
-                            'const i *= *h;' +
-                            'const c *= *i\\(\'0x1\'\\);' +
-                            'const d *= *i\\(\'0x2\'\\);' +
-                            'function e\\( *\\) *{' +
-                                'const j *= *i;' +
-                                'const f *= *j\\(\'0x3\'\\);' +
-                                'const g *= *j\\(\'0x4\'\\);' +
-                                'return f *\\+ *g;' +
+                        'const q *= *b;' +
+                        'const foo *= *q\\(\'0x0\'\\);' +
+                        'function test\\(c, *d\\) *{' +
+                            'const r *= *q;' +
+                            'const e *= *r\\(\'0x1\'\\);' +
+                            'const f *= *r\\(\'0x2\'\\);' +
+                            'function g\\(h, *i\\) *{' +
+                                'const s *= *r;' +
+                                'const j *= *s\\(\'0x3\'\\);' +
+                                'const k *= *s\\(\'0x4\'\\);' +
+                                'function l\\(m, *n *\\) *{' +
+                                    'const t *= *s;' +
+                                    'const o *= *t\\(\'0x3\'\\);' +
+                                    'const p *= *t\\(\'0x4\'\\);' +
+                                    'return o *\\+ *p;' +
+                                '}' +
+                                'return j *\\+ *k;' +
                             '}' +
-                            'return c *\\+ *d *\\+ *e\\(\\);' +
+                            'return e *\\+ *f *\\+ *g\\(\\);' +
                         '}'
                     );
 
                     let obfuscatedCode: string;
 
                     before(() => {
-                        const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls.js');
+                        const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-1.js');
 
                         obfuscatedCode = JavaScriptObfuscator.obfuscate(
                             code,
@@ -300,40 +306,164 @@ describe('StringArrayTransformer', function () {
             });
 
             describe('Variant #2: correct evaluation of the string array wrappers chained calls', () => {
-                const samplesCount: number = 50;
-                const expectedEvaluationResult: string = 'aaabbbcccdddeee';
-                let isEvaluationSuccessful: boolean = true;
+                describe('Variant #1: base', () => {
+                    describe('Variant #1: `Hexadecimal` identifier names generator', () => {
+                        const samplesCount: number = 50;
+                        const expectedEvaluationResult: string = 'aaabbbcccdddeee';
+                        let isEvaluationSuccessful: boolean = true;
+
+                        before(() => {
+                            const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-1.js');
+
+                            for (let i = 0; i < samplesCount; i++) {
+                                const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
+                                    code,
+                                    {
+                                        ...NO_ADDITIONAL_NODES_PRESET,
+                                        identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
+                                        stringArray: true,
+                                        stringArrayThreshold: 1,
+                                        stringArrayEncoding: [
+                                            StringArrayEncoding.None,
+                                            StringArrayEncoding.Rc4
+                                        ],
+                                        stringArrayWrappersChainedCalls: true,
+                                        stringArrayWrappersCount: 5
+                                    }
+                                ).getObfuscatedCode();
+
+                                const evaluationResult: string = eval(obfuscatedCode);
+
+                                if (evaluationResult !== expectedEvaluationResult) {
+                                    isEvaluationSuccessful = false;
+                                    break;
+                                }
+                            }
+                        });
 
-                before(() => {
-                    const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls.js');
+                        it('should correctly evaluate string array wrappers chained calls', () => {
+                            assert.equal(isEvaluationSuccessful, true);
+                        });
+                    });
 
-                    for (let i = 0; i < samplesCount; i++) {
-                        const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
-                            code,
-                            {
-                                ...NO_ADDITIONAL_NODES_PRESET,
-                                stringArray: true,
-                                stringArrayThreshold: 1,
-                                stringArrayEncoding: [
-                                    StringArrayEncoding.None,
-                                    StringArrayEncoding.Rc4
-                                ],
-                                stringArrayWrappersChainedCalls: true,
-                                stringArrayWrappersCount: 5
+                    describe('Variant #2: `Mangled` identifier names generator', () => {
+                        const samplesCount: number = 50;
+                        const expectedEvaluationResult: string = 'aaabbbcccdddeee';
+                        let isEvaluationSuccessful: boolean = true;
+
+                        before(() => {
+                            const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-1.js');
+
+                            for (let i = 0; i < samplesCount; i++) {
+                                const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
+                                    code,
+                                    {
+                                        ...NO_ADDITIONAL_NODES_PRESET,
+                                        identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
+                                        stringArray: true,
+                                        stringArrayThreshold: 1,
+                                        stringArrayEncoding: [
+                                            StringArrayEncoding.None,
+                                            StringArrayEncoding.Rc4
+                                        ],
+                                        stringArrayWrappersChainedCalls: true,
+                                        stringArrayWrappersCount: 5
+                                    }
+                                ).getObfuscatedCode();
+
+                                const evaluationResult: string = eval(obfuscatedCode);
+
+                                if (evaluationResult !== expectedEvaluationResult) {
+                                    isEvaluationSuccessful = false;
+                                    break;
+                                }
                             }
-                        ).getObfuscatedCode();
+                        });
 
-                        const evaluationResult: string = eval(obfuscatedCode);
-
-                        if (evaluationResult !== expectedEvaluationResult) {
-                            isEvaluationSuccessful = false;
-                            break;
-                        }
-                    }
+                        it('should correctly evaluate string array wrappers chained calls', () => {
+                            assert.equal(isEvaluationSuccessful, true);
+                        });
+                    });
                 });
 
-                it('should correctly evaluate string array wrappers chained calls', () => {
-                    assert.equal(isEvaluationSuccessful, true);
+                describe('Variant #2: advanced', () => {
+                    describe('Variant #1: `Hexadecimal` identifier names generator', () => {
+                        const samplesCount: number = 50;
+                        const expectedEvaluationResult: string = 'aaabbbcccdddeee';
+                        let isEvaluationSuccessful: boolean = true;
+
+                        before(() => {
+                            const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-2.js');
+
+                            for (let i = 0; i < samplesCount; i++) {
+                                const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
+                                    code,
+                                    {
+                                        ...NO_ADDITIONAL_NODES_PRESET,
+                                        identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
+                                        stringArray: true,
+                                        stringArrayThreshold: 1,
+                                        stringArrayEncoding: [
+                                            StringArrayEncoding.None,
+                                            StringArrayEncoding.Rc4
+                                        ],
+                                        stringArrayWrappersChainedCalls: true,
+                                        stringArrayWrappersCount: 5
+                                    }
+                                ).getObfuscatedCode();
+
+                                const evaluationResult: string = eval(obfuscatedCode);
+
+                                if (evaluationResult !== expectedEvaluationResult) {
+                                    isEvaluationSuccessful = false;
+                                    break;
+                                }
+                            }
+                        });
+
+                        it('should correctly evaluate string array wrappers chained calls', () => {
+                            assert.equal(isEvaluationSuccessful, true);
+                        });
+                    });
+
+                    describe('Variant #2: `Mangled` identifier names generator', () => {
+                        const samplesCount: number = 50;
+                        const expectedEvaluationResult: string = 'aaabbbcccdddeee';
+                        let isEvaluationSuccessful: boolean = true;
+
+                        before(() => {
+                            const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-2.js');
+
+                            for (let i = 0; i < samplesCount; i++) {
+                                const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
+                                    code,
+                                    {
+                                        ...NO_ADDITIONAL_NODES_PRESET,
+                                        identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
+                                        stringArray: true,
+                                        stringArrayThreshold: 1,
+                                        stringArrayEncoding: [
+                                            StringArrayEncoding.None,
+                                            StringArrayEncoding.Rc4
+                                        ],
+                                        stringArrayWrappersChainedCalls: true,
+                                        stringArrayWrappersCount: 5
+                                    }
+                                ).getObfuscatedCode();
+
+                                const evaluationResult: string = eval(obfuscatedCode);
+
+                                if (evaluationResult !== expectedEvaluationResult) {
+                                    isEvaluationSuccessful = false;
+                                    break;
+                                }
+                            }
+                        });
+
+                        it('should correctly evaluate string array wrappers chained calls', () => {
+                            assert.equal(isEvaluationSuccessful, true);
+                        });
+                    });
                 });
             });
         });

+ 24 - 0
test/functional-tests/node-transformers/string-array-transformers/string-array-transformer/fixtures/string-array-wrappers-chained-calls-1.js

@@ -0,0 +1,24 @@
+const foo = 'aaa';
+
+function test (a, b) {
+    const bar = 'bbb';
+    const baz = 'ccc';
+
+    function test1 (a, b) {
+        const bark = 'ddd';
+        const hawk = 'eee';
+
+        function test2 (a, b) {
+            const bark = 'ddd';
+            const hawk = 'eee';
+
+            return bark + hawk;
+        }
+
+        return bark + hawk;
+    }
+
+    return bar + baz + test1();
+}
+
+foo + test();

+ 27 - 0
test/functional-tests/node-transformers/string-array-transformers/string-array-transformer/fixtures/string-array-wrappers-chained-calls-2.js

@@ -0,0 +1,27 @@
+const foo = 'aaa';
+
+function test (a, b) {
+    const bar = 'bbb';
+
+    function test1 (a, b) {
+        const baz = 'ccc';
+
+        function test2 (a, b) {
+            const bark = 'ddd';
+
+            return bark;
+        }
+
+        return baz + test2();
+    }
+
+    return bar + test1();
+}
+
+function test3 (a, b) {
+    const hawk = 'eee';
+
+    return hawk;
+}
+
+foo + test() + test3();

+ 0 - 17
test/functional-tests/node-transformers/string-array-transformers/string-array-transformer/fixtures/string-array-wrappers-chained-calls.js

@@ -1,17 +0,0 @@
-const foo = 'aaa';
-
-function test () {
-    const bar = 'bbb';
-    const baz = 'ccc';
-
-    function test1 () {
-        const bark = 'ddd';
-        const hawk = 'eee';
-
-        return bark + hawk;
-    }
-
-    return bar + baz + test1();
-}
-
-foo + test();

+ 60 - 1
test/unit-tests/generators/identifier-names-generators/MangledlIdentifierNamesGenerator.spec.ts

@@ -10,6 +10,7 @@ import { IInversifyContainerFacade } from '../../../../src/interfaces/container/
 import { IdentifierNamesGenerator } from '../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
 
 import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
+import { MangledIdentifierNamesGenerator } from '../../../../src/generators/identifier-names-generators/MangledIdentifierNamesGenerator';
 
 describe('MangledIdentifierNamesGenerator', () => {
     describe('generateNext', () => {
@@ -170,7 +171,65 @@ describe('MangledIdentifierNamesGenerator', () => {
         });
     });
 
-    describe('isValidIdentifierName (identifierName: string): boolean', () => {
+    describe('isIncrementedMangledName', () => {
+        const names: [nameA: string, nameB: string, result: boolean][] = [
+            ['aa', 'aa', false],
+
+            ['a', '9', true],
+            ['9', 'a', false],
+
+            ['b', 'a', true],
+            ['a', 'b', false],
+
+            ['A', 'z', true],
+            ['z', 'A', false],
+
+            ['B', 'A', true],
+            ['A', 'B', false],
+
+            ['a0', 'Z', true],
+            ['Z', 'a0', false],
+
+            ['a9', 'a0', true],
+            ['a0', 'a9', false],
+
+            ['z0', 'a0', true],
+            ['a0', 'z0', false],
+
+            ['a0', 'a', true],
+            ['a', 'a0', false],
+
+            ['A0', 'a0', true],
+            ['a0', 'A0', false],
+
+            ['z1', 'a0', true],
+            ['a0', 'z1', false],
+
+            ['aa0', 'ZZ', true],
+            ['ZZ', 'aa0', false],
+
+            ['aaA', 'aa0', true],
+            ['aa0', 'aaA', false]
+        ];
+
+        names.forEach(([nameA, nameB, expectedResult], index: number) => {
+            describe(`Variant #${index + 1}: \`${nameA}\` and \`${nameB}\``, () => {
+                let result: boolean;
+
+                beforeEach(() => {
+                    console.time();
+                    result = MangledIdentifierNamesGenerator.isIncrementedMangledName(nameA, nameB);
+                    console.timeEnd();
+                });
+
+                it('should compare mangled names', () => {
+                    assert.equal(result, expectedResult);
+                });
+            });
+        })
+    });
+
+    describe('isValidIdentifierName', () => {
         describe('Variant #1: reserved name as simple string', () => {
             const expectedFirstIdentifier: string = 'a';
             const expectedSecondIdentifier: string = 'd';

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