VariableDeclarationObfuscator.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import * as estraverse from 'estraverse';
  2. import * as ESTree from 'estree';
  3. import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
  4. import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
  5. import { IOptions } from '../../interfaces/IOptions';
  6. import { IStorage } from '../../interfaces/IStorage';
  7. import { NodeType } from '../../enums/NodeType';
  8. import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
  9. import { IdentifierReplacer } from './replacers/IdentifierReplacer';
  10. import { Node } from '../../node/Node';
  11. import { NodeUtils } from '../../node/NodeUtils';
  12. /**
  13. * replaces:
  14. * var variable = 1;
  15. * variable++;
  16. *
  17. * on:
  18. * var _0x12d45f = 1;
  19. * _0x12d45f++;
  20. *
  21. */
  22. export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
  23. /**
  24. * @type {IdentifierReplacer}
  25. */
  26. private readonly identifierReplacer: IdentifierReplacer;
  27. /**
  28. * @param customNodesStorage
  29. * @param options
  30. */
  31. constructor(customNodesStorage: IStorage<ICustomNode>, options: IOptions) {
  32. super(customNodesStorage, options);
  33. this.identifierReplacer = new IdentifierReplacer(this.customNodesStorage, this.options);
  34. }
  35. /**
  36. * @param variableDeclarationNode
  37. * @param parentNode
  38. */
  39. public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void {
  40. const blockScopeOfVariableDeclarationNode: TNodeWithBlockStatement = NodeUtils
  41. .getBlockScopeOfNode(variableDeclarationNode);
  42. if (blockScopeOfVariableDeclarationNode.type === NodeType.Program) {
  43. return;
  44. }
  45. const scopeNode: ESTree.Node = variableDeclarationNode.kind === 'var'
  46. ? blockScopeOfVariableDeclarationNode
  47. : parentNode;
  48. this.storeVariableNames(variableDeclarationNode);
  49. this.replaceVariableNames(scopeNode);
  50. }
  51. /**
  52. * @param variableDeclarationNode
  53. */
  54. private storeVariableNames (variableDeclarationNode: ESTree.VariableDeclaration): void {
  55. variableDeclarationNode.declarations
  56. .forEach((declarationNode: ESTree.VariableDeclarator) => {
  57. NodeUtils.typedTraverse(declarationNode.id, NodeType.Identifier, {
  58. enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name)
  59. });
  60. });
  61. }
  62. /**
  63. * @param scopeNode
  64. */
  65. private replaceVariableNames (scopeNode: ESTree.Node): void {
  66. estraverse.replace(scopeNode, {
  67. enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
  68. if (!node.obfuscated && Node.isReplaceableIdentifierNode(node, parentNode)) {
  69. node.name = this.identifierReplacer.replace(node.name);
  70. }
  71. }
  72. });
  73. }
  74. }