Browse Source

Replacers and refactoring

sanex3339 8 years ago
parent
commit
3a2d695175
35 changed files with 643 additions and 449 deletions
  1. 331 209
      dist/index.js
  2. 20 0
      src/Nodes.ts
  3. 1 1
      src/Obfuscator.ts
  4. 1 1
      src/custom-nodes/AbstractCustomNode.ts
  5. 2 2
      src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts
  6. 2 2
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts
  7. 2 2
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts
  8. 2 2
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts
  9. 2 2
      src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts
  10. 2 2
      src/custom-nodes/unicode-array-nodes/UnicodeArrayCallsWrapper.ts
  11. 2 2
      src/custom-nodes/unicode-array-nodes/UnicodeArrayDecodeNode.ts
  12. 2 2
      src/custom-nodes/unicode-array-nodes/UnicodeArrayNode.ts
  13. 2 2
      src/custom-nodes/unicode-array-nodes/UnicodeArrayRotateFunctionNode.ts
  14. 3 0
      src/interfaces/IReplacer.d.ts
  15. 2 2
      src/node-groups/AbstractNodesGroup.ts
  16. 2 2
      src/node-groups/ConsoleOutputNodesGroup.ts
  17. 2 2
      src/node-groups/DebugProtectionNodesGroup.ts
  18. 2 2
      src/node-groups/SelfDefendingNodesGroup.ts
  19. 2 2
      src/node-groups/UnicodeArrayNodesGroup.ts
  20. 61 0
      src/node-obfuscators/AbstractNodeObfuscator.ts
  21. 6 4
      src/node-obfuscators/CatchClauseObfuscator.ts
  22. 6 4
      src/node-obfuscators/FunctionDeclarationObfuscator.ts
  23. 6 4
      src/node-obfuscators/FunctionObfuscator.ts
  24. 12 6
      src/node-obfuscators/LiteralObfuscator.ts
  25. 5 4
      src/node-obfuscators/MemberExpressionObfuscator.ts
  26. 5 3
      src/node-obfuscators/MethodDefinitionObfuscator.ts
  27. 0 174
      src/node-obfuscators/NodeObfuscator.ts
  28. 2 2
      src/node-obfuscators/ObjectExpressionObfuscator.ts
  29. 9 6
      src/node-obfuscators/VariableDeclarationObfuscator.ts
  30. 31 0
      src/node-obfuscators/replacers/AbstractReplacer.ts
  31. 13 0
      src/node-obfuscators/replacers/BooleanLiteralReplacer.ts
  32. 18 0
      src/node-obfuscators/replacers/IdentifierReplacer.ts
  33. 18 0
      src/node-obfuscators/replacers/NumberLiteralReplacer.ts
  34. 64 0
      src/node-obfuscators/replacers/StringLiteralReplacer.ts
  35. 3 3
      test/unit-tests/NodeUtils.spec.ts

File diff suppressed because it is too large
+ 331 - 209
dist/index.js


+ 20 - 0
src/Nodes.ts

@@ -104,6 +104,26 @@ export class Nodes {
         return node.type === NodeType.Property;
     }
 
+    /**
+     * @param node
+     * @param parentNode
+     * @returns {boolean}
+     */
+    public static isReplaceableIdentifierNode (node: INode, parentNode: INode): node is IIdentifierNode {
+        if (!Nodes.isIdentifierNode(node)) {
+            return false;
+        }
+
+        const parentNodeIsPropertyNode: boolean = Nodes.isPropertyNode(parentNode) && parentNode.key === node;
+        const parentNodeIsMemberExpressionNode: boolean = (
+            Nodes.isMemberExpressionNode(parentNode) &&
+            parentNode.computed === false &&
+            parentNode.property === node
+        );
+
+        return !parentNodeIsPropertyNode && !parentNodeIsMemberExpressionNode;
+    }
+
     /**
      *
      * @param node

+ 1 - 1
src/Obfuscator.ts

@@ -27,7 +27,7 @@ import { VariableDeclarationObfuscator } from './node-obfuscators/VariableDeclar
 
 export class Obfuscator implements IObfuscator {
     /**
-     * @type {Map<string, Node>}
+     * @type {Map<string, AbstractCustomNode>}
      */
     private nodes: Map <string, ICustomNode>;
 

+ 1 - 1
src/custom-nodes/Node.ts → src/custom-nodes/AbstractCustomNode.ts

@@ -4,7 +4,7 @@ import { IOptions } from "../interfaces/IOptions";
 
 import { AppendState } from '../enums/AppendState';
 
