diff --git a/README.md b/README.md index e1f4deb7..ff298281 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,8 @@ Compact code output on one line. ### `controlFlowFlattening` Type: `boolean` Default: `false` +##### :warning: This option greatly affects the performance up to 2x slower runtime speed. Use [`controlFlowFlatteningThreshold`](#controlflowflatteningthreshold) to set percentage of nodes that will affected by control flow flattening. + Enables code control flow flattening. Control flow flattening is a structure transformation of the source code that hinders program comprehension. Example: @@ -211,31 +213,57 @@ Example: function foo () { return function () { var sum = 1 + 2; + console.log(1); + console.log(2); + console.log(3); + console.log(4); + console.log(5); + console.log(6); } } })(); // output -(function() { - var _0x451dc8 = { - '\x44\x64\x4f': function _0x3(_0x4ea314, _0x4fa62e) { - return _0x4ea314 + _0x4fa62e; +(function () { + var _0x4cd5dd = { + '\x42\x4e\x62': function _0x14cffe(_0x38a20c, _0x42b1f2) { + return _0x38a20c + _0x42b1f2; } }; - - function _0x5382d8() { - var _0x349b22 = { - '\x48\x65\x61': function _0x2(_0x14a596, _0x250c4b) { - return _0x451dc8['\x44\x64\x4f'](_0x14a596, _0x250c4b); + function _0xd58698() { + var _0x36cac7 = { + '\x6a\x52\x79': function _0x2d3ac9(_0x2e037c, _0x457f42) { + return _0x4cd5dd['BNb'](_0x2e037c, _0x457f42); } }; - return function() { - var _0x412353 = { - '\x73\x47\x6f': function _0x4(_0x43c6b0, _0x133730) { - return _0x349b22['\x48\x65\x61'](_0x43c6b0, _0x133730); + return function () { + var _0x42a17d = '5\x7c3\x7c2\x7c6\x7c4\x7c1\x7c0'['split']('\x7c'), _0x1fcdcf = 0x0; + while (!![]) { + switch (_0x42a17d[_0x1fcdcf++]) { + case '0': + console['log'](0x6); + continue; + case '1': + console['log'](0x5); + continue; + case '2': + console['log'](0x2); + continue; + case '3': + console['log'](0x1); + continue; + case '4': + console['log'](0x4); + continue; + case '5': + var _0x15a932 = _0x36cac7['jRy'](0x1, 0x2); + continue; + case '6': + console['log'](0x3); + continue; } - }; - var _0x1d8637 = _0x412353['\x73\x47\x6f'](0x1, 0x2); + break; + } }; } }()); @@ -401,6 +429,69 @@ Allows to enable/disable string conversion to unicode escape sequence. Unicode escape sequence increases code size greatly. It is recommended to disable this option when using [`stringArrayEncoding`](#stringarrayencoding) (especially with `rc4` encoding). +## Option Presets +### High obfuscation, low performance + +Performance will 50-100% slower then without obfuscation + +```javascript +{ + compact: true, + controlFlowFlattening: true, + controlFlowFlatteningThreshold: 1, + debugProtection: true, + debugProtectionInterval: true, + disableConsoleOutput: true, + rotateStringArray: true, + selfDefending: true, + stringArray: true, + stringArrayEncoding: 'rc4', + stringArrayThreshold: 1, + unicodeEscapeSequence: false +} +``` + +### Medium obfuscation, optimal performance + +Performance will 30-35% slower then without obfuscation + +```javascript +{ + compact: true, + controlFlowFlattening: true, + controlFlowFlatteningThreshold: 0.75, + debugProtection: false, + debugProtectionInterval: false, + disableConsoleOutput: true, + rotateStringArray: true, + selfDefending: true, + stringArray: true, + stringArrayEncoding: 'base64', + stringArrayThreshold: 0.75, + unicodeEscapeSequence: false +} +``` + +### Low obfuscation, High performance + +Performance will slightly slower then without obfuscation + +```javascript +{ + compact: true, + controlFlowFlattening: false, + debugProtection: false, + debugProtectionInterval: false, + disableConsoleOutput: true, + rotateStringArray: true, + selfDefending: true, + stringArray: true, + stringArrayEncoding: false, + stringArrayThreshold: 0.75, + unicodeEscapeSequence: true +} +``` + ## License Copyright (C) 2016 [Timofey Kachalov](http://github.com/sanex3339). diff --git a/dist/index.js b/dist/index.js index b2803e25..d3676d4b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -5184,8 +5184,8 @@ var FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = function return FunctionControlFlowTransformer; }(AbstractNodeTransformer_1.AbstractNodeTransformer); FunctionControlFlowTransformer.controlFlowReplacersMap = new _map2.default([[NodeType_1.NodeType.BinaryExpression, NodeControlFlowReplacers_1.NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer], [NodeType_1.NodeType.BlockStatement, NodeControlFlowReplacers_1.NodeControlFlowReplacers.BlockStatementControlFlowReplacer], [NodeType_1.NodeType.CallExpression, NodeControlFlowReplacers_1.NodeControlFlowReplacers.CallExpressionControlFlowReplacer], [NodeType_1.NodeType.LogicalExpression, NodeControlFlowReplacers_1.NodeControlFlowReplacers.LogicalExpressionControlFlowReplacer]]); -FunctionControlFlowTransformer.hostNodeSearchMinDepth = 2; -FunctionControlFlowTransformer.hostNodeSearchMaxDepth = 10; +FunctionControlFlowTransformer.hostNodeSearchMinDepth = 0; +FunctionControlFlowTransformer.hostNodeSearchMaxDepth = 2; FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = tslib_1.__decorate([inversify_1.injectable(), tslib_1.__param(0, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.Factory__TControlFlowStorage)), tslib_1.__param(1, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.Factory__IControlFlowReplacer)), tslib_1.__param(2, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.Factory__ICustomNode)), tslib_1.__param(3, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.IOptions)), tslib_1.__metadata("design:paramtypes", [Function, Function, Function, Object])], FunctionControlFlowTransformer); exports.FunctionControlFlowTransformer = FunctionControlFlowTransformer; var FunctionControlFlowTransformer_1; @@ -5256,9 +5256,9 @@ var BinaryExpressionControlFlowReplacer_1; "use strict"; -var _from = __webpack_require__(46); +var _toConsumableArray2 = __webpack_require__(27); -var _from2 = _interopRequireDefault(_from); +var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); var _getPrototypeOf = __webpack_require__(5); @@ -5304,7 +5304,7 @@ var BlockStatementControlFlowReplacer = BlockStatementControlFlowReplacer_1 = fu return blockStatementNode; } var blockStatementBody = blockStatementNode.body; - var originalKeys = (0, _from2.default)(Array(blockStatementBody.length).keys()); + var originalKeys = [].concat((0, _toConsumableArray3.default)(Array(blockStatementBody.length).keys())); var shuffledKeys = Utils_1.Utils.arrayShuffle(originalKeys); var originalKeysIndexesInShuffledArray = originalKeys.map(function (key) { return shuffledKeys.indexOf(key); diff --git a/package.json b/package.json index b12f900a..36f13409 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-obfuscator", - "version": "0.9.0-dev.7", + "version": "0.9.0-dev.8", "description": "JavaScript obfuscator", "keywords": [ "obfuscator", diff --git a/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts b/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts index 88a0d87f..0180f123 100644 --- a/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts +++ b/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts @@ -38,12 +38,12 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer { /** * @type {number} */ - private static readonly hostNodeSearchMinDepth: number = 2; + private static readonly hostNodeSearchMinDepth: number = 0; /** * @type {number} */ - private static readonly hostNodeSearchMaxDepth: number = 10; + private static readonly hostNodeSearchMaxDepth: number = 2; /** * @type {Map>} diff --git a/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BlockStatementControlFlowReplacer.ts b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BlockStatementControlFlowReplacer.ts index b20699a7..5ed8878d 100644 --- a/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BlockStatementControlFlowReplacer.ts +++ b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BlockStatementControlFlowReplacer.ts @@ -57,7 +57,7 @@ export class BlockStatementControlFlowReplacer extends AbstractControlFlowReplac } const blockStatementBody: ESTree.Statement[] = blockStatementNode.body; - const originalKeys: number[] = Array.from(Array(blockStatementBody.length).keys()); + const originalKeys: number[] = [...Array(blockStatementBody.length).keys()]; const shuffledKeys: number[] = Utils.arrayShuffle(originalKeys); const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key)); diff --git a/test/dev/dev.ts b/test/dev/dev.ts index a93eba66..33459b06 100644 --- a/test/dev/dev.ts +++ b/test/dev/dev.ts @@ -1,4 +1,5 @@ 'use strict'; +import { NO_CUSTOM_NODES_PRESET } from '../../src/options/presets/NoCustomNodes'; if (!(global)._babelPolyfill) { require('babel-polyfill'); @@ -10,96 +11,25 @@ if (!(global)._babelPolyfill) { let obfuscatedCode: string = JavaScriptObfuscator.obfuscate( ` (function(){ - var result = 1, - term1 = 0, - term2 = 1, - i = 1; - while(i < 10) - { - var test = 10; - result = term1 + term2; - console.log(result); - term1 = term2; - term2 = result; - i++; - } - - console.log(test); - - var test = function (test) { - console.log(test); - - if (true) { - var test = 5 - } - - return test; - } - - console.log(test(1)); - - function test2 (abc) { - function test1 () { - console.log('inside', abc.item); - } - - console.log('ั‚ะตัั‚', abc); - - var abc = {}; - - return abc.item = 15, test1(); - }; - - var regexptest = /version\\/(\\d+)/i; - console.log(regexptest); - - test2(22); - console.log(105.4); - console.log(true, false); - - var sA = 'shorthand1'; - var sB = 'shorthand2'; - - console.log({sA, sB}); - function foo () { return function () { - var sum1 = 10 + 20; - var sum2 = 20 + 30; - var sum3 = 30 + 50; - var sub = sum3 - sum2; - - return sum1 + sub; + var sum = 1 + 2; + console.log(1); + console.log(2); + console.log(3); + console.log(4); + console.log(5); + console.log(6); } } - - try { - } catch (error) { - console.log(error); - } - - console.log(foo()()); - - function bar () { - console.log(1); - console.log(2); - console.log(3); - console.log(4); - console.log(5); - console.log(6); - console.log(7); - console.log(8); - } - - bar(); })(); `, { + ...NO_CUSTOM_NODES_PRESET, compact: false, controlFlowFlattening: true, controlFlowFlatteningThreshold: 1, disableConsoleOutput: false, - stringArray: true, unicodeEscapeSequence: false } ).getObfuscatedCode(); diff --git a/test/fixtures/node-transformers/node-control-flow-transformers/function-control-flow-transformer-2.js b/test/fixtures/node-transformers/node-control-flow-transformers/function-control-flow-transformer-2.js index 0916c2b8..5b404f52 100644 --- a/test/fixtures/node-transformers/node-control-flow-transformers/function-control-flow-transformer-2.js +++ b/test/fixtures/node-transformers/node-control-flow-transformers/function-control-flow-transformer-2.js @@ -1,11 +1,7 @@ (function () { function foo () { function bar () { - function baz () { - function bash () { - var variable = 1 + 2; - } - } + var variable = 1 + 2; } } })();