FunctionTransformer.ts 3.3 KB

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