8000 String array calls transform fix (#1050) · sec-js/javascript-obfuscator@ec4b70f · GitHub
[go: up one dir, main page]

Skip to content

Commit ec4b70f

Browse files
authored
String array calls transform fix (javascript-obfuscator#1050)
* 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
1 parent 77f64bf commit ec4b70f

File tree

14 files changed

+177
-25
lines changed

14 files changed

+177
-25
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
Change Log
22

3+
v3.2.3
4+
---
5+
* Fixed missing transformation of string array calls in some cases
6+
* Fixed generation of reserved identifier names like `Map` or `Set` for `mangled` and `mangled-shuffled` identifier names generators
7+
38
v3.2.2
49
---
510
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1039

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "javascript-obfuscator",
3-
"version": "3.2.2",
3+
"version": "3.2.3",
44
"description": "JavaScript obfuscator",
55
"keywords": [
66
"obfuscator",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const reservedIdentifierNames = [
2+
// reserved identifiers
3+
'byte', 'case', 'char', 'do', 'else', 'enum', 'eval', 'for', 'goto',
4+
'if', 'in', 'int', 'let', 'long', 'new', 'null', 'this', 'true', 'try',
5+
'var', 'void', 'with',
6+
7+
// reserved global object identifiers
8+
'Array', 'Attr', 'Audio', 'Blob', 'Cache', 'Date', 'Error', 'Event',
9+
'Feed', 'File', 'Hz', 'Image', 'Intl', 'Lock', 'Map', 'Math', 'Node',
10+
'Proxy', 'Range', 'Rect', 'Set', 'Table', 'Text', 'Touch'
11+
];

src/generators/identifier-names-generators/AbstractIdentifierNamesGenerator.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ export abstract class AbstractIdentifierNamesGenerator implements IIdentifierNam
7979
* @returns {boolean}
8080
*/
8181
public isValidIdentifierName (name: string): boolean {
82-
return this.notReservedName(name) && !this.preservedNamesSet.has(name);
82+
return !this.isReservedName(name)
83+
&& !this.preservedNamesSet.has(name);
8384
}
8485

8586
/**
@@ -112,12 +113,12 @@ export abstract class AbstractIdentifierNamesGenerator implements IIdentifierNam
112113
* @param {string} name
113114
* @returns {boolean}
114115
*/
115-
private notReservedName (name: string): boolean {
116+
private isReservedName (name: string): boolean {
116117
return this.options.reservedNames.length
117-
? !this.options.reservedNames.some((reservedName: string) =>
118+
? this.options.reservedNames.some((reservedName: string) =>
118119
new RegExp(reservedName, 'g').exec(name) !== null
119120
)
120-
: true;
121+
: false;
121122

122123
}
123124

src/generators/identifier-names-generators/MangledIdentifierNamesGenerator.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import { IOptions } from '../../interfaces/options/IOptions';
77
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
88
import { ISetUtils } from '../../interfaces/utils/ISetUtils';
99

10-
import { numbersString } from '../../constants/NumbersString';
1110
import { alphabetString } from '../../constants/AlphabetString';
1211
import { alphabetStringUppercase } from '../../constants/AlphabetStringUppercase';
12+
import { numbersString } from '../../constants/NumbersString';
13+
import { reservedIdentifierNames } from '../../constants/ReservedIdentifierNames';
1314

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

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

5250
/**
5351
* @type {WeakMap<string, string>}

src/node-transformers/control-flow-transformers/StringArrayControlFlowTransformer.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from '../../types/container/node-transformers/TControlFlowStorageFactoryCreator';
1212
import { TNodeWithStatements } from '../../types/node/TNodeWithStatements';
1313

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

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

2828
@injectable()
2929
export class StringArrayControlFlowTransformer extends FunctionControlFlowTransformer {
@@ -120,12 +120,20 @@ export class StringArrayControlFlowTransformer extends FunctionControlFlowTransf
120120
&& this.controlFlowStorageNodes.has(node);
121121

122122
if (isControlFlowStorageNode) {
123-
return estraverse.VisitorOption.Break;
123+
return estraverse.VisitorOption.Skip;
124124
}
125125

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

129+
/**
130+
* @param {TNodeWithStatements} hostNode
131+
* @returns {TControlFlowStorage}
132+
*/
133+
protected override getControlFlowStorage (hostNode: TNodeWithStatements): IControlFlowStorage {
134+
return this.controlFlowStorageFactory();
135+
}
136+
129137
/**
130138
* @param {TNodeWithStatements} hostNode
131139
* @param {VariableDeclaration} controlFlowStorageNode

src/node-transformers/rename-properties-transformers/replacer/RenamePropertiesReplacer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { IPropertyIdentifierNamesCacheStorage } from '../../../interfaces/storag
1212
import { IRenamePropertiesReplacer } from '../../../interfaces/node-transformers/rename-properties-transformers/replacer/IRenamePropertiesReplacer';
1313

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

1717
import { NodeGuards } from '../../../node/NodeGuards';
1818
import { NodeFactory } from '../../../node/NodeFactory';

test/dev/dev.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,55 @@
11
'use strict';
22

3+
import { StringArrayWrappersType } from '../../src/enums/node-transformers/string-array-transformers/StringArrayWrappersType';
4+
35
(function () {
46
const JavaScriptObfuscator: any = require('../../index');
57

68
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
79
`
8-
async function xyzzy(a,b)
9-
{
10-
if (a) {
11-
return await foo(a) ;
12-
console.log(a) ;
13-
} else {
14-
return await bar(b) ;
15-
console.log(b) ;
10+
function foo () {
11+
function bar() {
12+
var string1 = 'string1';
13+
var string2 = 'string2';
14+
var string3 = 'string3';
15+
var string4 = 'string4';
16+
var string5 = 'string5';
17+
var string6 = 'string6';
18+
19+
function bark () {
20+
var string1 = 'string1';
21+
var string2 = 'string2';
22+
var string3 = 'string3';
23+
var string4 = 'string4';
24+
var string5 = 'string5';
25+
var string6 = 'string6';
26+
}
1627
}
28+
29+
bar()
1730
}
31+
32+
console.log(foo());
1833
`,
1934
{
2035
identifierNamesGenerator: 'mangled',
2136
compact: false,
22-
simplify: true,
23-
stringArray: false
37+
controlFlowFlattening: false,
38+
controlFlowFlatteningThreshold: 1,
39+
simplify: false,
40+
stringArrayRotate: false,
41+
stringArray: true,
42+
stringArrayIndexesType: [
43+
'hexadecimal-number',
44+
'hexadecimal-numeric-string'
45+
],
46+
stringArrayThreshold: 1,
47+
stringArrayCallsTransform: true,
48+
stringArrayCallsTransformThreshold: 1,
49+
rotateStringArray: true,
50+
stringArrayWrappersType: StringArrayWrappersType.Function,
51+
transformObjectKeys: false,
52+
seed: 1
2453
}
2554
).getObfuscatedCode();
2655

test/functional-tests/node-transformers/control-flow-transformers/string-array-control-flow-transformer/StringArrayControlFlowTransformer.spec.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,43 @@ describe('StringArrayControlFlowTransformer', function () {
191191
assert.match(obfuscatedCode, regexp);
192192
});
193193
});
194+
195+
describe('Variant #5 - multiple `control flow storages` on the same block scope', () => {
196+
const regexp: RegExp = new RegExp(
197+
`var ${hexadecimalVariableMatch} *= *\\{` +
198+
`${hexadecimalVariableMatch} *: *0x0, *` +
199+
`${hexadecimalVariableMatch} *: *0x1 *` +
200+
`\\}; *` +
201+
`var ${hexadecimalVariableMatch} *= *\\{` +
202+
203+
`${hexadecimalVariableMatch} *: *0x2, *` +
204+
`${hexadecimalVariableMatch} *: *0x3 *` +
205+
`\\};`
206+
);
207+
208+
let obfuscatedCode: string;
209+
210+
before(() => {
211+
const code: string = readFileAsString(__dirname + '/fixtures/multiple-storages-1.js');
212+
213+
obfuscatedCode = JavaScriptObfuscator.obfuscate(
214+
code,
215+
{
216+
...NO_ADDITIONAL_NODES_PRESET,
217+
stringArray: true,
218+
stringArrayThreshold: 1,
219+
stringArrayCallsTransform: true,
220+
stringArrayCallsTransformThreshold: 1
221+
}
222+
).getObfuscatedCode();
223+
224+
console.log(obfuscatedCode);
225+
});
226+
227+
it('should add `control flow storage` node with multiple items to the obfuscated code', () => {
228+
assert.match(obfuscatedCode, regexp);
229+
});
230+
});
194231
});
195232

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

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

325362
obfuscatedCode = JavaScriptObfuscator.obfuscate(
326363
code,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
(function () {
2+
var variable1 = 'foo' + 'bar';
3+
4+
function foo (arg) {
5+
var variable2 = 'baz' + 'bark';
6+
}
7+
})();

test/unit-tests/generators/identifier-names-generators/MangledShuffledlIdentifierNamesGenerator.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,33 @@ describe('MangledShuffledIdentifierNamesGenerator', () => {
186186
assert.isTrue(isSuccessComparison);
187187
});
188188
});
189+
190+
describe('isValidIdentifierName', () => {
191+
describe('Variant #1: reserved dom property name', () => {
192+
let identifierNamesGenerator: IIdentifierNamesGenerator,
193+
isValidName1: boolean,
194+
isValidName2: boolean,
195+
isValidName3: boolean;
196+
197+
beforeEach(() => {
198+
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
199+
200+
inversifyContainerFacade.load('', '', {} );
201+
identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
202+
ServiceIdentifiers.IIdentifierNamesGenerator,
203+
IdentifierNamesGenerator.MangledShuffledIdentifierNamesGenerator
204+
);
205+
206+
isValidName1 = identifierNamesGenerator.isValidIdentifierName('Set');
207+
isValidName2 = identifierNamesGenerator.isValidIdentifierName('Array');
208+
isValidName3 = identifierNamesGenerator.isValidIdentifierName('WeakSet');
209+
});
210+
211+
it('should generate first identifier', () => {
212+
assert.isFalse(isValidName1);
213+
assert.isFalse(isValidName2);
214+
assert.isTrue(isValidName3);
215+
});
216+
});
217+
});
189218
});

test/unit-tests/generators/identifier-names-generators/MangledlIdentifierNamesGenerator.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,5 +312,32 @@ describe('MangledIdentifierNamesGenerator', () => {
312312
assert.equal(secondMangledIdentifierName, expectedSecondIdentifier);
313313
});
314314
});
315+
316+
describe('Variant #3: reserved dom property name', () => {
317+
let identifierNamesGenerator: IIdentifierNamesGenerator,
318+
isValidName1: boolean,
319+
isValidName2: boolean,
320+
isValidName3: boolean;
321+
322+
beforeEach(() => {
323+
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
324+
325+
inversifyContainerFacade.load('', '', {} );
326+
identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
327+
ServiceIdentifiers.IIdentifierNamesGenerator,
328+
IdentifierNamesGenerator.MangledIdentifierNamesGenerator
329+
);
330+
331+
isValidName1 = identifierNamesGenerator.isValidIdentifierName('Set');
332+
isValidName2 = identifierNamesGenerator.isValidIdentifierName('Array');
333+
isValidName3 = identifierNamesGenerator.isValidIdentifierName('WeakSet');
334+
});
335+
336+
it('should generate first identifier', () => {
337+
assert.isFalse(isValidName1);
338+
assert.isFalse(isValidName2);
339+
assert.isTrue(isValidName3);
340+
});
341+
});
315342
});
316343
});

0 commit comments

Comments
 (0)
0