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);
        }
    }
}