mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
This commit is contained in:
+15
-14
@@ -8,15 +8,16 @@ v0.10.0
|
||||
* **Breaking change:** `disableConsoleOutput` option now disabled by default.
|
||||
* **Breaking change:** `escapeUnicodeSequence` option now disabled by default.
|
||||
* `controlFlowFlattening` now affects string literal nodes.
|
||||
* increased runtime performance with `rc4` `stringArrayEncoding`.
|
||||
* added support for async functions
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/65
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/60
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/59
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/54
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/57
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/58
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/58
|
||||
* Increased runtime performance with `rc4` `stringArrayEncoding`.
|
||||
* Added support for async functions
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/71
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/65
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/60
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/59
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/54
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/57
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/58
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/58
|
||||
|
||||
v0.9.3
|
||||
---
|
||||
@@ -70,15 +71,15 @@ v0.9.0-beta.1
|
||||
|
||||
v0.8.6
|
||||
---
|
||||
* additional fixes for https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
|
||||
* Additional fixes for https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
|
||||
|
||||
v0.8.5
|
||||
---
|
||||
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
|
||||
|
||||
v0.8.4
|
||||
---
|
||||
* fixed https://github.com/javascript-obfuscator/webpack-obfuscator/issues/13
|
||||
* Fixed https://github.com/javascript-obfuscator/webpack-obfuscator/issues/13
|
||||
|
||||
v0.8.3
|
||||
---
|
||||
@@ -113,9 +114,9 @@ v0.7.3
|
||||
|
||||
v0.7.2
|
||||
---
|
||||
* runtime error fix [#7](https://github.com/sanex3339/webpack-obfuscator/issues/7)
|
||||
* Runtime error fix [#7](https://github.com/sanex3339/webpack-obfuscator/issues/7)
|
||||
|
||||
* shorthand object expression fix [#16](https://github.com/sanex3339/javascript-obfuscator/issues/16)
|
||||
* Shorthand object expression fix [#16](https://github.com/sanex3339/javascript-obfuscator/issues/16)
|
||||
|
||||
v0.7.1
|
||||
---
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+31
-6
@@ -1,6 +1,7 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
|
||||
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TControlFlowCustomNodeFactory } from '../../types/container/custom-nodes/TControlFlowCustomNodeFactory';
|
||||
@@ -61,6 +62,35 @@ export class BlockStatementControlFlowTransformer extends AbstractNodeTransforme
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {BlockStatement} blockStatementNode
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private static canTransformBlockStatementNode (blockStatementNode: ESTree.BlockStatement): boolean {
|
||||
let canTransform: boolean = true;
|
||||
|
||||
estraverse.traverse(blockStatementNode, {
|
||||
enter: (node: ESTree.Node): any => {
|
||||
if (Node.isWhileStatementNode(node)) {
|
||||
return estraverse.VisitorOption.Skip;
|
||||
}
|
||||
|
||||
if (
|
||||
Node.isBlockStatementNode(node)
|
||||
&& BlockStatementControlFlowTransformer.blockStatementHasProhibitedStatements(node)
|
||||
) {
|
||||
canTransform = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (blockStatementNode.body.length <= 4) {
|
||||
canTransform = false;
|
||||
}
|
||||
|
||||
return canTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {IVisitor}
|
||||
*/
|
||||
@@ -82,17 +112,12 @@ export class BlockStatementControlFlowTransformer extends AbstractNodeTransforme
|
||||
public transformNode (blockStatementNode: ESTree.BlockStatement, parentNode: ESTree.Node): ESTree.Node {
|
||||
if (
|
||||
this.randomGenerator.getMathRandom() > this.options.controlFlowFlatteningThreshold ||
|
||||
BlockStatementControlFlowTransformer.blockStatementHasProhibitedStatements(blockStatementNode)
|
||||
!BlockStatementControlFlowTransformer.canTransformBlockStatementNode(blockStatementNode)
|
||||
) {
|
||||
return blockStatementNode;
|
||||
}
|
||||
|
||||
const blockStatementBody: ESTree.Statement[] = blockStatementNode.body;
|
||||
|
||||
if (blockStatementBody.length <= 4) {
|
||||
return blockStatementNode;
|
||||
}
|
||||
|
||||
const originalKeys: number[] = this.arrayUtils.arrayRange(blockStatementBody.length);
|
||||
const shuffledKeys: number[] = this.arrayUtils.arrayShuffle(originalKeys);
|
||||
const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key));
|
||||
|
||||
@@ -253,4 +253,12 @@ export class Node {
|
||||
public static isVariableDeclaratorNode (node: ESTree.Node): node is ESTree.VariableDeclarator {
|
||||
return node.type === NodeType.VariableDeclarator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isWhileStatementNode (node: ESTree.Node): node is ESTree.WhileStatement {
|
||||
return node.type === NodeType.WhileStatement;
|
||||
}
|
||||
}
|
||||
|
||||
+118
-6
@@ -270,13 +270,13 @@ describe('BlockStatementControlFlowTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #6: block statement contain break statement', () => {
|
||||
describe('variant #6: block statement contain break statement #1', () => {
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *break; *console\['log'\]\(0x1\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/break-statement.js');
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/break-statement-1.js');
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
@@ -294,13 +294,69 @@ describe('BlockStatementControlFlowTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #7: block statement contain continue statement', () => {
|
||||
describe('variant #7: block statement contain break statement #2', () => {
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *if *\(!!\[\]\) *\{ *break; *\} *console\['log'\]\(0x1\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/break-statement-2.js');
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
);
|
||||
|
||||
obfuscatedCode = obfuscationResult.getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('shouldn\'t transform block statement', () => {
|
||||
assert.match(obfuscatedCode, statementRegExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #8: block statement contain while statement with break statement', () => {
|
||||
const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
|
||||
const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
|
||||
const expectedSwitchCaseLength: number = 5;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
switchCaseLength: number;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/break-statement-inside-while-statement.js');
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
);
|
||||
|
||||
obfuscatedCode = obfuscationResult.getObfuscatedCode();
|
||||
switchCaseLength = obfuscatedCode.match(switchCaseLengthRegExp)!.length;
|
||||
});
|
||||
|
||||
it('should wrap block statement statements in switch-case structure', () => {
|
||||
assert.match(obfuscatedCode, switchCaseRegExp);
|
||||
});
|
||||
|
||||
it('each statement should be wrapped by switch-case structure', () => {
|
||||
assert.equal(switchCaseLength, expectedSwitchCaseLength);
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #9: block statement contain continue statement #1', () => {
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *continue; *console\['log'\]\(0x1\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/continue-statement.js');
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/continue-statement-1.js');
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
@@ -318,7 +374,63 @@ describe('BlockStatementControlFlowTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #8: block statement contain function declaration', () => {
|
||||
describe('variant #10: block statement contain continue statement #2', () => {
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *if *\(!!\[\]\) *\{ *continue; *\} *console\['log'\]\(0x1\);/;
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/continue-statement-2.js');
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
);
|
||||
|
||||
obfuscatedCode = obfuscationResult.getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('shouldn\'t transform block statement', () => {
|
||||
assert.match(obfuscatedCode, statementRegExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #11: block statement contain while statement with continue statement', () => {
|
||||
const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
|
||||
const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
|
||||
const expectedSwitchCaseLength: number = 5;
|
||||
|
||||
let obfuscatedCode: string,
|
||||
switchCaseLength: number;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/continue-statement-inside-while-statement.js');
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
);
|
||||
|
||||
obfuscatedCode = obfuscationResult.getObfuscatedCode();
|
||||
switchCaseLength = obfuscatedCode.match(switchCaseLengthRegExp)!.length;
|
||||
});
|
||||
|
||||
it('should wrap block statement statements in switch-case structure', () => {
|
||||
assert.match(obfuscatedCode, switchCaseRegExp);
|
||||
});
|
||||
|
||||
it('each statement should be wrapped by switch-case structure', () => {
|
||||
assert.equal(switchCaseLength, expectedSwitchCaseLength);
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #12: block statement contain function declaration', () => {
|
||||
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-f0-9]){4,6} *\( *\) *\{ *\} *console\['log'\]\(0x1\);/
|
||||
|
||||
let obfuscatedCode: string;
|
||||
@@ -342,7 +454,7 @@ describe('BlockStatementControlFlowTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #9: `controlFlowFlatteningThreshold` chance', () => {
|
||||
describe('variant #13: `controlFlowFlatteningThreshold` chance', () => {
|
||||
const samples: number = 1000;
|
||||
const delta: number = 0.1;
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
(function () {
|
||||
while (true) {
|
||||
if (true) {
|
||||
break;
|
||||
}
|
||||
console.log(1);
|
||||
console.log(2);
|
||||
console.log(3);
|
||||
console.log(4);
|
||||
console.log(5);
|
||||
}
|
||||
})();
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
(function () {
|
||||
while (true) {
|
||||
while (true) {
|
||||
break;
|
||||
}
|
||||
console.log(1);
|
||||
console.log(2);
|
||||
console.log(3);
|
||||
console.log(4);
|
||||
console.log(5);
|
||||
}
|
||||
})();
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
(function () {
|
||||
while (true) {
|
||||
if (true) {
|
||||
continue;
|
||||
}
|
||||
console.log(1);
|
||||
console.log(2);
|
||||
console.log(3);
|
||||
console.log(4);
|
||||
console.log(5);
|
||||
}
|
||||
})();
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
(function () {
|
||||
while (true) {
|
||||
while (true) {
|
||||
continue;
|
||||
}
|
||||
console.log(1);
|
||||
console.log(2);
|
||||
console.log(3);
|
||||
console.log(4);
|
||||
console.log(5);
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user