Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Change Log

v2.10.0
---
* Improved `rotateStringArray` option

v2.9.6
---
* Preventing move of `"use strict";` directive during obfuscation
Expand Down
2 changes: 1 addition & 1 deletion dist/index.browser.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.cli.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "2.9.6",
"version": "2.10.0",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand Down Expand Up @@ -62,8 +62,8 @@
"@types/sinon": "9.0.10",
"@types/string-template": "1.0.2",
"@types/webpack-env": "1.16.0",
"@typescript-eslint/eslint-plugin": "4.11.0",
"@typescript-eslint/parser": "4.11.0",
"@typescript-eslint/eslint-plugin": "4.11.1",
"@typescript-eslint/parser": "4.11.1",
"chai": "4.2.0",
"chai-exclude": "2.0.2",
"cross-env": "7.0.3",
Expand All @@ -85,7 +85,7 @@
"ts-loader": "8.0.12",
"ts-node": "9.1.1",
"typescript": "4.1.3",
"webpack": "5.11.0",
"webpack": "5.11.1",
"webpack-cli": "4.3.0",
"webpack-node-externals": "2.5.2"
},
Expand Down
1 change: 1 addition & 0 deletions src/JavaScriptObfuscator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
NodeTransformer.ParentificationTransformer,
NodeTransformer.ScopeIdentifiersTransformer,
NodeTransformer.SplitStringTransformer,
NodeTransformer.StringArrayRotateFunctionTransformer,
NodeTransformer.StringArrayScopeCallsWrapperTransformer,
NodeTransformer.StringArrayTransformer,
NodeTransformer.TemplateLiteralTransformer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class NumberNumericalExpressionAnalyzer implements INumberNumericalExpres
/**
* @type {number}
*/
private static readonly additionalParts: number = 3;
public static readonly defaultAdditionalPartsCount: number = 3;

/**
* @type {Map<number, number[]>}
Expand All @@ -40,9 +40,13 @@ export class NumberNumericalExpressionAnalyzer implements INumberNumericalExpres

/**
* @param {number} number
* @param {number} additionalPartsCount
* @returns {TNumberNumericalExpressionData}
*/
public analyze (number: number): TNumberNumericalExpressionData {
public analyze (
number: number,
additionalPartsCount: number
): TNumberNumericalExpressionData {
if (isNaN(number)) {
throw new Error('Given value is NaN');
}
Expand All @@ -51,16 +55,17 @@ export class NumberNumericalExpressionAnalyzer implements INumberNumericalExpres
return [number];
}

const additionParts: number[] = this.generateAdditionParts(number);
const additionParts: number[] = this.generateAdditionParts(number, additionalPartsCount);

return additionParts.map((addition: number) => this.mixWithMultiplyParts(addition));
}

