shuffleStringArray option

This commit is contained in:
sanex3339
2020-01-12 19:55:41 +03:00
parent b764844696
commit 1edf96c0a0
28 changed files with 392 additions and 88 deletions
@@ -4,10 +4,9 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { TStringArrayStorage } from '../../types/storages/TStringArrayStorage';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IStringArrayStorage } from '../../interfaces/storages/string-array-storage/IStringArrayStorage';
import { IStringArrayStorageAnalyzer } from '../../interfaces/analyzers/string-array-storage-analyzer/IStringArrayStorageAnalyzer';
import { IStringArrayStorageItemData } from '../../interfaces/storages/string-array-storage/IStringArrayStorageItem';
@@ -35,9 +34,9 @@ export class StringArrayStorageAnalyzer implements IStringArrayStorageAnalyzer {
private readonly randomGenerator: IRandomGenerator;
/**
* @type {TStringArrayStorage}
* @type {IStringArrayStorage}
*/
private readonly stringArrayStorage: TStringArrayStorage;
private readonly stringArrayStorage: IStringArrayStorage;
/**
* @type {Map<ESTree.Literal, IStringArrayStorageItemData>}
@@ -45,12 +44,12 @@ export class StringArrayStorageAnalyzer implements IStringArrayStorageAnalyzer {
private readonly stringArrayStorageData: Map<ESTree.Literal, IStringArrayStorageItemData> = new Map();
/**
* @param {TStringArrayStorage} stringArrayStorage
* @param {IStringArrayStorage} stringArrayStorage
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: TStringArrayStorage,
@inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: IStringArrayStorage,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions,
) {
+5 -1
View File
@@ -283,7 +283,7 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
BooleanSanitizer
)
.option(
'--rotate-string-array <boolean>', 'Disable rotation of unicode array values during obfuscation',
'--rotate-string-array <boolean>', 'Enable rotation of string array values during obfuscation',
BooleanSanitizer
)
.option(
@@ -296,6 +296,10 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
'Disables self-defending for obfuscated code',
BooleanSanitizer
)
.option(
'--shuffle-string-array <boolean>', 'Randomly shuffles string array items',
BooleanSanitizer
)
.option(
'--source-map <boolean>',
'Enables source map generation',
@@ -3,10 +3,10 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { TControlFlowStorage } from '../../../types/storages/TControlFlowStorage';
import { TCustomNodeGroupStorage } from '../../../types/storages/TCustomNodeGroupStorage';
import { TStringArrayStorage } from '../../../types/storages/TStringArrayStorage';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { IStringArrayStorage } from '../../../interfaces/storages/string-array-storage/IStringArrayStorage';
import { ControlFlowStorage } from '../../../storages/control-flow/ControlFlowStorage';
import { CustomNodeGroupStorage } from '../../../storages/custom-node-group/CustomNodeGroupStorage';
@@ -18,7 +18,7 @@ export const storagesModule: interfaces.ContainerModule = new ContainerModule((b
.to(CustomNodeGroupStorage)
.inSingletonScope();
bind<TStringArrayStorage>(ServiceIdentifiers.TStringArrayStorage)
bind<IStringArrayStorage>(ServiceIdentifiers.TStringArrayStorage)
.to(StringArrayStorage)
.inSingletonScope();
@@ -3,11 +3,11 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { TStringArrayStorage } from '../../types/storages/TStringArrayStorage';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ICustomNodeFormatter } from '../../interfaces/custom-nodes/ICustomNodeFormatter';
import { IStringArrayStorage } from '../../interfaces/storages/string-array-storage/IStringArrayStorage';
import { initializable } from '../../decorators/Initializable';
@@ -15,15 +15,14 @@ import { StringArrayTemplate } from '../../templates/string-array-nodes/string-a
import { AbstractCustomNode } from '../AbstractCustomNode';
import { NodeUtils } from '../../node/NodeUtils';
import { StringArrayStorage } from '../../storages/string-array/StringArrayStorage';
@injectable()
export class StringArrayNode extends AbstractCustomNode {
/**
* @type {TStringArrayStorage}
* @type {IStringArrayStorage}
*/
@initializable()
private stringArrayStorage!: TStringArrayStorage;
private stringArrayStorage!: IStringArrayStorage;
/**
* @type {string}
@@ -31,12 +30,6 @@ export class StringArrayNode extends AbstractCustomNode {
@initializable()
private stringArrayName!: string;
/**
* @type {number}
*/
@initializable()
private stringArrayRotateValue!: number;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomNodeFormatter} customNodeFormatter
@@ -54,27 +47,15 @@ export class StringArrayNode extends AbstractCustomNode {
}
/**
* @param {TStringArrayStorage} stringArrayStorage
* @param {IStringArrayStorage} stringArrayStorage
* @param {string} stringArrayName
* @param {number} stringArrayRotateValue
*/
public initialize (
stringArrayStorage: TStringArrayStorage,
stringArrayName: string,
stringArrayRotateValue: number
stringArrayStorage: IStringArrayStorage,
stringArrayName: string
): void {
this.stringArrayStorage = stringArrayStorage;
this.stringArrayName = stringArrayName;
this.stringArrayRotateValue = stringArrayRotateValue;
}
/**
* @returns {TStatement[]}
*/
public getNode (): TStatement[] {
(<StringArrayStorage>this.stringArrayStorage).rotateStorage(this.stringArrayRotateValue);
return super.getNode();
}
/**
@@ -38,7 +38,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
* @param {number}
*/
@initializable()
private stringArrayRotateValue!: number;
private stringArrayRotationAmount!: number;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
@@ -62,14 +62,14 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
/**
* @param {string} stringArrayName
* @param {number} stringArrayRotateValue
* @param {number} stringArrayRotationAmount
*/
public initialize (
stringArrayName: string,
stringArrayRotateValue: number
stringArrayRotationAmount: number
): void {
this.stringArrayName = stringArrayName;
this.stringArrayRotateValue = stringArrayRotateValue;
this.stringArrayRotationAmount = stringArrayRotationAmount;
}
/**
@@ -103,7 +103,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
code,
timesName,
stringArrayName: this.stringArrayName,
stringArrayRotateValue: NumberUtils.toHex(this.stringArrayRotateValue),
stringArrayRotationAmount: NumberUtils.toHex(this.stringArrayRotationAmount),
whileFunctionName
}),
{
@@ -5,12 +5,12 @@ import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCusto
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TInitialData } from '../../../types/TInitialData';
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
import { TStringArrayStorage } from '../../../types/storages/TStringArrayStorage';
import { ICallsGraphData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphData';
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ICallsGraphData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphData';
import { IStringArrayStorage } from '../../../interfaces/storages/string-array-storage/IStringArrayStorage';
import { initializable } from '../../../decorators/Initializable';
@@ -42,20 +42,20 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
private readonly customNodeFactory: TCustomNodeFactory;
/**
* @type {TStringArrayStorage}
* @type {IStringArrayStorage}
*/
private readonly stringArrayStorage: TStringArrayStorage;
private readonly stringArrayStorage: IStringArrayStorage;
/**
* @param {TCustomNodeFactory} customNodeFactory
* @param {TStringArrayStorage} stringArrayStorage
* @param {IStringArrayStorage} stringArrayStorage
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
@inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: TStringArrayStorage,
@inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: IStringArrayStorage,
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@@ -106,21 +106,13 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
const stringArrayRotateFunctionNode: ICustomNode<TInitialData<StringArrayRotateFunctionNode>> =
this.customNodeFactory(CustomNode.StringArrayRotateFunctionNode);
const stringArrayStorageId: string = this.stringArrayStorage.getStorageId();
const stringArrayName: string = this.stringArrayStorage.getStorageName();
const stringArrayCallsWrapperName: string = this.stringArrayStorage.getStorageCallsWrapperName();
const stringArrayRotationAmount: number = this.stringArrayStorage.getRotationAmount();
const [stringArrayName, stringArrayCallsWrapperName]: string[] = stringArrayStorageId.split('|');
let stringArrayRotateValue: number;
if (this.options.rotateStringArray) {
stringArrayRotateValue = this.randomGenerator.getRandomInteger(100, 500);
} else {
stringArrayRotateValue = 0;
}
stringArrayNode.initialize(this.stringArrayStorage, stringArrayName, stringArrayRotateValue);
stringArrayNode.initialize(this.stringArrayStorage, stringArrayName);
stringArrayCallsWrapper.initialize(stringArrayName, stringArrayCallsWrapperName);
stringArrayRotateFunctionNode.initialize(stringArrayName, stringArrayRotateValue);
stringArrayRotateFunctionNode.initialize(stringArrayName, stringArrayRotationAmount);
this.customNodes.set(CustomNode.StringArrayNode, stringArrayNode);
this.customNodes.set(CustomNode.StringArrayCallsWrapper, stringArrayCallsWrapper);
+1
View File
@@ -27,6 +27,7 @@ export interface IOptions {
readonly rotateStringArray: boolean;
readonly seed: string | number;
readonly selfDefending: boolean;
readonly shuffleStringArray: boolean;
readonly sourceMap: boolean;
readonly sourceMapBaseUrl: string;
readonly sourceMapFileName: string;
@@ -0,0 +1,24 @@
import { IStringArrayStorageItemData } from './IStringArrayStorageItem';
import { IMapStorage } from '../IMapStorage';
export interface IStringArrayStorage extends IMapStorage <string, IStringArrayStorageItemData> {
/**
* @returns {number}
*/
getRotationAmount (): number;
/**
* @returns {string}
*/
getStorageName (): string;
/**
* @returns {string}
*/
getStorageCallsWrapperName (): string;
rotateStorage (): void;
shuffleStorage (): void;
}
@@ -1,15 +1,17 @@
import { inject, injectable, } from 'inversify';
import { inject, injectable, postConstruct } from 'inversify';
import { ServiceIdentifiers } from '../../../../container/ServiceIdentifiers';
import * as ESTree from 'estree';
import { TStringArrayStorage } from '../../../../types/storages/TStringArrayStorage';
import { IEscapeSequenceEncoder } from '../../../../interfaces/utils/IEscapeSequenceEncoder';
import { IInitializable } from '../../../../interfaces/IInitializable';
import { IOptions } from '../../../../interfaces/options/IOptions';
import { IStringArrayStorage } from '../../../../interfaces/storages/string-array-storage/IStringArrayStorage';
import { IStringArrayStorageAnalyzer } from '../../../../interfaces/analyzers/string-array-storage-analyzer/IStringArrayStorageAnalyzer';
import { IStringArrayStorageItemData } from '../../../../interfaces/storages/string-array-storage/IStringArrayStorageItem';
import { initializable } from '../../../../decorators/Initializable';
import { StringArrayEncoding } from '../../../../enums/StringArrayEncoding';
import { AbstractObfuscatingReplacer } from '../AbstractObfuscatingReplacer';
@@ -19,7 +21,7 @@ import { NumberUtils } from '../../../../utils/NumberUtils';
import { Utils } from '../../../../utils/Utils';
@injectable()
export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplacer {
export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplacer implements IInitializable {
/**
* @type {IEscapeSequenceEncoder}
*/
@@ -30,6 +32,11 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
*/
private readonly nodesCache: Map <string, ESTree.Node> = new Map();
/**
* @type {IStringArrayStorage}
*/
private readonly stringArrayStorage: IStringArrayStorage;
/**
* @type {IStringArrayStorageAnalyzer}
*/
@@ -38,26 +45,26 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
/**
* @type {string}
*/
private readonly stringArrayStorageCallsWrapperName: string;
@initializable()
private stringArrayStorageCallsWrapperName!: string;
/**
* @param {TStringArrayStorage} stringArrayStorage
* @param {IStringArrayStorage} stringArrayStorage
* @param {IStringArrayStorageAnalyzer} stringArrayStorageAnalyzer
* @param {IEscapeSequenceEncoder} escapeSequenceEncoder
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: TStringArrayStorage,
@inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: IStringArrayStorage,
@inject(ServiceIdentifiers.IStringArrayStorageAnalyzer) stringArrayStorageAnalyzer: IStringArrayStorageAnalyzer,
@inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
this.stringArrayStorage = stringArrayStorage;
this.stringArrayStorageAnalyzer = stringArrayStorageAnalyzer;
this.escapeSequenceEncoder = escapeSequenceEncoder;
this.stringArrayStorageCallsWrapperName = stringArrayStorage.getStorageId().split('|')[1];
}
/**
@@ -84,6 +91,19 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
return rc4KeyLiteralNode;
}
@postConstruct()
public initialize (): void {
this.stringArrayStorageCallsWrapperName = this.stringArrayStorage.getStorageCallsWrapperName();
if (this.options.shuffleStringArray) {
this.stringArrayStorage.shuffleStorage();
}
if (this.options.rotateStringArray) {
this.stringArrayStorage.rotateStorage();
}
}
/**
* @param {SimpleLiteral} literalNode
* @returns {Node}
+6
View File
@@ -188,6 +188,12 @@ export class Options implements IOptions {
@IsBoolean()
public readonly selfDefending!: boolean;
/**
* @type {boolean}
*/
@IsBoolean()
public readonly shuffleStringArray!: boolean;
/**
* @type {boolean}
*/
@@ -11,6 +11,7 @@ export const StringArrayRule: TOptionsNormalizerRule = (options: IOptions): IOpt
options = {
...options,
rotateStringArray: false,
shuffleStringArray: false,
stringArray: false,
stringArrayEncoding: false,
stringArrayThreshold: 0
+1
View File
@@ -27,6 +27,7 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
rotateStringArray: true,
seed: 0,
selfDefending: false,
shuffleStringArray: true,
sourceMap: false,
sourceMapBaseUrl: '',
sourceMapFileName: '',
+1
View File
@@ -26,6 +26,7 @@ export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
rotateStringArray: false,
seed: 0,
selfDefending: false,
shuffleStringArray: false,
sourceMap: false,
sourceMapBaseUrl: '',
sourceMapFileName: '',
@@ -10,14 +10,17 @@ import { IEncodedValue } from '../../interfaces/IEncodedValue';
import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IStringArrayStorage } from '../../interfaces/storages/string-array-storage/IStringArrayStorage';
import { IStringArrayStorageItemData } from '../../interfaces/storages/string-array-storage/IStringArrayStorageItem';
import { initializable } from '../../decorators/Initializable';
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
import { MapStorage } from '../MapStorage';
@injectable()
export class StringArrayStorage extends MapStorage <string, IStringArrayStorageItemData> {
export class StringArrayStorage extends MapStorage <string, IStringArrayStorageItemData> implements IStringArrayStorage {
/**
* @type {number}
*/
@@ -58,6 +61,23 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
*/
private readonly rc4Keys: string[];
/**
* @type {number}
*/
private rotationAmount: number = 0;
/**
* @type {string}
*/
@initializable()
private stringArrayStorageName!: string;
/**
* @type {string}
*/
@initializable()
private stringArrayStorageCallsWrapperName!: string;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {IArrayUtils} arrayUtils
@@ -99,10 +119,13 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
.generate(StringArrayStorage.stringArrayNameLength);
const baseStringArrayCallsWrapperName: string = this.identifierNamesGenerator
.generate(StringArrayStorage.stringArrayNameLength);
const stringArrayName: string = `${this.options.identifiersPrefix}${baseStringArrayName}`;
const stringArrayCallsWrapperName: string = `${this.options.identifiersPrefix}${baseStringArrayCallsWrapperName}`;
this.storageId = `${stringArrayName}|${stringArrayCallsWrapperName}`;
this.stringArrayStorageName = `${this.options.identifiersPrefix}${baseStringArrayName}`;
this.stringArrayStorageCallsWrapperName = `${this.options.identifiersPrefix}${baseStringArrayCallsWrapperName}`;
this.rotationAmount = this.options.rotateStringArray
? this.randomGenerator.getRandomInteger(100, 500)
: 0;
}
/**
@@ -114,26 +137,76 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
}
/**
* @param {number} rotationAmount
* @returns {number}
*/
public rotateStorage (rotationAmount: number): void {
public getRotationAmount (): number {
return this.rotationAmount;
}
/**
* @returns {string}
*/
public getStorageId (): string {
return this.stringArrayStorageName;
}
/**
* @returns {string}
*/
public getStorageName (): string {
return this.getStorageId();
}
/**
* @returns {string}
*/
public getStorageCallsWrapperName (): string {
return this.stringArrayStorageCallsWrapperName;
}
public rotateStorage (): void {
if (!this.getLength()) {
return;
}
this.storage = new Map(
this.arrayUtils.rotate(
Array.from(this.storage.entries()),
rotationAmount
this.rotationAmount
)
);
}
public shuffleStorage (): void {
this.storage = new Map(
this.arrayUtils
.shuffle(Array.from(this.storage.entries()))
.map<[string, IStringArrayStorageItemData]>(
(
[value, stringArrayStorageItemData]: [string, IStringArrayStorageItemData],
index: number
) => {
stringArrayStorageItemData.index = index;
return [value, stringArrayStorageItemData];
}
)
.sort((
[, stringArrayStorageItemDataA]: [string, IStringArrayStorageItemData],
[, stringArrayStorageItemDataB]: [string, IStringArrayStorageItemData]
) => stringArrayStorageItemDataA.index - stringArrayStorageItemDataB.index)
);
}
/**
* @returns {string}
*/
public toString (): string {
return Array
.from(this.storage.values())
.map((item: IStringArrayStorageItemData) => {
.map((stringArrayStorageItemData: IStringArrayStorageItemData) => {
return `'${this.escapeSequenceEncoder.encode(
item.encodedValue,
stringArrayStorageItemData.encodedValue,
this.options.unicodeEscapeSequence
)}'`;
}).toString();
@@ -11,6 +11,6 @@ export function StringArrayRotateFunctionTemplate (): string {
};
{code}
})({stringArrayName}, 0x{stringArrayRotateValue});
})({stringArrayName}, 0x{stringArrayRotationAmount});
`;
}
-5
View File
@@ -1,5 +0,0 @@
import { IStringArrayStorageItemData } from '../../interfaces/storages/string-array-storage/IStringArrayStorageItem';
import { IMapStorage } from '../../interfaces/storages/IMapStorage';
export type TStringArrayStorage = IMapStorage <string, IStringArrayStorageItemData>;