Browse Source

refactoring + control flow storage test

sanex3339 8 years ago
parent
commit
1e7628b983

File diff suppressed because it is too large
+ 248 - 287
dist/index.js


+ 1 - 1
package.json

@@ -20,7 +20,7 @@
     "javascript-obfuscator": "./bin/javascript-obfuscator.js"
   },
   "dependencies": {
-    "babel-polyfill": "6.16.0",
+    "babel-polyfill": "6.20.0",
     "chance": "1.0.4",
     "class-validator": "0.6.6",
     "commander": "2.9.0",

+ 2 - 8
src/container/InversifyContainerFacade.ts

@@ -6,6 +6,7 @@ import { nodeControlFlowTransformersModule } from './modules/node-transformers/N
 import { nodeObfuscatorsModule } from './modules/node-transformers/NodeObfuscatorsModule';
 import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
 import { stackTraceAnalyzerModule } from './modules/stack-trace-analyzer/StackTraceAnalyzerModule';
+import { storagesModule } from './modules/storages/StoragesModule';
 
 import { TInputOptions } from '../types/options/TInputOptions';
 
@@ -23,9 +24,6 @@ import { ObfuscationResult } from '../ObfuscationResult';
 import { Obfuscator } from '../Obfuscator';
 import { Options } from "../options/Options";
 import { SourceMapCorrector } from '../SourceMapCorrector';
-import { IStorage } from '../interfaces/storages/IStorage';
-import { ICustomNodeGroup } from '../interfaces/custom-nodes/ICustomNodeGroup';
-import { CustomNodeGroupStorage } from '../storages/custom-node-group/CustomNodeGroupStorage';
 
 export class InversifyContainerFacade implements IInversifyContainerFacade {
     /**
@@ -79,17 +77,13 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
             .to(SourceMapCorrector)
             .inSingletonScope();
 
-        this.container
-            .bind<IStorage<ICustomNodeGroup>>(ServiceIdentifiers['IStorage<ICustomNodeGroup>'])
-            .to(CustomNodeGroupStorage)
-            .inSingletonScope();
-
         this.container
             .bind<IObfuscationEventEmitter>(ServiceIdentifiers.IObfuscationEventEmitter)
             .to(ObfuscationEventEmitter)
             .inSingletonScope();
 
         // modules
+        this.container.load(storagesModule);
         this.container.load(stackTraceAnalyzerModule);
         this.container.load(customNodesModule);
         this.container.load(nodeTransformersModule);

+ 2 - 0
src/container/ServiceIdentifiers.ts

@@ -6,6 +6,7 @@ export const ServiceIdentifiers: any = {
     'Factory<INodeTransformer[]>': Symbol('Factory<INodeTransformer[]>'),
     'Factory<IObfuscationResult>': Symbol('Factory<IObfuscationResult>'),
     'Factory<IReplacer>': Symbol('Factory<IReplacer>'),
+    'Factory<IStorage<ICustomNode>>': Symbol('Factory<IStorage<ICustomNode>>'),
     ICalleeDataExtractor: Symbol('ICalleeDataExtractor'),
     ICustomNode: Symbol('ICustomNode'),
     ICustomNodeGroup: Symbol('ICustomNodeGroup'),
@@ -19,5 +20,6 @@ export const ServiceIdentifiers: any = {
     IReplacer: Symbol('IReplacer'),
     ISourceMapCorrector: Symbol('ISourceMapCorrector'),
     IStackTraceAnalyzer: Symbol('IStackTraceAnalyzer'),
+    'IStorage<ICustomNode>': Symbol('IStorage<ICustomNode>'),
     'IStorage<ICustomNodeGroup>': Symbol('IStorage<ICustomNodeGroup>')
 };

+ 8 - 8
src/container/modules/node-transformers/NodeControlFlowTransformersModule.ts

@@ -3,30 +3,30 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers';
 
 import { IControlFlowReplacer } from '../../../interfaces/node-transformers/IControlFlowReplacer';
 
-import { NodeControlFlowTransformersReplacers } from '../../../enums/container/NodeControlFlowTransformersReplacers';
+import { NodeControlFlowReplacers } from '../../../enums/container/NodeControlFlowReplacers';
 
 import { BinaryExpressionControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer';
 
 export const nodeControlFlowTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
     bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
         .to(BinaryExpressionControlFlowReplacer)
-        .whenTargetNamed(NodeControlFlowTransformersReplacers.BinaryExpressionControlFlowReplacer);
+        .whenTargetNamed(NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer);
 
     bind<IControlFlowReplacer>(ServiceIdentifiers['Factory<IControlFlowReplacer>'])
         .toFactory<IControlFlowReplacer>((context: interfaces.Context) => {
-            const cache: Map <NodeControlFlowTransformersReplacers, IControlFlowReplacer> = new Map <NodeControlFlowTransformersReplacers, IControlFlowReplacer> ();
+            const cache: Map <NodeControlFlowReplacers, IControlFlowReplacer> = new Map <NodeControlFlowReplacers, IControlFlowReplacer> ();
 
-            return (replacer: NodeControlFlowTransformersReplacers) => {
-                if (cache.has(replacer)) {
-                    return <IControlFlowReplacer>cache.get(replacer);
+            return (replacerName: NodeControlFlowReplacers) => {
+                if (cache.has(replacerName)) {
+                    return <IControlFlowReplacer>cache.get(replacerName);
                 }
 
                 const controlFlowReplacer: IControlFlowReplacer = context.container.getNamed<IControlFlowReplacer>(
                     ServiceIdentifiers.IControlFlowReplacer,
-                    replacer
+                    replacerName
                 );
 
-                cache.set(replacer, controlFlowReplacer);
+                cache.set(replacerName, controlFlowReplacer);
 
                 return controlFlowReplacer;
             };

+ 5 - 5
src/container/modules/node-transformers/NodeObfuscatorsModule.ts

@@ -31,17 +31,17 @@ export const nodeObfuscatorsModule: interfaces.ContainerModule = new ContainerMo
         .toFactory<IReplacer>((context: interfaces.Context) => {
             const cache: Map <NodeObfuscatorsReplacers, IReplacer> = new Map <NodeObfuscatorsReplacers, IReplacer> ();
 
-            return (replacer: NodeObfuscatorsReplacers) => {
-                if (cache.has(replacer)) {
-                    return <IReplacer>cache.get(replacer);
+            return (replacerName: NodeObfuscatorsReplacers) => {
+                if (cache.has(replacerName)) {
+                    return <IReplacer>cache.get(replacerName);
                 }
 
                 const obfuscationReplacer: IReplacer = context.container.getNamed<IReplacer>(
                     ServiceIdentifiers.IReplacer,
-                    replacer
+                    replacerName
                 );
 
-                cache.set(replacer, obfuscationReplacer);
+                cache.set(replacerName, obfuscationReplacer);
 
                 return obfuscationReplacer;
             };

+ 27 - 0
src/container/modules/storages/StoragesModule.ts

@@ -0,0 +1,27 @@
+import { ContainerModule, interfaces } from 'inversify';
+import { ServiceIdentifiers } from '../../ServiceIdentifiers';
+
+import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { ICustomNodeGroup } from '../../../interfaces/custom-nodes/ICustomNodeGroup';
+import { IStorage } from '../../../interfaces/storages/IStorage';
+
+import { ControlFlowStorage } from '../../../storages/control-flow/ControlFlowStorage';
+import { CustomNodeGroupStorage } from '../../../storages/custom-node-group/CustomNodeGroupStorage';
+
+export const storagesModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
+    // storages
+    bind<IStorage<ICustomNodeGroup>>(ServiceIdentifiers['IStorage<ICustomNodeGroup>'])
+        .to(CustomNodeGroupStorage)
+        .inSingletonScope();
+
+    bind<IStorage<ICustomNode>>(ServiceIdentifiers['IStorage<ICustomNode>'])
+        .to(ControlFlowStorage);
+
+    // controlFlowStorage factory
+    bind<IStorage<ICustomNode>>(ServiceIdentifiers['Factory<IStorage<ICustomNode>>'])
+        .toFactory<IStorage<ICustomNode>>((context: interfaces.Context) => {
+            return () => {
+                return context.container.get<IStorage<ICustomNode>>(ServiceIdentifiers['IStorage<ICustomNode>']);
+            };
+        });
+});

+ 3 - 0
src/enums/container/NodeControlFlowReplacers.ts

@@ -0,0 +1,3 @@
+export enum NodeControlFlowReplacers {
+    BinaryExpressionControlFlowReplacer
+}

+ 0 - 3
src/enums/container/NodeControlFlowTransformersReplacers.ts

@@ -1,3 +0,0 @@
-export enum NodeControlFlowTransformersReplacers {
-    BinaryExpressionControlFlowReplacer
-}

+ 41 - 16
src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts

@@ -4,39 +4,65 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
 import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
-import { TControlFlowReplacer } from '../../types/node-transformers/TControlFlowReplacer';
+import { TControlFlowReplacerFactory } from '../../types/container/TControlFlowReplacerFactory';
+import { TControlFlowStorageFactory } from '../../types/container/TControlFlowStorageFactory';
+import { TCustomNodeFactory } from '../../types/container/TCustomNodeFactory';
 import { TStatement } from '../../types/node/TStatement';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/options/IOptions';
 import { IStorage } from '../../interfaces/storages/IStorage';
 
+import { CustomNodes } from '../../enums/container/CustomNodes';
 import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
-import { BinaryExpressionControlFlowReplacer } from './control-flow-replacers/BinaryExpressionControlFlowReplacer';
-import { ControlFlowStorage } from '../../storages/control-flow/ControlFlowStorage';
-import { ControlFlowStorageNode } from '../../custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode';
 import { Node } from '../../node/Node';
 import { NodeAppender } from '../../node/NodeAppender';
+import { NodeControlFlowReplacers } from '../../enums/container/NodeControlFlowReplacers';
 import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
     /**
-     * @type {Map <string, IReplacer>}
+     * @type {Map <string, NodeControlFlowReplacers>}
      */
-    private static readonly controlFlowReplacers: Map <string, TControlFlowReplacer> = new Map <string, TControlFlowReplacer> ([
-        [NodeType.BinaryExpression, BinaryExpressionControlFlowReplacer]
+    private static readonly controlFlowReplacersMap: Map <string, NodeControlFlowReplacers> = new Map <string, NodeControlFlowReplacers> ([
+        [NodeType.BinaryExpression, NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer]
     ]);
 
     /**
+     * @type {TControlFlowReplacerFactory}
+     */
+    private readonly controlFlowReplacerFactory: TControlFlowReplacerFactory;
+
+    /**
+     * @type {TControlFlowStorageFactory}
+     */
+    private readonly controlFlowStorageFactory: TControlFlowStorageFactory;
+
+    /**
+     * @type {TCustomNodeFactory}
+     */
+    private readonly customNodeFactory: TCustomNodeFactory;
+
+    /**
+     * @param controlFlowStorageFactory
+     * @param controlFlowReplacerFactory
+     * @param customNodeFactory
      * @param options
      */
     constructor (
+        @inject(ServiceIdentifiers['Factory<IStorage<ICustomNode>>']) controlFlowStorageFactory: TControlFlowStorageFactory,
+        @inject(ServiceIdentifiers['Factory<IControlFlowReplacer>']) controlFlowReplacerFactory: TControlFlowReplacerFactory,
+        @inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(options);
+
+        this.controlFlowStorageFactory = controlFlowStorageFactory;
+        this.controlFlowReplacerFactory = controlFlowReplacerFactory;
+        this.customNodeFactory = customNodeFactory;
     }
 
     /**
@@ -54,21 +80,20 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
             return;
         }
 
-        const controlFlowStorage: IStorage <ICustomNode> = new ControlFlowStorage();
+        const controlFlowStorage: IStorage <ICustomNode> = this.controlFlowStorageFactory();
         const controlFlowStorageCustomNodeName: string = RandomGeneratorUtils.getRandomVariableName(6);
 
         estraverse.replace(functionNode.body, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
-                const controlFlowReplacer: TControlFlowReplacer | undefined = FunctionControlFlowTransformer
-                    .controlFlowReplacers.get(node.type);
+                const controlFlowReplacerName: NodeControlFlowReplacers | undefined = FunctionControlFlowTransformer
+                    .controlFlowReplacersMap.get(node.type);
 
-                if (!controlFlowReplacer) {
+                if (controlFlowReplacerName === undefined) {
                     return;
                 }
 
-                const controlFlowStorageCallCustomNode: ICustomNode | undefined = new controlFlowReplacer(
-                    this.options
-                ).replace(node, parentNode, controlFlowStorage, controlFlowStorageCustomNodeName);
+                const controlFlowStorageCallCustomNode: ICustomNode | undefined = this.controlFlowReplacerFactory(controlFlowReplacerName)
+                    .replace(node, parentNode, controlFlowStorage, controlFlowStorageCustomNodeName);
 
                 if (!controlFlowStorageCallCustomNode) {
                     return;
@@ -78,7 +103,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
                 // so we can get it by index `0`
                 // also we need to return `expression` property of `ExpressionStatement` node because bug:
                 // https://github.com/estools/escodegen/issues/289
-                const statementNode: TStatement | undefined = controlFlowStorageCallCustomNode.getNode()[0];
+                const statementNode: TStatement = controlFlowStorageCallCustomNode.getNode()[0];
 
                 if (!statementNode || !Node.isExpressionStatementNode(statementNode)) {
                     throw new Error(`\`controlFlowStorageCallCustomNode.getNode()\` should returns array with \`ExpressionStatement\` node`);
@@ -92,7 +117,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
             return;
         }
 
-        const controlFlowStorageCustomNode: ICustomNode = new ControlFlowStorageNode(this.options);
+        const controlFlowStorageCustomNode: ICustomNode = this.customNodeFactory(CustomNodes.ControlFlowStorageNode);
 
         controlFlowStorageCustomNode.initialize(controlFlowStorage, controlFlowStorageCustomNodeName);
 

+ 17 - 9
src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts

@@ -4,23 +4,34 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
 import * as escodegen from 'escodegen';
 import * as ESTree from 'estree';
 
+import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';
+
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../../interfaces/options/IOptions';
 import { IStorage } from '../../../interfaces/storages/IStorage';
 
+import { CustomNodes } from '../../../enums/container/CustomNodes';
+
 import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
-import { BinaryExpressionFunctionNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode';
-import { ControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode';
 
 @injectable()
 export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
     /**
+     * @type {TCustomNodeFactory}
+     */
+    private readonly customNodeFactory: TCustomNodeFactory;
+
+    /**
+     * @param customNodeFactory
      * @param options
      */
     constructor (
+        @inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(options);
+
+        this.customNodeFactory = customNodeFactory;
     }
 
     /**
@@ -47,15 +58,10 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl
         controlFlowStorageCustomNodeName: string
     ): ICustomNode {
         const key: string = AbstractControlFlowReplacer.getStorageKey();
-        const binaryExpressionFunctionNode = new BinaryExpressionFunctionNode(this.options);
+        const binaryExpressionFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.BinaryExpressionFunctionNode);
+        const controlFlowStorageCallNode: ICustomNode = this.customNodeFactory(CustomNodes.ControlFlowStorageCallNode);
 
-        // TODO: pass through real stackTraceData
         binaryExpressionFunctionNode.initialize(binaryExpressionNode.operator);
-
-        controlFlowStorage.set(key, binaryExpressionFunctionNode);
-
-        const controlFlowStorageCallNode: ICustomNode = new ControlFlowStorageCallNode(this.options);
-
         controlFlowStorageCallNode.initialize(
             controlFlowStorageCustomNodeName,
             key,
@@ -63,6 +69,8 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl
             BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.right)
         );
 
+        controlFlowStorage.set(key, binaryExpressionFunctionNode);
+
         return controlFlowStorageCallNode;
     }
 }

+ 5 - 0
src/types/container/TControlFlowReplacerFactory.d.ts

@@ -0,0 +1,5 @@
+import { IControlFlowReplacer } from '../../interfaces/node-transformers/IControlFlowReplacer';
+
+import { NodeControlFlowReplacers } from '../../enums/container/NodeControlFlowReplacers';
+
+export type TControlFlowReplacerFactory = (replacer: NodeControlFlowReplacers) => IControlFlowReplacer;

+ 4 - 0
src/types/container/TControlFlowStorageFactory.d.ts

@@ -0,0 +1,4 @@
+import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
+import { IStorage } from '../../interfaces/storages/IStorage';
+
+export type TControlFlowStorageFactory = () => IStorage<ICustomNode>;

+ 0 - 4
src/types/node-transformers/TControlFlowReplacer.d.ts

@@ -1,4 +0,0 @@
-import { IControlFlowReplacer } from '../../interfaces/node-transformers/IControlFlowReplacer';
-import { IOptions } from '../../interfaces/options/IOptions';
-
-export type TControlFlowReplacer = (new (options: IOptions) => IControlFlowReplacer);

+ 19 - 8
test/unit-tests/storages/ControlFlowStorage.spec.ts

@@ -1,7 +1,8 @@
-/*
 import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
 
- import { assert } from 'chai';
+import { assert } from 'chai';
+
+import { TCustomNodeFactory } from '../../../src/types/container/TCustomNodeFactory';
 
 import { ICustomNode } from '../../../src/interfaces/custom-nodes/ICustomNode';
 import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade';
@@ -13,19 +14,29 @@ import { InversifyContainerFacade } from '../../../src/container/InversifyContai
 
 describe('ControlFlowStorage', () => {
     describe('toString (): string', () => {
-        it('should returns obfuscated code if `.toString()` was called on `ObfuscationResult` object', () => {
+        it('should return correct ControlFlowStorage data after `.toString()` call', () => {
+            const key1: string = 'key1';
+            const key2: string = 'key2';
             const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade({
                 controlFlowFlattening: true
             });
+            const customNodeFactory: TCustomNodeFactory = inversifyContainerFacade
+                .get<TCustomNodeFactory>(ServiceIdentifiers['Factory<ICustomNode>']);
             const controlFlowStorage: IStorage <ICustomNode> = inversifyContainerFacade
                 .get<IStorage<ICustomNode>>(ServiceIdentifiers['IStorage<ICustomNode>']);
-            const controlFlowStorageCallNode: ICustomNode = inversifyContainerFacade
-                .getNamed<ICustomNode>(ServiceIdentifiers.ICustomNode, CustomNodes.ControlFlowStorageCallNode);
+            const controlFlowStorageCallNode1: ICustomNode = customNodeFactory(CustomNodes.ControlFlowStorageCallNode);
+            const controlFlowStorageCallNode2: ICustomNode = customNodeFactory(CustomNodes.ControlFlowStorageCallNode);
+
+            controlFlowStorageCallNode1.initialize('controlFlowStorageName', key1, 1, 2);
+            controlFlowStorageCallNode2.initialize('controlFlowStorageName', key2, 3, 4);
 
-            controlFlowStorage.set('key1', controlFlowStorageCallNode);
+            controlFlowStorage.set(key1, controlFlowStorageCallNode1);
+            controlFlowStorage.set(key2, controlFlowStorageCallNode2);
 
-            assert.equal(controlFlowStorage.toString(), [`key1: ${controlFlowStorageCallNode.getCode()}`]);
+            assert.equal(
+                controlFlowStorage.toString(),
+                `${key1}: ${controlFlowStorageCallNode1.getCode()},${key2}: ${controlFlowStorageCallNode2.getCode()}`
+            );
         });
     });
 });
-*/

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