ソースを参照

added BlockStatementControlFlowReplacer

sanex3339 8 年 前
コミット
cd02a0bf82

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


+ 5 - 0
src/container/modules/node-transformers/NodeControlFlowTransformersModule.ts

@@ -6,6 +6,7 @@ import { IControlFlowReplacer } from '../../../interfaces/node-transformers/ICon
 import { NodeControlFlowReplacers } from '../../../enums/container/NodeControlFlowReplacers';
 
 import { BinaryExpressionControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer';
+import { BlockStatementControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/BlockStatementControlFlowReplacer';
 import { CallExpressionControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer';
 import { LogicalExpressionControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer';
 
@@ -14,6 +15,10 @@ export const nodeControlFlowTransformersModule: interfaces.ContainerModule = new
         .to(BinaryExpressionControlFlowReplacer)
         .whenTargetNamed(NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer);
 
+    bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
+        .to(BlockStatementControlFlowReplacer)
+        .whenTargetNamed(NodeControlFlowReplacers.BlockStatementControlFlowReplacer);
+
     bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
         .to(CallExpressionControlFlowReplacer)
         .whenTargetNamed(NodeControlFlowReplacers.CallExpressionControlFlowReplacer);

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

@@ -1,5 +1,6 @@
 export enum NodeControlFlowReplacers {
     BinaryExpressionControlFlowReplacer,
+    BlockStatementControlFlowReplacer,
     CallExpressionControlFlowReplacer,
     LogicalExpressionControlFlowReplacer
 }

+ 20 - 127
src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts

@@ -20,10 +20,8 @@ import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { Node } from '../../node/Node';
 import { NodeAppender } from '../../node/NodeAppender';
 import { NodeControlFlowReplacers } from '../../enums/container/NodeControlFlowReplacers';
-import { Nodes } from '../../node/Nodes';
 import { NodeUtils } from '../../node/NodeUtils';
 import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
-import { Utils } from '../../utils/Utils';
 
 @injectable()
 export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
@@ -32,6 +30,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
      */
     private static readonly controlFlowReplacersMap: Map <string, NodeControlFlowReplacers> = new Map([
         [NodeType.BinaryExpression, NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer],
+        [NodeType.BlockStatement, NodeControlFlowReplacers.BlockStatementControlFlowReplacer],
         [NodeType.CallExpression, NodeControlFlowReplacers.CallExpressionControlFlowReplacer],
         [NodeType.LogicalExpression, NodeControlFlowReplacers.LogicalExpressionControlFlowReplacer]
     ]);
@@ -90,18 +89,6 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
         this.customNodeFactory = customNodeFactory;
     }
 
-    /**
-     * @param node
-     * @return {boolean}
-     */
-    private static functionHasProhibitedStatements (node: ESTree.Node): boolean {
-        const isBreakOrContinueStatement: boolean = Node.isBreakStatementNode(node) || Node.isContinueStatementNode(node);
-        const isVariableDeclarationWithLetOrConstKind: boolean = Node.isVariableDeclarationNode(node) &&
-            (node.kind === 'const' ||  node.kind === 'let');
-
-        return Node.isFunctionDeclarationNode(node) || isBreakOrContinueStatement || isVariableDeclarationWithLetOrConstKind;
-    }
-
     /**
      * @param functionNode
      * @returns {TNodeWithBlockStatement}
@@ -138,23 +125,8 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
         const hostNode: TNodeWithBlockStatement = FunctionControlFlowTransformer.getHostNode(functionNode);
         const controlFlowStorage: IStorage<ICustomNode> = this.getControlFlowStorage(hostNode);
 
-        let functionHasProhibitedStatements: boolean = false;
-
         this.controlFlowData.set(hostNode, controlFlowStorage);
-
-        estraverse.replace(functionNode.body, {
-            enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
-                if (!functionHasProhibitedStatements) {
-                    functionHasProhibitedStatements = FunctionControlFlowTransformer.functionHasProhibitedStatements(node);
-                }
-
-                return this.transformFunctionNodes(node, parentNode, controlFlowStorage);
-            }
-        });
-
-        if (!functionHasProhibitedStatements) {
-            this.transformFunctionStatements(functionNode);
-        }
+        this.transformFunctionBody(functionNode.body, controlFlowStorage);
 
         if (!controlFlowStorage.getLength()) {
             return functionNode;
@@ -190,108 +162,29 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
     }
 
     /**
-     * @param node
-     * @param parentNode
+     * @param functionNodeBody
      * @param controlFlowStorage
      * @return {ESTree.Node}
      */
-    private transformFunctionNodes (
-        node: ESTree.Node,
-        parentNode: ESTree.Node,
-        controlFlowStorage: IStorage<ICustomNode>
-    ): ESTree.Node {
-        if (!FunctionControlFlowTransformer.controlFlowReplacersMap.has(node.type)) {
-            return node;
-        }
-
-        if (RandomGeneratorUtils.getRandomFloat(0, 1) > this.options.controlFlowFlatteningThreshold) {
-            return node;
-        }
-
-        const controlFlowReplacerName: NodeControlFlowReplacers = <NodeControlFlowReplacers>FunctionControlFlowTransformer
-            .controlFlowReplacersMap.get(node.type);
-
-        return {
-            ...this.controlFlowReplacerFactory(controlFlowReplacerName).replace(node, parentNode, controlFlowStorage),
-            parentNode
-        };
-    }
+    private transformFunctionBody (functionNodeBody: ESTree.BlockStatement, controlFlowStorage: IStorage<ICustomNode>): void {
+        estraverse.replace(functionNodeBody, {
+            enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
+                if (!FunctionControlFlowTransformer.controlFlowReplacersMap.has(node.type)) {
+                    return node;
+                }
 
-    /**
-     * @param functionNode
-     */
-    private transformFunctionStatements (functionNode: ESTree.FunctionExpression | ESTree.FunctionDeclaration): void {
-        if (RandomGeneratorUtils.getRandomFloat(0, 1) > this.options.controlFlowFlatteningThreshold) {
-            return;
-        }
+                if (RandomGeneratorUtils.getRandomFloat(0, 1) > this.options.controlFlowFlatteningThreshold) {
+                    return node;
+                }
 
-        const functionStatements: ESTree.Statement[] = functionNode.body.body;
-        const functionStatementsObject: any = Object.assign({}, functionStatements);
-        const originalKeys: number[] = Object.keys(functionStatementsObject).map((key: string) => parseInt(key, 10));
-        const shuffledKeys: number[] = Utils.arrayShuffle(originalKeys);
-        const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key));
-
-        if (functionStatements.length <= 4) {
-            return;
-        } else if (!functionStatements.length) {
-            functionStatements.push(
-                Nodes.getReturnStatementNode(
-                    Nodes.getLiteralNode(true)
-                )
-            );
-        }
+                const controlFlowReplacerName: NodeControlFlowReplacers = <NodeControlFlowReplacers>FunctionControlFlowTransformer
+                    .controlFlowReplacersMap.get(node.type);
 
-        const controllerIdentifierName: string = RandomGeneratorUtils.getRandomString(3);
-        const indexIdentifierName: string = RandomGeneratorUtils.getRandomString(3);
-
-        functionNode.body.body = [
-            Nodes.getVariableDeclarationNode([
-                Nodes.getVariableDeclaratorNode(
-                    Nodes.getIdentifierNode(controllerIdentifierName),
-                    Nodes.getCallExpressionNode(
-                        Nodes.getMemberExpressionNode(
-                            Nodes.getLiteralNode(
-                                originalKeysIndexesInShuffledArray.join('|')
-                            ),
-                            Nodes.getIdentifierNode('split')
-                        ),
-                        [
-                            Nodes.getLiteralNode('|')
-                        ]
-                    )
-                ),
-                Nodes.getVariableDeclaratorNode(
-                    Nodes.getIdentifierNode(indexIdentifierName),
-                    Nodes.getLiteralNode(0)
-                )
-            ]),
-            Nodes.getWhileStatementNode(
-                Nodes.getLiteralNode(true),
-                Nodes.getBlockStatementNode([
-                    Nodes.getSwitchStatementNode(
-                        Nodes.getMemberExpressionNode(
-                            Nodes.getIdentifierNode(controllerIdentifierName),
-                            Nodes.getUpdateExpressionNode(
-                                '++',
-                                Nodes.getIdentifierNode(indexIdentifierName)
-                            ),
-                            true
-                        ),
-                        shuffledKeys.map((key: number, index: number) => {
-                            return Nodes.getSwitchCaseNode(
-                                Nodes.getLiteralNode(String(index)),
-                                [
-                                    functionStatementsObject[key],
-                                    Nodes.getContinueStatement()
-                                ]
-                            );
-                        })
-                    ),
-                    Nodes.getBreakStatement()
-                ])
-            )
-        ];
-
-        NodeUtils.parentize(functionNode.body);
+                return {
+                    ...this.controlFlowReplacerFactory(controlFlowReplacerName).replace(node, parentNode, controlFlowStorage),
+                    parentNode
+                };
+            }
+        });
     }
 }

