All files / src Obfuscator.ts

100% Statements 38/38
100% Branches 6/6
100% Functions 5/5
100% Lines 38/38
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 1351x                 1x 1x   1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1x                 14x                                                 14x   14x                         14x   14x 14x 14x   14x             14x 11x 9x                 14x 11x 2x                     907x   907x 550x     357x 361x               14x   907x          
import * as estraverse from 'estraverse';
 
import { ICustomNode } from './interfaces/custom-nodes/ICustomNode';
import { INode } from './interfaces/nodes/INode';
import { IObfuscator } from "./interfaces/IObfuscator";
import { IOptions } from "./interfaces/IOptions";
 
import { TNodeObfuscator } from "./types/TNodeObfuscator";
 
import { AppendState } from './enums/AppendState';
import { NodeType } from './enums/NodeType';
 
import { CatchClauseObfuscator } from './node-obfuscators/CatchClauseObfuscator';
import { ConsoleOutputNodesGroup } from "./node-groups/ConsoleOutputNodesGroup";
import { DebugProtectionNodesGroup } from './node-groups/DebugProtectionNodesGroup';
import { FunctionDeclarationObfuscator } from './node-obfuscators/FunctionDeclarationObfuscator';
import { FunctionObfuscator } from './node-obfuscators/FunctionObfuscator';
import { LiteralObfuscator } from './node-obfuscators/LiteralObfuscator';
import { MemberExpressionObfuscator } from './node-obfuscators/MemberExpressionObfuscator';
import { MethodDefinitionObfuscator } from './node-obfuscators/MethodDefinitionObfuscator';
import { NodeUtils } from "./NodeUtils";
import { ObjectExpressionObfuscator } from './node-obfuscators/ObjectExpressionObfuscator';
import { SelfDefendingNodesGroup } from "./node-groups/SelfDefendingNodesGroup";
import { UnicodeArrayNodesGroup } from './node-groups/UnicodeArrayNodesGroup';
import { VariableDeclarationObfuscator } from './node-obfuscators/VariableDeclarationObfuscator';
 
export class Obfuscator implements IObfuscator {
    /**
     * @type {Map<string, Node>}
     */
    private nodes: Map <string, ICustomNode>;
 
    /**
     * @type {Map<string, TNodeObfuscator[]>}
     */
    private nodeObfuscators: Map <string, TNodeObfuscator[]> = new Map <string, TNodeObfuscator[]> ([
        [NodeType.ArrowFunctionExpression, [FunctionObfuscator]],
        [NodeType.ClassDeclaration, [FunctionDeclarationObfuscator]],
        [NodeType.CatchClause, [CatchClauseObfuscator]],
        [NodeType.FunctionDeclaration, [
            FunctionDeclarationObfuscator,
            FunctionObfuscator
        ]],
        [NodeType.FunctionExpression, [FunctionObfuscator]],
        [NodeType.MemberExpression, [MemberExpressionObfuscator]],
        [NodeType.MethodDefinition, [MethodDefinitionObfuscator]],
        [NodeType.ObjectExpression, [ObjectExpressionObfuscator]],
        [NodeType.VariableDeclaration, [VariableDeclarationObfuscator]],
        [NodeType.Literal, [LiteralObfuscator]]
    ]);
 
    /**
     * @type {IOptions}
     */
    private options: IOptions;
 
    /**
     * @param options
     */
    constructor (options: IOptions) {
        this.options = options;
 
        this.nodes = new Map <string, ICustomNode> ([
            ...new SelfDefendingNodesGroup(this.options).getNodes(),
            ...new ConsoleOutputNodesGroup(this.options).getNodes(),
            ...new DebugProtectionNodesGroup(this.options).getNodes(),
            ...new UnicodeArrayNodesGroup(this.options).getNodes()
        ]);
    }
 
    /**
     * @param node
     * @returns {INode}
     */
    public obfuscateNode (node: INode): INode {
        NodeUtils.parentize(node);
 
        this.beforeObfuscation(node);
        this.obfuscate(node);
        this.afterObfuscation(node);
 
        return node;
    }
 
    /**
     * @param astTree
     */
    private afterObfuscation (astTree: INode): void {
        this.nodes.forEach((node: ICustomNode) => {
            if (node.getAppendState() === AppendState.AfterObfuscation) {
                node.appendNode(astTree);
            }
        });
    }
 
    /**
     * @param astTree
     */
    private beforeObfuscation (astTree: INode): void {
        this.nodes.forEach((node: ICustomNode) => {
            if (node.getAppendState() === AppendState.BeforeObfuscation) {
                node.appendNode(astTree);
            }
        });
    };
 
 
    /**
     * @param node
     * @param parentNode
     */
    private initializeNodeObfuscators (node: INode, parentNode: INode): void {
        let nodeObfuscators: TNodeObfuscator[] | undefined = this.nodeObfuscators.get(node.type);
 
        if (!nodeObfuscators) {
            return;
        }
 
        nodeObfuscators.forEach((obfuscator: TNodeObfuscator) => {
            new obfuscator(this.nodes, this.options).obfuscateNode(node, parentNode);
        });
    }
 
    /**
     * @param node
     */
    private obfuscate (node: INode): void {
        estraverse.replace(node, {
            leave: (node: INode, parentNode: INode): any => {
                this.initializeNodeObfuscators(node, parentNode);
            }
        });
    }
}