VariableDeclarationObfuscator.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import * as estraverse from 'estraverse';
  2. import { INode } from "../interfaces/nodes/INode";
  3. import { IVariableDeclarationNode } from "../interfaces/nodes/IVariableDeclarationNode";
  4. import { IVariableDeclaratorNode } from "../interfaces/nodes/IVariableDeclaratorNode";
  5. import { NodeType } from "../enums/NodeType";
  6. import { NodeObfuscator } from './NodeObfuscator';
  7. import { NodeUtils } from "../NodeUtils";
  8. import { Utils } from '../Utils';
  9. /**
  10. * replaces:
  11. * var variable = 1;
  12. * variable++;
  13. *
  14. * on:
  15. * var _0x12d45f = 1;
  16. * _0x12d45f++;
  17. *
  18. */
  19. export class VariableDeclarationObfuscator extends NodeObfuscator {
  20. /**
  21. * @type {Map<string, string>}
  22. */
  23. private variableNames: Map <string, string> = new Map <string, string> ();
  24. /**
  25. * @param variableDeclarationNode
  26. * @param parentNode
  27. */
  28. public obfuscateNode (variableDeclarationNode: IVariableDeclarationNode, parentNode: INode): void {
  29. if (parentNode.type === NodeType.Program) {
  30. return;
  31. }
  32. this.replaceVariableName(variableDeclarationNode);
  33. this.replaceVariableCalls(variableDeclarationNode, parentNode);
  34. }
  35. /**
  36. * @param variableDeclarationNode
  37. */
  38. private replaceVariableName (variableDeclarationNode: IVariableDeclarationNode): void {
  39. variableDeclarationNode.declarations.forEach((declarationNode: IVariableDeclaratorNode) => {
  40. estraverse.replace(declarationNode.id, {
  41. enter: (node: INode): any => {
  42. if (NodeUtils.isIdentifierNode(node)) {
  43. this.variableNames.set(node.name, Utils.getRandomVariableName());
  44. node.name = this.variableNames.get(node.name);
  45. return;
  46. }
  47. return estraverse.VisitorOption.Skip;
  48. }
  49. });
  50. });
  51. }
  52. /**
  53. * @param variableDeclarationNode
  54. * @param variableParentNode
  55. */
  56. private replaceVariableCalls (variableDeclarationNode: IVariableDeclarationNode, variableParentNode: INode): void {
  57. let scopeNode: INode;
  58. scopeNode = variableDeclarationNode.kind === 'var' ? NodeUtils.getBlockScopeOfNode(
  59. variableDeclarationNode
  60. ) : variableParentNode;
  61. let isNodeAfterVariableDeclaratorFlag: boolean = false;
  62. estraverse.replace(scopeNode, {
  63. enter: (node: INode, parentNode: INode): any => {
  64. const functionNodes: string[] = [
  65. NodeType.ArrowFunctionExpression,
  66. NodeType.FunctionDeclaration,
  67. NodeType.FunctionExpression
  68. ];
  69. if (Utils.arrayContains(functionNodes, node.type)) {
  70. estraverse.replace(node, {
  71. enter: (node: INode, parentNode: INode): any => {
  72. this.replaceNodeIdentifierByNewValue(node, parentNode, this.variableNames);
  73. }
  74. });
  75. }
  76. if (node === variableDeclarationNode) {
  77. isNodeAfterVariableDeclaratorFlag = true;
  78. }
  79. if (isNodeAfterVariableDeclaratorFlag) {
  80. this.replaceNodeIdentifierByNewValue(node, parentNode, this.variableNames);
  81. }
  82. }
  83. });
  84. }
  85. }