X Tutup
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Change Log

v1.5.1
---
* Fixed runtime error when `IfStatement` contains only single `let` or `const` variable declaration when `simlify` option enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/661
* Fixed wrong `source-map: 'inline'` encoding after `1.3.0`

v1.5.0
---
* New `mangled-shuffled` identifier names generator based on `mangled` identifier names generator
Expand Down
14 changes: 7 additions & 7 deletions 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.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "1.5.0",
"version": "1.5.1",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand Down
5 changes: 5 additions & 0 deletions src/constants/Base64Alphabet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { alphabetStringUppercase } from './AlphabetStringUppercase';
import { alphabetString } from './AlphabetString';
import { numbersString } from './NumbersString';

export const base64alphabet: string = `${alphabetStringUppercase}${alphabetString}${numbersString}+/=`;
8 changes: 8 additions & 0 deletions src/constants/Base64AlphabetSwapped.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { alphabetStringUppercase } from './AlphabetStringUppercase';
import { alphabetString } from './AlphabetString';
import { numbersString } from './NumbersString';

/**
* Swapped lowercase and uppercase groups of alphabet to prevent easy decode
*/
export const base64alphabetSwapped: string = `${alphabetString}${alphabetStringUppercase}${numbersString}+/=`;
1 change: 1 addition & 0 deletions src/container/ServiceIdentifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export enum ServiceIdentifiers {
ICodeTransformerNamesGroupsBuilder = 'ICodeTransformerNamesGroupsBuilder',
ICodeTransformersRunner = 'ICodeTransformersRunner',
ICryptUtils = 'ICryptUtils',
ICryptUtilsSwappedAlphabet = 'ICryptUtilsSwappedAlphabet',
ICustomCodeHelper = 'ICustomCodeHelper',
ICustomCodeHelperGroup = 'ICustomCodeHelperGroup',
IControlFlowReplacer = 'IControlFlowReplacer',
Expand Down
7 changes: 7 additions & 0 deletions src/container/modules/utils/UtilsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers';

import { IArrayUtils } from '../../../interfaces/utils/IArrayUtils';
import { ICryptUtils } from '../../../interfaces/utils/ICryptUtils';
import { ICryptUtilsSwappedAlphabet } from '../../../interfaces/utils/ICryptUtilsSwappedAlphabet';
import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenceEncoder';
import { ILevelledTopologicalSorter } from '../../../interfaces/utils/ILevelledTopologicalSorter';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';

import { ArrayUtils } from '../../../utils/ArrayUtils';
import { CryptUtils } from '../../../utils/CryptUtils';
import { CryptUtilsSwappedAlphabet } from '../../../utils/CryptUtilsSwappedAlphabet';
import { EscapeSequenceEncoder } from '../../../utils/EscapeSequenceEncoder';
import { LevelledTopologicalSorter } from '../../../utils/LevelledTopologicalSorter';
import { RandomGenerator } from '../../../utils/RandomGenerator';
Expand All @@ -29,6 +31,11 @@ export const utilsModule: interfaces.ContainerModule = new ContainerModule((bind
.to(CryptUtils)
.inSingletonScope();

// crypt utils with swapped alphabet
bind<ICryptUtilsSwappedAlphabet>(ServiceIdentifiers.ICryptUtilsSwappedAlphabet)
.to(CryptUtilsSwappedAlphabet)
.inSingletonScope();

// escape sequence encoder
bind<IEscapeSequenceEncoder>(ServiceIdentifiers.IEscapeSequenceEncoder)
.to(EscapeSequenceEncoder)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { alphabetStringUppercase } from '../../../../constants/AlphabetStringUppercase';
import { alphabetString } from '../../../../constants/AlphabetString';
import { numbersString } from '../../../../constants/NumbersString';
import { base64alphabetSwapped } from '../../../../constants/Base64AlphabetSwapped';

/**
* @returns {string}
*/
export function AtobTemplate (): string {
// swapped lowercase and uppercase groups of alphabet to prevent easy decode!!!!
return `
var {atobFunctionName} = function (input) {
const chars = '${alphabetString}${alphabetStringUppercase}${numbersString}+/=';
const chars = '${base64alphabetSwapped}';

const str = String(input).replace(/=+$/, '');
let output = '';
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/utils/ICryptUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface ICryptUtils {
/**
* @param string
* @param {string} string
* @returns {string}
*/
btoa (string: string): string;

Expand Down
4 changes: 4 additions & 0 deletions src/interfaces/utils/ICryptUtilsSwappedAlphabet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
import { ICryptUtils } from './ICryptUtils';

export interface ICryptUtilsSwappedAlphabet extends ICryptUtils {}
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,9 @@ export class IfStatementSimplifyTransformer extends AbstractNodeTransformer {
* @returns {boolean}
*/
private isProhibitedSingleStatementForIfStatementBranch (statement: ESTree.Statement): boolean {
// TODO: write tests
// function declaration is not allowed outside of block in `strict` mode
/**
* Function declaration is not allowed outside of block in `strict` mode
*/
return NodeGuards.isFunctionDeclarationNode(statement)
/**
* Without ignore it can break following code:
Expand All @@ -443,6 +444,19 @@ export class IfStatementSimplifyTransformer extends AbstractNodeTransformer {
* else
* var baz = bark();
*/
|| NodeGuards.isIfStatementNode(statement);
|| NodeGuards.isIfStatementNode(statement)

/**
* `let` and `const` variable declarations are not allowed outside of `IfStatement` block statement
* Input:
* if (condition1) {
* const foo = 1;
* }
*
* Invalid output with runtime error:
* if (condition1)
* const foo = 1;
*/
|| (NodeGuards.isVariableDeclarationNode(statement) && statement.kind !== 'var');
}
}
16 changes: 8 additions & 8 deletions src/storages/string-array/StringArrayStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TIdentifierNamesGeneratorFactory } from '../../types/container/generato
import { IIdentifierNamesGenerator } from '../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';

import { IArrayUtils } from '../../interfaces/utils/IArrayUtils';
import { ICryptUtils } from '../../interfaces/utils/ICryptUtils';
import { ICryptUtilsSwappedAlphabet } from '../../interfaces/utils/ICryptUtilsSwappedAlphabet';
import { IEncodedValue } from '../../interfaces/IEncodedValue';
import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
import { IOptions } from '../../interfaces/options/IOptions';
Expand Down Expand Up @@ -50,9 +50,9 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
private readonly arrayUtils: IArrayUtils;

/**
* @type {ICryptUtils}
* @type {ICryptUtilsSwappedAlphabet}
*/
private readonly cryptUtils: ICryptUtils;
private readonly cryptUtilsSwappedAlphabet: ICryptUtilsSwappedAlphabet;

/**
* @type {IEscapeSequenceEncoder}
Expand Down Expand Up @@ -94,7 +94,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
* @param {IArrayUtils} arrayUtils
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
* @param {ICryptUtils} cryptUtils
* @param {ICryptUtilsSwappedAlphabet} cryptUtilsSwappedAlphabet
* @param {IEscapeSequenceEncoder} escapeSequenceEncoder
*/
public constructor (
Expand All @@ -103,14 +103,14 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
@inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions,
@inject(ServiceIdentifiers.ICryptUtils) cryptUtils: ICryptUtils,
@inject(ServiceIdentifiers.ICryptUtilsSwappedAlphabet) cryptUtilsSwappedAlphabet: ICryptUtilsSwappedAlphabet,
@inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder
) {
super(randomGenerator, options);

this.identifierNamesGenerator = identifierNamesGeneratorFactory(options);
this.arrayUtils = arrayUtils;
this.cryptUtils = cryptUtils;
this.cryptUtilsSwappedAlphabet = cryptUtilsSwappedAlphabet;
this.escapeSequenceEncoder = escapeSequenceEncoder;

this.rc4Keys = this.randomGenerator.getRandomGenerator()
Expand Down Expand Up @@ -275,7 +275,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
*/
case StringArrayEncoding.Rc4: {
const decodeKey: string = this.randomGenerator.getRandomGenerator().pickone(this.rc4Keys);
const encodedValue: string = this.cryptUtils.btoa(this.cryptUtils.rc4(value, decodeKey));
const encodedValue: string = this.cryptUtilsSwappedAlphabet.btoa(this.cryptUtilsSwappedAlphabet.rc4(value, decodeKey));

const encodedValueSources: string[] = this.rc4EncodedValuesSourcesCache.get(encodedValue) ?? [];
let encodedValueSourcesLength: number = encodedValueSources.length;
Expand All @@ -298,7 +298,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI

case StringArrayEncoding.Base64: {
const decodeKey: null = null;
const encodedValue: string = this.cryptUtils.btoa(value);
const encodedValue: string = this.cryptUtilsSwappedAlphabet.btoa(value);

return { encodedValue, decodeKey };
}
Expand Down
12 changes: 7 additions & 5 deletions src/utils/CryptUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { ICryptUtils } from '../interfaces/utils/ICryptUtils';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';

import { alphabetStringUppercase } from '../constants/AlphabetStringUppercase';
import { alphabetString } from '../constants/AlphabetString';
import { numbersString } from '../constants/NumbersString';
import { base64alphabet } from '../constants/Base64Alphabet';

import { RandomGenerator } from './RandomGenerator';
import { Utils } from './Utils';

@injectable()
export class CryptUtils implements ICryptUtils {
/**
* @type {string}
*/
protected readonly base64Alphabet: string = base64alphabet;

/**
* @type {IRandomGenerator}
*/
Expand All @@ -32,8 +35,7 @@ export class CryptUtils implements ICryptUtils {
* @returns {string}
*/
public btoa (string: string): string {
// swapped lowercase and uppercase groups of alphabet to prevent easy decode!!!!
const chars: string = `${alphabetString}${alphabetStringUppercase}${numbersString}+/=`;
const chars: string = this.base64Alphabet;

let output: string = '';

Expand Down
26 changes: 26 additions & 0 deletions src/utils/CryptUtilsSwappedAlphabet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';

import { ICryptUtilsSwappedAlphabet } from '../interfaces/utils/ICryptUtilsSwappedAlphabet';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';

import { base64alphabetSwapped } from '../constants/Base64AlphabetSwapped';

import { CryptUtils } from './CryptUtils';

@injectable()
export class CryptUtilsSwappedAlphabet extends CryptUtils implements ICryptUtilsSwappedAlphabet {
/**
* @type {string}
*/
protected readonly base64Alphabet: string = base64alphabetSwapped;

/**
* @param {IRandomGenerator} randomGenerator
*/
public constructor (
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator
) {
super(randomGenerator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { assert } from 'chai';

import { ServiceIdentifiers } from '../../../../../../src/container/ServiceIdentifiers';

import { ICryptUtils } from '../../../../../../src/interfaces/utils/ICryptUtils';
import { ICryptUtilsSwappedAlphabet } from '../../../../../../src/interfaces/utils/ICryptUtilsSwappedAlphabet';
import { IInversifyContainerFacade } from '../../../../../../src/interfaces/container/IInversifyContainerFacade';
import { IObfuscatedCode } from '../../../../../../src/interfaces/source-code/IObfuscatedCode';
import { IRandomGenerator } from '../../../../../../src/interfaces/utils/IRandomGenerator';
Expand All @@ -28,15 +28,17 @@ describe('StringArrayCallsWrapperTemplate', () => {
const stringArrayCallsWrapperName: string = 'stringArrayCallsWrapperName';
const atobFunctionName: string = 'atob';

let cryptUtils: ICryptUtils,
let cryptUtilsSwappedAlphabet: ICryptUtilsSwappedAlphabet,
randomGenerator: IRandomGenerator;

before(() => {
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();

inversifyContainerFacade.load('', '', {});
cryptUtils = inversifyContainerFacade.get<ICryptUtils>(ServiceIdentifiers.ICryptUtils);
randomGenerator = inversifyContainerFacade.get<IRandomGenerator>(ServiceIdentifiers.IRandomGenerator);
cryptUtilsSwappedAlphabet = inversifyContainerFacade
.get<ICryptUtilsSwappedAlphabet>(ServiceIdentifiers.ICryptUtilsSwappedAlphabet);
randomGenerator = inversifyContainerFacade
.get<IRandomGenerator>(ServiceIdentifiers.IRandomGenerator);
});

describe('Variant #1: `base64` encoding', () => {
Expand Down Expand Up @@ -65,7 +67,7 @@ describe('StringArrayCallsWrapperTemplate', () => {
});

decodedValue = Function(`
var ${stringArrayName} = ['${cryptUtils.btoa('test1')}'];
var ${stringArrayName} = ['${cryptUtilsSwappedAlphabet.btoa('test1')}'];

${stringArrayCallsWrapperTemplate}

Expand Down Expand Up @@ -108,7 +110,7 @@ describe('StringArrayCallsWrapperTemplate', () => {
});

decodedValue = Function(`
var ${stringArrayName} = ['${cryptUtils.btoa(cryptUtils.rc4('test1', key))}'];
var ${stringArrayName} = ['${cryptUtilsSwappedAlphabet.btoa(cryptUtilsSwappedAlphabet.rc4('test1', key))}'];

${stringArrayCallsWrapperTemplate}

Expand Down
Loading
X Tutup