diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fee049b..89d124bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log === +v0.7.2 +--- +* runtime error fix [#7](https://github.com/sanex3339/webpack-obfuscator/issues/7) + +* shorthand object expression fix [#16](https://github.com/sanex3339/javascript-obfuscator/issues/16) + v0.7.1 --- * IE error fix [#14](https://github.com/sanex3339/javascript-obfuscator/issues/14) diff --git a/dist/index.js b/dist/index.js index 3142bdc4..83f46197 100644 --- a/dist/index.js +++ b/dist/index.js @@ -221,7 +221,7 @@ var escodegen = __webpack_require__(10); var esprima = __webpack_require__(18); var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(7); -var Nodes_1 = __webpack_require__(6); +var Nodes_1 = __webpack_require__(5); var Utils_1 = __webpack_require__(0); var NodeUtils = function () { @@ -324,6 +324,7 @@ var NodeUtils = function () { value = parentNode || node; } node['parentNode'] = value; + node['obfuscated'] = false; } }); } @@ -413,8 +414,88 @@ 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 NodeType_1 = __webpack_require__(7); + +var Nodes = function () { + function Nodes() { + _classCallCheck(this, Nodes); + } + + _createClass(Nodes, null, [{ + key: "getProgramNode", + value: function getProgramNode(bodyNode) { + return { + 'type': NodeType_1.NodeType.Program, + 'body': bodyNode, + 'sourceType': 'script', + 'obfuscated': false + }; + } + }, { + key: "isBlockStatementNode", + value: function isBlockStatementNode(node) { + return node.type === NodeType_1.NodeType.BlockStatement; + } + }, { + key: "isCallExpressionNode", + value: function isCallExpressionNode(node) { + return node.type === NodeType_1.NodeType.CallExpression; + } + }, { + key: "isIdentifierNode", + value: function isIdentifierNode(node) { + return node.type === NodeType_1.NodeType.Identifier; + } + }, { + key: "isLiteralNode", + value: function isLiteralNode(node) { + return node.type === NodeType_1.NodeType.Literal; + } + }, { + key: "isMemberExpressionNode", + value: function isMemberExpressionNode(node) { + return node.type === NodeType_1.NodeType.MemberExpression; + } + }, { + key: "isProgramNode", + value: function isProgramNode(node) { + return node.type === NodeType_1.NodeType.Program; + } + }, { + key: "isPropertyNode", + value: function isPropertyNode(node) { + return node.type === NodeType_1.NodeType.Property; + } + }, { + key: "isVariableDeclaratorNode", + value: function isVariableDeclaratorNode(node) { + return node.type === NodeType_1.NodeType.VariableDeclarator; + } + }, { + key: "isNodeHasBlockStatement", + value: function isNodeHasBlockStatement(node) { + return node.hasOwnProperty('body') && Array.isArray(node.body); + } + }]); + + return Nodes; +}(); + +exports.Nodes = Nodes; + +/***/ }, +/* 6 */ +/***/ 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 JSFuck_1 = __webpack_require__(16); -var Nodes_1 = __webpack_require__(6); +var Nodes_1 = __webpack_require__(5); var Utils_1 = __webpack_require__(0); var NodeObfuscator = function () { @@ -512,80 +593,6 @@ var NodeObfuscator = function () { exports.NodeObfuscator = NodeObfuscator; -/***/ }, -/* 6 */ -/***/ 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 NodeType_1 = __webpack_require__(7); - -var Nodes = function () { - function Nodes() { - _classCallCheck(this, Nodes); - } - - _createClass(Nodes, null, [{ - key: "getProgramNode", - value: function getProgramNode(bodyNode) { - return { - 'type': NodeType_1.NodeType.Program, - 'body': bodyNode, - 'sourceType': 'script' - }; - } - }, { - key: "isBlockStatementNode", - value: function isBlockStatementNode(node) { - return node.type === NodeType_1.NodeType.BlockStatement; - } - }, { - key: "isIdentifierNode", - value: function isIdentifierNode(node) { - return node.type === NodeType_1.NodeType.Identifier; - } - }, { - key: "isLiteralNode", - value: function isLiteralNode(node) { - return node.type === NodeType_1.NodeType.Literal; - } - }, { - key: "isMemberExpressionNode", - value: function isMemberExpressionNode(node) { - return node.type === NodeType_1.NodeType.MemberExpression; - } - }, { - key: "isProgramNode", - value: function isProgramNode(node) { - return node.type === NodeType_1.NodeType.Program; - } - }, { - key: "isPropertyNode", - value: function isPropertyNode(node) { - return node.type === NodeType_1.NodeType.Property; - } - }, { - key: "isVariableDeclaratorNode", - value: function isVariableDeclaratorNode(node) { - return node.type === NodeType_1.NodeType.VariableDeclarator; - } - }, { - key: "isNodeHasBlockStatement", - value: function isNodeHasBlockStatement(node) { - return node.hasOwnProperty('body') && Array.isArray(node.body); - } - }]); - - return Nodes; -}(); - -exports.Nodes = Nodes; - /***/ }, /* 7 */ /***/ function(module, exports, __webpack_require__) { @@ -990,7 +997,7 @@ var FunctionObfuscator_1 = __webpack_require__(40); var LiteralObfuscator_1 = __webpack_require__(41); var MemberExpressionObfuscator_1 = __webpack_require__(42); var MethodDefinitionObfuscator_1 = __webpack_require__(43); -var Nodes_1 = __webpack_require__(6); +var Nodes_1 = __webpack_require__(5); var NodeUtils_1 = __webpack_require__(1); var ObjectExpressionObfuscator_1 = __webpack_require__(44); var SelfDefendingNodesGroup_1 = __webpack_require__(36); @@ -1055,7 +1062,7 @@ var Obfuscator = function () { var _this2 = this; estraverse.replace(node, { - leave: function leave(node, parentNode) { + enter: function enter(node, parentNode) { _this2.initializeNodeObfuscators(node, parentNode); } }); @@ -1378,15 +1385,9 @@ var ConsoleOutputDisableExpressionNode = function (_Node_1$Node) { _inherits(ConsoleOutputDisableExpressionNode, _Node_1$Node); function ConsoleOutputDisableExpressionNode() { - var _Object$getPrototypeO; - _classCallCheck(this, ConsoleOutputDisableExpressionNode); - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(ConsoleOutputDisableExpressionNode)).call.apply(_Object$getPrototypeO, [this].concat(args))); + var _this = _possibleConstructorReturn(this, (ConsoleOutputDisableExpressionNode.__proto__ || Object.getPrototypeOf(ConsoleOutputDisableExpressionNode)).apply(this, arguments)); _this.appendState = AppendState_1.AppendState.BeforeObfuscation; return _this; @@ -1436,7 +1437,7 @@ var DebugProtectionFunctionCallNode = function (_Node_1$Node) { function DebugProtectionFunctionCallNode(debugProtectionFunctionName, options) { _classCallCheck(this, DebugProtectionFunctionCallNode); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionCallNode).call(this, options)); + var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionCallNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionCallNode)).call(this, options)); _this.appendState = AppendState_1.AppendState.BeforeObfuscation; _this.debugProtectionFunctionName = debugProtectionFunctionName; @@ -1489,7 +1490,7 @@ var DebugProtectionFunctionIntervalNode = function (_Node_1$Node) { function DebugProtectionFunctionIntervalNode(debugProtectionFunctionName, options) { _classCallCheck(this, DebugProtectionFunctionIntervalNode); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionIntervalNode).call(this, options)); + var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionIntervalNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionIntervalNode)).call(this, options)); _this.appendState = AppendState_1.AppendState.BeforeObfuscation; _this.debugProtectionFunctionName = debugProtectionFunctionName; @@ -1543,7 +1544,7 @@ var DebugProtectionFunctionNode = function (_Node_1$Node) { function DebugProtectionFunctionNode(debugProtectionFunctionName, options) { _classCallCheck(this, DebugProtectionFunctionNode); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionNode).call(this, options)); + var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionNode)).call(this, options)); _this.appendState = AppendState_1.AppendState.BeforeObfuscation; _this.debugProtectionFunctionName = debugProtectionFunctionName; @@ -1606,15 +1607,9 @@ var SelfDefendingUnicodeNode = function (_Node_1$Node) { _inherits(SelfDefendingUnicodeNode, _Node_1$Node); function SelfDefendingUnicodeNode() { - var _Object$getPrototypeO; - _classCallCheck(this, SelfDefendingUnicodeNode); - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(SelfDefendingUnicodeNode)).call.apply(_Object$getPrototypeO, [this].concat(args))); + var _this = _possibleConstructorReturn(this, (SelfDefendingUnicodeNode.__proto__ || Object.getPrototypeOf(SelfDefendingUnicodeNode)).apply(this, arguments)); _this.appendState = AppendState_1.AppendState.AfterObfuscation; return _this; @@ -1675,7 +1670,7 @@ var UnicodeArrayCallsWrapper = function (_Node_1$Node) { function UnicodeArrayCallsWrapper(unicodeArrayCallsWrapperName, unicodeArrayName, unicodeArray, options) { _classCallCheck(this, UnicodeArrayCallsWrapper); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayCallsWrapper).call(this, options)); + var _this = _possibleConstructorReturn(this, (UnicodeArrayCallsWrapper.__proto__ || Object.getPrototypeOf(UnicodeArrayCallsWrapper)).call(this, options)); _this.appendState = AppendState_1.AppendState.AfterObfuscation; _this.unicodeArrayCallsWrapperName = unicodeArrayCallsWrapperName; @@ -1700,7 +1695,7 @@ var UnicodeArrayCallsWrapper = function (_Node_1$Node) { }, { key: "getNode", value: function getNode() { - return _get(Object.getPrototypeOf(UnicodeArrayCallsWrapper.prototype), "getNode", this).call(this); + return _get(UnicodeArrayCallsWrapper.prototype.__proto__ || Object.getPrototypeOf(UnicodeArrayCallsWrapper.prototype), "getNode", this).call(this); } }, { key: "getNodeStructure", @@ -1752,7 +1747,7 @@ var UnicodeArrayDecodeNode = function (_Node_1$Node) { function UnicodeArrayDecodeNode(unicodeArrayName, unicodeArray, options) { _classCallCheck(this, UnicodeArrayDecodeNode); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayDecodeNode).call(this, options)); + var _this = _possibleConstructorReturn(this, (UnicodeArrayDecodeNode.__proto__ || Object.getPrototypeOf(UnicodeArrayDecodeNode)).call(this, options)); _this.appendState = AppendState_1.AppendState.AfterObfuscation; _this.unicodeArrayName = unicodeArrayName; @@ -1771,7 +1766,7 @@ var UnicodeArrayDecodeNode = function (_Node_1$Node) { }, { key: "getNode", value: function getNode() { - return _get(Object.getPrototypeOf(UnicodeArrayDecodeNode.prototype), "getNode", this).call(this); + return _get(UnicodeArrayDecodeNode.prototype.__proto__ || Object.getPrototypeOf(UnicodeArrayDecodeNode.prototype), "getNode", this).call(this); } }, { key: "getNodeStructure", @@ -1833,7 +1828,7 @@ var UnicodeArrayNode = function (_Node_1$Node) { _classCallCheck(this, UnicodeArrayNode); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayNode).call(this, options)); + var _this = _possibleConstructorReturn(this, (UnicodeArrayNode.__proto__ || Object.getPrototypeOf(UnicodeArrayNode)).call(this, options)); _this.appendState = AppendState_1.AppendState.AfterObfuscation; _this.unicodeArray = []; @@ -1864,7 +1859,7 @@ var UnicodeArrayNode = function (_Node_1$Node) { key: 'getNode', value: function getNode() { Utils_1.Utils.arrayRotate(this.unicodeArray, this.unicodeArrayRotateValue); - return _get(Object.getPrototypeOf(UnicodeArrayNode.prototype), 'getNode', this).call(this); + return _get(UnicodeArrayNode.prototype.__proto__ || Object.getPrototypeOf(UnicodeArrayNode.prototype), 'getNode', this).call(this); } }, { key: 'updateNodeData', @@ -1920,7 +1915,7 @@ var UnicodeArrayRotateFunctionNode = function (_Node_1$Node) { function UnicodeArrayRotateFunctionNode(unicodeArrayName, unicodeArray, unicodeArrayRotateValue, options) { _classCallCheck(this, UnicodeArrayRotateFunctionNode); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayRotateFunctionNode).call(this, options)); + var _this = _possibleConstructorReturn(this, (UnicodeArrayRotateFunctionNode.__proto__ || Object.getPrototypeOf(UnicodeArrayRotateFunctionNode)).call(this, options)); _this.appendState = AppendState_1.AppendState.AfterObfuscation; _this.unicodeArrayName = unicodeArrayName; @@ -1940,7 +1935,7 @@ var UnicodeArrayRotateFunctionNode = function (_Node_1$Node) { }, { key: "getNode", value: function getNode() { - return _get(Object.getPrototypeOf(UnicodeArrayRotateFunctionNode.prototype), "getNode", this).call(this); + return _get(UnicodeArrayRotateFunctionNode.prototype.__proto__ || Object.getPrototypeOf(UnicodeArrayRotateFunctionNode.prototype), "getNode", this).call(this); } }, { key: "getNodeStructure", @@ -1993,7 +1988,7 @@ var ConsoleOutputNodesGroup = function (_NodesGroup_1$NodesGr) { function ConsoleOutputNodesGroup(options) { _classCallCheck(this, ConsoleOutputNodesGroup); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ConsoleOutputNodesGroup).call(this, options)); + var _this = _possibleConstructorReturn(this, (ConsoleOutputNodesGroup.__proto__ || Object.getPrototypeOf(ConsoleOutputNodesGroup)).call(this, options)); if (!_this.options.disableConsoleOutput) { return _possibleConstructorReturn(_this); @@ -2032,7 +2027,7 @@ var DebugProtectionNodesGroup = function (_NodesGroup_1$NodesGr) { function DebugProtectionNodesGroup(options) { _classCallCheck(this, DebugProtectionNodesGroup); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionNodesGroup).call(this, options)); + var _this = _possibleConstructorReturn(this, (DebugProtectionNodesGroup.__proto__ || Object.getPrototypeOf(DebugProtectionNodesGroup)).call(this, options)); _this.debugProtectionFunctionIdentifier = Utils_1.Utils.getRandomVariableName(); if (!_this.options.debugProtection) { @@ -2073,7 +2068,7 @@ var SelfDefendingNodesGroup = function (_NodesGroup_1$NodesGr) { function SelfDefendingNodesGroup(options) { _classCallCheck(this, SelfDefendingNodesGroup); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SelfDefendingNodesGroup).call(this, options)); + var _this = _possibleConstructorReturn(this, (SelfDefendingNodesGroup.__proto__ || Object.getPrototypeOf(SelfDefendingNodesGroup)).call(this, options)); if (!_this.options.selfDefending) { return _possibleConstructorReturn(_this); @@ -2113,7 +2108,7 @@ var UnicodeArrayNodesGroup = function (_NodesGroup_1$NodesGr) { function UnicodeArrayNodesGroup(options) { _classCallCheck(this, UnicodeArrayNodesGroup); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayNodesGroup).call(this, options)); + var _this = _possibleConstructorReturn(this, (UnicodeArrayNodesGroup.__proto__ || Object.getPrototypeOf(UnicodeArrayNodesGroup)).call(this, options)); _this.unicodeArrayName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH); _this.unicodeArrayTranslatorName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH); @@ -2164,21 +2159,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 estraverse = __webpack_require__(4); -var NodeObfuscator_1 = __webpack_require__(5); +var NodeObfuscator_1 = __webpack_require__(6); var CatchClauseObfuscator = function (_NodeObfuscator_1$Nod) { _inherits(CatchClauseObfuscator, _NodeObfuscator_1$Nod); function CatchClauseObfuscator() { - var _Object$getPrototypeO; - _classCallCheck(this, CatchClauseObfuscator); - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(CatchClauseObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args))); + var _this = _possibleConstructorReturn(this, (CatchClauseObfuscator.__proto__ || Object.getPrototypeOf(CatchClauseObfuscator)).apply(this, arguments)); _this.catchClauseParam = new Map(); return _this; @@ -2196,7 +2185,7 @@ var CatchClauseObfuscator = function (_NodeObfuscator_1$Nod) { var _this2 = this; estraverse.traverse(catchClauseNode.param, { - leave: function leave(node) { + enter: function enter(node) { return _this2.storeIdentifiersNames(node, _this2.catchClauseParam); } }); @@ -2207,7 +2196,7 @@ var CatchClauseObfuscator = function (_NodeObfuscator_1$Nod) { var _this3 = this; estraverse.replace(catchClauseNode, { - leave: function leave(node, parentNode) { + enter: function enter(node, parentNode) { _this3.replaceIdentifiersWithRandomNames(node, parentNode, _this3.catchClauseParam); } }); @@ -2236,22 +2225,16 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(7); -var NodeObfuscator_1 = __webpack_require__(5); +var NodeObfuscator_1 = __webpack_require__(6); var NodeUtils_1 = __webpack_require__(1); var FunctionDeclarationObfuscator = function (_NodeObfuscator_1$Nod) { _inherits(FunctionDeclarationObfuscator, _NodeObfuscator_1$Nod); function FunctionDeclarationObfuscator() { - var _Object$getPrototypeO; - _classCallCheck(this, FunctionDeclarationObfuscator); - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(FunctionDeclarationObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args))); + var _this = _possibleConstructorReturn(this, (FunctionDeclarationObfuscator.__proto__ || Object.getPrototypeOf(FunctionDeclarationObfuscator)).apply(this, arguments)); _this.functionName = new Map(); return _this; @@ -2272,7 +2255,7 @@ var FunctionDeclarationObfuscator = function (_NodeObfuscator_1$Nod) { var _this2 = this; estraverse.traverse(functionDeclarationNode.id, { - leave: function leave(node) { + enter: function enter(node) { return _this2.storeIdentifiersNames(node, _this2.functionName); } }); @@ -2312,21 +2295,16 @@ 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 NodeObfuscator_1 = __webpack_require__(5); +var NodeObfuscator_1 = __webpack_require__(6); +var Nodes_1 = __webpack_require__(5); var FunctionObfuscator = function (_NodeObfuscator_1$Nod) { _inherits(FunctionObfuscator, _NodeObfuscator_1$Nod); function FunctionObfuscator() { - var _Object$getPrototypeO; - _classCallCheck(this, FunctionObfuscator); - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(FunctionObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args))); + var _this = _possibleConstructorReturn(this, (FunctionObfuscator.__proto__ || Object.getPrototypeOf(FunctionObfuscator)).apply(this, arguments)); _this.functionParams = new Map(); return _this; @@ -2345,7 +2323,7 @@ var FunctionObfuscator = function (_NodeObfuscator_1$Nod) { functionNode.params.forEach(function (paramsNode) { estraverse.traverse(paramsNode, { - leave: function leave(node) { + enter: function enter(node) { return _this2.storeIdentifiersNames(node, _this2.functionParams); } }); @@ -2357,8 +2335,17 @@ var FunctionObfuscator = function (_NodeObfuscator_1$Nod) { var _this3 = this; var replaceVisitor = { - leave: function leave(node, parentNode) { + enter: function enter(node, parentNode) { + var newNodeName = ''; + if (Nodes_1.Nodes.isIdentifierNode(node)) { + newNodeName = node.name; + } _this3.replaceIdentifiersWithRandomNames(node, parentNode, _this3.functionParams); + if (Nodes_1.Nodes.isIdentifierNode(node)) { + if (node.name !== newNodeName) { + node.obfuscated = true; + } + } } }; functionNode.params.forEach(function (paramsNode) { @@ -2391,8 +2378,8 @@ 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__(10); -var NodeObfuscator_1 = __webpack_require__(5); -var Nodes_1 = __webpack_require__(6); +var NodeObfuscator_1 = __webpack_require__(6); +var Nodes_1 = __webpack_require__(5); var LiteralObfuscator = function (_NodeObfuscator_1$Nod) { _inherits(LiteralObfuscator, _NodeObfuscator_1$Nod); @@ -2400,7 +2387,7 @@ var LiteralObfuscator = function (_NodeObfuscator_1$Nod) { function LiteralObfuscator() { _classCallCheck(this, LiteralObfuscator); - return _possibleConstructorReturn(this, Object.getPrototypeOf(LiteralObfuscator).apply(this, arguments)); + return _possibleConstructorReturn(this, (LiteralObfuscator.__proto__ || Object.getPrototypeOf(LiteralObfuscator)).apply(this, arguments)); } _createClass(LiteralObfuscator, [{ @@ -2456,8 +2443,8 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var escodegen = __webpack_require__(10); var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(7); -var NodeObfuscator_1 = __webpack_require__(5); -var Nodes_1 = __webpack_require__(6); +var NodeObfuscator_1 = __webpack_require__(6); +var Nodes_1 = __webpack_require__(5); var MemberExpressionObfuscator = function (_NodeObfuscator_1$Nod) { _inherits(MemberExpressionObfuscator, _NodeObfuscator_1$Nod); @@ -2465,7 +2452,7 @@ var MemberExpressionObfuscator = function (_NodeObfuscator_1$Nod) { function MemberExpressionObfuscator() { _classCallCheck(this, MemberExpressionObfuscator); - return _possibleConstructorReturn(this, Object.getPrototypeOf(MemberExpressionObfuscator).apply(this, arguments)); + return _possibleConstructorReturn(this, (MemberExpressionObfuscator.__proto__ || Object.getPrototypeOf(MemberExpressionObfuscator)).apply(this, arguments)); } _createClass(MemberExpressionObfuscator, [{ @@ -2474,7 +2461,7 @@ var MemberExpressionObfuscator = function (_NodeObfuscator_1$Nod) { var _this2 = this; estraverse.replace(memberExpressionNode.property, { - leave: function leave(node, parentNode) { + enter: function enter(node, parentNode) { if (Nodes_1.Nodes.isLiteralNode(node)) { _this2.obfuscateLiteralProperty(node); return; @@ -2538,23 +2525,17 @@ 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 NodeObfuscator_1 = __webpack_require__(5); -var Nodes_1 = __webpack_require__(6); +var NodeObfuscator_1 = __webpack_require__(6); +var Nodes_1 = __webpack_require__(5); var Utils_1 = __webpack_require__(0); var MethodDefinitionObfuscator = function (_NodeObfuscator_1$Nod) { _inherits(MethodDefinitionObfuscator, _NodeObfuscator_1$Nod); function MethodDefinitionObfuscator() { - var _Object$getPrototypeO; - _classCallCheck(this, MethodDefinitionObfuscator); - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(MethodDefinitionObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args))); + var _this = _possibleConstructorReturn(this, (MethodDefinitionObfuscator.__proto__ || Object.getPrototypeOf(MethodDefinitionObfuscator)).apply(this, arguments)); _this.ignoredNames = ['constructor']; return _this; @@ -2606,8 +2587,8 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var escodegen = __webpack_require__(10); var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(7); -var NodeObfuscator_1 = __webpack_require__(5); -var Nodes_1 = __webpack_require__(6); +var NodeObfuscator_1 = __webpack_require__(6); +var Nodes_1 = __webpack_require__(5); var Utils_1 = __webpack_require__(0); var ObjectExpressionObfuscator = function (_NodeObfuscator_1$Nod) { @@ -2616,7 +2597,7 @@ var ObjectExpressionObfuscator = function (_NodeObfuscator_1$Nod) { function ObjectExpressionObfuscator() { _classCallCheck(this, ObjectExpressionObfuscator); - return _possibleConstructorReturn(this, Object.getPrototypeOf(ObjectExpressionObfuscator).apply(this, arguments)); + return _possibleConstructorReturn(this, (ObjectExpressionObfuscator.__proto__ || Object.getPrototypeOf(ObjectExpressionObfuscator)).apply(this, arguments)); } _createClass(ObjectExpressionObfuscator, [{ @@ -2625,6 +2606,9 @@ var ObjectExpressionObfuscator = function (_NodeObfuscator_1$Nod) { var _this2 = this; objectExpressionNode.properties.forEach(function (property) { + if (property.shorthand) { + property.shorthand = false; + } estraverse.replace(property.key, { leave: function leave(node, parentNode) { if (Nodes_1.Nodes.isLiteralNode(node)) { @@ -2688,23 +2672,16 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var estraverse = __webpack_require__(4); var NodeType_1 = __webpack_require__(7); -var NodeObfuscator_1 = __webpack_require__(5); +var NodeObfuscator_1 = __webpack_require__(6); var NodeUtils_1 = __webpack_require__(1); -var Utils_1 = __webpack_require__(0); var VariableDeclarationObfuscator = function (_NodeObfuscator_1$Nod) { _inherits(VariableDeclarationObfuscator, _NodeObfuscator_1$Nod); function VariableDeclarationObfuscator() { - var _Object$getPrototypeO; - _classCallCheck(this, VariableDeclarationObfuscator); - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(VariableDeclarationObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args))); + var _this = _possibleConstructorReturn(this, (VariableDeclarationObfuscator.__proto__ || Object.getPrototypeOf(VariableDeclarationObfuscator)).apply(this, arguments)); _this.variableNames = new Map(); return _this; @@ -2737,22 +2714,10 @@ var VariableDeclarationObfuscator = function (_NodeObfuscator_1$Nod) { value: function replaceVariableNames(variableDeclarationNode, variableParentNode) { var _this3 = this; - var scopeNode = variableDeclarationNode.kind === 'var' ? NodeUtils_1.NodeUtils.getBlockScopeOfNode(variableDeclarationNode) : variableParentNode, - isNodeAfterVariableDeclaratorFlag = false; + var scopeNode = variableDeclarationNode.kind === 'var' ? NodeUtils_1.NodeUtils.getBlockScopeOfNode(variableDeclarationNode) : variableParentNode; estraverse.replace(scopeNode, { enter: function enter(node, parentNode) { - var functionNodes = [NodeType_1.NodeType.ArrowFunctionExpression, NodeType_1.NodeType.FunctionDeclaration, NodeType_1.NodeType.FunctionExpression]; - if (Utils_1.Utils.arrayContains(functionNodes, node.type)) { - estraverse.replace(node, { - enter: function enter(node, parentNode) { - _this3.replaceIdentifiersWithRandomNames(node, parentNode, _this3.variableNames); - } - }); - } - if (node === variableDeclarationNode) { - isNodeAfterVariableDeclaratorFlag = true; - } - if (isNodeAfterVariableDeclaratorFlag) { + if (!node.obfuscated) { _this3.replaceIdentifiersWithRandomNames(node, parentNode, _this3.variableNames); } } diff --git a/package.json b/package.json index f5406515..e6594df0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-obfuscator", - "version": "0.7.1", + "version": "0.7.2", "description": "JavaScript obfuscator", "keywords": [ "obfuscator", @@ -22,43 +22,43 @@ "dependencies": { "babel-polyfill": "^6.13.0", "chance": "^1.0.4", - "class-validator": "^0.5.0", + "class-validator": "^0.6.0", "commander": "^2.9.0", "escodegen": "^1.8.1", - "esprima": "^2.7.2", + "esprima": "^3.0.0", "estraverse": "^4.2.0", "format-unicorn": "^1.1.0", "mkdirp": "^0.5.1", "source-map-support": "^0.4.2" }, "devDependencies": { - "@types/chai": "^3.4.31", + "@types/chai": "^3.4.32", "@types/chance": "^0.7.28", "@types/commander": "^2.3.29", "@types/escodegen": "^0.0.3", "@types/esprima": "^2.1.30", "@types/estraverse": "^0.0.3", "@types/format-unicorn": "^0.0.28", - "@types/joi": "^9.0.30", + "@types/joi": "^9.0.31", "@types/mkdirp": "^0.3.28", - "@types/mocha": "^2.2.30", + "@types/mocha": "^2.2.31", "@types/node": "^4.0.30", - "@types/sinon": "^1.16.28", - "babel-cli": "^6.11.4", + "@types/sinon": "^1.16.29", + "babel-cli": "^6.14.0", "babel-loader": "^6.2.5", - "babel-preset-es2015": "^6.13.2", + "babel-preset-es2015": "^6.14.0", "chai": "^3.5.0", - "chai-members-deep": "^1.1.0", - "coveralls": "^2.11.12", + "coveralls": "^2.11.14", "istanbul": "1.1.0-alpha.1", "mocha": "^3.0.2", - "sinon": "^2.0.0-pre.2", + "optimize-js-plugin": "0.0.4", + "sinon": "^2.0.0-pre.3", "ts-loader": "^0.8.2", "ts-node": "^1.3.0", - "tslint": "^3.14.0", + "tslint": "^3.15.1", "typescript": "^2.0.0", - "webpack": "^2.1.0-beta.21", - "webpack-node-externals": "^1.3.3" + "webpack": "^2.1.0-beta.25", + "webpack-node-externals": "^1.4.3" }, "repository": { "type": "git", @@ -83,4 +83,4 @@ "name": "Timofey Kachalov" }, "license": "BSD-2-Clause" -} +} \ No newline at end of file diff --git a/src/NodeUtils.ts b/src/NodeUtils.ts index e616e776..c66b99e7 100644 --- a/src/NodeUtils.ts +++ b/src/NodeUtils.ts @@ -152,6 +152,7 @@ export class NodeUtils { } node['parentNode'] = value; + node['obfuscated'] = false; } }); } diff --git a/src/Nodes.ts b/src/Nodes.ts index 0dfba048..aafe0562 100644 --- a/src/Nodes.ts +++ b/src/Nodes.ts @@ -12,6 +12,7 @@ import { TStatement } from "./types/nodes/TStatement"; import { TNodeWithBlockStatement } from "./types/TNodeWithBlockStatement"; import { NodeType } from "./enums/NodeType"; +import { ICallExpressionNode } from "./interfaces/nodes/ICallExpressionNode"; export class Nodes { /** @@ -22,7 +23,8 @@ export class Nodes { return { 'type': NodeType.Program, 'body': bodyNode, - 'sourceType': 'script' + 'sourceType': 'script', + 'obfuscated': false }; } @@ -34,6 +36,14 @@ export class Nodes { return node.type === NodeType.BlockStatement; } + /** + * @param node + * @returns {boolean} + */ + public static isCallExpressionNode (node: INode): node is ICallExpressionNode { + return node.type === NodeType.CallExpression; + } + /** * @param node * @returns {boolean} diff --git a/src/Obfuscator.ts b/src/Obfuscator.ts index fbc1e86b..74301f30 100644 --- a/src/Obfuscator.ts +++ b/src/Obfuscator.ts @@ -131,7 +131,7 @@ export class Obfuscator implements IObfuscator { */ private obfuscate (node: INode): void { estraverse.replace(node, { - leave: (node: INode, parentNode: INode): any => { + enter: (node: INode, parentNode: INode): any => { this.initializeNodeObfuscators(node, parentNode); } }); diff --git a/src/interfaces/nodes/INode.d.ts b/src/interfaces/nodes/INode.d.ts index 468e02df..5c798c5f 100644 --- a/src/interfaces/nodes/INode.d.ts +++ b/src/interfaces/nodes/INode.d.ts @@ -1,4 +1,5 @@ export interface INode { type: string; parentNode?: INode; + obfuscated?: boolean; } diff --git a/src/node-obfuscators/CatchClauseObfuscator.ts b/src/node-obfuscators/CatchClauseObfuscator.ts index 4061484c..6d843bf4 100644 --- a/src/node-obfuscators/CatchClauseObfuscator.ts +++ b/src/node-obfuscators/CatchClauseObfuscator.ts @@ -32,7 +32,7 @@ export class CatchClauseObfuscator extends NodeObfuscator { */ private storeCatchClauseParam (catchClauseNode: ICatchClauseNode): void { estraverse.traverse(catchClauseNode.param, { - leave: (node: INode): any => this.storeIdentifiersNames(node, this.catchClauseParam) + enter: (node: INode): any => this.storeIdentifiersNames(node, this.catchClauseParam) }); } @@ -41,7 +41,7 @@ export class CatchClauseObfuscator extends NodeObfuscator { */ private replaceCatchClauseParam (catchClauseNode: ICatchClauseNode): void { estraverse.replace(catchClauseNode, { - leave: (node: INode, parentNode: INode): any => { + enter: (node: INode, parentNode: INode): any => { this.replaceIdentifiersWithRandomNames(node, parentNode, this.catchClauseParam); } }); diff --git a/src/node-obfuscators/FunctionDeclarationObfuscator.ts b/src/node-obfuscators/FunctionDeclarationObfuscator.ts index 6cca873a..d97e1216 100644 --- a/src/node-obfuscators/FunctionDeclarationObfuscator.ts +++ b/src/node-obfuscators/FunctionDeclarationObfuscator.ts @@ -41,7 +41,7 @@ export class FunctionDeclarationObfuscator extends NodeObfuscator { */ private storeFunctionName (functionDeclarationNode: IFunctionDeclarationNode): void { estraverse.traverse(functionDeclarationNode.id, { - leave: (node: INode): any => this.storeIdentifiersNames(node, this.functionName) + enter: (node: INode): any => this.storeIdentifiersNames(node, this.functionName) }); } diff --git a/src/node-obfuscators/FunctionObfuscator.ts b/src/node-obfuscators/FunctionObfuscator.ts index 73117633..9a006a4a 100644 --- a/src/node-obfuscators/FunctionObfuscator.ts +++ b/src/node-obfuscators/FunctionObfuscator.ts @@ -4,6 +4,7 @@ import { IFunctionNode } from "../interfaces/nodes/IFunctionNode"; import { INode } from "../interfaces/nodes/INode"; import { NodeObfuscator } from './NodeObfuscator'; +import { Nodes } from "../Nodes"; /** * replaces: @@ -34,7 +35,7 @@ export class FunctionObfuscator extends NodeObfuscator { functionNode.params .forEach((paramsNode: INode) => { estraverse.traverse(paramsNode, { - leave: (node: INode): any => this.storeIdentifiersNames(node, this.functionParams) + enter: (node: INode): any => this.storeIdentifiersNames(node, this.functionParams) }); }); } @@ -44,8 +45,20 @@ export class FunctionObfuscator extends NodeObfuscator { */ private replaceFunctionParams (functionNode: IFunctionNode): void { let replaceVisitor: estraverse.Visitor = { - leave: (node: INode, parentNode: INode): any => { + enter: (node: INode, parentNode: INode): any => { + let newNodeName: string = ''; + + if (Nodes.isIdentifierNode(node)) { + newNodeName = node.name; + } + this.replaceIdentifiersWithRandomNames(node, parentNode, this.functionParams); + + if (Nodes.isIdentifierNode(node)) { + if (node.name !== newNodeName) { + node.obfuscated = true; + } + } } }; diff --git a/src/node-obfuscators/MemberExpressionObfuscator.ts b/src/node-obfuscators/MemberExpressionObfuscator.ts index 3507c121..90066b4a 100644 --- a/src/node-obfuscators/MemberExpressionObfuscator.ts +++ b/src/node-obfuscators/MemberExpressionObfuscator.ts @@ -17,7 +17,7 @@ export class MemberExpressionObfuscator extends NodeObfuscator { */ public obfuscateNode (memberExpressionNode: IMemberExpressionNode): void { estraverse.replace(memberExpressionNode.property, { - leave: (node: INode, parentNode: INode): any => { + enter: (node: INode, parentNode: INode): any => { if (Nodes.isLiteralNode(node)) { this.obfuscateLiteralProperty(node); diff --git a/src/node-obfuscators/ObjectExpressionObfuscator.ts b/src/node-obfuscators/ObjectExpressionObfuscator.ts index 895f241e..68610753 100644 --- a/src/node-obfuscators/ObjectExpressionObfuscator.ts +++ b/src/node-obfuscators/ObjectExpressionObfuscator.ts @@ -30,6 +30,10 @@ export class ObjectExpressionObfuscator extends NodeObfuscator { public obfuscateNode (objectExpressionNode: IObjectExpressionNode): void { objectExpressionNode.properties .forEach((property: IPropertyNode) => { + if (property.shorthand) { + property.shorthand = false; + } + estraverse.replace(property.key, { leave: (node: INode, parentNode: INode): any => { if (Nodes.isLiteralNode(node)) { diff --git a/src/node-obfuscators/VariableDeclarationObfuscator.ts b/src/node-obfuscators/VariableDeclarationObfuscator.ts index 97f479f5..441a540f 100644 --- a/src/node-obfuscators/VariableDeclarationObfuscator.ts +++ b/src/node-obfuscators/VariableDeclarationObfuscator.ts @@ -8,7 +8,6 @@ import { NodeType } from "../enums/NodeType"; import { NodeObfuscator } from './NodeObfuscator'; import { NodeUtils } from "../NodeUtils"; -import { Utils } from '../Utils'; /** * replaces: @@ -58,30 +57,11 @@ export class VariableDeclarationObfuscator extends NodeObfuscator { private replaceVariableNames (variableDeclarationNode: IVariableDeclarationNode, variableParentNode: INode): void { let scopeNode: INode = variableDeclarationNode.kind === 'var' ? NodeUtils.getBlockScopeOfNode( variableDeclarationNode - ) : variableParentNode, - isNodeAfterVariableDeclaratorFlag: boolean = false; + ) : variableParentNode; estraverse.replace(scopeNode, { enter: (node: INode, parentNode: INode): any => { - const functionNodes: string[] = [ - NodeType.ArrowFunctionExpression, - NodeType.FunctionDeclaration, - NodeType.FunctionExpression - ]; - - if (Utils.arrayContains(functionNodes, node.type)) { - estraverse.replace(node, { - enter: (node: INode, parentNode: INode): any => { - this.replaceIdentifiersWithRandomNames(node, parentNode, this.variableNames); - } - }); - } - - if (node === variableDeclarationNode) { - isNodeAfterVariableDeclaratorFlag = true; - } - - if (isNodeAfterVariableDeclaratorFlag) { + if (!node.obfuscated) { this.replaceIdentifiersWithRandomNames(node, parentNode, this.variableNames); } } diff --git a/test/dev/test.ts b/test/dev/test.ts index d5aedbb5..2d9ef22d 100644 --- a/test/dev/test.ts +++ b/test/dev/test.ts @@ -56,6 +56,11 @@ let obfuscatedCode: string = JavaScriptObfuscator.obfuscate( console.log(105.4); console.log(true, false); + var sA = 'shorthand1'; + var sB = 'shorthand2'; + + console.log({sA, sB}); + try { } catch (error) { console.log(error); diff --git a/test/functional-tests/node-obfuscators/FunctionObfuscator.spec.ts b/test/functional-tests/node-obfuscators/FunctionObfuscator.spec.ts new file mode 100644 index 00000000..368dcccd --- /dev/null +++ b/test/functional-tests/node-obfuscators/FunctionObfuscator.spec.ts @@ -0,0 +1,42 @@ +import { IObfuscationResult } from "../../../src/interfaces/IObfuscationResult"; + +import { NO_CUSTOM_NODES_PRESET } from "../../../src/preset-options/NoCustomNodesPreset"; + +import { JavaScriptObfuscator } from "../../../src/JavaScriptObfuscator"; + +const assert: Chai.AssertStatic = require('chai').assert; + +describe('FunctionObfuscator', () => { + describe('identifiers obfuscation inside `FunctionDeclaration` and `FunctionExpression` node body', () => { + it('should correct obfuscate both function parameter identifier and function body identifier with same name', () => { + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + ` + (function () { + var test = function (test) { + console.log(test); + + if (true) { + var test = 5 + } + + return test; + } + })(); + `, + Object.assign({}, NO_CUSTOM_NODES_PRESET) + ); + + const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); + + const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode + .match(/var _0x[a-z0-9]{5,6} *= *function *\((_0x[a-z0-9]{5,6})\) *\{/); + const functionBodyIdentifierMatch: RegExpMatchArray|null = obfuscatedCode + .match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-z0-9]{5,6})\)/); + + const functionParamIdentifierName: string = (functionParamIdentifierMatch)[1]; + const functionBodyIdentifierName: string = (functionBodyIdentifierMatch)[1]; + + assert.equal(functionParamIdentifierName, functionBodyIdentifierName); + }); + }); +}); diff --git a/test/functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec.ts b/test/functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec.ts index 581a3dbb..d1d545c1 100644 --- a/test/functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec.ts +++ b/test/functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec.ts @@ -24,4 +24,22 @@ describe('ObjectExpressionObfuscator', () => { assert.match(obfuscationResult.getObfuscatedCode(), /^var *test *= *\{'\\x66\\x6f\\x6f':0x0\};$/); }); + + it('should correct convert shorthand ES6 object expression to non-shorthand object expression', () => { + let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + ` + (function () { + let a = 0; + let b = 0; + var test = {a, b}; + })(); + `, + Object.assign({}, NO_CUSTOM_NODES_PRESET) + ); + + assert.match( + obfuscationResult.getObfuscatedCode(), + /var *_0x[a-z0-9]{4,6} *= *\{'\\x61': *_0x[a-z0-9]{4,6}\, *'\\x62': *_0x[a-z0-9]{4,6}\};/ + ); + }); }); diff --git a/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts b/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts index 537e58a5..511140ef 100644 --- a/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts +++ b/test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts @@ -18,8 +18,8 @@ describe('VariableDeclarationObfuscator', () => { Object.assign({}, NO_CUSTOM_NODES_PRESET) ); - assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){6} *= *'\\x61\\x62\\x63';/); - assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){6}\);/); + assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4,6} *= *'\\x61\\x62\\x63';/); + assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/); }); it('should obfuscate variable call (`identifier` node) outside of block scope of node in which this variable was declared with `var` kind', () => { @@ -35,7 +35,65 @@ describe('VariableDeclarationObfuscator', () => { Object.assign({}, NO_CUSTOM_NODES_PRESET) ); - assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){6}\);/); + assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/); + }); + + describe(`variable calls before variable declaration when function param has the same name as variables name`, () => { + let obfuscationResult: IObfuscationResult, + functionParamIdentifierName: string|null, + innerFunctionParamIdentifierName: string|null, + constructorIdentifierName: string|null, + objectIdentifierName: string|null, + variableDeclarationIdentifierName: string|null; + + beforeEach(() => { + obfuscationResult = JavaScriptObfuscator.obfuscate( + ` + (function () { + function foo (t, e) { + return function () { + function baz (t) { + console.log(t); + } + + return {t: t}; + var t; + }(); + } + })(); + `, + Object.assign({}, NO_CUSTOM_NODES_PRESET) + ); + }); + + it('should correct obfuscate variables inside function body', () => { + const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); + const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode + .match(/function *_0x[a-z0-9]{5,6} *\((_0x[a-z0-9]{5,6})\,(_0x[a-z0-9]{5,6})\) *\{/); + const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode + .match(/function _0x[a-z0-9]{5,6} *\((_0x[a-z0-9]{5,6})\) *\{/); + const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode + .match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-z0-9]{5,6})\)/); + const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode + .match(/return\{'\\x74':(_0x[a-z0-9]{5,6})\}/); + const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode + .match(/var *(_0x[a-z0-9]{5,6});/); + + functionParamIdentifierName = (functionParamIdentifierMatch)[1]; + innerFunctionParamIdentifierName = (innerFunctionParamIdentifierMatch)[1]; + constructorIdentifierName = (constructorIdentifierMatch)[1]; + objectIdentifierName = (objectIdentifierMatch)[1]; + variableDeclarationIdentifierName = (variableDeclarationIdentifierMatch)[1]; + + assert.notEqual(functionParamIdentifierName, constructorIdentifierName); + assert.notEqual(functionParamIdentifierName, innerFunctionParamIdentifierName); + + assert.equal(functionParamIdentifierName, objectIdentifierName); + assert.equal(functionParamIdentifierName, variableDeclarationIdentifierName); + + assert.equal(innerFunctionParamIdentifierName, constructorIdentifierName); + assert.equal(variableDeclarationIdentifierName, objectIdentifierName); + }); }); it('should not obfuscate variable call (`identifier` node) outside of block scope of node in which this variable was declared with `let` kind', () => { @@ -78,11 +136,11 @@ describe('VariableDeclarationObfuscator', () => { }); it('should obfuscate variable call (`identifier` node) before variable declaration if this call is inside function body', () => { - assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){6}\['\\x69\\x74\\x65\\x6d'\]\);/); + assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\['\\x69\\x74\\x65\\x6d'\]\);/); }); it('should not obfuscate variable call (`identifier` node) before variable declaration', () => { - assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(abc\);/); + assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){5,6}\);/); }); }); }); diff --git a/test/index.spec.ts b/test/index.spec.ts index d3c27a5f..1bd89964 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -23,6 +23,7 @@ import './unit-tests/node-obfuscators/FunctionObfuscator.spec'; import './functional-tests/JavaScriptObfuscator.spec'; import './functional-tests/JavaScriptObfuscatorCLI.spec'; import './functional-tests/JavaScriptObfuscatorInternal.spec'; +import './functional-tests/node-obfuscators/FunctionObfuscator.spec'; import './functional-tests/node-obfuscators/LiteralObfuscator.spec'; import './functional-tests/node-obfuscators/MemberExpressionObfuscator.spec'; import './functional-tests/node-obfuscators/MethodDefinitionObfuscator.spec'; diff --git a/test/mocks/NodeMocks.ts b/test/mocks/NodeMocks.ts index 48fd7a25..bd0cf4a7 100644 --- a/test/mocks/NodeMocks.ts +++ b/test/mocks/NodeMocks.ts @@ -28,7 +28,8 @@ export class NodeMocks { return { type: NodeType.Program, body: bodyNodes, - sourceType: 'script' + sourceType: 'script', + obfuscated: false }; } @@ -39,7 +40,8 @@ export class NodeMocks { public static getBlockStatementNode (bodyNodes: TStatement[] = []): IBlockStatementNode { return { type: NodeType.BlockStatement, - body: bodyNodes + body: bodyNodes, + obfuscated: false }; } @@ -51,7 +53,8 @@ export class NodeMocks { return { type: NodeType.CatchClause, param: NodeMocks.getIdentifierNode('err'), - body: NodeMocks.getBlockStatementNode(bodyNodes) + body: NodeMocks.getBlockStatementNode(bodyNodes), + obfuscated: false }; } @@ -67,7 +70,8 @@ export class NodeMocks { return { type: NodeType.CallExpression, callee: callee, - arguments: args + arguments: args, + obfuscated: false }; } @@ -80,7 +84,8 @@ export class NodeMocks { ): IExpressionStatementNode { return { type: NodeType.ExpressionStatement, - expression: expression + expression: expression, + obfuscated: false }; } @@ -101,7 +106,8 @@ export class NodeMocks { params: params, body: blockStatementNode, generator: false, - expression: false + expression: false, + obfuscated: false }; } @@ -115,10 +121,12 @@ export class NodeMocks { test: { type: 'Literal', value: true, - raw: 'true' + raw: 'true', + obfuscated: false }, consequent: blockStatementNode, - alternate: null + alternate: null, + obfuscated: false }; } @@ -130,6 +138,7 @@ export class NodeMocks { return { type: NodeType.Identifier, name: identifierName, + obfuscated: false }; } @@ -145,7 +154,8 @@ export class NodeMocks { 'x-verbatim-property': { content: `'${value}'`, precedence: escodegen.Precedence.Primary - } + }, + obfuscated: false }; } @@ -162,7 +172,8 @@ export class NodeMocks { type: NodeType.MemberExpression, computed: false, object: object, - property: property + property: property, + obfuscated: false }; } @@ -178,7 +189,8 @@ export class NodeMocks { return { type: NodeType.VariableDeclaration, declarations: declarations, - kind: kind + kind: kind, + obfuscated: false }; } @@ -191,7 +203,8 @@ export class NodeMocks { return { type: NodeType.VariableDeclarator, id: id, - init: init + init: init, + obfuscated: false }; } } diff --git a/test/unit-tests/NodeUtils.spec.ts b/test/unit-tests/NodeUtils.spec.ts index ba13a0b3..d47e7ab7 100644 --- a/test/unit-tests/NodeUtils.spec.ts +++ b/test/unit-tests/NodeUtils.spec.ts @@ -102,7 +102,7 @@ describe('NodeUtils', () => { }); it('should convert code to `INode` structure', () => { - assert.deepEqualIdent(NodeUtils.convertCodeToStructure(code), variableDeclarationNode); + assert.deepEqual(NodeUtils.convertCodeToStructure(code), variableDeclarationNode); }); }); diff --git a/webpack.config.js b/webpack.config.js index 036f0f17..953b86ea 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,15 +1,13 @@ 'use strict'; -let fs = require("fs"), +var fs = require("fs"), nodeExternals = require('webpack-node-externals'), - webpack = require('webpack'); + webpack = require('webpack'), + OptimizeJSPlugin = require('optimize-js-plugin'); function getLicenseText () { - return `/* -Copyright (C) 2016 Timofey Kachalov - -${fs.readFileSync('./LICENSE.BSD', 'utf8')} -*/`; + return "/*\nCopyright (C) 2016 Timofey Kachalov \n\n" + + fs.readFileSync('./LICENSE.BSD', 'utf8') + "\n*/"; } module.exports = { @@ -25,17 +23,16 @@ module.exports = { ] }, resolve: { - extensions: ['', '.ts'], - modulesDirectories: ['./src', './node_modules'] + extensions: ['.ts'] }, plugins: [ new webpack.BannerPlugin( { - banner: `${getLicenseText()}\n\nrequire("source-map-support").install();\n`, + banner: getLicenseText() + '\n\nrequire("source-map-support").install();\n', raw: true, entryOnly: false } - ) + ), ], output: { path: './dist', @@ -43,4 +40,4 @@ module.exports = { libraryTarget: "commonjs2", library: "JavaScriptObfuscator" } -}; +}; \ No newline at end of file