diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a2ef345..c67995fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ Change Log === +v0.8.2 +--- +* New option `seed` sets seed for random generator. This is useful for creating repeatable results. +* IE8 runtime error fix. + v0.8.1 --- * `disableConsoleOutput` option now replaces `console.xxx` functions on empty function instead of infinity loop. diff --git a/README.md b/README.md index 3d77f5fe..986b7c35 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ Following options available for the JS Obfuscator: disableConsoleOutput: true, reservedNames: [], rotateStringArray: true, + seed: 0, selfDefending: true, sourceMap: false, sourceMapBaseUrl: '', @@ -131,7 +132,7 @@ Following options available for the JS Obfuscator: stringArray: true, stringArrayEncoding: false, stringArrayThreshold: 0.8, - unicdeEscapeSequence: true + unicodeEscapeSequence: true } ``` @@ -148,6 +149,7 @@ Following options available for the JS Obfuscator: --disableConsoleOutput --reservedNames (comma separated) --rotateStringArray + --seed --selfDefending --sourceMap --sourceMapBaseUrl @@ -218,6 +220,12 @@ Shift the `stringArray` array by a fixed and random (generated at the code obfus This option is recommended if your original source code isn't small, as the helper function can attract attention. +### `seed` +Type: `number` Default: `0` + +This option sets seed for random generator. This is useful for creating repeatable results. + +If seed is `0` - random generator will work without seed. ### `selfDefending` Type: `boolean` Default: `true` diff --git a/dist/index.js b/dist/index.js index 48c1c2c0..41628e70 100644 --- a/dist/index.js +++ b/dist/index.js @@ -88,7 +88,7 @@ module.exports = /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 89); +/******/ return __webpack_require__(__webpack_require__.s = 105); /******/ }) /************************************************************************/ /******/ ([ @@ -98,12 +98,15 @@ module.exports = "use strict"; "use strict"; +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; })(); + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var chance_1 = __webpack_require__(82); +var chance_1 = __webpack_require__(25); var JSFuck_1 = __webpack_require__(21); +var isEqual = __webpack_require__(102); var Utils = function () { function Utils() { @@ -167,11 +170,32 @@ var Utils = function () { domain = domain.split(':')[0]; return domain; } + }, { + key: 'getRandomFloat', + value: function getRandomFloat(min, max) { + return Utils.getRandomGenerator().floating({ + min: min, + max: max, + fixed: 7 + }); + } }, { key: 'getRandomGenerator', value: function getRandomGenerator() { + var randomGenerator = Utils.randomGenerator; + if (!randomGenerator) { + throw new Error('`randomGenerator` static property is undefined'); + } return Utils.randomGenerator; } + }, { + key: 'getRandomInteger', + value: function getRandomInteger(min, max) { + return Utils.getRandomGenerator().integer({ + min: min, + max: max + }); + } }, { key: 'getRandomVariableName', value: function getRandomVariableName() { @@ -180,10 +204,7 @@ var Utils = function () { var rangeMinInteger = 10000, rangeMaxInteger = 99999999, prefix = '_0x'; - return '' + prefix + Utils.decToHex(Utils.getRandomGenerator().integer({ - min: rangeMinInteger, - max: rangeMaxInteger - })).substr(0, length); + return '' + prefix + Utils.decToHex(Utils.getRandomInteger(rangeMinInteger, rangeMaxInteger)).substr(0, length); } }, { key: 'hideString', @@ -196,7 +217,7 @@ var Utils = function () { i2 = -1, result = ''; while (i1 < s1.length || i2 < s2.length) { - if (Math.random() < 0.5 && i2 < s2.length) { + if (Utils.getRandomFloat(0, 1) < 0.5 && i2 < s2.length) { result += s2.charAt(++i2); } else { result += s1.charAt(++i1); @@ -204,10 +225,12 @@ var Utils = function () { } return result; }; - var customPool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - var randomString = Utils.randomGenerator.string({ length: length, pool: customPool }), - randomStringDiff = randomString.replace(new RegExp('[' + escapeRegExp(str) + ']', 'g'), ''), - randomStringDiffArray = randomStringDiff.split(''); + var randomString = Utils.randomGenerator.string({ + length: length, + pool: Utils.randomGeneratorPool + }); + var randomStringDiff = randomString.replace(new RegExp('[' + escapeRegExp(str) + ']', 'g'), ''); + var randomStringDiffArray = randomStringDiff.split(''); Utils.randomGenerator.shuffle(randomStringDiffArray); randomStringDiff = randomStringDiffArray.join(''); return [randomMerge(str, randomStringDiff), randomStringDiff]; @@ -217,6 +240,40 @@ var Utils = function () { value: function isInteger(number) { return number % 1 === 0; } + }, { + key: 'mapGetFirstKeyOf', + value: function mapGetFirstKeyOf(map, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = map[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _step$value = _slicedToArray(_step.value, 2), + key = _step$value[0], + storageValue = _step$value[1]; + + if (isEqual(value, storageValue)) { + return key; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } }, { key: 'rc4', value: function rc4(string, key) { @@ -245,6 +302,11 @@ var Utils = function () { } return result; } + }, { + key: 'setRandomGenerator', + value: function setRandomGenerator(randomGenerator) { + Utils.randomGenerator = randomGenerator; + } }, { key: 'strEnumify', value: function strEnumify(obj) { @@ -280,143 +342,22 @@ var Utils = function () { return Utils; }(); +Utils.randomGeneratorPool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; Utils.randomGenerator = new chance_1.Chance(); exports.Utils = Utils; /***/ }, /* 1 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function(module, exports) { "use strict"; "use strict"; -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var escodegen = __webpack_require__(13); -var esprima = __webpack_require__(24); -var estraverse = __webpack_require__(4); -var NodeType_1 = __webpack_require__(6); -var Node_1 = __webpack_require__(2); -var Utils_1 = __webpack_require__(0); - -var NodeUtils = function () { - function NodeUtils() { - _classCallCheck(this, NodeUtils); - } - - _createClass(NodeUtils, null, [{ - key: 'addXVerbatimPropertyToLiterals', - value: function addXVerbatimPropertyToLiterals(node) { - NodeUtils.typedReplace(node, NodeType_1.NodeType.Literal, { - leave: function leave(node) { - node['x-verbatim-property'] = { - content: node.raw, - precedence: escodegen.Precedence.Primary - }; - } - }); - } - }, { - key: 'convertCodeToStructure', - value: function convertCodeToStructure(code) { - var structure = esprima.parse(code); - NodeUtils.addXVerbatimPropertyToLiterals(structure); - NodeUtils.parentize(structure); - return structure.body; - } - }, { - key: 'getBlockStatementNodeByIndex', - value: function getBlockStatementNodeByIndex(node) { - var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - if (Node_1.Node.isNodeHasBlockStatement(node)) { - if (node.body[index] === undefined) { - throw new ReferenceError('Wrong index `' + index + '`. Block-statement body length is `' + node.body.length + '`'); - } - return node.body[index]; - } - throw new TypeError('The specified node have no a block-statement'); - } - }, { - key: 'getBlockScopeOfNode', - value: function getBlockScopeOfNode(node) { - var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - var parentNode = node.parentNode; - if (!parentNode) { - throw new ReferenceError('`parentNode` property of given node is `undefined`'); - } - if (Node_1.Node.isBlockStatementNode(parentNode)) { - if (!parentNode.parentNode) { - throw new ReferenceError('`parentNode` property of `parentNode` of given node is `undefined`'); - } - if (!Utils_1.Utils.arrayContains(NodeUtils.nodesWithBlockScope, parentNode.parentNode.type)) { - return NodeUtils.getBlockScopeOfNode(parentNode, depth); - } else if (depth > 0) { - return NodeUtils.getBlockScopeOfNode(parentNode, --depth); - } - return parentNode; - } - if (Node_1.Node.isProgramNode(parentNode)) { - return parentNode; - } - return NodeUtils.getBlockScopeOfNode(parentNode); - } - }, { - key: 'parentize', - value: function parentize(node) { - var isRootNode = true; - estraverse.replace(node, { - enter: function enter(node, parentNode) { - var value = void 0; - if (isRootNode) { - if (node.type === NodeType_1.NodeType.Program) { - value = node; - } else { - value = Node_1.Node.getProgramNode([node]); - value.parentNode = value; - } - isRootNode = false; - } else { - value = parentNode || node; - } - node.parentNode = value; - node.obfuscated = false; - } - }); - } - }, { - key: 'typedReplace', - value: function typedReplace(node, nodeType, visitor) { - NodeUtils.typedTraverse(node, nodeType, visitor, 'replace'); - } - }, { - key: 'typedTraverse', - value: function typedTraverse(node, nodeType, visitor) { - var traverseType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'traverse'; - - estraverse[traverseType](node, { - enter: function enter(node, parentNode) { - if (node.type === nodeType && visitor.enter) { - visitor.enter(node, parentNode); - } - }, - leave: function leave(node, parentNode) { - if (node.type === nodeType && visitor.leave) { - visitor.leave(node, parentNode); - } - } - }); - } - }]); - - return NodeUtils; -}(); - -NodeUtils.nodesWithBlockScope = [NodeType_1.NodeType.ArrowFunctionExpression, NodeType_1.NodeType.FunctionDeclaration, NodeType_1.NodeType.FunctionExpression, NodeType_1.NodeType.MethodDefinition, NodeType_1.NodeType.Program]; -exports.NodeUtils = NodeUtils; +(function (AppendState) { + AppendState[AppendState["AfterObfuscation"] = 0] = "AfterObfuscation"; + AppendState[AppendState["BeforeObfuscation"] = 1] = "BeforeObfuscation"; +})(exports.AppendState || (exports.AppendState = {})); +var AppendState = exports.AppendState; /***/ }, /* 2 */ @@ -563,25 +504,6 @@ exports.Node = Node; /***/ }, /* 3 */ -/***/ function(module, exports) { - -"use strict"; -"use strict"; - -(function (AppendState) { - AppendState[AppendState["AfterObfuscation"] = 0] = "AfterObfuscation"; - AppendState[AppendState["BeforeObfuscation"] = 1] = "BeforeObfuscation"; -})(exports.AppendState || (exports.AppendState = {})); -var AppendState = exports.AppendState; - -/***/ }, -/* 4 */ -/***/ function(module, exports) { - -module.exports = require("estraverse"); - -/***/ }, -/* 5 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -640,10 +562,7 @@ var NodeAppender = function () { }, { key: 'getRandomStackTraceIndex', value: function getRandomStackTraceIndex(stackTraceRootLength) { - return Utils_1.Utils.getRandomGenerator().integer({ - min: 0, - max: Math.max(0, Math.round(stackTraceRootLength - 1)) - }); + return Utils_1.Utils.getRandomInteger(0, Math.max(0, Math.round(stackTraceRootLength - 1))); } }, { key: 'insertNodeAtIndex', @@ -707,6 +626,59 @@ var NodeAppender = function () { exports.NodeAppender = NodeAppender; +/***/ }, +/* 4 */ +/***/ function(module, exports) { + +module.exports = require("estraverse"); + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var NodeUtils_1 = __webpack_require__(8); + +var AbstractCustomNode = function () { + function AbstractCustomNode(options) { + _classCallCheck(this, AbstractCustomNode); + + this.options = options; + } + + _createClass(AbstractCustomNode, [{ + key: "getAppendState", + value: function getAppendState() { + return this.appendState; + } + }, { + key: "getNode", + value: function getNode() { + return this.getNodeStructure(); + } + }, { + key: "setAppendState", + value: function setAppendState(appendState) { + this.appendState = appendState; + } + }, { + key: "getNodeStructure", + value: function getNodeStructure() { + return NodeUtils_1.NodeUtils.convertCodeToStructure(this.getCode()); + } + }]); + + return AbstractCustomNode; +}(); + +exports.AbstractCustomNode = AbstractCustomNode; + /***/ }, /* 6 */ /***/ function(module, exports, __webpack_require__) { @@ -752,6 +724,12 @@ exports.NodeType = Utils_1.Utils.strEnumify({ /* 7 */ /***/ function(module, exports) { +module.exports = require("string-template"); + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + "use strict"; "use strict"; @@ -759,37 +737,149 @@ var _createClass = (function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var AbstractCustomNode = function () { - function AbstractCustomNode(options) { - _classCallCheck(this, AbstractCustomNode); +var escodegen = __webpack_require__(11); +var esprima = __webpack_require__(26); +var estraverse = __webpack_require__(4); +var NodeType_1 = __webpack_require__(6); +var Node_1 = __webpack_require__(2); +var Utils_1 = __webpack_require__(0); - this.options = options; +var NodeUtils = function () { + function NodeUtils() { + _classCallCheck(this, NodeUtils); } - _createClass(AbstractCustomNode, [{ - key: "getAppendState", - value: function getAppendState() { - return this.appendState; + _createClass(NodeUtils, null, [{ + key: 'addXVerbatimPropertyToLiterals', + value: function addXVerbatimPropertyToLiterals(node) { + NodeUtils.typedReplace(node, NodeType_1.NodeType.Literal, { + leave: function leave(node) { + node['x-verbatim-property'] = { + content: node.raw, + precedence: escodegen.Precedence.Primary + }; + } + }); } }, { - key: "getNode", - value: function getNode() { - return this.getNodeStructure(); + key: 'convertCodeToStructure', + value: function convertCodeToStructure(code) { + var structure = esprima.parse(code); + NodeUtils.addXVerbatimPropertyToLiterals(structure); + NodeUtils.parentize(structure); + return structure.body; } }, { - key: "setAppendState", - value: function setAppendState(appendState) { - this.appendState = appendState; + key: 'getBlockStatementNodeByIndex', + value: function getBlockStatementNodeByIndex(node) { + var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + + if (Node_1.Node.isNodeHasBlockStatement(node)) { + if (node.body[index] === undefined) { + throw new ReferenceError('Wrong index `' + index + '`. Block-statement body length is `' + node.body.length + '`'); + } + return node.body[index]; + } + throw new TypeError('The specified node have no a block-statement'); + } + }, { + key: 'getBlockScopeOfNode', + value: function getBlockScopeOfNode(node) { + var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + + var parentNode = node.parentNode; + if (!parentNode) { + throw new ReferenceError('`parentNode` property of given node is `undefined`'); + } + if (Node_1.Node.isBlockStatementNode(parentNode)) { + if (!parentNode.parentNode) { + throw new ReferenceError('`parentNode` property of `parentNode` of given node is `undefined`'); + } + if (!Utils_1.Utils.arrayContains(NodeUtils.nodesWithBlockScope, parentNode.parentNode.type)) { + return NodeUtils.getBlockScopeOfNode(parentNode, depth); + } else if (depth > 0) { + return NodeUtils.getBlockScopeOfNode(parentNode, --depth); + } + return parentNode; + } + if (Node_1.Node.isProgramNode(parentNode)) { + return parentNode; + } + return NodeUtils.getBlockScopeOfNode(parentNode); + } + }, { + key: 'getNodeBlockScopeDepth', + value: function getNodeBlockScopeDepth(node) { + var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + + var parentNode = node.parentNode; + if (!parentNode) { + throw new ReferenceError('`parentNode` property of given node is `undefined`'); + } + if (Node_1.Node.isProgramNode(parentNode)) { + return depth; + } + if (Node_1.Node.isBlockStatementNode(node)) { + return NodeUtils.getNodeBlockScopeDepth(parentNode, ++depth); + } + return NodeUtils.getNodeBlockScopeDepth(parentNode, depth); + } + }, { + key: 'parentize', + value: function parentize(node) { + var isRootNode = true; + estraverse.replace(node, { + enter: function enter(node, parentNode) { + var value = void 0; + if (isRootNode) { + if (node.type === NodeType_1.NodeType.Program) { + value = node; + } else { + value = Node_1.Node.getProgramNode([node]); + value.parentNode = value; + } + isRootNode = false; + } else { + value = parentNode || node; + } + node.parentNode = value; + node.obfuscated = false; + } + }); + } + }, { + key: 'typedReplace', + value: function typedReplace(node, nodeType, visitor) { + NodeUtils.typedTraverse(node, nodeType, visitor, 'replace'); + } + }, { + key: 'typedTraverse', + value: function typedTraverse(node, nodeType, visitor) { + var traverseType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'traverse'; + + estraverse[traverseType](node, { + enter: function enter(node, parentNode) { + if (node.type === nodeType && visitor.enter) { + visitor.enter(node, parentNode); + } + }, + leave: function leave(node, parentNode) { + if (node.type === nodeType && visitor.leave) { + visitor.leave(node, parentNode); + } + } + }); } }]); - return AbstractCustomNode; + return NodeUtils; }(); -exports.AbstractCustomNode = AbstractCustomNode; +NodeUtils.nodesWithBlockScope = [NodeType_1.NodeType.ArrowFunctionExpression, NodeType_1.NodeType.FunctionDeclaration, NodeType_1.NodeType.FunctionExpression, NodeType_1.NodeType.MethodDefinition, NodeType_1.NodeType.Program]; +exports.NodeUtils = NodeUtils; /***/ }, -/* 8 */ +/* 9 */ /***/ function(module, exports) { "use strict"; @@ -797,20 +887,14 @@ exports.AbstractCustomNode = AbstractCustomNode; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var AbstractNodeObfuscator = function AbstractNodeObfuscator(nodes, options) { - _classCallCheck(this, AbstractNodeObfuscator); +var AbstractNodeTransformer = function AbstractNodeTransformer(nodes, options) { + _classCallCheck(this, AbstractNodeTransformer); this.nodes = nodes; this.options = options; }; -exports.AbstractNodeObfuscator = AbstractNodeObfuscator; - -/***/ }, -/* 9 */ -/***/ function(module, exports) { - -module.exports = require("format-unicorn"); +exports.AbstractNodeTransformer = AbstractNodeTransformer; /***/ }, /* 10 */ @@ -823,8 +907,9 @@ var _createClass = (function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var JavaScriptObfuscatorCLI_1 = __webpack_require__(32); -var JavaScriptObfuscatorInternal_1 = __webpack_require__(27); +var JavaScriptObfuscatorCLI_1 = __webpack_require__(33); +var JavaScriptObfuscatorInternal_1 = __webpack_require__(29); +var Options_1 = __webpack_require__(67); var JavaScriptObfuscator = function () { function JavaScriptObfuscator() { @@ -836,9 +921,8 @@ var JavaScriptObfuscator = function () { value: function obfuscate(sourceCode) { var obfuscatorOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var javaScriptObfuscator = new JavaScriptObfuscatorInternal_1.JavaScriptObfuscatorInternal(sourceCode, obfuscatorOptions); - javaScriptObfuscator.obfuscate(); - return javaScriptObfuscator.getObfuscationResult(); + var javaScriptObfuscator = new JavaScriptObfuscatorInternal_1.JavaScriptObfuscatorInternal(new Options_1.Options(obfuscatorOptions)); + return javaScriptObfuscator.obfuscate(sourceCode); } }, { key: 'runCLI', @@ -854,6 +938,12 @@ exports.JavaScriptObfuscator = JavaScriptObfuscator; /***/ }, /* 11 */ +/***/ function(module, exports) { + +module.exports = require("escodegen"); + +/***/ }, +/* 12 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -863,7 +953,7 @@ var _createClass = (function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var AppendState_1 = __webpack_require__(3); +var AppendState_1 = __webpack_require__(1); var AbstractNodesGroup = function () { function AbstractNodesGroup(stackTraceData, options) { @@ -892,7 +982,7 @@ var AbstractNodesGroup = function () { exports.AbstractNodesGroup = AbstractNodesGroup; /***/ }, -/* 12 */ +/* 13 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -951,12 +1041,6 @@ var IdentifierReplacer = function (_AbstractReplacer_1$A) { exports.IdentifierReplacer = IdentifierReplacer; -/***/ }, -/* 13 */ -/***/ function(module, exports) { - -module.exports = require("escodegen"); - /***/ }, /* 14 */ /***/ function(module, exports) { @@ -997,12 +1081,14 @@ exports.AbstractReplacer = AbstractReplacer; var SourceMapMode_1 = __webpack_require__(14); exports.NO_CUSTOM_NODES_PRESET = Object.freeze({ compact: true, + controlFlowFlattening: false, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: false, domainLock: [], reservedNames: [], rotateStringArray: false, + seed: 0, selfDefending: false, sourceMap: false, sourceMapBaseUrl: '', @@ -1029,14 +1115,13 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); -var SingleNodeCallControllerTemplate_1 = __webpack_require__(66); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var SingleNodeCallControllerTemplate_1 = __webpack_require__(80); var NoCustomNodesPreset_1 = __webpack_require__(16); -var AbstractCustomNode_1 = __webpack_require__(7); +var AbstractCustomNode_1 = __webpack_require__(5); var JavaScriptObfuscator_1 = __webpack_require__(10); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var NodeAppender_1 = __webpack_require__(3); var NodeCallsControllerFunctionNode = function (_AbstractCustomNode_) { _inherits(NodeCallsControllerFunctionNode, _AbstractCustomNode_); @@ -1065,16 +1150,18 @@ var NodeCallsControllerFunctionNode = function (_AbstractCustomNode_) { NodeAppender_1.NodeAppender.prependNode(targetBlockScope, this.getNode()); } }, { - key: 'getNodeStructure', - value: function getNodeStructure() { + key: 'getCode', + value: function getCode() { if (this.appendState === AppendState_1.AppendState.AfterObfuscation) { - return NodeUtils_1.NodeUtils.convertCodeToStructure(JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(SingleNodeCallControllerTemplate_1.SingleNodeCallControllerTemplate().formatUnicorn({ + return JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(format(SingleNodeCallControllerTemplate_1.SingleNodeCallControllerTemplate(), { singleNodeCallControllerFunctionName: this.callsControllerFunctionName - }), NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET).getObfuscatedCode()); + }), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, { + seed: this.options.seed + })).getObfuscatedCode(); } - return NodeUtils_1.NodeUtils.convertCodeToStructure(SingleNodeCallControllerTemplate_1.SingleNodeCallControllerTemplate().formatUnicorn({ + return format(SingleNodeCallControllerTemplate_1.SingleNodeCallControllerTemplate(), { singleNodeCallControllerFunctionName: this.callsControllerFunctionName - })); + }); } }]); @@ -1112,7 +1199,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var StringArrayEncoding_1 = __webpack_require__(18); var AbstractReplacer_1 = __webpack_require__(15); -var NumberLiteralReplacer_1 = __webpack_require__(22); +var NumberLiteralReplacer_1 = __webpack_require__(23); var Utils_1 = __webpack_require__(0); var StringLiteralReplacer = function (_AbstractReplacer_1$A) { @@ -1127,7 +1214,7 @@ var StringLiteralReplacer = function (_AbstractReplacer_1$A) { _createClass(StringLiteralReplacer, [{ key: 'replace', value: function replace(nodeValue) { - var replaceWithStringArrayFlag = nodeValue.length >= StringLiteralReplacer.minimumLengthForStringArray && Math.random() <= this.options.stringArrayThreshold; + var replaceWithStringArrayFlag = nodeValue.length >= StringLiteralReplacer.minimumLengthForStringArray && Utils_1.Utils.getRandomFloat(0, 1) <= this.options.stringArrayThreshold; if (this.options.stringArray && replaceWithStringArrayFlag) { return this.replaceStringLiteralWithStringArrayCall(nodeValue); } @@ -1138,7 +1225,7 @@ var StringLiteralReplacer = function (_AbstractReplacer_1$A) { value: function replaceStringLiteralWithStringArrayCall(value) { var stringArrayNode = this.nodes.get('stringArrayNode'); if (!stringArrayNode) { - throw new ReferenceError('`stringArrayNode` node is not found in Map with custom node.'); + throw new ReferenceError('`stringArrayNode` node is not found in Map with custom nodes.'); } var rc4Key = ''; switch (this.options.stringArrayEncoding) { @@ -1153,18 +1240,17 @@ var StringLiteralReplacer = function (_AbstractReplacer_1$A) { if (this.options.unicodeEscapeSequence) { value = Utils_1.Utils.stringToUnicodeEscapeSequence(value); } - var stringArray = stringArrayNode.getNodeData(), - indexOfExistingValue = stringArray.getIndexOf(value), - indexOfValue = void 0, - hexadecimalIndex = void 0; + var stringArray = stringArrayNode.getNodeData(); + var indexOfExistingValue = stringArray.getKeyOf(value); + var indexOfValue = void 0; if (indexOfExistingValue >= 0) { indexOfValue = indexOfExistingValue; } else { indexOfValue = stringArray.getLength(); - stringArrayNode.updateNodeData(value); + stringArray.set(null, value); } - hexadecimalIndex = new NumberLiteralReplacer_1.NumberLiteralReplacer(this.nodes, this.options).replace(indexOfValue); var stringArrayCallsWrapper = this.nodes.get('stringArrayCallsWrapper'); + var hexadecimalIndex = new NumberLiteralReplacer_1.NumberLiteralReplacer(this.nodes, this.options).replace(indexOfValue); if (!stringArrayCallsWrapper) { throw new ReferenceError('`stringArrayCallsWrapper` node is not found in Map with custom node.'); } @@ -1233,7 +1319,6 @@ exports.ObfuscationResult = ObfuscationResult; "use strict"; exports.JSFuck = { - Window: '[]["filter"]["constructor"]("return this")()', False: '![]', True: '!![]', a: '(false+"")[1]', @@ -1292,6 +1377,44 @@ exports.JSFuck = { /***/ }, /* 22 */ +/***/ function(module, exports) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var AbstractNodeTransformersFactory = function () { + function AbstractNodeTransformersFactory(customNodes, options) { + _classCallCheck(this, AbstractNodeTransformersFactory); + + this.customNodes = customNodes; + this.options = options; + } + + _createClass(AbstractNodeTransformersFactory, [{ + key: "initializeNodeTransformers", + value: function initializeNodeTransformers(nodeType) { + var _this = this; + + var nodeTransformers = this.nodeTransformers.get(nodeType) || []; + var instancesArray = []; + nodeTransformers.forEach(function (transformer) { + instancesArray.push(new transformer(_this.customNodes, _this.options)); + }); + return instancesArray; + } + }]); + + return AbstractNodeTransformersFactory; +}(); + +exports.AbstractNodeTransformersFactory = AbstractNodeTransformersFactory; + +/***/ }, +/* 23 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1334,7 +1457,7 @@ var NumberLiteralReplacer = function (_AbstractReplacer_1$A) { exports.NumberLiteralReplacer = NumberLiteralReplacer; /***/ }, -/* 23 */ +/* 24 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1343,12 +1466,14 @@ exports.NumberLiteralReplacer = NumberLiteralReplacer; var SourceMapMode_1 = __webpack_require__(14); exports.DEFAULT_PRESET = Object.freeze({ compact: true, + controlFlowFlattening: false, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: true, domainLock: [], reservedNames: [], rotateStringArray: true, + seed: 0, selfDefending: true, sourceMap: false, sourceMapBaseUrl: '', @@ -1360,26 +1485,32 @@ exports.DEFAULT_PRESET = Object.freeze({ unicodeEscapeSequence: true }); -/***/ }, -/* 24 */ -/***/ function(module, exports) { - -module.exports = require("esprima"); - /***/ }, /* 25 */ /***/ function(module, exports) { -module.exports = require("path"); +module.exports = require("chance"); /***/ }, /* 26 */ /***/ function(module, exports) { -module.exports = require("babel-polyfill"); +module.exports = require("esprima"); /***/ }, /* 27 */ +/***/ function(module, exports) { + +module.exports = require("path"); + +/***/ }, +/* 28 */ +/***/ function(module, exports) { + +module.exports = require("babel-polyfill"); + +/***/ }, +/* 29 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1389,36 +1520,36 @@ var _createClass = (function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var esprima = __webpack_require__(24); -var escodegen = __webpack_require__(13); +var esprima = __webpack_require__(26); +var escodegen = __webpack_require__(11); +var chance_1 = __webpack_require__(25); var ObfuscationResult_1 = __webpack_require__(20); -var Obfuscator_1 = __webpack_require__(28); -var Options_1 = __webpack_require__(57); -var SourceMapCorrector_1 = __webpack_require__(29); +var Obfuscator_1 = __webpack_require__(30); +var SourceMapCorrector_1 = __webpack_require__(31); +var Utils_1 = __webpack_require__(0); var JavaScriptObfuscatorInternal = function () { - function JavaScriptObfuscatorInternal(sourceCode) { - var obfuscatorOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - + function JavaScriptObfuscatorInternal(options) { _classCallCheck(this, JavaScriptObfuscatorInternal); - this.sourceCode = sourceCode; - this.options = new Options_1.Options(obfuscatorOptions); + this.options = options; } _createClass(JavaScriptObfuscatorInternal, [{ key: 'getObfuscationResult', - value: function getObfuscationResult() { - return new SourceMapCorrector_1.SourceMapCorrector(new ObfuscationResult_1.ObfuscationResult(this.generatorOutput.code, this.generatorOutput.map), this.options.sourceMapBaseUrl + this.options.sourceMapFileName, this.options.sourceMapMode).correct(); + value: function getObfuscationResult(generatorOutput) { + return new SourceMapCorrector_1.SourceMapCorrector(new ObfuscationResult_1.ObfuscationResult(generatorOutput.code, generatorOutput.map), this.options.sourceMapBaseUrl + this.options.sourceMapFileName, this.options.sourceMapMode).correct(); } }, { key: 'obfuscate', - value: function obfuscate() { - var astTree = esprima.parse(this.sourceCode, { - loc: true - }); - astTree = new Obfuscator_1.Obfuscator(this.options).obfuscateNode(astTree); - this.generatorOutput = JavaScriptObfuscatorInternal.generateCode(this.sourceCode, astTree, this.options); + value: function obfuscate(sourceCode) { + if (this.options.seed !== 0) { + Utils_1.Utils.setRandomGenerator(new chance_1.Chance(this.options.seed)); + } + var astTree = esprima.parse(sourceCode, JavaScriptObfuscatorInternal.esprimaParams); + var obfuscatedAstTree = new Obfuscator_1.Obfuscator(this.options).obfuscateAstTree(astTree); + var generatorOutput = JavaScriptObfuscatorInternal.generateCode(sourceCode, obfuscatedAstTree, this.options); + return this.getObfuscationResult(generatorOutput); } }], [{ key: 'generateCode', @@ -1444,10 +1575,13 @@ JavaScriptObfuscatorInternal.escodegenParams = { verbatim: 'x-verbatim-property', sourceMapWithCode: true }; +JavaScriptObfuscatorInternal.esprimaParams = { + loc: true +}; exports.JavaScriptObfuscatorInternal = JavaScriptObfuscatorInternal; /***/ }, -/* 28 */ +/* 30 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1455,68 +1589,64 @@ exports.JavaScriptObfuscatorInternal = JavaScriptObfuscatorInternal; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var estraverse = __webpack_require__(4); -var AppendState_1 = __webpack_require__(3); -var NodeType_1 = __webpack_require__(6); -var CatchClauseObfuscator_1 = __webpack_require__(47); -var ConsoleOutputNodesGroup_1 = __webpack_require__(42); -var DebugProtectionNodesGroup_1 = __webpack_require__(43); -var DomainLockNodesGroup_1 = __webpack_require__(44); -var FunctionDeclarationObfuscator_1 = __webpack_require__(48); -var FunctionObfuscator_1 = __webpack_require__(49); -var LabeledStatementObfuscator_1 = __webpack_require__(50); -var LiteralObfuscator_1 = __webpack_require__(51); -var MemberExpressionObfuscator_1 = __webpack_require__(52); -var MethodDefinitionObfuscator_1 = __webpack_require__(53); +var AppendState_1 = __webpack_require__(1); +var VisitorDirection_1 = __webpack_require__(46); +var ConsoleOutputNodesGroup_1 = __webpack_require__(47); +var DebugProtectionNodesGroup_1 = __webpack_require__(48); +var DomainLockNodesGroup_1 = __webpack_require__(49); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); -var ObjectExpressionObfuscator_1 = __webpack_require__(54); -var SelfDefendingNodesGroup_1 = __webpack_require__(45); -var StackTraceAnalyzer_1 = __webpack_require__(60); -var StringArrayNodesGroup_1 = __webpack_require__(46); -var VariableDeclarationObfuscator_1 = __webpack_require__(55); +var NodeControlFlowTransformersFactory_1 = __webpack_require__(55); +var NodeObfuscatorsFactory_1 = __webpack_require__(65); +var NodeUtils_1 = __webpack_require__(8); +var SelfDefendingNodesGroup_1 = __webpack_require__(50); +var StackTraceAnalyzer_1 = __webpack_require__(70); +var StringArrayNodesGroup_1 = __webpack_require__(51); var Obfuscator = function () { function Obfuscator(options) { _classCallCheck(this, Obfuscator); - this.customNodes = new Map(); this.options = options; } _createClass(Obfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(node) { - if (Node_1.Node.isProgramNode(node) && !node.body.length) { - return node; + key: 'obfuscateAstTree', + value: function obfuscateAstTree(astTree) { + if (Node_1.Node.isProgramNode(astTree) && !astTree.body.length) { + return astTree; } - NodeUtils_1.NodeUtils.parentize(node); - var stackTraceData = new StackTraceAnalyzer_1.StackTraceAnalyzer(node.body).analyze(); - this.initializeCustomNodes(stackTraceData); - this.beforeObfuscation(node); - this.obfuscate(node); - this.afterObfuscation(node); - return node; + NodeUtils_1.NodeUtils.parentize(astTree); + this.initializeCustomNodes(new StackTraceAnalyzer_1.StackTraceAnalyzer().analyze(astTree.body)); + this.beforeTransform(astTree); + if (this.options.controlFlowFlattening) { + this.transformAstTree(astTree, VisitorDirection_1.VisitorDirection.leave, new NodeControlFlowTransformersFactory_1.NodeControlFlowTransformersFactory(this.customNodes, this.options)); + } + this.transformAstTree(astTree, VisitorDirection_1.VisitorDirection.enter, new NodeObfuscatorsFactory_1.NodeObfuscatorsFactory(this.customNodes, this.options)); + this.afterTransform(astTree); + return astTree; } }, { - key: 'afterObfuscation', - value: function afterObfuscation(astTree) { - this.customNodes.forEach(function (node) { - if (node.getAppendState() === AppendState_1.AppendState.AfterObfuscation) { - node.appendNode(astTree); + key: 'afterTransform', + value: function afterTransform(astTree) { + this.customNodes.forEach(function (customNode) { + if (customNode.getAppendState() === AppendState_1.AppendState.AfterObfuscation) { + customNode.appendNode(astTree); } }); } }, { - key: 'beforeObfuscation', - value: function beforeObfuscation(astTree) { - this.customNodes.forEach(function (node) { - if (node.getAppendState() === AppendState_1.AppendState.BeforeObfuscation) { - node.appendNode(astTree); + key: 'beforeTransform', + value: function beforeTransform(astTree) { + this.customNodes.forEach(function (customNode) { + if (customNode.getAppendState() === AppendState_1.AppendState.BeforeObfuscation) { + customNode.appendNode(astTree); } }); } @@ -1536,28 +1666,14 @@ var Obfuscator = function () { this.customNodes = new Map(customNodes); } }, { - key: 'initializeNodeObfuscators', - value: function initializeNodeObfuscators(node, parentNode) { - var _this2 = this; - - var nodeObfuscators = Obfuscator.nodeObfuscators.get(node.type); - if (!nodeObfuscators) { - return; - } - nodeObfuscators.forEach(function (obfuscator) { - new obfuscator(_this2.customNodes, _this2.options).obfuscateNode(node, parentNode); - }); - } - }, { - key: 'obfuscate', - value: function obfuscate(node) { - var _this3 = this; - - estraverse.traverse(node, { - enter: function enter(node, parentNode) { - _this3.initializeNodeObfuscators(node, parentNode); - } - }); + key: 'transformAstTree', + value: function transformAstTree(astTree, direction, nodeTransformersFactory) { + estraverse.traverse(astTree, _defineProperty({}, direction, function (node, parentNode) { + var nodeTransformers = nodeTransformersFactory.initializeNodeTransformers(node.type); + nodeTransformers.forEach(function (nodeTransformer) { + nodeTransformer.transformNode(node, parentNode); + }); + })); } }]); @@ -1565,11 +1681,10 @@ var Obfuscator = function () { }(); Obfuscator.nodeGroups = [DomainLockNodesGroup_1.DomainLockNodesGroup, SelfDefendingNodesGroup_1.SelfDefendingNodesGroup, ConsoleOutputNodesGroup_1.ConsoleOutputNodesGroup, DebugProtectionNodesGroup_1.DebugProtectionNodesGroup, StringArrayNodesGroup_1.StringArrayNodesGroup]; -Obfuscator.nodeObfuscators = new Map([[NodeType_1.NodeType.ArrowFunctionExpression, [FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.ClassDeclaration, [FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator]], [NodeType_1.NodeType.CatchClause, [CatchClauseObfuscator_1.CatchClauseObfuscator]], [NodeType_1.NodeType.FunctionDeclaration, [FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator, FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.FunctionExpression, [FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.MemberExpression, [MemberExpressionObfuscator_1.MemberExpressionObfuscator]], [NodeType_1.NodeType.MethodDefinition, [MethodDefinitionObfuscator_1.MethodDefinitionObfuscator]], [NodeType_1.NodeType.ObjectExpression, [ObjectExpressionObfuscator_1.ObjectExpressionObfuscator]], [NodeType_1.NodeType.VariableDeclaration, [VariableDeclarationObfuscator_1.VariableDeclarationObfuscator]], [NodeType_1.NodeType.LabeledStatement, [LabeledStatementObfuscator_1.LabeledStatementObfuscator]], [NodeType_1.NodeType.Literal, [LiteralObfuscator_1.LiteralObfuscator]]]); exports.Obfuscator = Obfuscator; /***/ }, -/* 29 */ +/* 31 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1627,7 +1742,7 @@ var SourceMapCorrector = function () { exports.SourceMapCorrector = SourceMapCorrector; /***/ }, -/* 30 */ +/* 32 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1637,68 +1752,9 @@ var _createClass = (function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var Utils_1 = __webpack_require__(0); - -var StringArray = function () { - function StringArray() { - _classCallCheck(this, StringArray); - - this.array = []; - } - - _createClass(StringArray, [{ - key: "addToArray", - value: function addToArray(value) { - this.array.push(value); - } - }, { - key: "getArray", - value: function getArray() { - return this.array; - } - }, { - key: "getIndexOf", - value: function getIndexOf(value) { - return this.array.indexOf(value); - } - }, { - key: "getLength", - value: function getLength() { - return this.array.length; - } - }, { - key: "rotateArray", - value: function rotateArray(rotationValue) { - this.array = Utils_1.Utils.arrayRotate(this.array, rotationValue); - } - }, { - key: "toString", - value: function toString() { - return this.array.map(function (value) { - return "'" + value + "'"; - }).toString(); - } - }]); - - return StringArray; -}(); - -exports.StringArray = StringArray; - -/***/ }, -/* 31 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -"use strict"; - -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var fs = __webpack_require__(85); -var mkdirp = __webpack_require__(86); -var path = __webpack_require__(25); +var fs = __webpack_require__(101); +var mkdirp = __webpack_require__(103); +var path = __webpack_require__(27); var Utils_1 = __webpack_require__(0); var CLIUtils = function () { @@ -1778,7 +1834,7 @@ CLIUtils.encoding = 'utf8'; exports.CLIUtils = CLIUtils; /***/ }, -/* 32 */ +/* 33 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1788,12 +1844,12 @@ var _createClass = (function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var commander = __webpack_require__(84); -var path = __webpack_require__(25); +var commander = __webpack_require__(100); +var path = __webpack_require__(27); var SourceMapMode_1 = __webpack_require__(14); var StringArrayEncoding_1 = __webpack_require__(18); -var DefaultPreset_1 = __webpack_require__(23); -var CLIUtils_1 = __webpack_require__(31); +var DefaultPreset_1 = __webpack_require__(24); +var CLIUtils_1 = __webpack_require__(32); var JavaScriptObfuscator_1 = __webpack_require__(10); var Utils_1 = __webpack_require__(0); @@ -1822,8 +1878,8 @@ var JavaScriptObfuscatorCLI = function () { }, { key: 'buildOptions', value: function buildOptions() { - var obfuscatorOptions = {}, - availableOptions = Object.keys(DefaultPreset_1.DEFAULT_PRESET); + var obfuscatorOptions = {}; + var availableOptions = Object.keys(DefaultPreset_1.DEFAULT_PRESET); for (var option in this.commands) { if (!this.commands.hasOwnProperty(option)) { continue; @@ -1838,11 +1894,11 @@ var JavaScriptObfuscatorCLI = function () { }, { key: 'configureCommands', value: function configureCommands() { - this.commands = new commander.Command().version(JavaScriptObfuscatorCLI.getBuildVersion(), '-v, --version').usage(' [options]').option('-o, --output ', 'Output path for obfuscated code').option('--compact ', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtection ', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtectionInterval ', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--disableConsoleOutput ', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean).option('--domainLock ', 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)', function (val) { + this.commands = new commander.Command().version(JavaScriptObfuscatorCLI.getBuildVersion(), '-v, --version').usage(' [options]').option('-o, --output ', 'Output path for obfuscated code').option('--compact ', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean).option('--controlFlowFlattening ', 'Enables control flow flattening', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtection ', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtectionInterval ', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--disableConsoleOutput ', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean).option('--domainLock ', 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)', function (val) { return val.split(','); }).option('--reservedNames ', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', function (val) { return val.split(','); - }).option('--rotateStringArray ', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean).option('--selfDefending ', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMap ', 'Enables source map generation', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMapBaseUrl ', 'Sets base url to the source map import url when `--sourceMapMode=separate`').option('--sourceMapFileName ', 'Sets file name for output source map when `--sourceMapMode=separate`').option('--sourceMapMode [inline, separate]', 'Specify source map output mode', JavaScriptObfuscatorCLI.parseSourceMapMode).option('--stringArray ', 'Disables gathering of all literal strings into an array and replacing every literal string with an array call', JavaScriptObfuscatorCLI.parseBoolean).option('--stringArrayEncoding [true, false, base64, rc4]', 'Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed', JavaScriptObfuscatorCLI.parseStringArrayEncoding).option('--stringArrayThreshold ', 'The probability that the literal string will be inserted into stringArray (Default: 0.8, Min: 0, Max: 1)', parseFloat).option('--unicodeEscapeSequence ', 'Allows to enable/disable string conversion to unicode escape sequence', JavaScriptObfuscatorCLI.parseBoolean).parse(this.rawArguments); + }).option('--rotateStringArray ', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean).option('--seed ', 'Sets seed for random generator. This is useful for creating repeatable results.', parseFloat).option('--selfDefending ', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMap ', 'Enables source map generation', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMapBaseUrl ', 'Sets base url to the source map import url when `--sourceMapMode=separate`').option('--sourceMapFileName ', 'Sets file name for output source map when `--sourceMapMode=separate`').option('--sourceMapMode [inline, separate]', 'Specify source map output mode', JavaScriptObfuscatorCLI.parseSourceMapMode).option('--stringArray ', 'Disables gathering of all literal strings into an array and replacing every literal string with an array call', JavaScriptObfuscatorCLI.parseBoolean).option('--stringArrayEncoding [true, false, base64, rc4]', 'Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed', JavaScriptObfuscatorCLI.parseStringArrayEncoding).option('--stringArrayThreshold ', 'The probability that the literal string will be inserted into stringArray (Default: 0.8, Min: 0, Max: 1)', parseFloat).option('--unicodeEscapeSequence ', 'Allows to enable/disable string conversion to unicode escape sequence', JavaScriptObfuscatorCLI.parseBoolean).parse(this.rawArguments); this.commands.on('--help', function () { console.log(' Examples:\n'); console.log(' %> javascript-obfuscator in.js --compact true --selfDefending false'); @@ -1858,8 +1914,8 @@ var JavaScriptObfuscatorCLI = function () { }, { key: 'processData', value: function processData() { - var options = this.buildOptions(), - outputCodePath = CLIUtils_1.CLIUtils.getOutputCodePath(this.commands.output, this.inputPath); + var options = this.buildOptions(); + var outputCodePath = CLIUtils_1.CLIUtils.getOutputCodePath(this.commands.output, this.inputPath); if (options.sourceMap) { this.processDataWithSourceMap(outputCodePath, options); } else { @@ -1926,7 +1982,7 @@ var JavaScriptObfuscatorCLI = function () { exports.JavaScriptObfuscatorCLI = JavaScriptObfuscatorCLI; /***/ }, -/* 33 */ +/* 34 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1940,12 +1996,11 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); -var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(67); -var AbstractCustomNode_1 = __webpack_require__(7); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(81); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); var Utils_1 = __webpack_require__(0); var ConsoleOutputDisableExpressionNode = function (_AbstractCustomNode_) { @@ -1969,12 +2024,12 @@ var ConsoleOutputDisableExpressionNode = function (_AbstractCustomNode_) { NodeAppender_1.NodeAppender.appendNodeToOptimalBlockScope(this.stackTraceData, blockScopeNode, this.getNode(), this.randomStackTraceIndex); } }, { - key: 'getNodeStructure', - value: function getNodeStructure() { - return NodeUtils_1.NodeUtils.convertCodeToStructure(ConsoleOutputDisableExpressionTemplate_1.ConsoleOutputDisableExpressionTemplate().formatUnicorn({ + key: 'getCode', + value: function getCode() { + return format(ConsoleOutputDisableExpressionTemplate_1.ConsoleOutputDisableExpressionTemplate(), { consoleLogDisableFunctionName: Utils_1.Utils.getRandomVariableName(), singleNodeCallControllerFunctionName: this.callsControllerFunctionName - })); + }); } }]); @@ -1984,7 +2039,7 @@ var ConsoleOutputDisableExpressionNode = function (_AbstractCustomNode_) { exports.ConsoleOutputDisableExpressionNode = ConsoleOutputDisableExpressionNode; /***/ }, -/* 34 */ +/* 35 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1998,12 +2053,177 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); -var DebufProtectionFunctionCallTemplate_1 = __webpack_require__(68); -var AbstractCustomNode_1 = __webpack_require__(7); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var BinaryExpressionFunctionTemplate_1 = __webpack_require__(82); +var AbstractCustomNode_1 = __webpack_require__(5); +var Utils_1 = __webpack_require__(0); + +var BinaryExpressionFunctionNode = function (_AbstractCustomNode_) { + _inherits(BinaryExpressionFunctionNode, _AbstractCustomNode_); + + function BinaryExpressionFunctionNode(operator, options) { + _classCallCheck(this, BinaryExpressionFunctionNode); + + var _this = _possibleConstructorReturn(this, (BinaryExpressionFunctionNode.__proto__ || Object.getPrototypeOf(BinaryExpressionFunctionNode)).call(this, options)); + + _this.appendState = AppendState_1.AppendState.BeforeObfuscation; + _this.operator = operator; + return _this; + } + + _createClass(BinaryExpressionFunctionNode, [{ + key: 'appendNode', + value: function appendNode(blockScopeNode) {} + }, { + key: 'getCode', + value: function getCode() { + return format(BinaryExpressionFunctionTemplate_1.BinaryExpressionFunctionTemplate(), { + functionName: Utils_1.Utils.getRandomVariableName(1), + operator: this.operator + }); + } + }]); + + return BinaryExpressionFunctionNode; +}(AbstractCustomNode_1.AbstractCustomNode); + +exports.BinaryExpressionFunctionNode = BinaryExpressionFunctionNode; + +/***/ }, +/* 36 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var ControlFlowStorageCallTemplate_1 = __webpack_require__(83); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); + +var ControlFlowStorageCallNode = function (_AbstractCustomNode_) { + _inherits(ControlFlowStorageCallNode, _AbstractCustomNode_); + + function ControlFlowStorageCallNode(controlFlowStorageName, controlFlowStorageKey, leftValue, rightValue, options) { + _classCallCheck(this, ControlFlowStorageCallNode); + + var _this = _possibleConstructorReturn(this, (ControlFlowStorageCallNode.__proto__ || Object.getPrototypeOf(ControlFlowStorageCallNode)).call(this, options)); + + _this.appendState = AppendState_1.AppendState.AfterObfuscation; + _this.controlFlowStorageName = controlFlowStorageName; + _this.controlFlowStorageKey = controlFlowStorageKey; + _this.leftValue = leftValue; + _this.rightValue = rightValue; + return _this; + } + + _createClass(ControlFlowStorageCallNode, [{ + key: 'appendNode', + value: function appendNode(blockScopeNode) { + NodeAppender_1.NodeAppender.prependNode(blockScopeNode, this.getNode()); + } + }, { + key: 'getCode', + value: function getCode() { + return format(ControlFlowStorageCallTemplate_1.ControlFlowStorageCallTemplate(), { + controlFlowStorageKey: this.controlFlowStorageKey, + controlFlowStorageName: this.controlFlowStorageName, + leftValue: this.leftValue, + rightValue: this.rightValue + }); + } + }]); + + return ControlFlowStorageCallNode; +}(AbstractCustomNode_1.AbstractCustomNode); + +exports.ControlFlowStorageCallNode = ControlFlowStorageCallNode; + +/***/ }, +/* 37 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var ControlFlowStorageTemplate_1 = __webpack_require__(84); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); + +var ControlFlowStorageNode = function (_AbstractCustomNode_) { + _inherits(ControlFlowStorageNode, _AbstractCustomNode_); + + function ControlFlowStorageNode(controlFlowStorage, controlFlowStorageName, options) { + _classCallCheck(this, ControlFlowStorageNode); + + var _this = _possibleConstructorReturn(this, (ControlFlowStorageNode.__proto__ || Object.getPrototypeOf(ControlFlowStorageNode)).call(this, options)); + + _this.appendState = AppendState_1.AppendState.AfterObfuscation; + _this.controlFlowStorage = controlFlowStorage; + _this.controlFlowStorageName = controlFlowStorageName; + return _this; + } + + _createClass(ControlFlowStorageNode, [{ + key: 'appendNode', + value: function appendNode(blockScopeNode) { + NodeAppender_1.NodeAppender.prependNode(blockScopeNode, this.getNode()); + } + }, { + key: 'getCode', + value: function getCode() { + return format(ControlFlowStorageTemplate_1.ControlFlowStorageTemplate(), { + controlFlowStorage: this.controlFlowStorage.toString(), + controlFlowStorageName: this.controlFlowStorageName + }); + } + }]); + + return ControlFlowStorageNode; +}(AbstractCustomNode_1.AbstractCustomNode); + +exports.ControlFlowStorageNode = ControlFlowStorageNode; + +/***/ }, +/* 38 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var DebufProtectionFunctionCallTemplate_1 = __webpack_require__(85); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); var DebugProtectionFunctionCallNode = function (_AbstractCustomNode_) { _inherits(DebugProtectionFunctionCallNode, _AbstractCustomNode_); @@ -2024,11 +2244,11 @@ var DebugProtectionFunctionCallNode = function (_AbstractCustomNode_) { NodeAppender_1.NodeAppender.appendNode(blockScopeNode, this.getNode()); } }, { - key: 'getNodeStructure', - value: function getNodeStructure() { - return NodeUtils_1.NodeUtils.convertCodeToStructure(DebufProtectionFunctionCallTemplate_1.DebugProtectionFunctionCallTemplate().formatUnicorn({ + key: 'getCode', + value: function getCode() { + return format(DebufProtectionFunctionCallTemplate_1.DebugProtectionFunctionCallTemplate(), { debugProtectionFunctionName: this.debugProtectionFunctionName - })); + }); } }]); @@ -2038,7 +2258,7 @@ var DebugProtectionFunctionCallNode = function (_AbstractCustomNode_) { exports.DebugProtectionFunctionCallNode = DebugProtectionFunctionCallNode; /***/ }, -/* 35 */ +/* 39 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2052,12 +2272,11 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); -var DebugProtectionFunctionIntervalTemplate_1 = __webpack_require__(69); -var AbstractCustomNode_1 = __webpack_require__(7); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var DebugProtectionFunctionIntervalTemplate_1 = __webpack_require__(86); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); var DebugProtectionFunctionIntervalNode = function (_AbstractCustomNode_) { _inherits(DebugProtectionFunctionIntervalNode, _AbstractCustomNode_); @@ -2078,11 +2297,11 @@ var DebugProtectionFunctionIntervalNode = function (_AbstractCustomNode_) { NodeAppender_1.NodeAppender.appendNode(blockScopeNode, this.getNode()); } }, { - key: 'getNodeStructure', - value: function getNodeStructure() { - return NodeUtils_1.NodeUtils.convertCodeToStructure(DebugProtectionFunctionIntervalTemplate_1.DebugProtectionFunctionIntervalTemplate().formatUnicorn({ + key: 'getCode', + value: function getCode() { + return format(DebugProtectionFunctionIntervalTemplate_1.DebugProtectionFunctionIntervalTemplate(), { debugProtectionFunctionName: this.debugProtectionFunctionName - })); + }); } }]); @@ -2092,7 +2311,7 @@ var DebugProtectionFunctionIntervalNode = function (_AbstractCustomNode_) { exports.DebugProtectionFunctionIntervalNode = DebugProtectionFunctionIntervalNode; /***/ }, -/* 36 */ +/* 40 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2106,12 +2325,11 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); -var DebugProtectionFunctionTemplate_1 = __webpack_require__(70); -var AbstractCustomNode_1 = __webpack_require__(7); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var DebugProtectionFunctionTemplate_1 = __webpack_require__(87); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); var Utils_1 = __webpack_require__(0); var DebugProtectionFunctionNode = function (_AbstractCustomNode_) { @@ -2131,23 +2349,15 @@ var DebugProtectionFunctionNode = function (_AbstractCustomNode_) { key: 'appendNode', value: function appendNode(blockScopeNode) { var programBodyLength = blockScopeNode.body.length, - randomIndex = Utils_1.Utils.getRandomGenerator().integer({ - min: 0, - max: programBodyLength - }); + randomIndex = Utils_1.Utils.getRandomInteger(0, programBodyLength); NodeAppender_1.NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), randomIndex); } }, { - key: 'getNodeIdentifier', - value: function getNodeIdentifier() { - return this.debugProtectionFunctionName; - } - }, { - key: 'getNodeStructure', - value: function getNodeStructure() { - return NodeUtils_1.NodeUtils.convertCodeToStructure(DebugProtectionFunctionTemplate_1.DebugProtectionFunctionTemplate().formatUnicorn({ + key: 'getCode', + value: function getCode() { + return format(DebugProtectionFunctionTemplate_1.DebugProtectionFunctionTemplate(), { debugProtectionFunctionName: this.debugProtectionFunctionName - })); + }); } }]); @@ -2157,7 +2367,7 @@ var DebugProtectionFunctionNode = function (_AbstractCustomNode_) { exports.DebugProtectionFunctionNode = DebugProtectionFunctionNode; /***/ }, -/* 37 */ +/* 41 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2173,12 +2383,11 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); -var DomainLockNodeTemplate_1 = __webpack_require__(71); -var AbstractCustomNode_1 = __webpack_require__(7); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var DomainLockNodeTemplate_1 = __webpack_require__(88); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); var Utils_1 = __webpack_require__(0); var DomainLockNode = function (_AbstractCustomNode_) { @@ -2202,19 +2411,19 @@ var DomainLockNode = function (_AbstractCustomNode_) { NodeAppender_1.NodeAppender.appendNodeToOptimalBlockScope(this.stackTraceData, blockScopeNode, this.getNode(), this.randomStackTraceIndex); } }, { - key: 'getNodeStructure', - value: function getNodeStructure() { + key: 'getCode', + value: function getCode() { var domainsString = this.options.domainLock.join(';'), _Utils_1$Utils$hideSt = Utils_1.Utils.hideString(domainsString, domainsString.length * 3), _Utils_1$Utils$hideSt2 = _slicedToArray(_Utils_1$Utils$hideSt, 2), hiddenDomainsString = _Utils_1$Utils$hideSt2[0], diff = _Utils_1$Utils$hideSt2[1]; - return NodeUtils_1.NodeUtils.convertCodeToStructure(DomainLockNodeTemplate_1.DomainLockNodeTemplate().formatUnicorn({ + return format(DomainLockNodeTemplate_1.DomainLockNodeTemplate(), { domainLockFunctionName: Utils_1.Utils.getRandomVariableName(), diff: diff, domains: hiddenDomainsString, singleNodeCallControllerFunctionName: this.callsControllerFunctionName - })); + }); } }]); @@ -2224,7 +2433,7 @@ var DomainLockNode = function (_AbstractCustomNode_) { exports.DomainLockNode = DomainLockNode; /***/ }, -/* 38 */ +/* 42 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2238,13 +2447,13 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var AppendState_1 = __webpack_require__(3); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); var NoCustomNodesPreset_1 = __webpack_require__(16); -var SelfDefendingTemplate_1 = __webpack_require__(72); -var AbstractCustomNode_1 = __webpack_require__(7); -var NodeAppender_1 = __webpack_require__(5); +var SelfDefendingTemplate_1 = __webpack_require__(89); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); var JavaScriptObfuscator_1 = __webpack_require__(10); -var NodeUtils_1 = __webpack_require__(1); var Utils_1 = __webpack_require__(0); var SelfDefendingUnicodeNode = function (_AbstractCustomNode_) { @@ -2268,12 +2477,14 @@ var SelfDefendingUnicodeNode = function (_AbstractCustomNode_) { NodeAppender_1.NodeAppender.appendNodeToOptimalBlockScope(this.stackTraceData, blockScopeNode, this.getNode(), this.randomStackTraceIndex); } }, { - key: 'getNodeStructure', - value: function getNodeStructure() { - return NodeUtils_1.NodeUtils.convertCodeToStructure(JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(SelfDefendingTemplate_1.SelfDefendingTemplate().formatUnicorn({ + key: 'getCode', + value: function getCode() { + return JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(format(SelfDefendingTemplate_1.SelfDefendingTemplate(), { selfDefendingFunctionName: Utils_1.Utils.getRandomVariableName(), singleNodeCallControllerFunctionName: this.callsControllerFunctionName - }), NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET).getObfuscatedCode()); + }), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, { + seed: this.options.seed + })).getObfuscatedCode(); } }]); @@ -2283,7 +2494,7 @@ var SelfDefendingUnicodeNode = function (_AbstractCustomNode_) { exports.SelfDefendingUnicodeNode = SelfDefendingUnicodeNode; /***/ }, -/* 39 */ +/* 43 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2299,20 +2510,19 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); var StringArrayEncoding_1 = __webpack_require__(18); var NoCustomNodesPreset_1 = __webpack_require__(16); -var AtobTemplate_1 = __webpack_require__(64); -var Rc4Template_1 = __webpack_require__(65); -var SelfDefendingTemplate_1 = __webpack_require__(73); -var StringArrayBase64DecodeNodeTemplate_1 = __webpack_require__(74); -var StringArrayCallsWrapperTemplate_1 = __webpack_require__(75); -var StringArrayRC4DecodeNodeTemplate_1 = __webpack_require__(76); -var AbstractCustomNode_1 = __webpack_require__(7); +var AtobTemplate_1 = __webpack_require__(78); +var Rc4Template_1 = __webpack_require__(79); +var SelfDefendingTemplate_1 = __webpack_require__(90); +var StringArrayBase64DecodeNodeTemplate_1 = __webpack_require__(91); +var StringArrayCallsWrapperTemplate_1 = __webpack_require__(92); +var StringArrayRC4DecodeNodeTemplate_1 = __webpack_require__(93); +var AbstractCustomNode_1 = __webpack_require__(5); var JavaScriptObfuscator_1 = __webpack_require__(10); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var NodeAppender_1 = __webpack_require__(3); var StringArrayCallsWrapper = function (_AbstractCustomNode_) { _inherits(StringArrayCallsWrapper, _AbstractCustomNode_); @@ -2337,6 +2547,18 @@ var StringArrayCallsWrapper = function (_AbstractCustomNode_) { } NodeAppender_1.NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), 1); } + }, { + key: 'getCode', + value: function getCode() { + var decodeNodeTemplate = this.getDecodeStringArrayTemplate(); + return JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(format(StringArrayCallsWrapperTemplate_1.StringArrayCallsWrapperTemplate(), { + decodeNodeTemplate: decodeNodeTemplate, + stringArrayCallsWrapperName: this.stringArrayCallsWrapperName, + stringArrayName: this.stringArrayName + }), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, { + seed: this.options.seed + })).getObfuscatedCode(); + } }, { key: 'getNodeIdentifier', value: function getNodeIdentifier() { @@ -2353,21 +2575,21 @@ var StringArrayCallsWrapper = function (_AbstractCustomNode_) { var decodeStringArrayTemplate = '', selfDefendingCode = ''; if (this.options.selfDefending) { - selfDefendingCode = SelfDefendingTemplate_1.SelfDefendingTemplate().formatUnicorn({ + selfDefendingCode = format(SelfDefendingTemplate_1.SelfDefendingTemplate(), { stringArrayCallsWrapperName: this.stringArrayCallsWrapperName, stringArrayName: this.stringArrayName }); } switch (this.options.stringArrayEncoding) { case StringArrayEncoding_1.StringArrayEncoding.base64: - decodeStringArrayTemplate = StringArrayBase64DecodeNodeTemplate_1.StringArrayBase64DecodeNodeTemplate().formatUnicorn({ + decodeStringArrayTemplate = format(StringArrayBase64DecodeNodeTemplate_1.StringArrayBase64DecodeNodeTemplate(), { atobPolyfill: AtobTemplate_1.AtobTemplate(), selfDefendingCode: selfDefendingCode, stringArrayCallsWrapperName: this.stringArrayCallsWrapperName }); break; case StringArrayEncoding_1.StringArrayEncoding.rc4: - decodeStringArrayTemplate = StringArrayRC4DecodeNodeTemplate_1.StringArrayRc4DecodeNodeTemplate().formatUnicorn({ + decodeStringArrayTemplate = format(StringArrayRC4DecodeNodeTemplate_1.StringArrayRc4DecodeNodeTemplate(), { atobPolyfill: AtobTemplate_1.AtobTemplate(), rc4Polyfill: Rc4Template_1.Rc4Template(), selfDefendingCode: selfDefendingCode, @@ -2377,16 +2599,6 @@ var StringArrayCallsWrapper = function (_AbstractCustomNode_) { } return decodeStringArrayTemplate; } - }, { - key: 'getNodeStructure', - value: function getNodeStructure() { - var decodeNodeTemplate = this.getDecodeStringArrayTemplate(); - return NodeUtils_1.NodeUtils.convertCodeToStructure(JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(StringArrayCallsWrapperTemplate_1.StringArrayCallsWrapperTemplate().formatUnicorn({ - decodeNodeTemplate: decodeNodeTemplate, - stringArrayCallsWrapperName: this.stringArrayCallsWrapperName, - stringArrayName: this.stringArrayName - }), NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET).getObfuscatedCode()); - } }]); return StringArrayCallsWrapper; @@ -2395,7 +2607,7 @@ var StringArrayCallsWrapper = function (_AbstractCustomNode_) { exports.StringArrayCallsWrapper = StringArrayCallsWrapper; /***/ }, -/* 40 */ +/* 44 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2411,12 +2623,11 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); -var StringArrayTemplate_1 = __webpack_require__(77); -var AbstractCustomNode_1 = __webpack_require__(7); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); +var StringArrayTemplate_1 = __webpack_require__(94); +var AbstractCustomNode_1 = __webpack_require__(5); +var NodeAppender_1 = __webpack_require__(3); var StringArrayNode = function (_AbstractCustomNode_) { _inherits(StringArrayNode, _AbstractCustomNode_); @@ -2445,9 +2656,12 @@ var StringArrayNode = function (_AbstractCustomNode_) { NodeAppender_1.NodeAppender.prependNode(blockScopeNode, this.getNode()); } }, { - key: 'getNodeIdentifier', - value: function getNodeIdentifier() { - return this.stringArrayName; + key: 'getCode', + value: function getCode() { + return format(StringArrayTemplate_1.StringArrayTemplate(), { + stringArrayName: this.stringArrayName, + stringArray: this.stringArray.toString() + }); } }, { key: 'getNodeData', @@ -2460,19 +2674,6 @@ var StringArrayNode = function (_AbstractCustomNode_) { this.stringArray.rotateArray(this.stringArrayRotateValue); return _get(StringArrayNode.prototype.__proto__ || Object.getPrototypeOf(StringArrayNode.prototype), 'getNode', this).call(this); } - }, { - key: 'updateNodeData', - value: function updateNodeData(data) { - this.stringArray.addToArray(data); - } - }, { - key: 'getNodeStructure', - value: function getNodeStructure() { - return NodeUtils_1.NodeUtils.convertCodeToStructure(StringArrayTemplate_1.StringArrayTemplate().formatUnicorn({ - stringArrayName: this.stringArrayName, - stringArray: this.stringArray.toString() - })); - } }]); return StringArrayNode; @@ -2482,7 +2683,7 @@ StringArrayNode.ARRAY_RANDOM_LENGTH = 4; exports.StringArrayNode = StringArrayNode; /***/ }, -/* 41 */ +/* 45 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2490,23 +2691,20 @@ exports.StringArrayNode = StringArrayNode; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); -var _get = (function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }); - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -__webpack_require__(9); -var AppendState_1 = __webpack_require__(3); +var format = __webpack_require__(7); +var AppendState_1 = __webpack_require__(1); var NoCustomNodesPreset_1 = __webpack_require__(16); -var SelfDefendingTemplate_1 = __webpack_require__(78); -var StringArrayRotateFunctionTemplate_1 = __webpack_require__(79); -var AbstractCustomNode_1 = __webpack_require__(7); +var SelfDefendingTemplate_1 = __webpack_require__(95); +var StringArrayRotateFunctionTemplate_1 = __webpack_require__(96); +var AbstractCustomNode_1 = __webpack_require__(5); var JavaScriptObfuscator_1 = __webpack_require__(10); -var NodeAppender_1 = __webpack_require__(5); -var NodeUtils_1 = __webpack_require__(1); +var NodeAppender_1 = __webpack_require__(3); var Utils_1 = __webpack_require__(0); var StringArrayRotateFunctionNode = function (_AbstractCustomNode_) { @@ -2533,31 +2731,28 @@ var StringArrayRotateFunctionNode = function (_AbstractCustomNode_) { NodeAppender_1.NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), 1); } }, { - key: 'getNode', - value: function getNode() { - return _get(StringArrayRotateFunctionNode.prototype.__proto__ || Object.getPrototypeOf(StringArrayRotateFunctionNode.prototype), 'getNode', this).call(this); - } - }, { - key: 'getNodeStructure', - value: function getNodeStructure() { + key: 'getCode', + value: function getCode() { var code = '', timesName = Utils_1.Utils.getRandomVariableName(), whileFunctionName = Utils_1.Utils.getRandomVariableName(); if (this.options.selfDefending) { - code = SelfDefendingTemplate_1.SelfDefendingTemplate().formatUnicorn({ + code = format(SelfDefendingTemplate_1.SelfDefendingTemplate(), { timesName: timesName, whileFunctionName: whileFunctionName }); } else { code = whileFunctionName + '(++' + timesName + ')'; } - return NodeUtils_1.NodeUtils.convertCodeToStructure(JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(StringArrayRotateFunctionTemplate_1.StringArrayRotateFunctionTemplate().formatUnicorn({ + return JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(format(StringArrayRotateFunctionTemplate_1.StringArrayRotateFunctionTemplate(), { code: code, timesName: timesName, stringArrayName: this.stringArrayName, stringArrayRotateValue: Utils_1.Utils.decToHex(this.stringArrayRotateValue), whileFunctionName: whileFunctionName - }), NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET).getObfuscatedCode()); + }), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, { + seed: this.options.seed + })).getObfuscatedCode(); } }]); @@ -2567,7 +2762,20 @@ var StringArrayRotateFunctionNode = function (_AbstractCustomNode_) { exports.StringArrayRotateFunctionNode = StringArrayRotateFunctionNode; /***/ }, -/* 42 */ +/* 46 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var Utils_1 = __webpack_require__(0); +exports.VisitorDirection = Utils_1.Utils.strEnumify({ + enter: 'enter', + leave: 'leave' +}); + +/***/ }, +/* 47 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2581,10 +2789,10 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var ConsoleOutputDisableExpressionNode_1 = __webpack_require__(33); +var ConsoleOutputDisableExpressionNode_1 = __webpack_require__(34); var NodeCallsControllerFunctionNode_1 = __webpack_require__(17); -var AbstractNodesGroup_1 = __webpack_require__(11); -var NodeAppender_1 = __webpack_require__(5); +var AbstractNodesGroup_1 = __webpack_require__(12); +var NodeAppender_1 = __webpack_require__(3); var Utils_1 = __webpack_require__(0); var ConsoleOutputNodesGroup = function (_AbstractNodesGroup_) { @@ -2614,7 +2822,7 @@ var ConsoleOutputNodesGroup = function (_AbstractNodesGroup_) { exports.ConsoleOutputNodesGroup = ConsoleOutputNodesGroup; /***/ }, -/* 43 */ +/* 48 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2628,10 +2836,10 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var DebugProtectionFunctionCallNode_1 = __webpack_require__(34); -var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(35); -var DebugProtectionFunctionNode_1 = __webpack_require__(36); -var AbstractNodesGroup_1 = __webpack_require__(11); +var DebugProtectionFunctionCallNode_1 = __webpack_require__(38); +var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(39); +var DebugProtectionFunctionNode_1 = __webpack_require__(40); +var AbstractNodesGroup_1 = __webpack_require__(12); var Utils_1 = __webpack_require__(0); var DebugProtectionNodesGroup = function (_AbstractNodesGroup_) { @@ -2664,7 +2872,7 @@ var DebugProtectionNodesGroup = function (_AbstractNodesGroup_) { exports.DebugProtectionNodesGroup = DebugProtectionNodesGroup; /***/ }, -/* 44 */ +/* 49 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2678,10 +2886,10 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var DomainLockNode_1 = __webpack_require__(37); +var DomainLockNode_1 = __webpack_require__(41); var NodeCallsControllerFunctionNode_1 = __webpack_require__(17); -var AbstractNodesGroup_1 = __webpack_require__(11); -var NodeAppender_1 = __webpack_require__(5); +var AbstractNodesGroup_1 = __webpack_require__(12); +var NodeAppender_1 = __webpack_require__(3); var Utils_1 = __webpack_require__(0); var DomainLockNodesGroup = function (_AbstractNodesGroup_) { @@ -2711,7 +2919,7 @@ var DomainLockNodesGroup = function (_AbstractNodesGroup_) { exports.DomainLockNodesGroup = DomainLockNodesGroup; /***/ }, -/* 45 */ +/* 50 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2725,11 +2933,11 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var AppendState_1 = __webpack_require__(3); +var AppendState_1 = __webpack_require__(1); var NodeCallsControllerFunctionNode_1 = __webpack_require__(17); -var SelfDefendingUnicodeNode_1 = __webpack_require__(38); -var AbstractNodesGroup_1 = __webpack_require__(11); -var NodeAppender_1 = __webpack_require__(5); +var SelfDefendingUnicodeNode_1 = __webpack_require__(42); +var AbstractNodesGroup_1 = __webpack_require__(12); +var NodeAppender_1 = __webpack_require__(3); var Utils_1 = __webpack_require__(0); var SelfDefendingNodesGroup = function (_AbstractNodesGroup_) { @@ -2762,7 +2970,7 @@ var SelfDefendingNodesGroup = function (_AbstractNodesGroup_) { exports.SelfDefendingNodesGroup = SelfDefendingNodesGroup; /***/ }, -/* 46 */ +/* 51 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2776,12 +2984,12 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var AppendState_1 = __webpack_require__(3); -var StringArrayCallsWrapper_1 = __webpack_require__(39); -var StringArrayNode_1 = __webpack_require__(40); -var StringArrayRotateFunctionNode_1 = __webpack_require__(41); -var AbstractNodesGroup_1 = __webpack_require__(11); -var StringArray_1 = __webpack_require__(30); +var AppendState_1 = __webpack_require__(1); +var StringArrayCallsWrapper_1 = __webpack_require__(43); +var StringArrayNode_1 = __webpack_require__(44); +var StringArrayRotateFunctionNode_1 = __webpack_require__(45); +var AbstractNodesGroup_1 = __webpack_require__(12); +var StringArrayStorage_1 = __webpack_require__(77); var Utils_1 = __webpack_require__(0); var StringArrayNodesGroup = function (_AbstractNodesGroup_) { @@ -2805,14 +3013,11 @@ var StringArrayNodesGroup = function (_AbstractNodesGroup_) { return; } if (this.options.rotateStringArray) { - this.stringArrayRotateValue = Utils_1.Utils.getRandomGenerator().integer({ - min: 100, - max: 500 - }); + this.stringArrayRotateValue = Utils_1.Utils.getRandomInteger(100, 500); } else { this.stringArrayRotateValue = 0; } - var stringArray = new StringArray_1.StringArray(); + var stringArray = new StringArrayStorage_1.StringArrayStorage(); var stringArrayNode = new StringArrayNode_1.StringArrayNode(stringArray, this.stringArrayName, this.stringArrayRotateValue, this.options); var customNodes = new Map([['stringArrayNode', stringArrayNode], ['stringArrayCallsWrapper', new StringArrayCallsWrapper_1.StringArrayCallsWrapper(this.stringArrayCallsWrapper, this.stringArrayName, stringArray, this.options)]]); if (this.options.rotateStringArray) { @@ -2828,7 +3033,7 @@ var StringArrayNodesGroup = function (_AbstractNodesGroup_) { exports.StringArrayNodesGroup = StringArrayNodesGroup; /***/ }, -/* 47 */ +/* 52 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2844,13 +3049,212 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var AbstractNodeObfuscator_1 = __webpack_require__(8); -var IdentifierReplacer_1 = __webpack_require__(12); +var AbstractNodeTransformer_1 = __webpack_require__(9); +var BinaryExpressionControlFlowReplacer_1 = __webpack_require__(54); +var ControlFlowStorage_1 = __webpack_require__(76); +var ControlFlowStorageNode_1 = __webpack_require__(37); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeAppender_1 = __webpack_require__(3); +var Utils_1 = __webpack_require__(0); +var NodeUtils_1 = __webpack_require__(8); -var CatchClauseObfuscator = function (_AbstractNodeObfuscat) { - _inherits(CatchClauseObfuscator, _AbstractNodeObfuscat); +var FunctionControlFlowTransformer = function (_AbstractNodeTransfor) { + _inherits(FunctionControlFlowTransformer, _AbstractNodeTransfor); + + function FunctionControlFlowTransformer(nodes, options) { + _classCallCheck(this, FunctionControlFlowTransformer); + + return _possibleConstructorReturn(this, (FunctionControlFlowTransformer.__proto__ || Object.getPrototypeOf(FunctionControlFlowTransformer)).call(this, nodes, options)); + } + + _createClass(FunctionControlFlowTransformer, [{ + key: 'transformNode', + value: function transformNode(functionNode) { + this.changeFunctionBodyControlFlow(functionNode); + } + }, { + key: 'changeFunctionBodyControlFlow', + value: function changeFunctionBodyControlFlow(functionNode) { + var _this2 = this; + + if (Node_1.Node.isArrowFunctionExpressionNode(functionNode)) { + return; + } + var controlFlowStorage = new ControlFlowStorage_1.ControlFlowStorage(); + var controlFlowStorageCustomNodeName = Utils_1.Utils.getRandomVariableName(6); + console.log(NodeUtils_1.NodeUtils.getNodeBlockScopeDepth(functionNode.body)); + estraverse.replace(functionNode.body, { + enter: function enter(node, parentNode) { + var controlFlowReplacer = FunctionControlFlowTransformer.controlFlowReplacers.get(node.type); + if (!controlFlowReplacer) { + return; + } + var controlFlowStorageCallCustomNode = new controlFlowReplacer(_this2.nodes, _this2.options).replace(node, parentNode, controlFlowStorage, controlFlowStorageCustomNodeName); + if (!controlFlowStorageCallCustomNode) { + return; + } + var statementNode = controlFlowStorageCallCustomNode.getNode()[0]; + if (!statementNode || !Node_1.Node.isExpressionStatementNode(statementNode)) { + throw new Error('`controlFlowStorageCallCustomNode.getNode()` should returns array with `ExpressionStatement` node'); + } + return statementNode.expression; + } + }); + var controlFlowStorageCustomNode = new ControlFlowStorageNode_1.ControlFlowStorageNode(controlFlowStorage, controlFlowStorageCustomNodeName, this.options); + NodeAppender_1.NodeAppender.prependNode(functionNode.body, controlFlowStorageCustomNode.getNode()); + } + }]); + + return FunctionControlFlowTransformer; +}(AbstractNodeTransformer_1.AbstractNodeTransformer); + +FunctionControlFlowTransformer.controlFlowReplacers = new Map([[NodeType_1.NodeType.BinaryExpression, BinaryExpressionControlFlowReplacer_1.BinaryExpressionControlFlowReplacer]]); +exports.FunctionControlFlowTransformer = FunctionControlFlowTransformer; + +/***/ }, +/* 53 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Utils_1 = __webpack_require__(0); + +var AbstractControlFlowReplacer = function () { + function AbstractControlFlowReplacer(nodes, options) { + _classCallCheck(this, AbstractControlFlowReplacer); + + this.nodes = nodes; + this.options = options; + } + + _createClass(AbstractControlFlowReplacer, null, [{ + key: "getStorageKey", + value: function getStorageKey() { + return Utils_1.Utils.getRandomGenerator().string({ + length: 3, + pool: Utils_1.Utils.randomGeneratorPool + }); + } + }]); + + return AbstractControlFlowReplacer; +}(); + +exports.AbstractControlFlowReplacer = AbstractControlFlowReplacer; + +/***/ }, +/* 54 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var escodegen = __webpack_require__(11); +var AbstractControlFlowReplacer_1 = __webpack_require__(53); +var BinaryExpressionFunctionNode_1 = __webpack_require__(35); +var ControlFlowStorageCallNode_1 = __webpack_require__(36); + +var BinaryExpressionControlFlowReplacer = function (_AbstractControlFlowR) { + _inherits(BinaryExpressionControlFlowReplacer, _AbstractControlFlowR); + + function BinaryExpressionControlFlowReplacer() { + _classCallCheck(this, BinaryExpressionControlFlowReplacer); + + return _possibleConstructorReturn(this, (BinaryExpressionControlFlowReplacer.__proto__ || Object.getPrototypeOf(BinaryExpressionControlFlowReplacer)).apply(this, arguments)); + } + + _createClass(BinaryExpressionControlFlowReplacer, [{ + key: 'replace', + value: function replace(binaryExpressionNode, parentNode, controlFlowStorage, controlFlowStorageCustomNodeName) { + var key = AbstractControlFlowReplacer_1.AbstractControlFlowReplacer.getStorageKey(); + controlFlowStorage.set(key, new BinaryExpressionFunctionNode_1.BinaryExpressionFunctionNode(binaryExpressionNode.operator, this.options)); + return new ControlFlowStorageCallNode_1.ControlFlowStorageCallNode(controlFlowStorageCustomNodeName, key, BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.left), BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.right), this.options); + } + }], [{ + key: 'getExpressionValue', + value: function getExpressionValue(expressionNode) { + return escodegen.generate(expressionNode, { + sourceMapWithCode: true + }).code; + } + }]); + + return BinaryExpressionControlFlowReplacer; +}(AbstractControlFlowReplacer_1.AbstractControlFlowReplacer); + +exports.BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer; + +/***/ }, +/* 55 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var NodeType_1 = __webpack_require__(6); +var FunctionControlFlowTransformer_1 = __webpack_require__(52); +var AbstractNodeTransformersFactory_1 = __webpack_require__(22); + +var NodeControlFlowTransformersFactory = function (_AbstractNodeTransfor) { + _inherits(NodeControlFlowTransformersFactory, _AbstractNodeTransfor); + + function NodeControlFlowTransformersFactory() { + _classCallCheck(this, NodeControlFlowTransformersFactory); + + var _this = _possibleConstructorReturn(this, (NodeControlFlowTransformersFactory.__proto__ || Object.getPrototypeOf(NodeControlFlowTransformersFactory)).apply(this, arguments)); + + _this.nodeTransformers = new Map([[NodeType_1.NodeType.FunctionDeclaration, [FunctionControlFlowTransformer_1.FunctionControlFlowTransformer]], [NodeType_1.NodeType.FunctionExpression, [FunctionControlFlowTransformer_1.FunctionControlFlowTransformer]]]); + return _this; + } + + return NodeControlFlowTransformersFactory; +}(AbstractNodeTransformersFactory_1.AbstractNodeTransformersFactory); + +exports.NodeControlFlowTransformersFactory = NodeControlFlowTransformersFactory; + +/***/ }, +/* 56 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var estraverse = __webpack_require__(4); +var NodeType_1 = __webpack_require__(6); +var AbstractNodeTransformer_1 = __webpack_require__(9); +var IdentifierReplacer_1 = __webpack_require__(13); +var Node_1 = __webpack_require__(2); +var NodeUtils_1 = __webpack_require__(8); + +var CatchClauseObfuscator = function (_AbstractNodeTransfor) { + _inherits(CatchClauseObfuscator, _AbstractNodeTransfor); function CatchClauseObfuscator(nodes, options) { _classCallCheck(this, CatchClauseObfuscator); @@ -2862,8 +3266,8 @@ var CatchClauseObfuscator = function (_AbstractNodeObfuscat) { } _createClass(CatchClauseObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(catchClauseNode) { + key: 'transformNode', + value: function transformNode(catchClauseNode) { this.storeCatchClauseParam(catchClauseNode); this.replaceCatchClauseParam(catchClauseNode); } @@ -2872,7 +3276,7 @@ var CatchClauseObfuscator = function (_AbstractNodeObfuscat) { value: function storeCatchClauseParam(catchClauseNode) { var _this2 = this; - NodeUtils_1.NodeUtils.typedReplace(catchClauseNode.param, NodeType_1.NodeType.Identifier, { + NodeUtils_1.NodeUtils.typedTraverse(catchClauseNode.param, NodeType_1.NodeType.Identifier, { enter: function enter(node) { return _this2.identifierReplacer.storeNames(node.name); } @@ -2894,12 +3298,12 @@ var CatchClauseObfuscator = function (_AbstractNodeObfuscat) { }]); return CatchClauseObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); exports.CatchClauseObfuscator = CatchClauseObfuscator; /***/ }, -/* 48 */ +/* 57 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2915,13 +3319,13 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var AbstractNodeObfuscator_1 = __webpack_require__(8); -var IdentifierReplacer_1 = __webpack_require__(12); +var AbstractNodeTransformer_1 = __webpack_require__(9); +var IdentifierReplacer_1 = __webpack_require__(13); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeUtils_1 = __webpack_require__(8); -var FunctionDeclarationObfuscator = function (_AbstractNodeObfuscat) { - _inherits(FunctionDeclarationObfuscator, _AbstractNodeObfuscat); +var FunctionDeclarationObfuscator = function (_AbstractNodeTransfor) { + _inherits(FunctionDeclarationObfuscator, _AbstractNodeTransfor); function FunctionDeclarationObfuscator(nodes, options) { _classCallCheck(this, FunctionDeclarationObfuscator); @@ -2933,8 +3337,8 @@ var FunctionDeclarationObfuscator = function (_AbstractNodeObfuscat) { } _createClass(FunctionDeclarationObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(functionDeclarationNode, parentNode) { + key: 'transformNode', + value: function transformNode(functionDeclarationNode, parentNode) { var blockScopeOfFunctionDeclarationNode = NodeUtils_1.NodeUtils.getBlockScopeOfNode(functionDeclarationNode); if (blockScopeOfFunctionDeclarationNode.type === NodeType_1.NodeType.Program) { return; @@ -2947,7 +3351,7 @@ var FunctionDeclarationObfuscator = function (_AbstractNodeObfuscat) { value: function storeFunctionName(functionDeclarationNode) { var _this2 = this; - NodeUtils_1.NodeUtils.typedReplace(functionDeclarationNode.id, NodeType_1.NodeType.Identifier, { + NodeUtils_1.NodeUtils.typedTraverse(functionDeclarationNode.id, NodeType_1.NodeType.Identifier, { enter: function enter(node) { return _this2.identifierReplacer.storeNames(node.name); } @@ -2969,12 +3373,12 @@ var FunctionDeclarationObfuscator = function (_AbstractNodeObfuscat) { }]); return FunctionDeclarationObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); exports.FunctionDeclarationObfuscator = FunctionDeclarationObfuscator; /***/ }, -/* 49 */ +/* 58 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2990,13 +3394,13 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var AbstractNodeObfuscator_1 = __webpack_require__(8); -var IdentifierReplacer_1 = __webpack_require__(12); +var AbstractNodeTransformer_1 = __webpack_require__(9); +var IdentifierReplacer_1 = __webpack_require__(13); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeUtils_1 = __webpack_require__(8); -var FunctionObfuscator = function (_AbstractNodeObfuscat) { - _inherits(FunctionObfuscator, _AbstractNodeObfuscat); +var FunctionObfuscator = function (_AbstractNodeTransfor) { + _inherits(FunctionObfuscator, _AbstractNodeTransfor); function FunctionObfuscator(nodes, options) { _classCallCheck(this, FunctionObfuscator); @@ -3008,8 +3412,8 @@ var FunctionObfuscator = function (_AbstractNodeObfuscat) { } _createClass(FunctionObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(functionNode) { + key: 'transformNode', + value: function transformNode(functionNode) { this.storeFunctionParams(functionNode); this.replaceFunctionParams(functionNode); } @@ -3019,7 +3423,7 @@ var FunctionObfuscator = function (_AbstractNodeObfuscat) { var _this2 = this; functionNode.params.forEach(function (paramsNode) { - NodeUtils_1.NodeUtils.typedReplace(paramsNode, NodeType_1.NodeType.Identifier, { + NodeUtils_1.NodeUtils.typedTraverse(paramsNode, NodeType_1.NodeType.Identifier, { enter: function enter(node) { return _this2.identifierReplacer.storeNames(node.name); } @@ -3031,7 +3435,7 @@ var FunctionObfuscator = function (_AbstractNodeObfuscat) { value: function replaceFunctionParams(functionNode) { var _this3 = this; - var replaceVisitor = { + var traverseVisitor = { enter: function enter(node, parentNode) { if (Node_1.Node.isReplaceableIdentifierNode(node, parentNode)) { var newNodeName = _this3.identifierReplacer.replace(node.name); @@ -3043,19 +3447,19 @@ var FunctionObfuscator = function (_AbstractNodeObfuscat) { } }; functionNode.params.forEach(function (paramsNode) { - estraverse.replace(paramsNode, replaceVisitor); + return estraverse.replace(paramsNode, traverseVisitor); }); - estraverse.replace(functionNode.body, replaceVisitor); + estraverse.replace(functionNode.body, traverseVisitor); } }]); return FunctionObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); exports.FunctionObfuscator = FunctionObfuscator; /***/ }, -/* 50 */ +/* 59 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3071,13 +3475,13 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var AbstractNodeObfuscator_1 = __webpack_require__(8); -var IdentifierReplacer_1 = __webpack_require__(12); +var AbstractNodeTransformer_1 = __webpack_require__(9); +var IdentifierReplacer_1 = __webpack_require__(13); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeUtils_1 = __webpack_require__(8); -var LabeledStatementObfuscator = function (_AbstractNodeObfuscat) { - _inherits(LabeledStatementObfuscator, _AbstractNodeObfuscat); +var LabeledStatementObfuscator = function (_AbstractNodeTransfor) { + _inherits(LabeledStatementObfuscator, _AbstractNodeTransfor); function LabeledStatementObfuscator(nodes, options) { _classCallCheck(this, LabeledStatementObfuscator); @@ -3089,8 +3493,8 @@ var LabeledStatementObfuscator = function (_AbstractNodeObfuscat) { } _createClass(LabeledStatementObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(labeledStatementNode) { + key: 'transformNode', + value: function transformNode(labeledStatementNode) { this.storeLabeledStatementName(labeledStatementNode); this.replaceLabeledStatementName(labeledStatementNode); } @@ -3099,7 +3503,7 @@ var LabeledStatementObfuscator = function (_AbstractNodeObfuscat) { value: function storeLabeledStatementName(labeledStatementNode) { var _this2 = this; - NodeUtils_1.NodeUtils.typedReplace(labeledStatementNode.label, NodeType_1.NodeType.Identifier, { + NodeUtils_1.NodeUtils.typedTraverse(labeledStatementNode.label, NodeType_1.NodeType.Identifier, { enter: function enter(node) { return _this2.identifierReplacer.storeNames(node.name); } @@ -3121,12 +3525,12 @@ var LabeledStatementObfuscator = function (_AbstractNodeObfuscat) { }]); return LabeledStatementObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); exports.LabeledStatementObfuscator = LabeledStatementObfuscator; /***/ }, -/* 51 */ +/* 60 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3142,15 +3546,15 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var escodegen = __webpack_require__(13); -var AbstractNodeObfuscator_1 = __webpack_require__(8); -var BooleanLiteralReplacer_1 = __webpack_require__(56); +var escodegen = __webpack_require__(11); +var AbstractNodeTransformer_1 = __webpack_require__(9); +var BooleanLiteralReplacer_1 = __webpack_require__(66); var Node_1 = __webpack_require__(2); -var NumberLiteralReplacer_1 = __webpack_require__(22); +var NumberLiteralReplacer_1 = __webpack_require__(23); var StringLiteralReplacer_1 = __webpack_require__(19); -var LiteralObfuscator = function (_AbstractNodeObfuscat) { - _inherits(LiteralObfuscator, _AbstractNodeObfuscat); +var LiteralObfuscator = function (_AbstractNodeTransfor) { + _inherits(LiteralObfuscator, _AbstractNodeTransfor); function LiteralObfuscator() { _classCallCheck(this, LiteralObfuscator); @@ -3159,8 +3563,8 @@ var LiteralObfuscator = function (_AbstractNodeObfuscat) { } _createClass(LiteralObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(literalNode, parentNode) { + key: 'transformNode', + value: function transformNode(literalNode, parentNode) { if (Node_1.Node.isPropertyNode(parentNode) && parentNode.key === literalNode) { return; } @@ -3186,12 +3590,12 @@ var LiteralObfuscator = function (_AbstractNodeObfuscat) { }]); return LiteralObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); exports.LiteralObfuscator = LiteralObfuscator; /***/ }, -/* 52 */ +/* 61 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3205,15 +3609,15 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var escodegen = __webpack_require__(13); +var escodegen = __webpack_require__(11); var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var AbstractNodeObfuscator_1 = __webpack_require__(8); +var AbstractNodeTransformer_1 = __webpack_require__(9); var Node_1 = __webpack_require__(2); var StringLiteralReplacer_1 = __webpack_require__(19); -var MemberExpressionObfuscator = function (_AbstractNodeObfuscat) { - _inherits(MemberExpressionObfuscator, _AbstractNodeObfuscat); +var MemberExpressionObfuscator = function (_AbstractNodeTransfor) { + _inherits(MemberExpressionObfuscator, _AbstractNodeTransfor); function MemberExpressionObfuscator() { _classCallCheck(this, MemberExpressionObfuscator); @@ -3222,11 +3626,11 @@ var MemberExpressionObfuscator = function (_AbstractNodeObfuscat) { } _createClass(MemberExpressionObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(memberExpressionNode) { + key: 'transformNode', + value: function transformNode(memberExpressionNode) { var _this2 = this; - estraverse.replace(memberExpressionNode.property, { + estraverse.traverse(memberExpressionNode.property, { enter: function enter(node, parentNode) { if (Node_1.Node.isLiteralNode(node)) { _this2.obfuscateLiteralProperty(node); @@ -3245,8 +3649,8 @@ var MemberExpressionObfuscator = function (_AbstractNodeObfuscat) { }, { key: 'obfuscateIdentifierProperty', value: function obfuscateIdentifierProperty(node) { - var nodeValue = node.name, - literalNode = { + var nodeValue = node.name; + var literalNode = { raw: '\'' + nodeValue + '\'', 'x-verbatim-property': { content: new StringLiteralReplacer_1.StringLiteralReplacer(this.nodes, this.options).replace(nodeValue), @@ -3271,12 +3675,12 @@ var MemberExpressionObfuscator = function (_AbstractNodeObfuscat) { }]); return MemberExpressionObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); exports.MemberExpressionObfuscator = MemberExpressionObfuscator; /***/ }, -/* 53 */ +/* 62 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3291,13 +3695,13 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var estraverse = __webpack_require__(4); -var AbstractNodeObfuscator_1 = __webpack_require__(8); +var AbstractNodeTransformer_1 = __webpack_require__(9); var Node_1 = __webpack_require__(2); var Utils_1 = __webpack_require__(0); var StringLiteralReplacer_1 = __webpack_require__(19); -var MethodDefinitionObfuscator = function (_AbstractNodeObfuscat) { - _inherits(MethodDefinitionObfuscator, _AbstractNodeObfuscat); +var MethodDefinitionObfuscator = function (_AbstractNodeTransfor) { + _inherits(MethodDefinitionObfuscator, _AbstractNodeTransfor); function MethodDefinitionObfuscator() { _classCallCheck(this, MethodDefinitionObfuscator); @@ -3306,8 +3710,8 @@ var MethodDefinitionObfuscator = function (_AbstractNodeObfuscat) { } _createClass(MethodDefinitionObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(methodDefinitionNode, parentNode) { + key: 'transformNode', + value: function transformNode(methodDefinitionNode, parentNode) { this.replaceMethodName(methodDefinitionNode); } }, { @@ -3329,13 +3733,13 @@ var MethodDefinitionObfuscator = function (_AbstractNodeObfuscat) { }]); return MethodDefinitionObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); MethodDefinitionObfuscator.ignoredNames = ['constructor']; exports.MethodDefinitionObfuscator = MethodDefinitionObfuscator; /***/ }, -/* 54 */ +/* 63 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3349,15 +3753,15 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var escodegen = __webpack_require__(13); +var escodegen = __webpack_require__(11); var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var AbstractNodeObfuscator_1 = __webpack_require__(8); +var AbstractNodeTransformer_1 = __webpack_require__(9); var Node_1 = __webpack_require__(2); var Utils_1 = __webpack_require__(0); -var ObjectExpressionObfuscator = function (_AbstractNodeObfuscat) { - _inherits(ObjectExpressionObfuscator, _AbstractNodeObfuscat); +var ObjectExpressionObfuscator = function (_AbstractNodeTransfor) { + _inherits(ObjectExpressionObfuscator, _AbstractNodeTransfor); function ObjectExpressionObfuscator() { _classCallCheck(this, ObjectExpressionObfuscator); @@ -3366,15 +3770,15 @@ var ObjectExpressionObfuscator = function (_AbstractNodeObfuscat) { } _createClass(ObjectExpressionObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(objectExpressionNode) { + key: 'transformNode', + value: function transformNode(objectExpressionNode) { var _this2 = this; objectExpressionNode.properties.forEach(function (property) { if (property.shorthand) { property.shorthand = false; } - estraverse.replace(property.key, { + estraverse.traverse(property.key, { enter: function enter(node, parentNode) { if (Node_1.Node.isLiteralNode(node)) { _this2.obfuscateLiteralPropertyKey(node); @@ -3400,8 +3804,8 @@ var ObjectExpressionObfuscator = function (_AbstractNodeObfuscat) { }, { key: 'obfuscateIdentifierPropertyKey', value: function obfuscateIdentifierPropertyKey(node) { - var nodeValue = node.name, - literalNode = { + var nodeValue = node.name; + var literalNode = { raw: '\'' + nodeValue + '\'', 'x-verbatim-property': { content: '\'' + Utils_1.Utils.stringToUnicodeEscapeSequence(nodeValue) + '\'', @@ -3416,12 +3820,12 @@ var ObjectExpressionObfuscator = function (_AbstractNodeObfuscat) { }]); return ObjectExpressionObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); exports.ObjectExpressionObfuscator = ObjectExpressionObfuscator; /***/ }, -/* 55 */ +/* 64 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3437,13 +3841,13 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var AbstractNodeObfuscator_1 = __webpack_require__(8); -var IdentifierReplacer_1 = __webpack_require__(12); +var AbstractNodeTransformer_1 = __webpack_require__(9); +var IdentifierReplacer_1 = __webpack_require__(13); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeUtils_1 = __webpack_require__(8); -var VariableDeclarationObfuscator = function (_AbstractNodeObfuscat) { - _inherits(VariableDeclarationObfuscator, _AbstractNodeObfuscat); +var VariableDeclarationObfuscator = function (_AbstractNodeTransfor) { + _inherits(VariableDeclarationObfuscator, _AbstractNodeTransfor); function VariableDeclarationObfuscator(nodes, options) { _classCallCheck(this, VariableDeclarationObfuscator); @@ -3455,8 +3859,8 @@ var VariableDeclarationObfuscator = function (_AbstractNodeObfuscat) { } _createClass(VariableDeclarationObfuscator, [{ - key: 'obfuscateNode', - value: function obfuscateNode(variableDeclarationNode, parentNode) { + key: 'transformNode', + value: function transformNode(variableDeclarationNode, parentNode) { var blockScopeOfVariableDeclarationNode = NodeUtils_1.NodeUtils.getBlockScopeOfNode(variableDeclarationNode); if (blockScopeOfVariableDeclarationNode.type === NodeType_1.NodeType.Program) { return; @@ -3471,7 +3875,7 @@ var VariableDeclarationObfuscator = function (_AbstractNodeObfuscat) { var _this2 = this; variableDeclarationNode.declarations.forEach(function (declarationNode) { - NodeUtils_1.NodeUtils.typedReplace(declarationNode.id, NodeType_1.NodeType.Identifier, { + NodeUtils_1.NodeUtils.typedTraverse(declarationNode.id, NodeType_1.NodeType.Identifier, { enter: function enter(node) { return _this2.identifierReplacer.storeNames(node.name); } @@ -3494,12 +3898,54 @@ var VariableDeclarationObfuscator = function (_AbstractNodeObfuscat) { }]); return VariableDeclarationObfuscator; -}(AbstractNodeObfuscator_1.AbstractNodeObfuscator); +}(AbstractNodeTransformer_1.AbstractNodeTransformer); exports.VariableDeclarationObfuscator = VariableDeclarationObfuscator; /***/ }, -/* 56 */ +/* 65 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var NodeType_1 = __webpack_require__(6); +var CatchClauseObfuscator_1 = __webpack_require__(56); +var FunctionDeclarationObfuscator_1 = __webpack_require__(57); +var FunctionObfuscator_1 = __webpack_require__(58); +var LabeledStatementObfuscator_1 = __webpack_require__(59); +var LiteralObfuscator_1 = __webpack_require__(60); +var MemberExpressionObfuscator_1 = __webpack_require__(61); +var MethodDefinitionObfuscator_1 = __webpack_require__(62); +var ObjectExpressionObfuscator_1 = __webpack_require__(63); +var VariableDeclarationObfuscator_1 = __webpack_require__(64); +var AbstractNodeTransformersFactory_1 = __webpack_require__(22); + +var NodeObfuscatorsFactory = function (_AbstractNodeTransfor) { + _inherits(NodeObfuscatorsFactory, _AbstractNodeTransfor); + + function NodeObfuscatorsFactory() { + _classCallCheck(this, NodeObfuscatorsFactory); + + var _this = _possibleConstructorReturn(this, (NodeObfuscatorsFactory.__proto__ || Object.getPrototypeOf(NodeObfuscatorsFactory)).apply(this, arguments)); + + _this.nodeTransformers = new Map([[NodeType_1.NodeType.ArrowFunctionExpression, [FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.ClassDeclaration, [FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator]], [NodeType_1.NodeType.CatchClause, [CatchClauseObfuscator_1.CatchClauseObfuscator]], [NodeType_1.NodeType.FunctionDeclaration, [FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator, FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.FunctionExpression, [FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.MemberExpression, [MemberExpressionObfuscator_1.MemberExpressionObfuscator]], [NodeType_1.NodeType.MethodDefinition, [MethodDefinitionObfuscator_1.MethodDefinitionObfuscator]], [NodeType_1.NodeType.ObjectExpression, [ObjectExpressionObfuscator_1.ObjectExpressionObfuscator]], [NodeType_1.NodeType.VariableDeclaration, [VariableDeclarationObfuscator_1.VariableDeclarationObfuscator]], [NodeType_1.NodeType.LabeledStatement, [LabeledStatementObfuscator_1.LabeledStatementObfuscator]], [NodeType_1.NodeType.Literal, [LiteralObfuscator_1.LiteralObfuscator]]]); + return _this; + } + + return NodeObfuscatorsFactory; +}(AbstractNodeTransformersFactory_1.AbstractNodeTransformersFactory); + +exports.NodeObfuscatorsFactory = NodeObfuscatorsFactory; + +/***/ }, +/* 66 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3538,7 +3984,7 @@ var BooleanLiteralReplacer = function (_AbstractReplacer_1$A) { exports.BooleanLiteralReplacer = BooleanLiteralReplacer; /***/ }, -/* 57 */ +/* 67 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3559,12 +4005,12 @@ var __decorate = undefined && undefined.__decorate || function (decorators, targ var __metadata = undefined && undefined.__metadata || function (k, v) { if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; -var class_validator_1 = __webpack_require__(83); -var TSourceMapMode_1 = __webpack_require__(80); -var TStringArrayEncoding_1 = __webpack_require__(81); -var DefaultPreset_1 = __webpack_require__(23); -var OptionsNormalizer_1 = __webpack_require__(58); -var ValidationErrorsFormatter_1 = __webpack_require__(59); +var class_validator_1 = __webpack_require__(99); +var TSourceMapMode_1 = __webpack_require__(97); +var TStringArrayEncoding_1 = __webpack_require__(98); +var DefaultPreset_1 = __webpack_require__(24); +var OptionsNormalizer_1 = __webpack_require__(68); +var ValidationErrorsFormatter_1 = __webpack_require__(69); var Options = function Options(obfuscatorOptions) { _classCallCheck(this, Options); @@ -3583,6 +4029,7 @@ Options.validatorOptions = { } }; __decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "compact", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "controlFlowFlattening", void 0); __decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "debugProtection", void 0); __decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "debugProtectionInterval", void 0); __decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "disableConsoleOutput", void 0); @@ -3593,6 +4040,7 @@ __decorate([class_validator_1.IsArray(), class_validator_1.ArrayUnique(), class_ each: true }), __metadata('design:type', Array)], Options.prototype, "reservedNames", void 0); __decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "rotateStringArray", void 0); +__decorate([class_validator_1.IsNumber(), __metadata('design:type', Number)], Options.prototype, "seed", void 0); __decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "selfDefending", void 0); __decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "sourceMap", void 0); __decorate([class_validator_1.IsString(), class_validator_1.ValidateIf(function (options) { @@ -3611,7 +4059,7 @@ exports.Options = Options; var _a, _b; /***/ }, -/* 58 */ +/* 68 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3778,7 +4226,7 @@ OptionsNormalizer.normalizerRules = [OptionsNormalizer.domainLockRule, OptionsNo exports.OptionsNormalizer = OptionsNormalizer; /***/ }, -/* 59 */ +/* 69 */ /***/ function(module, exports) { "use strict"; @@ -3827,8 +4275,8 @@ var ValidationErrorsFormatter = function () { }, { key: "formatError", value: function formatError(validationError) { - var errorString = "`" + validationError.property + "` errors:\n", - constraints = validationError.constraints; + var constraints = validationError.constraints; + var errorString = "`" + validationError.property + "` errors:\n"; for (var constraint in constraints) { if (!constraints.hasOwnProperty(constraint)) { continue; @@ -3845,7 +4293,7 @@ var ValidationErrorsFormatter = function () { exports.ValidationErrorsFormatter = ValidationErrorsFormatter; /***/ }, -/* 60 */ +/* 70 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3857,24 +4305,23 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var FunctionDeclarationCalleeDataExtractor_1 = __webpack_require__(61); -var FunctionExpressionCalleeDataExtractor_1 = __webpack_require__(62); -var ObjectExpressionCalleeDataExtractor_1 = __webpack_require__(63); +var FunctionDeclarationCalleeDataExtractor_1 = __webpack_require__(71); +var FunctionExpressionCalleeDataExtractor_1 = __webpack_require__(72); +var ObjectExpressionCalleeDataExtractor_1 = __webpack_require__(73); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeUtils_1 = __webpack_require__(8); var StackTraceAnalyzer = function () { - function StackTraceAnalyzer(blockScopeBody) { + function StackTraceAnalyzer() { _classCallCheck(this, StackTraceAnalyzer); this.calleeDataExtractors = new Map([[NodeType_1.NodeType.FunctionDeclaration, FunctionDeclarationCalleeDataExtractor_1.FunctionDeclarationCalleeDataExtractor], [NodeType_1.NodeType.FunctionExpression, FunctionExpressionCalleeDataExtractor_1.FunctionExpressionCalleeDataExtractor], [NodeType_1.NodeType.ObjectExpression, ObjectExpressionCalleeDataExtractor_1.ObjectExpressionCalleeDataExtractor]]); - this.blockScopeBody = blockScopeBody; } _createClass(StackTraceAnalyzer, [{ key: 'analyze', - value: function analyze() { - return this.analyzeRecursive(this.blockScopeBody); + value: function analyze(blockScopeBody) { + return this.analyzeRecursive(blockScopeBody); } }, { key: 'analyzeRecursive', @@ -3938,7 +4385,7 @@ StackTraceAnalyzer.limitThreshold = 0.002; exports.StackTraceAnalyzer = StackTraceAnalyzer; /***/ }, -/* 61 */ +/* 71 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3950,7 +4397,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons var estraverse = __webpack_require__(4); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeUtils_1 = __webpack_require__(8); var FunctionDeclarationCalleeDataExtractor = function () { function FunctionDeclarationCalleeDataExtractor(blockScopeBody, callee) { @@ -3997,7 +4444,7 @@ var FunctionDeclarationCalleeDataExtractor = function () { exports.FunctionDeclarationCalleeDataExtractor = FunctionDeclarationCalleeDataExtractor; /***/ }, -/* 62 */ +/* 72 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -4009,7 +4456,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons var estraverse = __webpack_require__(4); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeUtils_1 = __webpack_require__(8); var FunctionExpressionCalleeDataExtractor = function () { function FunctionExpressionCalleeDataExtractor(blockScopeBody, callee) { @@ -4059,7 +4506,7 @@ var FunctionExpressionCalleeDataExtractor = function () { exports.FunctionExpressionCalleeDataExtractor = FunctionExpressionCalleeDataExtractor; /***/ }, -/* 63 */ +/* 73 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -4071,7 +4518,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons var estraverse = __webpack_require__(4); var Node_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); +var NodeUtils_1 = __webpack_require__(8); var ObjectExpressionCalleeDataExtractor = function () { function ObjectExpressionCalleeDataExtractor(blockScopeBody, callee) { @@ -4191,7 +4638,210 @@ var ObjectExpressionCalleeDataExtractor = function () { exports.ObjectExpressionCalleeDataExtractor = ObjectExpressionCalleeDataExtractor; /***/ }, -/* 64 */ +/* 74 */ +/***/ function(module, exports) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var ArrayStorage = function () { + function ArrayStorage() { + _classCallCheck(this, ArrayStorage); + + this.storage = []; + } + + _createClass(ArrayStorage, [{ + key: "get", + value: function get(key) { + var value = this.storage[key]; + if (!value) { + throw new Error("No value found in array storage with key `" + key + "`"); + } + return value; + } + }, { + key: "getKeyOf", + value: function getKeyOf(value) { + return this.storage.indexOf(value); + } + }, { + key: "getLength", + value: function getLength() { + return this.storage.length; + } + }, { + key: "getStorage", + value: function getStorage() { + return this.storage; + } + }, { + key: "set", + value: function set(key, value) { + this.storage.push(value); + } + }]); + + return ArrayStorage; +}(); + +exports.ArrayStorage = ArrayStorage; + +/***/ }, +/* 75 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Utils_1 = __webpack_require__(0); + +var MapStorage = function () { + function MapStorage() { + _classCallCheck(this, MapStorage); + + this.storage = new Map(); + } + + _createClass(MapStorage, [{ + key: "get", + value: function get(key) { + var value = this.storage.get(key); + if (!value) { + throw new Error("No value found in map storage with key `" + key + "`"); + } + return value; + } + }, { + key: "getKeyOf", + value: function getKeyOf(value) { + return Utils_1.Utils.mapGetFirstKeyOf(this.storage, value); + } + }, { + key: "getLength", + value: function getLength() { + return Array.from(this.storage).length; + } + }, { + key: "getStorage", + value: function getStorage() { + return this.storage; + } + }, { + key: "set", + value: function set(key, value) { + this.storage.set(key, value); + } + }]); + + return MapStorage; +}(); + +exports.MapStorage = MapStorage; + +/***/ }, +/* 76 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; })(); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var MapStorage_1 = __webpack_require__(75); + +var ControlFlowStorage = function (_MapStorage_1$MapStor) { + _inherits(ControlFlowStorage, _MapStorage_1$MapStor); + + function ControlFlowStorage() { + _classCallCheck(this, ControlFlowStorage); + + return _possibleConstructorReturn(this, (ControlFlowStorage.__proto__ || Object.getPrototypeOf(ControlFlowStorage)).apply(this, arguments)); + } + + _createClass(ControlFlowStorage, [{ + key: 'toString', + value: function toString() { + return Array.from(this.storage).reduce(function (controlFlowStorageItems, _ref) { + var _ref2 = _slicedToArray(_ref, 2), + key = _ref2[0], + value = _ref2[1]; + + controlFlowStorageItems.push(key + ': ' + value.getCode()); + return controlFlowStorageItems; + }, []).join(','); + } + }]); + + return ControlFlowStorage; +}(MapStorage_1.MapStorage); + +exports.ControlFlowStorage = ControlFlowStorage; + +/***/ }, +/* 77 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ArrayStorage_1 = __webpack_require__(74); +var Utils_1 = __webpack_require__(0); + +var StringArrayStorage = function (_ArrayStorage_1$Array) { + _inherits(StringArrayStorage, _ArrayStorage_1$Array); + + function StringArrayStorage() { + _classCallCheck(this, StringArrayStorage); + + return _possibleConstructorReturn(this, (StringArrayStorage.__proto__ || Object.getPrototypeOf(StringArrayStorage)).apply(this, arguments)); + } + + _createClass(StringArrayStorage, [{ + key: 'rotateArray', + value: function rotateArray(rotationValue) { + this.storage = Utils_1.Utils.arrayRotate(this.storage, rotationValue); + } + }, { + key: 'toString', + value: function toString() { + return this.storage.map(function (value) { + return '\'' + value + '\''; + }).toString(); + } + }]); + + return StringArrayStorage; +}(ArrayStorage_1.ArrayStorage); + +exports.StringArrayStorage = StringArrayStorage; + +/***/ }, +/* 78 */ /***/ function(module, exports) { "use strict"; @@ -4203,7 +4853,7 @@ function AtobTemplate() { exports.AtobTemplate = AtobTemplate; /***/ }, -/* 65 */ +/* 79 */ /***/ function(module, exports) { "use strict"; @@ -4215,7 +4865,7 @@ function Rc4Template() { exports.Rc4Template = Rc4Template; /***/ }, -/* 66 */ +/* 80 */ /***/ function(module, exports) { "use strict"; @@ -4227,7 +4877,7 @@ function SingleNodeCallControllerTemplate() { exports.SingleNodeCallControllerTemplate = SingleNodeCallControllerTemplate; /***/ }, -/* 67 */ +/* 81 */ /***/ function(module, exports) { "use strict"; @@ -4239,7 +4889,43 @@ function ConsoleOutputDisableExpressionTemplate() { exports.ConsoleOutputDisableExpressionTemplate = ConsoleOutputDisableExpressionTemplate; /***/ }, -/* 68 */ +/* 82 */ +/***/ function(module, exports) { + +"use strict"; +"use strict"; + +function BinaryExpressionFunctionTemplate() { + return "\n function {functionName} (x, y) {\n return x {operator} y;\n }\n "; +} +exports.BinaryExpressionFunctionTemplate = BinaryExpressionFunctionTemplate; + +/***/ }, +/* 83 */ +/***/ function(module, exports) { + +"use strict"; +"use strict"; + +function ControlFlowStorageCallTemplate() { + return '{controlFlowStorageName}.{controlFlowStorageKey}({leftValue}, {rightValue})'; +} +exports.ControlFlowStorageCallTemplate = ControlFlowStorageCallTemplate; + +/***/ }, +/* 84 */ +/***/ function(module, exports) { + +"use strict"; +"use strict"; + +function ControlFlowStorageTemplate() { + return "\n var {controlFlowStorageName} = { {controlFlowStorage} };\n "; +} +exports.ControlFlowStorageTemplate = ControlFlowStorageTemplate; + +/***/ }, +/* 85 */ /***/ function(module, exports) { "use strict"; @@ -4251,7 +4937,7 @@ function DebugProtectionFunctionCallTemplate() { exports.DebugProtectionFunctionCallTemplate = DebugProtectionFunctionCallTemplate; /***/ }, -/* 69 */ +/* 86 */ /***/ function(module, exports) { "use strict"; @@ -4263,20 +4949,19 @@ function DebugProtectionFunctionIntervalTemplate() { exports.DebugProtectionFunctionIntervalTemplate = DebugProtectionFunctionIntervalTemplate; /***/ }, -/* 70 */ -/***/ function(module, exports, __webpack_require__) { +/* 87 */ +/***/ function(module, exports) { "use strict"; "use strict"; -var Utils_1 = __webpack_require__(0); function DebugProtectionFunctionTemplate() { - return '\n var {debugProtectionFunctionName} = function () {\n function debuggerProtection (counter) {\n if ((\'\' + counter / counter)[\'length\'] !== 1 || counter % 20 === 0) {\n (function () {}.constructor(\'debugger\')());\n } else {\n [].filter.constructor(' + Utils_1.Utils.stringToJSFuck('debugger') + ')();\n }\n \n debuggerProtection(++counter);\n }\n \n try {\n debuggerProtection(0);\n } catch (y) {}\n };\n '; + return "\n var {debugProtectionFunctionName} = function () {\n function debuggerProtection (counter) {\n if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {\n (function () {}.constructor('debugger')());\n } else {\n (function () {}.constructor('debugger')());\n }\n \n debuggerProtection(++counter);\n }\n \n try {\n debuggerProtection(0);\n } catch (y) {}\n };\n "; } exports.DebugProtectionFunctionTemplate = DebugProtectionFunctionTemplate; /***/ }, -/* 71 */ +/* 88 */ /***/ function(module, exports) { "use strict"; @@ -4288,7 +4973,7 @@ function DomainLockNodeTemplate() { exports.DomainLockNodeTemplate = DomainLockNodeTemplate; /***/ }, -/* 72 */ +/* 89 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -4301,7 +4986,7 @@ function SelfDefendingTemplate() { exports.SelfDefendingTemplate = SelfDefendingTemplate; /***/ }, -/* 73 */ +/* 90 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -4314,7 +4999,7 @@ function SelfDefendingTemplate() { exports.SelfDefendingTemplate = SelfDefendingTemplate; /***/ }, -/* 74 */ +/* 91 */ /***/ function(module, exports) { "use strict"; @@ -4326,7 +5011,7 @@ function StringArrayBase64DecodeNodeTemplate() { exports.StringArrayBase64DecodeNodeTemplate = StringArrayBase64DecodeNodeTemplate; /***/ }, -/* 75 */ +/* 92 */ /***/ function(module, exports) { "use strict"; @@ -4338,7 +5023,7 @@ function StringArrayCallsWrapperTemplate() { exports.StringArrayCallsWrapperTemplate = StringArrayCallsWrapperTemplate; /***/ }, -/* 76 */ +/* 93 */ /***/ function(module, exports) { "use strict"; @@ -4350,7 +5035,7 @@ function StringArrayRc4DecodeNodeTemplate() { exports.StringArrayRc4DecodeNodeTemplate = StringArrayRc4DecodeNodeTemplate; /***/ }, -/* 77 */ +/* 94 */ /***/ function(module, exports) { "use strict"; @@ -4362,7 +5047,7 @@ function StringArrayTemplate() { exports.StringArrayTemplate = StringArrayTemplate; /***/ }, -/* 78 */ +/* 95 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -4375,7 +5060,7 @@ function SelfDefendingTemplate() { exports.SelfDefendingTemplate = SelfDefendingTemplate; /***/ }, -/* 79 */ +/* 96 */ /***/ function(module, exports) { "use strict"; @@ -4387,53 +5072,52 @@ function StringArrayRotateFunctionTemplate() { exports.StringArrayRotateFunctionTemplate = StringArrayRotateFunctionTemplate; /***/ }, -/* 80 */ +/* 97 */ /***/ function(module, exports) { "use strict"; "use strict"; /***/ }, -/* 81 */ +/* 98 */ /***/ function(module, exports) { "use strict"; "use strict"; /***/ }, -/* 82 */ -/***/ function(module, exports) { - -module.exports = require("chance"); - -/***/ }, -/* 83 */ +/* 99 */ /***/ function(module, exports) { module.exports = require("class-validator"); /***/ }, -/* 84 */ +/* 100 */ /***/ function(module, exports) { module.exports = require("commander"); /***/ }, -/* 85 */ +/* 101 */ /***/ function(module, exports) { module.exports = require("fs"); /***/ }, -/* 86 */ +/* 102 */ +/***/ function(module, exports) { + +module.exports = require("is-equal"); + +/***/ }, +/* 103 */ /***/ function(module, exports) { module.exports = require("mkdirp"); /***/ }, -/* 87 */, -/* 88 */, -/* 89 */ +/* 104 */, +/* 105 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -4441,7 +5125,7 @@ module.exports = require("mkdirp"); var JavaScriptObfuscator_1 = __webpack_require__(10); if (!global._babelPolyfill) { - __webpack_require__(26); + __webpack_require__(28); } module.exports = JavaScriptObfuscator_1.JavaScriptObfuscator; diff --git a/package.json b/package.json index ce62c719..85c2375d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-obfuscator", - "version": "0.8.1", + "version": "0.8.2", "description": "JavaScript obfuscator", "keywords": [ "obfuscator", @@ -27,27 +27,28 @@ "escodegen": "1.8.1", "esprima": "3.1.1", "estraverse": "4.2.0", - "format-unicorn": "1.1.0", + "is-equal": "^1.5.3", "mkdirp": "0.5.1", - "source-map-support": "0.4.6" + "source-map-support": "0.4.6", + "string-template": "^1.0.0" }, "devDependencies": { "@types/chai": "3.4.34", "@types/chance": "0.7.31", - "@types/commander": "2.3.30", + "@types/commander": "2.3.31", "@types/escodegen": "0.0.6", "@types/esprima": "2.1.33", "@types/estraverse": "0.0.6", "@types/estree": "0.0.34", - "@types/format-unicorn": "0.0.29", "@types/joi": "9.0.33", "@types/mkdirp": "0.3.29", "@types/mocha": "2.2.33", - "@types/node": "6.0.47", - "@types/sinon": "1.16.31", + "@types/node": "6.0.49", + "@types/sinon": "1.16.32", + "@types/string-template": "^1.0.2", "awesome-typescript-loader": "2.2.4", "babel-cli": "6.18.0", - "babel-loader": "6.2.7", + "babel-loader": "6.2.8", "babel-preset-es2015": "6.18.0", "chai": "3.5.0", "coveralls": "2.11.15", @@ -55,9 +56,9 @@ "mocha": "3.1.2", "sinon": "2.0.0-pre.3", "ts-node": "1.7.0", - "tslint": "3.15.1", + "tslint": "4.0.1", "typescript": "2.0.10", - "webpack": "2.1.0-beta.25", + "webpack": "2.1.0-beta.27", "webpack-node-externals": "1.5.4" }, "repository": { diff --git a/src/JavaScriptObfuscator.ts b/src/JavaScriptObfuscator.ts index 561e4d6b..c4354131 100644 --- a/src/JavaScriptObfuscator.ts +++ b/src/JavaScriptObfuscator.ts @@ -3,6 +3,7 @@ import { IObfuscatorOptions } from './interfaces/IObfuscatorOptions'; import { JavaScriptObfuscatorCLI } from './cli/JavaScriptObfuscatorCLI'; import { JavaScriptObfuscatorInternal } from './JavaScriptObfuscatorInternal'; +import { Options } from './options/Options'; export class JavaScriptObfuscator { /** @@ -11,14 +12,11 @@ export class JavaScriptObfuscator { * @returns {string} */ public static obfuscate (sourceCode: string, obfuscatorOptions: IObfuscatorOptions = {}): IObfuscationResult { - let javaScriptObfuscator: JavaScriptObfuscatorInternal = new JavaScriptObfuscatorInternal( - sourceCode, - obfuscatorOptions + const javaScriptObfuscator: JavaScriptObfuscatorInternal = new JavaScriptObfuscatorInternal( + new Options(obfuscatorOptions) ); - javaScriptObfuscator.obfuscate(); - - return javaScriptObfuscator.getObfuscationResult(); + return javaScriptObfuscator.obfuscate(sourceCode); } /** diff --git a/src/JavaScriptObfuscatorInternal.ts b/src/JavaScriptObfuscatorInternal.ts index 4c32e958..a98f991d 100644 --- a/src/JavaScriptObfuscatorInternal.ts +++ b/src/JavaScriptObfuscatorInternal.ts @@ -2,47 +2,43 @@ import * as esprima from 'esprima'; import * as escodegen from 'escodegen'; import * as ESTree from 'estree'; -import { IObfuscatorOptions } from './interfaces/IObfuscatorOptions'; +import { Chance } from 'chance'; + import { IGeneratorOutput } from './interfaces/IGeneratorOutput'; import { IObfuscationResult } from './interfaces/IObfuscationResult'; import { IOptions } from './interfaces/IOptions'; import { ObfuscationResult } from './ObfuscationResult'; import { Obfuscator } from './Obfuscator'; -import { Options } from './options/Options'; import { SourceMapCorrector } from './SourceMapCorrector'; +import { Utils } from './Utils'; export class JavaScriptObfuscatorInternal { /** * @type {GenerateOptions} */ - private static escodegenParams: escodegen.GenerateOptions = { + private static readonly escodegenParams: escodegen.GenerateOptions = { verbatim: 'x-verbatim-property', sourceMapWithCode: true }; /** - * @type {IGeneratorOutput} + * @type {esprima.Options} */ - private generatorOutput: IGeneratorOutput; + private static readonly esprimaParams: esprima.Options = { + loc: true + }; /** * @type {IOptions} */ - private options: IOptions; + private readonly options: IOptions; /** - * @type {string} + * @param options */ - private sourceCode: string; - - /** - * @param sourceCode - * @param obfuscatorOptions - */ - constructor (sourceCode: string, obfuscatorOptions: IObfuscatorOptions = {}) { - this.sourceCode = sourceCode; - this.options = new Options(obfuscatorOptions); + constructor (options: IOptions) { + this.options = options; } /** @@ -50,7 +46,7 @@ export class JavaScriptObfuscatorInternal { * @param astTree * @param options */ - private static generateCode (sourceCode: string, astTree: ESTree.Node, options: IOptions): IGeneratorOutput { + private static generateCode (sourceCode: string, astTree: ESTree.Program, options: IOptions): IGeneratorOutput { const escodegenParams: escodegen.GenerateOptions = Object.assign( {}, JavaScriptObfuscatorInternal.escodegenParams @@ -73,26 +69,37 @@ export class JavaScriptObfuscatorInternal { } /** + * @param generatorOutput * @returns {IObfuscationResult} */ - public getObfuscationResult (): IObfuscationResult { + public getObfuscationResult (generatorOutput: IGeneratorOutput): IObfuscationResult { return new SourceMapCorrector( new ObfuscationResult( - this.generatorOutput.code, - this.generatorOutput.map + generatorOutput.code, + generatorOutput.map ), this.options.sourceMapBaseUrl + this.options.sourceMapFileName, this.options.sourceMapMode ).correct(); } - public obfuscate (): void { - let astTree: ESTree.Node = esprima.parse(this.sourceCode, { - loc: true - }); + /** + * @param sourceCode + * @returns {IObfuscationResult} + */ + public obfuscate (sourceCode: string): IObfuscationResult { + if (this.options.seed !== 0) { + Utils.setRandomGenerator(new Chance(this.options.seed)); + } - astTree = new Obfuscator(this.options).obfuscateNode(astTree); + const astTree: ESTree.Program = esprima.parse(sourceCode, JavaScriptObfuscatorInternal.esprimaParams); + const obfuscatedAstTree: ESTree.Program = new Obfuscator(this.options).obfuscateAstTree(astTree); + const generatorOutput: IGeneratorOutput = JavaScriptObfuscatorInternal.generateCode( + sourceCode, + obfuscatedAstTree, + this.options + ); - this.generatorOutput = JavaScriptObfuscatorInternal.generateCode(this.sourceCode, astTree, this.options); + return this.getObfuscationResult(generatorOutput); } } diff --git a/src/Obfuscator.ts b/src/Obfuscator.ts index a031a92e..a5aa7a23 100644 --- a/src/Obfuscator.ts +++ b/src/Obfuscator.ts @@ -2,39 +2,34 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; import { TNodeGroup } from './types/TNodeGroup'; -import { TNodeObfuscator } from './types/TNodeObfuscator'; +import { TVisitorDirection } from './types/TVisitorDirection'; import { ICustomNode } from './interfaces/custom-nodes/ICustomNode'; import { IObfuscator } from './interfaces/IObfuscator'; import { IOptions } from './interfaces/IOptions'; +import { INodeTransformer } from './interfaces/INodeTransformer'; +import { INodeTransformersFactory } from './interfaces/INodeTransformersFactory'; import { IStackTraceData } from './interfaces/stack-trace-analyzer/IStackTraceData'; import { AppendState } from './enums/AppendState'; -import { NodeType } from './enums/NodeType'; +import { VisitorDirection } from './enums/VisitorDirection'; -import { CatchClauseObfuscator } from './node-obfuscators/CatchClauseObfuscator'; import { ConsoleOutputNodesGroup } from './node-groups/ConsoleOutputNodesGroup'; import { DebugProtectionNodesGroup } from './node-groups/DebugProtectionNodesGroup'; import { DomainLockNodesGroup } from './node-groups/DomainLockNodesGroup'; -import { FunctionDeclarationObfuscator } from './node-obfuscators/FunctionDeclarationObfuscator'; -import { FunctionObfuscator } from './node-obfuscators/FunctionObfuscator'; -import { LabeledStatementObfuscator } from './node-obfuscators/LabeledStatementObfuscator'; -import { LiteralObfuscator } from './node-obfuscators/LiteralObfuscator'; -import { MemberExpressionObfuscator } from './node-obfuscators/MemberExpressionObfuscator'; -import { MethodDefinitionObfuscator } from './node-obfuscators/MethodDefinitionObfuscator'; import { Node } from './node/Node'; +import { NodeControlFlowTransformersFactory } from './node-transformers/node-control-flow-transformers/factory/NodeControlFlowTransformersFactory'; +import { NodeObfuscatorsFactory } from './node-transformers/node-obfuscators/factory/NodeObfuscatorsFactory'; import { NodeUtils } from './node/NodeUtils'; -import { ObjectExpressionObfuscator } from './node-obfuscators/ObjectExpressionObfuscator'; import { SelfDefendingNodesGroup } from './node-groups/SelfDefendingNodesGroup'; import { StackTraceAnalyzer } from './stack-trace-analyzer/StackTraceAnalyzer'; import { StringArrayNodesGroup } from './node-groups/StringArrayNodesGroup'; -import { VariableDeclarationObfuscator } from './node-obfuscators/VariableDeclarationObfuscator'; export class Obfuscator implements IObfuscator { /** * @type {TNodeGroup[]} */ - private static nodeGroups: TNodeGroup[] = [ + private static readonly nodeGroups: TNodeGroup[] = [ DomainLockNodesGroup, SelfDefendingNodesGroup, ConsoleOutputNodesGroup, @@ -42,35 +37,15 @@ export class Obfuscator implements IObfuscator { StringArrayNodesGroup ]; - /** - * @type {Map} - */ - private static nodeObfuscators: Map = new Map ([ - [NodeType.ArrowFunctionExpression, [FunctionObfuscator]], - [NodeType.ClassDeclaration, [FunctionDeclarationObfuscator]], - [NodeType.CatchClause, [CatchClauseObfuscator]], - [NodeType.FunctionDeclaration, [ - FunctionDeclarationObfuscator, - FunctionObfuscator - ]], - [NodeType.FunctionExpression, [FunctionObfuscator]], - [NodeType.MemberExpression, [MemberExpressionObfuscator]], - [NodeType.MethodDefinition, [MethodDefinitionObfuscator]], - [NodeType.ObjectExpression, [ObjectExpressionObfuscator]], - [NodeType.VariableDeclaration, [VariableDeclarationObfuscator]], - [NodeType.LabeledStatement, [LabeledStatementObfuscator]], - [NodeType.Literal, [LiteralObfuscator]] - ]); - /** * @type {Map} */ - private customNodes: Map = new Map (); + private customNodes: Map ; /** * @type {IOptions} */ - private options: IOptions; + private readonly options: IOptions; /** * @param options @@ -80,34 +55,47 @@ export class Obfuscator implements IObfuscator { } /** - * @param node - * @returns {ESTree.Node} + * @param astTree + * @returns {ESTree.Program} */ - public obfuscateNode (node: ESTree.Program): ESTree.Node { - if (Node.isProgramNode(node) && !node.body.length) { - return node; + public obfuscateAstTree (astTree: ESTree.Program): ESTree.Program { + if (Node.isProgramNode(astTree) && !astTree.body.length) { + return astTree; } - NodeUtils.parentize(node); + NodeUtils.parentize(astTree); + this.initializeCustomNodes(new StackTraceAnalyzer().analyze(astTree.body)); - const stackTraceData: IStackTraceData[] = new StackTraceAnalyzer(node.body).analyze(); + // tasks before nodes transformation + this.beforeTransform(astTree); - this.initializeCustomNodes(stackTraceData); + // first pass: control flow flattening + if (this.options.controlFlowFlattening) { + this.transformAstTree(astTree, VisitorDirection.leave, new NodeControlFlowTransformersFactory( + this.customNodes, + this.options + )); + } - this.beforeObfuscation(node); - this.obfuscate(node); - this.afterObfuscation(node); + // second pass: nodes obfuscation + this.transformAstTree(astTree, VisitorDirection.enter, new NodeObfuscatorsFactory( + this.customNodes, + this.options + )); - return node; + // tasks after nodes transformation + this.afterTransform(astTree); + + return astTree; } /** * @param astTree */ - private afterObfuscation (astTree: ESTree.Node): void { - this.customNodes.forEach((node: ICustomNode) => { - if (node.getAppendState() === AppendState.AfterObfuscation) { - node.appendNode(astTree); + private afterTransform (astTree: ESTree.Program): void { + this.customNodes.forEach((customNode: ICustomNode) => { + if (customNode.getAppendState() === AppendState.AfterObfuscation) { + customNode.appendNode(astTree); } }); } @@ -115,10 +103,10 @@ export class Obfuscator implements IObfuscator { /** * @param astTree */ - private beforeObfuscation (astTree: ESTree.Node): void { - this.customNodes.forEach((node: ICustomNode) => { - if (node.getAppendState() === AppendState.BeforeObfuscation) { - node.appendNode(astTree); + private beforeTransform (astTree: ESTree.Program): void { + this.customNodes.forEach((customNode: ICustomNode) => { + if (customNode.getAppendState() === AppendState.BeforeObfuscation) { + customNode.appendNode(astTree); } }); }; @@ -127,7 +115,7 @@ export class Obfuscator implements IObfuscator { * @param stackTraceData */ private initializeCustomNodes (stackTraceData: IStackTraceData[]): void { - let customNodes: [string, ICustomNode][] = []; + const customNodes: [string, ICustomNode][] = []; Obfuscator.nodeGroups.forEach((nodeGroupConstructor: TNodeGroup) => { const nodeGroupNodes: Map | undefined = new nodeGroupConstructor( @@ -144,30 +132,23 @@ export class Obfuscator implements IObfuscator { this.customNodes = new Map (customNodes); } - /** - * @param node - * @param parentNode + * @param astTree + * @param direction + * @param nodeTransformersFactory */ - private initializeNodeObfuscators (node: ESTree.Node, parentNode: ESTree.Node): void { - let nodeObfuscators: TNodeObfuscator[] | undefined = Obfuscator.nodeObfuscators.get(node.type); + private transformAstTree ( + astTree: ESTree.Program, + direction: TVisitorDirection, + nodeTransformersFactory: INodeTransformersFactory + ): void { + estraverse.traverse(astTree, { + [direction]: (node: ESTree.Node, parentNode: ESTree.Node): void => { + const nodeTransformers: INodeTransformer[] = nodeTransformersFactory.initializeNodeTransformers(node.type); - if (!nodeObfuscators) { - return; - } - - nodeObfuscators.forEach((obfuscator: TNodeObfuscator) => { - new obfuscator(this.customNodes, this.options).obfuscateNode(node, parentNode); - }); - } - - /** - * @param node - */ - private obfuscate (node: ESTree.Node): void { - estraverse.traverse(node, { - enter: (node: ESTree.Node, parentNode: ESTree.Node): void => { - this.initializeNodeObfuscators(node, parentNode); + nodeTransformers.forEach((nodeTransformer: INodeTransformer) => { + nodeTransformer.transformNode(node, parentNode); + }); } }); } diff --git a/src/SourceMapCorrector.ts b/src/SourceMapCorrector.ts index 52c937b7..8c60cd4c 100644 --- a/src/SourceMapCorrector.ts +++ b/src/SourceMapCorrector.ts @@ -12,22 +12,22 @@ export class SourceMapCorrector implements ISourceMapCorrector { /** * @type {string} */ - private obfuscatedCode: string; + private readonly obfuscatedCode: string; /** * @type {string} */ - private sourceMap: string; + private readonly sourceMap: string; /** * @type {TSourceMapMode} */ - private sourceMapMode: TSourceMapMode; + private readonly sourceMapMode: TSourceMapMode; /** * @type {string} */ - private sourceMapUrl: string; + private readonly sourceMapUrl: string; /** * @param obfuscationResult diff --git a/src/StringArray.ts b/src/StringArray.ts deleted file mode 100644 index 99943427..00000000 --- a/src/StringArray.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Utils } from './Utils'; - -export class StringArray { - /** - * @type {string[]} - */ - private array: string[] = []; - - /** - * @param value - */ - public addToArray (value: string): void { - this.array.push(value); - } - - /** - * @returns {string[]} - */ - public getArray (): string[] { - return this.array; - } - - /** - * @param value - * @returns {number} - */ - public getIndexOf(value: string): number { - return this.array.indexOf(value); - } - - /** - * @returns {number} - */ - public getLength (): number { - return this.array.length; - } - - /** - * @param rotationValue - */ - public rotateArray (rotationValue: number): void { - this.array = Utils.arrayRotate(this.array, rotationValue); - } - - /** - * @returns {string} - */ - public toString (): string { - return this.array.map((value: string) => { - return `'${value}'`; - }).toString() - } -} diff --git a/src/Utils.ts b/src/Utils.ts index 02d14e1c..57988d7c 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -2,11 +2,18 @@ import { Chance } from 'chance'; import { JSFuck } from './enums/JSFuck'; +const isEqual = require('is-equal'); + export class Utils { /** - * @type {Chance.Chance} + * @type {string} */ - private static randomGenerator: Chance.Chance = new Chance(); + public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + /** + * @type {Chance.Chance | Chance.SeededChance} + */ + private static randomGenerator: Chance.Chance | Chance.SeededChance = new Chance(); /** * @param array @@ -99,13 +106,44 @@ export class Utils { return domain; } + /** + * @param min + * @param max + * @returns {number} + */ + public static getRandomFloat (min: number, max: number): number { + return Utils.getRandomGenerator().floating({ + min: min, + max: max, + fixed: 7 + }); + } + /** * @returns {Chance.Chance} */ public static getRandomGenerator (): Chance.Chance { + const randomGenerator: Chance.Chance = Utils.randomGenerator; + + if (!randomGenerator) { + throw new Error(`\`randomGenerator\` static property is undefined`); + } + return Utils.randomGenerator; } + /** + * @param min + * @param max + * @returns {number} + */ + public static getRandomInteger (min: number, max: number): number { + return Utils.getRandomGenerator().integer({ + min: min, + max: max + }); + } + /** * @param length * @returns {string} @@ -117,10 +155,7 @@ export class Utils { return `${prefix}${( Utils.decToHex( - Utils.getRandomGenerator().integer({ - min: rangeMinInteger, - max: rangeMaxInteger - }) + Utils.getRandomInteger(rangeMinInteger, rangeMaxInteger) ) ).substr(0, length)}`; } @@ -140,7 +175,7 @@ export class Utils { result: string = ''; while (i1 < s1.length || i2 < s2.length) { - if (Math.random() < 0.5 && i2 < s2.length) { + if (Utils.getRandomFloat(0, 1) < 0.5 && i2 < s2.length) { result += s2.charAt(++i2); } else { result += s1.charAt(++i1); @@ -150,13 +185,16 @@ export class Utils { return result; }; - const customPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + const randomString: string = Utils.randomGenerator.string({ + length: length, + pool: Utils.randomGeneratorPool + }); - let randomString: string = Utils.randomGenerator.string({length: length, pool: customPool}), - randomStringDiff: string = randomString.replace( - new RegExp('[' + escapeRegExp(str) + ']', 'g'), - ''), - randomStringDiffArray: string[] = randomStringDiff.split(''); + let randomStringDiff: string = randomString.replace( + new RegExp('[' + escapeRegExp(str) + ']', 'g'), + ''); + + const randomStringDiffArray: string[] = randomStringDiff.split(''); Utils.randomGenerator.shuffle(randomStringDiffArray); randomStringDiff = randomStringDiffArray.join(''); @@ -173,6 +211,21 @@ export class Utils { return number % 1 === 0; } + /** + * @param map + * @param value + * @returns {any} + */ + public static mapGetFirstKeyOf(map: Map , value: any): any { + for (var [key, storageValue] of map) { + if (isEqual(value, storageValue)) { + return key; + } + } + + return null; + } + /** * RC4 symmetric cipher encryption/decryption * https://gist.github.com/farhadi/2185197 @@ -213,6 +266,13 @@ export class Utils { return result; } + /** + * @param randomGenerator + */ + public static setRandomGenerator (randomGenerator: Chance.Chance | Chance.SeededChance): void { + Utils.randomGenerator = randomGenerator; + } + /** * @param obj * @returns {T} diff --git a/src/cli/CLIUtils.ts b/src/cli/CLIUtils.ts index 12caa909..0f8f5a23 100644 --- a/src/cli/CLIUtils.ts +++ b/src/cli/CLIUtils.ts @@ -10,14 +10,14 @@ export class CLIUtils { /** * @type {string[]} */ - private static availableInputExtensions: string[] = [ + private static readonly availableInputExtensions: string[] = [ '.js' ]; /** * @type {BufferEncoding} */ - private static encoding: BufferEncoding = 'utf8'; + private static readonly encoding: BufferEncoding = 'utf8'; /** * @param outputPath diff --git a/src/cli/JavaScriptObfuscatorCLI.ts b/src/cli/JavaScriptObfuscatorCLI.ts index 6776daba..e29b6386 100644 --- a/src/cli/JavaScriptObfuscatorCLI.ts +++ b/src/cli/JavaScriptObfuscatorCLI.ts @@ -19,7 +19,7 @@ export class JavaScriptObfuscatorCLI { /** * @type {string[]} */ - private arguments: string[]; + private readonly arguments: string[]; /** * @type {commander.ICommand} @@ -69,7 +69,7 @@ export class JavaScriptObfuscatorCLI { * @returns {string} */ private static parseSourceMapMode (value: string): string { - let availableMode: boolean = Object + const availableMode: boolean = Object .keys(SourceMapMode) .some((key: string): boolean => { return SourceMapMode[key] === value; @@ -121,8 +121,8 @@ export class JavaScriptObfuscatorCLI { * @returns {IObfuscatorOptions} */ private buildOptions (): IObfuscatorOptions { - let obfuscatorOptions: IObfuscatorOptions = {}, - availableOptions: string[] = Object.keys(DEFAULT_PRESET); + const obfuscatorOptions: IObfuscatorOptions = {}; + const availableOptions: string[] = Object.keys(DEFAULT_PRESET); for (const option in this.commands) { if (!this.commands.hasOwnProperty(option)) { @@ -145,12 +145,14 @@ export class JavaScriptObfuscatorCLI { .usage(' [options]') .option('-o, --output ', 'Output path for obfuscated code') .option('--compact ', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean) + .option('--controlFlowFlattening ', 'Enables control flow flattening', JavaScriptObfuscatorCLI.parseBoolean) .option('--debugProtection ', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean) .option('--debugProtectionInterval ', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean) .option('--disableConsoleOutput ', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean) .option('--domainLock ', 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)', (val: string) => val.split(',')) .option('--reservedNames ', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', (val: string) => val.split(',')) .option('--rotateStringArray ', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean) + .option('--seed ', 'Sets seed for random generator. This is useful for creating repeatable results.', parseFloat) .option('--selfDefending ', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean) .option('--sourceMap ', 'Enables source map generation', JavaScriptObfuscatorCLI.parseBoolean) .option('--sourceMapBaseUrl ', 'Sets base url to the source map import url when `--sourceMapMode=separate`') @@ -179,8 +181,8 @@ export class JavaScriptObfuscatorCLI { } private processData (): void { - let options: IObfuscatorOptions = this.buildOptions(), - outputCodePath: string = CLIUtils.getOutputCodePath((this.commands).output, this.inputPath); + const options: IObfuscatorOptions = this.buildOptions(); + const outputCodePath: string = CLIUtils.getOutputCodePath((this.commands).output, this.inputPath); if (options.sourceMap) { this.processDataWithSourceMap(outputCodePath, options); @@ -194,7 +196,7 @@ export class JavaScriptObfuscatorCLI { * @param options */ private processDataWithoutSourceMap (outputCodePath: string, options: IObfuscatorOptions): void { - let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(this.data, options).getObfuscatedCode(); + const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(this.data, options).getObfuscatedCode(); CLIUtils.writeFile(outputCodePath, obfuscatedCode); } @@ -204,7 +206,7 @@ export class JavaScriptObfuscatorCLI { * @param options */ private processDataWithSourceMap (outputCodePath: string, options: IObfuscatorOptions): void { - let outputSourceMapPath: string = CLIUtils.getOutputSourceMapPath( + const outputSourceMapPath: string = CLIUtils.getOutputSourceMapPath( outputCodePath, options.sourceMapFileName || '' ); diff --git a/src/custom-nodes/AbstractCustomNode.ts b/src/custom-nodes/AbstractCustomNode.ts index 00aa6a3c..b0ff8f45 100644 --- a/src/custom-nodes/AbstractCustomNode.ts +++ b/src/custom-nodes/AbstractCustomNode.ts @@ -5,6 +5,7 @@ import { IOptions } from '../interfaces/IOptions'; import { TStatement } from '../types/TStatement'; import { AppendState } from '../enums/AppendState'; +import { NodeUtils } from '../node/NodeUtils'; export abstract class AbstractCustomNode implements ICustomNode { /** @@ -15,7 +16,7 @@ export abstract class AbstractCustomNode implements ICustomNode { /** * @type {IOptions} */ - protected options: IOptions; + protected readonly options: IOptions; /** * @param options @@ -36,6 +37,11 @@ export abstract class AbstractCustomNode implements ICustomNode { return this.appendState; } + /** + * @returns {string} + */ + public abstract getCode (): string; + /** * @returns {TStatement[]} */ @@ -53,5 +59,7 @@ export abstract class AbstractCustomNode implements ICustomNode { /** * @returns {TStatement[]} */ - protected abstract getNodeStructure (): TStatement[]; + protected getNodeStructure (): TStatement[] { + return NodeUtils.convertCodeToStructure(this.getCode()); + } } diff --git a/src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts b/src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts index 89dadd35..2ebe9eee 100644 --- a/src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts +++ b/src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts @@ -1,7 +1,6 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { TStatement } from '../../types/TStatement'; import { IOptions } from '../../interfaces/IOptions'; import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData'; @@ -12,7 +11,6 @@ import { ConsoleOutputDisableExpressionTemplate } from '../../templates/custom-n import { AbstractCustomNode } from '../AbstractCustomNode'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; import { Utils } from '../../Utils'; export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode { @@ -68,27 +66,12 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode { } /** - * JSCrush version of following code - * - * (function () { - * var _console = []["filter"]["constructor"]("return this")().console; - * var _function = function () {}; - * - * _console.log = _function; - * _console.info = _function; - * _console.warn = _function; - * _console.error = _function; - * _console - * })(); - * - * @returns {TStatement[]} + * @returns {string} */ - protected getNodeStructure (): TStatement[] { - return NodeUtils.convertCodeToStructure( - ConsoleOutputDisableExpressionTemplate().formatUnicorn({ - consoleLogDisableFunctionName: Utils.getRandomVariableName(), - singleNodeCallControllerFunctionName: this.callsControllerFunctionName - }) - ); + public getCode (): string { + return format(ConsoleOutputDisableExpressionTemplate(), { + consoleLogDisableFunctionName: Utils.getRandomVariableName(), + singleNodeCallControllerFunctionName: this.callsControllerFunctionName + }); } } diff --git a/src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts b/src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts new file mode 100644 index 00000000..1455262d --- /dev/null +++ b/src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts @@ -0,0 +1,49 @@ +import * as format from 'string-template'; + +import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement'; + +import { IOptions } from '../../../interfaces/IOptions'; + +import { AppendState } from '../../../enums/AppendState'; + +import { BinaryExpressionFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate'; + +import { AbstractCustomNode } from '../../AbstractCustomNode'; +import { Utils } from '../../../Utils'; + +export class BinaryExpressionFunctionNode extends AbstractCustomNode { + /** + * @type {AppendState} + */ + protected appendState: AppendState = AppendState.BeforeObfuscation; + + /** + * @type {string} + */ + private operator: string; + + /** + * @param operator + * @param options + */ + constructor (operator: string, options: IOptions) { + super(options); + + this.operator = operator; + } + + /** + * @param blockScopeNode + */ + public appendNode (blockScopeNode: TNodeWithBlockStatement): void {} + + /** + * @returns {string} + */ + public getCode (): string { + return format(BinaryExpressionFunctionTemplate(), { + functionName: Utils.getRandomVariableName(1), + operator: this.operator + }); + } +} diff --git a/src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode.ts b/src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode.ts new file mode 100644 index 00000000..274a5bf4 --- /dev/null +++ b/src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode.ts @@ -0,0 +1,80 @@ +import * as format from 'string-template'; + +import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement'; + +import { IOptions } from '../../../interfaces/IOptions'; + +import { AppendState } from '../../../enums/AppendState'; + +import { ControlFlowStorageCallTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallTemplate'; + +import { AbstractCustomNode } from '../../AbstractCustomNode'; +import { NodeAppender } from '../../../node/NodeAppender'; + +export class ControlFlowStorageCallNode extends AbstractCustomNode { + /** + * @type {AppendState} + */ + protected appendState: AppendState = AppendState.AfterObfuscation; + + /** + * @type {string} + */ + private controlFlowStorageKey: string; + + /** + * @type {string} + */ + private controlFlowStorageName: string; + + /** + * @type {string} + */ + private leftValue: string; + + /** + * @type {string} + */ + private rightValue: string; + + /** + * @param controlFlowStorageName + * @param controlFlowStorageKey + * @param leftValue + * @param rightValue + * @param options + */ + constructor ( + controlFlowStorageName: string, + controlFlowStorageKey: string, + leftValue: string, + rightValue: string, + options: IOptions + ) { + super(options); + + this.controlFlowStorageName = controlFlowStorageName; + this.controlFlowStorageKey = controlFlowStorageKey; + this.leftValue = leftValue; + this.rightValue = rightValue; + } + + /** + * @param blockScopeNode + */ + public appendNode (blockScopeNode: TNodeWithBlockStatement): void { + NodeAppender.prependNode(blockScopeNode, this.getNode()); + } + + /** + * @returns {string} + */ + public getCode (): string { + return format(ControlFlowStorageCallTemplate(), { + controlFlowStorageKey: this.controlFlowStorageKey, + controlFlowStorageName: this.controlFlowStorageName, + leftValue: this.leftValue, + rightValue: this.rightValue + }); + } +} diff --git a/src/custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts b/src/custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts new file mode 100644 index 00000000..a27dfef8 --- /dev/null +++ b/src/custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts @@ -0,0 +1,64 @@ +import * as format from 'string-template'; + +import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; + +import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../interfaces/IOptions'; +import { IStorage } from '../../interfaces/IStorage'; + +import { AppendState } from '../../enums/AppendState'; + +import { ControlFlowStorageTemplate } from '../../templates/custom-nodes/control-flow-storage-nodes/ControlFlowStorageTemplate'; + +import { AbstractCustomNode } from '../AbstractCustomNode'; +import { NodeAppender } from '../../node/NodeAppender'; + +export class ControlFlowStorageNode extends AbstractCustomNode { + /** + * @type {AppendState} + */ + protected appendState: AppendState = AppendState.AfterObfuscation; + + /** + * @type {IStorage } + */ + private controlFlowStorage: IStorage ; + + /** + * @type {string} + */ + private controlFlowStorageName: string; + + /** + * @param controlFlowStorage + * @param controlFlowStorageName + * @param options + */ + constructor ( + controlFlowStorage: IStorage , + controlFlowStorageName: string, + options: IOptions + ) { + super(options); + + this.controlFlowStorage = controlFlowStorage; + this.controlFlowStorageName = controlFlowStorageName; + } + + /** + * @param blockScopeNode + */ + public appendNode (blockScopeNode: TNodeWithBlockStatement): void { + NodeAppender.prependNode(blockScopeNode, this.getNode()); + } + + /** + * @returns {string} + */ + public getCode (): string { + return format(ControlFlowStorageTemplate(), { + controlFlowStorage: this.controlFlowStorage.toString(), + controlFlowStorageName: this.controlFlowStorageName + }); + } +} diff --git a/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts b/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts index 99205b51..05806436 100644 --- a/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts +++ b/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts @@ -1,7 +1,6 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { TStatement } from '../../types/TStatement'; import { IOptions } from '../../interfaces/IOptions'; @@ -11,7 +10,6 @@ import { DebugProtectionFunctionCallTemplate } from '../../templates/custom-node import { AbstractCustomNode } from '../AbstractCustomNode'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; export class DebugProtectionFunctionCallNode extends AbstractCustomNode { /** @@ -42,13 +40,11 @@ export class DebugProtectionFunctionCallNode extends AbstractCustomNode { } /** - * @returns {TStatement[]} + * @returns {string} */ - protected getNodeStructure (): TStatement[] { - return NodeUtils.convertCodeToStructure( - DebugProtectionFunctionCallTemplate().formatUnicorn({ - debugProtectionFunctionName: this.debugProtectionFunctionName - }) - ); + public getCode (): string { + return format(DebugProtectionFunctionCallTemplate(), { + debugProtectionFunctionName: this.debugProtectionFunctionName + }); } } diff --git a/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts b/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts index f0d10f08..1fccffb1 100644 --- a/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts +++ b/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts @@ -1,7 +1,6 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { TStatement } from '../../types/TStatement'; import { IOptions } from '../../interfaces/IOptions'; @@ -11,7 +10,6 @@ import { DebugProtectionFunctionIntervalTemplate } from '../../templates/custom- import { AbstractCustomNode } from '../AbstractCustomNode'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode { /** @@ -42,13 +40,11 @@ export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode { } /** - * @returns {TStatement[]} + * @returns {string} */ - protected getNodeStructure (): TStatement[] { - return NodeUtils.convertCodeToStructure( - DebugProtectionFunctionIntervalTemplate().formatUnicorn({ - debugProtectionFunctionName: this.debugProtectionFunctionName - }) - ); + public getCode (): string { + return format(DebugProtectionFunctionIntervalTemplate(), { + debugProtectionFunctionName: this.debugProtectionFunctionName + }); } } diff --git a/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts b/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts index e5444285..0fa5f889 100644 --- a/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts +++ b/src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts @@ -1,7 +1,6 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { TStatement } from '../../types/TStatement'; import { IOptions } from '../../interfaces/IOptions'; @@ -11,7 +10,6 @@ import { DebugProtectionFunctionTemplate } from '../../templates/custom-nodes/de import { AbstractCustomNode } from '../AbstractCustomNode'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; import { Utils } from '../../Utils'; export class DebugProtectionFunctionNode extends AbstractCustomNode { @@ -40,10 +38,7 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode { */ public appendNode (blockScopeNode: TNodeWithBlockStatement): void { let programBodyLength: number = blockScopeNode.body.length, - randomIndex: number = Utils.getRandomGenerator().integer({ - min: 0, - max: programBodyLength - }); + randomIndex: number = Utils.getRandomInteger(0, programBodyLength); NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), randomIndex); } @@ -51,20 +46,9 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode { /** * @returns {string} */ - public getNodeIdentifier (): string { - return this.debugProtectionFunctionName; - } - - /** - * Found this trick in JScrambler - * - * @returns {TStatement[]} - */ - protected getNodeStructure (): TStatement[] { - return NodeUtils.convertCodeToStructure( - DebugProtectionFunctionTemplate().formatUnicorn({ - debugProtectionFunctionName: this.debugProtectionFunctionName - }) - ); + public getCode (): string { + return format(DebugProtectionFunctionTemplate(), { + debugProtectionFunctionName: this.debugProtectionFunctionName + }); } } diff --git a/src/custom-nodes/domain-lock-nodes/DomainLockNode.ts b/src/custom-nodes/domain-lock-nodes/DomainLockNode.ts index a25be4f4..7f2ef313 100644 --- a/src/custom-nodes/domain-lock-nodes/DomainLockNode.ts +++ b/src/custom-nodes/domain-lock-nodes/DomainLockNode.ts @@ -1,7 +1,6 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { TStatement } from '../../types/TStatement'; import { IOptions } from '../../interfaces/IOptions'; import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData'; @@ -12,7 +11,6 @@ import { DomainLockNodeTemplate } from '../../templates/custom-nodes/domain-lock import { AbstractCustomNode } from '../AbstractCustomNode'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; import { Utils } from '../../Utils'; export class DomainLockNode extends AbstractCustomNode { @@ -68,19 +66,17 @@ export class DomainLockNode extends AbstractCustomNode { } /** - * @returns {TStatement[]} + * @returns {string} */ - protected getNodeStructure (): TStatement[] { + public getCode (): string { let domainsString: string = this.options.domainLock.join(';'), [hiddenDomainsString, diff]: string[] = Utils.hideString(domainsString, domainsString.length * 3); - return NodeUtils.convertCodeToStructure( - DomainLockNodeTemplate().formatUnicorn({ - domainLockFunctionName: Utils.getRandomVariableName(), - diff: diff, - domains: hiddenDomainsString, - singleNodeCallControllerFunctionName: this.callsControllerFunctionName - }) - ); + return format(DomainLockNodeTemplate(), { + domainLockFunctionName: Utils.getRandomVariableName(), + diff: diff, + domains: hiddenDomainsString, + singleNodeCallControllerFunctionName: this.callsControllerFunctionName + }); } } diff --git a/src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts b/src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts index 338d4122..722608dc 100644 --- a/src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts +++ b/src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts @@ -1,7 +1,6 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { TStatement } from '../../types/TStatement'; import { IOptions } from '../../interfaces/IOptions'; import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData'; @@ -15,7 +14,6 @@ import { NO_CUSTOM_NODES_PRESET } from '../../preset-options/NoCustomNodesPreset import { AbstractCustomNode } from '../AbstractCustomNode'; import { JavaScriptObfuscator } from '../../JavaScriptObfuscator'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; export class NodeCallsControllerFunctionNode extends AbstractCustomNode { /** @@ -74,21 +72,22 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode { } /** - * @returns {TStatement[]} + * @returns {string} */ - protected getNodeStructure (): TStatement[] { + public getCode (): string { if (this.appendState === AppendState.AfterObfuscation) { - return NodeUtils.convertCodeToStructure( - JavaScriptObfuscator.obfuscate(SingleNodeCallControllerTemplate().formatUnicorn({ + return JavaScriptObfuscator.obfuscate( + format(SingleNodeCallControllerTemplate(), { singleNodeCallControllerFunctionName: this.callsControllerFunctionName - }), NO_CUSTOM_NODES_PRESET).getObfuscatedCode() - ); + }), + Object.assign({}, NO_CUSTOM_NODES_PRESET, { + seed: this.options.seed + }) + ).getObfuscatedCode(); } - return NodeUtils.convertCodeToStructure( - SingleNodeCallControllerTemplate().formatUnicorn({ - singleNodeCallControllerFunctionName: this.callsControllerFunctionName - }) - ); + return format(SingleNodeCallControllerTemplate(), { + singleNodeCallControllerFunctionName: this.callsControllerFunctionName + }); } } diff --git a/src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts b/src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts index 0562a13e..96e7856f 100644 --- a/src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts +++ b/src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts @@ -1,5 +1,6 @@ +import * as format from 'string-template'; + import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { TStatement } from '../../types/TStatement'; import { IOptions } from '../../interfaces/IOptions'; import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData'; @@ -13,7 +14,6 @@ import { SelfDefendingTemplate } from '../../templates/custom-nodes/self-defendi import { AbstractCustomNode } from '../AbstractCustomNode'; import { NodeAppender } from '../../node/NodeAppender'; import { JavaScriptObfuscator } from '../../JavaScriptObfuscator'; -import { NodeUtils } from '../../node/NodeUtils'; import { Utils } from '../../Utils'; export class SelfDefendingUnicodeNode extends AbstractCustomNode { @@ -69,17 +69,17 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode { } /** - * @returns {TStatement[]} + * @returns {string} */ - protected getNodeStructure (): TStatement[] { - return NodeUtils.convertCodeToStructure( - JavaScriptObfuscator.obfuscate( - SelfDefendingTemplate().formatUnicorn({ - selfDefendingFunctionName: Utils.getRandomVariableName(), - singleNodeCallControllerFunctionName: this.callsControllerFunctionName - }), - NO_CUSTOM_NODES_PRESET - ).getObfuscatedCode() - ); + public getCode (): string { + return JavaScriptObfuscator.obfuscate( + format(SelfDefendingTemplate(), { + selfDefendingFunctionName: Utils.getRandomVariableName(), + singleNodeCallControllerFunctionName: this.callsControllerFunctionName + }), + Object.assign({}, NO_CUSTOM_NODES_PRESET, { + seed: this.options.seed + }) + ).getObfuscatedCode(); } } diff --git a/src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts b/src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts index 849dfab5..c8c16649 100644 --- a/src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts +++ b/src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts @@ -1,9 +1,11 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; import { TStatement } from '../../types/TStatement'; +import { ICustomNodeWithIdentifier } from '../../interfaces/custom-nodes/ICustomNodeWithIdentifier'; import { IOptions } from '../../interfaces/IOptions'; +import { IStorage } from '../../interfaces/IStorage'; import { AppendState } from '../../enums/AppendState'; import { StringArrayEncoding } from '../../enums/StringArrayEncoding'; @@ -20,19 +22,17 @@ import { StringArrayRc4DecodeNodeTemplate } from '../../templates/custom-nodes/s import { AbstractCustomNode } from '../AbstractCustomNode'; import { JavaScriptObfuscator } from '../../JavaScriptObfuscator'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; -import { StringArray } from '../../StringArray'; -export class StringArrayCallsWrapper extends AbstractCustomNode { +export class StringArrayCallsWrapper extends AbstractCustomNode implements ICustomNodeWithIdentifier { /** * @type {AppendState} */ protected appendState: AppendState = AppendState.AfterObfuscation; /** - * @type {StringArray} + * @type {IStorage } */ - private stringArray: StringArray; + private stringArray: IStorage ; /** * @type {string} @@ -53,7 +53,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode { constructor ( stringArrayCallsWrapperName: string, stringArrayName: string, - stringArray: StringArray, + stringArray: IStorage , options: IOptions ) { super(options); @@ -74,6 +74,24 @@ export class StringArrayCallsWrapper extends AbstractCustomNode { NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), 1); } + /** + * @returns {string} + */ + public getCode (): string { + const decodeNodeTemplate: string = this.getDecodeStringArrayTemplate(); + + return JavaScriptObfuscator.obfuscate( + format(StringArrayCallsWrapperTemplate(), { + decodeNodeTemplate, + stringArrayCallsWrapperName: this.stringArrayCallsWrapperName, + stringArrayName: this.stringArrayName + }), + Object.assign({}, NO_CUSTOM_NODES_PRESET, { + seed: this.options.seed + }) + ).getObfuscatedCode(); + } + /** * @returns {string} */ @@ -96,7 +114,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode { selfDefendingCode: string = ''; if (this.options.selfDefending) { - selfDefendingCode = SelfDefendingTemplate().formatUnicorn({ + selfDefendingCode = format(SelfDefendingTemplate(), { stringArrayCallsWrapperName: this.stringArrayCallsWrapperName, stringArrayName: this.stringArrayName }); @@ -104,7 +122,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode { switch (this.options.stringArrayEncoding) { case StringArrayEncoding.base64: - decodeStringArrayTemplate = StringArrayBase64DecodeNodeTemplate().formatUnicorn({ + decodeStringArrayTemplate = format(StringArrayBase64DecodeNodeTemplate(), { atobPolyfill: AtobTemplate(), selfDefendingCode, stringArrayCallsWrapperName: this.stringArrayCallsWrapperName @@ -113,7 +131,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode { break; case StringArrayEncoding.rc4: - decodeStringArrayTemplate = StringArrayRc4DecodeNodeTemplate().formatUnicorn({ + decodeStringArrayTemplate = format(StringArrayRc4DecodeNodeTemplate(), { atobPolyfill: AtobTemplate(), rc4Polyfill: Rc4Template(), selfDefendingCode, @@ -125,22 +143,4 @@ export class StringArrayCallsWrapper extends AbstractCustomNode { return decodeStringArrayTemplate; } - - /** - * @returns {TStatement[]} - */ - protected getNodeStructure (): TStatement[] { - const decodeNodeTemplate: string = this.getDecodeStringArrayTemplate(); - - return NodeUtils.convertCodeToStructure( - JavaScriptObfuscator.obfuscate( - StringArrayCallsWrapperTemplate().formatUnicorn({ - decodeNodeTemplate, - stringArrayCallsWrapperName: this.stringArrayCallsWrapperName, - stringArrayName: this.stringArrayName - }), - NO_CUSTOM_NODES_PRESET - ).getObfuscatedCode() - ); - } } diff --git a/src/custom-nodes/string-array-nodes/StringArrayNode.ts b/src/custom-nodes/string-array-nodes/StringArrayNode.ts index 303097b3..f6b26dbd 100644 --- a/src/custom-nodes/string-array-nodes/StringArrayNode.ts +++ b/src/custom-nodes/string-array-nodes/StringArrayNode.ts @@ -1,21 +1,21 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; import { TStatement } from '../../types/TStatement'; +import { ICustomNodeWithData } from '../../interfaces/custom-nodes/ICustomNodeWithData'; import { IOptions } from '../../interfaces/IOptions'; +import { IStorage } from '../../interfaces/IStorage'; import { AppendState } from '../../enums/AppendState'; -import { StringArray } from '../../StringArray'; - import { StringArrayTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-node/StringArrayTemplate'; import { AbstractCustomNode } from '../AbstractCustomNode'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; +import { StringArrayStorage } from '../../storages/string-array/StringArrayStorage'; -export class StringArrayNode extends AbstractCustomNode { +export class StringArrayNode extends AbstractCustomNode implements ICustomNodeWithData { /** * @type {number} */ @@ -27,9 +27,9 @@ export class StringArrayNode extends AbstractCustomNode { protected appendState: AppendState = AppendState.AfterObfuscation; /** - * @type {StringArray} + * @type {IStorage } */ - private stringArray: StringArray; + private stringArray: IStorage ; /** * @type {string} @@ -48,7 +48,7 @@ export class StringArrayNode extends AbstractCustomNode { * @param options */ constructor ( - stringArray: StringArray, + stringArray: IStorage , stringArrayName: string, stringArrayRotateValue: number = 0, options: IOptions @@ -74,14 +74,17 @@ export class StringArrayNode extends AbstractCustomNode { /** * @returns {string} */ - public getNodeIdentifier (): string { - return this.stringArrayName; + public getCode (): string { + return format(StringArrayTemplate(), { + stringArrayName: this.stringArrayName, + stringArray: this.stringArray.toString() + }); } /** - * @returns {StringArray} + * @returns {IStorage } */ - public getNodeData (): StringArray { + public getNodeData (): IStorage { return this.stringArray; } @@ -89,27 +92,8 @@ export class StringArrayNode extends AbstractCustomNode { * @returns {TStatement[]} */ public getNode (): TStatement[] { - this.stringArray.rotateArray(this.stringArrayRotateValue); + (this.stringArray).rotateArray(this.stringArrayRotateValue); return super.getNode(); } - - /** - * @param data - */ - public updateNodeData (data: string): void { - this.stringArray.addToArray(data); - } - - /** - * @returns {TStatement[]} - */ - protected getNodeStructure (): TStatement[] { - return NodeUtils.convertCodeToStructure( - StringArrayTemplate().formatUnicorn({ - stringArrayName: this.stringArrayName, - stringArray: this.stringArray.toString() - }) - ); - } } diff --git a/src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts b/src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts index 9f00be66..1438d02a 100644 --- a/src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts +++ b/src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts @@ -1,9 +1,9 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { TStatement } from '../../types/TStatement'; import { IOptions } from '../../interfaces/IOptions'; +import { IStorage } from '../../interfaces/IStorage'; import { AppendState } from '../../enums/AppendState'; @@ -15,8 +15,6 @@ import { StringArrayRotateFunctionTemplate } from '../../templates/custom-nodes/ import { AbstractCustomNode } from '../AbstractCustomNode'; import { JavaScriptObfuscator } from '../../JavaScriptObfuscator'; import { NodeAppender } from '../../node/NodeAppender'; -import { NodeUtils } from '../../node/NodeUtils'; -import { StringArray } from '../../StringArray'; import { Utils } from '../../Utils'; export class StringArrayRotateFunctionNode extends AbstractCustomNode { @@ -26,9 +24,9 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode { protected appendState: AppendState = AppendState.AfterObfuscation; /** - * @type {StringArray} + * @type {IStorage } */ - private stringArray: StringArray; + private stringArray: IStorage ; /** * @type {string} @@ -48,7 +46,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode { */ constructor ( stringArrayName: string, - stringArray: StringArray, + stringArray: IStorage , stringArrayRotateValue: number, options: IOptions ) { @@ -71,22 +69,15 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode { } /** - * @returns {TStatement[]} + * @returns {string} */ - public getNode (): TStatement[] { - return super.getNode(); - } - - /** - * @returns {TStatement[]} - */ - protected getNodeStructure (): TStatement[] { + public getCode (): string { let code: string = '', timesName: string = Utils.getRandomVariableName(), whileFunctionName: string = Utils.getRandomVariableName(); if (this.options.selfDefending) { - code = SelfDefendingTemplate().formatUnicorn({ + code = format(SelfDefendingTemplate(), { timesName, whileFunctionName }); @@ -94,17 +85,17 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode { code = `${whileFunctionName}(++${timesName})`; } - return NodeUtils.convertCodeToStructure( - JavaScriptObfuscator.obfuscate( - StringArrayRotateFunctionTemplate().formatUnicorn({ - code, - timesName, - stringArrayName: this.stringArrayName, - stringArrayRotateValue: Utils.decToHex(this.stringArrayRotateValue), - whileFunctionName - }), - NO_CUSTOM_NODES_PRESET - ).getObfuscatedCode() - ); + return JavaScriptObfuscator.obfuscate( + format(StringArrayRotateFunctionTemplate(), { + code, + timesName, + stringArrayName: this.stringArrayName, + stringArrayRotateValue: Utils.decToHex(this.stringArrayRotateValue), + whileFunctionName + }), + Object.assign({}, NO_CUSTOM_NODES_PRESET, { + seed: this.options.seed + }) + ).getObfuscatedCode(); } } diff --git a/src/enums/JSFuck.ts b/src/enums/JSFuck.ts index f211463f..6fe31a6c 100644 --- a/src/enums/JSFuck.ts +++ b/src/enums/JSFuck.ts @@ -1,6 +1,4 @@ export const JSFuck: any = { - Window: '[]["filter"]["constructor"]("return this")()', - False: '![]', True: '!![]', diff --git a/src/enums/VisitorDirection.ts b/src/enums/VisitorDirection.ts new file mode 100644 index 00000000..b21f6532 --- /dev/null +++ b/src/enums/VisitorDirection.ts @@ -0,0 +1,6 @@ +import { Utils } from '../Utils'; + +export const VisitorDirection: any = Utils.strEnumify({ + enter: 'enter', + leave: 'leave' +}); diff --git a/src/interfaces/IControlFlowReplacer.d.ts b/src/interfaces/IControlFlowReplacer.d.ts new file mode 100644 index 00000000..7a8912b8 --- /dev/null +++ b/src/interfaces/IControlFlowReplacer.d.ts @@ -0,0 +1,13 @@ +import * as ESTree from 'estree'; + +import { ICustomNode } from './custom-nodes/ICustomNode'; +import { IStorage } from './IStorage'; + +export interface IControlFlowReplacer { + replace ( + node: ESTree.Node, + parentNode: ESTree.Node, + controlFlowStorage: IStorage , + controlFlowStorageCustomNodeName: string + ): ICustomNode | undefined; +} diff --git a/src/interfaces/INodeObfuscator.d.ts b/src/interfaces/INodeObfuscator.d.ts deleted file mode 100644 index 614c7481..00000000 --- a/src/interfaces/INodeObfuscator.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as ESTree from 'estree'; - -export interface INodeObfuscator { - /** - * @param node - * @param parentNode - */ - obfuscateNode (node: ESTree.Node, parentNode?: ESTree.Node): void; -} diff --git a/src/interfaces/INodeTransformer.d.ts b/src/interfaces/INodeTransformer.d.ts new file mode 100644 index 00000000..c65f2ad2 --- /dev/null +++ b/src/interfaces/INodeTransformer.d.ts @@ -0,0 +1,5 @@ +import * as ESTree from 'estree'; + +export interface INodeTransformer { + transformNode (node: ESTree.Node, parentNode?: ESTree.Node): void; +} diff --git a/src/interfaces/INodeTransformersFactory.d.ts b/src/interfaces/INodeTransformersFactory.d.ts new file mode 100644 index 00000000..124e21e2 --- /dev/null +++ b/src/interfaces/INodeTransformersFactory.d.ts @@ -0,0 +1,5 @@ +import { INodeTransformer } from './INodeTransformer'; + +export interface INodeTransformersFactory { + initializeNodeTransformers (nodeType: string): INodeTransformer[]; +} diff --git a/src/interfaces/IObfuscator.d.ts b/src/interfaces/IObfuscator.d.ts index 25f1fbbb..51bac08d 100644 --- a/src/interfaces/IObfuscator.d.ts +++ b/src/interfaces/IObfuscator.d.ts @@ -1,5 +1,5 @@ import * as ESTree from 'estree'; export interface IObfuscator { - obfuscateNode (node: ESTree.Node): ESTree.Node; + obfuscateAstTree (node: ESTree.Program): ESTree.Program; } diff --git a/src/interfaces/IObfuscatorOptions.d.ts b/src/interfaces/IObfuscatorOptions.d.ts index eef2e4b1..90aeeb8d 100644 --- a/src/interfaces/IObfuscatorOptions.d.ts +++ b/src/interfaces/IObfuscatorOptions.d.ts @@ -3,12 +3,14 @@ import { TStringArrayEncoding } from '../types/TStringArrayEncoding'; export interface IObfuscatorOptions { compact?: boolean; + controlFlowFlattening?: boolean; debugProtection?: boolean; debugProtectionInterval?: boolean; disableConsoleOutput?: boolean; domainLock?: string[]; reservedNames?: string[]; rotateStringArray?: boolean; + seed?: number; selfDefending?: boolean; sourceMap?: boolean; sourceMapBaseUrl?: string; diff --git a/src/interfaces/IOptions.d.ts b/src/interfaces/IOptions.d.ts index 14757a3b..a9e187ad 100644 --- a/src/interfaces/IOptions.d.ts +++ b/src/interfaces/IOptions.d.ts @@ -3,12 +3,14 @@ import { TStringArrayEncoding } from '../types/TStringArrayEncoding'; export interface IOptions { readonly compact: boolean; + readonly controlFlowFlattening: boolean; readonly debugProtection: boolean; readonly debugProtectionInterval: boolean; readonly disableConsoleOutput: boolean; readonly domainLock: string[]; readonly reservedNames: string[]; readonly rotateStringArray: boolean; + readonly seed: number; readonly selfDefending: boolean; readonly sourceMap: boolean; readonly sourceMapBaseUrl: string; diff --git a/src/interfaces/IStorage.d.ts b/src/interfaces/IStorage.d.ts new file mode 100644 index 00000000..036c8545 --- /dev/null +++ b/src/interfaces/IStorage.d.ts @@ -0,0 +1,8 @@ +export interface IStorage { + get (key: string | number): T; + getKeyOf (value: T): string | number | null; + getLength (): number; + getStorage (): any; + set (key: string | number | null, value: T): void; + toString (): string; +} diff --git a/src/interfaces/custom-nodes/ICustomNode.d.ts b/src/interfaces/custom-nodes/ICustomNode.d.ts index 6e6b84fe..5d671b54 100644 --- a/src/interfaces/custom-nodes/ICustomNode.d.ts +++ b/src/interfaces/custom-nodes/ICustomNode.d.ts @@ -15,6 +15,11 @@ export interface ICustomNode { */ getAppendState (): AppendState; + /** + * @returns {string} + */ + getCode (): string; + /** * @returns ESTree.Node[] */ diff --git a/src/interfaces/custom-nodes/ICustomNodeWithData.d.ts b/src/interfaces/custom-nodes/ICustomNodeWithData.d.ts index a5b0fc6e..afbaa164 100644 --- a/src/interfaces/custom-nodes/ICustomNodeWithData.d.ts +++ b/src/interfaces/custom-nodes/ICustomNodeWithData.d.ts @@ -5,9 +5,4 @@ export interface ICustomNodeWithData extends ICustomNode { * @returns any */ getNodeData (): any; - - /** - * @param data - */ - updateNodeData (data: any): void; } diff --git a/src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer.d.ts b/src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer.d.ts index 293657f6..e3609720 100644 --- a/src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer.d.ts +++ b/src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer.d.ts @@ -1,5 +1,7 @@ +import * as ESTree from 'estree'; + import { IStackTraceData } from './IStackTraceData'; export interface IStackTraceAnalyzer { - analyze (): IStackTraceData[]; + analyze (blockScopeBody: ESTree.Node[]): IStackTraceData[]; } diff --git a/src/node-groups/AbstractNodesGroup.ts b/src/node-groups/AbstractNodesGroup.ts index f4141bf2..eb6df4e4 100644 --- a/src/node-groups/AbstractNodesGroup.ts +++ b/src/node-groups/AbstractNodesGroup.ts @@ -9,17 +9,17 @@ export abstract class AbstractNodesGroup implements INodesGroup { /** * @type {AppendState} */ - protected appendState: AppendState = AppendState.BeforeObfuscation; + protected readonly appendState: AppendState = AppendState.BeforeObfuscation; /** * @type {IStackTraceData[]} */ - protected stackTraceData: IStackTraceData[]; + protected readonly stackTraceData: IStackTraceData[]; /** * @type {IOptions} */ - protected options: IOptions; + protected readonly options: IOptions; /** * @param stackTraceData diff --git a/src/node-groups/StringArrayNodesGroup.ts b/src/node-groups/StringArrayNodesGroup.ts index 242e084c..96670cea 100644 --- a/src/node-groups/StringArrayNodesGroup.ts +++ b/src/node-groups/StringArrayNodesGroup.ts @@ -7,8 +7,9 @@ import { StringArrayNode } from '../custom-nodes/string-array-nodes/StringArrayN import { StringArrayRotateFunctionNode } from '../custom-nodes/string-array-nodes/StringArrayRotateFunctionNode'; import { AbstractNodesGroup } from './AbstractNodesGroup'; -import { StringArray } from '../StringArray'; +import { StringArrayStorage } from '../storages/string-array/StringArrayStorage'; import { Utils } from '../Utils'; +import { IStorage } from '../interfaces/IStorage'; export class StringArrayNodesGroup extends AbstractNodesGroup { /** @@ -40,15 +41,12 @@ export class StringArrayNodesGroup extends AbstractNodesGroup { } if (this.options.rotateStringArray) { - this.stringArrayRotateValue = Utils.getRandomGenerator().integer({ - min: 100, - max: 500 - }); + this.stringArrayRotateValue = Utils.getRandomInteger(100, 500); } else { this.stringArrayRotateValue = 0; } - const stringArray: StringArray = new StringArray(); + const stringArray: IStorage = new StringArrayStorage(); const stringArrayNode: ICustomNode = new StringArrayNode( stringArray, this.stringArrayName, diff --git a/src/node-obfuscators/AbstractNodeObfuscator.ts b/src/node-transformers/AbstractNodeTransformer.ts similarity index 55% rename from src/node-obfuscators/AbstractNodeObfuscator.ts rename to src/node-transformers/AbstractNodeTransformer.ts index c5eed01c..71d84c6e 100644 --- a/src/node-obfuscators/AbstractNodeObfuscator.ts +++ b/src/node-transformers/AbstractNodeTransformer.ts @@ -1,25 +1,25 @@ import * as ESTree from 'estree'; import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; -import { INodeObfuscator } from '../interfaces/INodeObfuscator'; +import { INodeTransformer } from '../interfaces/INodeTransformer'; import { IOptions } from '../interfaces/IOptions'; -export abstract class AbstractNodeObfuscator implements INodeObfuscator { +export abstract class AbstractNodeTransformer implements INodeTransformer { /** * @type Map */ - protected nodes: Map ; + protected readonly nodes: Map ; /** * @type {IOptions} */ - protected options: IOptions; + protected readonly options: IOptions; /** * @param nodes * @param options */ - constructor(nodes: Map , options: IOptions) { + constructor (nodes: Map , options: IOptions) { this.nodes = nodes; this.options = options; } @@ -28,5 +28,5 @@ export abstract class AbstractNodeObfuscator implements INodeObfuscator { * @param node * @param parentNode */ - public abstract obfuscateNode (node: ESTree.Node, parentNode?: ESTree.Node): void; + public abstract transformNode (node: ESTree.Node, parentNode?: ESTree.Node): void; } diff --git a/src/node-transformers/AbstractNodeTransformersFactory.ts b/src/node-transformers/AbstractNodeTransformersFactory.ts new file mode 100644 index 00000000..3b05c25a --- /dev/null +++ b/src/node-transformers/AbstractNodeTransformersFactory.ts @@ -0,0 +1,49 @@ +import { TNodeTransformer } from '../types/TNodeTransformer'; + +import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; +import { INodeTransformer } from '../interfaces/INodeTransformer'; +import { INodeTransformersFactory } from '../interfaces/INodeTransformersFactory'; +import { IOptions } from '../interfaces/IOptions'; + +export abstract class AbstractNodeTransformersFactory implements INodeTransformersFactory { + /** + * @type {Map} + */ + protected abstract readonly nodeTransformers: Map ; + + /** + * @type Map + */ + protected readonly customNodes: Map ; + + /** + * @type {IOptions} + */ + protected readonly options: IOptions; + + /** + * @param customNodes + * @param options + */ + constructor (customNodes: Map , options: IOptions) { + this.customNodes = customNodes; + this.options = options; + } + + /** + * @param nodeType + * @returns {INodeTransformer[]} + */ + public initializeNodeTransformers (nodeType: string): INodeTransformer[] { + const nodeTransformers: TNodeTransformer[] = this.nodeTransformers.get(nodeType) || []; + const instancesArray: INodeTransformer[] = []; + + nodeTransformers.forEach((transformer: TNodeTransformer) => { + instancesArray.push( + new transformer(this.customNodes, this.options) + ); + }); + + return instancesArray; + } +} diff --git a/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts b/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts new file mode 100644 index 00000000..90f61fb3 --- /dev/null +++ b/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts @@ -0,0 +1,98 @@ +import * as estraverse from 'estraverse'; +import * as ESTree from 'estree'; + +import { TControlFlowReplacer } from '../../types/TControlFlowReplacer'; +import { TStatement } from '../../types/TStatement'; + +import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../interfaces/IOptions'; +import { IStorage } from '../../interfaces/IStorage'; + +import { NodeType } from '../../enums/NodeType'; + +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; +import { BinaryExpressionControlFlowReplacer } from './control-flow-replacers/BinaryExpressionControlFlowReplacer'; +import { ControlFlowStorage } from '../../storages/control-flow/ControlFlowStorage'; +import { ControlFlowStorageNode } from '../../custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode'; +import { Node } from '../../node/Node'; +import { NodeAppender } from '../../node/NodeAppender'; +import { Utils } from '../../Utils'; +import { NodeUtils } from '../../node/NodeUtils'; + +export class FunctionControlFlowTransformer extends AbstractNodeTransformer { + /** + * @type {Map } + */ + private static readonly controlFlowReplacers: Map = new Map ([ + [NodeType.BinaryExpression, BinaryExpressionControlFlowReplacer] + ]); + + /** + * @param nodes + * @param options + */ + constructor (nodes: Map , options: IOptions) { + super(nodes, options); + } + + /** + * @param functionNode + */ + public transformNode (functionNode: ESTree.Function): void { + this.changeFunctionBodyControlFlow(functionNode); + } + + /** + * @param functionNode + */ + private changeFunctionBodyControlFlow (functionNode: ESTree.Function): void { + if (Node.isArrowFunctionExpressionNode(functionNode)) { + return; + } + + const controlFlowStorage: IStorage = new ControlFlowStorage(); + const controlFlowStorageCustomNodeName: string = Utils.getRandomVariableName(6); + + console.log(NodeUtils.getNodeBlockScopeDepth(functionNode.body)); + + estraverse.replace(functionNode.body, { + enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { + const controlFlowReplacer: TControlFlowReplacer | undefined = FunctionControlFlowTransformer + .controlFlowReplacers.get(node.type); + + if (!controlFlowReplacer) { + return; + } + + const controlFlowStorageCallCustomNode: ICustomNode | undefined = new controlFlowReplacer( + this.nodes, + this.options + ).replace(node, parentNode, controlFlowStorage, controlFlowStorageCustomNodeName); + + if (!controlFlowStorageCallCustomNode) { + return; + } + + // controlFlowStorageCallCustomNode will always have only one TStatement node, + // so we can get it by index `0` + // also we need to return `expression` property of `ExpressionStatement` node because bug: + // https://github.com/estools/escodegen/issues/289 + const statementNode: TStatement | undefined = controlFlowStorageCallCustomNode.getNode()[0]; + + if (!statementNode || !Node.isExpressionStatementNode(statementNode)) { + throw new Error(`\`controlFlowStorageCallCustomNode.getNode()\` should returns array with \`ExpressionStatement\` node`); + } + + return statementNode.expression; + } + }); + + const controlFlowStorageCustomNode: ICustomNode = new ControlFlowStorageNode( + controlFlowStorage, + controlFlowStorageCustomNodeName, + this.options + ); + + NodeAppender.prependNode(functionNode.body, controlFlowStorageCustomNode.getNode()); + } +} diff --git a/src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts new file mode 100644 index 00000000..18f55048 --- /dev/null +++ b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts @@ -0,0 +1,53 @@ +import * as ESTree from 'estree'; + +import { IControlFlowReplacer } from '../../../interfaces/IControlFlowReplacer'; +import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../../interfaces/IOptions'; +import { IStorage } from '../../../interfaces/IStorage'; + +import { Utils } from '../../../Utils'; + +export abstract class AbstractControlFlowReplacer implements IControlFlowReplacer { + /** + * @type Map + */ + protected readonly nodes: Map ; + + /** + * @type {IOptions} + */ + protected readonly options : IOptions; + + /** + * @param nodes + * @param options + */ + constructor (nodes: Map , options: IOptions) { + this.nodes = nodes; + this.options = options; + } + + /** + * @returns {string} + */ + protected static getStorageKey (): string { + return Utils.getRandomGenerator().string({ + length: 3, + pool: Utils.randomGeneratorPool + }); + } + + /** + * @param node + * @param parentNode + * @param controlFlowStorage + * @param controlFlowStorageCustomNodeName + * @returns {ICustomNode | undefined} + */ + public abstract replace ( + node: ESTree.Node, + parentNode: ESTree.Node, + controlFlowStorage: IStorage , + controlFlowStorageCustomNodeName: string + ): ICustomNode | undefined; +} diff --git a/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts new file mode 100644 index 00000000..92bd930f --- /dev/null +++ b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts @@ -0,0 +1,47 @@ +import * as escodegen from 'escodegen'; +import * as ESTree from 'estree'; + +import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; +import { IStorage } from '../../../interfaces/IStorage'; + +import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer'; +import { BinaryExpressionFunctionNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode'; +import { ControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode'; + +export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowReplacer { + /** + * @param expressionNode + * @returns {string} + */ + private static getExpressionValue (expressionNode: ESTree.Expression): string { + return escodegen.generate(expressionNode, { + sourceMapWithCode: true + }).code; + } + + /** + * @param binaryExpressionNode + * @param parentNode + * @param controlFlowStorage + * @param controlFlowStorageCustomNodeName + * @returns {ICustomNode | undefined} + */ + public replace ( + binaryExpressionNode: ESTree.BinaryExpression, + parentNode: ESTree.Node, + controlFlowStorage: IStorage , + controlFlowStorageCustomNodeName: string + ): ICustomNode | undefined { + const key: string = AbstractControlFlowReplacer.getStorageKey(); + + controlFlowStorage.set(key, new BinaryExpressionFunctionNode(binaryExpressionNode.operator, this.options)); + + return new ControlFlowStorageCallNode( + controlFlowStorageCustomNodeName, + key, + BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.left), + BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.right), + this.options + ); + } +} diff --git a/src/node-transformers/node-control-flow-transformers/factory/NodeControlFlowTransformersFactory.ts b/src/node-transformers/node-control-flow-transformers/factory/NodeControlFlowTransformersFactory.ts new file mode 100644 index 00000000..61fc9ebd --- /dev/null +++ b/src/node-transformers/node-control-flow-transformers/factory/NodeControlFlowTransformersFactory.ts @@ -0,0 +1,16 @@ +import { TNodeTransformer } from '../../../types/TNodeTransformer'; + +import { NodeType } from '../../../enums/NodeType'; + +import { FunctionControlFlowTransformer } from '../FunctionControlFlowTransformer'; +import { AbstractNodeTransformersFactory } from '../../AbstractNodeTransformersFactory'; + +export class NodeControlFlowTransformersFactory extends AbstractNodeTransformersFactory { + /** + * @type {Map} + */ + protected readonly nodeTransformers: Map = new Map ([ + [NodeType.FunctionDeclaration, [FunctionControlFlowTransformer]], + [NodeType.FunctionExpression, [FunctionControlFlowTransformer]] + ]); +} diff --git a/src/node-obfuscators/CatchClauseObfuscator.ts b/src/node-transformers/node-obfuscators/CatchClauseObfuscator.ts similarity index 70% rename from src/node-obfuscators/CatchClauseObfuscator.ts rename to src/node-transformers/node-obfuscators/CatchClauseObfuscator.ts index 48612a5b..d91360e0 100644 --- a/src/node-obfuscators/CatchClauseObfuscator.ts +++ b/src/node-transformers/node-obfuscators/CatchClauseObfuscator.ts @@ -1,15 +1,15 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; -import { IOptions } from '../interfaces/IOptions'; +import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../interfaces/IOptions'; -import { NodeType } from '../enums/NodeType'; +import { NodeType } from '../../enums/NodeType'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; import { IdentifierReplacer } from './replacers/IdentifierReplacer'; -import { Node } from '../node/Node'; -import { NodeUtils } from '../node/NodeUtils'; +import { Node } from '../../node/Node'; +import { NodeUtils } from '../../node/NodeUtils'; /** * replaces: @@ -19,11 +19,11 @@ import { NodeUtils } from '../node/NodeUtils'; * try {} catch (_0x12d45f) { console.log(_0x12d45f); }; * */ -export class CatchClauseObfuscator extends AbstractNodeObfuscator { +export class CatchClauseObfuscator extends AbstractNodeTransformer { /** * @type {IdentifierReplacer} */ - private identifierReplacer: IdentifierReplacer; + private readonly identifierReplacer: IdentifierReplacer; /** * @param nodes @@ -38,7 +38,7 @@ export class CatchClauseObfuscator extends AbstractNodeObfuscator { /** * @param catchClauseNode */ - public obfuscateNode (catchClauseNode: ESTree.CatchClause): void { + public transformNode (catchClauseNode: ESTree.CatchClause): void { this.storeCatchClauseParam(catchClauseNode); this.replaceCatchClauseParam(catchClauseNode); } @@ -47,7 +47,7 @@ export class CatchClauseObfuscator extends AbstractNodeObfuscator { * @param catchClauseNode */ private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause): void { - NodeUtils.typedReplace(catchClauseNode.param, NodeType.Identifier, { + NodeUtils.typedTraverse(catchClauseNode.param, NodeType.Identifier, { enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name) }); } diff --git a/src/node-obfuscators/FunctionDeclarationObfuscator.ts b/src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.ts similarity index 71% rename from src/node-obfuscators/FunctionDeclarationObfuscator.ts rename to src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.ts index 84bbed41..98fb41c7 100644 --- a/src/node-obfuscators/FunctionDeclarationObfuscator.ts +++ b/src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.ts @@ -1,17 +1,17 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { TNodeWithBlockStatement } from '../types/TNodeWithBlockStatement'; +import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; -import { IOptions } from '../interfaces/IOptions'; +import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../interfaces/IOptions'; -import { NodeType } from '../enums/NodeType'; +import { NodeType } from '../../enums/NodeType'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; import { IdentifierReplacer } from './replacers/IdentifierReplacer'; -import { Node } from '../node/Node'; -import { NodeUtils } from '../node/NodeUtils'; +import { Node } from '../../node/Node'; +import { NodeUtils } from '../../node/NodeUtils'; /** * replaces: @@ -22,11 +22,11 @@ import { NodeUtils } from '../node/NodeUtils'; * function _0x12d45f () { //... }; * _0x12d45f(); */ -export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator { +export class FunctionDeclarationObfuscator extends AbstractNodeTransformer { /** * @type {IdentifierReplacer} */ - private identifierReplacer: IdentifierReplacer; + private readonly identifierReplacer: IdentifierReplacer; /** * @param nodes @@ -42,7 +42,7 @@ export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator { * @param functionDeclarationNode * @param parentNode */ - public obfuscateNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): void { + public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): void { const blockScopeOfFunctionDeclarationNode: TNodeWithBlockStatement = NodeUtils .getBlockScopeOfNode(functionDeclarationNode); @@ -58,7 +58,7 @@ export class FunctionDeclarationObfuscator extends AbstractNodeObfuscator { * @param functionDeclarationNode */ private storeFunctionName (functionDeclarationNode: ESTree.FunctionDeclaration): void { - NodeUtils.typedReplace(functionDeclarationNode.id, NodeType.Identifier, { + NodeUtils.typedTraverse(functionDeclarationNode.id, NodeType.Identifier, { enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name) }); } diff --git a/src/node-obfuscators/FunctionObfuscator.ts b/src/node-transformers/node-obfuscators/FunctionObfuscator.ts similarity index 66% rename from src/node-obfuscators/FunctionObfuscator.ts rename to src/node-transformers/node-obfuscators/FunctionObfuscator.ts index 4721f623..a8143226 100644 --- a/src/node-obfuscators/FunctionObfuscator.ts +++ b/src/node-transformers/node-obfuscators/FunctionObfuscator.ts @@ -1,15 +1,15 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; -import { IOptions } from '../interfaces/IOptions'; +import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../interfaces/IOptions'; -import { NodeType } from '../enums/NodeType'; +import { NodeType } from '../../enums/NodeType'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; import { IdentifierReplacer } from './replacers/IdentifierReplacer'; -import { Node } from '../node/Node'; -import { NodeUtils } from '../node/NodeUtils'; +import { Node } from '../../node/Node'; +import { NodeUtils } from '../../node/NodeUtils'; /** * replaces: @@ -19,11 +19,11 @@ import { NodeUtils } from '../node/NodeUtils'; * function foo (_0x12d45f) { return _0x12d45f; }; * */ -export class FunctionObfuscator extends AbstractNodeObfuscator { +export class FunctionObfuscator extends AbstractNodeTransformer { /** * @type {IdentifierReplacer} */ - private identifierReplacer: IdentifierReplacer; + private readonly identifierReplacer: IdentifierReplacer; /** * @param nodes @@ -38,7 +38,7 @@ export class FunctionObfuscator extends AbstractNodeObfuscator { /** * @param functionNode */ - public obfuscateNode (functionNode: ESTree.Function): void { + public transformNode (functionNode: ESTree.Function): void { this.storeFunctionParams(functionNode); this.replaceFunctionParams(functionNode); } @@ -49,7 +49,7 @@ export class FunctionObfuscator extends AbstractNodeObfuscator { private storeFunctionParams (functionNode: ESTree.Function): void { functionNode.params .forEach((paramsNode: ESTree.Node) => { - NodeUtils.typedReplace(paramsNode, NodeType.Identifier, { + NodeUtils.typedTraverse(paramsNode, NodeType.Identifier, { enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name) }); }); @@ -59,7 +59,7 @@ export class FunctionObfuscator extends AbstractNodeObfuscator { * @param functionNode */ private replaceFunctionParams (functionNode: ESTree.Function): void { - let replaceVisitor: estraverse.Visitor = { + let traverseVisitor: estraverse.Visitor = { enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { if (Node.isReplaceableIdentifierNode(node, parentNode)) { const newNodeName: string = this.identifierReplacer.replace(node.name); @@ -72,11 +72,8 @@ export class FunctionObfuscator extends AbstractNodeObfuscator { } }; - functionNode.params - .forEach((paramsNode: ESTree.Node) => { - estraverse.replace(paramsNode, replaceVisitor); - }); + functionNode.params.forEach((paramsNode: ESTree.Node) => estraverse.replace(paramsNode, traverseVisitor)); - estraverse.replace(functionNode.body, replaceVisitor); + estraverse.replace(functionNode.body, traverseVisitor); } } diff --git a/src/node-obfuscators/LabeledStatementObfuscator.ts b/src/node-transformers/node-obfuscators/LabeledStatementObfuscator.ts similarity index 72% rename from src/node-obfuscators/LabeledStatementObfuscator.ts rename to src/node-transformers/node-obfuscators/LabeledStatementObfuscator.ts index 833b0e47..1486f905 100644 --- a/src/node-obfuscators/LabeledStatementObfuscator.ts +++ b/src/node-transformers/node-obfuscators/LabeledStatementObfuscator.ts @@ -1,15 +1,15 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; -import { IOptions } from '../interfaces/IOptions'; +import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../interfaces/IOptions'; -import { NodeType } from '../enums/NodeType'; +import { NodeType } from '../../enums/NodeType'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; import { IdentifierReplacer } from './replacers/IdentifierReplacer'; -import { Node } from '../node/Node'; -import { NodeUtils } from '../node/NodeUtils'; +import { Node } from '../../node/Node'; +import { NodeUtils } from '../../node/NodeUtils'; /** * replaces: @@ -27,11 +27,11 @@ import { NodeUtils } from '../node/NodeUtils'; * } * */ -export class LabeledStatementObfuscator extends AbstractNodeObfuscator { +export class LabeledStatementObfuscator extends AbstractNodeTransformer { /** * @type {IdentifierReplacer} */ - private identifierReplacer: IdentifierReplacer; + private readonly identifierReplacer: IdentifierReplacer; /** * @param nodes @@ -46,7 +46,7 @@ export class LabeledStatementObfuscator extends AbstractNodeObfuscator { /** * @param labeledStatementNode */ - public obfuscateNode (labeledStatementNode: ESTree.LabeledStatement): void { + public transformNode (labeledStatementNode: ESTree.LabeledStatement): void { this.storeLabeledStatementName(labeledStatementNode); this.replaceLabeledStatementName(labeledStatementNode); } @@ -55,7 +55,7 @@ export class LabeledStatementObfuscator extends AbstractNodeObfuscator { * @param labeledStatementNode */ private storeLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement): void { - NodeUtils.typedReplace(labeledStatementNode.label, NodeType.Identifier, { + NodeUtils.typedTraverse(labeledStatementNode.label, NodeType.Identifier, { enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name) }); } diff --git a/src/node-obfuscators/LiteralObfuscator.ts b/src/node-transformers/node-obfuscators/LiteralObfuscator.ts similarity index 81% rename from src/node-obfuscators/LiteralObfuscator.ts rename to src/node-transformers/node-obfuscators/LiteralObfuscator.ts index bf46f3e4..f1986a5f 100644 --- a/src/node-obfuscators/LiteralObfuscator.ts +++ b/src/node-transformers/node-obfuscators/LiteralObfuscator.ts @@ -1,18 +1,18 @@ import * as escodegen from 'escodegen'; import * as ESTree from 'estree'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; import { BooleanLiteralReplacer } from './replacers/BooleanLiteralReplacer'; -import { Node } from '../node/Node'; +import { Node } from '../../node/Node'; import { NumberLiteralReplacer } from './replacers/NumberLiteralReplacer'; import { StringLiteralReplacer } from './replacers/StringLiteralReplacer'; -export class LiteralObfuscator extends AbstractNodeObfuscator { +export class LiteralObfuscator extends AbstractNodeTransformer { /** * @param literalNode * @param parentNode */ - public obfuscateNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void { + public transformNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void { if (Node.isPropertyNode(parentNode) && parentNode.key === literalNode) { return; } @@ -34,7 +34,7 @@ export class LiteralObfuscator extends AbstractNodeObfuscator { case 'string': content = new StringLiteralReplacer(this.nodes, this.options) - .replace(literalNode.value); + .replace(literalNode.value); break; diff --git a/src/node-obfuscators/MemberExpressionObfuscator.ts b/src/node-transformers/node-obfuscators/MemberExpressionObfuscator.ts similarity index 68% rename from src/node-obfuscators/MemberExpressionObfuscator.ts rename to src/node-transformers/node-obfuscators/MemberExpressionObfuscator.ts index 223e83af..7007ccce 100644 --- a/src/node-obfuscators/MemberExpressionObfuscator.ts +++ b/src/node-transformers/node-obfuscators/MemberExpressionObfuscator.ts @@ -2,18 +2,18 @@ import * as escodegen from 'escodegen'; import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { NodeType } from '../enums/NodeType'; +import { NodeType } from '../../enums/NodeType'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; -import { Node } from '../node/Node'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; +import { Node } from '../../node/Node'; import { StringLiteralReplacer } from './replacers/StringLiteralReplacer'; -export class MemberExpressionObfuscator extends AbstractNodeObfuscator { +export class MemberExpressionObfuscator extends AbstractNodeTransformer { /** * @param memberExpressionNode */ - public obfuscateNode (memberExpressionNode: ESTree.MemberExpression): void { - estraverse.replace(memberExpressionNode.property, { + public transformNode (memberExpressionNode: ESTree.MemberExpression): void { + estraverse.traverse(memberExpressionNode.property, { enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { if (Node.isLiteralNode(node)) { this.obfuscateLiteralProperty(node); @@ -46,16 +46,16 @@ export class MemberExpressionObfuscator extends AbstractNodeObfuscator { * @param node */ private obfuscateIdentifierProperty (node: ESTree.Identifier): void { - let nodeValue: string = node.name, - literalNode: ESTree.Literal = { - raw: `'${nodeValue}'`, - 'x-verbatim-property': { - content : new StringLiteralReplacer(this.nodes, this.options).replace(nodeValue), - precedence: escodegen.Precedence.Primary - }, - type: NodeType.Literal, - value: nodeValue - }; + const nodeValue: string = node.name; + const literalNode: ESTree.Literal = { + raw: `'${nodeValue}'`, + 'x-verbatim-property': { + content : new StringLiteralReplacer(this.nodes, this.options).replace(nodeValue), + precedence: escodegen.Precedence.Primary + }, + type: NodeType.Literal, + value: nodeValue + }; delete node.name; diff --git a/src/node-obfuscators/MethodDefinitionObfuscator.ts b/src/node-transformers/node-obfuscators/MethodDefinitionObfuscator.ts similarity index 78% rename from src/node-obfuscators/MethodDefinitionObfuscator.ts rename to src/node-transformers/node-obfuscators/MethodDefinitionObfuscator.ts index 279133f4..b632699d 100644 --- a/src/node-obfuscators/MethodDefinitionObfuscator.ts +++ b/src/node-transformers/node-obfuscators/MethodDefinitionObfuscator.ts @@ -1,9 +1,9 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; -import { Node } from '../node/Node'; -import { Utils } from '../Utils'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; +import { Node } from '../../node/Node'; +import { Utils } from '../../Utils'; import { StringLiteralReplacer } from './replacers/StringLiteralReplacer'; /** @@ -13,17 +13,17 @@ import { StringLiteralReplacer } from './replacers/StringLiteralReplacer'; * on: * [_0x9a4e('0x0')] { //... }; */ -export class MethodDefinitionObfuscator extends AbstractNodeObfuscator { +export class MethodDefinitionObfuscator extends AbstractNodeTransformer { /** * @type {string[]} */ - private static ignoredNames: string[] = ['constructor']; + private static readonly ignoredNames: string[] = ['constructor']; /** * @param methodDefinitionNode * @param parentNode */ - public obfuscateNode (methodDefinitionNode: ESTree.MethodDefinition, parentNode: ESTree.Node): void { + public transformNode (methodDefinitionNode: ESTree.MethodDefinition, parentNode: ESTree.Node): void { this.replaceMethodName(methodDefinitionNode); } diff --git a/src/node-obfuscators/ObjectExpressionObfuscator.ts b/src/node-transformers/node-obfuscators/ObjectExpressionObfuscator.ts similarity index 67% rename from src/node-obfuscators/ObjectExpressionObfuscator.ts rename to src/node-transformers/node-obfuscators/ObjectExpressionObfuscator.ts index 3932ef2a..2ea7beef 100644 --- a/src/node-obfuscators/ObjectExpressionObfuscator.ts +++ b/src/node-transformers/node-obfuscators/ObjectExpressionObfuscator.ts @@ -2,11 +2,11 @@ import * as escodegen from 'escodegen'; import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { NodeType } from '../enums/NodeType'; +import { NodeType } from '../../enums/NodeType'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; -import { Node } from '../node/Node'; -import { Utils } from '../Utils'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; +import { Node } from '../../node/Node'; +import { Utils } from '../../Utils'; /** * replaces: @@ -18,18 +18,18 @@ import { Utils } from '../Utils'; * on: * var object = { '\u0050\u0053\u0045\u0055\u0044\u004f': 1 }; */ -export class ObjectExpressionObfuscator extends AbstractNodeObfuscator { +export class ObjectExpressionObfuscator extends AbstractNodeTransformer { /** * @param objectExpressionNode */ - public obfuscateNode (objectExpressionNode: ESTree.ObjectExpression): void { + public transformNode (objectExpressionNode: ESTree.ObjectExpression): void { objectExpressionNode.properties .forEach((property: ESTree.Property) => { if (property.shorthand) { property.shorthand = false; } - estraverse.replace(property.key, { + estraverse.traverse(property.key, { enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { if (Node.isLiteralNode(node)) { this.obfuscateLiteralPropertyKey(node); @@ -61,16 +61,16 @@ export class ObjectExpressionObfuscator extends AbstractNodeObfuscator { * @param node */ private obfuscateIdentifierPropertyKey (node: ESTree.Identifier): void { - let nodeValue: string = node.name, - literalNode: ESTree.Literal = { - raw: `'${nodeValue}'`, - 'x-verbatim-property': { - content : `'${Utils.stringToUnicodeEscapeSequence(nodeValue)}'`, - precedence: escodegen.Precedence.Primary - }, - type: NodeType.Literal, - value: nodeValue - }; + const nodeValue: string = node.name; + const literalNode: ESTree.Literal = { + raw: `'${nodeValue}'`, + 'x-verbatim-property': { + content : `'${Utils.stringToUnicodeEscapeSequence(nodeValue)}'`, + precedence: escodegen.Precedence.Primary + }, + type: NodeType.Literal, + value: nodeValue + }; delete node.name; diff --git a/src/node-obfuscators/VariableDeclarationObfuscator.ts b/src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts similarity index 74% rename from src/node-obfuscators/VariableDeclarationObfuscator.ts rename to src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts index 4ebc7a2a..b51e8ca2 100644 --- a/src/node-obfuscators/VariableDeclarationObfuscator.ts +++ b/src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts @@ -1,17 +1,17 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { TNodeWithBlockStatement } from '../types/TNodeWithBlockStatement'; +import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; -import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; -import { IOptions } from '../interfaces/IOptions'; +import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../interfaces/IOptions'; -import { NodeType } from '../enums/NodeType'; +import { NodeType } from '../../enums/NodeType'; -import { AbstractNodeObfuscator } from './AbstractNodeObfuscator'; +import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; import { IdentifierReplacer } from './replacers/IdentifierReplacer'; -import { Node } from '../node/Node'; -import { NodeUtils } from '../node/NodeUtils'; +import { Node } from '../../node/Node'; +import { NodeUtils } from '../../node/NodeUtils'; /** * replaces: @@ -23,11 +23,11 @@ import { NodeUtils } from '../node/NodeUtils'; * _0x12d45f++; * */ -export class VariableDeclarationObfuscator extends AbstractNodeObfuscator { +export class VariableDeclarationObfuscator extends AbstractNodeTransformer { /** * @type {IdentifierReplacer} */ - private identifierReplacer: IdentifierReplacer; + private readonly identifierReplacer: IdentifierReplacer; /** * @param nodes @@ -43,7 +43,7 @@ export class VariableDeclarationObfuscator extends AbstractNodeObfuscator { * @param variableDeclarationNode * @param parentNode */ - public obfuscateNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void { + public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void { const blockScopeOfVariableDeclarationNode: TNodeWithBlockStatement = NodeUtils .getBlockScopeOfNode(variableDeclarationNode); @@ -65,7 +65,7 @@ export class VariableDeclarationObfuscator extends AbstractNodeObfuscator { private storeVariableNames (variableDeclarationNode: ESTree.VariableDeclaration): void { variableDeclarationNode.declarations .forEach((declarationNode: ESTree.VariableDeclarator) => { - NodeUtils.typedReplace(declarationNode.id, NodeType.Identifier, { + NodeUtils.typedTraverse(declarationNode.id, NodeType.Identifier, { enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name) }); }); diff --git a/src/node-transformers/node-obfuscators/factory/NodeObfuscatorsFactory.ts b/src/node-transformers/node-obfuscators/factory/NodeObfuscatorsFactory.ts new file mode 100644 index 00000000..60088462 --- /dev/null +++ b/src/node-transformers/node-obfuscators/factory/NodeObfuscatorsFactory.ts @@ -0,0 +1,36 @@ +import { TNodeTransformer } from '../../../types/TNodeTransformer'; + +import { NodeType } from '../../../enums/NodeType'; + +import { CatchClauseObfuscator } from '../CatchClauseObfuscator'; +import { FunctionDeclarationObfuscator } from '../FunctionDeclarationObfuscator'; +import { FunctionObfuscator } from '../FunctionObfuscator'; +import { LabeledStatementObfuscator } from '../LabeledStatementObfuscator'; +import { LiteralObfuscator } from '../LiteralObfuscator'; +import { MemberExpressionObfuscator } from '../MemberExpressionObfuscator'; +import { MethodDefinitionObfuscator } from '../MethodDefinitionObfuscator'; +import { ObjectExpressionObfuscator } from '../ObjectExpressionObfuscator'; +import { VariableDeclarationObfuscator } from '../VariableDeclarationObfuscator'; +import { AbstractNodeTransformersFactory } from '../../AbstractNodeTransformersFactory'; + +export class NodeObfuscatorsFactory extends AbstractNodeTransformersFactory { + /** + * @type {Map} + */ + protected readonly nodeTransformers: Map = new Map ([ + [NodeType.ArrowFunctionExpression, [FunctionObfuscator]], + [NodeType.ClassDeclaration, [FunctionDeclarationObfuscator]], + [NodeType.CatchClause, [CatchClauseObfuscator]], + [NodeType.FunctionDeclaration, [ + FunctionDeclarationObfuscator, + FunctionObfuscator + ]], + [NodeType.FunctionExpression, [FunctionObfuscator]], + [NodeType.MemberExpression, [MemberExpressionObfuscator]], + [NodeType.MethodDefinition, [MethodDefinitionObfuscator]], + [NodeType.ObjectExpression, [ObjectExpressionObfuscator]], + [NodeType.VariableDeclaration, [VariableDeclarationObfuscator]], + [NodeType.LabeledStatement, [LabeledStatementObfuscator]], + [NodeType.Literal, [LiteralObfuscator]] + ]); +} diff --git a/src/node-obfuscators/replacers/AbstractReplacer.ts b/src/node-transformers/node-obfuscators/replacers/AbstractReplacer.ts similarity index 64% rename from src/node-obfuscators/replacers/AbstractReplacer.ts rename to src/node-transformers/node-obfuscators/replacers/AbstractReplacer.ts index 09bc1980..f8f25743 100644 --- a/src/node-obfuscators/replacers/AbstractReplacer.ts +++ b/src/node-transformers/node-obfuscators/replacers/AbstractReplacer.ts @@ -1,17 +1,17 @@ -import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; -import { IOptions } from '../../interfaces/IOptions'; -import { IReplacer } from '../../interfaces/IReplacer'; +import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../../../interfaces/IOptions'; +import { IReplacer } from '../../../interfaces/IReplacer'; export abstract class AbstractReplacer implements IReplacer { /** * @type Map */ - protected nodes: Map ; + protected readonly nodes: Map ; /** * @type {IOptions} */ - protected options : IOptions; + protected readonly options : IOptions; /** * @param nodes diff --git a/src/node-obfuscators/replacers/BooleanLiteralReplacer.ts b/src/node-transformers/node-obfuscators/replacers/BooleanLiteralReplacer.ts similarity index 86% rename from src/node-obfuscators/replacers/BooleanLiteralReplacer.ts rename to src/node-transformers/node-obfuscators/replacers/BooleanLiteralReplacer.ts index 30d98218..2ee02684 100644 --- a/src/node-obfuscators/replacers/BooleanLiteralReplacer.ts +++ b/src/node-transformers/node-obfuscators/replacers/BooleanLiteralReplacer.ts @@ -1,4 +1,4 @@ -import { JSFuck } from '../../enums/JSFuck'; +import { JSFuck } from '../../../enums/JSFuck'; import { AbstractReplacer } from './AbstractReplacer'; diff --git a/src/node-obfuscators/replacers/IdentifierReplacer.ts b/src/node-transformers/node-obfuscators/replacers/IdentifierReplacer.ts similarity index 90% rename from src/node-obfuscators/replacers/IdentifierReplacer.ts rename to src/node-transformers/node-obfuscators/replacers/IdentifierReplacer.ts index 3cf97ade..d08817e8 100644 --- a/src/node-obfuscators/replacers/IdentifierReplacer.ts +++ b/src/node-transformers/node-obfuscators/replacers/IdentifierReplacer.ts @@ -1,11 +1,11 @@ import { AbstractReplacer } from './AbstractReplacer'; -import { Utils } from '../../Utils'; +import { Utils } from '../../../Utils'; export class IdentifierReplacer extends AbstractReplacer { /** * @type {Map} */ - private namesMap: Map = new Map(); + private readonly namesMap: Map = new Map(); /** * @param nodeValue diff --git a/src/node-obfuscators/replacers/NumberLiteralReplacer.ts b/src/node-transformers/node-obfuscators/replacers/NumberLiteralReplacer.ts similarity index 91% rename from src/node-obfuscators/replacers/NumberLiteralReplacer.ts rename to src/node-transformers/node-obfuscators/replacers/NumberLiteralReplacer.ts index 3daa2ae4..89a7ab84 100644 --- a/src/node-obfuscators/replacers/NumberLiteralReplacer.ts +++ b/src/node-transformers/node-obfuscators/replacers/NumberLiteralReplacer.ts @@ -1,5 +1,5 @@ import { AbstractReplacer } from './AbstractReplacer'; -import { Utils } from '../../Utils'; +import { Utils } from '../../../Utils'; export class NumberLiteralReplacer extends AbstractReplacer { /** diff --git a/src/node-obfuscators/replacers/StringLiteralReplacer.ts b/src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts similarity index 65% rename from src/node-obfuscators/replacers/StringLiteralReplacer.ts rename to src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts index 266337b4..37165126 100644 --- a/src/node-obfuscators/replacers/StringLiteralReplacer.ts +++ b/src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts @@ -1,23 +1,23 @@ -import { TStringArrayCallsWrapper } from '../../types/custom-nodes/TStringArrayCallsWrapper'; -import { TStringArrayNode } from '../../types/custom-nodes/TStringArrayNode'; +import { ICustomNodeWithData } from '../../../interfaces/custom-nodes/ICustomNodeWithData'; +import { IStorage } from '../../../interfaces/IStorage'; -import { StringArrayEncoding } from '../../enums/StringArrayEncoding'; +import { StringArrayEncoding } from '../../../enums/StringArrayEncoding'; import { AbstractReplacer } from './AbstractReplacer'; import { NumberLiteralReplacer } from './NumberLiteralReplacer'; -import { StringArray } from '../../StringArray'; -import { Utils } from '../../Utils'; +import { Utils } from '../../../Utils'; +import { ICustomNodeWithIdentifier } from '../../../interfaces/custom-nodes/ICustomNodeWithIdentifier'; export class StringLiteralReplacer extends AbstractReplacer { /** * @type {number} */ - private static minimumLengthForStringArray: number = 3; + private static readonly minimumLengthForStringArray: number = 3; /** * @type {string[]} */ - private static rc4Keys: string[] = Utils.getRandomGenerator() + private static readonly rc4Keys: string[] = Utils.getRandomGenerator() .n(() => Utils.getRandomGenerator().string({length: 4}), 50); /** @@ -27,7 +27,7 @@ export class StringLiteralReplacer extends AbstractReplacer { public replace (nodeValue: string): string { const replaceWithStringArrayFlag: boolean = ( nodeValue.length >= StringLiteralReplacer.minimumLengthForStringArray - && Math.random() <= this.options.stringArrayThreshold + && Utils.getRandomFloat(0, 1) <= this.options.stringArrayThreshold ); if (this.options.stringArray && replaceWithStringArrayFlag) { @@ -42,10 +42,10 @@ export class StringLiteralReplacer extends AbstractReplacer { * @returns {string} */ private replaceStringLiteralWithStringArrayCall (value: string): string { - const stringArrayNode: TStringArrayNode = this.nodes.get('stringArrayNode'); + const stringArrayNode: ICustomNodeWithData = this.nodes.get('stringArrayNode'); if (!stringArrayNode) { - throw new ReferenceError('`stringArrayNode` node is not found in Map with custom node.'); + throw new ReferenceError('`stringArrayNode` node is not found in Map with custom nodes.'); } let rc4Key: string = ''; @@ -67,22 +67,20 @@ export class StringLiteralReplacer extends AbstractReplacer { value = Utils.stringToUnicodeEscapeSequence(value); } - let stringArray: StringArray = stringArrayNode.getNodeData(), - indexOfExistingValue: number = stringArray.getIndexOf(value), - indexOfValue: number, - hexadecimalIndex: string; + const stringArray: IStorage = stringArrayNode.getNodeData(); + const indexOfExistingValue: number = stringArray.getKeyOf(value); + + let indexOfValue: number; if (indexOfExistingValue >= 0) { indexOfValue = indexOfExistingValue; } else { indexOfValue = stringArray.getLength(); - stringArrayNode.updateNodeData(value); + stringArray.set(null, value); } - hexadecimalIndex = new NumberLiteralReplacer(this.nodes, this.options) - .replace(indexOfValue); - - const stringArrayCallsWrapper: TStringArrayCallsWrapper = this.nodes.get('stringArrayCallsWrapper'); + const stringArrayCallsWrapper: ICustomNodeWithIdentifier = this.nodes.get('stringArrayCallsWrapper'); + const hexadecimalIndex: string = new NumberLiteralReplacer(this.nodes, this.options).replace(indexOfValue); if (!stringArrayCallsWrapper) { throw new ReferenceError('`stringArrayCallsWrapper` node is not found in Map with custom node.'); diff --git a/src/node/NodeAppender.ts b/src/node/NodeAppender.ts index b5abe4a6..af01e760 100644 --- a/src/node/NodeAppender.ts +++ b/src/node/NodeAppender.ts @@ -101,10 +101,7 @@ export class NodeAppender { * @param stackTraceRootLength */ public static getRandomStackTraceIndex (stackTraceRootLength: number): number { - return Utils.getRandomGenerator().integer({ - min: 0, - max: Math.max(0, Math.round(stackTraceRootLength - 1)) - }); + return Utils.getRandomInteger(0, Math.max(0, Math.round(stackTraceRootLength - 1))); } /** diff --git a/src/node/NodeUtils.ts b/src/node/NodeUtils.ts index 6996df93..743faf7a 100644 --- a/src/node/NodeUtils.ts +++ b/src/node/NodeUtils.ts @@ -15,7 +15,7 @@ export class NodeUtils { /** * @type {string[]} */ - private static nodesWithBlockScope: string[] = [ + private static readonly nodesWithBlockScope: string[] = [ NodeType.ArrowFunctionExpression, NodeType.FunctionDeclaration, NodeType.FunctionExpression, @@ -42,7 +42,7 @@ export class NodeUtils { * @returns {TStatement[]} */ public static convertCodeToStructure (code: string): TStatement[] { - let structure: ESTree.Program = esprima.parse(code); + const structure: ESTree.Program = esprima.parse(code); NodeUtils.addXVerbatimPropertyToLiterals(structure); NodeUtils.parentize(structure); @@ -73,7 +73,7 @@ export class NodeUtils { * @returns {ESTree.Node} */ public static getBlockScopeOfNode (node: ESTree.Node, depth: number = 0): TNodeWithBlockStatement { - let parentNode: ESTree.Node | undefined = node.parentNode; + const parentNode: ESTree.Node | undefined = node.parentNode; if (!parentNode) { throw new ReferenceError('`parentNode` property of given node is `undefined`'); @@ -100,6 +100,29 @@ export class NodeUtils { return NodeUtils.getBlockScopeOfNode(parentNode); } + /** + * @param node + * @param depth + * @returns {number} + */ + public static getNodeBlockScopeDepth (node: ESTree.Node, depth: number = 0): number { + const parentNode: ESTree.Node | undefined = node.parentNode; + + if (!parentNode) { + throw new ReferenceError('`parentNode` property of given node is `undefined`'); + } + + if (Node.isProgramNode(parentNode)) { + return depth; + } + + if (Node.isBlockStatementNode(node)) { + return NodeUtils.getNodeBlockScopeDepth(parentNode, ++depth); + } + + return NodeUtils.getNodeBlockScopeDepth(parentNode, depth); + } + /** * @param node */ diff --git a/src/options/Options.ts b/src/options/Options.ts index 49eec25d..2c0f593f 100644 --- a/src/options/Options.ts +++ b/src/options/Options.ts @@ -41,6 +41,12 @@ export class Options implements IOptions { @IsBoolean() public readonly compact: boolean; + /** + * @type {boolean} + */ + @IsBoolean() + public readonly controlFlowFlattening: boolean; + /** * @type {boolean} */ @@ -85,6 +91,12 @@ export class Options implements IOptions { @IsBoolean() public readonly rotateStringArray: boolean; + /** + * @type {number} + */ + @IsNumber() + public readonly seed: number; + /** * @type {boolean} */ @@ -152,7 +164,7 @@ export class Options implements IOptions { constructor (obfuscatorOptions: IObfuscatorOptions) { Object.assign(this, DEFAULT_PRESET, obfuscatorOptions); - let errors: ValidationError[] = validateSync(this, Options.validatorOptions); + const errors: ValidationError[] = validateSync(this, Options.validatorOptions); if (errors.length) { throw new ReferenceError(`Validation failed. errors:\n${ValidationErrorsFormatter.format(errors)}`); diff --git a/src/options/OptionsNormalizer.ts b/src/options/OptionsNormalizer.ts index b21ccf2f..ea9efed1 100644 --- a/src/options/OptionsNormalizer.ts +++ b/src/options/OptionsNormalizer.ts @@ -9,7 +9,7 @@ export class OptionsNormalizer { /** * @type {IObfuscatorOptions} */ - private static DISABLED_UNICODE_ARRAY_OPTIONS: IObfuscatorOptions = { + private static readonly DISABLED_UNICODE_ARRAY_OPTIONS: IObfuscatorOptions = { rotateStringArray: false, stringArray: false, stringArrayEncoding: false, @@ -19,7 +19,7 @@ export class OptionsNormalizer { /** * @type {IObfuscatorOptions} */ - private static SELF_DEFENDING_OPTIONS: IObfuscatorOptions = { + private static readonly SELF_DEFENDING_OPTIONS: IObfuscatorOptions = { compact: true, selfDefending: true }; @@ -27,14 +27,14 @@ export class OptionsNormalizer { /** * @type {IObfuscatorOptions} */ - private static UNICODE_ARRAY_ENCODING_OPTIONS: IObfuscatorOptions = { + private static readonly UNICODE_ARRAY_ENCODING_OPTIONS: IObfuscatorOptions = { stringArrayEncoding: 'base64' }; /** * @type {TOptionsNormalizerRule[]} */ - private static normalizerRules: TOptionsNormalizerRule[] = [ + private static readonly normalizerRules: TOptionsNormalizerRule[] = [ OptionsNormalizer.domainLockRule, OptionsNormalizer.selfDefendingRule, OptionsNormalizer.sourceMapBaseUrlRule, @@ -64,7 +64,7 @@ export class OptionsNormalizer { */ private static domainLockRule (options: IOptions): IOptions { if (options.domainLock.length) { - let normalizedDomains: string[] = []; + const normalizedDomains: string[] = []; for (const domain of options.domainLock) { normalizedDomains.push(Utils.extractDomainFromUrl(domain)); @@ -95,7 +95,7 @@ export class OptionsNormalizer { * @returns {IOptions} */ private static sourceMapBaseUrlRule (options: IOptions): IOptions { - let sourceMapBaseUrl: string = options.sourceMapBaseUrl; + const sourceMapBaseUrl: string = options.sourceMapBaseUrl; if (!options.sourceMapFileName) { Object.assign(options, { diff --git a/src/options/ValidationErrorsFormatter.ts b/src/options/ValidationErrorsFormatter.ts index e04ef666..52a79a88 100644 --- a/src/options/ValidationErrorsFormatter.ts +++ b/src/options/ValidationErrorsFormatter.ts @@ -6,7 +6,7 @@ export class ValidationErrorsFormatter { * @returns {string} */ public static format (validationErrors: ValidationError[]): string { - let errorsArray: string[] = []; + const errorsArray: string[] = []; for (const error of validationErrors) { errorsArray.push(ValidationErrorsFormatter.formatError(error)); @@ -20,8 +20,9 @@ export class ValidationErrorsFormatter { * @returns {string} */ private static formatError (validationError: ValidationError): string { - let errorString: string = `\`${validationError.property}\` errors:\n`, - constraints: {[type: string]: string} = validationError.constraints; + const constraints: {[type: string]: string} = validationError.constraints; + + let errorString: string = `\`${validationError.property}\` errors:\n`; for (const constraint in constraints) { if (!constraints.hasOwnProperty(constraint)) { diff --git a/src/preset-options/DefaultPreset.ts b/src/preset-options/DefaultPreset.ts index 1d6a5fe1..7f35d55d 100644 --- a/src/preset-options/DefaultPreset.ts +++ b/src/preset-options/DefaultPreset.ts @@ -4,12 +4,14 @@ import { SourceMapMode } from '../enums/SourceMapMode'; export const DEFAULT_PRESET: IObfuscatorOptions = Object.freeze({ compact: true, + controlFlowFlattening: false, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: true, domainLock: [], reservedNames: [], rotateStringArray: true, + seed: 0, selfDefending: true, sourceMap: false, sourceMapBaseUrl: '', diff --git a/src/preset-options/NoCustomNodesPreset.ts b/src/preset-options/NoCustomNodesPreset.ts index f8f000a3..fb5ad5f4 100644 --- a/src/preset-options/NoCustomNodesPreset.ts +++ b/src/preset-options/NoCustomNodesPreset.ts @@ -4,12 +4,14 @@ import { SourceMapMode } from '../enums/SourceMapMode'; export const NO_CUSTOM_NODES_PRESET: IObfuscatorOptions = Object.freeze({ compact: true, + controlFlowFlattening: false, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: false, domainLock: [], reservedNames: [], rotateStringArray: false, + seed: 0, selfDefending: false, sourceMap: false, sourceMapBaseUrl: '', diff --git a/src/stack-trace-analyzer/StackTraceAnalyzer.ts b/src/stack-trace-analyzer/StackTraceAnalyzer.ts index c30155b1..46015fca 100644 --- a/src/stack-trace-analyzer/StackTraceAnalyzer.ts +++ b/src/stack-trace-analyzer/StackTraceAnalyzer.ts @@ -51,34 +51,22 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer { /** * @type {number} */ - private static limitThresholdActivationLength: number = 25; + private static readonly limitThresholdActivationLength: number = 25; /** * @type {number} */ - private static limitThreshold: number = 0.002; - - /** - * @type {ESTree.Node[]} - */ - private blockScopeBody: ESTree.Node[]; + private static readonly limitThreshold: number = 0.002; /** * @type {Map} */ - private calleeDataExtractors: Map = new Map ([ + private readonly calleeDataExtractors: Map = new Map ([ [NodeType.FunctionDeclaration, FunctionDeclarationCalleeDataExtractor], [NodeType.FunctionExpression, FunctionExpressionCalleeDataExtractor], [NodeType.ObjectExpression, ObjectExpressionCalleeDataExtractor] ]); - /** - * @param blockScopeBody - */ - constructor (blockScopeBody: ESTree.Node[]) { - this.blockScopeBody = blockScopeBody; - } - /** * @param blockScopeBodyLength * @returns {number} @@ -103,10 +91,11 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer { } /** + * @param blockScopeBody * @returns {IStackTraceData[]} */ - public analyze (): IStackTraceData[] { - return this.analyzeRecursive(this.blockScopeBody); + public analyze (blockScopeBody: ESTree.Node[]): IStackTraceData[] { + return this.analyzeRecursive(blockScopeBody); } /** @@ -122,7 +111,7 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer { index < blockScopeBodyLength; index++ ) { - let rootNode: ESTree.Node = blockScopeBody[index]; + const rootNode: ESTree.Node = blockScopeBody[index]; if (index > limitIndex) { break; diff --git a/src/storages/ArrayStorage.ts b/src/storages/ArrayStorage.ts new file mode 100644 index 00000000..1c6b452a --- /dev/null +++ b/src/storages/ArrayStorage.ts @@ -0,0 +1,52 @@ +import { IStorage } from '../interfaces/IStorage'; + +export abstract class ArrayStorage implements IStorage { + /** + * @type {T[]} + */ + protected storage: T[] = []; + + /** + * @param key + * @returns {T} + */ + public get (key: number): T { + const value: T | undefined = this.storage[key]; + + if (!value) { + throw new Error(`No value found in array storage with key \`${key}\``); + } + + return value; + } + + /** + * @param value + * @returns {string | number} + */ + public getKeyOf (value: T): string | number { + return this.storage.indexOf(value); + } + + /** + * @returns {number} + */ + public getLength (): number { + return this.storage.length; + } + + /** + * @returns {T[]} + */ + public getStorage (): T[] { + return this.storage; + } + + /** + * @param key + * @param value + */ + public set (key: string | null, value: T): void { + this.storage.push(value); + } +} diff --git a/src/storages/MapStorage.ts b/src/storages/MapStorage.ts new file mode 100644 index 00000000..9d7944a6 --- /dev/null +++ b/src/storages/MapStorage.ts @@ -0,0 +1,54 @@ +import { IStorage } from '../interfaces/IStorage'; + +import { Utils } from '../Utils'; + +export abstract class MapStorage implements IStorage { + /** + * @type {Map } + */ + protected storage: Map = new Map (); + + /** + * @param key + * @returns {T} + */ + public get (key: string | number): T { + const value: T | undefined = this.storage.get(key); + + if (!value) { + throw new Error(`No value found in map storage with key \`${key}\``); + } + + return value; + } + + /** + * @param value + * @returns {string | number | null} + */ + public getKeyOf (value: T): string | number | null { + return Utils.mapGetFirstKeyOf(this.storage, value); + } + + /** + * @returns {number} + */ + public getLength (): number { + return Array.from(this.storage).length; + } + + /** + * @returns {Map } + */ + public getStorage (): Map { + return this.storage; + } + + /** + * @param key + * @param value + */ + public set (key: string | number, value: T): void { + this.storage.set(key, value); + } +} diff --git a/src/storages/control-flow/ControlFlowStorage.ts b/src/storages/control-flow/ControlFlowStorage.ts new file mode 100644 index 00000000..f14d4ed2 --- /dev/null +++ b/src/storages/control-flow/ControlFlowStorage.ts @@ -0,0 +1,19 @@ +import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; + +import { MapStorage } from '../MapStorage'; + +export class ControlFlowStorage extends MapStorage { + /** + * @returns {string} + */ + public toString (): string { + return Array + .from(this.storage) + .reduce((controlFlowStorageItems: string[], [key, value]: [string, ICustomNode]) => { + controlFlowStorageItems.push(`${key}: ${value.getCode()}`); + + return controlFlowStorageItems; + }, []) + .join(','); + } +} diff --git a/src/storages/string-array/StringArrayStorage.ts b/src/storages/string-array/StringArrayStorage.ts new file mode 100644 index 00000000..9c7c7458 --- /dev/null +++ b/src/storages/string-array/StringArrayStorage.ts @@ -0,0 +1,20 @@ +import { ArrayStorage } from '../ArrayStorage'; +import { Utils } from '../../Utils'; + +export class StringArrayStorage extends ArrayStorage { + /** + * @param rotationValue + */ + public rotateArray (rotationValue: number): void { + this.storage = Utils.arrayRotate(this.storage, rotationValue); + } + + /** + * @returns {string} + */ + public toString (): string { + return this.storage.map((value: string) => { + return `'${value}'`; + }).toString(); + } +} diff --git a/src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate.ts b/src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate.ts new file mode 100644 index 00000000..5f6e479b --- /dev/null +++ b/src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate.ts @@ -0,0 +1,10 @@ +/** + * @returns {string} + */ +export function BinaryExpressionFunctionTemplate (): string { + return ` + function {functionName} (x, y) { + return x {operator} y; + } + `; +} diff --git a/src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallTemplate.ts b/src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallTemplate.ts new file mode 100644 index 00000000..a1147cf1 --- /dev/null +++ b/src/templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallTemplate.ts @@ -0,0 +1,6 @@ +/** + * @returns {string} + */ +export function ControlFlowStorageCallTemplate (): string { + return '{controlFlowStorageName}.{controlFlowStorageKey}({leftValue}, {rightValue})'; +} diff --git a/src/templates/custom-nodes/control-flow-storage-nodes/ControlFlowStorageTemplate.ts b/src/templates/custom-nodes/control-flow-storage-nodes/ControlFlowStorageTemplate.ts new file mode 100644 index 00000000..00de90f7 --- /dev/null +++ b/src/templates/custom-nodes/control-flow-storage-nodes/ControlFlowStorageTemplate.ts @@ -0,0 +1,8 @@ +/** + * @returns {string} + */ +export function ControlFlowStorageTemplate (): string { + return ` + var {controlFlowStorageName} = { {controlFlowStorage} }; + `; +} diff --git a/src/templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate.ts b/src/templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate.ts index 4a8627a3..db74f382 100644 --- a/src/templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate.ts +++ b/src/templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate.ts @@ -1,5 +1,3 @@ -import { Utils } from '../../../../Utils'; - /** * @returns {string} */ @@ -10,7 +8,7 @@ export function DebugProtectionFunctionTemplate (): string { if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) { (function () {}.constructor('debugger')()); } else { - [].filter.constructor(${Utils.stringToJSFuck('debugger')})(); + (function () {}.constructor('debugger')()); } debuggerProtection(++counter); diff --git a/src/types/TControlFlowReplacer.d.ts b/src/types/TControlFlowReplacer.d.ts new file mode 100644 index 00000000..b80db1e5 --- /dev/null +++ b/src/types/TControlFlowReplacer.d.ts @@ -0,0 +1,5 @@ +import { IControlFlowReplacer } from '../interfaces/IControlFlowReplacer'; +import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; +import { IOptions } from '../interfaces/IOptions'; + +export type TControlFlowReplacer = (new (nodes: Map , options: IOptions) => IControlFlowReplacer); diff --git a/src/types/TNodeObfuscator.d.ts b/src/types/TNodeObfuscator.d.ts deleted file mode 100644 index 7dc60547..00000000 --- a/src/types/TNodeObfuscator.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; -import { INodeObfuscator } from '../interfaces/INodeObfuscator'; -import { IOptions } from '../interfaces/IOptions'; - -export type TNodeObfuscator = (new (nodes: Map , options: IOptions) => INodeObfuscator); diff --git a/src/types/TNodeTransformer.d.ts b/src/types/TNodeTransformer.d.ts new file mode 100644 index 00000000..2483c600 --- /dev/null +++ b/src/types/TNodeTransformer.d.ts @@ -0,0 +1,5 @@ +import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; +import { INodeTransformer } from '../interfaces/INodeTransformer'; +import { IOptions } from '../interfaces/IOptions'; + +export type TNodeTransformer = (new (nodes: Map , options: IOptions) => INodeTransformer); diff --git a/src/types/TVisitorDirection.d.ts b/src/types/TVisitorDirection.d.ts new file mode 100644 index 00000000..830fc4be --- /dev/null +++ b/src/types/TVisitorDirection.d.ts @@ -0,0 +1 @@ +export type TVisitorDirection = 'enter' | 'leave'; diff --git a/src/types/custom-nodes/TStringArrayCallsWrapper.d.ts b/src/types/custom-nodes/TStringArrayCallsWrapper.d.ts deleted file mode 100644 index beb1903b..00000000 --- a/src/types/custom-nodes/TStringArrayCallsWrapper.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ICustomNodeWithIdentifier } from '../../interfaces/custom-nodes/ICustomNodeWithIdentifier'; - -export type TStringArrayCallsWrapper = ICustomNodeWithIdentifier; diff --git a/src/types/custom-nodes/TStringArrayNode.d.ts b/src/types/custom-nodes/TStringArrayNode.d.ts deleted file mode 100644 index 5d5e42d4..00000000 --- a/src/types/custom-nodes/TStringArrayNode.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ICustomNodeWithData } from '../../interfaces/custom-nodes/ICustomNodeWithData'; -import { ICustomNodeWithIdentifier } from '../../interfaces/custom-nodes/ICustomNodeWithIdentifier'; - -export type TStringArrayNode = ICustomNodeWithData & ICustomNodeWithIdentifier; diff --git a/test/dev/dev.ts b/test/dev/dev.ts index f9502967..a2d9076e 100644 --- a/test/dev/dev.ts +++ b/test/dev/dev.ts @@ -1,4 +1,5 @@ 'use strict'; +import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset'; if (!(global)._babelPolyfill) { require('babel-polyfill'); @@ -7,72 +8,21 @@ if (!(global)._babelPolyfill) { (function () { const JavaScriptObfuscator: any = require("../../index"); - 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 + let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(` + (function(){ + function t () { + return function () { + var t = 1 * 2; + } } - 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}); - - try { - } catch (error) { - console.log(error); - } - })(); + var s = 1 - 3; + })(); `, - { - disableConsoleOutput: false, - selfDefending: true, - stringArrayEncoding: 'rc4' - } + Object.assign({}, NO_CUSTOM_NODES_PRESET, { + controlFlowFlattening: true, + disableConsoleOutput: false + }) ).getObfuscatedCode(); console.log(obfuscatedCode); diff --git a/test/fixtures/compile-performance.js b/test/fixtures/compile-performance.js index 1aaef076..21682938 100644 --- a/test/fixtures/compile-performance.js +++ b/test/fixtures/compile-performance.js @@ -6371,7 +6371,7 @@ /* 42 */ /***/ function(module, exports, __webpack_require__) { -// to indexed object, toObject with fallback for non-array-like ES3 strings +// to indexed object, toString with fallback for non-array-like ES3 strings var IObject = __webpack_require__(118) , defined = __webpack_require__(59); module.exports = function(it){ diff --git a/test/fixtures/node-obfuscators/catch-clause-obfuscator/catch-clause-obfuscator.js b/test/fixtures/node-transformers/node-obfuscators/catch-clause-obfuscator/catch-clause-obfuscator.js similarity index 100% rename from test/fixtures/node-obfuscators/catch-clause-obfuscator/catch-clause-obfuscator.js rename to test/fixtures/node-transformers/node-obfuscators/catch-clause-obfuscator/catch-clause-obfuscator.js diff --git a/test/fixtures/node-obfuscators/labeled-statement-obfuscator/labeled-statement-obfuscator.js b/test/fixtures/node-transformers/node-obfuscators/labeled-statement-obfuscator/labeled-statement-obfuscator.js similarity index 100% rename from test/fixtures/node-obfuscators/labeled-statement-obfuscator/labeled-statement-obfuscator.js rename to test/fixtures/node-transformers/node-obfuscators/labeled-statement-obfuscator/labeled-statement-obfuscator.js diff --git a/test/functional-tests/JavaScriptObfuscator.spec.ts b/test/functional-tests/JavaScriptObfuscator.spec.ts index 1ee8cb00..4dc1f763 100644 --- a/test/functional-tests/JavaScriptObfuscator.spec.ts +++ b/test/functional-tests/JavaScriptObfuscator.spec.ts @@ -3,6 +3,7 @@ import { IObfuscationResult } from '../../src/interfaces/IObfuscationResult'; import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscator'; import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset'; +import { readFileAsString } from '../helpers/readFileAsString'; const assert: Chai.AssertStatic = require('chai').assert; @@ -125,5 +126,40 @@ describe('JavaScriptObfuscator', () => { assert.match(obfuscatedCode2, pattern1); assert.match(obfuscatedCode2, pattern2); }); + + it('should returns same code every time with same `seed`', () => { + const code: string = readFileAsString('./test/fixtures/sample.js'); + const seed: number = 12345; + + const obfuscationResult1: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, { seed: seed } + ); + const obfuscationResult2: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, { seed: seed } + ); + + assert.equal(obfuscationResult1.getObfuscatedCode(), obfuscationResult2.getObfuscatedCode()); + }); + + it('should returns different code with different `seed` option value', () => { + const code: string = readFileAsString('./test/fixtures/sample.js'); + + const obfuscationResult1: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, { seed: 12345 } + ); + const obfuscationResult2: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, { seed: 12346 } + ); + + const obfuscationResult3: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, { seed: 0 } + ); + const obfuscationResult4: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, { seed: 0 } + ); + + assert.notEqual(obfuscationResult1.getObfuscatedCode(), obfuscationResult2.getObfuscatedCode()); + assert.notEqual(obfuscationResult3.getObfuscatedCode(), obfuscationResult4.getObfuscatedCode()); + }); }); }); diff --git a/test/functional-tests/JavaScriptObfuscatorInternal.spec.ts b/test/functional-tests/JavaScriptObfuscatorInternal.spec.ts index 7e59d3f3..a7bd66e4 100644 --- a/test/functional-tests/JavaScriptObfuscatorInternal.spec.ts +++ b/test/functional-tests/JavaScriptObfuscatorInternal.spec.ts @@ -4,6 +4,8 @@ import { JavaScriptObfuscatorInternal } from '../../src/JavaScriptObfuscatorInte import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset'; +import { Options } from '../../src/options/Options'; + const assert: Chai.AssertStatic = require('chai').assert; describe('JavaScriptObfuscatorInternal', () => { @@ -14,16 +16,15 @@ describe('JavaScriptObfuscatorInternal', () => { it('should link obfuscated code with source map', () => { javaScriptObfuscator = new JavaScriptObfuscatorInternal( - `var test = 1;`, - Object.assign({}, NO_CUSTOM_NODES_PRESET, { - sourceMap: true, - sourceMapFileName: sourceMapUrl - }) + new Options( + Object.assign({}, NO_CUSTOM_NODES_PRESET, { + sourceMap: true, + sourceMapFileName: sourceMapUrl + }) + ) ); - javaScriptObfuscator.obfuscate(); - - obfuscationResult = javaScriptObfuscator.getObfuscationResult(); + obfuscationResult = javaScriptObfuscator.obfuscate('var test = 1;'); assert.match( obfuscationResult.getObfuscatedCode(), @@ -36,17 +37,16 @@ describe('JavaScriptObfuscatorInternal', () => { let sourceMapBaseUrl: string = 'http://localhost:9000'; javaScriptObfuscator = new JavaScriptObfuscatorInternal( - `var test = 1;`, - Object.assign({}, NO_CUSTOM_NODES_PRESET, { - sourceMap: true, - sourceMapBaseUrl: sourceMapBaseUrl, - sourceMapFileName: sourceMapUrl - }) + new Options( + Object.assign({}, NO_CUSTOM_NODES_PRESET, { + sourceMap: true, + sourceMapBaseUrl: sourceMapBaseUrl, + sourceMapFileName: sourceMapUrl + }) + ) ); - javaScriptObfuscator.obfuscate(); - - obfuscationResult = javaScriptObfuscator.getObfuscationResult(); + obfuscationResult = javaScriptObfuscator.obfuscate('var test = 1;'); assert.match( obfuscationResult.getObfuscatedCode(), diff --git a/test/functional-tests/node-obfuscators/CatchClauseObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec.ts similarity index 70% rename from test/functional-tests/node-obfuscators/CatchClauseObfuscator.spec.ts rename to test/functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec.ts index 7e8a07ce..ca2ef6f3 100644 --- a/test/functional-tests/node-obfuscators/CatchClauseObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec.ts @@ -1,17 +1,19 @@ -import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult'; +import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult'; -import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset'; +import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset'; -import { readFileAsString } from '../../helpers/readFileAsString'; +import { readFileAsString } from '../../../helpers/readFileAsString'; -import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator'; +import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator'; const assert: Chai.AssertStatic = require('chai').assert; describe('CatchClauseObfuscator', () => { - describe('obfuscateNode (catchClauseNode: ESTree.CatchClause): void', () => { + describe('changeControlFlow (catchClauseNode: ESTree.CatchClause): void', () => { const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( - readFileAsString('./test/fixtures/node-obfuscators/catch-clause-obfuscator/catch-clause-obfuscator.js'), + readFileAsString( + './test/fixtures/node-transformers/node-obfuscators/catch-clause-obfuscator/catch-clause-obfuscator.js' + ), Object.assign({}, NO_CUSTOM_NODES_PRESET) ); const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); diff --git a/test/functional-tests/node-obfuscators/FunctionObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts similarity index 86% rename from test/functional-tests/node-obfuscators/FunctionObfuscator.spec.ts rename to test/functional-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts index 3c6b312f..9208bc5c 100644 --- a/test/functional-tests/node-obfuscators/FunctionObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts @@ -1,8 +1,8 @@ -import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult'; +import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult'; -import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset'; +import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset'; -import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator'; +import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator'; const assert: Chai.AssertStatic = require('chai').assert; diff --git a/test/functional-tests/node-obfuscators/LabeledStatementObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/LabeledStatementObfuscator.spec.ts similarity index 77% rename from test/functional-tests/node-obfuscators/LabeledStatementObfuscator.spec.ts rename to test/functional-tests/node-transformers/node-obfuscators/LabeledStatementObfuscator.spec.ts index 7e567178..06accdd1 100644 --- a/test/functional-tests/node-obfuscators/LabeledStatementObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/LabeledStatementObfuscator.spec.ts @@ -1,17 +1,19 @@ -import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult'; +import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult'; -import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset'; +import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset'; -import { readFileAsString } from '../../helpers/readFileAsString'; +import { readFileAsString } from '../../../helpers/readFileAsString'; -import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator'; +import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator'; const assert: Chai.AssertStatic = require('chai').assert; describe('LabeledStatementObfuscator', () => { - describe('obfuscateNode (labeledStatementNode: ESTree.LabeledStatement): void', () => { + describe('changeControlFlow (labeledStatementNode: ESTree.LabeledStatement): void', () => { const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( - readFileAsString('./test/fixtures/node-obfuscators/labeled-statement-obfuscator/labeled-statement-obfuscator.js'), + readFileAsString( + './test/fixtures/node-transformers/node-obfuscators/labeled-statement-obfuscator/labeled-statement-obfuscator.js' + ), Object.assign({}, NO_CUSTOM_NODES_PRESET) ); const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); diff --git a/test/functional-tests/node-obfuscators/LiteralObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/LiteralObfuscator.spec.ts similarity index 95% rename from test/functional-tests/node-obfuscators/LiteralObfuscator.spec.ts rename to test/functional-tests/node-transformers/node-obfuscators/LiteralObfuscator.spec.ts index 837e0d54..9d8c2562 100644 --- a/test/functional-tests/node-obfuscators/LiteralObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/LiteralObfuscator.spec.ts @@ -1,8 +1,8 @@ -import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult'; +import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult'; -import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset'; +import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset'; -import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator'; +import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator'; const assert: Chai.AssertStatic = require('chai').assert; diff --git a/test/functional-tests/node-obfuscators/MemberExpressionObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/MemberExpressionObfuscator.spec.ts similarity index 91% rename from test/functional-tests/node-obfuscators/MemberExpressionObfuscator.spec.ts rename to test/functional-tests/node-transformers/node-obfuscators/MemberExpressionObfuscator.spec.ts index e24df2e2..10de5feb 100644 --- a/test/functional-tests/node-obfuscators/MemberExpressionObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/MemberExpressionObfuscator.spec.ts @@ -1,8 +1,8 @@ -import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult'; +import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult'; -import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset'; +import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset'; -import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator'; +import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator'; const assert: Chai.AssertStatic = require('chai').assert; diff --git a/test/functional-tests/node-obfuscators/MethodDefinitionObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/MethodDefinitionObfuscator.spec.ts similarity index 85% rename from test/functional-tests/node-obfuscators/MethodDefinitionObfuscator.spec.ts rename to test/functional-tests/node-transformers/node-obfuscators/MethodDefinitionObfuscator.spec.ts index f5d09cdd..2d517d62 100644 --- a/test/functional-tests/node-obfuscators/MethodDefinitionObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/MethodDefinitionObfuscator.spec.ts @@ -1,8 +1,8 @@ -import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult'; +import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult'; -import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset'; +import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset'; -import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator'; +import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator'; const assert: Chai.AssertStatic = require('chai').assert; diff --git a/test/functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/ObjectExpressionObfuscator.spec.ts similarity index 89% rename from test/functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec.ts rename to test/functional-tests/node-transformers/node-obfuscators/ObjectExpressionObfuscator.spec.ts index 793fa305..90e1b1d4 100644 --- a/test/functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/ObjectExpressionObfuscator.spec.ts @@ -1,8 +1,8 @@ -import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult'; +import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult'; -import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset'; +import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset'; -import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator'; +import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator'; const assert: Chai.AssertStatic = require('chai').assert; diff --git a/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/VariableDeclarationObfuscator.spec.ts similarity index 97% rename from test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts rename to test/functional-tests/node-transformers/node-obfuscators/VariableDeclarationObfuscator.spec.ts index 28fd2333..df52191c 100644 --- a/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/VariableDeclarationObfuscator.spec.ts @@ -1,8 +1,8 @@ -import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult'; +import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult'; -import { NO_CUSTOM_NODES_PRESET } from '../../../src/preset-options/NoCustomNodesPreset'; +import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset'; -import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator'; +import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator'; const assert: Chai.AssertStatic = require('chai').assert; diff --git a/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts b/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts index 9f57f12e..86859603 100644 --- a/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts +++ b/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts @@ -4,6 +4,7 @@ import * as ESTree from 'estree'; import { TNodeWithBlockStatement } from '../../../src/types/TNodeWithBlockStatement'; +import { IStackTraceAnalyzer } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer'; import { IStackTraceData } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceData'; import { readFileAsString } from '../../helpers/readFileAsString'; @@ -145,6 +146,8 @@ function getObjectFunctionExpressionByName (astTree: ESTree.Node, objectName: st describe('StackTraceAnalyzer', () => { describe('extract (): IStackTraceData[]', () => { + const stackTraceAnalyzer: IStackTraceAnalyzer = new StackTraceAnalyzer(); + let astTree: TNodeWithBlockStatement, stackTraceData: IStackTraceData[], expectedStackTraceData: IStackTraceData[]; @@ -191,7 +194,7 @@ describe('StackTraceAnalyzer', () => { } ]; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -227,7 +230,7 @@ describe('StackTraceAnalyzer', () => { } ]; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -263,7 +266,7 @@ describe('StackTraceAnalyzer', () => { } ]; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -283,7 +286,7 @@ describe('StackTraceAnalyzer', () => { } ]; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -339,7 +342,7 @@ describe('StackTraceAnalyzer', () => { } ]; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -364,7 +367,7 @@ describe('StackTraceAnalyzer', () => { }, ]; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -378,7 +381,7 @@ describe('StackTraceAnalyzer', () => { expectedStackTraceData = []; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -392,7 +395,7 @@ describe('StackTraceAnalyzer', () => { expectedStackTraceData = []; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -424,7 +427,7 @@ describe('StackTraceAnalyzer', () => { } ]; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); @@ -444,7 +447,7 @@ describe('StackTraceAnalyzer', () => { } ]; - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); assert.deepEqual(stackTraceData, expectedStackTraceData); }); diff --git a/test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts b/test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts index b65c8ab2..7a63ee44 100644 --- a/test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts +++ b/test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts @@ -1,4 +1,4 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { DomainLockNodeTemplate } from '../../../../../src/templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate'; @@ -14,7 +14,7 @@ const assert: Chai.AssertStatic = require('chai').assert; * @returns {Function} */ function getFunctionFromTemplate (templateData: any, callsControllerFunctionName: string, currentDomain: string) { - let domainLockTemplate: string = DomainLockNodeTemplate().formatUnicorn(templateData); + let domainLockTemplate: string = format(DomainLockNodeTemplate(), templateData); return Function(` document = { diff --git a/test/functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts b/test/functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts index 8135300e..773039b4 100644 --- a/test/functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts +++ b/test/functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts @@ -1,4 +1,4 @@ -import 'format-unicorn'; +import * as format from 'string-template'; import { AtobTemplate } from '../../../../../src/templates/custom-nodes/AtobTemplate'; import { Rc4Template } from '../../../../../src/templates/custom-nodes/Rc4Template'; @@ -23,7 +23,7 @@ function getFunctionFromTemplateBase64Encoding ( stringArrayCallsWrapperName: string, index: string ) { - let stringArrayCallsWrapperTemplate: string = StringArrayCallsWrapperTemplate().formatUnicorn(templateData); + let stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), templateData); return Function(` var ${stringArrayName} = ['${Utils.btoa('test1')}']; @@ -49,7 +49,7 @@ function getFunctionFromTemplateRc4Encoding ( index: string, key: string ) { - let stringArrayCallsWrapperTemplate: string = StringArrayCallsWrapperTemplate().formatUnicorn(templateData); + let stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), templateData); return Function(` var ${stringArrayName} = ['${Utils.btoa(Utils.rc4('test1', key))}']; @@ -63,12 +63,12 @@ function getFunctionFromTemplateRc4Encoding ( describe('StringArrayCallsWrapperNodeTemplate (): string', () => { let stringArrayName: string = 'stringArrayName', stringArrayCallsWrapperName: string = 'stringArrayCallsWrapperName', - atobDecodeNodeTemplate: string = StringArrayBase64DecodeNodeTemplate().formatUnicorn({ + atobDecodeNodeTemplate: string = format(StringArrayBase64DecodeNodeTemplate(), { atobPolyfill: AtobTemplate(), selfDefendingCode: '', stringArrayCallsWrapperName }), - rc4DecodeNodeTemplate: string = StringArrayRc4DecodeNodeTemplate().formatUnicorn({ + rc4DecodeNodeTemplate: string = format(StringArrayRc4DecodeNodeTemplate(), { atobPolyfill: AtobTemplate(), rc4Polyfill: Rc4Template(), selfDefendingCode: '', diff --git a/test/index.spec.ts b/test/index.spec.ts index 5eb695f1..5a2e2271 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -14,8 +14,8 @@ import './unit-tests/OptionsNormalizer.spec'; import './unit-tests/SourceMapCorrector.spec'; import './unit-tests/Utils.spec'; import './unit-tests/cli/CLIUtils.spec'; -import './unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec'; -import './unit-tests/node-obfuscators/FunctionObfuscator.spec'; +import './unit-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec'; +import './unit-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec'; import './unit-tests/stack-trace-analyzer/StackTraceAnalyzer.spec'; /** @@ -29,14 +29,14 @@ import './functional-tests/custom-nodes/domain-lock-nodes/DomainLockNode.spec'; import './functional-tests/custom-nodes/string-array-nodes/StringArrayCallsWrapper.spec'; import './functional-tests/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.spec'; import './functional-tests/custom-nodes/string-array-nodes/StringArrayNode.spec'; -import './functional-tests/node-obfuscators/CatchClauseObfuscator.spec'; -import './functional-tests/node-obfuscators/FunctionObfuscator.spec'; -import './functional-tests/node-obfuscators/LabeledStatementObfuscator.spec'; -import './functional-tests/node-obfuscators/LiteralObfuscator.spec'; -import './functional-tests/node-obfuscators/MemberExpressionObfuscator.spec'; -import './functional-tests/node-obfuscators/MethodDefinitionObfuscator.spec'; -import './functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec'; -import './functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec'; +import './functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec'; +import './functional-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec'; +import './functional-tests/node-transformers/node-obfuscators/LabeledStatementObfuscator.spec'; +import './functional-tests/node-transformers/node-obfuscators/LiteralObfuscator.spec'; +import './functional-tests/node-transformers/node-obfuscators/MemberExpressionObfuscator.spec'; +import './functional-tests/node-transformers/node-obfuscators/MethodDefinitionObfuscator.spec'; +import './functional-tests/node-transformers/node-obfuscators/ObjectExpressionObfuscator.spec'; +import './functional-tests/node-transformers/node-obfuscators/VariableDeclarationObfuscator.spec'; import './functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec'; import './functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec'; import './functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec'; diff --git a/test/unit-tests/Utils.spec.ts b/test/unit-tests/Utils.spec.ts index a0bc6bba..8f9c6898 100644 --- a/test/unit-tests/Utils.spec.ts +++ b/test/unit-tests/Utils.spec.ts @@ -75,6 +75,34 @@ describe('Utils', () => { }); }); + describe('mapGetFirstKeyOf(map: Map , value: any): any', () => { + it('should returns key of map item', () => { + const map: Map = new Map(); + + map.set('number1', 1); + map.set('number2', 2); + map.set('number3', 2); + + map.set('string1', 'foo'); + map.set('string2', 'bar'); + + map.set('object1', {item: 'value'}); + map.set('object2', {item: 'value'}); + map.set({key: 'object'}, [1, 2, 3]); + + assert.deepEqual(Utils.mapGetFirstKeyOf(map, 1), 'number1'); + assert.deepEqual(Utils.mapGetFirstKeyOf(map, 2), 'number2'); + + assert.deepEqual(Utils.mapGetFirstKeyOf(map, 'foo'), 'string1'); + assert.deepEqual(Utils.mapGetFirstKeyOf(map, 'bar'), 'string2'); + + assert.deepEqual(Utils.mapGetFirstKeyOf(map, {item: 'value'}), 'object1'); + assert.deepEqual(Utils.mapGetFirstKeyOf(map, [1, 2, 3]), {key: 'object'}); + + assert.deepEqual(Utils.mapGetFirstKeyOf(map, 3), null); + }); + }); + describe('stringToJSFuck (string: string): string', () => { let expected: string = `${JSFuck.s} + ${JSFuck.t} + ${JSFuck.r} + ${JSFuck.i} + ${JSFuck.n} + ${JSFuck.g}`; diff --git a/test/unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec.ts b/test/unit-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec.ts similarity index 84% rename from test/unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec.ts rename to test/unit-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec.ts index eb0fb824..c2116bf6 100644 --- a/test/unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec.ts +++ b/test/unit-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec.ts @@ -1,17 +1,17 @@ import * as ESTree from 'estree'; -import { ICustomNode } from '../../../src/interfaces/custom-nodes/ICustomNode'; +import { ICustomNode } from '../../../../src/interfaces/custom-nodes/ICustomNode'; -import { DEFAULT_PRESET } from '../../../src/preset-options/DefaultPreset'; +import { DEFAULT_PRESET } from '../../../../src/preset-options/DefaultPreset'; -import { FunctionDeclarationObfuscator } from '../../../src/node-obfuscators/FunctionDeclarationObfuscator'; -import { NodeMocks } from '../../mocks/NodeMocks'; -import { Options } from '../../../src/options/Options'; +import { FunctionDeclarationObfuscator } from '../../../../src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator'; +import { NodeMocks } from '../../../mocks/NodeMocks'; +import { Options } from '../../../../src/options/Options'; const assert: Chai.AssertStatic = require('chai').assert; describe('FunctionDeclarationObfuscator', () => { - describe('obfuscateNode (functionDeclarationNode: IFunctionDeclarationNode, parentNode: INode): void', () => { + describe('changeControlFlow (functionDeclarationNode: IFunctionDeclarationNode, parentNode: INode): void', () => { let expressionStatementNode: ESTree.ExpressionStatement, functionDeclarationObfuscator: FunctionDeclarationObfuscator, functionDeclarationNode: ESTree.FunctionDeclaration, @@ -59,7 +59,7 @@ describe('FunctionDeclarationObfuscator', () => { functionDeclarationNode['parentNode'] = blockStatementNode; expressionStatementNode['parentNode'] = blockStatementNode; - functionDeclarationObfuscator.obfuscateNode( + functionDeclarationObfuscator.transformNode( functionDeclarationNode, blockStatementNode ); @@ -83,7 +83,7 @@ describe('FunctionDeclarationObfuscator', () => { functionDeclarationNode['parentNode'] = programNode; expressionStatementNode['parentNode'] = programNode; - functionDeclarationObfuscator.obfuscateNode( + functionDeclarationObfuscator.transformNode( functionDeclarationNode, programNode ); diff --git a/test/unit-tests/node-obfuscators/FunctionObfuscator.spec.ts b/test/unit-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts similarity index 84% rename from test/unit-tests/node-obfuscators/FunctionObfuscator.spec.ts rename to test/unit-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts index 52671a73..8f2dc1f9 100644 --- a/test/unit-tests/node-obfuscators/FunctionObfuscator.spec.ts +++ b/test/unit-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts @@ -1,18 +1,18 @@ import * as ESTree from 'estree'; -import { ICustomNode } from '../../../src/interfaces/custom-nodes/ICustomNode'; +import { ICustomNode } from '../../../../src/interfaces/custom-nodes/ICustomNode'; -import { DEFAULT_PRESET } from '../../../src/preset-options/DefaultPreset'; +import { DEFAULT_PRESET } from '../../../../src/preset-options/DefaultPreset'; -import { FunctionObfuscator } from '../../../src/node-obfuscators/FunctionObfuscator'; -import { NodeMocks } from '../../mocks/NodeMocks'; -import { Options } from '../../../src/options/Options'; +import { FunctionObfuscator } from '../../../../src/node-transformers/node-obfuscators/FunctionObfuscator'; +import { NodeMocks } from '../../../mocks/NodeMocks'; +import { Options } from '../../../../src/options/Options'; const assert: Chai.AssertStatic = require('chai').assert; describe('FunctionObfuscator', () => { - describe('obfuscateNode (functionNode: IFunctionNode): void', () => { + describe('changeControlFlow (functionNode: IFunctionNode): void', () => { let blockStatementNode: ESTree.BlockStatement, expressionStatementNode1: ESTree.ExpressionStatement, expressionStatementNode2: ESTree.ExpressionStatement, @@ -66,7 +66,7 @@ describe('FunctionObfuscator', () => { new Options(DEFAULT_PRESET) ); - functionObfuscator.obfuscateNode(functionDeclarationNode); + functionObfuscator.transformNode(functionDeclarationNode); }); it('should obfuscate function parameter', () => { diff --git a/test/unit-tests/node/NodeAppender.spec.ts b/test/unit-tests/node/NodeAppender.spec.ts index e88c63d6..7db6461b 100644 --- a/test/unit-tests/node/NodeAppender.spec.ts +++ b/test/unit-tests/node/NodeAppender.spec.ts @@ -3,6 +3,7 @@ import * as ESTree from 'estree'; import { TStatement } from '../../../src/types/TStatement'; +import { IStackTraceAnalyzer } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer'; import { IStackTraceData } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceData'; import { readFileAsString } from '../../helpers/readFileAsString'; @@ -49,6 +50,8 @@ describe('NodeAppender', () => { }); describe('appendNodeToOptimalBlockScope (blockScopeStackTraceData: IStackTraceData[], blockScopeNode: TNodeWithBlockStatement, nodeBodyStatements: TStatement[], index: number = 0): void', () => { + const stackTraceAnalyzer: IStackTraceAnalyzer = new StackTraceAnalyzer(); + let astTree: ESTree.Program, expectedAstTree: ESTree.Program, node: TStatement[], @@ -73,7 +76,7 @@ describe('NodeAppender', () => { ) ); - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); NodeAppender.appendNodeToOptimalBlockScope(stackTraceData, astTree, node); assert.deepEqual(astTree, expectedAstTree); @@ -92,7 +95,7 @@ describe('NodeAppender', () => { ) ); - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); NodeAppender.appendNodeToOptimalBlockScope(stackTraceData, astTree, node); assert.deepEqual(astTree, expectedAstTree); @@ -118,7 +121,7 @@ describe('NodeAppender', () => { ) ); - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); NodeAppender.appendNodeToOptimalBlockScope(stackTraceData, astTree, node, 2); assert.deepEqual(astTree, expectedAstTree); @@ -132,7 +135,7 @@ describe('NodeAppender', () => { ) ); - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); NodeAppender.appendNodeToOptimalBlockScope(stackTraceData, astTree, node, 1); assert.deepEqual(astTree, expectedAstTree); @@ -150,7 +153,7 @@ describe('NodeAppender', () => { ) ); - stackTraceData = new StackTraceAnalyzer(astTree.body).analyze(); + stackTraceData = stackTraceAnalyzer.analyze(astTree.body); NodeAppender.appendNodeToOptimalBlockScope( stackTraceData, astTree, diff --git a/tslint.json b/tslint.json index dcedfa2a..de7efbf4 100644 --- a/tslint.json +++ b/tslint.json @@ -31,7 +31,6 @@ ], "jsdoc-format": true, "label-position": true, - "label-undefined": true, "max-line-length": false, "member-access": true, "member-ordering": [ @@ -54,10 +53,8 @@ "trace" ], "no-construct": true, - "no-constructor-vars": true, "no-debugger": true, "no-default-export": true, - "no-duplicate-key": true, "no-duplicate-variable": true, "no-empty": false, "no-eval": false, @@ -65,15 +62,14 @@ "no-internal-module": true, "no-invalid-this": true, "no-null-keyword": false, + "no-parameter-properties": true, "no-reference": true, "no-require-imports": false, "no-shadowed-variable": false, "no-string-literal": true, "no-switch-case-fall-through": false, "no-trailing-whitespace": true, - "no-unreachable": true, "no-unused-expression": true, - "no-unused-variable": true, "no-use-before-declare": true, "no-var-keyword": true, "no-var-requires": false, @@ -124,7 +120,6 @@ } ], "use-isnan": true, - "use-strict": false, "variable-name": false, "whitespace": [ true,