+ 132 - 0
src/node-transformers/node-control-flow-transformers/control-flow-replacers/BlockStatementControlFlowReplacer.ts

@@ -0,0 +1,132 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
+
+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 { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
+import { Node } from '../../../node/Node';
+import { Nodes } from '../../../node/Nodes';
+import { NodeUtils } from '../../../node/NodeUtils';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
+import { Utils } from '../../../utils/Utils';
+
+@injectable()
+export class BlockStatementControlFlowReplacer extends AbstractControlFlowReplacer {
+    /**
+     * @param customNodeFactory
+     * @param options
+     */
+    constructor (
+        @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(customNodeFactory, options);
+    }
+
+    /**
+     * @param blockStatementNode
+     * @return {boolean}
+     */
+    private static blockStatementHasProhibitedStatements (blockStatementNode: ESTree.BlockStatement): boolean {
+        return blockStatementNode.body.some((statement: ESTree.Statement) => {
+            const isBreakOrContinueStatement: boolean = Node.isBreakStatementNode(statement) || Node.isContinueStatementNode(statement);
+            const isVariableDeclarationWithLetOrConstKind: boolean = Node.isVariableDeclarationNode(statement) &&
+                (statement.kind === 'const' ||  statement.kind === 'let');
+
+            return Node.isFunctionDeclarationNode(statement) || isBreakOrContinueStatement || isVariableDeclarationWithLetOrConstKind;
+        });
+    }
+
+    /**
+     * @param blockStatementNode
+     * @param parentNode
+     * @param controlFlowStorage
+     * @returns {ESTree.Node}
+     */
+    public replace (
+        blockStatementNode: ESTree.BlockStatement,
+        parentNode: ESTree.Node,
+        controlFlowStorage: IStorage <ICustomNode>
+    ): ESTree.BlockStatement {
+        if (BlockStatementControlFlowReplacer.blockStatementHasProhibitedStatements(blockStatementNode)) {
+            return blockStatementNode;
+        }
+
+        const blockStatementStatements: ESTree.Statement[] = blockStatementNode.body;
+        const blockStatementStatementsAsObject: any = Object.assign({}, blockStatementStatements);
+        const originalKeys: number[] = Object.keys(blockStatementStatementsAsObject).map((key: string) => parseInt(key, 10));
+        const shuffledKeys: number[] = Utils.arrayShuffle(originalKeys);
+        const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key));
+
+        if (blockStatementStatements.length <= 4) {
+            return blockStatementNode;
+        } else if (!blockStatementStatements.length) {
+            blockStatementStatements.push(
+                Nodes.getReturnStatementNode(
+                    Nodes.getLiteralNode(true)
+                )
+            );
+        }
+
+        const controllerIdentifierName: string = RandomGeneratorUtils.getRandomString(3);
+        const indexIdentifierName: string = RandomGeneratorUtils.getRandomString(3);
+
+        blockStatementNode.body = [
+            Nodes.getVariableDeclarationNode([
+                Nodes.getVariableDeclaratorNode(
+                    Nodes.getIdentifierNode(controllerIdentifierName),
+                    Nodes.getCallExpressionNode(
+                        Nodes.getMemberExpressionNode(
+                            Nodes.getLiteralNode(
+                                originalKeysIndexesInShuffledArray.join('|')
+                            ),
+                            Nodes.getIdentifierNode('split')
+                        ),
+                        [
+                            Nodes.getLiteralNode('|')
+                        ]
+                    )
+                ),
+                Nodes.getVariableDeclaratorNode(
+                    Nodes.getIdentifierNode(indexIdentifierName),
+                    Nodes.getLiteralNode(0)
+                )
+            ]),
+            Nodes.getWhileStatementNode(
+                Nodes.getLiteralNode(true),
+                Nodes.getBlockStatementNode([
+                    Nodes.getSwitchStatementNode(
+                        Nodes.getMemberExpressionNode(
+                            Nodes.getIdentifierNode(controllerIdentifierName),
+                            Nodes.getUpdateExpressionNode(
+                                '++',
+                                Nodes.getIdentifierNode(indexIdentifierName)
+                            ),
+                            true
+                        ),
+                        shuffledKeys.map((key: number, index: number) => {
+                            return Nodes.getSwitchCaseNode(
+                                Nodes.getLiteralNode(String(index)),
+                                [
+                                    blockStatementStatementsAsObject[key],
+                                    Nodes.getContinueStatement()
+                                ]
+                            );
+                        })
+                    ),
+                    Nodes.getBreakStatement()
+                ])
+            )
+        ];
+
+        NodeUtils.parentize(blockStatementNode);
+
+        return blockStatementNode;
+    }
+}

+ 1 - 1
test/dev/dev.ts

@@ -99,7 +99,7 @@ if (!(<any>global)._babelPolyfill) {
             controlFlowFlattening: true,
             controlFlowFlatteningThreshold: 1,
             disableConsoleOutput: false,
-            stringArray: false,
+            stringArray: true,
             unicodeEscapeSequence: false
         }
     ).getObfuscatedCode();

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