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       6265x           1x                               1x                           6265x   6265x 6265x 6265x               6262x 5534x       728x 728x       728x 728x       728x 713x         6262x   6262x 5531x     731x 731x 731x   731x   731x 731x   731x   731x 713x   18x     731x 731x 731x   731x 731x   731x 713x        
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 {Map<CustomNodes, ICustomNode>}
     */
    @initializable()
    protected customNodes: Map <CustomNodes, ICustomNode>;
 
    /**
     * @type {TCustomNodeFactory}
     */
    private readonly customNodeFactory: TCustomNodeFactory;
 
    /**
     * @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.TStringArrayStorage) 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, 1)}`;
 
        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);
        }
    }
}