Prechádzať zdrojové kódy

control flow flattening wip

sanex3339 8 rokov pred
rodič
commit
2fc6c96165
40 zmenil súbory, kde vykonal 338 pridanie a 817 odobranie
  1. 142 390
      dist/index.js
  2. 36 37
      src/Obfuscator.ts
  3. 1 1
      src/cli/JavaScriptObfuscatorCLI.ts
  4. 0 39
      src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionDivideFunctionNode.ts
  5. 0 39
      src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionExponentiationFunctionNode.ts
  6. 22 6
      src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts
  7. 0 39
      src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSubtractFunctionNode.ts
  8. 0 39
      src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSumFunctionNode.ts
  9. 0 9
      src/interfaces/INodeControlFlowChanger.d.ts
  10. 2 2
      src/interfaces/INodeTransformer.d.ts
  11. 1 1
      src/interfaces/IObfuscatorOptions.d.ts
  12. 1 1
      src/interfaces/IOptions.d.ts
  13. 0 83
      src/node-control-flow-changers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts
  14. 3 3
      src/node-control-flow-transformers/AbstractNodeControlFlowTransformer.ts
  15. 24 15
      src/node-control-flow-transformers/FunctionControlFlowTransformer.ts
  16. 0 0
      src/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts
  17. 47 0
      src/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts
  18. 3 3
      src/node-obfuscators/AbstractNodeObfuscator.ts
  19. 1 1
      src/node-obfuscators/CatchClauseObfuscator.ts
  20. 1 1
      src/node-obfuscators/FunctionDeclarationObfuscator.ts
  21. 1 1
      src/node-obfuscators/FunctionObfuscator.ts
  22. 1 1
      src/node-obfuscators/LabeledStatementObfuscator.ts
  23. 1 1
      src/node-obfuscators/LiteralObfuscator.ts
  24. 1 1
      src/node-obfuscators/MemberExpressionObfuscator.ts
  25. 1 1
      src/node-obfuscators/MethodDefinitionObfuscator.ts
  26. 1 1
      src/node-obfuscators/ObjectExpressionObfuscator.ts
  27. 1 1
      src/node-obfuscators/VariableDeclarationObfuscator.ts
  28. 23 0
      src/node/NodeUtils.ts
  29. 1 1
      src/options/Options.ts
  30. 1 1
      src/preset-options/DefaultPreset.ts
  31. 1 1
      src/preset-options/NoCustomNodesPreset.ts
  32. 0 10
      src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionDivideFunctionTemplate.ts
  33. 0 10
      src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionExponentitionFunctionTemplate.ts
  34. 2 2
      src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate.ts
  35. 0 10
      src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSubtractFunctionTemplate.ts
  36. 0 10
      src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSumFunctionTemplate.ts
  37. 0 5
      src/types/TNodeControlFlowChanger.d.ts
  38. 0 5
      src/types/TNodeObfuscator.d.ts
  39. 5 0
      src/types/TNodeTransformer.d.ts
  40. 14 46
      test/dev/dev.ts

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 142 - 390
dist/index.js


+ 36 - 37
src/Obfuscator.ts

@@ -1,9 +1,8 @@
 import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
-import { TNodeControlFlowChanger } from './types/TNodeControlFlowChanger';
 import { TNodeGroup } from './types/TNodeGroup';
-import { TNodeObfuscator } from './types/TNodeObfuscator';
+import { TNodeTransformer } from './types/TNodeTransformer';
 
 import { ICustomNode } from './interfaces/custom-nodes/ICustomNode';
 import { IObfuscator } from './interfaces/IObfuscator';
@@ -30,15 +29,15 @@ import { SelfDefendingNodesGroup } from './node-groups/SelfDefendingNodesGroup';
 import { StackTraceAnalyzer } from './stack-trace-analyzer/StackTraceAnalyzer';
 import { StringArrayNodesGroup } from './node-groups/StringArrayNodesGroup';
 import { VariableDeclarationObfuscator } from './node-obfuscators/VariableDeclarationObfuscator';
