ソースを参照

Obfuscation of import specifiers #2

sanex3339 7 年 前
コミット
bcb3569e83

ファイルの差分が大きいため隠しています
+ 0 - 0
dist/index.js


+ 1 - 1
src/JavaScriptObfuscator.ts

@@ -61,7 +61,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
         NodeTransformer.CatchClauseTransformer,
         NodeTransformer.FunctionDeclarationTransformer,
         NodeTransformer.FunctionTransformer,
-        NodeTransformer.ImportSpecifierTransformer,
+        NodeTransformer.ImportDeclarationTransformer,
         NodeTransformer.LabeledStatementTransformer,
         NodeTransformer.LiteralTransformer,
         NodeTransformer.MemberExpressionTransformer,

+ 3 - 3
src/container/modules/node-transformers/ObfuscatingTransformersModule.ts

@@ -16,7 +16,7 @@ import { CatchClauseTransformer } from '../../../node-transformers/obfuscating-t
 import { ClassDeclarationTransformer } from '../../../node-transformers/obfuscating-transformers/ClassDeclarationTransformer';
 import { FunctionDeclarationTransformer } from '../../../node-transformers/obfuscating-transformers/FunctionDeclarationTransformer';
 import { FunctionTransformer } from '../../../node-transformers/obfuscating-transformers/FunctionTransformer';
-import { ImportSpecifierTransformer } from '../../../node-transformers/obfuscating-transformers/ImportSpecifierTransformer';
+import { ImportDeclarationTransformer } from '../../../node-transformers/obfuscating-transformers/ImportDeclarationTransformer';
 import { LabeledStatementTransformer } from '../../../node-transformers/obfuscating-transformers/LabeledStatementTransformer';
 import { LiteralTransformer } from '../../../node-transformers/obfuscating-transformers/LiteralTransformer';
 import { NumberLiteralObfuscatingReplacer } from '../../../node-transformers/obfuscating-transformers/obfuscating-replacers/literal-obfuscating-replacers/NumberLiteralObfuscatingReplacer';
@@ -42,8 +42,8 @@ export const obfuscatingTransformersModule: interfaces.ContainerModule = new Con
         .whenTargetNamed(NodeTransformer.FunctionTransformer);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
-        .to(ImportSpecifierTransformer)
-        .whenTargetNamed(NodeTransformer.ImportSpecifierTransformer);
+        .to(ImportDeclarationTransformer)
+        .whenTargetNamed(NodeTransformer.ImportDeclarationTransformer);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(LabeledStatementTransformer)

+ 1 - 1
src/enums/node-transformers/NodeTransformer.ts

