mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
callExpression control flow replacer
This commit is contained in:
Vendored
+1245
-922
File diff suppressed because it is too large
Load Diff
@@ -15,13 +15,15 @@ import { SelfDefendingCustomNodeGroup } from '../../../custom-nodes/self-defendi
|
||||
import { StringArrayCustomNodeGroup } from '../../../custom-nodes/string-array-nodes/group/StringArrayCustomNodeGroup';
|
||||
|
||||
import { BinaryExpressionFunctionNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode';
|
||||
import { ControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-storage-nodes/ControlFlowStorageCallNode';
|
||||
import { CallExpressionControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-storage-nodes/CallExpressionControlFlowStorageCallNode';
|
||||
import { CallExpressionFunctionNode } from '../../../custom-nodes/control-flow-replacers-nodes/call-expression-control-flow-replacer-nodes/CallExpressionFunctionNode';
|
||||
import { ControlFlowStorageNode } from '../../../custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode';
|
||||
import { ConsoleOutputDisableExpressionNode } from '../../../custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode';
|
||||
import { DebugProtectionFunctionCallNode } from '../../../custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode';
|
||||
import { DebugProtectionFunctionIntervalNode } from '../../../custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode';
|
||||
import { DebugProtectionFunctionNode } from '../../../custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode';
|
||||
import { DomainLockNode } from '../../../custom-nodes/domain-lock-nodes/DomainLockNode';
|
||||
import { ExpressionWithOperatorControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode';
|
||||
import { LogicalExpressionFunctionNode } from '../../../custom-nodes/control-flow-replacers-nodes/logical-expression-control-flow-replacer-nodes/LogicalExpressionFunctionNode';
|
||||
import { NodeCallsControllerFunctionNode } from '../../../custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode';
|
||||
import { SelfDefendingUnicodeNode } from '../../../custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode';
|
||||
@@ -36,8 +38,12 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
|
||||
.whenTargetNamed(CustomNodes.BinaryExpressionFunctionNode);
|
||||
|
||||
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
|
||||
.toConstructor(ControlFlowStorageCallNode)
|
||||
.whenTargetNamed(CustomNodes.ControlFlowStorageCallNode);
|
||||
.toConstructor(CallExpressionControlFlowStorageCallNode)
|
||||
.whenTargetNamed(CustomNodes.CallExpressionControlFlowStorageCallNode);
|
||||
|
||||
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
|
||||
.toConstructor(CallExpressionFunctionNode)
|
||||
.whenTargetNamed(CustomNodes.CallExpressionFunctionNode);
|
||||
|
||||
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
|
||||
.toConstructor(ControlFlowStorageNode)
|
||||
@@ -63,6 +69,10 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
|
||||
.toConstructor(DomainLockNode)
|
||||
.whenTargetNamed(CustomNodes.DomainLockNode);
|
||||
|
||||
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
|
||||
.toConstructor(ExpressionWithOperatorControlFlowStorageCallNode)
|
||||
.whenTargetNamed(CustomNodes.ExpressionWithOperatorControlFlowStorageCallNode);
|
||||
|
||||
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
|
||||
.toConstructor(LogicalExpressionFunctionNode)
|
||||
.whenTargetNamed(CustomNodes.LogicalExpressionFunctionNode);
|
||||
|
||||
@@ -6,6 +6,7 @@ import { IControlFlowReplacer } from '../../../interfaces/node-transformers/ICon
|
||||
import { NodeControlFlowReplacers } from '../../../enums/container/NodeControlFlowReplacers';
|
||||
|
||||
import { BinaryExpressionControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer';
|
||||
import { CallExpressionControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer';
|
||||
import { LogicalExpressionControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer';
|
||||
|
||||
export const nodeControlFlowTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
|
||||
@@ -13,6 +14,10 @@ export const nodeControlFlowTransformersModule: interfaces.ContainerModule = new
|
||||
.to(BinaryExpressionControlFlowReplacer)
|
||||
.whenTargetNamed(NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer);
|
||||
|
||||
bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
|
||||
.to(CallExpressionControlFlowReplacer)
|
||||
.whenTargetNamed(NodeControlFlowReplacers.CallExpressionControlFlowReplacer);
|
||||
|
||||
bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
|
||||
.to(LogicalExpressionControlFlowReplacer)
|
||||
.whenTargetNamed(NodeControlFlowReplacers.LogicalExpressionControlFlowReplacer);
|
||||
|
||||
@@ -51,7 +51,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
|
||||
*/
|
||||
protected getTemplate (): string {
|
||||
return format(ConsoleOutputDisableExpressionTemplate(), {
|
||||
consoleLogDisableFunctionName: RandomGeneratorUtils.getRandomVariableName(),
|
||||
consoleLogDisableFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
|
||||
const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNodes.ConsoleOutputDisableExpressionNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return [
|
||||
Nodes.getFunctionDeclarationNode(
|
||||
RandomGeneratorUtils.getRandomVariableName(1),
|
||||
RandomGeneratorUtils.getRandomVariableName(1, true, false),
|
||||
[
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TStatement } from '../../../types/node/TStatement';
|
||||
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
|
||||
import { initializable } from '../../../decorators/Initializable';
|
||||
|
||||
import { AbstractCustomNode } from '../../AbstractCustomNode';
|
||||
import { Nodes } from '../../../node/Nodes';
|
||||
import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
|
||||
|
||||
@injectable()
|
||||
export class CallExpressionFunctionNode extends AbstractCustomNode {
|
||||
/**
|
||||
* @type {(ESTree.Expression | ESTree.SpreadElement)[]}
|
||||
*/
|
||||
@initializable()
|
||||
private expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[];
|
||||
|
||||
/**
|
||||
* @param options
|
||||
*/
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expressionArguments
|
||||
*/
|
||||
public initialize (expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[]): void {
|
||||
this.expressionArguments = expressionArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const calleeIdentifier: ESTree.Identifier = Nodes.getIdentifierNode('callee');
|
||||
const params: ESTree.Identifier[] = [];
|
||||
const argumentsLength: number = this.expressionArguments.length;
|
||||
|
||||
for (let i: number = 0; i < argumentsLength; i++) {
|
||||
params.push(Nodes.getIdentifierNode(`param${i + 1}`));
|
||||
}
|
||||
|
||||
return [
|
||||
Nodes.getFunctionDeclarationNode(
|
||||
RandomGeneratorUtils.getRandomVariableName(1, true, false),
|
||||
[
|
||||
calleeIdentifier,
|
||||
...params
|
||||
],
|
||||
Nodes.getBlockStatementNode([
|
||||
Nodes.getReturnStatementNode(
|
||||
Nodes.getCallExpressionNode(
|
||||
calleeIdentifier,
|
||||
params
|
||||
)
|
||||
)
|
||||
])
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -43,7 +43,7 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode {
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return [
|
||||
Nodes.getFunctionDeclarationNode(
|
||||
RandomGeneratorUtils.getRandomVariableName(1),
|
||||
RandomGeneratorUtils.getRandomVariableName(1, true, false),
|
||||
[
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
import { Expression } from 'estree';
|
||||
|
||||
import { TStatement } from '../../types/node/TStatement';
|
||||
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
|
||||
import { initializable } from '../../decorators/Initializable';
|
||||
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { Nodes } from '../../node/Nodes';
|
||||
|
||||
@injectable()
|
||||
export class CallExpressionControlFlowStorageCallNode extends AbstractCustomNode {
|
||||
/**
|
||||
* @type {Expression}
|
||||
*/
|
||||
@initializable()
|
||||
private callee: Expression;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@initializable()
|
||||
private controlFlowStorageKey: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@initializable()
|
||||
private controlFlowStorageName: string;
|
||||
|
||||
/**
|
||||
* @type {(ESTree.Expression | ESTree.SpreadElement)[]}
|
||||
*/
|
||||
@initializable()
|
||||
private expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[];
|
||||
|
||||
/**
|
||||
* @param options
|
||||
*/
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param controlFlowStorageName
|
||||
* @param controlFlowStorageKey
|
||||
* @param callee
|
||||
* @param expressionArguments
|
||||
*/
|
||||
public initialize (
|
||||
controlFlowStorageName: string,
|
||||
controlFlowStorageKey: string,
|
||||
callee: Expression,
|
||||
expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[]
|
||||
): void {
|
||||
this.controlFlowStorageName = controlFlowStorageName;
|
||||
this.controlFlowStorageKey = controlFlowStorageKey;
|
||||
this.callee = callee;
|
||||
this.expressionArguments = expressionArguments;
|
||||
}
|
||||
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
return [
|
||||
Nodes.getExpressionStatementNode(
|
||||
Nodes.getCallExpressionNode(
|
||||
Nodes.getMemberExpressionNode(
|
||||
Nodes.getIdentifierNode(this.controlFlowStorageName),
|
||||
Nodes.getIdentifierNode(this.controlFlowStorageKey)
|
||||
),
|
||||
[
|
||||
this.callee,
|
||||
...this.expressionArguments
|
||||
]
|
||||
)
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -13,7 +13,7 @@ import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { Nodes } from '../../node/Nodes';
|
||||
|
||||
@injectable()
|
||||
export class ControlFlowStorageCallNode extends AbstractCustomNode {
|
||||
export class ExpressionWithOperatorControlFlowStorageCallNode extends AbstractCustomNode {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@@ -89,7 +89,7 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const debugProtectionFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
|
||||
const debugProtectionFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
|
||||
const debugProtectionFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.DebugProtectionFunctionNode);
|
||||
const debugProtectionFunctionCallNode: ICustomNode = this.customNodeFactory(CustomNodes.DebugProtectionFunctionCallNode);
|
||||
|
||||
@@ -55,7 +55,7 @@ export class DomainLockNode extends AbstractCustomNode {
|
||||
const [hiddenDomainsString, diff]: string[] = CryptUtils.hideString(domainsString, domainsString.length * 3);
|
||||
|
||||
return format(DomainLockNodeTemplate(), {
|
||||
domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(),
|
||||
domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
|
||||
diff: diff,
|
||||
domains: hiddenDomainsString,
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
|
||||
@@ -96,7 +96,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
|
||||
const domainLockNode: ICustomNode = this.customNodeFactory(CustomNodes.DomainLockNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
|
||||
|
||||
@@ -55,7 +55,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
|
||||
protected getTemplate (): string {
|
||||
return JavaScriptObfuscator.obfuscate(
|
||||
format(SelfDefendingTemplate(), {
|
||||
selfDefendingFunctionName: RandomGeneratorUtils.getRandomVariableName(),
|
||||
selfDefendingFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
}),
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
|
||||
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
|
||||
const selfDefendingUnicodeNode: ICustomNode = this.customNodeFactory(CustomNodes.SelfDefendingUnicodeNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
|
||||
|
||||
@@ -76,8 +76,8 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
* @returns {string}
|
||||
*/
|
||||
protected getTemplate (): string {
|
||||
const timesName: string = RandomGeneratorUtils.getRandomVariableName();
|
||||
const whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
|
||||
const timesName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
const whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
|
||||
|
||||
let code: string = '';
|
||||
|
||||
|
||||
Vendored
+1
@@ -6,6 +6,7 @@ declare module 'estree' {
|
||||
interface BaseNode {
|
||||
obfuscated?: boolean;
|
||||
parentNode?: ESTree.Node;
|
||||
skippedByControlFlow?: boolean;
|
||||
}
|
||||
|
||||
interface SimpleLiteral extends ESTree.BaseNode, ESTree.BaseExpression {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
export enum CustomNodes {
|
||||
BinaryExpressionFunctionNode,
|
||||
ControlFlowStorageCallNode,
|
||||
CallExpressionControlFlowStorageCallNode,
|
||||
CallExpressionFunctionNode,
|
||||
ControlFlowStorageNode,
|
||||
ConsoleOutputDisableExpressionNode,
|
||||
DebugProtectionFunctionCallNode,
|
||||
DebugProtectionFunctionIntervalNode,
|
||||
DebugProtectionFunctionNode,
|
||||
DomainLockNode,
|
||||
ExpressionWithOperatorControlFlowStorageCallNode,
|
||||
LogicalExpressionFunctionNode,
|
||||
NodeCallsControllerFunctionNode,
|
||||
SelfDefendingUnicodeNode,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export enum NodeControlFlowReplacers {
|
||||
BinaryExpressionControlFlowReplacer,
|
||||
CallExpressionControlFlowReplacer,
|
||||
LogicalExpressionControlFlowReplacer
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
|
||||
*/
|
||||
private static readonly controlFlowReplacersMap: Map <string, NodeControlFlowReplacers> = new Map([
|
||||
[NodeType.BinaryExpression, NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer],
|
||||
[NodeType.CallExpression, NodeControlFlowReplacers.CallExpressionControlFlowReplacer],
|
||||
[NodeType.LogicalExpression, NodeControlFlowReplacers.LogicalExpressionControlFlowReplacer]
|
||||
]);
|
||||
|
||||
|
||||
+1
-31
@@ -4,16 +4,12 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';
|
||||
import { TStatement } from '../../../types/node/TStatement';
|
||||
|
||||
import { IControlFlowReplacer } from '../../../interfaces/node-transformers/IControlFlowReplacer';
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
import { IStorage } from '../../../interfaces/storages/IStorage';
|
||||
|
||||
import { BinaryExpressionControlFlowReplacer } from './BinaryExpressionControlFlowReplacer';
|
||||
import { CustomNodes } from '../../../enums/container/CustomNodes';
|
||||
import { Node } from '../../../node/Node';
|
||||
import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
|
||||
|
||||
@injectable()
|
||||
@@ -73,32 +69,6 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
|
||||
*/
|
||||
public abstract replace (node: ESTree.Node, parentNode: ESTree.Node, controlFlowStorage: IStorage <ICustomNode>): ESTree.Node;
|
||||
|
||||
/**
|
||||
* @param controlFlowStorageId
|
||||
* @param storageKey
|
||||
* @param leftExpression
|
||||
* @param rightExpression
|
||||
* @returns {ESTree.Node}
|
||||
*/
|
||||
protected getControlFlowStorageCallNode (
|
||||
controlFlowStorageId: string,
|
||||
storageKey: string,
|
||||
leftExpression: ESTree.Expression,
|
||||
rightExpression: ESTree.Expression
|
||||
): ESTree.Node {
|
||||
const controlFlowStorageCallCustomNode: ICustomNode = this.customNodeFactory(CustomNodes.ControlFlowStorageCallNode);
|
||||
|
||||
controlFlowStorageCallCustomNode.initialize(controlFlowStorageId, storageKey, leftExpression, rightExpression);
|
||||
|
||||
const statementNode: TStatement = controlFlowStorageCallCustomNode.getNode()[0];
|
||||
|
||||
if (!statementNode || !Node.isExpressionStatementNode(statementNode)) {
|
||||
throw new Error(`\`controlFlowStorageCallNode.getNode()[0]\` should returns array with \`ExpressionStatement\` node`);
|
||||
}
|
||||
|
||||
return statementNode.expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param customNode
|
||||
* @param controlFlowStorage
|
||||
@@ -113,7 +83,7 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
|
||||
usingExistingIdentifierChance: number
|
||||
): string {
|
||||
const controlFlowStorageId: string = controlFlowStorage.getStorageId();
|
||||
const storageKeysById: Map<string, string[]> = BinaryExpressionControlFlowReplacer
|
||||
const storageKeysById: Map<string, string[]> = AbstractControlFlowReplacer
|
||||
.getStorageKeysByIdForCurrentStorage(this.replacerDataByControlFlowStorageId, controlFlowStorageId);
|
||||
const storageKeysForCurrentId: string[] | undefined = storageKeysById.get(replacerId);
|
||||
|
||||
|
||||
+2
-2
@@ -11,10 +11,10 @@ import { IStorage } from '../../../interfaces/storages/IStorage';
|
||||
|
||||
import { CustomNodes } from '../../../enums/container/CustomNodes';
|
||||
|
||||
import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
|
||||
import { ExpressionWithOperatorControlFlowReplacer } from './ExpressionWithOperatorControlFlowReplacer';
|
||||
|
||||
@injectable()
|
||||
export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
|
||||
export class BinaryExpressionControlFlowReplacer extends ExpressionWithOperatorControlFlowReplacer {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';
|
||||
import { TStatement } from '../../../types/node/TStatement';
|
||||
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
import { IStorage } from '../../../interfaces/storages/IStorage';
|
||||
|
||||
import { CustomNodes } from '../../../enums/container/CustomNodes';
|
||||
|
||||
import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
|
||||
import { Node } from '../../../node/Node';
|
||||
|
||||
@injectable()
|
||||
export class CallExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
private static readonly usingExistingIdentifierChance: number = 0.5;
|
||||
|
||||
/**
|
||||
* @param customNodeFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
super(customNodeFactory, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callExpressionNode
|
||||
* @param parentNode
|
||||
* @param controlFlowStorage
|
||||
* @returns {ESTree.Node}
|
||||
*/
|
||||
public replace (
|
||||
callExpressionNode: ESTree.CallExpression,
|
||||
parentNode: ESTree.Node,
|
||||
controlFlowStorage: IStorage <ICustomNode>
|
||||
): ESTree.Node {
|
||||
const callee: ESTree.Expression = <ESTree.Expression>callExpressionNode.callee;
|
||||
|
||||
if (!Node.isIdentifierNode(callee)) {
|
||||
return callExpressionNode;
|
||||
}
|
||||
|
||||
const replacerId: string = String(callExpressionNode.arguments.length);
|
||||
const callExpressionFunctionCustomNode: ICustomNode = this.customNodeFactory(CustomNodes.CallExpressionFunctionNode);
|
||||
const expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[] = callExpressionNode.arguments;
|
||||
|
||||
callExpressionFunctionCustomNode.initialize(expressionArguments);
|
||||
|
||||
const storageKey: string = this.insertCustomNodeToControlFlowStorage(
|
||||
callExpressionFunctionCustomNode,
|
||||
controlFlowStorage,
|
||||
replacerId,
|
||||
CallExpressionControlFlowReplacer.usingExistingIdentifierChance
|
||||
);
|
||||
|
||||
return this.getControlFlowStorageCallNode(
|
||||
controlFlowStorage.getStorageId(),
|
||||
storageKey,
|
||||
callee,
|
||||
expressionArguments
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param controlFlowStorageId
|
||||
* @param storageKey
|
||||
* @param callee
|
||||
* @param expressionArguments
|
||||
* @param arguments
|
||||
* @returns {ESTree.Node}
|
||||
*/
|
||||
protected getControlFlowStorageCallNode (
|
||||
controlFlowStorageId: string,
|
||||
storageKey: string,
|
||||
callee: ESTree.Expression,
|
||||
expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[]
|
||||
): ESTree.Node {
|
||||
const controlFlowStorageCallCustomNode: ICustomNode = this.customNodeFactory(
|
||||
CustomNodes.CallExpressionControlFlowStorageCallNode
|
||||
);
|
||||
|
||||
controlFlowStorageCallCustomNode.initialize(controlFlowStorageId, storageKey, callee, expressionArguments);
|
||||
|
||||
const statementNode: TStatement = controlFlowStorageCallCustomNode.getNode()[0];
|
||||
|
||||
if (!statementNode || !Node.isExpressionStatementNode(statementNode)) {
|
||||
throw new Error(`\`controlFlowStorageCallCustomNode.getNode()[0]\` should returns array with \`ExpressionStatement\` node`);
|
||||
}
|
||||
|
||||
return statementNode.expression;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';
|
||||
import { TStatement } from '../../../types/node/TStatement';
|
||||
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
|
||||
import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
|
||||
import { CustomNodes } from '../../../enums/container/CustomNodes';
|
||||
import { Node } from '../../../node/Node';
|
||||
|
||||
@injectable()
|
||||
export abstract class ExpressionWithOperatorControlFlowReplacer extends AbstractControlFlowReplacer {
|
||||
/**
|
||||
* @type {TCustomNodeFactory}
|
||||
*/
|
||||
protected readonly customNodeFactory: TCustomNodeFactory;
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
protected readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @type {Map<string, Map<string, string[]>>}
|
||||
*/
|
||||
protected readonly replacerDataByControlFlowStorageId: Map <string, Map<string, string[]>> = new Map();
|
||||
|
||||
/**
|
||||
* @param customNodeFactory
|
||||
* @param options
|
||||
*/
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
super(customNodeFactory, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param controlFlowStorageId
|
||||
* @param storageKey
|
||||
* @param leftExpression
|
||||
* @param rightExpression
|
||||
* @returns {ESTree.Node}
|
||||
*/
|
||||
protected getControlFlowStorageCallNode (
|
||||
controlFlowStorageId: string,
|
||||
storageKey: string,
|
||||
leftExpression: ESTree.Expression,
|
||||
rightExpression: ESTree.Expression
|
||||
): ESTree.Node {
|
||||
const controlFlowStorageCallCustomNode: ICustomNode = this.customNodeFactory(
|
||||
CustomNodes.ExpressionWithOperatorControlFlowStorageCallNode
|
||||
);
|
||||
|
||||
controlFlowStorageCallCustomNode.initialize(controlFlowStorageId, storageKey, leftExpression, rightExpression);
|
||||
|
||||
const statementNode: TStatement = controlFlowStorageCallCustomNode.getNode()[0];
|
||||
|
||||
if (!statementNode || !Node.isExpressionStatementNode(statementNode)) {
|
||||
throw new Error(`\`controlFlowStorageCallCustomNode.getNode()[0]\` should returns array with \`ExpressionStatement\` node`);
|
||||
}
|
||||
|
||||
return statementNode.expression;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -11,12 +11,12 @@ import { IStorage } from '../../../interfaces/storages/IStorage';
|
||||
|
||||
import { CustomNodes } from '../../../enums/container/CustomNodes';
|
||||
|
||||
import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
|
||||
import { ExpressionWithOperatorControlFlowReplacer } from './ExpressionWithOperatorControlFlowReplacer';
|
||||
import { Node } from '../../../node/Node';
|
||||
import { NodeUtils } from '../../../node/NodeUtils';
|
||||
|
||||
@injectable()
|
||||
export class LogicalExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
|
||||
export class LogicalExpressionControlFlowReplacer extends ExpressionWithOperatorControlFlowReplacer {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
|
||||
@@ -47,7 +47,7 @@ export class IdentifierReplacer extends AbstractReplacer implements IObfuscatorR
|
||||
*/
|
||||
public storeNames (nodeName: string, nodeIdentifier: number): void {
|
||||
if (!this.isReservedName(nodeName)) {
|
||||
this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, RandomGeneratorUtils.getRandomVariableName());
|
||||
this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, RandomGeneratorUtils.getRandomVariableName(6, true, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+50
-2
@@ -51,6 +51,23 @@ export class Nodes {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param label
|
||||
* @return {ESTree.BreakStatement}
|
||||
*/
|
||||
public static getBreakStatement (label?: ESTree.Identifier): ESTree.BreakStatement {
|
||||
const breakStatementNode: ESTree.BreakStatement = {
|
||||
type: NodeType.BreakStatement,
|
||||
obfuscated: false
|
||||
};
|
||||
|
||||
if (label) {
|
||||
breakStatementNode.label = label;
|
||||
}
|
||||
|
||||
return breakStatementNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param body
|
||||
* @returns {ESTree.CatchClause}
|
||||
@@ -71,7 +88,7 @@ export class Nodes {
|
||||
*/
|
||||
public static getCallExpressionNode (
|
||||
callee: ESTree.Expression,
|
||||
args: ESTree.Expression[] | ESTree.SpreadElement[] = []
|
||||
args: (ESTree.Expression | ESTree.SpreadElement)[] = []
|
||||
): ESTree.CallExpression {
|
||||
return {
|
||||
type: NodeType.CallExpression,
|
||||
@@ -202,7 +219,7 @@ export class Nodes {
|
||||
* @return {ESTree.MemberExpression}
|
||||
*/
|
||||
public static getMemberExpressionNode (
|
||||
object: ESTree.Identifier,
|
||||
object: ESTree.Expression | ESTree.Super,
|
||||
property: ESTree.Identifier|ESTree.Literal,
|
||||
computed: boolean = false
|
||||
): ESTree.MemberExpression {
|
||||
@@ -279,6 +296,37 @@ export class Nodes {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param discriminant
|
||||
* @param cases
|
||||
* @returns {ESTree.SwitchStatement}
|
||||
*/
|
||||
public static getSwitchStatementNode (
|
||||
discriminant: ESTree.Expression,
|
||||
cases: ESTree.SwitchCase[]
|
||||
): ESTree.SwitchStatement {
|
||||
return {
|
||||
type: NodeType.SwitchStatement,
|
||||
discriminant,
|
||||
cases,
|
||||
obfuscated: false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param test
|
||||
* @param consequent
|
||||
* @returns {ESTree.SwitchCase}
|
||||
*/
|
||||
public static getSwitchCaseNode (test: ESTree.Expression, consequent: ESTree.Statement[]): ESTree.SwitchCase {
|
||||
return {
|
||||
type: NodeType.SwitchCase,
|
||||
test,
|
||||
consequent,
|
||||
obfuscated: false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param declarations
|
||||
* @param kind
|
||||
|
||||
@@ -18,7 +18,7 @@ export class StringArrayStorage extends ArrayStorage <string> {
|
||||
public initialize (...args: any[]): void {
|
||||
super.initialize(args);
|
||||
|
||||
this.storageId = RandomGeneratorUtils.getRandomVariableName(4, false);
|
||||
this.storageId = RandomGeneratorUtils.getRandomVariableName(4, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,11 @@ export class RandomGeneratorUtils {
|
||||
*/
|
||||
public static readonly randomGeneratorPoolWithNumbers: string = `${RandomGeneratorUtils.randomGeneratorPool}0123456789`;
|
||||
|
||||
/**
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
public static randomVariableNameSet: Set <string> = new Set();
|
||||
|
||||
/**
|
||||
* @type {Chance.Chance | Chance.SeededChance}
|
||||
*/
|
||||
@@ -68,18 +73,26 @@ export class RandomGeneratorUtils {
|
||||
/**
|
||||
* @param length
|
||||
* @param withPrefix
|
||||
* @param unique
|
||||
* @returns {string}
|
||||
*/
|
||||
public static getRandomVariableName (length: number = 6, withPrefix: boolean = true): string {
|
||||
public static getRandomVariableName (length: number, withPrefix: boolean, unique: boolean): string {
|
||||
const prefix: string = withPrefix ? `_${Utils.hexadecimalPrefix}` : '';
|
||||
const rangeMinInteger: number = 10000;
|
||||
const rangeMaxInteger: number = 99999999;
|
||||
|
||||
return `${prefix}${(
|
||||
const randomVariableName: string = `${prefix}${(
|
||||
Utils.decToHex(
|
||||
RandomGeneratorUtils.getRandomInteger(rangeMinInteger, rangeMaxInteger)
|
||||
)
|
||||
).substr(0, length)}`;
|
||||
|
||||
if (unique && RandomGeneratorUtils.randomVariableNameSet.has(randomVariableName)) {
|
||||
return RandomGeneratorUtils.getRandomVariableName(length, withPrefix, unique);
|
||||
}
|
||||
|
||||
RandomGeneratorUtils.randomVariableNameSet.add(randomVariableName);
|
||||
|
||||
return randomVariableName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-30
@@ -49,41 +49,12 @@ if (!(<any>global)._babelPolyfill) {
|
||||
|
||||
return abc.item = 15, test1();
|
||||
};
|
||||
|
||||
var regexptest = /version\\/(\\d+)/i;
|
||||
console.log(regexptest);
|
||||
|
||||
test2(22);
|
||||
console.log(105.4);
|
||||
console.log(true, false);
|
||||
|
||||
var sA = 'shorthand1';
|
||||
var sB = 'shorthand2';
|
||||
|
||||
console.log({sA, sB});
|
||||
|
||||
try {
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
function foo () {
|
||||
return function () {
|
||||
var sum1 = 10 + 20;
|
||||
var sum2 = 20 + 30;
|
||||
var sum3 = 30 + 50;
|
||||
var sub = sum3 - sum2;
|
||||
|
||||
return sum1 + sub;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(foo()());
|
||||
})();
|
||||
`,
|
||||
{
|
||||
compact: false,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1,
|
||||
disableConsoleOutput: false
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
(function () {
|
||||
function sum (a, b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
var variable = sum(1, 2);
|
||||
})();
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
(function () {
|
||||
function sum (a, b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
var variable1 = sum(1, 2);
|
||||
var variable2 = sum(2, 3);
|
||||
})();
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
(function () {
|
||||
var object = {
|
||||
sum: function (a, b) {
|
||||
return a + b;
|
||||
}
|
||||
};
|
||||
|
||||
var variable = object.sum(1, 2);
|
||||
})();
|
||||
@@ -152,9 +152,12 @@ describe('JavaScriptObfuscator', () => {
|
||||
const obfuscationResult1: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code, { seed: seed }
|
||||
);
|
||||
RandomGeneratorUtils.randomVariableNameSet.clear();
|
||||
|
||||
const obfuscationResult2: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code, { seed: seed }
|
||||
);
|
||||
RandomGeneratorUtils.randomVariableNameSet.clear();
|
||||
|
||||
assert.equal(obfuscationResult1.getObfuscatedCode(), obfuscationResult2.getObfuscatedCode());
|
||||
});
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { IObfuscationResult } from '../../../../../src/interfaces/IObfuscationResult';
|
||||
|
||||
import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
|
||||
|
||||
import { readFileAsString } from '../../../../helpers/readFileAsString';
|
||||
|
||||
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
|
||||
|
||||
describe('CallExpressionControlFlowReplacer', () => {
|
||||
describe('replace (callExpressionNode: ESTree.CallExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
|
||||
describe('variant #1 - single call expression', () => {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(
|
||||
'./test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/call-expression-control-flow-replacer-1.js'
|
||||
),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(_0x([a-z0-9]){4,6}, *0x1, *0x2\);/;
|
||||
|
||||
it('should replace call expression node by call to control flow storage node', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #2 - multiple call expressions with threshold = 1', () => {
|
||||
it('should replace call expression node by call to control flow storage node', function () {
|
||||
this.timeout(4000);
|
||||
|
||||
const samplesCount: number = 200;
|
||||
const expectedValue: number = 0.5;
|
||||
const delta: number = 0.1;
|
||||
|
||||
let equalsValue: number = 0;
|
||||
|
||||
for (let i = 0; i < samplesCount; i++) {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(
|
||||
'./test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/call-expression-control-flow-replacer-2.js'
|
||||
),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-z0-9]){4,6}, *0x1, *0x2\);/;
|
||||
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-z0-9]){4,6}, *0x2, *0x3\);/;
|
||||
|
||||
const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
|
||||
const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
|
||||
|
||||
const firstMatch: string | undefined = firstMatchArray ? firstMatchArray[2] : undefined;
|
||||
const secondMatch: string | undefined = secondMatchArray ? secondMatchArray[2] : undefined;
|
||||
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp1);
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp2);
|
||||
assert.isOk(firstMatch);
|
||||
assert.isOk(secondMatch);
|
||||
|
||||
if (firstMatch === secondMatch) {
|
||||
equalsValue++;
|
||||
}
|
||||
}
|
||||
|
||||
assert.closeTo(equalsValue / samplesCount, expectedValue, delta);
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #3 - callee - member expression', () => {
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
readFileAsString(
|
||||
'./test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/call-expression-control-flow-replacer-3.js'
|
||||
),
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
);
|
||||
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
|
||||
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['\\x73\\x75\\x6d'\]\(0x1, *0x2\);/;
|
||||
|
||||
it('shouldn\'t replace call expression node by call to control flow storage node if call expression callee is member expression node', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -32,6 +32,7 @@ import './functional-tests/custom-nodes/string-array-nodes/StringArrayRotateFunc
|
||||
import './functional-tests/custom-nodes/string-array-nodes/StringArrayNode.spec';
|
||||
import './functional-tests/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.spec';
|
||||
import './functional-tests/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.spec';
|
||||
import './functional-tests/node-transformers/node-control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer.spec';
|
||||
import './functional-tests/node-transformers/node-control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer.spec';
|
||||
import './functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec';
|
||||
import './functional-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec';
|
||||
|
||||
@@ -5,8 +5,8 @@ import { RandomGeneratorUtils } from '../../../src/utils/RandomGeneratorUtils';
|
||||
describe('RandomGeneratorUtils', () => {
|
||||
describe('getRandomVariableName (length: number = 6): string', () => {
|
||||
it('should return a string of given length with random variable name', () => {
|
||||
assert.match(RandomGeneratorUtils.getRandomVariableName(4), /^_0x(\w){4}$/);
|
||||
assert.match(RandomGeneratorUtils.getRandomVariableName(6), /^_0x(\w){4,6}$/);
|
||||
assert.match(RandomGeneratorUtils.getRandomVariableName(4, true, false), /^_0x(\w){4}$/);
|
||||
assert.match(RandomGeneratorUtils.getRandomVariableName(6, true, true), /^_0x(\w){4,6}$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user