-import { FunctionControlFlowChanger } from './node-control-flow-changers/FunctionControlFlowChanger';
+import { FunctionControlFlowTransformer } from './node-control-flow-transformers/FunctionControlFlowTransformer';
 
 export class Obfuscator implements IObfuscator {
     /**
-     * @type {Map<string, TNodeControlFlowChanger[]>}
+     * @type {Map<string, TNodeTransformer[]>}
      */
-    private static nodeControlFlowChangers: Map <string, TNodeControlFlowChanger[]> = new Map <string, TNodeControlFlowChanger[]> ([
-        [NodeType.FunctionDeclaration, [FunctionControlFlowChanger]],
-        [NodeType.FunctionExpression, [FunctionControlFlowChanger]]
+    private static nodeControlFlowChangers: Map <string, TNodeTransformer[]> = new Map <string, TNodeTransformer[]> ([
+        [NodeType.FunctionDeclaration, [FunctionControlFlowTransformer]],
+        [NodeType.FunctionExpression, [FunctionControlFlowTransformer]]
     ]);
 
     /**
@@ -53,9 +52,9 @@ export class Obfuscator implements IObfuscator {
     ];
 
     /**
-     * @type {Map<string, TNodeObfuscator[]>}
+     * @type {Map<string, TNodeTransformer[]>}
      */
-    private static nodeObfuscators: Map <string, TNodeObfuscator[]> = new Map <string, TNodeObfuscator[]> ([
+    private static nodeObfuscators: Map <string, TNodeTransformer[]> = new Map <string, TNodeTransformer[]> ([
         [NodeType.ArrowFunctionExpression, [FunctionObfuscator]],
         [NodeType.ClassDeclaration, [FunctionDeclarationObfuscator]],
         [NodeType.CatchClause, [CatchClauseObfuscator]],
@@ -104,10 +103,6 @@ export class Obfuscator implements IObfuscator {
 
         this.initializeCustomNodes(stackTraceData);
 
-        if (this.options.controlFlow) {
-            this.changeControlFlow(node);
-        }
-
         this.beforeObfuscation(node);
         this.obfuscate(node);
         this.afterObfuscation(node);
@@ -137,17 +132,6 @@ export class Obfuscator implements IObfuscator {
         });
     };
 
-    /**
-     * @param node
-     */
-    private changeControlFlow (node: ESTree.Node): void {
-        estraverse.traverse(node, {
-            leave: (node: ESTree.Node, parentNode: ESTree.Node): void => {
-                this.initializeNodeControlFlowChangers(node, parentNode);
-            }
-        });
-    }
-
     /**
      * @param stackTraceData
      */
@@ -174,15 +158,7 @@ export class Obfuscator implements IObfuscator {
      * @param parentNode
      */
     private initializeNodeControlFlowChangers (node: ESTree.Node, parentNode: ESTree.Node): void {
-        let nodeControlFlowChangers: TNodeControlFlowChanger[] | undefined = Obfuscator.nodeControlFlowChangers.get(node.type);
-
-        if (!nodeControlFlowChangers) {
-            return;
-        }
-
-        nodeControlFlowChangers.forEach((controlFlowChanger: TNodeControlFlowChanger) => {
-            new controlFlowChanger(this.customNodes, this.options).changeControlFlow(node, parentNode);
-        });
+        this.initializeNodeTransformers(node, parentNode, Obfuscator.nodeControlFlowChangers);
     }
 
     /**
@@ -190,14 +166,27 @@ export class Obfuscator implements IObfuscator {
      * @param parentNode
      */
     private initializeNodeObfuscators (node: ESTree.Node, parentNode: ESTree.Node): void {
-        let nodeObfuscators: TNodeObfuscator[] | undefined = Obfuscator.nodeObfuscators.get(node.type);
+        this.initializeNodeTransformers(node, parentNode, Obfuscator.nodeObfuscators);
+    }
 
-        if (!nodeObfuscators) {
+    /**
+     * @param node
+     * @param parentNode
+     * @param nodeTransformersMap
+     */
+    private initializeNodeTransformers (
+        node: ESTree.Node,
+        parentNode: ESTree.Node,
+        nodeTransformersMap: Map <string, TNodeTransformer[]>
+    ): void {
+        let nodeTransformers: TNodeTransformer[] | undefined = nodeTransformersMap.get(node.type);
+
+        if (!nodeTransformers) {
             return;
         }
 
-        nodeObfuscators.forEach((obfuscator: TNodeObfuscator) => {
-            new obfuscator(this.customNodes, this.options).obfuscateNode(node, parentNode);
+        nodeTransformers.forEach((transformer: TNodeTransformer) => {
+            new transformer(this.customNodes, this.options).transformNode(node, parentNode);
         });
     }
 
@@ -205,6 +194,16 @@ export class Obfuscator implements IObfuscator {
      * @param node
      */
     private obfuscate (node: ESTree.Node): void {
+        // first pass: control flow flattening
+        if (this.options.controlFlowFlattening) {
+            estraverse.traverse(node, {
+                leave: (node: ESTree.Node, parentNode: ESTree.Node): void => {
+                    this.initializeNodeControlFlowChangers(node, parentNode);
+                }
+            });
+        }
+
+        // second pass: nodes obfuscation
         estraverse.traverse(node, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): void => {
                 this.initializeNodeObfuscators(node, parentNode);

+ 1 - 1
src/cli/JavaScriptObfuscatorCLI.ts

@@ -145,7 +145,7 @@ export class JavaScriptObfuscatorCLI {
             .usage('<inputPath> [options]')
             .option('-o, --output <path>', 'Output path for obfuscated code')
             .option('--compact <boolean>', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean)
-            .option('--controlFlow <boolean>', 'Enables control flow change', JavaScriptObfuscatorCLI.parseBoolean)
+            .option('--controlFlowFlattening <boolean>', 'Enables control flow flattening', JavaScriptObfuscatorCLI.parseBoolean)
             .option('--debugProtection <boolean>', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean)
             .option('--debugProtectionInterval <boolean>', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean)
             .option('--disableConsoleOutput <boolean>', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean)

+ 0 - 39
src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionDivideFunctionNode.ts

@@ -1,39 +0,0 @@
-import * as format from 'string-template';
-
-import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
-
-import { AppendState } from '../../../enums/AppendState';
-
-import { NO_CUSTOM_NODES_PRESET } from '../../../preset-options/NoCustomNodesPreset';
-
-import { BinaryExpressionDivideFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionDivideFunctionTemplate';
-
-import { AbstractCustomNode } from '../../AbstractCustomNode';
-import { JavaScriptObfuscator } from '../../../JavaScriptObfuscator';
-import { Utils } from '../../../Utils';
-
-export class BinaryExpressionDivideFunctionNode extends AbstractCustomNode {
-    /**
-     * @type {AppendState}
-     */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
-
-    /**
-     * @param blockScopeNode
-     */
-    public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
-
-    }
-
-    /**
-     * @returns {string}
-     */
-    public getCode (): string {
-        return JavaScriptObfuscator.obfuscate(
-            format(BinaryExpressionDivideFunctionTemplate(), {
-                functionName: Utils.getRandomVariableName()
-            }),
-            NO_CUSTOM_NODES_PRESET
-        ).getObfuscatedCode();
-    }
-}

+ 0 - 39
src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionExponentiationFunctionNode.ts

@@ -1,39 +0,0 @@
-import * as format from 'string-template';
-
-import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
-
-import { AppendState } from '../../../enums/AppendState';
-
-import { NO_CUSTOM_NODES_PRESET } from '../../../preset-options/NoCustomNodesPreset';
-
-import { BinaryExpressionExponentiationFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionExponentitionFunctionTemplate';
-
-import { AbstractCustomNode } from '../../AbstractCustomNode';
-import { JavaScriptObfuscator } from '../../../JavaScriptObfuscator';
-import { Utils } from '../../../Utils';
-
-export class BinaryExpressionExponentiationFunctionNode extends AbstractCustomNode {
-    /**
-     * @type {AppendState}
-     */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
-
-    /**
-     * @param blockScopeNode
-     */
-    public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
-
-    }
-
-    /**
-     * @returns {string}
-     */
-    public getCode (): string {
-        return JavaScriptObfuscator.obfuscate(
-            format(BinaryExpressionExponentiationFunctionTemplate(), {
-                functionName: Utils.getRandomVariableName()
-            }),
-            NO_CUSTOM_NODES_PRESET
-        ).getObfuscatedCode();
-    }
-}

+ 22 - 6
src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionMultiplyFunctionNode.ts → src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts

@@ -2,36 +2,52 @@ import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
 
+import { IOptions } from '../../../interfaces/IOptions';
+
 import { AppendState } from '../../../enums/AppendState';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../../preset-options/NoCustomNodesPreset';
 
-import { BinaryExpressionMultiplyFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionMultiplyFunctionTemplate';
+import { BinaryExpressionFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate';
 
 import { AbstractCustomNode } from '../../AbstractCustomNode';
 import { JavaScriptObfuscator } from '../../../JavaScriptObfuscator';
 import { Utils } from '../../../Utils';
 
-export class BinaryExpressionMultiplyFunctionNode extends AbstractCustomNode {
+export class BinaryExpressionFunctionNode extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */
     protected appendState: AppendState = AppendState.BeforeObfuscation;
 
     /**
-     * @param blockScopeNode
+     * @type {string}
+     */
+    private operator: string;
+
+    /**
+     * @param operator
+     * @param options
      */
-    public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
+    constructor (operator: string, options: IOptions) {
+        super(options);
 
+        this.operator = operator;
     }
 
+    /**
+     * @param blockScopeNode
+     */
+    public appendNode (blockScopeNode: TNodeWithBlockStatement): void {}
+
     /**
      * @returns {string}
      */
     public getCode (): string {
         return JavaScriptObfuscator.obfuscate(
-            format(BinaryExpressionMultiplyFunctionTemplate(), {
-                functionName: Utils.getRandomVariableName()
+            format(BinaryExpressionFunctionTemplate(), {
+                functionName: Utils.getRandomVariableName(),
+                operator: this.operator
             }),
             NO_CUSTOM_NODES_PRESET
         ).getObfuscatedCode();

+ 0 - 39
src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSubtractFunctionNode.ts

@@ -1,39 +0,0 @@
-import * as format from 'string-template';
-
-import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
-
-import { AppendState } from '../../../enums/AppendState';
-
-import { NO_CUSTOM_NODES_PRESET } from '../../../preset-options/NoCustomNodesPreset';
-
-import { BinaryExpressionSubtractFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSubtractFunctionTemplate';
-
-import { AbstractCustomNode } from '../../AbstractCustomNode';
-import { JavaScriptObfuscator } from '../../../JavaScriptObfuscator';
-import { Utils } from '../../../Utils';
-
-export class BinaryExpressionSubtractFunctionNode extends AbstractCustomNode {
-    /**
-     * @type {AppendState}
-     */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
-
-    /**
-     * @param blockScopeNode
-     */
-    public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
-
-    }
-
-    /**
-     * @returns {string}
-     */
-    public getCode (): string {
-        return JavaScriptObfuscator.obfuscate(
-            format(BinaryExpressionSubtractFunctionTemplate(), {
-                functionName: Utils.getRandomVariableName()
-            }),
-            NO_CUSTOM_NODES_PRESET
-        ).getObfuscatedCode();
-    }
-}

+ 0 - 39
src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSumFunctionNode.ts

@@ -1,39 +0,0 @@
-import * as format from 'string-template';
-
-import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
-
-import { AppendState } from '../../../enums/AppendState';
-
-import { NO_CUSTOM_NODES_PRESET } from '../../../preset-options/NoCustomNodesPreset';
-
-import { BinaryExpressionSumFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSumFunctionTemplate';
-
-import { AbstractCustomNode } from '../../AbstractCustomNode';
-import { JavaScriptObfuscator } from '../../../JavaScriptObfuscator';
-import { Utils } from '../../../Utils';
-
-export class BinaryExpressionSumFunctionNode extends AbstractCustomNode {
-    /**
-     * @type {AppendState}
-     */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
-
-    /**
-     * @param blockScopeNode
-     */
-    public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
-
-    }
-
-    /**
-     * @returns {string}
-     */
-    public getCode (): string {
-        return JavaScriptObfuscator.obfuscate(
-            format(BinaryExpressionSumFunctionTemplate(), {
-                functionName: Utils.getRandomVariableName()
-            }),
-            NO_CUSTOM_NODES_PRESET
-        ).getObfuscatedCode();
-    }
-}

+ 0 - 9
src/interfaces/INodeControlFlowChanger.d.ts

@@ -1,9 +0,0 @@
-import * as ESTree from 'estree';
-
-export interface INodeControlFlowChanger {
-    /**
-     * @param node
-     * @param parentNode
-     */
-    changeControlFlow (node: ESTree.Node, parentNode?: ESTree.Node): void;
-}

+ 2 - 2
src/interfaces/INodeObfuscator.d.ts → src/interfaces/INodeTransformer.d.ts

@@ -1,9 +1,9 @@
 import * as ESTree from 'estree';
 
-export interface INodeObfuscator {
+export interface INodeTransformer {
     /**
      * @param node
      * @param parentNode
      */
-    obfuscateNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
+    transformNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
 }

+ 1 - 1
src/interfaces/IObfuscatorOptions.d.ts

@@ -3,7 +3,7 @@ import { TStringArrayEncoding } from '../types/TStringArrayEncoding';
 
 export interface IObfuscatorOptions {
     compact?: boolean;
-    controlFlow?: boolean;
+    controlFlowFlattening?: boolean;
     debugProtection?: boolean;
     debugProtectionInterval?: boolean;
     disableConsoleOutput?: boolean;

+ 1 - 1
src/interfaces/IOptions.d.ts

@@ -3,7 +3,7 @@ import { TStringArrayEncoding } from '../types/TStringArrayEncoding';
 
 export interface IOptions {
     readonly compact: boolean;
-    readonly controlFlow: boolean;
+    readonly controlFlowFlattening: boolean;
     readonly debugProtection: boolean;
     readonly debugProtectionInterval: boolean;
     readonly disableConsoleOutput: boolean;

+ 0 - 83
src/node-control-flow-changers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts

@@ -1,83 +0,0 @@
-import * as escodegen from 'escodegen';
-import * as ESTree from 'estree';
-
-import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
-
-import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
-import { BinaryExpressionSumFunctionNode } from '../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSumFunctionNode';
-import { BinaryExpressionSubtractFunctionNode } from '../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSubtractFunctionNode';
-import { BinaryExpressionMultiplyFunctionNode } from '../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionMultiplyFunctionNode';
-import { BinaryExpressionDivideFunctionNode } from '../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionDivideFunctionNode';
-import { BinaryExpressionExponentiationFunctionNode } from '../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionExponentiationFunctionNode';
-import { ControlFlowStorage } from '../../ControlFlowStorage';
-import { ControlFlowStorageCallNode } from '../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode';
-
-export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
-    /**
-     * @param expressionNode
-     * @returns {string}
-     */
-    private static getExpressionValue (expressionNode: ESTree.Expression): string {
-        return escodegen.generate(expressionNode, {
-            sourceMapWithCode: true
-        }).code;
-    }
-
-    /**
-     * @param binaryExpressionNode
-     * @param parentNode
-     * @param controlFlowStorage
-     * @param controlFlowStorageCustomNodeName
-     * @returns {ICustomNode | undefined}
-     */
-    public replace (
-        binaryExpressionNode: ESTree.BinaryExpression,
-        parentNode: ESTree.Node,
-        controlFlowStorage: ControlFlowStorage,
-        controlFlowStorageCustomNodeName: string
-    ): ICustomNode | undefined {
-        let binaryExpressionFunctionNode: ICustomNode;
-
-        switch (binaryExpressionNode.operator) {
-            case '+':
-                binaryExpressionFunctionNode = new BinaryExpressionSumFunctionNode(this.options);
-
-                break;
-
-            case '-':
-                binaryExpressionFunctionNode = new BinaryExpressionSubtractFunctionNode(this.options);
-
-                break;
-
-            case '*':
-                binaryExpressionFunctionNode = new BinaryExpressionMultiplyFunctionNode(this.options);
-
-                break;
-
-            case '/':
-                binaryExpressionFunctionNode = new BinaryExpressionDivideFunctionNode(this.options);
-
-                break;
-
-            case '**':
-                binaryExpressionFunctionNode = new BinaryExpressionExponentiationFunctionNode(this.options);
-
-                break;
-
-            default:
-                return;
-        }
-
-        const key: string = AbstractControlFlowReplacer.getStorageKey();
-
-        controlFlowStorage.addToStorage(key, binaryExpressionFunctionNode);
-
-        return new ControlFlowStorageCallNode(
-            controlFlowStorageCustomNodeName,
-            key,
-            BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.left),
-            BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.right),
-            this.options
-        );
-    }
-}

+ 3 - 3
src/node-control-flow-changers/AbstractNodeControlFlowChanger.ts → src/node-control-flow-transformers/AbstractNodeControlFlowTransformer.ts

@@ -1,10 +1,10 @@
 import * as ESTree from 'estree';
 
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
-import { INodeControlFlowChanger } from '../interfaces/INodeControlFlowChanger';
+import { INodeTransformer } from '../interfaces/INodeTransformer';
 import { IOptions } from '../interfaces/IOptions';
 
-export abstract class AbstractNodeControlFlowChanger implements INodeControlFlowChanger {
+export abstract class AbstractNodeControlFlowTransformer implements INodeTransformer {
     /**
      * @type Map <string, AbstractCustomNode>
      */
@@ -28,5 +28,5 @@ export abstract class AbstractNodeControlFlowChanger implements INodeControlFlow
      * @param node
      * @param parentNode
      */
-    public abstract changeControlFlow (node: ESTree.Node, parentNode?: ESTree.Node): void;
+    public abstract transformNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
 }

+ 24 - 15
src/node-control-flow-changers/FunctionControlFlowChanger.ts → src/node-control-flow-transformers/FunctionControlFlowTransformer.ts

@@ -2,21 +2,23 @@ import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
 import { TControlFlowReplacer } from '../types/TControlFlowReplacer';
+import { TStatement } from '../types/TStatement';
 
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../interfaces/IOptions';
 
 import { NodeType } from '../enums/NodeType';
 
-import { AbstractNodeControlFlowChanger } from './AbstractNodeControlFlowChanger';
+import { AbstractNodeControlFlowTransformer } from './AbstractNodeControlFlowTransformer';
 import { BinaryExpressionControlFlowReplacer } from './control-flow-replacers/BinaryExpressionControlFlowReplacer';
 import { ControlFlowStorage } from '../ControlFlowStorage';
 import { ControlFlowStorageNode } from '../custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode';
 import { Node } from '../node/Node';
 import { NodeAppender } from '../node/NodeAppender';
 import { Utils } from '../Utils';
+import { NodeUtils } from '../node/NodeUtils';
 
-export class FunctionControlFlowChanger extends AbstractNodeControlFlowChanger {
+export class FunctionControlFlowTransformer extends AbstractNodeControlFlowTransformer {
     /**
      * @type {Map <string, IReplacer>}
      */
@@ -35,7 +37,7 @@ export class FunctionControlFlowChanger extends AbstractNodeControlFlowChanger {
     /**
      * @param functionNode
      */
-    public changeControlFlow (functionNode: ESTree.Function): void {
+    public transformNode (functionNode: ESTree.Function): void {
         this.changeFunctionBodyControlFlow(functionNode);
     }
 
@@ -43,36 +45,43 @@ export class FunctionControlFlowChanger extends AbstractNodeControlFlowChanger {
      * @param functionNode
      */
     private changeFunctionBodyControlFlow (functionNode: ESTree.Function): void {
+        if (Node.isArrowFunctionExpressionNode(functionNode)) {
+            return;
+        }
+
         const controlFlowStorage: ControlFlowStorage = new ControlFlowStorage();
         const controlFlowStorageCustomNodeName: string = Utils.getRandomVariableName(6);
 
-        if (!Node.isFunctionDeclarationNode(functionNode) && !Node.isFunctionExpressionNode(functionNode)) {
-            return;
-        }
+        console.log(NodeUtils.getNodeBlockScopeDepth(functionNode.body));
 
         estraverse.replace(functionNode.body, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
-                const controlFlowReplacerConstructor: TControlFlowReplacer | undefined = FunctionControlFlowChanger.controlFlowReplacers
-                    .get(node.type);
+                const controlFlowReplacer: TControlFlowReplacer | undefined = FunctionControlFlowTransformer
+                    .controlFlowReplacers.get(node.type);
 
-                if (!controlFlowReplacerConstructor) {
+                if (!controlFlowReplacer) {
                     return;
                 }
 
-                const controlFlowStorageCallCustomNode: ICustomNode | undefined = new controlFlowReplacerConstructor(
-                    this.nodes,
-                    this.options
+                const controlFlowStorageCallCustomNode: ICustomNode | undefined = new controlFlowReplacer(
+                    this.nodes, this.options
                 ).replace(node, parentNode, controlFlowStorage, controlFlowStorageCustomNodeName);
 
                 if (!controlFlowStorageCallCustomNode) {
                     return;
                 }
 
-                // controlFlowStorageCallCustomNode will always has only one TStatement node,
+                // controlFlowStorageCallCustomNode will always have only one TStatement node,
                 // so we can get it by index `0`
-                // also we need to `expression` property of `ExpressionStatement` node because bug:
+                // also we need to return `expression` property of `ExpressionStatement` node because bug:
                 // https://github.com/estools/escodegen/issues/289
-                return (<ESTree.ExpressionStatement>controlFlowStorageCallCustomNode.getNode()[0]).expression;
+                const statementNode: TStatement | undefined = controlFlowStorageCallCustomNode.getNode()[0];
+
+                if (!statementNode || !Node.isExpressionStatementNode(statementNode)) {
+                    throw new Error(`\`controlFlowStorageCallCustomNode.getNode()\` should returns array with \`ExpressionStatement\` node`);
+                }
+
+                return statementNode.expression;
             }
         });
 

+ 0 - 0
src/node-control-flow-changers/control-flow-replacers/AbstractControlFlowReplacer.ts → src/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts


+ 47 - 0
src/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts

@@ -0,0 +1,47 @@
+import * as escodegen from 'escodegen';
+import * as ESTree from 'estree';
+
+import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
+
+import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
+import { BinaryExpressionFunctionNode } from '../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode';
+import { ControlFlowStorage } from '../../ControlFlowStorage';
+import { ControlFlowStorageCallNode } from '../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode';
+
+export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
+    /**
+     * @param expressionNode
+     * @returns {string}
+     */
+    private static getExpressionValue (expressionNode: ESTree.Expression): string {
+        return escodegen.generate(expressionNode, {
+            sourceMapWithCode: true
+        }).code;
+    }
+
+    /**
+     * @param binaryExpressionNode
+     * @param parentNode
+     * @param controlFlowStorage
+     * @param controlFlowStorageCustomNodeName
+     * @returns {ICustomNode | undefined}
+     */
+    public replace (
+        binaryExpressionNode: ESTree.BinaryExpression,
+        parentNode: ESTree.Node,
+        controlFlowStorage: ControlFlowStorage,
+        controlFlowStorageCustomNodeName: string
+    ): ICustomNode | undefined {
+        const key: string = AbstractControlFlowReplacer.getStorageKey();
+
+        controlFlowStorage.addToStorage(key, new BinaryExpressionFunctionNode(binaryExpressionNode.operator, this.options));
+
+        return new ControlFlowStorageCallNode(
+            controlFlowStorageCustomNodeName,
+            key,
+            BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.left),
+            BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.right),
+            this.options
+        );
+    }
+}

+ 3 - 3
src/node-obfuscators/AbstractNodeObfuscator.ts

@@ -1,10 +1,10 @@
 import * as ESTree from 'estree';
 
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
-import { INodeObfuscator } from '../interfaces/INodeObfuscator';
+import { INodeTransformer } from '../interfaces/INodeTransformer';
 import { IOptions } from '../interfaces/IOptions';
 
-export abstract class AbstractNodeObfuscator implements INodeObfuscator {
+export abstract class AbstractNodeObfuscator implements INodeTransformer {
     /**
      * @type Map <string, AbstractCustomNode>
      */
@@ -28,5 +28,5 @@ export abstract class AbstractNodeObfuscator implements INodeObfuscator {
      * @param node
      * @param parentNode
      */
-    public abstract obfuscateNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
+    public abstract transformNode (node: ESTree.Node, parentNode?: ESTree.Node): void;
 }

+ 1 - 1
src/node-obfuscators/CatchClauseObfuscator.ts

@@ -38,7 +38,7 @@ export class CatchClauseObfuscator extends AbstractNodeObfuscator {
     /**
      * @param catchClauseNode
      */
-    public obfuscateNode (catchClauseNode: ESTree.CatchClause): void {
+    public transformNode (catchClauseNode: ESTree.CatchClause): void {
         this.storeCatchClauseParam(catchClauseNode);
         this.replaceCatchClauseParam(catchClauseNode);
     }

+ 1 - 1
src/node-obfuscators/FunctionDeclarationObfuscator.ts

@@ -42,7 +42,7 @@ export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator {
      * @param functionDeclarationNode
      * @param parentNode
      */
-    public obfuscateNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): void {
+    public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): void {
         const blockScopeOfFunctionDeclarationNode: TNodeWithBlockStatement = NodeUtils
             .getBlockScopeOfNode(functionDeclarationNode);
 

+ 1 - 1
src/node-obfuscators/FunctionObfuscator.ts

@@ -38,7 +38,7 @@ export class FunctionObfuscator extends AbstractNodeObfuscator {
     /**
      * @param functionNode
      */
-    public obfuscateNode (functionNode: ESTree.Function): void {
+    public transformNode (functionNode: ESTree.Function): void {
         this.storeFunctionParams(functionNode);
         this.replaceFunctionParams(functionNode);
     }

+ 1 - 1
src/node-obfuscators/LabeledStatementObfuscator.ts

@@ -46,7 +46,7 @@ export class LabeledStatementObfuscator extends AbstractNodeObfuscator {
     /**
      * @param labeledStatementNode
      */
-    public obfuscateNode (labeledStatementNode: ESTree.LabeledStatement): void {
+    public transformNode (labeledStatementNode: ESTree.LabeledStatement): void {
         this.storeLabeledStatementName(labeledStatementNode);
         this.replaceLabeledStatementName(labeledStatementNode);
     }

+ 1 - 1
src/node-obfuscators/LiteralObfuscator.ts

@@ -12,7 +12,7 @@ export class LiteralObfuscator extends AbstractNodeObfuscator {
      * @param literalNode
      * @param parentNode
      */
-    public obfuscateNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void {
+    public transformNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void {
         if (Node.isPropertyNode(parentNode) && parentNode.key === literalNode) {
             return;
         }

+ 1 - 1
src/node-obfuscators/MemberExpressionObfuscator.ts

@@ -12,7 +12,7 @@ export class MemberExpressionObfuscator extends AbstractNodeObfuscator {
     /**
      * @param memberExpressionNode
      */
-    public obfuscateNode (memberExpressionNode: ESTree.MemberExpression): void {
+    public transformNode (memberExpressionNode: ESTree.MemberExpression): void {
         estraverse.replace(memberExpressionNode.property, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
                 if (Node.isLiteralNode(node)) {

+ 1 - 1
src/node-obfuscators/MethodDefinitionObfuscator.ts

@@ -23,7 +23,7 @@ export class MethodDefinitionObfuscator extends AbstractNodeObfuscator {
      * @param methodDefinitionNode
      * @param parentNode
      */
-    public obfuscateNode (methodDefinitionNode: ESTree.MethodDefinition, parentNode: ESTree.Node): void {
+    public transformNode (methodDefinitionNode: ESTree.MethodDefinition, parentNode: ESTree.Node): void {
         this.replaceMethodName(methodDefinitionNode);
     }
 

+ 1 - 1
src/node-obfuscators/ObjectExpressionObfuscator.ts

@@ -22,7 +22,7 @@ export class ObjectExpressionObfuscator extends AbstractNodeObfuscator {
     /**
      * @param objectExpressionNode
      */
-    public obfuscateNode (objectExpressionNode: ESTree.ObjectExpression): void {
+    public transformNode (objectExpressionNode: ESTree.ObjectExpression): void {
         objectExpressionNode.properties
             .forEach((property: ESTree.Property) => {
                 if (property.shorthand) {

+ 1 - 1
src/node-obfuscators/VariableDeclarationObfuscator.ts

@@ -43,7 +43,7 @@ export class VariableDeclarationObfuscator extends AbstractNodeObfuscator {
      * @param variableDeclarationNode
      * @param parentNode
      */
-    public obfuscateNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void {
+    public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void {
         const blockScopeOfVariableDeclarationNode: TNodeWithBlockStatement = NodeUtils
             .getBlockScopeOfNode(variableDeclarationNode);
 

+ 23 - 0
src/node/NodeUtils.ts

@@ -100,6 +100,29 @@ export class NodeUtils {
         return NodeUtils.getBlockScopeOfNode(parentNode);
     }
 
+    /**
+     * @param node
+     * @param depth
+     * @returns {number}
+     */
+    public static getNodeBlockScopeDepth (node: ESTree.Node, depth: number = 0): number {
+        let parentNode: ESTree.Node | undefined = node.parentNode;
+
+        if (!parentNode) {
+            throw new ReferenceError('`parentNode` property of given node is `undefined`');
+        }
+
+        if (Node.isProgramNode(parentNode)) {
+            return depth;
+        }
+
+        if (Node.isBlockStatementNode(node)) {
+            return NodeUtils.getNodeBlockScopeDepth(parentNode, ++depth);
+        }
+
+        return NodeUtils.getNodeBlockScopeDepth(parentNode, depth);
+    }
+
     /**
      * @param node
      */

+ 1 - 1
src/options/Options.ts

@@ -45,7 +45,7 @@ export class Options implements IOptions {
      * @type {boolean}
      */
     @IsBoolean()
-    public readonly controlFlow: boolean;
+    public readonly controlFlowFlattening: boolean;
 
     /**
      * @type {boolean}

+ 1 - 1
src/preset-options/DefaultPreset.ts

@@ -4,7 +4,7 @@ import { SourceMapMode } from '../enums/SourceMapMode';
 
 export const DEFAULT_PRESET: IObfuscatorOptions = Object.freeze({
     compact: true,
-    controlFlow: false,
+    controlFlowFlattening: false,
     debugProtection: false,
     debugProtectionInterval: false,
     disableConsoleOutput: true,

+ 1 - 1
src/preset-options/NoCustomNodesPreset.ts

@@ -4,7 +4,7 @@ import { SourceMapMode } from '../enums/SourceMapMode';
 
 export const NO_CUSTOM_NODES_PRESET: IObfuscatorOptions = Object.freeze({
     compact: true,
-    controlFlow: false,
+    controlFlowFlattening: false,
     debugProtection: false,
     debugProtectionInterval: false,
     disableConsoleOutput: false,

+ 0 - 10
src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionDivideFunctionTemplate.ts

@@ -1,10 +0,0 @@
-/**
- * @returns {string}
- */
-export function BinaryExpressionDivideFunctionTemplate (): string {
-    return `
-        function {functionName} (x, y) {
-            return x / y;
-        }
-    `;
-}

+ 0 - 10
src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionExponentitionFunctionTemplate.ts

@@ -1,10 +0,0 @@
-/**
- * @returns {string}
- */
-export function BinaryExpressionExponentiationFunctionTemplate (): string {
-    return `
-        function {functionName} (x, y) {
-            return Math.pow(x, y);
-        }
-    `;
-}

+ 2 - 2
src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionMultiplyFunctionTemplate.ts → src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate.ts

@@ -1,10 +1,10 @@
 /**
  * @returns {string}
  */
-export function BinaryExpressionMultiplyFunctionTemplate (): string {
+export function BinaryExpressionFunctionTemplate (): string {
     return `
         function {functionName} (x, y) {
-            return x * y;
+            return x {operator} y;
         }
     `;
 }

+ 0 - 10
src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSubtractFunctionTemplate.ts

@@ -1,10 +0,0 @@
-/**
- * @returns {string}
- */
-export function BinaryExpressionSubtractFunctionTemplate (): string {
-    return `
-        function {functionName} (x, y) {
-            return x - y;
-        }
-    `;
-}

+ 0 - 10
src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionSumFunctionTemplate.ts

@@ -1,10 +0,0 @@
-/**
- * @returns {string}
- */
-export function BinaryExpressionSumFunctionTemplate (): string {
-    return `
-        function {functionName} (x, y) {
-            return x + y;
-        }
-    `;
-}

+ 0 - 5
src/types/TNodeControlFlowChanger.d.ts

@@ -1,5 +0,0 @@
-import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
-import { INodeControlFlowChanger } from '../interfaces/INodeControlFlowChanger';
-import { IOptions } from '../interfaces/IOptions';
-
-export type TNodeControlFlowChanger = (new (nodes: Map <string, ICustomNode>, options: IOptions) => INodeControlFlowChanger);

+ 0 - 5
src/types/TNodeObfuscator.d.ts

@@ -1,5 +0,0 @@
-import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
-import { INodeObfuscator } from '../interfaces/INodeObfuscator';
-import { IOptions } from '../interfaces/IOptions';
-
-export type TNodeObfuscator = (new (nodes: Map <string, ICustomNode>, options: IOptions) => INodeObfuscator);

+ 5 - 0
src/types/TNodeTransformer.d.ts

@@ -0,0 +1,5 @@
+import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
+import { INodeTransformer } from '../interfaces/INodeTransformer';
+import { IOptions } from '../interfaces/IOptions';
+
+export type TNodeTransformer = (new (nodes: Map <string, ICustomNode>, options: IOptions) => INodeTransformer);

+ 14 - 46
test/dev/dev.ts

@@ -1,4 +1,5 @@
 'use strict';
+import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset';
 
 if (!(<any>global)._babelPolyfill) {
     require('babel-polyfill');
@@ -7,54 +8,21 @@ if (!(<any>global)._babelPolyfill) {
 (function () {
     const JavaScriptObfuscator: any = require("../../index");
 
-    let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
-        `
-    (function(){
-        var result = 1,
-            term1 = 0,
-            term2 = 1,
-            i = 1;
-        while(i < 10)
-        {
-            var test = 10;
-            result = term1 + term2;
-            console.log(result);
-            term1 = term2;
-            term2 = result;
-            i++;
-        }
-
-        console.log(test);
-        
-        var test = function (test) {
-            console.log(test);
-            
-            if (true) {
-                var test = 5
+    let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(`
+        (function(){
+            function t () {
+                return function () {
+                    var t = 1 * 2;
+                }
             }
-        }
-        
-        function t () {
-            return function () {
-                return 100 * 2 - 70;
-            }
-        }
-        
-        var n = 100 + 50;
-        var b = true + true;
-        var s = 'str' + 'ing';
-        var r = /re/ + /g/;
-        
-        console.log(t()());
-        console.log(n);
-    })();
+            
+            var s = 1 - 3;
+        })();
     `,
-        {
-            controlFlow: true,
-            disableConsoleOutput: false,
-            selfDefending: true,
-            stringArrayEncoding: 'rc4'
-        }
+        Object.assign({}, NO_CUSTOM_NODES_PRESET,  {
+            controlFlowFlattening: true,
+            disableConsoleOutput: false
+        })
     ).getObfuscatedCode();
 
     console.log(obfuscatedCode);

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov