# All files / src/custom-nodes/string-array-nodes/group StringArrayCustomNodeGroup.ts

100% Statements 48/48
100% Branches 8/8
100% Functions 4/4
100% Lines 45/45

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    1331x
    1x

    1x

    1x
    1x

    1x
    1x
    1x
    1x

    1x

    1812x

    1x

    1x

    1812x

    1812x
    1812x
    1812x

    1809x
    1282x

    527x
    527x

    527x
    527x

    527x
    515x

    1809x

    1809x
    1279x

    530x
    530x
    530x

    530x

    530x
    530x

    530x

    530x
    515x

    15x

    530x
    530x
    530x

    530x
    530x

    530x
    515x

     import { injectable, inject } from 'inversify';
    import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';

    import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';
    import { TNodeWithBlockStatement } from '../../../types/node/TNodeWithBlockStatement';
    import { TObfuscationEvent } from '../../../types/event-emitters/TObfuscationEvent';

    import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
    import { IObfuscationEventEmitter } from '../../../interfaces/event-emitters/IObfuscationEventEmitter';
    import { IOptions } from '../../../interfaces/options/IOptions';
    import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData';
    import { IStorage } from '../../../interfaces/storages/IStorage';

    import { initializable } from '../../../decorators/Initializable';

    import { CustomNodes } from '../../../enums/container/CustomNodes';
    import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';

    import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup';
    import { NodeAppender } from '../../../node/NodeAppender';
    import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
    import { Utils } from '../../../utils/Utils';

    @injectable()
    export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
        /**
         * @type {TObfuscationEvent}
         */
        protected appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;

        /**
         * @type {TCustomNodeFactory}
         */
        private readonly customNodeFactory: TCustomNodeFactory;

        /**
         * @type {Map<CustomNodes, ICustomNode>}
         */
        @initializable()
        protected customNodes: Map <CustomNodes, ICustomNode>;

        /**
         * @type {IObfuscationEventEmitter}
         */
        private readonly obfuscationEventEmitter: IObfuscationEventEmitter;

        /**
         * @type {IStorage <string>}
         */
        @initializable()
        private stringArrayStorage: IStorage <string>;

        /**
         * @param customNodeFactory
         * @param obfuscationEventEmitter
         * @param stringArrayStorage
         * @param options
         */
        constructor (
            @inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
            @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
            @inject(ServiceIdentifiers['IStorage<string>']) stringArrayStorage: IStorage<string>,
            @inject(ServiceIdentifiers.IOptions) options: IOptions
        ) {
            super(options);

            this.customNodeFactory = customNodeFactory;
            this.obfuscationEventEmitter = obfuscationEventEmitter;
            this.stringArrayStorage = stringArrayStorage;
        }

        /**
         * @param blockScopeNode
         * @param stackTraceData
         */
        public appendCustomNodes (blockScopeNode: TNodeWithBlockStatement, stackTraceData: IStackTraceData[]): void {
            if (!this.stringArrayStorage.getLength()) {
                return;
            }

            // stringArrayNode append
            this.appendCustomNodeIfExist(CustomNodes.StringArrayNode, (customNode: ICustomNode) => {
                NodeAppender.prependNode(blockScopeNode, customNode.getNode());
            });

            // stringArrayCallsWrapper append
            this.appendCustomNodeIfExist(CustomNodes.StringArrayCallsWrapper, (customNode: ICustomNode) => {
                NodeAppender.insertNodeAtIndex(blockScopeNode, customNode.getNode(), 1);
            });

            // stringArrayRotateFunctionNode append
            this.appendCustomNodeIfExist(CustomNodes.StringArrayRotateFunctionNode, (customNode: ICustomNode) => {
                NodeAppender.insertNodeAtIndex(blockScopeNode, customNode.getNode(), 1);
            });
        }

        public initialize (): void {
            this.customNodes = new Map <CustomNodes, ICustomNode> ();

            if (!this.options.stringArray) {
                return;
            }

            const stringArrayNode: ICustomNode = this.customNodeFactory(CustomNodes.StringArrayNode);
            const stringArrayCallsWrapper: ICustomNode = this.customNodeFactory(CustomNodes.StringArrayCallsWrapper);
            const stringArrayRotateFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.StringArrayRotateFunctionNode);

            const stringArrayStorageId: string = this.stringArrayStorage.getStorageId();

            const stringArrayName: string = `_${Utils.hexadecimalPrefix}${stringArrayStorageId}`;
            const stringArrayCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${Utils.stringRotate(stringArrayStorageId, 2)}`;

            let stringArrayRotateValue: number;

            if (this.options.rotateStringArray) {
                stringArrayRotateValue = RandomGeneratorUtils.getRandomInteger(100, 500);
            } else {
                stringArrayRotateValue = 0;
            }

            stringArrayNode.initialize(this.stringArrayStorage, stringArrayName, stringArrayRotateValue);
            stringArrayCallsWrapper.initialize(this.stringArrayStorage, stringArrayName, stringArrayCallsWrapperName);
            stringArrayRotateFunctionNode.initialize(this.stringArrayStorage, stringArrayName, stringArrayRotateValue);

            this.customNodes.set(CustomNodes.StringArrayNode, stringArrayNode);
            this.customNodes.set(CustomNodes.StringArrayCallsWrapper, stringArrayCallsWrapper);

            if (this.options.rotateStringArray) {
                this.customNodes.set(CustomNodes.StringArrayRotateFunctionNode, stringArrayRotateFunctionNode);
            }
        }
    }