-export abstract class Node implements ICustomNode {
+export abstract class AbstractCustomNode implements ICustomNode {
     /**
      * @type {AppendState}
      */

+ 2 - 2
src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts

@@ -6,10 +6,10 @@ import { AppendState } from "../../enums/AppendState";
 
 import { ConsoleOutputDisableExpressionTemplate } from "../../templates/custom-nodes/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate";
 
-import { Node } from '../Node';
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from "../../NodeUtils";
 
-export class ConsoleOutputDisableExpressionNode extends Node {
+export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */

+ 2 - 2
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts

@@ -9,10 +9,10 @@ import { AppendState } from "../../enums/AppendState";
 
 import { DebugProtectionFunctionCallTemplate } from "../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate";
 
-import { Node } from '../Node';
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from "../../NodeUtils";
 
-export class DebugProtectionFunctionCallNode extends Node {
+export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */

+ 2 - 2
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts

@@ -9,10 +9,10 @@ import { AppendState } from "../../enums/AppendState";
 
 import { DebugProtectionFunctionIntervalTemplate } from "../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-interval-node/DebugProtectionFunctionIntervalTemplate";
 
-import { Node } from '../Node';
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from '../../NodeUtils';
 
-export class DebugProtectionFunctionIntervalNode extends Node {
+export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */

+ 2 - 2
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts

@@ -9,11 +9,11 @@ import { AppendState } from "../../enums/AppendState";
 
 import { DebugProtectionFunctionTemplate } from "../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate";
 
-import { Node } from '../Node';
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from '../../NodeUtils';
 import { Utils } from "../../Utils";
 
-export class DebugProtectionFunctionNode extends Node {
+export class DebugProtectionFunctionNode extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */

+ 2 - 2
src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts

@@ -8,12 +8,12 @@ import { NO_CUSTOM_NODES_PRESET } from "../../preset-options/NoCustomNodesPreset
 
 import { SelfDefendingTemplate } from "../../templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate";
 
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { JavaScriptObfuscator } from "../../JavaScriptObfuscator";
-import { Node } from '../Node';
 import { NodeUtils } from "../../NodeUtils";
 import { Utils } from "../../Utils";
 
-export class SelfDefendingUnicodeNode extends Node {
+export class SelfDefendingUnicodeNode extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */

+ 2 - 2
src/custom-nodes/unicode-array-nodes/UnicodeArrayCallsWrapper.ts

@@ -9,12 +9,12 @@ import { AppendState } from "../../enums/AppendState";
 
 import { UnicodeArrayCallsWrapperTemplate } from "../../templates/custom-nodes/unicode-array-nodes/unicode-array-calls-wrapper/UnicodeArrayCallsWrapperTemplate";
 
-import { Node } from '../Node';
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from "../../NodeUtils";
 import { UnicodeArray } from "../../UnicodeArray";
 import { Utils } from "../../Utils";
 
-export class UnicodeArrayCallsWrapper extends Node {
+export class UnicodeArrayCallsWrapper extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */

+ 2 - 2
src/custom-nodes/unicode-array-nodes/UnicodeArrayDecodeNode.ts

@@ -13,12 +13,12 @@ import { AtobTemplate } from "../../templates/custom-nodes/AtobTemplate";
 import { SelfDefendingTemplate } from "../../templates/custom-nodes/unicode-array-nodes/unicode-array-decode-node/SelfDefendingTemplate";
 import { UnicodeArrayDecodeTemplate } from "../../templates/custom-nodes/unicode-array-nodes/unicode-array-decode-node/UnicodeArrayDecodeTemplate";
 
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
-import { Node } from '../Node';
 import { NodeUtils } from "../../NodeUtils";
 import { UnicodeArray } from "../../UnicodeArray";
 
-export class UnicodeArrayDecodeNode extends Node {
+export class UnicodeArrayDecodeNode extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */

+ 2 - 2
src/custom-nodes/unicode-array-nodes/UnicodeArrayNode.ts

@@ -11,10 +11,10 @@ import { UnicodeArray } from '../../UnicodeArray';
 
 import { UnicodeArrayTemplate } from "../../templates/custom-nodes/unicode-array-nodes/unicode-array-node/UnicodeArrayTemplate";
 
-import { Node } from '../Node';
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from "../../NodeUtils";
 
-export class UnicodeArrayNode extends Node {
+export class UnicodeArrayNode extends AbstractCustomNode {
     /**
      * @type {number}
      */

+ 2 - 2
src/custom-nodes/unicode-array-nodes/UnicodeArrayRotateFunctionNode.ts

@@ -12,13 +12,13 @@ import { NO_CUSTOM_NODES_PRESET } from "../../preset-options/NoCustomNodesPreset
 import { SelfDefendingTemplate } from "../../templates/custom-nodes/unicode-array-nodes/unicode-array-rotate-function-node/SelfDefendingTemplate";
 import { UnicodeArrayRotateFunctionTemplate } from "../../templates/custom-nodes/unicode-array-nodes/unicode-array-rotate-function-node/UnicodeArrayRotateFunctionTemplate";
 
+import { AbstractCustomNode } from '../AbstractCustomNode';
 import { JavaScriptObfuscator } from "../../JavaScriptObfuscator";
-import { Node } from '../Node';
 import { NodeUtils } from "../../NodeUtils";
 import { UnicodeArray } from "../../UnicodeArray";
 import { Utils } from "../../Utils";
 
-export class UnicodeArrayRotateFunctionNode extends Node {
+export class UnicodeArrayRotateFunctionNode extends AbstractCustomNode {
     /**
      * @type {AppendState}
      */

+ 3 - 0
src/interfaces/IReplacer.d.ts

@@ -0,0 +1,3 @@
+export interface IReplacer {
+    replace (nodeValue: any, namesMap?: Map <string, string>): string;
+}

+ 2 - 2
src/node-groups/NodesGroup.ts → src/node-groups/AbstractNodesGroup.ts

@@ -3,9 +3,9 @@ import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 import { INodesGroup } from '../interfaces/INodesGroup';
 import { IOptions } from "../interfaces/IOptions";
 
-export abstract class NodesGroup implements INodesGroup {
+export abstract class AbstractNodesGroup implements INodesGroup {
     /**
-     * @type {Map<string, Node>}
+     * @type {Map<string, AbstractCustomNode>}
      */
     protected nodes: Map <string, ICustomNode> = new Map <string, ICustomNode> ();
 

+ 2 - 2
src/node-groups/ConsoleOutputNodesGroup.ts

@@ -1,9 +1,9 @@
 import { IOptions } from "../interfaces/IOptions";
 
+import { AbstractNodesGroup } from './AbstractNodesGroup';
 import { ConsoleOutputDisableExpressionNode } from "../custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode";
-import { NodesGroup } from './NodesGroup';
 
-export class ConsoleOutputNodesGroup extends NodesGroup {
+export class ConsoleOutputNodesGroup extends AbstractNodesGroup {
     /**
      * @param options
      */

+ 2 - 2
src/node-groups/DebugProtectionNodesGroup.ts

@@ -4,10 +4,10 @@ import { DebugProtectionFunctionCallNode } from "../custom-nodes/debug-protectio
 import { DebugProtectionFunctionIntervalNode } from "../custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode";
 import { DebugProtectionFunctionNode } from "../custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode";
 
-import { NodesGroup } from './NodesGroup';
+import { AbstractNodesGroup } from './AbstractNodesGroup';
 import { Utils } from '../Utils';
 
-export class DebugProtectionNodesGroup extends NodesGroup {
+export class DebugProtectionNodesGroup extends AbstractNodesGroup {
     /**
      * @type {string}
      */

+ 2 - 2
src/node-groups/SelfDefendingNodesGroup.ts

@@ -1,9 +1,9 @@
 import { IOptions } from "../interfaces/IOptions";
 
-import { NodesGroup } from './NodesGroup';
+import { AbstractNodesGroup } from './AbstractNodesGroup';
 import { SelfDefendingUnicodeNode } from "../custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode";
 
-export class SelfDefendingNodesGroup extends NodesGroup {
+export class SelfDefendingNodesGroup extends AbstractNodesGroup {
     /**
      * @param options
      */

+ 2 - 2
src/node-groups/UnicodeArrayNodesGroup.ts

@@ -1,6 +1,6 @@
 import { IOptions } from "../interfaces/IOptions";
 
-import { NodesGroup } from './NodesGroup';
+import { AbstractNodesGroup } from './AbstractNodesGroup';
 import { UnicodeArray } from "../UnicodeArray";
 import { UnicodeArrayCallsWrapper } from "../custom-nodes/unicode-array-nodes/UnicodeArrayCallsWrapper";
 import { UnicodeArrayDecodeNode } from "../custom-nodes/unicode-array-nodes/UnicodeArrayDecodeNode";
@@ -8,7 +8,7 @@ import { UnicodeArrayNode } from '../custom-nodes/unicode-array-nodes/UnicodeArr
 import { UnicodeArrayRotateFunctionNode } from '../custom-nodes/unicode-array-nodes/UnicodeArrayRotateFunctionNode';
 import { Utils } from '../Utils';
 
-export class UnicodeArrayNodesGroup extends NodesGroup {
+export class UnicodeArrayNodesGroup extends AbstractNodesGroup {
     /**
      * @type {string}
      */

+ 61 - 0
src/node-obfuscators/AbstractNodeObfuscator.ts

@@ -0,0 +1,61 @@
+import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
+import { INodeObfuscator } from '../interfaces/INodeObfuscator';
+import { INode } from "../interfaces/nodes/INode";
+import { IOptions } from "../interfaces/IOptions";
+
+import { Nodes } from "../Nodes";
+import { Utils } from '../Utils';
+
+export abstract class AbstractNodeObfuscator implements INodeObfuscator {
+    /**
+     * @type Map <string, AbstractCustomNode>
+     */
+    protected nodes: Map <string, ICustomNode>;
+
+    /**
+     * @type {IOptions}
+     */
+    protected options: IOptions;
+
+    /**
+     * @param nodes
+     * @param options
+     */
+    constructor(nodes: Map <string, ICustomNode>, options: IOptions) {
+        this.nodes = nodes;
+        this.options = options;
+    }
+
+    /**
+     * @param node
+     * @param parentNode
+     */
+    public abstract obfuscateNode (node: INode, parentNode?: INode): void;
+
+    /**
+     * @param name
+     * @returns {boolean}
+     */
+    protected isReservedName (name: string): boolean {
+        return this.options.reservedNames
+            .some((reservedName: string) => {
+                return new RegExp(reservedName, 'g').test(name);
+            });
+    }
+
+    /**
+     * Store all identifiers names as keys in given `namesMap` with random names as value.
+     * Reserved names will be ignored.
+     *
+     * @param node
+     * @param namesMap
+     */
+    protected storeIdentifiersNames (
+        node: INode,
+        namesMap: Map <string, string>
+    ): void {
+        if (Nodes.isIdentifierNode(node) && !this.isReservedName(node.name)) {
+            namesMap.set(node.name, Utils.getRandomVariableName());
+        }
+    }
+}

+ 6 - 4
src/node-obfuscators/CatchClauseObfuscator.ts

@@ -3,7 +3,8 @@ import * as estraverse from 'estraverse';
 import { ICatchClauseNode } from "../interfaces/nodes/ICatchClauseNode";
 import { INode } from '../interfaces/nodes/INode';
 
-import { NodeObfuscator } from './NodeObfuscator';
+import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
+import { IdentifierReplacer } from "./replacers/IdentifierReplacer";
 import { Nodes } from "../Nodes";
 
 /**
@@ -14,7 +15,7 @@ import { Nodes } from "../Nodes";
  *     try {} catch (_0x12d45f) { console.log(_0x12d45f); };
  *
  */
-export class CatchClauseObfuscator extends NodeObfuscator {
+export class CatchClauseObfuscator extends AbstractNodeObfuscator {
     /**
      * @type {Map<string, string>}
      */
@@ -43,8 +44,9 @@ export class CatchClauseObfuscator extends NodeObfuscator {
     private replaceCatchClauseParam (catchClauseNode: ICatchClauseNode): void {
         estraverse.replace(catchClauseNode, {
             leave: (node: INode, parentNode: INode): any => {
-                if (Nodes.isIdentifierNode(node)) {
-                    node.name = this.replaceIdentifiersWithRandomNames(node, parentNode, this.catchClauseParam);
+                if (Nodes.isReplaceableIdentifierNode(node, parentNode)) {
+                    node.name = new IdentifierReplacer(this.nodes, this.options)
+                        .replace(node.name, this.catchClauseParam);
                 }
             }
         });

+ 6 - 4
src/node-obfuscators/FunctionDeclarationObfuscator.ts

@@ -5,7 +5,8 @@ import { INode } from "../interfaces/nodes/INode";
 
 import { NodeType } from "../enums/NodeType";
 
-import { NodeObfuscator } from './NodeObfuscator';
+import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
+import { IdentifierReplacer } from "./replacers/IdentifierReplacer";
 import { Nodes } from "../Nodes";
 import { NodeUtils } from "../NodeUtils";
 
@@ -18,7 +19,7 @@ import { NodeUtils } from "../NodeUtils";
  *     function _0x12d45f () { //... };
  *     _0x12d45f();
  */
-export class FunctionDeclarationObfuscator extends NodeObfuscator {
+export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator {
     /**
      * @type {Map<string, string>}
      */
@@ -56,8 +57,9 @@ export class FunctionDeclarationObfuscator extends NodeObfuscator {
 
         estraverse.replace(scopeNode, {
             enter: (node: INode, parentNode: INode): any => {
-                if (Nodes.isIdentifierNode(node)) {
-                    node.name = this.replaceIdentifiersWithRandomNames(node, parentNode, this.functionName);
+                if (Nodes.isReplaceableIdentifierNode(node, parentNode)) {
+                    node.name = new IdentifierReplacer(this.nodes, this.options)
+                        .replace(node.name, this.functionName);
                 }
             }
         });

+ 6 - 4
src/node-obfuscators/FunctionObfuscator.ts

@@ -3,7 +3,8 @@ import * as estraverse from 'estraverse';
 import { IFunctionNode } from "../interfaces/nodes/IFunctionNode";
 import { INode } from "../interfaces/nodes/INode";
 
-import { NodeObfuscator } from './NodeObfuscator';
+import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
+import { IdentifierReplacer } from "./replacers/IdentifierReplacer";
 import { Nodes } from "../Nodes";
 
 /**
@@ -14,7 +15,7 @@ import { Nodes } from "../Nodes";
  *     function foo (_0x12d45f) { return _0x12d45f; };
  *
  */
-export class FunctionObfuscator extends NodeObfuscator {
+export class FunctionObfuscator extends AbstractNodeObfuscator {
     /**
      * @type {Map<string, string>}
      */
@@ -46,8 +47,9 @@ export class FunctionObfuscator extends NodeObfuscator {
     private replaceFunctionParams (functionNode: IFunctionNode): void {
         let replaceVisitor: estraverse.Visitor = {
             leave: (node: INode, parentNode: INode): any => {
-                if (Nodes.isIdentifierNode(node)) {
-                    node.name = this.replaceIdentifiersWithRandomNames(node, parentNode, this.functionParams);
+                if (Nodes.isReplaceableIdentifierNode(node, parentNode)) {
+                    node.name = new IdentifierReplacer(this.nodes, this.options)
+                        .replace(node.name, this.functionParams);
                 }
             }
         };

+ 12 - 6
src/node-obfuscators/LiteralObfuscator.ts

@@ -1,12 +1,15 @@
 import * as escodegen from 'escodegen';
 
 import { ILiteralNode } from "../interfaces/nodes/ILiteralNode";
-
 import { INode } from "../interfaces/nodes/INode";
-import { NodeObfuscator } from './NodeObfuscator';
+
+import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
+import { BooleanLiteralReplacer } from "./replacers/BooleanLiteralReplacer";
 import { Nodes } from "../Nodes";
+import { NumberLiteralReplacer } from "./replacers/NumberLiteralReplacer";
+import { StringLiteralReplacer } from "./replacers/StringLiteralReplacer";
 
-export class LiteralObfuscator extends NodeObfuscator {
+export class LiteralObfuscator extends AbstractNodeObfuscator {
     /**
      * @param literalNode
      * @param parentNode
@@ -24,18 +27,21 @@ export class LiteralObfuscator extends NodeObfuscator {
 
         switch (typeof literalNode.value) {
             case 'boolean':
-                content = this.replaceLiteralBooleanWithJSFuck(<boolean>literalNode.value);
+                content = new BooleanLiteralReplacer(this.nodes, this.options)
+                    .replace(<boolean>literalNode.value);
 
                 break;
 
             case 'number':
-                content = this.replaceLiteralNumberWithHexadecimalValue(<number>literalNode.value);
+                content = new NumberLiteralReplacer(this.nodes, this.options)
+                    .replace(<number>literalNode.value);
 
                 break;
 
 
             case 'string':
-                content = this.replaceLiteralValueWithUnicodeValue(<string>literalNode.value);
+                content = new StringLiteralReplacer(this.nodes, this.options)
+                        .replace(<string>literalNode.value);
 
                 break;
 

+ 5 - 4
src/node-obfuscators/MemberExpressionObfuscator.ts

@@ -8,10 +8,11 @@ import { INode } from "../interfaces/nodes/INode";
 
 import { NodeType } from "../enums/NodeType";
 
-import { NodeObfuscator } from './NodeObfuscator';
+import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
 import { Nodes } from "../Nodes";
+import { StringLiteralReplacer } from "./replacers/StringLiteralReplacer";
 
-export class MemberExpressionObfuscator extends NodeObfuscator {
+export class MemberExpressionObfuscator extends AbstractNodeObfuscator {
     /**
      * @param memberExpressionNode
      */
@@ -53,7 +54,7 @@ export class MemberExpressionObfuscator extends NodeObfuscator {
             literalNode: ILiteralNode = {
                 raw: `'${nodeValue}'`,
                 'x-verbatim-property': {
-                    content : this.replaceLiteralValueWithUnicodeValue(nodeValue),
+                    content : new StringLiteralReplacer(this.nodes, this.options).replace(nodeValue),
                     precedence: escodegen.Precedence.Primary
                 },
                 type: NodeType.Literal,
@@ -77,7 +78,7 @@ export class MemberExpressionObfuscator extends NodeObfuscator {
     private obfuscateLiteralProperty (node: ILiteralNode): void {
         if (typeof node.value === 'string' && !node['x-verbatim-property']) {
             node['x-verbatim-property'] = {
-                content : this.replaceLiteralValueWithUnicodeValue(node.value),
+                content : new StringLiteralReplacer(this.nodes, this.options).replace(node.value),
                 precedence: escodegen.Precedence.Primary
             };
         }

+ 5 - 3
src/node-obfuscators/MethodDefinitionObfuscator.ts

@@ -3,9 +3,10 @@ import * as estraverse from 'estraverse';
 import { IMethodDefinitionNode } from "../interfaces/nodes/IMethodDefinitionNode";
 import { INode } from "../interfaces/nodes/INode";
 
-import { NodeObfuscator } from './NodeObfuscator';
+import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
 import { Nodes } from "../Nodes";
 import { Utils } from "../Utils";
+import { StringLiteralReplacer } from "./replacers/StringLiteralReplacer";
 
 /**
  * replaces:
@@ -14,7 +15,7 @@ import { Utils } from "../Utils";
  * on:
  *     [_0x9a4e('0x0')] { //... };
  */
-export class MethodDefinitionObfuscator extends NodeObfuscator {
+export class MethodDefinitionObfuscator extends AbstractNodeObfuscator {
     /**
      * @type {string[]}
      */
@@ -40,7 +41,8 @@ export class MethodDefinitionObfuscator extends NodeObfuscator {
                     methodDefinitionNode.computed === false
                 ) {
                     methodDefinitionNode.computed = true;
-                    node.name = this.replaceLiteralValueWithUnicodeValue(node.name);
+                    node.name = new StringLiteralReplacer(this.nodes, this.options)
+                        .replace(node.name);
 
                     return;
                 }

+ 0 - 174
src/node-obfuscators/NodeObfuscator.ts

@@ -1,174 +0,0 @@
-import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
-import { IIdentifierNode } from "../interfaces/nodes/IIdentifierNode";
-import { INodeObfuscator } from '../interfaces/INodeObfuscator';
-import { INode } from "../interfaces/nodes/INode";
-import { IOptions } from "../interfaces/IOptions";
-
-import { TUnicodeArrayCallsWrapper } from "../types/custom-nodes/TUnicodeArrayCallsWrapper";
-import { TUnicodeArrayNode } from "../types/custom-nodes/TUnicodeArrayNode";
-
-import { JSFuck } from "../enums/JSFuck";
-
-import { Nodes } from "../Nodes";
-import { UnicodeArray } from "../UnicodeArray";
-import { Utils } from '../Utils';
-
-export abstract class NodeObfuscator implements INodeObfuscator {
-    /**
-     * @type Map <string, Node>
-     */
-    protected nodes: Map <string, ICustomNode>;
-
-    /**
-     * @type {IOptions}
-     */
-    protected options: IOptions;
-
-    /**
-     * @param nodes
-     * @param options
-     */
-    constructor(nodes: Map <string, ICustomNode>, options: IOptions) {
-        this.nodes = nodes;
-        this.options = options;
-    }
-
-    /**
-     * @param node
-     * @param parentNode
-     */
-    public abstract obfuscateNode (node: INode, parentNode?: INode): void;
-
-    /**
-     * @param name
-     * @returns {boolean}
-     */
-    protected isReservedName (name: string): boolean {
-        return this.options.reservedNames
-            .some((reservedName: string) => {
-                return new RegExp(reservedName, 'g').test(name);
-            });
-    }
-
-    /**
-     * Store all identifiers names as keys in given `namesMap` with random names as value.
-     * Reserved names will be ignored.
-     *
-     * @param node
-     * @param namesMap
-     */
-    protected storeIdentifiersNames (
-        node: INode,
-        namesMap: Map <string, string>
-    ): void {
-        if (Nodes.isIdentifierNode(node) && !this.isReservedName(node.name)) {
-            namesMap.set(node.name, Utils.getRandomVariableName());
-        }
-    }
-
-    /**
-     * @param node
-     * @param parentNode
-     * @param namesMap
-     * @returns {string}
-     */
-    protected replaceIdentifiersWithRandomNames (
-        node: IIdentifierNode,
-        parentNode: INode,
-        namesMap: Map <string, string>
-    ): string {
-        const obfuscatedIdentifierName: string|undefined = namesMap.get(node.name);
-        const parentNodeIsPropertyNode: boolean = Nodes.isPropertyNode(parentNode) && parentNode.key === node;
-        const parentNodeIsMemberExpressionNode: boolean = (
-            Nodes.isMemberExpressionNode(parentNode) &&
-            parentNode.computed === false &&
-            parentNode.property === node
-        );
-
-        if (parentNodeIsPropertyNode || parentNodeIsMemberExpressionNode || !obfuscatedIdentifierName) {
-            return node.name;
-        }
-
-        return obfuscatedIdentifierName;
-    }
-
-    /**
-     * @param nodeValue
-     * @returns {string}
-     */
-    protected replaceLiteralBooleanWithJSFuck (nodeValue: boolean): string {
-        return nodeValue ? JSFuck.True : JSFuck.False;
-    }
-
-    /**
-     * @param nodeValue
-     * @returns {string}
-     */
-    protected replaceLiteralNumberWithHexadecimalValue (nodeValue: number): string {
-        const prefix: string = '0x';
-
-        if (!Utils.isInteger(nodeValue)) {
-            return String(nodeValue);
-        }
-
-        return `${prefix}${Utils.decToHex(nodeValue)}`;
-    }
-
-    /**
-     * @param nodeValue
-     * @returns {string}
-     */
-    protected replaceLiteralValueWithUnicodeValue (nodeValue: string): string {
-        const replaceWithUnicodeArrayFlag: boolean = Math.random() <= this.options.unicodeArrayThreshold;
-
-        if (this.options.encodeUnicodeLiterals && replaceWithUnicodeArrayFlag) {
-            nodeValue = Utils.btoa(nodeValue);
-        }
-
-        nodeValue = Utils.stringToUnicode(nodeValue);
-
-        if (this.options.unicodeArray && replaceWithUnicodeArrayFlag) {
-            return this.replaceLiteralValueWithUnicodeArrayCall(nodeValue);
-        }
-
-        return nodeValue;
-    }
-
-    /**
-     * @param value
-     * @returns {string}
-     */
-    protected replaceLiteralValueWithUnicodeArrayCall (value: string): string {
-        const unicodeArrayNode: TUnicodeArrayNode = <TUnicodeArrayNode>this.nodes.get('unicodeArrayNode');
-
-        if (!unicodeArrayNode) {
-            throw new ReferenceError('`unicodeArrayNode` node is not found in Map with custom nodes.');
-        }
-
-        let unicodeArray: UnicodeArray = unicodeArrayNode.getNodeData(),
-            indexOfExistingValue: number = unicodeArray.getIndexOf(value),
-            indexOfValue: number,
-            hexadecimalIndex: string;
-
-        if (indexOfExistingValue >= 0) {
-            indexOfValue = indexOfExistingValue;
-        } else {
-            indexOfValue = unicodeArray.getLength();
-            unicodeArrayNode.updateNodeData(value);
-        }
-
-        hexadecimalIndex = this.replaceLiteralNumberWithHexadecimalValue(indexOfValue);
-
-        if (this.options.wrapUnicodeArrayCalls) {
-            const unicodeArrayCallsWrapper: TUnicodeArrayCallsWrapper = <TUnicodeArrayCallsWrapper>this.nodes.get('unicodeArrayCallsWrapper');
-
-            if (!unicodeArrayCallsWrapper) {
-                throw new ReferenceError('`unicodeArrayCallsWrapper` node is not found in Map with custom nodes.');
-            }
-
-            return `${unicodeArrayCallsWrapper.getNodeIdentifier()}('${hexadecimalIndex}')`;
-        }
-
-        return `${unicodeArrayNode.getNodeIdentifier()}[${hexadecimalIndex}]`;
-    }
-}

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

@@ -9,7 +9,7 @@ import { INode } from "../interfaces/nodes/INode";
 
 import { NodeType } from "../enums/NodeType";
 
-import { NodeObfuscator } from './NodeObfuscator';
+import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
 import { Nodes } from "../Nodes";
 import { Utils } from '../Utils';
 
@@ -23,7 +23,7 @@ import { Utils } from '../Utils';
  * on:
  *     var object = { '\u0050\u0053\u0045\u0055\u0044\u004f': 1 };
  */
-export class ObjectExpressionObfuscator extends NodeObfuscator {
+export class ObjectExpressionObfuscator extends AbstractNodeObfuscator {
     /**
      * @param objectExpressionNode
      */

+ 9 - 6
src/node-obfuscators/VariableDeclarationObfuscator.ts

@@ -6,7 +6,8 @@ import { IVariableDeclaratorNode } from "../interfaces/nodes/IVariableDeclarator
 
 import { NodeType } from "../enums/NodeType";
 
-import { NodeObfuscator } from './NodeObfuscator';
+import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
+import { IdentifierReplacer } from "./replacers/IdentifierReplacer";
 import { Nodes } from "../Nodes";
 import { NodeUtils } from "../NodeUtils";
 
@@ -20,7 +21,7 @@ import { NodeUtils } from "../NodeUtils";
  *     _0x12d45f++;
  *
  */
-export class VariableDeclarationObfuscator extends NodeObfuscator {
+export class VariableDeclarationObfuscator extends AbstractNodeObfuscator {
     /**
      * @type {Map<string, string>}
      */
@@ -70,8 +71,9 @@ export class VariableDeclarationObfuscator extends NodeObfuscator {
                 ) {
                     estraverse.replace(node, {
                         enter: (node: INode, parentNode: INode): any => {
-                            if (Nodes.isIdentifierNode(node)) {
-                                node.name = this.replaceIdentifiersWithRandomNames(node, parentNode, this.variableNames);
+                            if (Nodes.isReplaceableIdentifierNode(node, parentNode)) {
+                                node.name = new IdentifierReplacer(this.nodes, this.options)
+                                    .replace(node.name, this.variableNames);
                             }
                         }
                     });
@@ -81,8 +83,9 @@ export class VariableDeclarationObfuscator extends NodeObfuscator {
                     isNodeAfterVariableDeclaratorFlag = true;
                 }
 
-                if (Nodes.isIdentifierNode(node) && isNodeAfterVariableDeclaratorFlag) {
-                    node.name = this.replaceIdentifiersWithRandomNames(node, parentNode, this.variableNames);
+                if (Nodes.isReplaceableIdentifierNode(node, parentNode) && isNodeAfterVariableDeclaratorFlag) {
+                    node.name = new IdentifierReplacer(this.nodes, this.options)
+                        .replace(node.name, this.variableNames);
                 }
             }
         });

+ 31 - 0
src/node-obfuscators/replacers/AbstractReplacer.ts

@@ -0,0 +1,31 @@
+import { ICustomNode } from "../../interfaces/custom-nodes/ICustomNode";
+import { IOptions } from "../../interfaces/IOptions";
+import { IReplacer } from "../../interfaces/IReplacer";
+
+export abstract class AbstractReplacer implements IReplacer {
+    /**
+     * @type Map <string, AbstractCustomNode>
+     */
+    protected nodes: Map <string, ICustomNode>;
+
+    /**
+     * @type {IOptions}
+     */
+    protected options : IOptions;
+
+    /**
+     * @param nodes
+     * @param options
+     */
+    constructor (nodes: Map <string, ICustomNode>, options: IOptions) {
+        this.nodes = nodes;
+        this.options = options;
+    }
+
+    /**
+     * @param nodeValue
+     * @param namesMap
+     * @returns {string}
+     */
+    public abstract replace (nodeValue: any, namesMap?: Map <string, string>): string;
+}

+ 13 - 0
src/node-obfuscators/replacers/BooleanLiteralReplacer.ts

@@ -0,0 +1,13 @@
+import { JSFuck } from "../../enums/JSFuck";
+
+import { AbstractReplacer } from "./AbstractReplacer";
+
+export class BooleanLiteralReplacer extends AbstractReplacer {
+    /**
+     * @param nodeValue
+     * @returns {string}
+     */
+    public replace (nodeValue: boolean): string {
+        return nodeValue ? JSFuck.True : JSFuck.False;
+    }
+}

+ 18 - 0
src/node-obfuscators/replacers/IdentifierReplacer.ts

@@ -0,0 +1,18 @@
+import { AbstractReplacer } from "./AbstractReplacer";
+
+export class IdentifierReplacer extends AbstractReplacer {
+    /**
+     * @param nodeValue
+     * @param namesMap
+     * @returns {string}
+     */
+    public replace (nodeValue: string, namesMap: Map <string, string>): string {
+        const obfuscatedIdentifierName: string|undefined = namesMap.get(nodeValue);
+
+        if (!obfuscatedIdentifierName) {
+            return nodeValue;
+        }
+
+        return obfuscatedIdentifierName;
+    }
+}

+ 18 - 0
src/node-obfuscators/replacers/NumberLiteralReplacer.ts

@@ -0,0 +1,18 @@
+import { AbstractReplacer } from "./AbstractReplacer";
+import { Utils } from "../../Utils";
+
+export class NumberLiteralReplacer extends AbstractReplacer {
+    /**
+     * @param nodeValue
+     * @returns {string}
+     */
+    public replace (nodeValue: number): string {
+        const prefix: string = '0x';
+
+        if (!Utils.isInteger(nodeValue)) {
+            return String(nodeValue);
+        }
+
+        return `${prefix}${Utils.decToHex(nodeValue)}`;
+    }
+}

+ 64 - 0
src/node-obfuscators/replacers/StringLiteralReplacer.ts

@@ -0,0 +1,64 @@
+import { TUnicodeArrayCallsWrapper } from "../../types/custom-nodes/TUnicodeArrayCallsWrapper";
+import { TUnicodeArrayNode } from "../../types/custom-nodes/TUnicodeArrayNode";
+
+import { AbstractReplacer } from "./AbstractReplacer";
+import { NumberLiteralReplacer } from "./NumberLiteralReplacer";
+import { UnicodeArray } from "../../UnicodeArray";
+import { Utils } from "../../Utils";
+
+export class StringLiteralReplacer extends AbstractReplacer {
+    /**
+     * @param nodeValue
+     * @returns {string}
+     */
+    public replace (nodeValue: string): string {
+        const replaceWithUnicodeArrayFlag: boolean = Math.random() <= this.options.unicodeArrayThreshold;
+
+        if (this.options.encodeUnicodeLiterals && replaceWithUnicodeArrayFlag) {
+            nodeValue = Utils.btoa(nodeValue);
+        }
+
+        nodeValue = Utils.stringToUnicode(nodeValue);
+
+        if (this.options.unicodeArray && replaceWithUnicodeArrayFlag) {
+            return this.replaceStringLiteralWithUnicodeArrayCall(nodeValue);
+        }
+
+        return nodeValue;
+    }
+
+    private replaceStringLiteralWithUnicodeArrayCall (value: string): string {
+        const unicodeArrayNode: TUnicodeArrayNode = <TUnicodeArrayNode>this.nodes.get('unicodeArrayNode');
+
+        if (!unicodeArrayNode) {
+            throw new ReferenceError('`unicodeArrayNode` node is not found in Map with custom nodes.');
+        }
+
+        let unicodeArray: UnicodeArray = unicodeArrayNode.getNodeData(),
+            indexOfExistingValue: number = unicodeArray.getIndexOf(value),
+            indexOfValue: number,
+            hexadecimalIndex: string;
+
+        if (indexOfExistingValue >= 0) {
+            indexOfValue = indexOfExistingValue;
+        } else {
+            indexOfValue = unicodeArray.getLength();
+            unicodeArrayNode.updateNodeData(value);
+        }
+
+        hexadecimalIndex = new NumberLiteralReplacer(this.nodes, this.options)
+            .replace(indexOfValue);
+
+        if (this.options.wrapUnicodeArrayCalls) {
+            const unicodeArrayCallsWrapper: TUnicodeArrayCallsWrapper = <TUnicodeArrayCallsWrapper>this.nodes.get('unicodeArrayCallsWrapper');
+
+            if (!unicodeArrayCallsWrapper) {
+                throw new ReferenceError('`unicodeArrayCallsWrapper` node is not found in Map with custom nodes.');
+            }
+
+            return `${unicodeArrayCallsWrapper.getNodeIdentifier()}('${hexadecimalIndex}')`;
+        }
+
+        return `${unicodeArrayNode.getNodeIdentifier()}[${hexadecimalIndex}]`;
+    }
+}

+ 3 - 3
test/unit-tests/NodeUtils.spec.ts

@@ -58,7 +58,7 @@ describe('NodeUtils', () => {
             assert.deepEqual(blockStatementNode, expectedBlockStatementNode);
         });
 
-        it('should does not change `BlockStatement` node body if given node is not a valid Node', () => {
+        it('should does not change `BlockStatement` node body if given node is not a valid AbstractCustomNode', () => {
             assert.doesNotChange(
                 () => NodeUtils.appendNode(blockStatementNode.body, <INode>{}),
                 blockStatementNode,
@@ -227,7 +227,7 @@ describe('NodeUtils', () => {
             assert.deepEqual(blockStatementNode, expectedBlockStatementNode);
         });
 
-        it('should does not change `BlockStatement` node body if given node is not a valid Node', () => {
+        it('should does not change `BlockStatement` node body if given node is not a valid AbstractCustomNode', () => {
             assert.doesNotChange(
                 () => NodeUtils.insertNodeAtIndex(blockStatementNode.body, <INode>{}, 1),
                 blockStatementNode,
@@ -310,7 +310,7 @@ describe('NodeUtils', () => {
             assert.deepEqual(blockStatementNode, expectedBlockStatementNode);
         });
 
-        it('should does not change `BlockStatement` node body if given node is not a valid Node', () => {
+        it('should does not change `BlockStatement` node body if given node is not a valid AbstractCustomNode', () => {
             assert.doesNotChange(
                 () => NodeUtils.prependNode(blockStatementNode.body, <INode>{}),
                 blockStatementNode,

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