VariableDeclarationObfuscator.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 { Nodes } from "../Nodes";
  8. import { NodeUtils } from "../NodeUtils";
  9. import { Utils } from '../Utils';
  10. /**
  11. * replaces:
  12. * var variable = 1;
  13. * variable++;
  14. *
  15. * on:
  16. * var _0x12d45f = 1;
  17. * _0x12d45f++;
  18. *
  19. */
  20. export class VariableDeclarationObfuscator extends NodeObfuscator {
  21. /**
  22. * @type {Map<string, string>}
  23. */
  24. private variableNames: Map <string, string> = new Map <string, string> ();
  25. /**
  26. * @param variableDeclarationNode
  27. * @param parentNode
  28. */
  29. public obfuscateNode (variableDeclarationNode: IVariableDeclarationNode, parentNode: INode): void {
  30. if (parentNode.type === NodeType.Program) {
  31. return;
  32. }
  33. this.replaceVariableName(variableDeclarationNode);
  34. this.replaceVariableCalls(variableDeclarationNode, parentNode);
  35. }
  36. /**
  37. * @param variableDeclarationNode
  38. */
  39. private replaceVariableName (variableDeclarationNode: IVariableDeclarationNode): void {
  40. variableDeclarationNode.declarations.forEach((declarationNode: IVariableDeclaratorNode) => {
  41. estraverse.replace(declarationNode.id, {
  42. enter: (node: INode): any => {
  43. if (Nodes.isIdentifierNode(node) && !this.isReservedName(node.name)) {
  44. this.variableNames.set(node.name, Utils.getRandomVariableName());
  45. node.name = this.variableNames.get(node.name);
  46. return;
  47. }
  48. return estraverse.VisitorOption.Skip;
  49. }
  50. });
  51. });
  52. }
  53. /**
  54. * @param variableDeclarationNode
  55. * @param variableParentNode
  56. */
  57. private replaceVariableCalls (variableDeclarationNode: IVariableDeclarationNode, variableParentNode: INode): void {
  58. let scopeNode: INode = variableDeclarationNode.kind === 'var' ? NodeUtils.getBlockScopeOfNode(
  59. variableDeclarationNode
  60. ) : variableParentNode,
  61. 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. }