import * as estraverse from 'estraverse'; import { ICustomNode } from './interfaces/ICustomNode'; import { INodesGroup } from './interfaces/INodesGroup'; 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 { ConsoleOutputDisableExpressionNode } from './custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode'; 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} */ private nodes: Map = new Map (); /** * @type {Map} */ private nodeObfuscators: Map = new Map ([ [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; } /** * @param node * @returns {INode} */ public obfuscateNode (node: INode): INode { this.setNewNodes(); NodeUtils.parentize(node); this.beforeObfuscation(node); this.obfuscate(node); this.afterObfuscation(node); return node; } /** * @param nodeName * @param node */ private setNode (nodeName: string, node: ICustomNode): void { this.nodes.set(nodeName, node); } /** * @param nodesGroup */ private setNodesGroup (nodesGroup: INodesGroup): void { let nodes: Map = nodesGroup.getNodes(); nodes.forEach((node: ICustomNode, key: string) => { this.nodes.set(key, 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 { if (!this.nodeObfuscators.has(node.type)) { return; } this.nodeObfuscators.get(node.type).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); } }); } private setNewNodes (): void { if (this.options.get('selfDefending')) { this.setNodesGroup(new SelfDefendingNodesGroup(this.options)); } if (this.options.get('disableConsoleOutput')) { this.setNode( 'consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode(this.options) ); } if (this.options.get('debugProtection')) { this.setNodesGroup(new DebugProtectionNodesGroup(this.options)); } if (this.options.get('unicodeArray')) { /** * Important to set this nodes latest to prevent runtime errors caused by `rotateUnicodeArray` option */ this.setNodesGroup(new UnicodeArrayNodesGroup(this.options)); } } }