/**
* @param {number} number
* @param {number} additionalPartsCount
* @returns {number[]}
*/
private generateAdditionParts (number: number): number[] {
private generateAdditionParts (number: number, additionalPartsCount: number): number[] {
const additionParts = [];

const upperNumberLimit: number = Math.min(Math.abs(number * 2), Number.MAX_SAFE_INTEGER);
Expand All @@ -70,8 +75,8 @@ export class NumberNumericalExpressionAnalyzer implements INumberNumericalExpres

let temporarySum = 0;

for (let i = 0; i < NumberNumericalExpressionAnalyzer.additionalParts; i++) {
if (i < NumberNumericalExpressionAnalyzer.additionalParts - 1) {
for (let i = 0; i < additionalPartsCount; i++) {
if (i < additionalPartsCount - 1) {
// trailing parts

let addition: number = this.randomGenerator.getRandomInteger(from, to);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,11 @@ export class StringArrayStorageAnalyzer implements IStringArrayStorageAnalyzer {
});
}

/**
* @param {Literal} literalNode
* @returns {IStringArrayStorageItemData | undefined}
*/
public getItemDataForLiteralNode (literalNode: ESTree.Literal): IStringArrayStorageItemData | undefined {
return this.stringArrayStorageData.get(literalNode);
}

/**
* @param {Literal} literalNode
* @param {Node} parentNode
*/
private analyzeLiteralNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void {
public analyzeLiteralNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void {
if (!NodeLiteralUtils.isStringLiteralNode(literalNode)) {
return;
}
Expand All @@ -111,12 +103,27 @@ export class StringArrayStorageAnalyzer implements IStringArrayStorageAnalyzer {
return;
}

this.addItemDataForLiteralNode(literalNode);
}

/**
* @param {(SimpleLiteral & {value: string}) | (RegExpLiteral & {value: string})} literalNode
*/
public addItemDataForLiteralNode (literalNode: ESTree.Literal & {value: string}): void {
this.stringArrayStorageData.set(
literalNode,
this.stringArrayStorage.getOrThrow(literalNode.value)
);
}

/**
* @param {Literal} literalNode
* @returns {IStringArrayStorageItemData | undefined}
*/
public getItemDataForLiteralNode (literalNode: ESTree.Literal): IStringArrayStorageItemData | undefined {
return this.stringArrayStorageData.get(literalNode);
}

/**
* @param {(SimpleLiteral & {value: string})} literalNode
* @returns {boolean}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTra

import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';

import { StringArrayRotateFunctionTransformer } from '../../../node-transformers/string-array-transformers/StringArrayRotateFunctionTransformer';
import { StringArrayScopeCallsWrapperTransformer } from '../../../node-transformers/string-array-transformers/StringArrayScopeCallsWrapperTransformer';
import { StringArrayTransformer } from '../../../node-transformers/string-array-transformers/StringArrayTransformer';

export const stringArrayTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// strings transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(StringArrayRotateFunctionTransformer)
.whenTargetNamed(NodeTransformer.StringArrayRotateFunctionTransformer);

bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(StringArrayScopeCallsWrapperTransformer)
.whenTargetNamed(NodeTransformer.StringArrayScopeCallsWrapperTransformer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class StringArrayCallsWrapperBase64CodeHelper extends StringArrayCallsWra
atobPolyfill,
atobFunctionName,
selfDefendingCode,
stringArrayName: this.stringArrayName,
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class StringArrayCallsWrapperRc4CodeHelper extends StringArrayCallsWrappe
atobPolyfill,
rc4Polyfill,
selfDefendingCode,
stringArrayName: this.stringArrayName,
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
}
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Expression } from 'estree';
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';

Expand All @@ -6,54 +7,50 @@ import { TStatement } from '../../types/node/TStatement';

import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';

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

import { SelfDefendingTemplate } from './templates/string-array-rotate-function/SelfDefendingTemplate';
import { StringArrayRotateFunctionTemplate } from './templates/string-array-rotate-function/StringArrayRotateFunctionTemplate';

import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
import { NodeUtils } from '../../node/NodeUtils';
import { NumberUtils } from '../../utils/NumberUtils';

@injectable()
export class StringArrayRotateFunctionCodeHelper extends AbstractCustomCodeHelper {
/**
* @type {string}
* @type {number}
*/
@initializable()
private stringArrayName!: string;
private comparisonValue!: number;

/**
* @param {number}
* @type {Expression}
*/
@initializable()
private stringArrayRotationAmount!: number;
private comparisonExpressionNode!: Expression;

/**
* @type {IEscapeSequenceEncoder}
* @type {string}
*/
private readonly escapeSequenceEncoder: IEscapeSequenceEncoder;
@initializable()
private stringArrayName!: string;

/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
* @param {IEscapeSequenceEncoder} escapeSequenceEncoder
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions,
@inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(
identifierNamesGeneratorFactory,
Expand All @@ -62,20 +59,21 @@ export class StringArrayRotateFunctionCodeHelper extends AbstractCustomCodeHelpe
randomGenerator,
options
);

this.escapeSequenceEncoder = escapeSequenceEncoder;
}

/**
* @param {string} stringArrayName
* @param {number} stringArrayRotationAmount
* @param {number} comparisonValue
* @param {Expression} comparisonExpressionNode
*/
public initialize (
stringArrayName: string,
stringArrayRotationAmount: number
comparisonValue: number,
comparisonExpressionNode: Expression
): void {
this.stringArrayName = stringArrayName;
this.stringArrayRotationAmount = stringArrayRotationAmount;
this.comparisonValue = comparisonValue;
this.comparisonExpressionNode = comparisonExpressionNode;
}

/**
Expand All @@ -90,31 +88,14 @@ export class StringArrayRotateFunctionCodeHelper extends AbstractCustomCodeHelpe
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
const timesName: string = this.identifierNamesGenerator.generateNext();
const whileFunctionName: string = this.identifierNamesGenerator.generateNext();
const preservedNames: string[] = [`^${this.stringArrayName}$`];

let code: string = '';

if (this.options.selfDefending) {
code = this.customCodeHelperFormatter.formatTemplate(SelfDefendingTemplate(this.escapeSequenceEncoder), {
timesName,
whileFunctionName
});
} else {
code = `${whileFunctionName}(++${timesName})`;
}
const comparisonExpressionCode: string = NodeUtils.convertStructureToCode([this.comparisonExpressionNode]);

return this.customCodeHelperObfuscator.obfuscateTemplate(
this.customCodeHelperFormatter.formatTemplate(StringArrayRotateFunctionTemplate(), {
code,
timesName,
whileFunctionName,
stringArrayName: this.stringArrayName,
stringArrayRotationAmount: NumberUtils.toHex(this.stringArrayRotationAmount)
}),
return this.customCodeHelperFormatter.formatTemplate(
StringArrayRotateFunctionTemplate(),
{
reservedNames: preservedNames
comparisonExpressionCode,
comparisonValue: this.comparisonValue,
stringArrayName: this.stringArrayName
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { AbstractCustomCodeHelperGroup } from '../../AbstractCustomCodeHelperGro
import { NodeAppender } from '../../../node/NodeAppender';
import { StringArrayCallsWrapperCodeHelper } from '../StringArrayCallsWrapperCodeHelper';
import { StringArrayCodeHelper } from '../StringArrayCodeHelper';
import { StringArrayRotateFunctionCodeHelper } from '../StringArrayRotateFunctionCodeHelper';

@injectable()
export class StringArrayCodeHelperGroup extends AbstractCustomCodeHelperGroup {
Expand Down Expand Up @@ -102,14 +101,6 @@ export class StringArrayCodeHelperGroup extends AbstractCustomCodeHelperGroup {
}
);
}

// stringArrayRotateFunction helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.StringArrayRotateFunction,
(customCodeHelper: ICustomCodeHelper<TInitialData<StringArrayRotateFunctionCodeHelper>>) => {
NodeAppender.insertAtIndex(nodeWithStatements, customCodeHelper.getNode(), 1);
}
);
}

public initialize (): void {
Expand All @@ -133,7 +124,6 @@ export class StringArrayCodeHelperGroup extends AbstractCustomCodeHelperGroup {
const stringArrayCallsWrapperCodeHelper: ICustomCodeHelper<TInitialData<StringArrayCallsWrapperCodeHelper>> =
this.customCodeHelperFactory(stringArrayCallsWrapperCodeHelperName);
const stringArrayCallsWrapperName: string = this.stringArrayStorage.getStorageCallsWrapperName(stringArrayEncoding);

stringArrayCallsWrapperCodeHelper.initialize(
stringArrayName,
stringArrayCallsWrapperName,
Expand All @@ -142,19 +132,6 @@ export class StringArrayCodeHelperGroup extends AbstractCustomCodeHelperGroup {

this.customCodeHelpers.set(stringArrayCallsWrapperCodeHelperName, stringArrayCallsWrapperCodeHelper);
}

// stringArrayRotateFunction helper initialize
const stringArrayRotateFunctionCodeHelper: ICustomCodeHelper<TInitialData<StringArrayRotateFunctionCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.StringArrayRotateFunction);

stringArrayRotateFunctionCodeHelper.initialize(
stringArrayName,
this.stringArrayStorage.getRotationAmount()
);

if (this.options.rotateStringArray) {
this.customCodeHelpers.set(CustomCodeHelper.StringArrayRotateFunction, stringArrayRotateFunctionCodeHelper);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ export function StringArrayBase64DecodeTemplate (
{stringArrayCallsWrapperName}.${initializedIdentifier} = true;
}

const cachedValue = {stringArrayCallsWrapperName}.${dataIdentifier}[index];
const firstValue = {stringArrayName}[0];
const cacheKey = index + firstValue;
const cachedValue = {stringArrayCallsWrapperName}.${dataIdentifier}[cacheKey];

if (cachedValue === undefined) {
{selfDefendingCode}

value = {stringArrayCallsWrapperName}.${base64DecodeFunctionIdentifier}(value);
{stringArrayCallsWrapperName}.${dataIdentifier}[index] = value;
{stringArrayCallsWrapperName}.${dataIdentifier}[cacheKey] = value;
} else {
value = cachedValue;
}
Expand Down
Loading