@@ -9,7 +9,7 @@ export enum NodeTransformer {
     CatchClauseTransformer = 'CatchClauseTransformer',
     FunctionDeclarationTransformer = 'FunctionDeclarationTransformer',
     FunctionTransformer = 'FunctionTransformer',
-    ImportSpecifierTransformer = 'ImportSpecifierTransformer',
+    ImportDeclarationTransformer = 'ImportDeclarationTransformer',
     LabeledStatementTransformer = 'LabeledStatementTransformer',
     LiteralTransformer = 'LiteralTransformer',
     MemberExpressionTransformer = 'MemberExpressionTransformer',

+ 1 - 0
src/enums/node/NodeType.ts

@@ -21,6 +21,7 @@ export enum NodeType {
     ImportDeclaration = 'ImportDeclaration',
     ImportDefaultSpecifier = 'ImportDefaultSpecifier',
     ImportNamespaceSpecifier = 'ImportNamespaceSpecifier',
+    ImportSpecifier = 'ImportSpecifier',
     LabeledStatement = 'LabeledStatement',
     Literal = 'Literal',
     LogicalExpression = 'LogicalExpression',

+ 26 - 22
src/node-transformers/obfuscating-transformers/ImportSpecifierTransformer.ts → src/node-transformers/obfuscating-transformers/ImportDeclarationTransformer.ts

@@ -5,6 +5,7 @@ import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
 import { TIdentifierObfuscatingReplacerFactory } from "../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory";
+import { TImportSpecifier } from '../../types/node/TimportSpecifier';
 import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
 
 import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
@@ -30,7 +31,7 @@ import { NodeUtils } from '../../node/NodeUtils';
  *     import * as _0x12d45f from './bar';
  */
 @injectable()
-export class ImportSpecifierTransformer extends AbstractNodeTransformer {
+export class ImportDeclarationTransformer extends AbstractNodeTransformer {
     /**
      * @type {IIdentifierObfuscatingReplacer}
      */
@@ -59,6 +60,15 @@ export class ImportSpecifierTransformer extends AbstractNodeTransformer {
         );
     }
 
+    /**
+     * @param {TImportSpecifier} importSpecifierNode
+     * @returns {boolean}
+     */
+    private static isProhibitedImportSpecifierNode (importSpecifierNode: TImportSpecifier): boolean {
+        return NodeGuards.isImportSpecifierNode(importSpecifierNode)
+            && importSpecifierNode.imported.name === importSpecifierNode.local.name;
+    }
+
     /**
      * @param {TransformationStage} transformationStage
      * @returns {IVisitor | null}
@@ -68,13 +78,7 @@ export class ImportSpecifierTransformer extends AbstractNodeTransformer {
             case TransformationStage.Obfuscating:
                 return {
                     enter: (node: ESTree.Node, parentNode: ESTree.Node | null) => {
-                        if (
-                            parentNode
-                            && (
-                                NodeGuards.isImportDefaultSpecifierNode(node)
-                                || NodeGuards.isImportNamespaceSpecifierNode(node)
-                            )
-                        ) {
+                        if (parentNode && NodeGuards.isImportDeclarationNode(node)) {
                             return this.transformNode(node, parentNode);
                         }
                     }
@@ -86,18 +90,15 @@ export class ImportSpecifierTransformer extends AbstractNodeTransformer {
     }
 
     /**
-     * @param {ImportDefaultSpecifier | ImportNamespaceSpecifier} importSpecifierNode
+     * @param {ImportDeclaration} importDeclarationNode
      * @param {Node} parentNode
      * @returns {Node}
      */
-    public transformNode (
-        importSpecifierNode: ESTree.ImportDefaultSpecifier | ESTree.ImportNamespaceSpecifier,
-        parentNode: ESTree.Node
-    ): ESTree.Node {
+    public transformNode (importDeclarationNode: ESTree.ImportDeclaration, parentNode: ESTree.Node): ESTree.Node {
         const nodeIdentifier: number = this.nodeIdentifier++;
-        const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(importSpecifierNode)[0];
+        const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(importDeclarationNode)[0];
 
-        this.storeImportSpecifierName(importSpecifierNode, nodeIdentifier);
+        this.storeImportSpecifierNames(importDeclarationNode, nodeIdentifier);
 
         // check for cached identifiers for current scope node. If exist - loop through them.
         if (this.replaceableIdentifiers.has(blockScopeNode)) {
@@ -106,18 +107,21 @@ export class ImportSpecifierTransformer extends AbstractNodeTransformer {
             this.replaceScopeIdentifiers(blockScopeNode, nodeIdentifier);
         }
 
-        return importSpecifierNode;
+        return importDeclarationNode;
     }
 
     /**
-     * @param {ImportDefaultSpecifier | ImportNamespaceSpecifier} importSpecifierNode
+     * @param {ImportDefaultSpecifier | ImportNamespaceSpecifier} importDeclarationNode
      * @param {number} nodeIdentifier
      */
-    private storeImportSpecifierName (
-        importSpecifierNode: ESTree.ImportDefaultSpecifier | ESTree.ImportNamespaceSpecifier,
-        nodeIdentifier: number
-    ): void {
-        this.identifierObfuscatingReplacer.storeGlobalName(importSpecifierNode.local.name, nodeIdentifier);
+    private storeImportSpecifierNames (importDeclarationNode: ESTree.ImportDeclaration, nodeIdentifier: number): void {
+        importDeclarationNode.specifiers.forEach((importSpecifierNode: TImportSpecifier) => {
+            if (ImportDeclarationTransformer.isProhibitedImportSpecifierNode(importSpecifierNode)) {
+                return;
+            }
+
+            this.identifierObfuscatingReplacer.storeGlobalName(importSpecifierNode.local.name, nodeIdentifier);
+        });
     }
 
     /**

+ 8 - 0
src/node/NodeGuards.ts

@@ -168,6 +168,14 @@ export class NodeGuards {
         return node.type === NodeType.ImportNamespaceSpecifier;
     }
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isImportSpecifierNode (node: ESTree.Node): node is ESTree.ImportSpecifier {
+        return node.type === NodeType.ImportSpecifier;
+    }
+
     /**
      * @param {Node} node
      * @param {Node} parentNode

+ 5 - 0
src/types/node/TimportSpecifier.d.ts

@@ -0,0 +1,5 @@
+import * as ESTree from 'estree';
+
+export type TImportSpecifier = ESTree.ImportSpecifier
+    | ESTree.ImportDefaultSpecifier
+    | ESTree.ImportNamespaceSpecifier;

+ 152 - 0
test/functional-tests/node-transformers/obfuscating-transformers/impot-declaration-transformer/ImportDeclarationTransformer.spec.ts

@@ -0,0 +1,152 @@
+import { assert } from 'chai';
+
+import { IObfuscationResult } from '../../../../../src/interfaces/IObfuscationResult';
+
+import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
+
+import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
+import { readFileAsString } from '../../../../helpers/readFileAsString';
+
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
+
+describe('ImportDeclarationTransformer', () => {
+    describe('transformation of `importSpecifier` node identifiers', () => {
+        describe('Variant #1: `defaultImportSpecifier` node', () => {
+            const importSpecifierRegExp: RegExp = /import (_0x[a-f0-9]{4,6}) from *'\.\/foo';/;
+            const consoleLogRegExp: RegExp = /console\['log']\((_0x[a-f0-9]{4,6})\);/;
+
+            let obfuscatedCode: string,
+                importSpecifierIdentifier: string,
+                consoleLogIdentifier: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/default-import.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET
+                    }
+                );
+
+                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                importSpecifierIdentifier = getRegExpMatch(obfuscatedCode, importSpecifierRegExp);
+                consoleLogIdentifier = getRegExpMatch(obfuscatedCode, consoleLogRegExp);
+            });
+
+            it('should transform import specifier identifier name', () => {
+                assert.equal(importSpecifierIdentifier, consoleLogIdentifier);
+            });
+        });
+
+        describe('Variant #2: `namespaceImportSpecifier` node', () => {
+            const importSpecifierRegExp: RegExp = /import *\* *as *(_0x[a-f0-9]{4,6}) *from *'\.\/foo';/;
+            const consoleLogRegExp: RegExp = /console\['log']\((_0x[a-f0-9]{4,6})\);/;
+
+            let obfuscatedCode: string,
+                importSpecifierIdentifier: string,
+                consoleLogIdentifier: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/namespace-import.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET
+                    }
+                );
+
+                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                importSpecifierIdentifier = getRegExpMatch(obfuscatedCode, importSpecifierRegExp);
+                consoleLogIdentifier = getRegExpMatch(obfuscatedCode, consoleLogRegExp);
+            });
+
+            it('should transform import specifier identifier name', () => {
+                assert.equal(importSpecifierIdentifier, consoleLogIdentifier);
+            });
+        });
+
+        describe('Variant #3: named `importSpecifier` node', () => {
+            describe('Variant #1: named import specifier with same `import` and `local` names', () => {
+                const importSpecifierRegExp: RegExp = /import *{foo} *from *'\.\/foo';/;
+                const consoleLogRegExp: RegExp = /console\['log']\(foo\);/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/named-import-1.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    );
+
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                });
+
+                it('Match #1: shouldn\'t transform import specifier identifier name', () => {
+                    assert.match(obfuscatedCode, importSpecifierRegExp);
+                });
+
+                it('Match #2: shouldn\'t transform import specifier identifier name', () => {
+                    assert.match(obfuscatedCode, consoleLogRegExp);
+                });
+            });
+
+            describe('Variant #2: named import specifier with different `import` and `local` names', () => {
+                const importSpecifierRegExp: RegExp = /import *{foo as (_0x[a-f0-9]{4,6})} *from *'\.\/foo';/;
+                const consoleLogRegExp: RegExp = /console\['log']\((_0x[a-f0-9]{4,6})\);/;
+
+                let obfuscatedCode: string,
+                    importSpecifierIdentifier: string,
+                    consoleLogIdentifier: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/named-import-2.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    );
+
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                    importSpecifierIdentifier = getRegExpMatch(obfuscatedCode, importSpecifierRegExp);
+                    consoleLogIdentifier = getRegExpMatch(obfuscatedCode, consoleLogRegExp);
+                });
+
+                it('should transform import specifier identifier name', () => {
+                    assert.equal(importSpecifierIdentifier, consoleLogIdentifier);
+                });
+            });
+        });
+
+        describe('Variant #4: `identifiersPrefix` option', () => {
+            const importSpecifierRegExp: RegExp = /import *\* *as *(bark_0x[a-f0-9]{4,6}) *from *'\.\/foo';/;
+            const consoleLogRegExp: RegExp = /console\['log']\((bark_0x[a-f0-9]{4,6})\);/;
+
+            let obfuscatedCode: string,
+                importSpecifierIdentifier: string,
+                consoleLogIdentifier: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/namespace-import.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        identifiersPrefix: 'bark'
+                    }
+                );
+
+                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                importSpecifierIdentifier = getRegExpMatch(obfuscatedCode, importSpecifierRegExp);
+                consoleLogIdentifier = getRegExpMatch(obfuscatedCode, consoleLogRegExp);
+            });
+
+            it('should transform import specifier identifier name', () => {
+                assert.equal(importSpecifierIdentifier, consoleLogIdentifier);
+            });
+        });
+    });
+});

+ 0 - 0
test/functional-tests/node-transformers/obfuscating-transformers/impot-specifier-transformer/fixtures/default-import.js → test/functional-tests/node-transformers/obfuscating-transformers/impot-declaration-transformer/fixtures/default-import.js


+ 0 - 0
test/functional-tests/node-transformers/obfuscating-transformers/impot-specifier-transformer/fixtures/named-import.js → test/functional-tests/node-transformers/obfuscating-transformers/impot-declaration-transformer/fixtures/named-import-1.js


+ 2 - 0
test/functional-tests/node-transformers/obfuscating-transformers/impot-declaration-transformer/fixtures/named-import-2.js

@@ -0,0 +1,2 @@
+import {foo as bar} from './foo';
+console.log(bar);

+ 0 - 0
test/functional-tests/node-transformers/obfuscating-transformers/impot-specifier-transformer/fixtures/namespace-import.js → test/functional-tests/node-transformers/obfuscating-transformers/impot-declaration-transformer/fixtures/namespace-import.js


+ 0 - 95
test/functional-tests/node-transformers/obfuscating-transformers/impot-specifier-transformer/ImportSpecifierTransformer.spec.ts

@@ -1,95 +0,0 @@
-import { assert } from 'chai';
-
-import { IObfuscationResult } from '../../../../../src/interfaces/IObfuscationResult';
-
-import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
-
-import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
-import { readFileAsString } from '../../../../helpers/readFileAsString';
-
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
-
-describe('ImportSpecifierTransformer', () => {
-    describe('transformation of `importSpecifier` node identifiers', () => {
-        describe('Variant #1: `defaultImportSpecifier` node', () => {
-            const importSpecifierRegExp: RegExp = /import (_0x[a-f0-9]{4,6}) from *'\.\/foo';/;
-            const consoleLogRegExp: RegExp = /console\['log']\((_0x[a-f0-9]{4,6})\);/;
-
-            let obfuscatedCode: string,
-                importSpecifierIdentifier: string,
-                consoleLogIdentifier: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/default-import.js');
-                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET
-                    }
-                );
-
-                obfuscatedCode = obfuscationResult.getObfuscatedCode();
-                importSpecifierIdentifier = getRegExpMatch(obfuscatedCode, importSpecifierRegExp);
-                consoleLogIdentifier = getRegExpMatch(obfuscatedCode, consoleLogRegExp);
-            });
-
-            it('should transform import specifier identifier name', () => {
-                assert.equal(importSpecifierIdentifier, consoleLogIdentifier);
-            });
-        });
-
-        describe('Variant #2: `namespaceImportSpecifier` node', () => {
-            const importSpecifierRegExp: RegExp = /import *\* *as *(_0x[a-f0-9]{4,6}) *from *'\.\/foo';/;
-            const consoleLogRegExp: RegExp = /console\['log']\((_0x[a-f0-9]{4,6})\);/;
-
-            let obfuscatedCode: string,
-                importSpecifierIdentifier: string,
-                consoleLogIdentifier: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/namespace-import.js');
-                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET
-                    }
-                );
-
-                obfuscatedCode = obfuscationResult.getObfuscatedCode();
-                importSpecifierIdentifier = getRegExpMatch(obfuscatedCode, importSpecifierRegExp);
-                consoleLogIdentifier = getRegExpMatch(obfuscatedCode, consoleLogRegExp);
-            });
-
-            it('should transform import specifier identifier name', () => {
-                assert.equal(importSpecifierIdentifier, consoleLogIdentifier);
-            });
-        });
-
-        describe('Variant #3: `importSpecifier` node', () => {
-            const importSpecifierRegExp: RegExp = /import *{foo} *from *'\.\/foo';/;
-            const consoleLogRegExp: RegExp = /console\['log']\(foo\);/;
-
-            let obfuscatedCode: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/named-import.js');
-                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET
-                    }
-                );
-
-                obfuscatedCode = obfuscationResult.getObfuscatedCode();
-            });
-
-            it('Match #1: shouldn\'t transform import specifier identifier name', () => {
-                assert.match(obfuscatedCode, importSpecifierRegExp);
-            });
-
-            it('Match #2: shouldn\'t transform import specifier identifier name', () => {
-                assert.match(obfuscatedCode, consoleLogRegExp);
-            });
-        });
-    });
-});

+ 1 - 1
test/index.spec.ts

@@ -62,7 +62,7 @@ import './functional-tests/node-transformers/obfuscating-transformers/catch-clau
 import './functional-tests/node-transformers/obfuscating-transformers/class-declaration-transformer/ClassDeclarationTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec';
-import './functional-tests/node-transformers/obfuscating-transformers/impot-specifier-transformer/ImportSpecifierTransformer.spec';
+import './functional-tests/node-transformers/obfuscating-transformers/impot-declaration-transformer/ImportDeclarationTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/labeled-statement-transformer/LabeledStatementTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec';

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません