FunctionTransformer.ts 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { injectable, inject } from 'inversify';
  2. import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
  3. import * as estraverse from 'estraverse';
  4. import * as ESTree from 'estree';
  5. import { IOptions } from '../../interfaces/options/IOptions';
  6. import { IObfuscationReplacer } from '../../interfaces/node-transformers/IObfuscationReplacer';
  7. import { IObfuscationReplacerWithStorage } from '../../interfaces/node-transformers/IObfuscationReplacerWithStorage';
  8. import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscationReplacers';
  9. import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
  10. import { Node } from '../../node/Node';
  11. /**
  12. * replaces:
  13. * function foo (argument1) { return argument1; };
  14. *
  15. * on:
  16. * function foo (_0x12d45f) { return _0x12d45f; };
  17. *
  18. */
  19. @injectable()
  20. export class FunctionTransformer extends AbstractNodeTransformer {
  21. /**
  22. * @type {IObfuscationReplacerWithStorage}
  23. */
  24. private readonly identifierReplacer: IObfuscationReplacerWithStorage;
  25. /**
  26. * @param nodeObfuscatorsReplacersFactory
  27. * @param options
  28. */
  29. constructor (
  30. @inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
  31. @inject(ServiceIdentifiers.IOptions) options: IOptions
  32. ) {
  33. super(options);
  34. this.identifierReplacer = <IObfuscationReplacerWithStorage>nodeObfuscatorsReplacersFactory(NodeObfuscatorsReplacers.IdentifierReplacer);
  35. }
  36. /**
  37. * @param functionNode
  38. * @returns {ESTree.Node}
  39. */
  40. public transformNode (functionNode: ESTree.Function): ESTree.Node {
  41. const nodeIdentifier: number = this.nodeIdentifier++;
  42. this.storeFunctionParams(functionNode, nodeIdentifier);
  43. this.replaceFunctionParams(functionNode, nodeIdentifier);
  44. return functionNode;
  45. }
  46. /**
  47. * @param functionNode
  48. * @param nodeIdentifier
  49. */
  50. private storeFunctionParams (functionNode: ESTree.Function, nodeIdentifier: number): void {
  51. functionNode.params
  52. .forEach((paramsNode: ESTree.Node) => {
  53. if (Node.isIdentifierNode(paramsNode)) {
  54. this.identifierReplacer.storeNames(paramsNode.name, nodeIdentifier);
  55. }
  56. });
  57. }
  58. /**
  59. * @param functionNode
  60. * @param nodeIdentifier
  61. */
  62. private replaceFunctionParams (functionNode: ESTree.Function, nodeIdentifier: number): void {
  63. const traverseVisitor: estraverse.Visitor = {
  64. enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
  65. if (Node.isReplaceableIdentifierNode(node, parentNode)) {
  66. const newNodeName: string = this.identifierReplacer.replace(node.name, nodeIdentifier);
  67. if (node.name !== newNodeName) {
  68. node.name = newNodeName;
  69. node.obfuscated = true;
  70. }
  71. }
  72. }
  73. };
  74. functionNode.params.forEach((paramsNode: ESTree.Node) => estraverse.replace(paramsNode, traverseVisitor));
  75. estraverse.replace(functionNode.body, traverseVisitor);
  76. }
  77. }