Skip to content

Commit

Permalink
String array calls transform fix (#1050)
Browse files Browse the repository at this point in the history
* Fixed the wrong generation of code that has statements after `ReturnStatment` when `simplify` option is enabled

* Fixed generation of reserved identifier names like `Map` or `Set` for `mangled` and `mangled-shuffled` identifier names generators
  • Loading branch information
sanex3339 committed Feb 7, 2022
1 parent 77f64bf commit ec4b70f
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 25 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Change Log

v3.2.3
---
* Fixed missing transformation of string array calls in some cases
* Fixed generation of reserved identifier names like `Map` or `Set` for `mangled` and `mangled-shuffled` identifier names generators

v3.2.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1039
Expand Down
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": "3.2.2",
"version": "3.2.3",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand Down
File renamed without changes.
11 changes: 11 additions & 0 deletions src/constants/ReservedIdentifierNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const reservedIdentifierNames = [
// reserved identifiers
'byte', 'case', 'char', 'do', 'else', 'enum', 'eval', 'for', 'goto',
'if', 'in', 'int', 'let', 'long', 'new', 'null', 'this', 'true', 'try',
'var', 'void', 'with',

// reserved global object identifiers
'Array', 'Attr', 'Audio', 'Blob', 'Cache', 'Date', 'Error', 'Event',
'Feed', 'File', 'Hz', 'Image', 'Intl', 'Lock', 'Map', 'Math', 'Node',
'Proxy', 'Range', 'Rect', 'Set', 'Table', 'Text', 'Touch'
];
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ export abstract class AbstractIdentifierNamesGenerator implements IIdentifierNam
* @returns {boolean}
*/
public isValidIdentifierName (name: string): boolean {
return this.notReservedName(name) && !this.preservedNamesSet.has(name);
return !this.isReservedName(name)
&& !this.preservedNamesSet.has(name);
}

/**
Expand Down Expand Up @@ -112,12 +113,12 @@ export abstract class AbstractIdentifierNamesGenerator implements IIdentifierNam
* @param {string} name
* @returns {boolean}
*/
private notReservedName (name: string): boolean {
private isReservedName (name: string): boolean {
return this.options.reservedNames.length
? !this.options.reservedNames.some((reservedName: string) =>
? this.options.reservedNames.some((reservedName: string) =>
new RegExp(reservedName, 'g').exec(name) !== null
)
: true;
: false;

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ISetUtils } from '../../interfaces/utils/ISetUtils';

import { numbersString } from '../../constants/NumbersString';
import { alphabetString } from '../../constants/AlphabetString';
import { alphabetStringUppercase } from '../../constants/AlphabetStringUppercase';
import { numbersString } from '../../constants/NumbersString';
import { reservedIdentifierNames } from '../../constants/ReservedIdentifierNames';

import { AbstractIdentifierNamesGenerator } from './AbstractIdentifierNamesGenerator';
import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
Expand Down Expand Up @@ -40,14 +41,11 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene

/**
* Reserved JS words with length of 2-4 symbols that can be possible generated with this replacer
* + reserved DOM names like `Set`, `Map`, `Date`, etc
*
* @type {Set<string>}
*/
private static readonly reservedNamesSet: Set<string> = new Set([
'byte', 'case', 'char', 'do', 'else', 'enum', 'eval', 'for', 'goto',
'if', 'in', 'int', 'let', 'long', 'new', 'null', 'this', 'true', 'try',
'var', 'void', 'with'
]);
private static readonly reservedNamesSet: Set<string> = new Set(reservedIdentifierNames);

/**
* @type {WeakMap<string, string>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '../../types/container/node-transformers/TControlFlowStorageFactoryCreator';
import { TNodeWithStatements } from '../../types/node/TNodeWithStatements';

import { IControlFlowStorage } from '../../interfaces/storages/control-flow-transformers/IControlFlowStorage';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
Expand All @@ -23,7 +24,6 @@ import { NodeTransformer } from '../../enums/node-transformers/NodeTransformer';

import { FunctionControlFlowTransformer } from './FunctionControlFlowTransformer';
import { NodeGuards } from '../../node/NodeGuards';
import { IControlFlowStorage } from '../../interfaces/storages/control-flow-transformers/IControlFlowStorage';

@injectable()
export class StringArrayControlFlowTransformer extends FunctionControlFlowTransformer {
Expand Down Expand Up @@ -120,12 +120,20 @@ export class StringArrayControlFlowTransformer extends FunctionControlFlowTransf
&& this.controlFlowStorageNodes.has(node);

if (isControlFlowStorageNode) {
return estraverse.VisitorOption.Break;
return estraverse.VisitorOption.Skip;
}

return super.transformFunctionBodyNode(node, parentNode, functionNode, controlFlowStorage);
}

/**
* @param {TNodeWithStatements} hostNode
* @returns {TControlFlowStorage}
*/
protected override getControlFlowStorage (hostNode: TNodeWithStatements): IControlFlowStorage {
return this.controlFlowStorageFactory();
}

/**
* @param {TNodeWithStatements} hostNode
* @param {VariableDeclaration} controlFlowStorageNode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { IPropertyIdentifierNamesCacheStorage } from '../../../interfaces/storag
import { IRenamePropertiesReplacer } from '../../../interfaces/node-transformers/rename-properties-transformers/replacer/IRenamePropertiesReplacer';

// eslint-disable-next-line import/no-internal-modules
import ReservedDomProperties from './ReservedDomProperties.json';
import ReservedDomProperties from '../../../constants/ReservedDomProperties.json';

import { NodeGuards } from '../../../node/NodeGuards';
import { NodeFactory } from '../../../node/NodeFactory';
Expand Down
49 changes: 39 additions & 10 deletions test/dev/dev.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,55 @@
'use strict';

import { StringArrayWrappersType } from '../../src/enums/node-transformers/string-array-transformers/StringArrayWrappersType';

(function () {
const JavaScriptObfuscator: any = require('../../index');

let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
async function xyzzy(a,b)
{
if (a) {
return await foo(a) ;
console.log(a) ;
} else {
return await bar(b) ;
console.log(b) ;
function foo () {
function bar() {
var string1 = 'string1';
var string2 = 'string2';
var string3 = 'string3';
var string4 = 'string4';
var string5 = 'string5';
var string6 = 'string6';
function bark () {
var string1 = 'string1';
var string2 = 'string2';
var string3 = 'string3';
var string4 = 'string4';
var string5 = 'string5';
var string6 = 'string6';
}
}
bar()
}
console.log(foo());
`,
{
identifierNamesGenerator: 'mangled',
compact: false,
simplify: true,
stringArray: false
controlFlowFlattening: false,
controlFlowFlatteningThreshold: 1,
simplify: false,
stringArrayRotate: false,
stringArray: true,
stringArrayIndexesType: [
'hexadecimal-number',
'hexadecimal-numeric-string'
],
stringArrayThreshold: 1,
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 1,
rotateStringArray: true,
stringArrayWrappersType: StringArrayWrappersType.Function,
transformObjectKeys: false,
seed: 1
}
).getObfuscatedCode();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,43 @@ describe('StringArrayControlFlowTransformer', function () {
assert.match(obfuscatedCode, regexp);
});
});

describe('Variant #5 - multiple `control flow storages` on the same block scope', () => {
const regexp: RegExp = new RegExp(
`var ${hexadecimalVariableMatch} *= *\\{` +
`${hexadecimalVariableMatch} *: *0x0, *` +
`${hexadecimalVariableMatch} *: *0x1 *` +
`\\}; *` +
`var ${hexadecimalVariableMatch} *= *\\{` +

`${hexadecimalVariableMatch} *: *0x2, *` +
`${hexadecimalVariableMatch} *: *0x3 *` +
`\\};`
);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/multiple-storages-1.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1,
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 1
}
).getObfuscatedCode();

console.log(obfuscatedCode);
});

it('should add `control flow storage` node with multiple items to the obfuscated code', () => {
assert.match(obfuscatedCode, regexp);
});
});
});

describe('Variant #2 - negative cases', function () {
Expand Down Expand Up @@ -320,7 +357,7 @@ describe('StringArrayControlFlowTransformer', function () {
let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/multiple-storages.js');
const code: string = readFileAsString(__dirname + '/fixtures/multiple-storages-2.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(function () {
var variable1 = 'foo' + 'bar';

function foo (arg) {
var variable2 = 'baz' + 'bark';
}
})();
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,33 @@ describe('MangledShuffledIdentifierNamesGenerator', () => {
assert.isTrue(isSuccessComparison);
});
});

describe('isValidIdentifierName', () => {
describe('Variant #1: reserved dom property name', () => {
let identifierNamesGenerator: IIdentifierNamesGenerator,
isValidName1: boolean,
isValidName2: boolean,
isValidName3: boolean;

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

inversifyContainerFacade.load('', '', {} );
identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.MangledShuffledIdentifierNamesGenerator
);

isValidName1 = identifierNamesGenerator.isValidIdentifierName('Set');
isValidName2 = identifierNamesGenerator.isValidIdentifierName('Array');
isValidName3 = identifierNamesGenerator.isValidIdentifierName('WeakSet');
});

it('should generate first identifier', () => {
assert.isFalse(isValidName1);
assert.isFalse(isValidName2);
assert.isTrue(isValidName3);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -312,5 +312,32 @@ describe('MangledIdentifierNamesGenerator', () => {
assert.equal(secondMangledIdentifierName, expectedSecondIdentifier);
});
});

describe('Variant #3: reserved dom property name', () => {
let identifierNamesGenerator: IIdentifierNamesGenerator,
isValidName1: boolean,
isValidName2: boolean,
isValidName3: boolean;

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

inversifyContainerFacade.load('', '', {} );
identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.MangledIdentifierNamesGenerator
);

isValidName1 = identifierNamesGenerator.isValidIdentifierName('Set');
isValidName2 = identifierNamesGenerator.isValidIdentifierName('Array');
isValidName3 = identifierNamesGenerator.isValidIdentifierName('WeakSet');
});

it('should generate first identifier', () => {
assert.isFalse(isValidName1);
assert.isFalse(isValidName2);
assert.isTrue(isValidName3);
});
});
});
});

0 comments on commit ec4b70f

Please sign in to comment.