NodeObfuscator.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { ICustomNode } from '../interfaces/ICustomNode';
  2. import { INodeObfuscator } from '../interfaces/INodeObfuscator';
  3. import { INode } from "../interfaces/nodes/INode";
  4. import { IOptions } from "../interfaces/IOptions";
  5. import { JSFuck } from "../enums/JSFuck";
  6. import { NodeUtils } from "../NodeUtils";
  7. import { Utils } from '../Utils';
  8. import {UnicodeArrayNode} from "../custom-nodes/unicode-array-nodes/UnicodeArrayNode";
  9. export abstract class NodeObfuscator implements INodeObfuscator {
  10. /**
  11. * @type Map <string, Node>
  12. */
  13. protected nodes: Map <string, ICustomNode>;
  14. /**
  15. * @type {IOptions}
  16. */
  17. protected options: IOptions;
  18. /**
  19. * @param nodes
  20. * @param options
  21. */
  22. constructor(nodes: Map <string, ICustomNode>, options: IOptions = {}) {
  23. this.nodes = nodes;
  24. this.options = options;
  25. }
  26. /**
  27. * @param node
  28. * @param parentNode
  29. */
  30. public abstract obfuscateNode (node: INode, parentNode?: INode): void;
  31. /**
  32. * @param name
  33. * @returns {boolean}
  34. */
  35. protected isReservedName (name: string): boolean {
  36. return this.options['reservedNames'].some((reservedName: string) => {
  37. return reservedName === name;
  38. });
  39. }
  40. /**
  41. * @param node
  42. * @param parentNode
  43. * @param namesMap
  44. */
  45. protected replaceNodeIdentifierByNewValue (node: INode, parentNode: INode, namesMap: Map <string, string>): void {
  46. if (NodeUtils.isIdentifierNode(node) && namesMap.has(node.name)) {
  47. const parentNodeIsAPropertyNode: boolean = (
  48. NodeUtils.isPropertyNode(parentNode) &&
  49. parentNode.key === node
  50. ),
  51. parentNodeIsAMemberExpressionNode: boolean = (
  52. NodeUtils.isMemberExpressionNode(parentNode) &&
  53. parentNode.computed === false &&
  54. parentNode.property === node
  55. );
  56. if (parentNodeIsAPropertyNode || parentNodeIsAMemberExpressionNode) {
  57. return;
  58. }
  59. node.name = namesMap.get(node.name);
  60. }
  61. }
  62. /**
  63. * @param nodeValue
  64. * @returns {string}
  65. */
  66. protected replaceLiteralBooleanByJSFuck (nodeValue: boolean): string {
  67. return nodeValue ? JSFuck.True : JSFuck.False;
  68. }
  69. /**
  70. * @param nodeValue
  71. * @returns {string}
  72. */
  73. protected replaceLiteralNumberByHexadecimalValue (nodeValue: number): string {
  74. const prefix: string = '0x';
  75. if (!Utils.isInteger(nodeValue)) {
  76. return String(nodeValue);
  77. }
  78. return `${prefix}${Utils.decToHex(nodeValue)}`;
  79. }
  80. /**
  81. * @param nodeValue
  82. * @returns {string}
  83. */
  84. protected replaceLiteralValueByUnicodeValue (nodeValue: string): string {
  85. let value: string = nodeValue;
  86. if (this.options['encodeUnicodeLiterals']) {
  87. value = new Buffer(encodeURI(value)).toString('base64');
  88. }
  89. value = Utils.stringToUnicode(value);
  90. if (!this.options['unicodeArray']) {
  91. return value;
  92. }
  93. return this.replaceLiteralValueByUnicodeArrayCall(value)
  94. }
  95. /**
  96. * @param value
  97. * @returns {string}
  98. */
  99. protected replaceLiteralValueByUnicodeArrayCall (value: string): string {
  100. let unicodeArrayNode: UnicodeArrayNode = <UnicodeArrayNode> this.nodes.get('unicodeArrayNode'),
  101. unicodeArray: string[] = unicodeArrayNode.getNodeData(),
  102. sameIndex: number = unicodeArray.indexOf(value),
  103. index: number,
  104. hexadecimalIndex: string;
  105. if (sameIndex >= 0) {
  106. index = sameIndex;
  107. } else {
  108. index = unicodeArray.length;
  109. unicodeArrayNode.updateNodeData(value);
  110. }
  111. hexadecimalIndex = this.replaceLiteralNumberByHexadecimalValue(index);
  112. if (this.options['wrapUnicodeArrayCalls']) {
  113. return `${this.nodes.get('unicodeArrayCallsWrapper').getNodeIdentifier()}('${hexadecimalIndex}')`;
  114. }
  115. return `${unicodeArrayNode.getNodeIdentifier()}[${hexadecimalIndex}]`;
  116. }
  117. }