Obfuscator.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import * as estraverse from 'estraverse';
  2. import { INode } from './interfaces/INode';
  3. import { INodeObfuscator } from './interfaces/INodeObfuscator';
  4. import { INodesGroup } from './interfaces/INodesGroup';
  5. import { ITreeNode } from './interfaces/nodes/ITreeNode';
  6. import { AppendState } from './enums/AppendState';
  7. import { NodeType } from "./enums/NodeType";
  8. import { CatchClauseObfuscator } from "./node-obfuscators/CatchClauseObfuscator";
  9. import { DebugProtectionNodesGroup } from "./node-groups/DebugProtectionNodesGroup";
  10. import { FunctionDeclarationObfuscator } from './node-obfuscators/FunctionDeclarationObfuscator';
  11. import { FunctionObfuscator } from './node-obfuscators/FunctionObfuscator';
  12. import { LiteralObfuscator } from './node-obfuscators/LiteralObfuscator';
  13. import { MemberExpressionObfuscator } from './node-obfuscators/MemberExpressionObfuscator';
  14. import { MethodDefinitionObfuscator } from './node-obfuscators/MethodDefinitionObfuscator';
  15. import { ObjectExpressionObfuscator } from './node-obfuscators/ObjectExpressionObfuscator';
  16. import { UnicodeArrayNode } from './nodes/UnicodeArrayNode';
  17. import { UnicodeArrayNodesGroup } from './node-groups/UnicodeArrayNodesGroup';
  18. import { Utils } from './Utils';
  19. import { VariableDeclarationObfuscator } from './node-obfuscators/VariableDeclarationObfuscator';
  20. export class Obfuscator {
  21. /**
  22. * @type {Map<string, Node>}
  23. */
  24. private nodes: Map <string, INode> = new Map <string, INode> ();
  25. /**
  26. * @type {Map<string, Function[]>}
  27. */
  28. private nodeObfuscators: Map <string, Function[]> = new Map <string, Function[]> ([
  29. [NodeType.ArrowFunctionExpression, [FunctionObfuscator]],
  30. [NodeType.ClassDeclaration, [FunctionDeclarationObfuscator]],
  31. [NodeType.CatchClause, [CatchClauseObfuscator]],
  32. [NodeType.FunctionDeclaration, [
  33. FunctionDeclarationObfuscator,
  34. FunctionObfuscator
  35. ]],
  36. [NodeType.FunctionExpression, [FunctionObfuscator]],
  37. [NodeType.MemberExpression, [MemberExpressionObfuscator]],
  38. [NodeType.MethodDefinition, [MethodDefinitionObfuscator]],
  39. [NodeType.ObjectExpression, [ObjectExpressionObfuscator]],
  40. [NodeType.VariableDeclaration, [VariableDeclarationObfuscator]],
  41. [NodeType.Literal, [LiteralObfuscator]]
  42. ]);
  43. /**
  44. * @type any
  45. */
  46. private options: any;
  47. /**
  48. * @param options
  49. */
  50. constructor (options: any = {}) {
  51. this.options = options;
  52. }
  53. /**
  54. * @param node
  55. */
  56. public obfuscateNode (node: ITreeNode): void {
  57. this.insertNewNodes(node);
  58. this.beforeObfuscation(node);
  59. estraverse.replace(node, {
  60. enter: (node: ITreeNode, parent: ITreeNode): any => this.nodeControllerFirstPass(node, parent)
  61. });
  62. estraverse.replace(node, {
  63. leave: (node: ITreeNode, parent: ITreeNode): any => this.nodeControllerSecondPass(node, parent)
  64. });
  65. this.afterObfuscation(node);
  66. }
  67. /**
  68. * @param nodeName
  69. * @param node
  70. */
  71. public setNode (nodeName: string, node: INode): void {
  72. this.nodes.set(nodeName, node);
  73. }
  74. /**
  75. * @param nodesGroup
  76. */
  77. public setNodesGroup (nodesGroup: INodesGroup): void {
  78. let nodes: Map <string, INode> = nodesGroup.getNodes();
  79. nodes.forEach((node: INode, key: string) => {
  80. this.nodes.set(key, node);
  81. });
  82. }
  83. /**
  84. * @param node
  85. */
  86. private afterObfuscation (node: ITreeNode): void {
  87. this.nodes.forEach((node: INode) => {
  88. if (node.getAppendState() === AppendState.AfterObfuscation) {
  89. node.appendNode();
  90. }
  91. });
  92. }
  93. /**
  94. * @param node
  95. */
  96. private beforeObfuscation (node: ITreeNode): void {
  97. this.nodes.forEach((node: INode) => {
  98. if (node.getAppendState() === AppendState.BeforeObfuscation) {
  99. node.appendNode();
  100. }
  101. });
  102. };
  103. private insertNewNodes (astTree: ITreeNode): void {
  104. if (this.options['rotateUnicodeArray']) {
  105. this.setNodesGroup(new UnicodeArrayNodesGroup(astTree));
  106. } else {
  107. this.setNode(
  108. 'unicodeArrayNode',
  109. new UnicodeArrayNode(astTree, Utils.getRandomVariableName(UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH))
  110. );
  111. }
  112. if (this.options['debugProtection']) {
  113. this.setNodesGroup(new DebugProtectionNodesGroup(astTree, this.options));
  114. }
  115. }
  116. /**
  117. * @param node
  118. * @param parent
  119. */
  120. private nodeControllerFirstPass (node: ITreeNode, parent: ITreeNode): void {
  121. Object.defineProperty(node, 'parentNode', {
  122. configurable: true,
  123. enumerable: true,
  124. value: parent || node,
  125. writable: true
  126. });
  127. }
  128. /**
  129. * @param node
  130. * @param parent
  131. */
  132. private nodeControllerSecondPass (node: ITreeNode, parent: ITreeNode): void {
  133. switch (node.type) {
  134. default:
  135. this.initializeNodeObfuscators(node, parent);
  136. }
  137. }
  138. /**
  139. * @param node
  140. * @param parent
  141. */
  142. private initializeNodeObfuscators (node: ITreeNode, parent: ITreeNode): void {
  143. if (!this.nodeObfuscators.has(node.type)) {
  144. return;
  145. }
  146. this.nodeObfuscators.get(node.type).forEach((obfuscator: Function) => {
  147. new (<INodeObfuscator> obfuscator(this.nodes)).obfuscateNode(node, parent);
  148. });
  149. }
  150. }