diff --git a/CHANGELOG.md b/CHANGELOG.md index ef5f0f30..7865d276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ v0.10.0 * increased runtime performance with `rc4` `stringArrayEncoding`. * added support for async functions * fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/57 +* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/54 v0.9.3 --- diff --git a/dist/index.js b/dist/index.js index a3320b0a..3f6e9d7a 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,2 +1,2 @@ -require("source-map-support").install(),module.exports=function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=39)}([function(e,t){e.exports=require("inversify")},function(e,t){e.exports=require("tslib")},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ServiceIdentifiers={Factory__ICalleeDataExtractor:Symbol("Factory"),Factory__IControlFlowReplacer:Symbol("Factory"),Factory__ICustomNode:Symbol("Factory"),Factory__ICustomNodeGroup:Symbol("Factory"),Factory__IIdentifierObfuscatingReplacer:Symbol("Factory"),Factory__INodeTransformer:Symbol("Factory"),Factory__IObfuscationResult:Symbol("Factory"),Factory__IObfuscatingReplacer:Symbol("Factory"),Factory__TControlFlowStorage:Symbol("Factory"),ICalleeDataExtractor:Symbol("ICalleeDataExtractor"),ICustomNodeGroup:Symbol("ICustomNodeGroup"),IControlFlowReplacer:Symbol("IControlFlowReplacer"),IDeadCodeInjectionReplacer:Symbol("IDeadCodeInjectionReplacer"),IIdentifierObfuscatingReplacer:Symbol("IIdentifierObfuscatingReplacer"),IJavaScriptObfuscator:Symbol("IJavaScriptObfuscator"),INodeTransformer:Symbol("INodeTransformer"),IObfuscationEventEmitter:Symbol("IObfuscationEventEmitter"),IObfuscationResult:Symbol("IObfuscationResult"),IObfuscator:Symbol("IObfuscator"),IOptions:Symbol("IOptions"),IObfuscatingReplacer:Symbol("IObfuscatingReplacer"),ISourceMapCorrector:Symbol("ISourceMapCorrector"),IStackTraceAnalyzer:Symbol("IStackTraceAnalyzer"),Newable__ICustomNode:Symbol("Newable"),Newable__TControlFlowStorage:Symbol("Newable"),TCustomNodeGroupStorage:Symbol("TCustomNodeGroupStorage"),TStringArrayStorage:Symbol("TStringArrayStorage")}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:0;if(l.Node.isNodeHasBlockStatement(e)){if(void 0===e.body[t])throw new ReferenceError("Wrong index `"+t+"`. Block-statement body length is `"+e.body.length+"`");return e.body[t]}throw new TypeError("The specified node have no a block-statement")}},{key:"getBlockScopesOfNode",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=t.parentNode;if(!r)throw new ReferenceError("`parentNode` property of given node is `undefined`");if(l.Node.isBlockStatementNode(r)){if(!r.parentNode)throw new ReferenceError("`parentNode` property of `parentNode` of given node is `undefined`");-1!==e.nodesWithBlockScope.indexOf(r.parentNode.type)&&n.push(r)}return l.Node.isProgramNode(r)?(n.push(r),n):e.getBlockScopesOfNode(r,n)}},{key:"getNodeBlockScopeDepth",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=t.parentNode;if(!r)throw new ReferenceError("`parentNode` property of given node is `undefined`");return l.Node.isProgramNode(r)?n:l.Node.isBlockStatementNode(t)&&-1!==e.nodesWithBlockScope.indexOf(r.type)?e.getNodeBlockScopeDepth(r,++n):e.getNodeBlockScopeDepth(r,n)}},{key:"getUnaryExpressionArgumentNode",value:function(t){return l.Node.isUnaryExpressionNode(t.argument)?e.getUnaryExpressionArgumentNode(t.argument):t.argument}},{key:"parentize",value:function(e){var t=!0;return s.traverse(e,{enter:function(e,n){var r=void 0;t?(e.type===u.NodeType.Program?r=e:(r=f.Nodes.getProgramNode([e]),r.parentNode=r),t=!1):r=n||e,e.parentNode=r,e.obfuscatedNode=!1}}),e}},{key:"typedReplace",value:function(t,n,r){e.typedTraverse(t,n,r,"replace")}},{key:"typedTraverse",value:function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"traverse";s[r](e,{enter:function(e,r){if(e.type===t&&n.enter)return n.enter(e,r)},leave:function(e,r){if(e.type===t&&n.leave)return n.leave(e,r)}})}}]),e}();d.nodesWithBlockScope=[u.NodeType.ArrowFunctionExpression,u.NodeType.FunctionDeclaration,u.NodeType.FunctionExpression,u.NodeType.MethodDefinition,u.NodeType.Program],t.NodeUtils=d},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:e.randomGeneratorPool;return e.getRandomGenerator().string({length:t,pool:n})}},{key:"getRandomVariableName",value:function(t){var n="_"+i.Utils.hexadecimalPrefix,r=""+n+i.Utils.decToHex(e.getRandomInteger(1e4,99999999)).substr(0,t);return e.randomVariableNameSet.has(r)?e.getRandomVariableName(t):(e.randomVariableNameSet.add(r),r)}}]),e}();c.randomGeneratorPool="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",c.randomGeneratorPoolNumbers="0123456789",c.randomGeneratorPoolHexadecimal="abcdef"+c.randomGeneratorPoolNumbers,c.randomGeneratorPoolWithNumbers=""+c.randomGeneratorPool+c.randomGeneratorPoolNumbers,c.randomVariableNameSet=new Set,t.RandomGeneratorUtils=c},function(e,t,n){"use strict";function r(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"initialize",t=Object.keys(this)[0];return function(n,r){var o={configurable:!0,enumerable:!0},a=n[e];if(!a||"function"!=typeof a)throw new Error("`"+e+"` method with initialization logic not found. `@"+t+"` decorator requires `"+e+"` method");var i="_"+r,c=Object.getOwnPropertyDescriptor(n,i)||o,s=Object.getOwnPropertyDescriptor(n,e)||o,u=s.value;return Object.defineProperty(n,r,Object.assign({},c,{get:function(){if(void 0===this[i])throw new Error("Property `"+r+"` is not initialized! Initialize it first!");return this[i]},set:function(e){this[i]=e}})),Object.defineProperty(n,e,Object.assign({},s,{value:function(){u.apply(this,arguments),this[r]}})),c}}Object.defineProperty(t,"__esModule",{value:!0}),t.initializable=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:[];return{type:i.NodeType.Program,body:e,sourceType:"script",obfuscatedNode:!1}}},{key:"getArrayExpressionNode",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{type:i.NodeType.ArrayExpression,elements:e}}},{key:"getAssignmentExpressionNode",value:function(e,t,n){return{type:i.NodeType.AssignmentExpression,operator:e,left:t,right:n,obfuscatedNode:!1}}},{key:"getBinaryExpressionNode",value:function(e,t,n){return{type:i.NodeType.BinaryExpression,operator:e,left:t,right:n,obfuscatedNode:!1}}},{key:"getBlockStatementNode",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{type:i.NodeType.BlockStatement,body:e,obfuscatedNode:!1}}},{key:"getBreakStatement",value:function(e){var t={type:i.NodeType.BreakStatement,obfuscatedNode:!1};return e&&(t.label=e),t}},{key:"getCatchClauseNode",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{type:i.NodeType.CatchClause,param:e.getIdentifierNode("err"),body:e.getBlockStatementNode(t),obfuscatedNode:!1}}},{key:"getCallExpressionNode",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return{type:i.NodeType.CallExpression,callee:e,arguments:t,obfuscatedNode:!1}}},{key:"getContinueStatement",value:function(e){var t={type:i.NodeType.ContinueStatement,obfuscatedNode:!1};return e&&(t.label=e),t}},{key:"getExpressionStatementNode",value:function(e){return{type:i.NodeType.ExpressionStatement,expression:e,obfuscatedNode:!1}}},{key:"getFunctionDeclarationNode",value:function(t,n,r){return{type:i.NodeType.FunctionDeclaration,id:e.getIdentifierNode(t),params:n,body:r,generator:!1,obfuscatedNode:!1}}},{key:"getFunctionExpressionNode",value:function(e,t){return{type:i.NodeType.FunctionExpression,params:e,body:t,generator:!1,obfuscatedNode:!1}}},{key:"getIfStatementNode",value:function(e,t,n){return Object.assign({type:i.NodeType.IfStatement,test:e,consequent:t},n&&{alternate:n},{obfuscatedNode:!1})}},{key:"getIdentifierNode",value:function(e){return{type:i.NodeType.Identifier,name:e,obfuscatedNode:!1}}},{key:"getLabeledStatement",value:function(e,t){return{type:i.NodeType.LabeledStatement,label:e,body:t,obfuscatedNode:!1}}},{key:"getLiteralNode",value:function(e,t){return t=void 0!==t?t:"'"+e+"'",{type:i.NodeType.Literal,value:e,raw:t,"x-verbatim-property":{content:t,precedence:a.Precedence.Primary},obfuscatedNode:!1}}},{key:"getLogicalExpressionNode",value:function(e,t,n){return{type:i.NodeType.LogicalExpression,operator:e,left:t,right:n,obfuscatedNode:!1}}},{key:"getMemberExpressionNode",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return{type:i.NodeType.MemberExpression,computed:n,object:e,property:t,obfuscatedNode:!1}}},{key:"getObjectExpressionNode",value:function(e){return{type:i.NodeType.ObjectExpression,properties:e,obfuscatedNode:!1}}},{key:"getPropertyNode",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return{type:i.NodeType.Property,key:e,value:t,kind:"init",method:!1,shorthand:!1,computed:n,obfuscatedNode:!1}}},{key:"getUnaryExpressionNode",value:function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return{type:i.NodeType.UnaryExpression,operator:e,argument:t,prefix:n,obfuscatedNode:!1}}},{key:"getReturnStatementNode",value:function(e){return{type:i.NodeType.ReturnStatement,argument:e,obfuscatedNode:!1}}},{key:"getSwitchStatementNode",value:function(e,t){return{type:i.NodeType.SwitchStatement,discriminant:e,cases:t,obfuscatedNode:!1}}},{key:"getSwitchCaseNode",value:function(e,t){return{type:i.NodeType.SwitchCase,test:e,consequent:t,obfuscatedNode:!1}}},{key:"getUpdateExpressionNode",value:function(e,t){return{type:i.NodeType.UpdateExpression,operator:e,argument:t,prefix:!1,obfuscatedNode:!1}}},{key:"getVariableDeclarationNode",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"var";return{type:i.NodeType.VariableDeclaration,declarations:e,kind:t,obfuscatedNode:!1}}},{key:"getVariableDeclaratorNode",value:function(e,t){return{type:i.NodeType.VariableDeclarator,id:e,init:t,obfuscatedNode:!1}}},{key:"getWhileStatementNode",value:function(e,t){return{type:i.NodeType.WhileStatement,test:e,body:t,obfuscatedNode:!1}}}]),e}();t.Nodes=c},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});!function(e){e[e.BinaryExpressionFunctionNode=0]="BinaryExpressionFunctionNode",e[e.BlockStatementControlFlowFlatteningNode=1]="BlockStatementControlFlowFlatteningNode",e[e.CallExpressionControlFlowStorageCallNode=2]="CallExpressionControlFlowStorageCallNode",e[e.CallExpressionFunctionNode=3]="CallExpressionFunctionNode",e[e.ControlFlowStorageNode=4]="ControlFlowStorageNode",e[e.ConsoleOutputDisableExpressionNode=5]="ConsoleOutputDisableExpressionNode",e[e.DebugProtectionFunctionCallNode=6]="DebugProtectionFunctionCallNode",e[e.DebugProtectionFunctionIntervalNode=7]="DebugProtectionFunctionIntervalNode",e[e.DebugProtectionFunctionNode=8]="DebugProtectionFunctionNode",e[e.DomainLockNode=9]="DomainLockNode",e[e.ExpressionWithOperatorControlFlowStorageCallNode=10]="ExpressionWithOperatorControlFlowStorageCallNode",e[e.LogicalExpressionFunctionNode=11]="LogicalExpressionFunctionNode",e[e.NodeCallsControllerFunctionNode=12]="NodeCallsControllerFunctionNode",e[e.SelfDefendingUnicodeNode=13]="SelfDefendingUnicodeNode",e[e.StringArrayCallsWrapper=14]="StringArrayCallsWrapper",e[e.StringArrayNode=15]="StringArrayNode",e[e.StringArrayRotateFunctionNode=16]="StringArrayRotateFunctionNode",e[e.StringLiteralControlFlowStorageCallNode=17]="StringLiteralControlFlowStorageCallNode",e[e.StringLiteralNode=18]="StringLiteralNode"}(t.CustomNode||(t.CustomNode={}))},function(e,t){e.exports=require("estraverse")},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=n(1),a=n(0),i=n(2),c=n(4),s=function e(t){r(this,e),this.nodeIdentifier=c.RandomGeneratorUtils.getRandomInteger(0,1e4),this.options=t};s=o.__decorate([a.injectable(),o.__param(0,a.inject(i.ServiceIdentifiers.IOptions)),o.__metadata("design:paramtypes",[Object])],s),t.AbstractNodeTransformer=s},function(e,t,n){"use strict";function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t-1||0===e.indexOf("//")?e.split("/")[2]:e.split("/")[0],t=t.split(":")[0]}},{key:"isCeilNumber",value:function(e){return e%1==0}},{key:"strEnumify",value:function(e){return e}},{key:"stringRotate",value:function(e,t){if(!e)throw new ReferenceError("Cannot rotate empty string.");for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{},n=new i.InversifyContainerFacade(t),r=n.get(a.ServiceIdentifiers.IOptions);s.RandomGeneratorUtils.initializeRandomGenerator(r.seed);var o=n.get(a.ServiceIdentifiers.IJavaScriptObfuscator),c=o.obfuscate(e);return s.RandomGeneratorUtils.clearRandomGenerator(),c}},{key:"runCLI",value:function(e){new c.JavaScriptObfuscatorCLI(e).run()}}]),e}();t.JavaScriptObfuscator=u},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n3&&void 0!==arguments[3]?arguments[3]:0,a=void 0;a=t.length?e.getOptimalBlockScope(t,o):n,e.prependNode(a,r)}},{key:"getOptimalBlockScope",value:function(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1/0,o=t[n];if(r<=0)throw new Error("Invalid `deep` argument value. Value should be bigger then 0.");return r>1&&o.stackTrace.length?e.getOptimalBlockScope(o.stackTrace,0,--r):o.callee}},{key:"getRandomStackTraceIndex",value:function(e){return i.RandomGeneratorUtils.getRandomInteger(0,Math.max(0,Math.round(e-1)))}},{key:"insertNodeAtIndex",value:function(t,n,o){e.validateBodyStatements(n)||(n=[]),n=e.parentizeBodyStatementsBeforeAppend(t,n),t.body=[].concat(r(t.body.slice(0,o)),r(n),r(t.body.slice(o)))}},{key:"prependNode",value:function(t,n){e.validateBodyStatements(n)||(n=[]),n=e.parentizeBodyStatementsBeforeAppend(t,n),t.body=[].concat(r(n),r(t.body))}},{key:"parentizeBodyStatementsBeforeAppend",value:function(e,t){return t.forEach(function(t){t.parentNode=e}),t}},{key:"validateBodyStatements",value:function(e){return e.every(function(e){return!!e&&e.hasOwnProperty("type")})}}]),e}();t.NodeAppender=c},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});!function(e){e[e.BaseIdentifierObfuscatingReplacer=0]="BaseIdentifierObfuscatingReplacer"}(t.IdentifierObfuscatingReplacer||(t.IdentifierObfuscatingReplacer={}))},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n>8-o%1*8)){if((r=e.charCodeAt(o+=.75))>255)throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");n=n<<8|r}return t}},{key:"hideString",value:function(e,t){var n=a.RandomGeneratorUtils.getRandomGenerator().string({length:t,pool:a.RandomGeneratorUtils.randomGeneratorPool}),r=n.replace(new RegExp("["+function(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}(e)+"]","g"),""),o=r.split("");return a.RandomGeneratorUtils.getRandomGenerator().shuffle(o),r=o.join(""),[function(e,t){for(var n=-1,r=-1,o="";n1&&void 0!==arguments[1]&&arguments[1];this.storage=new Map([].concat(r(this.storage),r(e.getStorage()))),t&&(this.storageId=e.getStorageId())}},{key:"set",value:function(e,t){this.storage.set(e,t)}}]),e}();c.__decorate([u.initializable(),c.__metadata("design:type",String)],f.prototype,"storageId",void 0),c.__decorate([u.initializable(),c.__metadata("design:type",Map)],f.prototype,"storage",void 0),f=c.__decorate([s.injectable()],f),t.MapStorage=f},function(e,t){e.exports=require("path")},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(16);e.exports=r.JavaScriptObfuscator},function(e,t){e.exports=require("reflect-metadata")},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(17),o=n(0),a=n(2),i=n(30),c=n(42),s=n(45),u=n(46),l=n(47);t.controlFlowTransformersModule=new o.ContainerModule(function(e){e(a.ServiceIdentifiers.IControlFlowReplacer).to(c.BinaryExpressionControlFlowReplacer).whenTargetNamed(i.ControlFlowReplacer.BinaryExpressionControlFlowReplacer),e(a.ServiceIdentifiers.IControlFlowReplacer).to(s.CallExpressionControlFlowReplacer).whenTargetNamed(i.ControlFlowReplacer.CallExpressionControlFlowReplacer),e(a.ServiceIdentifiers.IControlFlowReplacer).to(u.LogicalExpressionControlFlowReplacer).whenTargetNamed(i.ControlFlowReplacer.LogicalExpressionControlFlowReplacer),e(a.ServiceIdentifiers.IControlFlowReplacer).to(l.StringLiteralControlFlowReplacer).whenTargetNamed(i.ControlFlowReplacer.StringLiteralControlFlowReplacer),e(a.ServiceIdentifiers.Factory__IControlFlowReplacer).toFactory(r.InversifyContainerFacade.getCacheFactory(a.ServiceIdentifiers.IControlFlowReplacer))})},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n> 1 + 255 % 0;\n \n if (string.indexOf('i' === i)) {\n recursiveFunc2(string)\n }\n };\n \n var recursiveFunc2 = function (string) {\n var i = ~-4 >> 1 + 255 % 0;\n \n if (string.indexOf((true+\"\")[3]) !== i) {\n recursiveFunc1(string)\n }\n };\n \n if (!test1()) {\n if (!test2()) {\n recursiveFunc1('indеxOf');\n } else {\n recursiveFunc1('indexOf');\n }\n } else {\n recursiveFunc1('indеxOf');\n }\n })\n \n {selfDefendingFunctionName}();\n "}Object.defineProperty(t,"__esModule",{value:!0});var o=n(12);t.SelfDefendingTemplate=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n> (-2 * bc & 6)) : 0\n ) {\n buffer = chars.indexOf(buffer);\n }\n return output;\n });\n })();\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.AtobTemplate=r},function(e,t,n){"use strict";function r(){return"\n var rc4 = function (str, key) {\n var s = [], j = 0, x, res = '', newStr = '';\n \n str = atob(str);\n \n for (var k = 0, length = str.length; k < length; k++) {\n newStr += '%' + ('00' + str.charCodeAt(k).toString(16)).slice(-2);\n }\n \n str = decodeURIComponent(newStr);\n \t \n\t for (var i = 0; i < 256; i++) {\n s[i] = i;\n }\n \n for (i = 0; i < 256; i++) {\n j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;\n x = s[i];\n s[i] = s[j];\n s[j] = x;\n }\n \n i = 0;\n j = 0;\n \n for (var y = 0; y < str.length; y++) {\n i = (i + 1) % 256;\n j = (j + s[i]) % 256;\n x = s[i];\n s[i] = s[j];\n s[j] = x;\n res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);\n }\n \n return res;\n }\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.Rc4Template=r},function(e,t,n){"use strict";function r(){return"\n var StatesClass = function (rc4Bytes) {\n this.rc4Bytes = rc4Bytes;\n this.states = [1, 0, 0];\n this.newState = function(){return 'newState';};\n this.firstState = '"+o.Utils.stringToUnicodeEscapeSequence("\\w+ *\\(\\) *{\\w+ *",!0)+"';\n this.secondState = '"+o.Utils.stringToUnicodeEscapeSequence("['|\"].+['|\"];? *}",!0)+"';\n };\n \n StatesClass.prototype.checkState = function () {\n var regExp = new RegExp(this.firstState + this.secondState);\n\n return this.runState(regExp.test(this.newState.toString()) ? --this.states[1] : --this.states[0]);\n };\n \n StatesClass.prototype.runState = function (stateResult) {\n if (!Boolean(~stateResult)) {\n return stateResult;\n }\n \n return this.getState(this.rc4Bytes);\n };\n\n StatesClass.prototype.getState = function (rc4Bytes) {\n for (var i = 0, len = this.states.length; i < len; i++) {\n this.states.push(Math.round(Math.random()));\n len = this.states.length;\n }\n \n return rc4Bytes(this.states[0]);\n };\n\n new StatesClass({stringArrayCallsWrapperName}).checkState();\n "}Object.defineProperty(t,"__esModule",{value:!0});var o=n(12);t.SelfDefendingTemplate=r},function(e,t,n){"use strict";function r(){return" \n if ({stringArrayCallsWrapperName}.initialized === undefined) {\n {atobPolyfill}\n \n {stringArrayCallsWrapperName}.base64DecodeUnicode = function (str) {\n var string = atob(str);\n var newStringChars = [];\n \n for (var i = 0, length = string.length; i < length; i++) {\n newStringChars += '%' + ('00' + string.charCodeAt(i).toString(16)).slice(-2);\n }\n \n return decodeURIComponent(newStringChars);\n };\n \n {stringArrayCallsWrapperName}.data = {};\n \n {stringArrayCallsWrapperName}.initialized = true;\n }\n \n var cachedValue = {stringArrayCallsWrapperName}.data[index];\n \n if (cachedValue === undefined) {\n {selfDefendingCode}\n \n value = {stringArrayCallsWrapperName}.base64DecodeUnicode(value);\n {stringArrayCallsWrapperName}.data[index] = value;\n } else {\n value = cachedValue;\n } \n "}Object.defineProperty(t,"__esModule",{value:!0}),t.StringArrayBase64DecodeNodeTemplate=r},function(e,t,n){"use strict";function r(){return"\n var {stringArrayCallsWrapperName} = function (index, key) {\n index = index - 0;\n \n var value = {stringArrayName}[index];\n \n {decodeNodeTemplate}\n \n return value;\n };\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.StringArrayCallsWrapperTemplate=r},function(e,t,n){"use strict";function r(){return"\n if ({stringArrayCallsWrapperName}.initialized === undefined) {\n {atobPolyfill}\n \n {rc4Polyfill}\n {stringArrayCallsWrapperName}.rc4 = rc4;\n \n {stringArrayCallsWrapperName}.data = {};\n \n {stringArrayCallsWrapperName}.initialized = true;\n }\n \n var cachedValue = {stringArrayCallsWrapperName}.data[index];\n\n if (cachedValue === undefined) {\n if ({stringArrayCallsWrapperName}.once === undefined) {\n {selfDefendingCode}\n \n {stringArrayCallsWrapperName}.once = true;\n }\n \n value = {stringArrayCallsWrapperName}.rc4(value, key);\n {stringArrayCallsWrapperName}.data[index] = value;\n } else {\n value = cachedValue;\n }\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.StringArrayRc4DecodeNodeTemplate=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n=g.minimumLengthForStringArray&&y.RandomGeneratorUtils.getMathRandom()<=this.options.stringArrayThreshold}},{key:"getStringArrayHexadecimalIndex",value:function(e,t){if(this.stringLiteralHexadecimalIndexCache.has(e))return{fromCache:!0,index:this.stringLiteralHexadecimalIndexCache.get(e)};var n=b.Utils.decToHex(t),r=""+b.Utils.hexadecimalPrefix+n;return this.stringLiteralHexadecimalIndexCache.set(e,r),{fromCache:!1,index:r}}},{key:"getEncodedValue",value:function(e){var t=void 0,n=null;switch(this.options.stringArrayEncoding){case l.StringArrayEncoding.Rc4:n=y.RandomGeneratorUtils.getRandomGenerator().pickone(this.rc4Keys),t=d.CryptUtils.btoa(d.CryptUtils.rc4(e,n));break;case l.StringArrayEncoding.Base64:t=d.CryptUtils.btoa(e);break;default:t=e}return{encodedValue:t,key:n}}},{key:"replaceWithLiteralNode",value:function(e){return p.Nodes.getLiteralNode(b.Utils.stringToUnicodeEscapeSequence(e,this.options.unicodeEscapeSequence))}},{key:"replaceWithStringArrayCallNode",value:function(e){var t=this.getEncodedValue(e),n=t.encodedValue,r=t.key,o=b.Utils.stringToUnicodeEscapeSequence(n,this.options.unicodeEscapeSequence),a=this.stringArrayStorage.getLength(),i=b.Utils.stringRotate(this.stringArrayStorage.getStorageId(),1),c="_"+b.Utils.hexadecimalPrefix+i,s=this.getStringArrayHexadecimalIndex(o,a),u=s.fromCache,l=s.index;u||this.stringArrayStorage.set(a,o);var f=[g.getHexadecimalLiteralNode(l)];return r&&f.push(g.getRc4KeyLiteralNode(b.Utils.stringToUnicodeEscapeSequence(r,this.options.unicodeEscapeSequence))),p.Nodes.getCallExpressionNode(p.Nodes.getIdentifierNode(c),f)}}],[{key:"getHexadecimalLiteralNode",value:function(e){var t=p.Nodes.getLiteralNode(e);return t.obfuscatedNode=!0,t}},{key:"getRc4KeyLiteralNode",value:function(e){var t=p.Nodes.getLiteralNode(e);return t.obfuscatedNode=!0,t}}]),t}(f.AbstractObfuscatingReplacer);m.minimumLengthForStringArray=3,m.rc4KeyLength=4,m.rc4KeysCount=50,m=g=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.TCustomNodeGroupStorage)),c.__param(1,s.inject(u.ServiceIdentifiers.TStringArrayStorage)),c.__param(2,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Object,Object,Object])],m),t.StringLiteralObfuscatingReplacer=m;var g},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(17),o=n(0),a=n(2),i=n(35),c=n(95),s=n(96),u=n(97),l=n(98),f=n(99),d=n(100),p=n(101),y=n(102),b=n(103),m=n(104),g=n(105),h=n(106),v=n(107);t.nodeTransformersModule=new o.ContainerModule(function(e){e(a.ServiceIdentifiers.INodeTransformer).to(s.BlockStatementControlFlowTransformer).whenTargetNamed(i.NodeTransformer.BlockStatementControlFlowTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(u.DeadCodeInjectionTransformer).whenTargetNamed(i.NodeTransformer.DeadCodeInjectionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(c.FunctionControlFlowTransformer).whenTargetNamed(i.NodeTransformer.FunctionControlFlowTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(b.MemberExpressionTransformer).whenTargetNamed(i.NodeTransformer.MemberExpressionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(m.MethodDefinitionTransformer).whenTargetNamed(i.NodeTransformer.MethodDefinitionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(h.TemplateLiteralTransformer).whenTargetNamed(i.NodeTransformer.TemplateLiteralTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(l.CatchClauseTransformer).whenTargetNamed(i.NodeTransformer.CatchClauseTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(f.FunctionDeclarationTransformer).whenTargetNamed(i.NodeTransformer.FunctionDeclarationTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(d.FunctionTransformer).whenTargetNamed(i.NodeTransformer.FunctionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(p.LabeledStatementTransformer).whenTargetNamed(i.NodeTransformer.LabeledStatementTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(y.LiteralTransformer).whenTargetNamed(i.NodeTransformer.LiteralTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(g.ObjectExpressionTransformer).whenTargetNamed(i.NodeTransformer.ObjectExpressionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(v.VariableDeclarationTransformer).whenTargetNamed(i.NodeTransformer.VariableDeclarationTransformer),e(a.ServiceIdentifiers.Factory__INodeTransformer).toFactory(r.InversifyContainerFacade.getCacheFactory(a.ServiceIdentifiers.INodeTransformer))})},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;nn.options.controlFlowFlatteningThreshold)return e;var o=_.controlFlowReplacersMap.get(e.type);return void 0===o?e:Object.assign({},n.controlFlowReplacerFactory(o).replace(e,r,t),{parentNode:r})}})}}],[{key:"getHostNode",value:function(e){var t=g.NodeUtils.getBlockScopesOfNode(e);return 1===t.length?e:(t.pop(),t.length>_.hostNodeSearchMinDepth&&t.splice(0,_.hostNodeSearchMinDepth),t.length>_.hostNodeSearchMaxDepth&&(t.length=_.hostNodeSearchMaxDepth),h.RandomGeneratorUtils.getRandomGenerator().pickone(t))}}]),t}(p.AbstractNodeTransformer);v.controlFlowReplacersMap=new Map([[d.NodeType.BinaryExpression,m.ControlFlowReplacer.BinaryExpressionControlFlowReplacer],[d.NodeType.CallExpression,m.ControlFlowReplacer.CallExpressionControlFlowReplacer],[d.NodeType.LogicalExpression,m.ControlFlowReplacer.LogicalExpressionControlFlowReplacer],[d.NodeType.Literal,m.ControlFlowReplacer.StringLiteralControlFlowReplacer]]),v.hostNodeSearchMinDepth=0,v.hostNodeSearchMaxDepth=2,v=_=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.Factory__TControlFlowStorage)),c.__param(1,s.inject(u.ServiceIdentifiers.Factory__IControlFlowReplacer)),c.__param(2,s.inject(u.ServiceIdentifiers.Factory__ICustomNode)),c.__param(3,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Function,Function,Function,Object])],v),t.FunctionControlFlowTransformer=v;var _},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;nthis.options.controlFlowFlatteningThreshold||m.blockStatementHasProhibitedStatements(e))return e;var n=e.body;if(n.length<=4)return e;var r=y.Utils.arrayRange(n.length),o=y.Utils.arrayShuffle(r),a=r.map(function(e){return o.indexOf(e)}),i=this.customNodeFactory(l.CustomNode.BlockStatementControlFlowFlatteningNode);return i.initialize(n,o,a),i.getNode()[0]}}],[{key:"blockStatementHasProhibitedStatements",value:function(e){return e.body.some(function(e){var t=d.Node.isBreakStatementNode(e)||d.Node.isContinueStatementNode(e),n=d.Node.isVariableDeclarationNode(e)&&("const"===e.kind||"let"===e.kind);return d.Node.isFunctionDeclarationNode(e)||t||n})}}]),t}(f.AbstractNodeTransformer);b=m=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.Factory__ICustomNode)),c.__param(1,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Function,Object])],b),t.BlockStatementControlFlowTransformer=b;var m},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;nt.options.deadCodeInjectionThreshold)return e;var r=b.RandomGeneratorUtils.getRandomInteger(0,t.collectedBlockStatements.length-1),o=t.collectedBlockStatements.splice(r,1)[0];return o===e?e:g.replaceBlockStatementNode(e,o)}})}}],[{key:"collectBlockStatementNodes",value:function(e,t){var n=y.NodeUtils.clone(e),r=0,o=!0;l.replace(n,{enter:function(e,t){return d.Node.isBlockStatementNode(e)&&r++,r>g.maxNestedBlockStatementsCount||d.Node.isBreakStatementNode(e)||d.Node.isContinueStatementNode(e)?(o=!1,l.VisitorOption.Break):(d.Node.isIdentifierNode(e)&&!d.Node.isMemberExpressionNode(t)&&(e.name=b.RandomGeneratorUtils.getRandomVariableName(6)),e)}}),o&&t.push(n)}},{key:"replaceBlockStatementNode",value:function(e,t){var n=b.RandomGeneratorUtils.getMathRandom()>.5,r=b.RandomGeneratorUtils.getMathRandom()>.5,o=n?"===":"!==",a=b.RandomGeneratorUtils.getRandomString(3),i=r?a:b.RandomGeneratorUtils.getRandomString(3),c=void 0,s=void 0;n&&r||!n&&!r?(c=e,s=t):(c=t,s=e);var u=p.Nodes.getBlockStatementNode([p.Nodes.getIfStatementNode(p.Nodes.getBinaryExpressionNode(o,p.Nodes.getLiteralNode(a),p.Nodes.getLiteralNode(i)),c,s)]);return u=y.NodeUtils.parentize(u)}}]),t}(f.AbstractNodeTransformer);m.maxNestedBlockStatementsCount=4,m.minCollectedBlockStatementsCount=5,m=g=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Object])],m),t.DeadCodeInjectionTransformer=m;var g},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n1){var o=d.Nodes.getBinaryExpressionNode("+",r.shift(),r.shift());return r.forEach(function(e){o=d.Nodes.getBinaryExpressionNode("+",o,e)}),o}return r[0]}}],[{key:"isLiteralNodeWithStringValue",value:function(e){return e&&f.Node.isLiteralNode(e)&&"string"==typeof e.value}}]),t}(l.AbstractNodeTransformer);p=y=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Object])],p),t.TemplateLiteralTransformer=p;var y},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;nn)return"break";var a=e[o];s.traverse(a,{enter:function(n){if(l.Node.isCallExpressionNode(n))return a.parentNode!==f.NodeUtils.getBlockScopesOfNode(n)[0]?s.VisitorOption.Skip:void t.analyzeCallExpressionNode(r,e,n)}})}(a))break}return r}},{key:"analyzeCallExpressionNode",value:function(e,t,n){var r=this;p.calleeDataExtractorsList.forEach(function(o){var a=r.calleeDataExtractorFactory(o).extract(t,n.callee);a&&e.push(Object.assign({},a,{stackTrace:r.analyzeRecursive(a.callee.body)}))})}}],[{key:"getLimitIndex",value:function(e){var t=e-1,n=p.limitThresholdActivationLength-1,r=t;return t>n&&(r=Math.round(n+t*p.limitThreshold))>t&&(r=t),r}}]),e}();d.calleeDataExtractorsList=[u.CalleeDataExtractor.FunctionDeclarationCalleeDataExtractor,u.CalleeDataExtractor.FunctionExpressionCalleeDataExtractor,u.CalleeDataExtractor.ObjectExpressionCalleeDataExtractor],d.limitThresholdActivationLength=25,d.limitThreshold=.002,d=p=a.__decorate([i.injectable(),a.__param(0,i.inject(c.ServiceIdentifiers.Factory__ICalleeDataExtractor)),a.__metadata("design:paramtypes",[Function])],d),t.StackTraceAnalyzer=d;var p},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),o=n(2),a=n(114),i=n(115),c=n(116);t.storagesModule=new r.ContainerModule(function(e){e(o.ServiceIdentifiers.TCustomNodeGroupStorage).to(i.CustomNodeGroupStorage).inSingletonScope(),e(o.ServiceIdentifiers.TStringArrayStorage).to(c.StringArrayStorage).inSingletonScope(),e(o.ServiceIdentifiers.Newable__TControlFlowStorage).toConstructor(a.ControlFlowStorage),e(o.ServiceIdentifiers.Factory__TControlFlowStorage).toFactory(function(e){return function(){var t=e.container.get(o.ServiceIdentifiers.Newable__TControlFlowStorage);return new t}})})},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var i=n(37),c=function(e){function t(){r(this,t);var e=o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.initialize(),e}return a(t,e),t}(i.MapStorage);t.ControlFlowStorage=c},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n=0?t:null}},{key:"getLength",value:function(){return this.storageLength}},{key:"getStorage",value:function(){return this.storage}},{key:"getStorageId",value:function(){return this.storageId}},{key:"initialize",value:function(){this.storage=[],this.storageId=u.RandomGeneratorUtils.getRandomString(6)}},{key:"mergeWith",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];this.storage=[].concat(r(this.storage),r(e.getStorage())),t&&(this.storageId=e.getStorageId())}},{key:"set",value:function(e,t){e===this.storageLength?this.storage.push(t):this.storage.splice(e,0,t),this.storageLength++}}]),e}();i.__decorate([s.initializable(),i.__metadata("design:type",Array)],l.prototype,"storage",void 0),i.__decorate([s.initializable(),i.__metadata("design:type",String)],l.prototype,"storageId",void 0),l=i.__decorate([c.injectable()],l),t.ArrayStorage=l},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n [options]").option("-o, --output ","Output path for obfuscated code").option("--compact ","Disable one line output code compacting",s.BooleanSanitizer).option("--controlFlowFlattening ","Enables control flow flattening",s.BooleanSanitizer).option("--controlFlowFlatteningThreshold ","The probability that the control flow flattening transformation will be applied to the node",parseFloat).option("--deadCodeInjection ","Enables dead code injection",s.BooleanSanitizer).option("--deadCodeInjectionThreshold ","The probability that the dead code injection transformation will be applied to the node",parseFloat).option("--debugProtection ","Disable browser Debug panel (can cause DevTools enabled browser freeze)",s.BooleanSanitizer).option("--debugProtectionInterval ","Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)",s.BooleanSanitizer).option("--disableConsoleOutput ","Allow console.log, console.info, console.error and console.warn messages output into browser console",s.BooleanSanitizer).option("--domainLock ","Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)",function(e){return e.split(",")}).option("--mangle ","Enables mangling of variable names",s.BooleanSanitizer).option("--reservedNames ","Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)",function(e){return e.split(",")}).option("--rotateStringArray ","Disable rotation of unicode array values during obfuscation",s.BooleanSanitizer).option("--seed ","Sets seed for random generator. This is useful for creating repeatable results.",parseFloat).option("--selfDefending ","Disables self-defending for obfuscated code",s.BooleanSanitizer).option("--sourceMap ","Enables source map generation",s.BooleanSanitizer).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",u.SourceMapModeSanitizer).option("--stringArray ","Disables gathering of all literal strings into an array and replacing every literal string with an array call",s.BooleanSanitizer).option("--stringArrayEncoding [true, false, base64, rc4]","Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed",l.StringArrayEncodingSanitizer).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",s.BooleanSanitizer).parse(this.rawArguments)}},{key:"configureHelp",value:function(){this.commands.on("--help",function(){console.log(" Examples:\n"),console.log(" %> javascript-obfuscator in.js --compact true --selfDefending false"),console.log(" %> javascript-obfuscator in.js --output out.js --compact true --selfDefending false"),console.log("")})}},{key:"getData",value:function(){this.sourceCode=f.CLIUtils.readFile(this.inputPath)}},{key:"processData",value:function(){var e=this.buildOptions(),t=f.CLIUtils.getOutputCodePath(this.commands.output,this.inputPath);e.sourceMap?this.processDataWithSourceMap(t,e):this.processDataWithoutSourceMap(t,e)}},{key:"processDataWithoutSourceMap",value:function(e,t){var n=d.JavaScriptObfuscator.obfuscate(this.sourceCode,t).getObfuscatedCode();f.CLIUtils.writeFile(e,n)}},{key:"processDataWithSourceMap",value:function(e,t){var n=f.CLIUtils.getOutputSourceMapPath(e,t.sourceMapFileName||"");t=Object.assign({},t,{sourceMapFileName:i.basename(n)});var r=d.JavaScriptObfuscator.obfuscate(this.sourceCode,t);f.CLIUtils.writeFile(e,r.getObfuscatedCode()),"separate"===t.sourceMapMode&&r.getSourceMap()&&f.CLIUtils.writeFile(n,r.getSourceMap())}}]),e}();t.JavaScriptObfuscatorCLI=p},function(e,t){e.exports=require("commander")},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BooleanSanitizer=function(e){return"true"===e||"1"===e}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(22);t.SourceMapModeSanitizer=function(e){if(!Object.keys(r.SourceMapMode).some(function(t){return r.SourceMapMode[t]===e}))throw new ReferenceError("Invalid value of `--sourceMapMode` option");return e}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(27);t.StringArrayEncodingSanitizer=function(e){switch(e){case"true":case"1":case r.StringArrayEncoding.Base64:return!0;case r.StringArrayEncoding.Rc4:return r.StringArrayEncoding.Rc4;default:return!1}}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"";return t&&(e=e.substring(0,e.lastIndexOf("/"))+"/"+t),/\.js\.map$/.test(e)?/\.js$/.test(e)&&(e+=".map"):e=e.split(".")[0]+".js.map",e}},{key:"getPackageConfig",value:function(){return JSON.parse(a.readFileSync(c.join(c.dirname(a.realpathSync(process.argv[1])),"../package.json"),e.encoding))}},{key:"isFilePath",value:function(e){try{return a.statSync(e).isFile()}catch(e){return!1}}},{key:"readFile",value:function(t){return a.readFileSync(t,e.encoding)}},{key:"validateInputPath",value:function(t){if(!e.isFilePath(t))throw new ReferenceError("Given input path must be a valid file path");if(-1===e.availableInputExtensions.indexOf(c.extname(t)))throw new ReferenceError("Input file must have .js extension")}},{key:"writeFile",value:function(t,n){i.sync(c.dirname(t)),a.writeFileSync(t,n,{encoding:e.encoding})}}]),e}();s.availableInputExtensions=[".js"],s.encoding="utf8",t.CLIUtils=s},function(e,t){e.exports=require("fs")},function(e,t){e.exports=require("mkdirp")}]); +require("source-map-support").install(),module.exports=function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=39)}([function(e,t){e.exports=require("inversify")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});!function(e){e.Factory__ICalleeDataExtractor="Factory",e.Factory__IControlFlowCustomNode="Factory",e.Factory__IControlFlowReplacer="Factory",e.Factory__ICustomNode="Factory",e.Factory__ICustomNodeGroup="Factory",e.Factory__IIdentifierObfuscatingReplacer="Factory",e.Factory__INodeTransformer="Factory",e.Factory__IObfuscationResult="Factory",e.Factory__IObfuscatingReplacer="Factory",e.Factory__TControlFlowStorage="Factory",e.IArrayUtils="IArrayUtils",e.ICalleeDataExtractor="ICalleeDataExtractor",e.ICryptUtils="ICryptUtils",e.ICustomNode="ICustomNode",e.ICustomNodeGroup="ICustomNodeGroup",e.IControlFlowReplacer="IControlFlowReplacer",e.IDeadCodeInjectionReplacer="IDeadCodeInjectionReplacer",e.IEscapeSequenceEncoder="IEscapeSequenceEncoder",e.IIdentifierObfuscatingReplacer="IIdentifierObfuscatingReplacer",e.IJavaScriptObfuscator="IJavaScriptObfuscator",e.INodeTransformer="INodeTransformer",e.IObfuscationEventEmitter="IObfuscationEventEmitter",e.IObfuscationResult="IObfuscationResult",e.IObfuscator="IObfuscator",e.IOptions="IOptions",e.IObfuscatingReplacer="IObfuscatingReplacer",e.IRandomGenerator="IRandomGenerator",e.ISourceMapCorrector="ISourceMapCorrector",e.IStackTraceAnalyzer="IStackTraceAnalyzer",e.Newable__ICustomNode="Newable",e.Newable__TControlFlowStorage="Newable",e.TCustomNodeGroupStorage="TCustomNodeGroupStorage",e.TStringArrayStorage="TStringArrayStorage"}(t.ServiceIdentifiers||(t.ServiceIdentifiers={}))},function(e,t){e.exports=require("tslib")},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a=function(){function e(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:0;if(l.Node.isNodeHasBlockStatement(e)){if(void 0===e.body[t])throw new ReferenceError("Wrong index `"+t+"`. Block-statement body length is `"+e.body.length+"`");return e.body[t]}throw new TypeError("The specified node have no a block-statement")}},{key:"getBlockScopesOfNode",value:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=t.parentNode;if(!n)throw new ReferenceError("`parentNode` property of given node is `undefined`");if(l.Node.isBlockStatementNode(n)){if(!n.parentNode)throw new ReferenceError("`parentNode` property of `parentNode` of given node is `undefined`");-1!==e.nodesWithBlockScope.indexOf(n.parentNode.type)&&r.push(n)}return l.Node.isProgramNode(n)?(r.push(n),r):e.getBlockScopesOfNode(n,r)}},{key:"getNodeBlockScopeDepth",value:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=t.parentNode;if(!n)throw new ReferenceError("`parentNode` property of given node is `undefined`");return l.Node.isProgramNode(n)?r:l.Node.isBlockStatementNode(t)&&-1!==e.nodesWithBlockScope.indexOf(n.type)?e.getNodeBlockScopeDepth(n,++r):e.getNodeBlockScopeDepth(n,r)}},{key:"getUnaryExpressionArgumentNode",value:function(t){return l.Node.isUnaryExpressionNode(t.argument)?e.getUnaryExpressionArgumentNode(t.argument):t.argument}},{key:"parentize",value:function(e){var t=!0;return s.traverse(e,{enter:function(e,r){var n=void 0;t?(e.type===u.NodeType.Program?n=e:(n=f.Nodes.getProgramNode([e]),n.parentNode=n),t=!1):n=r||e,e.parentNode=n,e.obfuscatedNode=!1}}),e}},{key:"typedReplace",value:function(t,r,n){e.typedTraverse(t,r,n,"replace")}},{key:"typedTraverse",value:function(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"traverse";s[n](e,{enter:function(e,n){if(e.type===t&&r.enter)return r.enter(e,n)},leave:function(e,n){if(e.type===t&&r.leave)return r.leave(e,n)}})}}]),e}();d.nodesWithBlockScope=[u.NodeType.ArrowFunctionExpression,u.NodeType.FunctionDeclaration,u.NodeType.FunctionExpression,u.NodeType.MethodDefinition,u.NodeType.Program],t.NodeUtils=d},function(e,t,r){"use strict";function n(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"initialize",t=Object.keys(this)[0];return function(r,n){var o={configurable:!0,enumerable:!0},a=r[e];if(!a||"function"!=typeof a)throw new Error("`"+e+"` method with initialization logic not found. `@"+t+"` decorator requires `"+e+"` method");var i="_"+n,c=Object.getOwnPropertyDescriptor(r,i)||o,s=Object.getOwnPropertyDescriptor(r,e)||o,u=s.value;return Object.defineProperty(r,n,Object.assign({},c,{get:function(){if(void 0===this[i])throw new Error("Property `"+n+"` is not initialized! Initialize it first!");return this[i]},set:function(e){this[i]=e}})),Object.defineProperty(r,e,Object.assign({},s,{value:function(){u.apply(this,arguments),this[n]}})),c}}Object.defineProperty(t,"__esModule",{value:!0}),t.initializable=n},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:[];return{type:i.NodeType.Program,body:e,sourceType:"script",obfuscatedNode:!1}}},{key:"getArrayExpressionNode",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{type:i.NodeType.ArrayExpression,elements:e}}},{key:"getAssignmentExpressionNode",value:function(e,t,r){return{type:i.NodeType.AssignmentExpression,operator:e,left:t,right:r,obfuscatedNode:!1}}},{key:"getBinaryExpressionNode",value:function(e,t,r){return{type:i.NodeType.BinaryExpression,operator:e,left:t,right:r,obfuscatedNode:!1}}},{key:"getBlockStatementNode",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{type:i.NodeType.BlockStatement,body:e,obfuscatedNode:!1}}},{key:"getBreakStatement",value:function(e){var t={type:i.NodeType.BreakStatement,obfuscatedNode:!1};return e&&(t.label=e),t}},{key:"getCatchClauseNode",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{type:i.NodeType.CatchClause,param:e.getIdentifierNode("err"),body:e.getBlockStatementNode(t),obfuscatedNode:!1}}},{key:"getCallExpressionNode",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return{type:i.NodeType.CallExpression,callee:e,arguments:t,obfuscatedNode:!1}}},{key:"getContinueStatement",value:function(e){var t={type:i.NodeType.ContinueStatement,obfuscatedNode:!1};return e&&(t.label=e),t}},{key:"getExpressionStatementNode",value:function(e){return{type:i.NodeType.ExpressionStatement,expression:e,obfuscatedNode:!1}}},{key:"getFunctionDeclarationNode",value:function(t,r,n){return{type:i.NodeType.FunctionDeclaration,id:e.getIdentifierNode(t),params:r,body:n,generator:!1,obfuscatedNode:!1}}},{key:"getFunctionExpressionNode",value:function(e,t){return{type:i.NodeType.FunctionExpression,params:e,body:t,generator:!1,obfuscatedNode:!1}}},{key:"getIfStatementNode",value:function(e,t,r){return Object.assign({type:i.NodeType.IfStatement,test:e,consequent:t},r&&{alternate:r},{obfuscatedNode:!1})}},{key:"getIdentifierNode",value:function(e){return{type:i.NodeType.Identifier,name:e,obfuscatedNode:!1}}},{key:"getLabeledStatement",value:function(e,t){return{type:i.NodeType.LabeledStatement,label:e,body:t,obfuscatedNode:!1}}},{key:"getLiteralNode",value:function(e,t){return t=void 0!==t?t:"'"+e+"'",{type:i.NodeType.Literal,value:e,raw:t,"x-verbatim-property":{content:t,precedence:a.Precedence.Primary},obfuscatedNode:!1}}},{key:"getLogicalExpressionNode",value:function(e,t,r){return{type:i.NodeType.LogicalExpression,operator:e,left:t,right:r,obfuscatedNode:!1}}},{key:"getMemberExpressionNode",value:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return{type:i.NodeType.MemberExpression,computed:r,object:e,property:t,obfuscatedNode:!1}}},{key:"getObjectExpressionNode",value:function(e){return{type:i.NodeType.ObjectExpression,properties:e,obfuscatedNode:!1}}},{key:"getPropertyNode",value:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return{type:i.NodeType.Property,key:e,value:t,kind:"init",method:!1,shorthand:!1,computed:r,obfuscatedNode:!1}}},{key:"getUnaryExpressionNode",value:function(e,t){var r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return{type:i.NodeType.UnaryExpression,operator:e,argument:t,prefix:r,obfuscatedNode:!1}}},{key:"getReturnStatementNode",value:function(e){return{type:i.NodeType.ReturnStatement,argument:e,obfuscatedNode:!1}}},{key:"getSwitchStatementNode",value:function(e,t){return{type:i.NodeType.SwitchStatement,discriminant:e,cases:t,obfuscatedNode:!1}}},{key:"getSwitchCaseNode",value:function(e,t){return{type:i.NodeType.SwitchCase,test:e,consequent:t,obfuscatedNode:!1}}},{key:"getUpdateExpressionNode",value:function(e,t){return{type:i.NodeType.UpdateExpression,operator:e,argument:t,prefix:!1,obfuscatedNode:!1}}},{key:"getVariableDeclarationNode",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"var";return{type:i.NodeType.VariableDeclaration,declarations:e,kind:t,obfuscatedNode:!1}}},{key:"getVariableDeclaratorNode",value:function(e,t){return{type:i.NodeType.VariableDeclarator,id:e,init:t,obfuscatedNode:!1}}},{key:"getWhileStatementNode",value:function(e,t){return{type:i.NodeType.WhileStatement,test:e,body:t,obfuscatedNode:!1}}}]),e}();t.Nodes=c},function(e,t){e.exports=require("estraverse")},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=r(2),a=r(0),i=r(1),c=function e(t,r){n(this,e),this.randomGenerator=t,this.options=r,this.nodeIdentifier=this.randomGenerator.getRandomInteger(0,1e4)};c=o.__decorate([a.injectable(),o.__param(0,a.inject(i.ServiceIdentifiers.IRandomGenerator)),o.__param(1,a.inject(i.ServiceIdentifiers.IOptions)),o.__metadata("design:paramtypes",[Object,Object])],c),t.AbstractNodeTransformer=c},function(e,t){e.exports=require("string-template")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});!function(e){e.ArrayExpression="ArrayExpression",e.ArrowFunctionExpression="ArrowFunctionExpression",e.AssignmentExpression="AssignmentExpression",e.AssignmentPattern="AssignmentPattern",e.BinaryExpression="BinaryExpression",e.BlockStatement="BlockStatement",e.BreakStatement="BreakStatement",e.CallExpression="CallExpression",e.CatchClause="CatchClause",e.ClassDeclaration="ClassDeclaration",e.ContinueStatement="ContinueStatement",e.ExpressionStatement="ExpressionStatement",e.FunctionDeclaration="FunctionDeclaration",e.FunctionExpression="FunctionExpression",e.Identifier="Identifier",e.IfStatement="IfStatement",e.LabeledStatement="LabeledStatement",e.Literal="Literal",e.LogicalExpression="LogicalExpression",e.MemberExpression="MemberExpression",e.MethodDefinition="MethodDefinition",e.ObjectExpression="ObjectExpression",e.ObjectPattern="ObjectPattern",e.Program="Program",e.Property="Property",e.ReturnStatement="ReturnStatement",e.SwitchCase="SwitchCase",e.SwitchStatement="SwitchStatement",e.TemplateLiteral="TemplateLiteral",e.TryStatement="TryStatement",e.UnaryExpression="UnaryExpression",e.UpdateExpression="UpdateExpression",e.VariableDeclaration="VariableDeclaration",e.VariableDeclarator="VariableDeclarator",e.WhileStatement="WhileStatement"}(t.NodeType||(t.NodeType={}))},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});!function(e){e[e.BinaryExpressionFunctionNode=0]="BinaryExpressionFunctionNode",e[e.BlockStatementControlFlowFlatteningNode=1]="BlockStatementControlFlowFlatteningNode",e[e.CallExpressionControlFlowStorageCallNode=2]="CallExpressionControlFlowStorageCallNode",e[e.CallExpressionFunctionNode=3]="CallExpressionFunctionNode",e[e.ControlFlowStorageNode=4]="ControlFlowStorageNode",e[e.ExpressionWithOperatorControlFlowStorageCallNode=5]="ExpressionWithOperatorControlFlowStorageCallNode",e[e.LogicalExpressionFunctionNode=6]="LogicalExpressionFunctionNode",e[e.StringLiteralControlFlowStorageCallNode=7]="StringLiteralControlFlowStorageCallNode",e[e.StringLiteralNode=8]="StringLiteralNode"}(t.ControlFlowCustomNode||(t.ControlFlowCustomNode={}))},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});!function(e){e.AfterObfuscation="afterObfuscation",e.BeforeObfuscation="beforeObfuscation"}(t.ObfuscationEvent||(t.ObfuscationEvent={}))},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var r=0;r-1||0===e.indexOf("//")?e.split("/")[2]:e.split("/")[0],t=t.split(":")[0]}},{key:"isCeilNumber",value:function(e){return e%1==0}},{key:"stringRotate",value:function(e,t){if(!e)throw new ReferenceError("Cannot rotate empty string.");for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:{},r=new i.InversifyContainerFacade;r.load(t);var n=r.get(a.ServiceIdentifiers.IJavaScriptObfuscator),o=n.obfuscate(e);return r.unload(),o}},{key:"runCLI",value:function(e){new c.JavaScriptObfuscatorCLI(e).run()}}]),e}();t.JavaScriptObfuscator=s},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var r=0;r1?t-1:0),n=1;n3&&void 0!==arguments[3]?arguments[3]:0,a=void 0;a=t.length?e.getOptimalBlockScope(t,o):r,e.prependNode(a,n)}},{key:"getOptimalBlockScope",value:function(t,r){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1/0,o=t[r];if(n<=0)throw new Error("Invalid `deep` argument value. Value should be bigger then 0.");return n>1&&o.stackTrace.length?e.getOptimalBlockScope(o.stackTrace,0,--n):o.callee}},{key:"insertNodeAtIndex",value:function(t,r,o){e.validateBodyStatements(r)||(r=[]),r=e.parentizeBodyStatementsBeforeAppend(t,r),t.body=[].concat(n(t.body.slice(0,o)),n(r),n(t.body.slice(o)))}},{key:"prependNode",value:function(t,r){e.validateBodyStatements(r)||(r=[]),r=e.parentizeBodyStatementsBeforeAppend(t,r),t.body=[].concat(n(r),n(t.body))}},{key:"parentizeBodyStatementsBeforeAppend",value:function(e,t){return t.forEach(function(t){t.parentNode=e}),t}},{key:"validateBodyStatements",value:function(e){return e.every(function(e){return!!e&&e.hasOwnProperty("type")})}}]),e}();t.NodeAppender=i},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});!function(e){e[e.BaseIdentifierObfuscatingReplacer=0]="BaseIdentifierObfuscatingReplacer"}(t.IdentifierObfuscatingReplacer||(t.IdentifierObfuscatingReplacer={}))},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:f.randomGeneratorPool;return this.getRandomGenerator().string({length:e,pool:t})}},{key:"getRandomVariableName",value:function(e){var t="_"+u.Utils.hexadecimalPrefix,r=""+t+u.Utils.decToHex(this.getRandomInteger(1e4,99999999)).substr(0,e);return this.randomVariableNameSet.has(r)?this.getRandomVariableName(e):(this.randomVariableNameSet.add(r),r)}}]),e}();l.randomGeneratorPool="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",l.randomGeneratorPoolNumbers="0123456789",l.randomGeneratorPoolHexadecimal="abcdef"+f.randomGeneratorPoolNumbers,l=f=a.__decorate([i.injectable(),a.__param(0,i.inject(c.ServiceIdentifiers.IOptions)),a.__metadata("design:paramtypes",[Object])],l),t.RandomGenerator=l;var f},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(22);t.DEFAULT_PRESET=Object.freeze({compact:!0,controlFlowFlattening:!1,controlFlowFlatteningThreshold:.75,deadCodeInjection:!1,deadCodeInjectionThreshold:.4,debugProtection:!1,debugProtectionInterval:!1,disableConsoleOutput:!0,domainLock:[],mangle:!1,reservedNames:[],rotateStringArray:!0,seed:0,selfDefending:!1,sourceMap:!1,sourceMapBaseUrl:"",sourceMapFileName:"",sourceMapMode:n.SourceMapMode.Separate,stringArray:!0,stringArrayEncoding:!1,stringArrayThreshold:.75,unicodeEscapeSequence:!1})},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});!function(e){e[e.BinaryExpressionControlFlowReplacer=0]="BinaryExpressionControlFlowReplacer",e[e.CallExpressionControlFlowReplacer=1]="CallExpressionControlFlowReplacer",e[e.LogicalExpressionControlFlowReplacer=2]="LogicalExpressionControlFlowReplacer",e[e.StringLiteralControlFlowReplacer=3]="StringLiteralControlFlowReplacer"}(t.ControlFlowReplacer||(t.ControlFlowReplacer={}))},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;r1&&void 0!==arguments[1]&&arguments[1];this.storage=new Map([].concat(n(this.storage),n(e.getStorage()))),t&&(this.storageId=e.getStorageId())}},{key:"set",value:function(e,t){this.storage.set(e,t)}}]),e}();c.__decorate([l.initializable(),c.__metadata("design:type",String)],f.prototype,"storageId",void 0),c.__decorate([l.initializable(),c.__metadata("design:type",Map)],f.prototype,"storage",void 0),f=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.IRandomGenerator)),c.__metadata("design:paramtypes",[Object])],f),t.MapStorage=f},function(e,t){e.exports=require("path")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(15);e.exports=n.JavaScriptObfuscator},function(e,t){e.exports=require("reflect-metadata")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(16),o=r(0),a=r(1),i=r(30),c=r(42),s=r(43),u=r(44),l=r(45);t.controlFlowTransformersModule=new o.ContainerModule(function(e){e(a.ServiceIdentifiers.IControlFlowReplacer).to(c.BinaryExpressionControlFlowReplacer).whenTargetNamed(i.ControlFlowReplacer.BinaryExpressionControlFlowReplacer),e(a.ServiceIdentifiers.IControlFlowReplacer).to(s.CallExpressionControlFlowReplacer).whenTargetNamed(i.ControlFlowReplacer.CallExpressionControlFlowReplacer),e(a.ServiceIdentifiers.IControlFlowReplacer).to(u.LogicalExpressionControlFlowReplacer).whenTargetNamed(i.ControlFlowReplacer.LogicalExpressionControlFlowReplacer),e(a.ServiceIdentifiers.IControlFlowReplacer).to(l.StringLiteralControlFlowReplacer).whenTargetNamed(i.ControlFlowReplacer.StringLiteralControlFlowReplacer),e(a.ServiceIdentifiers.Factory__IControlFlowReplacer).toFactory(n.InversifyContainerFacade.getCacheFactory(a.ServiceIdentifiers.IControlFlowReplacer))})},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;r> 1 + 255 % 0;\n \n if (string.indexOf('i' === i)) {\n recursiveFunc2(string)\n }\n };\n \n var recursiveFunc2 = function (string) {\n var i = ~-4 >> 1 + 255 % 0;\n \n if (string.indexOf((true+\"\")[3]) !== i) {\n recursiveFunc1(string)\n }\n };\n \n if (!test1()) {\n if (!test2()) {\n recursiveFunc1('indеxOf');\n } else {\n recursiveFunc1('indexOf');\n }\n } else {\n recursiveFunc1('indеxOf');\n }\n })\n \n {selfDefendingFunctionName}();\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.SelfDefendingTemplate=n},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;r> (-2 * bc & 6)) : 0\n ) {\n buffer = chars.indexOf(buffer);\n }\n return output;\n });\n })();\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.AtobTemplate=n},function(e,t,r){"use strict";function n(){return"\n var rc4 = function (str, key) {\n var s = [], j = 0, x, res = '', newStr = '';\n \n str = atob(str);\n \n for (var k = 0, length = str.length; k < length; k++) {\n newStr += '%' + ('00' + str.charCodeAt(k).toString(16)).slice(-2);\n }\n \n str = decodeURIComponent(newStr);\n \t \n\t for (var i = 0; i < 256; i++) {\n s[i] = i;\n }\n \n for (i = 0; i < 256; i++) {\n j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;\n x = s[i];\n s[i] = s[j];\n s[j] = x;\n }\n \n i = 0;\n j = 0;\n \n for (var y = 0; y < str.length; y++) {\n i = (i + 1) % 256;\n j = (j + s[i]) % 256;\n x = s[i];\n s[i] = s[j];\n s[j] = x;\n res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);\n }\n \n return res;\n }\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.Rc4Template=n},function(e,t,r){"use strict";function n(e){return"\n var StatesClass = function (rc4Bytes) {\n this.rc4Bytes = rc4Bytes;\n this.states = [1, 0, 0];\n this.newState = function(){return 'newState';};\n this.firstState = '"+e.encode("\\w+ *\\(\\) *{\\w+ *",!0)+"';\n this.secondState = '"+e.encode("['|\"].+['|\"];? *}",!0)+"';\n };\n \n StatesClass.prototype.checkState = function () {\n var regExp = new RegExp(this.firstState + this.secondState);\n\n return this.runState(regExp.test(this.newState.toString()) ? --this.states[1] : --this.states[0]);\n };\n \n StatesClass.prototype.runState = function (stateResult) {\n if (!Boolean(~stateResult)) {\n return stateResult;\n }\n \n return this.getState(this.rc4Bytes);\n };\n\n StatesClass.prototype.getState = function (rc4Bytes) {\n for (var i = 0, len = this.states.length; i < len; i++) {\n this.states.push(Math.round(Math.random()));\n len = this.states.length;\n }\n \n return rc4Bytes(this.states[0]);\n };\n\n new StatesClass({stringArrayCallsWrapperName}).checkState();\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.SelfDefendingTemplate=n},function(e,t,r){"use strict";function n(){return" \n if ({stringArrayCallsWrapperName}.initialized === undefined) {\n {atobPolyfill}\n \n {stringArrayCallsWrapperName}.base64DecodeUnicode = function (str) {\n var string = atob(str);\n var newStringChars = [];\n \n for (var i = 0, length = string.length; i < length; i++) {\n newStringChars += '%' + ('00' + string.charCodeAt(i).toString(16)).slice(-2);\n }\n \n return decodeURIComponent(newStringChars);\n };\n \n {stringArrayCallsWrapperName}.data = {};\n \n {stringArrayCallsWrapperName}.initialized = true;\n }\n \n var cachedValue = {stringArrayCallsWrapperName}.data[index];\n \n if (cachedValue === undefined) {\n {selfDefendingCode}\n \n value = {stringArrayCallsWrapperName}.base64DecodeUnicode(value);\n {stringArrayCallsWrapperName}.data[index] = value;\n } else {\n value = cachedValue;\n } \n "}Object.defineProperty(t,"__esModule",{value:!0}),t.StringArrayBase64DecodeNodeTemplate=n},function(e,t,r){"use strict";function n(){return"\n var {stringArrayCallsWrapperName} = function (index, key) {\n index = index - 0;\n \n var value = {stringArrayName}[index];\n \n {decodeNodeTemplate}\n \n return value;\n };\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.StringArrayCallsWrapperTemplate=n},function(e,t,r){"use strict";function n(){return"\n if ({stringArrayCallsWrapperName}.initialized === undefined) {\n {atobPolyfill}\n \n {rc4Polyfill}\n {stringArrayCallsWrapperName}.rc4 = rc4;\n \n {stringArrayCallsWrapperName}.data = {};\n \n {stringArrayCallsWrapperName}.initialized = true;\n }\n \n var cachedValue = {stringArrayCallsWrapperName}.data[index];\n\n if (cachedValue === undefined) {\n if ({stringArrayCallsWrapperName}.once === undefined) {\n {selfDefendingCode}\n \n {stringArrayCallsWrapperName}.once = true;\n }\n \n value = {stringArrayCallsWrapperName}.rc4(value, key);\n {stringArrayCallsWrapperName}.data[index] = value;\n } else {\n value = cachedValue;\n }\n "}Object.defineProperty(t,"__esModule",{value:!0}),t.StringArrayRc4DecodeNodeTemplate=n},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;r=m.minimumLengthForStringArray&&this.randomGenerator.getMathRandom()<=this.options.stringArrayThreshold}},{key:"getStringArrayHexadecimalIndex",value:function(e,t){if(this.stringLiteralHexadecimalIndexCache.has(e))return{fromCache:!0,index:this.stringLiteralHexadecimalIndexCache.get(e)};var r=p.Utils.decToHex(t),n=""+p.Utils.hexadecimalPrefix+r;return this.stringLiteralHexadecimalIndexCache.set(e,n),{fromCache:!1,index:n}}},{key:"getEncodedValue",value:function(e){var t=void 0,r=null;switch(this.options.stringArrayEncoding){case l.StringArrayEncoding.Rc4:r=this.randomGenerator.getRandomGenerator().pickone(this.rc4Keys),t=this.cryptUtils.btoa(this.cryptUtils.rc4(e,r));break;case l.StringArrayEncoding.Base64:t=this.cryptUtils.btoa(e);break;default:t=e}return{encodedValue:t,key:r}}},{key:"replaceWithLiteralNode",value:function(e){return d.Nodes.getLiteralNode(this.escapeSequenceEncoder.encode(e,this.options.unicodeEscapeSequence))}},{key:"replaceWithStringArrayCallNode",value:function(e){var t=this.getEncodedValue(e),r=t.encodedValue,n=t.key,o=this.escapeSequenceEncoder.encode(r,this.options.unicodeEscapeSequence),a=this.stringArrayStorage.getLength(),i=p.Utils.stringRotate(this.stringArrayStorage.getStorageId(),1),c="_"+p.Utils.hexadecimalPrefix+i,s=this.getStringArrayHexadecimalIndex(o,a),u=s.fromCache,l=s.index;u||this.stringArrayStorage.set(a,o);var f=[m.getHexadecimalLiteralNode(l)];return n&&f.push(m.getRc4KeyLiteralNode(this.escapeSequenceEncoder.encode(n,this.options.unicodeEscapeSequence))),d.Nodes.getCallExpressionNode(d.Nodes.getIdentifierNode(c),f)}}],[{key:"getHexadecimalLiteralNode",value:function(e){var t=d.Nodes.getLiteralNode(e);return t.obfuscatedNode=!0,t}},{key:"getRc4KeyLiteralNode",value:function(e){var t=d.Nodes.getLiteralNode(e);return t.obfuscatedNode=!0,t}}]),t}(f.AbstractObfuscatingReplacer);y.minimumLengthForStringArray=3,y.rc4KeyLength=4,y.rc4KeysCount=50,y=m=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.TCustomNodeGroupStorage)),c.__param(1,s.inject(u.ServiceIdentifiers.TStringArrayStorage)),c.__param(2,s.inject(u.ServiceIdentifiers.IEscapeSequenceEncoder)),c.__param(3,s.inject(u.ServiceIdentifiers.IRandomGenerator)),c.__param(4,s.inject(u.ServiceIdentifiers.ICryptUtils)),c.__param(5,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Object,Object,Object,Object,Object,Object])],y),t.StringLiteralObfuscatingReplacer=y;var m},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(16),o=r(0),a=r(1),i=r(35),c=r(94),s=r(95),u=r(96),l=r(97),f=r(98),d=r(99),p=r(100),y=r(101),m=r(102),b=r(103),g=r(104),v=r(105),h=r(106);t.nodeTransformersModule=new o.ContainerModule(function(e){e(a.ServiceIdentifiers.INodeTransformer).to(s.BlockStatementControlFlowTransformer).whenTargetNamed(i.NodeTransformer.BlockStatementControlFlowTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(u.DeadCodeInjectionTransformer).whenTargetNamed(i.NodeTransformer.DeadCodeInjectionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(c.FunctionControlFlowTransformer).whenTargetNamed(i.NodeTransformer.FunctionControlFlowTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(m.MemberExpressionTransformer).whenTargetNamed(i.NodeTransformer.MemberExpressionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(b.MethodDefinitionTransformer).whenTargetNamed(i.NodeTransformer.MethodDefinitionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(v.TemplateLiteralTransformer).whenTargetNamed(i.NodeTransformer.TemplateLiteralTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(l.CatchClauseTransformer).whenTargetNamed(i.NodeTransformer.CatchClauseTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(f.FunctionDeclarationTransformer).whenTargetNamed(i.NodeTransformer.FunctionDeclarationTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(d.FunctionTransformer).whenTargetNamed(i.NodeTransformer.FunctionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(p.LabeledStatementTransformer).whenTargetNamed(i.NodeTransformer.LabeledStatementTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(y.LiteralTransformer).whenTargetNamed(i.NodeTransformer.LiteralTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(g.ObjectExpressionTransformer).whenTargetNamed(i.NodeTransformer.ObjectExpressionTransformer),e(a.ServiceIdentifiers.INodeTransformer).to(h.VariableDeclarationTransformer).whenTargetNamed(i.NodeTransformer.VariableDeclarationTransformer),e(a.ServiceIdentifiers.Factory__INodeTransformer).toFactory(n.InversifyContainerFacade.getCacheFactory(a.ServiceIdentifiers.INodeTransformer))})},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;rh.hostNodeSearchMinDepth&&t.splice(0,h.hostNodeSearchMinDepth),t.length>h.hostNodeSearchMaxDepth&&(t.length=h.hostNodeSearchMaxDepth),this.randomGenerator.getRandomGenerator().pickone(t))}},{key:"isVisitedFunctionNode",value:function(e){return(y.Node.isFunctionDeclarationNode(e)||y.Node.isFunctionExpressionNode(e)||y.Node.isArrowFunctionExpressionNode(e))&&this.visitedFunctionNodes.has(e)}},{key:"transformFunctionBody",value:function(e,t){var r=this;l.replace(e,{enter:function(e,n){if(r.isVisitedFunctionNode(e))return l.VisitorOption.Skip;if(!h.controlFlowReplacersMap.has(e.type))return e;if(r.randomGenerator.getMathRandom()>r.options.controlFlowFlatteningThreshold)return e;var o=h.controlFlowReplacersMap.get(e.type);return void 0===o?e:Object.assign({},r.controlFlowReplacerFactory(o).replace(e,n,t),{parentNode:n})}})}}]),t}(p.AbstractNodeTransformer);v.controlFlowReplacersMap=new Map([[d.NodeType.BinaryExpression,b.ControlFlowReplacer.BinaryExpressionControlFlowReplacer],[d.NodeType.CallExpression,b.ControlFlowReplacer.CallExpressionControlFlowReplacer],[d.NodeType.LogicalExpression,b.ControlFlowReplacer.LogicalExpressionControlFlowReplacer],[d.NodeType.Literal,b.ControlFlowReplacer.StringLiteralControlFlowReplacer]]),v.hostNodeSearchMinDepth=0,v.hostNodeSearchMaxDepth=2,v=h=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.Factory__TControlFlowStorage)),c.__param(1,s.inject(u.ServiceIdentifiers.Factory__IControlFlowReplacer)),c.__param(2,s.inject(u.ServiceIdentifiers.Factory__IControlFlowCustomNode)),c.__param(3,s.inject(u.ServiceIdentifiers.IRandomGenerator)),c.__param(4,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Function,Function,Function,Object,Object])],v),t.FunctionControlFlowTransformer=v;var h},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;rthis.options.controlFlowFlatteningThreshold||y.blockStatementHasProhibitedStatements(e))return e;var r=e.body;if(r.length<=4)return e;var n=this.arrayUtils.arrayRange(r.length),o=this.arrayUtils.arrayShuffle(n),a=n.map(function(e){return o.indexOf(e)}),i=this.controlFlowCustomNodeFactory(l.ControlFlowCustomNode.BlockStatementControlFlowFlatteningNode);return i.initialize(r,o,a),i.getNode()[0]}}],[{key:"blockStatementHasProhibitedStatements",value:function(e){return e.body.some(function(e){var t=d.Node.isBreakStatementNode(e)||d.Node.isContinueStatementNode(e),r=d.Node.isVariableDeclarationNode(e)&&("const"===e.kind||"let"===e.kind);return d.Node.isFunctionDeclarationNode(e)||t||r})}}]),t}(f.AbstractNodeTransformer);p=y=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.Factory__IControlFlowCustomNode)),c.__param(1,s.inject(u.ServiceIdentifiers.IArrayUtils)),c.__param(2,s.inject(u.ServiceIdentifiers.IRandomGenerator)),c.__param(3,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Function,Object,Object,Object])],p),t.BlockStatementControlFlowTransformer=p;var y},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;rb.maxNestedBlockStatementsCount||d.Node.isBreakStatementNode(e)||d.Node.isContinueStatementNode(e)?(a=!1,l.VisitorOption.Break):(d.Node.isIdentifierNode(e)&&!d.Node.isMemberExpressionNode(t)&&(e.name=r.randomGenerator.getRandomVariableName(6)),e)}}),a&&t.push(n)}},{key:"replaceBlockStatementNode",value:function(e,t){var r=this.randomGenerator.getMathRandom()>.5,n=this.randomGenerator.getMathRandom()>.5,o=r?"===":"!==",a=this.randomGenerator.getRandomString(3),i=n?a:this.randomGenerator.getRandomString(3),c=void 0,s=void 0;r&&n||!r&&!n?(c=e,s=t):(c=t,s=e);var u=p.Nodes.getBlockStatementNode([p.Nodes.getIfStatementNode(p.Nodes.getBinaryExpressionNode(o,p.Nodes.getLiteralNode(a),p.Nodes.getLiteralNode(i)),c,s)]);return u=y.NodeUtils.parentize(u)}},{key:"transformProgramNode",value:function(e){var t=this;l.traverse(e,{enter:function(e,r){d.Node.isBlockStatementNode(e)&&t.collectBlockStatementNodes(e,t.collectedBlockStatements)}}),this.collectedBlockStatements.lengtht.options.deadCodeInjectionThreshold)return e;var n=t.randomGenerator.getRandomInteger(0,t.collectedBlockStatements.length-1),o=t.collectedBlockStatements.splice(n,1)[0];return o===e?e:t.replaceBlockStatementNode(e,o)}})}}]),t}(f.AbstractNodeTransformer);m.maxNestedBlockStatementsCount=4,m.minCollectedBlockStatementsCount=5,m=b=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.IRandomGenerator)),c.__param(1,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Object,Object])],m),t.DeadCodeInjectionTransformer=m;var b},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;r1){var o=d.Nodes.getBinaryExpressionNode("+",n.shift(),n.shift());return n.forEach(function(e){o=d.Nodes.getBinaryExpressionNode("+",o,e)}),o}return n[0]}}],[{key:"isLiteralNodeWithStringValue",value:function(e){return e&&f.Node.isLiteralNode(e)&&"string"==typeof e.value}}]),t}(l.AbstractNodeTransformer);p=y=c.__decorate([s.injectable(),c.__param(0,s.inject(u.ServiceIdentifiers.IRandomGenerator)),c.__param(1,s.inject(u.ServiceIdentifiers.IOptions)),c.__metadata("design:paramtypes",[Object,Object])],p),t.TemplateLiteralTransformer=p;var y},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;rr)return"break";var a=e[o];s.traverse(a,{enter:function(r){if(l.Node.isCallExpressionNode(r))return a.parentNode!==f.NodeUtils.getBlockScopesOfNode(r)[0]?s.VisitorOption.Skip:void t.analyzeCallExpressionNode(n,e,r)}})}(a))break}return n}},{key:"analyzeCallExpressionNode",value:function(e,t,r){var n=this;p.calleeDataExtractorsList.forEach(function(o){var a=n.calleeDataExtractorFactory(o).extract(t,r.callee);a&&e.push(Object.assign({},a,{stackTrace:n.analyzeRecursive(a.callee.body)}))})}}],[{key:"getLimitIndex",value:function(e){var t=e-1,r=p.limitThresholdActivationLength-1,n=t;return t>r&&(n=Math.round(r+t*p.limitThreshold))>t&&(n=t),n}}]),e}();d.calleeDataExtractorsList=[u.CalleeDataExtractor.FunctionDeclarationCalleeDataExtractor,u.CalleeDataExtractor.FunctionExpressionCalleeDataExtractor,u.CalleeDataExtractor.ObjectExpressionCalleeDataExtractor],d.limitThresholdActivationLength=25,d.limitThreshold=.002,d=p=a.__decorate([i.injectable(),a.__param(0,i.inject(c.ServiceIdentifiers.Factory__ICalleeDataExtractor)),a.__metadata("design:paramtypes",[Function])],d),t.StackTraceAnalyzer=d;var p},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(0),o=r(1),a=r(113),i=r(114),c=r(115);t.storagesModule=new n.ContainerModule(function(e){e(o.ServiceIdentifiers.TCustomNodeGroupStorage).to(i.CustomNodeGroupStorage).inSingletonScope(),e(o.ServiceIdentifiers.TStringArrayStorage).to(c.StringArrayStorage).inSingletonScope(),e(o.ServiceIdentifiers.Newable__TControlFlowStorage).toConstructor(a.ControlFlowStorage),e(o.ServiceIdentifiers.Factory__TControlFlowStorage).toFactory(function(e){return function(){var t=e.container.get(o.ServiceIdentifiers.Newable__TControlFlowStorage);return new t(e.container.get(o.ServiceIdentifiers.IRandomGenerator))}})})},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(2),c=r(0),s=r(1),u=r(37),l=function(e){function t(e){n(this,t);var r=o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return r.initialize(),r}return a(t,e),t}(u.MapStorage);l=i.__decorate([c.injectable(),i.__param(0,c.inject(s.ServiceIdentifiers.IRandomGenerator)),i.__metadata("design:paramtypes",[Object])],l),t.ControlFlowStorage=l},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var r=0;r=0?t:null}},{key:"getLength",value:function(){return this.storageLength}},{key:"getStorage",value:function(){return this.storage}},{key:"getStorageId",value:function(){return this.storageId}},{key:"initialize",value:function(){this.storage=[],this.storageId=this.randomGenerator.getRandomString(6)}},{key:"mergeWith",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];this.storage=[].concat(n(this.storage),n(e.getStorage())),t&&(this.storageId=e.getStorageId())}},{key:"set",value:function(e,t){e===this.storageLength?this.storage.push(t):this.storage.splice(e,0,t),this.storageLength++}}]),e}();i.__decorate([u.initializable(),i.__metadata("design:type",Array)],l.prototype,"storage",void 0),i.__decorate([u.initializable(),i.__metadata("design:type",String)],l.prototype,"storageId",void 0),l=i.__decorate([c.injectable(),i.__param(0,c.inject(s.ServiceIdentifiers.IRandomGenerator)),i.__metadata("design:paramtypes",[Object])],l),t.ArrayStorage=l},function(e,t){e.exports=require("chance")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(0),o=r(1),a=r(119),i=r(120),c=r(121),s=r(28);t.utilsModule=new n.ContainerModule(function(e){e(o.ServiceIdentifiers.IArrayUtils).to(a.ArrayUtils).inSingletonScope(),e(o.ServiceIdentifiers.IRandomGenerator).to(s.RandomGenerator).inSingletonScope(),e(o.ServiceIdentifiers.ICryptUtils).to(i.CryptUtils).inSingletonScope(),e(o.ServiceIdentifiers.IEscapeSequenceEncoder).to(c.EscapeSequenceEncoder).inSingletonScope()})},function(e,t,r){"use strict";function n(e){if(Array.isArray(e)){for(var t=0,r=Array(e.length);t>8-o%1*8)){if((n=e.charCodeAt(o+=.75))>255)throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");r=r<<8|n}return t}},{key:"hideString",value:function(e,t){var r=this,n=this.randomGenerator.getRandomGenerator().string({length:t,pool:s.RandomGenerator.randomGeneratorPool}),o=n.replace(new RegExp("["+function(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}(e)+"]","g"),""),a=o.split("");return this.randomGenerator.getRandomGenerator().shuffle(a),o=a.join(""),[function(e,t){for(var n=-1,o=-1,a="";n [options]").option("-o, --output ","Output path for obfuscated code").option("--compact ","Disable one line output code compacting",s.BooleanSanitizer).option("--controlFlowFlattening ","Enables control flow flattening",s.BooleanSanitizer).option("--controlFlowFlatteningThreshold ","The probability that the control flow flattening transformation will be applied to the node",parseFloat).option("--deadCodeInjection ","Enables dead code injection",s.BooleanSanitizer).option("--deadCodeInjectionThreshold ","The probability that the dead code injection transformation will be applied to the node",parseFloat).option("--debugProtection ","Disable browser Debug panel (can cause DevTools enabled browser freeze)",s.BooleanSanitizer).option("--debugProtectionInterval ","Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)",s.BooleanSanitizer).option("--disableConsoleOutput ","Allow console.log, console.info, console.error and console.warn messages output into browser console",s.BooleanSanitizer).option("--domainLock ","Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)",function(e){return e.split(",")}).option("--mangle ","Enables mangling of variable names",s.BooleanSanitizer).option("--reservedNames ","Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)",function(e){return e.split(",")}).option("--rotateStringArray ","Disable rotation of unicode array values during obfuscation",s.BooleanSanitizer).option("--seed ","Sets seed for random generator. This is useful for creating repeatable results.",parseFloat).option("--selfDefending ","Disables self-defending for obfuscated code",s.BooleanSanitizer).option("--sourceMap ","Enables source map generation",s.BooleanSanitizer).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",u.SourceMapModeSanitizer).option("--stringArray ","Disables gathering of all literal strings into an array and replacing every literal string with an array call",s.BooleanSanitizer).option("--stringArrayEncoding [true, false, base64, rc4]","Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed",l.StringArrayEncodingSanitizer).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",s.BooleanSanitizer).parse(this.rawArguments)}},{key:"configureHelp",value:function(){this.commands.on("--help",function(){console.log(" Examples:\n"),console.log(" %> javascript-obfuscator in.js --compact true --selfDefending false"),console.log(" %> javascript-obfuscator in.js --output out.js --compact true --selfDefending false"),console.log("")})}},{key:"getData",value:function(){this.sourceCode=f.CLIUtils.readFile(this.inputPath)}},{key:"processData",value:function(){var e=this.buildOptions(),t=f.CLIUtils.getOutputCodePath(this.commands.output,this.inputPath);e.sourceMap?this.processDataWithSourceMap(t,e):this.processDataWithoutSourceMap(t,e)}},{key:"processDataWithoutSourceMap",value:function(e,t){var r=d.JavaScriptObfuscator.obfuscate(this.sourceCode,t).getObfuscatedCode();f.CLIUtils.writeFile(e,r)}},{key:"processDataWithSourceMap",value:function(e,t){var r=f.CLIUtils.getOutputSourceMapPath(e,t.sourceMapFileName||"");t=Object.assign({},t,{sourceMapFileName:i.basename(r)});var n=d.JavaScriptObfuscator.obfuscate(this.sourceCode,t);f.CLIUtils.writeFile(e,n.getObfuscatedCode()),"separate"===t.sourceMapMode&&n.getSourceMap()&&f.CLIUtils.writeFile(r,n.getSourceMap())}}]),e}();t.JavaScriptObfuscatorCLI=p},function(e,t){e.exports=require("commander")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BooleanSanitizer=function(e){return"true"===e||"1"===e}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(22);t.SourceMapModeSanitizer=function(e){if(!Object.keys(n.SourceMapMode).some(function(t){return n.SourceMapMode[t]===e}))throw new ReferenceError("Invalid value of `--sourceMapMode` option");return e}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(26);t.StringArrayEncodingSanitizer=function(e){switch(e){case"true":case"1":case n.StringArrayEncoding.Base64:return!0;case n.StringArrayEncoding.Rc4:return n.StringArrayEncoding.Rc4;default:return!1}}},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:"";return t&&(e=e.substring(0,e.lastIndexOf("/"))+"/"+t),/\.js\.map$/.test(e)?/\.js$/.test(e)&&(e+=".map"):e=e.split(".")[0]+".js.map",e}},{key:"getPackageConfig",value:function(){return JSON.parse(a.readFileSync(c.join(c.dirname(a.realpathSync(process.argv[1])),"../package.json"),e.encoding))}},{key:"isFilePath",value:function(e){try{return a.statSync(e).isFile()}catch(e){return!1}}},{key:"readFile",value:function(t){return a.readFileSync(t,e.encoding)}},{key:"validateInputPath",value:function(t){if(!e.isFilePath(t))throw new ReferenceError("Given input path must be a valid file path");if(-1===e.availableInputExtensions.indexOf(c.extname(t)))throw new ReferenceError("Input file must have .js extension")}},{key:"writeFile",value:function(t,r){i.sync(c.dirname(t)),a.writeFileSync(t,r,{encoding:e.encoding})}}]),e}();s.availableInputExtensions=[".js"],s.encoding="utf8",t.CLIUtils=s},function(e,t){e.exports=require("fs")},function(e,t){e.exports=require("mkdirp")}]); //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/package.json b/package.json index 97c06610..b9e58c28 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-obfuscator", - "version": "0.10.0-beta.4", + "version": "0.10.0-beta.5", "description": "JavaScript obfuscator", "keywords": [ "obfuscator", @@ -21,7 +21,7 @@ "dependencies": { "chance": "1.0.10", "class-validator": "0.7.1", - "commander": "2.9.0", + "commander": "2.10.0", "escodegen-wallaby": "1.6.11", "esmangle": "1.0.1", "esprima": "4.0.0", @@ -35,7 +35,7 @@ "tslib": "1.7.1" }, "devDependencies": { - "@types/chai": "4.0.0", + "@types/chai": "4.0.1", "@types/chance": "0.7.33", "@types/commander": "2.9.1", "@types/escodegen": "0.0.6", @@ -44,12 +44,12 @@ "@types/estree": "0.0.35", "@types/mkdirp": "0.3.29", "@types/mocha": "2.2.41", - "@types/node": "8.0.0", - "@types/sinon": "2.3.1", + "@types/node": "8.0.3", + "@types/sinon": "2.3.2", "@types/string-template": "1.0.2", "awesome-typescript-loader": "3.1.3", "babel-cli": "6.24.1", - "babel-loader": "7.0.0", + "babel-loader": "7.1.0", "babel-plugin-array-includes": "2.0.3", "babel-preset-es2015": "6.24.1", "chai": "4.0.2", @@ -57,8 +57,8 @@ "istanbul": "1.1.0-alpha.1", "mocha": "3.4.2", "pre-commit": "1.2.2", - "sinon": "2.3.4", - "ts-node": "3.0.6", + "sinon": "2.3.5", + "ts-node": "3.1.0", "tslint": "5.4.3", "tslint-loader": "3.5.3", "typescript": "2.4.0", diff --git a/src/JavaScriptObfuscator.ts b/src/JavaScriptObfuscator.ts index 43667a41..a419689f 100644 --- a/src/JavaScriptObfuscator.ts +++ b/src/JavaScriptObfuscator.ts @@ -7,11 +7,9 @@ import { TInputOptions } from './types/options/TInputOptions'; import { IInversifyContainerFacade } from './interfaces/container/IInversifyContainerFacade'; import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator'; import { IObfuscationResult } from './interfaces/IObfuscationResult'; -import { IOptions } from './interfaces/options/IOptions'; import { InversifyContainerFacade } from './container/InversifyContainerFacade'; import { JavaScriptObfuscatorCLI } from './cli/JavaScriptObfuscatorCLI'; -import { RandomGeneratorUtils } from './utils/RandomGeneratorUtils'; export class JavaScriptObfuscator { /** @@ -20,16 +18,15 @@ export class JavaScriptObfuscator { * @returns {string} */ public static obfuscate (sourceCode: string, inputOptions: TInputOptions = {}): IObfuscationResult { - const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(inputOptions); - const options: IOptions = inversifyContainerFacade.get(ServiceIdentifiers.IOptions); + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); - RandomGeneratorUtils.initializeRandomGenerator(options.seed); + inversifyContainerFacade.load(inputOptions); const javaScriptObfuscator: IJavaScriptObfuscator = inversifyContainerFacade .get(ServiceIdentifiers.IJavaScriptObfuscator); const obfuscationResult: IObfuscationResult = javaScriptObfuscator.obfuscate(sourceCode); - RandomGeneratorUtils.clearRandomGenerator(); + inversifyContainerFacade.unload(); return obfuscationResult; } diff --git a/src/JavaScriptObfuscatorInternal.ts b/src/JavaScriptObfuscatorInternal.ts index f1e90fb8..a92b53f8 100644 --- a/src/JavaScriptObfuscatorInternal.ts +++ b/src/JavaScriptObfuscatorInternal.ts @@ -59,7 +59,7 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator { */ public obfuscate (sourceCode: string): IObfuscationResult { // parse AST tree - const astTree: ESTree.Program = esprima.parse(sourceCode, { loc: this.options.sourceMap }); + const astTree: ESTree.Program = this.parseCode(sourceCode); // obfuscate AST tree const obfuscatedAstTree: ESTree.Program = this.obfuscator.obfuscateAstTree(astTree); @@ -70,6 +70,16 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator { return this.getObfuscationResult(generatorOutput); } + /** + * @param sourceCode + * @return {ESTree.Program} + */ + private parseCode (sourceCode: string): ESTree.Program { + return esprima.parse(sourceCode, { + loc: this.options.sourceMap + }); + } + /** * @param sourceCode * @param astTree diff --git a/src/SourceMapCorrector.ts b/src/SourceMapCorrector.ts index db3c371f..46b9b8fe 100644 --- a/src/SourceMapCorrector.ts +++ b/src/SourceMapCorrector.ts @@ -3,16 +3,20 @@ import { ServiceIdentifiers } from './container/ServiceIdentifiers'; import { TObfuscationResultFactory } from './types/container/TObfuscationResultFactory'; +import { ICryptUtils } from './interfaces/utils/ICryptUtils'; import { IObfuscationResult } from './interfaces/IObfuscationResult'; import { IOptions } from './interfaces/options/IOptions'; import { ISourceMapCorrector } from './interfaces/ISourceMapCorrector'; import { SourceMapMode } from './enums/SourceMapMode'; -import { CryptUtils } from './utils/CryptUtils'; - @injectable() export class SourceMapCorrector implements ISourceMapCorrector { + /** + * @type {ICryptUtils} + */ + private readonly cryptUtils: ICryptUtils; + /** * @type {TObfuscationResultFactory} */ @@ -25,13 +29,16 @@ export class SourceMapCorrector implements ISourceMapCorrector { /** * @param obfuscationResultFactory + * @param cryptUtils * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__IObfuscationResult) obfuscationResultFactory: TObfuscationResultFactory, + @inject(ServiceIdentifiers.ICryptUtils) cryptUtils: ICryptUtils, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { this.obfuscationResultFactory = obfuscationResultFactory; + this.cryptUtils = cryptUtils; this.options = options; } @@ -63,7 +70,7 @@ export class SourceMapCorrector implements ISourceMapCorrector { switch (this.options.sourceMapMode) { case SourceMapMode.Inline: - sourceMappingUrl += `data:application/json;base64,${CryptUtils.btoa(sourceMap)}`; + sourceMappingUrl += `data:application/json;base64,${this.cryptUtils.btoa(sourceMap)}`; break; diff --git a/src/container/InversifyContainerFacade.ts b/src/container/InversifyContainerFacade.ts index 3d5e89f3..b5d64dd1 100644 --- a/src/container/InversifyContainerFacade.ts +++ b/src/container/InversifyContainerFacade.ts @@ -7,6 +7,7 @@ import { obfuscatingTransformersModule } from './modules/node-transformers/Obfus import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule'; import { stackTraceAnalyzerModule } from './modules/stack-trace-analyzer/StackTraceAnalyzerModule'; import { storagesModule } from './modules/storages/StoragesModule'; +import { utilsModule } from './modules/utils/UtilsModule'; import { TInputOptions } from '../types/options/TInputOptions'; @@ -31,64 +32,8 @@ export class InversifyContainerFacade implements IInversifyContainerFacade { */ private readonly container: interfaces.Container; - /** - * @param options - */ - constructor (options: TInputOptions) { + constructor () { this.container = new Container(); - - this.container - .bind(ServiceIdentifiers.IOptions) - .toDynamicValue(() => { - return new Options(options); - }) - .inSingletonScope(); - - this.container - .bind(ServiceIdentifiers.IJavaScriptObfuscator) - .to(JavaScriptObfuscatorInternal) - .inSingletonScope(); - - this.container - .bind(ServiceIdentifiers.IObfuscator) - .to(Obfuscator) - .inSingletonScope(); - - this.container - .bind(ServiceIdentifiers.IObfuscationResult) - .to(ObfuscationResult) - .inSingletonScope(); - - this.container - .bind(ServiceIdentifiers.Factory__IObfuscationResult) - .toFactory((context: interfaces.Context) => { - return (obfuscatedCode: string, sourceMap: string) => { - const obfuscationResult: IObfuscationResult = context.container - .get(ServiceIdentifiers.IObfuscationResult); - - obfuscationResult.initialize(obfuscatedCode, sourceMap); - - return obfuscationResult; - }; - }); - - this.container - .bind(ServiceIdentifiers.ISourceMapCorrector) - .to(SourceMapCorrector) - .inSingletonScope(); - - this.container - .bind(ServiceIdentifiers.IObfuscationEventEmitter) - .to(ObfuscationEventEmitter) - .inSingletonScope(); - - // modules - this.container.load(storagesModule); - this.container.load(stackTraceAnalyzerModule); - this.container.load(customNodesModule); - this.container.load(nodeTransformersModule); - this.container.load(controlFlowTransformersModule); - this.container.load(obfuscatingTransformersModule); } /** @@ -129,6 +74,43 @@ export class InversifyContainerFacade implements IInversifyContainerFacade { }; } + /** + * @param serviceIdentifier + * @param dependencies + * @return {(context: interfaces.Context) => (bindingName: T) => U} + */ + public static getConstructorFactory ( + serviceIdentifier: interfaces.ServiceIdentifier>, + ...dependencies: any[] + ): (context: interfaces.Context) => (bindingName: T) => U { + return (context: interfaces.Context): (bindingName: T) => U => { + const cache: Map> = new Map(); + const cachedDependencies: any[] = []; + + return (bindingName: T) => { + dependencies.forEach((dependency: any, index: number) => { + if (!cachedDependencies[index]) { + cachedDependencies[index] = context.container.get(dependency); + } + }); + + if (cache.has(bindingName)) { + return new (>cache.get(bindingName))(...cachedDependencies); + } + + const constructor: interfaces.Newable = context.container + .getNamed>( + serviceIdentifier, + bindingName + ); + + cache.set(bindingName, constructor); + + return new constructor(...cachedDependencies); + }; + }; + } + /** * @param serviceIdentifier * @returns {T} @@ -145,4 +127,65 @@ export class InversifyContainerFacade implements IInversifyContainerFacade { public getNamed (serviceIdentifier: interfaces.ServiceIdentifier, named: string | number | symbol): T { return this.container.getNamed(serviceIdentifier, named); } + + /** + * @param options + */ + public load (options: TInputOptions): void { + this.container + .bind(ServiceIdentifiers.IOptions) + .toDynamicValue(() => new Options(options)) + .inSingletonScope(); + + this.container + .bind(ServiceIdentifiers.IJavaScriptObfuscator) + .to(JavaScriptObfuscatorInternal) + .inSingletonScope(); + + this.container + .bind(ServiceIdentifiers.IObfuscator) + .to(Obfuscator) + .inSingletonScope(); + + this.container + .bind(ServiceIdentifiers.IObfuscationResult) + .to(ObfuscationResult) + .inSingletonScope(); + + this.container + .bind(ServiceIdentifiers.Factory__IObfuscationResult) + .toFactory((context: interfaces.Context) => { + return (obfuscatedCode: string, sourceMap: string) => { + const obfuscationResult: IObfuscationResult = context.container + .get(ServiceIdentifiers.IObfuscationResult); + + obfuscationResult.initialize(obfuscatedCode, sourceMap); + + return obfuscationResult; + }; + }); + + this.container + .bind(ServiceIdentifiers.ISourceMapCorrector) + .to(SourceMapCorrector) + .inSingletonScope(); + + this.container + .bind(ServiceIdentifiers.IObfuscationEventEmitter) + .to(ObfuscationEventEmitter) + .inSingletonScope(); + + // modules + this.container.load(utilsModule); + this.container.load(storagesModule); + this.container.load(stackTraceAnalyzerModule); + this.container.load(customNodesModule); + this.container.load(nodeTransformersModule); + this.container.load(controlFlowTransformersModule); + this.container.load(obfuscatingTransformersModule); + } + + public unload (): void { + this.container.unbindAll(); + } } diff --git a/src/container/ServiceIdentifiers.ts b/src/container/ServiceIdentifiers.ts index 9926ca9d..1c2d9256 100644 --- a/src/container/ServiceIdentifiers.ts +++ b/src/container/ServiceIdentifiers.ts @@ -1,29 +1,35 @@ -export const ServiceIdentifiers: any = { - Factory__ICalleeDataExtractor: Symbol('Factory'), - Factory__IControlFlowReplacer: Symbol('Factory'), - Factory__ICustomNode: Symbol('Factory'), - Factory__ICustomNodeGroup: Symbol('Factory'), - Factory__IIdentifierObfuscatingReplacer: Symbol('Factory'), - Factory__INodeTransformer: Symbol('Factory'), - Factory__IObfuscationResult: Symbol('Factory'), - Factory__IObfuscatingReplacer: Symbol('Factory'), - Factory__TControlFlowStorage: Symbol('Factory'), - ICalleeDataExtractor: Symbol('ICalleeDataExtractor'), - ICustomNodeGroup: Symbol('ICustomNodeGroup'), - IControlFlowReplacer: Symbol('IControlFlowReplacer'), - IDeadCodeInjectionReplacer: Symbol('IDeadCodeInjectionReplacer'), - IIdentifierObfuscatingReplacer: Symbol('IIdentifierObfuscatingReplacer'), - IJavaScriptObfuscator: Symbol('IJavaScriptObfuscator'), - INodeTransformer: Symbol('INodeTransformer'), - IObfuscationEventEmitter: Symbol('IObfuscationEventEmitter'), - IObfuscationResult: Symbol('IObfuscationResult'), - IObfuscator: Symbol('IObfuscator'), - IOptions: Symbol('IOptions'), - IObfuscatingReplacer: Symbol('IObfuscatingReplacer'), - ISourceMapCorrector: Symbol('ISourceMapCorrector'), - IStackTraceAnalyzer: Symbol('IStackTraceAnalyzer'), - Newable__ICustomNode: Symbol('Newable'), - Newable__TControlFlowStorage: Symbol('Newable'), - TCustomNodeGroupStorage: Symbol('TCustomNodeGroupStorage'), - TStringArrayStorage: Symbol('TStringArrayStorage') -}; +export enum ServiceIdentifiers { + Factory__ICalleeDataExtractor = 'Factory', + Factory__IControlFlowCustomNode = 'Factory', + Factory__IControlFlowReplacer = 'Factory', + Factory__ICustomNode = 'Factory', + Factory__ICustomNodeGroup = 'Factory', + Factory__IIdentifierObfuscatingReplacer = 'Factory', + Factory__INodeTransformer = 'Factory', + Factory__IObfuscationResult = 'Factory', + Factory__IObfuscatingReplacer = 'Factory', + Factory__TControlFlowStorage = 'Factory', + IArrayUtils = 'IArrayUtils', + ICalleeDataExtractor = 'ICalleeDataExtractor', + ICryptUtils = 'ICryptUtils', + ICustomNode = 'ICustomNode', + ICustomNodeGroup = 'ICustomNodeGroup', + IControlFlowReplacer = 'IControlFlowReplacer', + IDeadCodeInjectionReplacer = 'IDeadCodeInjectionReplacer', + IEscapeSequenceEncoder = 'IEscapeSequenceEncoder', + IIdentifierObfuscatingReplacer = 'IIdentifierObfuscatingReplacer', + IJavaScriptObfuscator = 'IJavaScriptObfuscator', + INodeTransformer = 'INodeTransformer', + IObfuscationEventEmitter = 'IObfuscationEventEmitter', + IObfuscationResult = 'IObfuscationResult', + IObfuscator = 'IObfuscator', + IOptions = 'IOptions', + IObfuscatingReplacer = 'IObfuscatingReplacer', + IRandomGenerator = 'IRandomGenerator', + ISourceMapCorrector = 'ISourceMapCorrector', + IStackTraceAnalyzer = 'IStackTraceAnalyzer', + Newable__ICustomNode = 'Newable', + Newable__TControlFlowStorage = 'Newable', + TCustomNodeGroupStorage = 'TCustomNodeGroupStorage', + TStringArrayStorage = 'TStringArrayStorage' +} diff --git a/src/container/modules/custom-nodes/CustomNodesModule.ts b/src/container/modules/custom-nodes/CustomNodesModule.ts index 758b371b..33926822 100644 --- a/src/container/modules/custom-nodes/CustomNodesModule.ts +++ b/src/container/modules/custom-nodes/CustomNodesModule.ts @@ -4,8 +4,8 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { ICustomNodeGroup } from '../../../interfaces/custom-nodes/ICustomNodeGroup'; -import { IOptions } from '../../../interfaces/options/IOptions'; +import { ControlFlowCustomNode } from "../../../enums/container/custom-nodes/ControlFlowCustomNode"; import { CustomNode } from '../../../enums/container/custom-nodes/CustomNode'; import { CustomNodeGroup } from '../../../enums/container/custom-nodes/CustomNodeGroup'; @@ -37,81 +37,82 @@ import { StringLiteralNode } from '../../../custom-nodes/control-flow-flattening export const customNodesModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => { // custom nodes + bind(ServiceIdentifiers.ICustomNode) + .to(ConsoleOutputDisableExpressionNode) + .whenTargetNamed(CustomNode.ConsoleOutputDisableExpressionNode); + + bind(ServiceIdentifiers.ICustomNode) + .to(DebugProtectionFunctionCallNode) + .whenTargetNamed(CustomNode.DebugProtectionFunctionCallNode); + + bind(ServiceIdentifiers.ICustomNode) + .to(DebugProtectionFunctionIntervalNode) + .whenTargetNamed(CustomNode.DebugProtectionFunctionIntervalNode); + + bind(ServiceIdentifiers.ICustomNode) + .to(DebugProtectionFunctionNode) + .whenTargetNamed(CustomNode.DebugProtectionFunctionNode); + + bind(ServiceIdentifiers.ICustomNode) + .to(DomainLockNode) + .whenTargetNamed(CustomNode.DomainLockNode); + + bind(ServiceIdentifiers.ICustomNode) + .to(NodeCallsControllerFunctionNode) + .whenTargetNamed(CustomNode.NodeCallsControllerFunctionNode); + + bind(ServiceIdentifiers.ICustomNode) + .to(SelfDefendingUnicodeNode) + .whenTargetNamed(CustomNode.SelfDefendingUnicodeNode); + + bind(ServiceIdentifiers.ICustomNode) + .to(StringArrayCallsWrapper) + .whenTargetNamed(CustomNode.StringArrayCallsWrapper); + + bind(ServiceIdentifiers.ICustomNode) + .to(StringArrayNode) + .whenTargetNamed(CustomNode.StringArrayNode); + + bind(ServiceIdentifiers.ICustomNode) + .to(StringArrayRotateFunctionNode) + .whenTargetNamed(CustomNode.StringArrayRotateFunctionNode); + + // control flow custom nodes bind>(ServiceIdentifiers.Newable__ICustomNode) .toConstructor(BinaryExpressionFunctionNode) - .whenTargetNamed(CustomNode.BinaryExpressionFunctionNode); + .whenTargetNamed(ControlFlowCustomNode.BinaryExpressionFunctionNode); bind>(ServiceIdentifiers.Newable__ICustomNode) .toConstructor(BlockStatementControlFlowFlatteningNode) - .whenTargetNamed(CustomNode.BlockStatementControlFlowFlatteningNode); + .whenTargetNamed(ControlFlowCustomNode.BlockStatementControlFlowFlatteningNode); bind>(ServiceIdentifiers.Newable__ICustomNode) .toConstructor(CallExpressionControlFlowStorageCallNode) - .whenTargetNamed(CustomNode.CallExpressionControlFlowStorageCallNode); + .whenTargetNamed(ControlFlowCustomNode.CallExpressionControlFlowStorageCallNode); bind>(ServiceIdentifiers.Newable__ICustomNode) .toConstructor(CallExpressionFunctionNode) - .whenTargetNamed(CustomNode.CallExpressionFunctionNode); + .whenTargetNamed(ControlFlowCustomNode.CallExpressionFunctionNode); bind>(ServiceIdentifiers.Newable__ICustomNode) .toConstructor(ControlFlowStorageNode) - .whenTargetNamed(CustomNode.ControlFlowStorageNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(ConsoleOutputDisableExpressionNode) - .whenTargetNamed(CustomNode.ConsoleOutputDisableExpressionNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(DebugProtectionFunctionCallNode) - .whenTargetNamed(CustomNode.DebugProtectionFunctionCallNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(DebugProtectionFunctionIntervalNode) - .whenTargetNamed(CustomNode.DebugProtectionFunctionIntervalNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(DebugProtectionFunctionNode) - .whenTargetNamed(CustomNode.DebugProtectionFunctionNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(DomainLockNode) - .whenTargetNamed(CustomNode.DomainLockNode); + .whenTargetNamed(ControlFlowCustomNode.ControlFlowStorageNode); bind>(ServiceIdentifiers.Newable__ICustomNode) .toConstructor(ExpressionWithOperatorControlFlowStorageCallNode) - .whenTargetNamed(CustomNode.ExpressionWithOperatorControlFlowStorageCallNode); + .whenTargetNamed(ControlFlowCustomNode.ExpressionWithOperatorControlFlowStorageCallNode); bind>(ServiceIdentifiers.Newable__ICustomNode) .toConstructor(LogicalExpressionFunctionNode) - .whenTargetNamed(CustomNode.LogicalExpressionFunctionNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(NodeCallsControllerFunctionNode) - .whenTargetNamed(CustomNode.NodeCallsControllerFunctionNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(SelfDefendingUnicodeNode) - .whenTargetNamed(CustomNode.SelfDefendingUnicodeNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(StringArrayCallsWrapper) - .whenTargetNamed(CustomNode.StringArrayCallsWrapper); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(StringArrayNode) - .whenTargetNamed(CustomNode.StringArrayNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(StringArrayRotateFunctionNode) - .whenTargetNamed(CustomNode.StringArrayRotateFunctionNode); - - bind>(ServiceIdentifiers.Newable__ICustomNode) - .toConstructor(StringLiteralControlFlowStorageCallNode) - .whenTargetNamed(CustomNode.StringLiteralControlFlowStorageCallNode); + .whenTargetNamed(ControlFlowCustomNode.LogicalExpressionFunctionNode); bind>(ServiceIdentifiers.Newable__ICustomNode) .toConstructor(StringLiteralNode) - .whenTargetNamed(CustomNode.StringLiteralNode); + .whenTargetNamed(ControlFlowCustomNode.StringLiteralNode); + + bind>(ServiceIdentifiers.Newable__ICustomNode) + .toConstructor(StringLiteralControlFlowStorageCallNode) + .whenTargetNamed(ControlFlowCustomNode.StringLiteralControlFlowStorageCallNode); // node groups bind(ServiceIdentifiers.ICustomNodeGroup) @@ -136,31 +137,17 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule // customNode factory bind(ServiceIdentifiers.Factory__ICustomNode) - .toFactory((context: interfaces.Context) => { - const cache: Map > = new Map(); + .toFactory(InversifyContainerFacade + .getFactory(ServiceIdentifiers.ICustomNode)); - let cachedOptions: IOptions; - - return (customNodeName: CustomNode) => { - if (!cachedOptions) { - cachedOptions = context.container.get(ServiceIdentifiers.IOptions); - } - - if (cache.has(customNodeName)) { - return new (>cache.get(customNodeName)); - } - - const constructor: interfaces.Newable = context.container - .getNamed>( - ServiceIdentifiers.Newable__ICustomNode, - customNodeName - ); - - cache.set(customNodeName, constructor); - - return new constructor(cachedOptions); - }; - }); + // control flow storage customNode constructor factory + bind(ServiceIdentifiers.Factory__IControlFlowCustomNode) + .toFactory(InversifyContainerFacade + .getConstructorFactory( + ServiceIdentifiers.Newable__ICustomNode, + ServiceIdentifiers.IRandomGenerator, + ServiceIdentifiers.IOptions + )); // customNodeGroup factory bind(ServiceIdentifiers.Factory__ICustomNodeGroup) diff --git a/src/container/modules/storages/StoragesModule.ts b/src/container/modules/storages/StoragesModule.ts index 43c2f4fa..43563f34 100644 --- a/src/container/modules/storages/StoragesModule.ts +++ b/src/container/modules/storages/StoragesModule.ts @@ -5,6 +5,8 @@ import { TControlFlowStorage } from '../../../types/storages/TControlFlowStorage import { TCustomNodeGroupStorage } from '../../../types/storages/TCustomNodeGroupStorage'; import { TStringArrayStorage } from '../../../types/storages/TStringArrayStorage'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; + import { ControlFlowStorage } from '../../../storages/control-flow/ControlFlowStorage'; import { CustomNodeGroupStorage } from '../../../storages/custom-node-group/CustomNodeGroupStorage'; import { StringArrayStorage } from '../../../storages/string-array/StringArrayStorage'; @@ -28,8 +30,10 @@ export const storagesModule: interfaces.ContainerModule = new ContainerModule((b return () => { const constructor: interfaces.Newable = context.container .get>(ServiceIdentifiers.Newable__TControlFlowStorage); + const randomGenerator: IRandomGenerator = context.container + .get(ServiceIdentifiers.IRandomGenerator); - return new constructor(); + return new constructor(randomGenerator); }; }); }); diff --git a/src/container/modules/utils/UtilsModule.ts b/src/container/modules/utils/UtilsModule.ts new file mode 100644 index 00000000..7258e364 --- /dev/null +++ b/src/container/modules/utils/UtilsModule.ts @@ -0,0 +1,34 @@ +import { ContainerModule, interfaces } from 'inversify'; +import { ServiceIdentifiers } from '../../ServiceIdentifiers'; + +import { IArrayUtils } from '../../../interfaces/utils/IArrayUtils'; +import { ICryptUtils } from '../../../interfaces/utils/ICryptUtils'; +import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenceEncoder'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; + +import { ArrayUtils } from '../../../utils/ArrayUtils'; +import { CryptUtils } from '../../../utils/CryptUtils'; +import { EscapeSequenceEncoder } from '../../../utils/EscapeSequenceEncoder'; +import { RandomGenerator } from '../../../utils/RandomGenerator'; + +export const utilsModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => { + // array utils + bind(ServiceIdentifiers.IArrayUtils) + .to(ArrayUtils) + .inSingletonScope(); + + // random generator + bind(ServiceIdentifiers.IRandomGenerator) + .to(RandomGenerator) + .inSingletonScope(); + + // crypt utils + bind(ServiceIdentifiers.ICryptUtils) + .to(CryptUtils) + .inSingletonScope(); + + // escape sequence encoder + bind(ServiceIdentifiers.IEscapeSequenceEncoder) + .to(EscapeSequenceEncoder) + .inSingletonScope(); +}); diff --git a/src/custom-nodes/AbstractCustomNodeGroup.ts b/src/custom-nodes/AbstractCustomNodeGroup.ts index 0231dc83..0ee9b390 100644 --- a/src/custom-nodes/AbstractCustomNodeGroup.ts +++ b/src/custom-nodes/AbstractCustomNodeGroup.ts @@ -6,6 +6,7 @@ import { TNodeWithBlockStatement } from '../types/node/TNodeWithBlockStatement'; import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; import { ICustomNodeGroup } from '../interfaces/custom-nodes/ICustomNodeGroup'; import { IOptions } from '../interfaces/options/IOptions'; +import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator'; import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData'; import { CustomNode } from '../enums/container/custom-nodes/CustomNode'; @@ -34,11 +35,19 @@ export abstract class AbstractCustomNodeGroup implements ICustomNodeGroup { protected readonly options: IOptions; /** + * @type {IRandomGenerator} + */ + protected readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { + this.randomGenerator = randomGenerator; this.options = options; } @@ -77,4 +86,11 @@ export abstract class AbstractCustomNodeGroup implements ICustomNodeGroup { callback(customNode); } + + /** + * @param stackTraceLength + */ + protected getRandomStackTraceIndex (stackTraceLength: number): number { + return this.randomGenerator.getRandomInteger(0, Math.max(0, Math.round(stackTraceLength - 1))); + } } diff --git a/src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts b/src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts index a8c64cb5..e243afe7 100644 --- a/src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts +++ b/src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts @@ -6,6 +6,7 @@ import * as format from 'string-template'; import { TStatement } from '../../types/node/TStatement'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { ConsoleOutputDisableExpressionTemplate } from '../../templates/custom-nodes/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate'; @@ -13,7 +14,6 @@ import { initializable } from '../../decorators/Initializable'; import { AbstractCustomNode } from '../AbstractCustomNode'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode { @@ -24,12 +24,21 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode { private callsControllerFunctionName: string; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** @@ -51,7 +60,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode { */ protected getTemplate (): string { return format(ConsoleOutputDisableExpressionTemplate(), { - consoleLogDisableFunctionName: RandomGeneratorUtils.getRandomVariableName(6), + consoleLogDisableFunctionName: this.randomGenerator.getRandomVariableName(6), singleNodeCallControllerFunctionName: this.callsControllerFunctionName }); } diff --git a/src/custom-nodes/console-output-nodes/group/ConsoleOutputCustomNodeGroup.ts b/src/custom-nodes/console-output-nodes/group/ConsoleOutputCustomNodeGroup.ts index da1c4ca7..f121dd24 100644 --- a/src/custom-nodes/console-output-nodes/group/ConsoleOutputCustomNodeGroup.ts +++ b/src/custom-nodes/console-output-nodes/group/ConsoleOutputCustomNodeGroup.ts @@ -7,6 +7,7 @@ import { TNodeWithBlockStatement } from '../../../types/node/TNodeWithBlockState import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IObfuscationEventEmitter } from '../../../interfaces/event-emitters/IObfuscationEventEmitter'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData'; import { initializable } from '../../../decorators/Initializable'; @@ -16,7 +17,6 @@ import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup'; import { NodeAppender } from '../../../node/NodeAppender'; -import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils'; @injectable() export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup { @@ -44,14 +44,16 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup { /** * @param customNodeFactory * @param obfuscationEventEmitter + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.customNodeFactory = customNodeFactory; this.obfuscationEventEmitter = obfuscationEventEmitter; @@ -62,7 +64,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup { * @param stackTraceData */ public appendCustomNodes (blockScopeNode: TNodeWithBlockStatement, stackTraceData: IStackTraceData[]): void { - const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(stackTraceData.length); + const randomStackTraceIndex: number = this.getRandomStackTraceIndex(stackTraceData.length); // consoleOutputDisableExpressionNode append this.appendCustomNodeIfExist(CustomNode.ConsoleOutputDisableExpressionNode, (customNode: ICustomNode) => { @@ -95,7 +97,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup { return; } - const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6); + const callsControllerFunctionName: string = this.randomGenerator.getRandomVariableName(6); const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNode.ConsoleOutputDisableExpressionNode); const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode); diff --git a/src/custom-nodes/control-flow-flattening-nodes/BinaryExpressionFunctionNode.ts b/src/custom-nodes/control-flow-flattening-nodes/BinaryExpressionFunctionNode.ts index 3c0ac3b8..f44939e4 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/BinaryExpressionFunctionNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/BinaryExpressionFunctionNode.ts @@ -6,13 +6,13 @@ import { BinaryOperator } from 'estree'; import { TStatement } from '../../types/node/TStatement'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../decorators/Initializable'; import { AbstractCustomNode } from '../AbstractCustomNode'; import { Nodes } from '../../node/Nodes'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class BinaryExpressionFunctionNode extends AbstractCustomNode { @@ -23,12 +23,21 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode { private operator: BinaryOperator; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** @@ -43,7 +52,7 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode { */ protected getNodeStructure (): TStatement[] { const structure: TStatement = Nodes.getFunctionDeclarationNode( - RandomGeneratorUtils.getRandomString(3), + this.randomGenerator.getRandomString(3), [ Nodes.getIdentifierNode('x'), Nodes.getIdentifierNode('y') diff --git a/src/custom-nodes/control-flow-flattening-nodes/BlockStatementControlFlowFlatteningNode.ts b/src/custom-nodes/control-flow-flattening-nodes/BlockStatementControlFlowFlatteningNode.ts index 397f8e6e..7a55bc35 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/BlockStatementControlFlowFlatteningNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/BlockStatementControlFlowFlatteningNode.ts @@ -6,13 +6,13 @@ import * as ESTree from 'estree'; import { TStatement } from '../../types/node/TStatement'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../decorators/Initializable'; import { AbstractCustomNode } from '../AbstractCustomNode'; import { Nodes } from '../../node/Nodes'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode { @@ -28,6 +28,11 @@ export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode @initializable() private originalKeysIndexesInShuffledArray: number[]; + /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + /** * @type {number[]} */ @@ -35,12 +40,16 @@ export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode private shuffledKeys: number[]; /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /*** @@ -62,8 +71,8 @@ export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode * @returns {TStatement[]} */ protected getNodeStructure (): TStatement[] { - const controllerIdentifierName: string = RandomGeneratorUtils.getRandomString(3); - const indexIdentifierName: string = RandomGeneratorUtils.getRandomString(3); + const controllerIdentifierName: string = this.randomGenerator.getRandomString(3); + const indexIdentifierName: string = this.randomGenerator.getRandomString(3); const structure: ESTree.BlockStatement = Nodes.getBlockStatementNode([ Nodes.getVariableDeclarationNode([ Nodes.getVariableDeclaratorNode( diff --git a/src/custom-nodes/control-flow-flattening-nodes/CallExpressionFunctionNode.ts b/src/custom-nodes/control-flow-flattening-nodes/CallExpressionFunctionNode.ts index a2f8f6e0..ae16e38b 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/CallExpressionFunctionNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/CallExpressionFunctionNode.ts @@ -6,13 +6,13 @@ import * as ESTree from 'estree'; import { TStatement } from '../../types/node/TStatement'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../decorators/Initializable'; import { AbstractCustomNode } from '../AbstractCustomNode'; import { Nodes } from '../../node/Nodes'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class CallExpressionFunctionNode extends AbstractCustomNode { @@ -23,12 +23,21 @@ export class CallExpressionFunctionNode extends AbstractCustomNode { private expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[]; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** @@ -51,7 +60,7 @@ export class CallExpressionFunctionNode extends AbstractCustomNode { } const structure: TStatement = Nodes.getFunctionDeclarationNode( - RandomGeneratorUtils.getRandomString(3), + this.randomGenerator.getRandomString(3), [ calleeIdentifier, ...params diff --git a/src/custom-nodes/control-flow-flattening-nodes/LogicalExpressionFunctionNode.ts b/src/custom-nodes/control-flow-flattening-nodes/LogicalExpressionFunctionNode.ts index b8388d89..47c116ca 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/LogicalExpressionFunctionNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/LogicalExpressionFunctionNode.ts @@ -6,12 +6,12 @@ import { LogicalOperator } from 'estree'; import { TStatement } from '../../types/node/TStatement'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../decorators/Initializable'; import { AbstractCustomNode } from '../AbstractCustomNode'; import { Nodes } from '../../node/Nodes'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; import { NodeUtils } from '../../node/NodeUtils'; @injectable() @@ -23,12 +23,21 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode { private operator: LogicalOperator; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** @@ -43,7 +52,7 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode { */ protected getNodeStructure (): TStatement[] { const structure: TStatement = Nodes.getFunctionDeclarationNode( - RandomGeneratorUtils.getRandomString(3), + this.randomGenerator.getRandomString(3), [ Nodes.getIdentifierNode('x'), Nodes.getIdentifierNode('y') diff --git a/src/custom-nodes/control-flow-flattening-nodes/StringLiteralNode.ts b/src/custom-nodes/control-flow-flattening-nodes/StringLiteralNode.ts index e6541dc9..768efeca 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/StringLiteralNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/StringLiteralNode.ts @@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; import { TStatement } from '../../types/node/TStatement'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../decorators/Initializable'; @@ -19,12 +20,21 @@ export class StringLiteralNode extends AbstractCustomNode { private literalValue: string; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** diff --git a/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/CallExpressionControlFlowStorageCallNode.ts b/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/CallExpressionControlFlowStorageCallNode.ts index 177804c1..ee8c2f5c 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/CallExpressionControlFlowStorageCallNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/CallExpressionControlFlowStorageCallNode.ts @@ -7,6 +7,7 @@ import { Expression } from 'estree'; import { TStatement } from '../../../types/node/TStatement'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from "../../../interfaces/utils/IRandomGenerator"; import { initializable } from '../../../decorators/Initializable'; @@ -41,12 +42,21 @@ export class CallExpressionControlFlowStorageCallNode extends AbstractCustomNode private expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[]; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** diff --git a/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts b/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts index 26b9fcd3..8b1d84c7 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts @@ -7,6 +7,7 @@ import { TStatement } from '../../../types/node/TStatement'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../interfaces/storages/IStorage'; import { initializable } from '../../../decorators/Initializable'; @@ -24,12 +25,21 @@ export class ControlFlowStorageNode extends AbstractCustomNode { private controlFlowStorage: IStorage ; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** diff --git a/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode.ts b/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode.ts index 8481e923..eb0896b9 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode.ts @@ -6,6 +6,7 @@ import { Expression } from 'estree'; import { TStatement } from '../../../types/node/TStatement'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../../decorators/Initializable'; @@ -33,6 +34,11 @@ export class ExpressionWithOperatorControlFlowStorageCallNode extends AbstractCu @initializable() private leftValue: Expression; + /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + /** * @type {ESTree.Expression} */ @@ -40,12 +46,16 @@ export class ExpressionWithOperatorControlFlowStorageCallNode extends AbstractCu private rightValue: Expression; /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** diff --git a/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/StringLiteralControlFlowStorageCallNode.ts b/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/StringLiteralControlFlowStorageCallNode.ts index 78155df9..27708896 100644 --- a/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/StringLiteralControlFlowStorageCallNode.ts +++ b/src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/StringLiteralControlFlowStorageCallNode.ts @@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; import { TStatement } from '../../../types/node/TStatement'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../../decorators/Initializable'; @@ -26,12 +27,21 @@ export class StringLiteralControlFlowStorageCallNode extends AbstractCustomNode private controlFlowStorageName: string; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** diff --git a/src/custom-nodes/debug-protection-nodes/group/DebugProtectionCustomNodeGroup.ts b/src/custom-nodes/debug-protection-nodes/group/DebugProtectionCustomNodeGroup.ts index c532b3ab..101ece59 100644 --- a/src/custom-nodes/debug-protection-nodes/group/DebugProtectionCustomNodeGroup.ts +++ b/src/custom-nodes/debug-protection-nodes/group/DebugProtectionCustomNodeGroup.ts @@ -7,6 +7,7 @@ import { TNodeWithBlockStatement } from '../../../types/node/TNodeWithBlockState import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IObfuscationEventEmitter } from '../../../interfaces/event-emitters/IObfuscationEventEmitter'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData'; import { initializable } from '../../../decorators/Initializable'; @@ -16,7 +17,6 @@ import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup'; import { NodeAppender } from '../../../node/NodeAppender'; -import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils'; @injectable() export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup { @@ -44,14 +44,16 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup { /** * @param customNodeFactory * @param obfuscationEventEmitter + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.customNodeFactory = customNodeFactory; this.obfuscationEventEmitter = obfuscationEventEmitter; @@ -75,7 +77,7 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup { // debugProtectionFunctionIntervalNode append this.appendCustomNodeIfExist(CustomNode.DebugProtectionFunctionIntervalNode, (customNode: ICustomNode) => { const programBodyLength: number = blockScopeNode.body.length; - const randomIndex: number = RandomGeneratorUtils.getRandomInteger(0, programBodyLength); + const randomIndex: number = this.randomGenerator.getRandomInteger(0, programBodyLength); NodeAppender.insertNodeAtIndex(blockScopeNode, customNode.getNode(), randomIndex); }); @@ -88,7 +90,7 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup { return; } - const debugProtectionFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6); + const debugProtectionFunctionName: string = this.randomGenerator.getRandomVariableName(6); const debugProtectionFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.DebugProtectionFunctionNode); const debugProtectionFunctionCallNode: ICustomNode = this.customNodeFactory(CustomNode.DebugProtectionFunctionCallNode); diff --git a/src/custom-nodes/domain-lock-nodes/DomainLockNode.ts b/src/custom-nodes/domain-lock-nodes/DomainLockNode.ts index 90a771aa..6c27c9ec 100644 --- a/src/custom-nodes/domain-lock-nodes/DomainLockNode.ts +++ b/src/custom-nodes/domain-lock-nodes/DomainLockNode.ts @@ -5,16 +5,16 @@ import * as format from 'string-template'; import { TStatement } from '../../types/node/TStatement'; +import { ICryptUtils } from '../../interfaces/utils/ICryptUtils'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../decorators/Initializable'; import { DomainLockNodeTemplate } from '../../templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate'; import { AbstractCustomNode } from '../AbstractCustomNode'; -import { CryptUtils } from '../../utils/CryptUtils'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class DomainLockNode extends AbstractCustomNode { @@ -25,12 +25,29 @@ export class DomainLockNode extends AbstractCustomNode { protected callsControllerFunctionName: string; /** + * @type {ICryptUtils} + */ + private readonly cryptUtils: ICryptUtils; + + /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator + * @param cryptUtils * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, + @inject(ServiceIdentifiers.ICryptUtils) cryptUtils: ICryptUtils, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; + this.cryptUtils = cryptUtils; } /** @@ -52,10 +69,13 @@ export class DomainLockNode extends AbstractCustomNode { */ protected getTemplate (): string { const domainsString: string = this.options.domainLock.join(';'); - const [hiddenDomainsString, diff]: string[] = CryptUtils.hideString(domainsString, domainsString.length * 3); + const [hiddenDomainsString, diff]: string[] = this.cryptUtils.hideString( + domainsString, + domainsString.length * 3 + ); return format(DomainLockNodeTemplate(), { - domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(6), + domainLockFunctionName: this.randomGenerator.getRandomVariableName(6), diff: diff, domains: hiddenDomainsString, singleNodeCallControllerFunctionName: this.callsControllerFunctionName diff --git a/src/custom-nodes/domain-lock-nodes/group/DomainLockCustomNodeGroup.ts b/src/custom-nodes/domain-lock-nodes/group/DomainLockCustomNodeGroup.ts index 36179cfd..243a541d 100644 --- a/src/custom-nodes/domain-lock-nodes/group/DomainLockCustomNodeGroup.ts +++ b/src/custom-nodes/domain-lock-nodes/group/DomainLockCustomNodeGroup.ts @@ -7,6 +7,7 @@ import { TNodeWithBlockStatement } from '../../../types/node/TNodeWithBlockState import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IObfuscationEventEmitter } from '../../../interfaces/event-emitters/IObfuscationEventEmitter'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData'; import { initializable } from '../../../decorators/Initializable'; @@ -16,7 +17,6 @@ import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup'; import { NodeAppender } from '../../../node/NodeAppender'; -import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils'; @injectable() export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup { @@ -44,14 +44,16 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup { /** * @param customNodeFactory * @param obfuscationEventEmitter + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.customNodeFactory = customNodeFactory; this.obfuscationEventEmitter = obfuscationEventEmitter; @@ -62,7 +64,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup { * @param stackTraceData */ public appendCustomNodes (blockScopeNode: TNodeWithBlockStatement, stackTraceData: IStackTraceData[]): void { - const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(stackTraceData.length); + const randomStackTraceIndex: number = this.getRandomStackTraceIndex(stackTraceData.length); // domainLockNode append this.appendCustomNodeIfExist(CustomNode.DomainLockNode, (customNode: ICustomNode) => { @@ -95,7 +97,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup { return; } - const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6); + const callsControllerFunctionName: string = this.randomGenerator.getRandomVariableName(6); const domainLockNode: ICustomNode = this.customNodeFactory(CustomNode.DomainLockNode); const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode); diff --git a/src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts b/src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts index 9d9e9734..8fb13067 100644 --- a/src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts +++ b/src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts @@ -5,7 +5,9 @@ import * as format from 'string-template'; import { TStatement } from '../../types/node/TStatement'; +import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { initializable } from '../../decorators/Initializable'; @@ -16,23 +18,39 @@ import { SelfDefendingTemplate } from '../../templates/custom-nodes/self-defendi import { AbstractCustomNode } from '../AbstractCustomNode'; import { JavaScriptObfuscator } from '../../JavaScriptObfuscator'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class SelfDefendingUnicodeNode extends AbstractCustomNode { + /** + * @type {IEscapeSequenceEncoder} + */ + private readonly escapeSequenceEncoder: IEscapeSequenceEncoder; + /** * @type {string} */ @initializable() - protected callsControllerFunctionName: string; + private callsControllerFunctionName: string; /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator + * @param escapeSequenceEncoder * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, + @inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; + this.escapeSequenceEncoder = escapeSequenceEncoder; } /** @@ -54,8 +72,8 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode { */ protected getTemplate (): string { return JavaScriptObfuscator.obfuscate( - format(SelfDefendingTemplate(), { - selfDefendingFunctionName: RandomGeneratorUtils.getRandomVariableName(6), + format(SelfDefendingTemplate(this.escapeSequenceEncoder), { + selfDefendingFunctionName: this.randomGenerator.getRandomVariableName(6), singleNodeCallControllerFunctionName: this.callsControllerFunctionName }), { diff --git a/src/custom-nodes/self-defending-nodes/group/SelfDefendingCustomNodeGroup.ts b/src/custom-nodes/self-defending-nodes/group/SelfDefendingCustomNodeGroup.ts index 369f3523..067166d8 100644 --- a/src/custom-nodes/self-defending-nodes/group/SelfDefendingCustomNodeGroup.ts +++ b/src/custom-nodes/self-defending-nodes/group/SelfDefendingCustomNodeGroup.ts @@ -7,6 +7,7 @@ import { TNodeWithBlockStatement } from '../../../types/node/TNodeWithBlockState import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IObfuscationEventEmitter } from '../../../interfaces/event-emitters/IObfuscationEventEmitter'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData'; import { initializable } from '../../../decorators/Initializable'; @@ -16,7 +17,6 @@ import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup'; import { NodeAppender } from '../../../node/NodeAppender'; -import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils'; @injectable() export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup { @@ -44,14 +44,16 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup { /** * @param customNodeFactory * @param obfuscationEventEmitter + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.customNodeFactory = customNodeFactory; this.obfuscationEventEmitter = obfuscationEventEmitter; @@ -62,7 +64,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup { * @param stackTraceData */ public appendCustomNodes (blockScopeNode: TNodeWithBlockStatement, stackTraceData: IStackTraceData[]): void { - const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(stackTraceData.length); + const randomStackTraceIndex: number = this.getRandomStackTraceIndex(stackTraceData.length); // selfDefendingUnicodeNode append this.appendCustomNodeIfExist(CustomNode.SelfDefendingUnicodeNode, (customNode: ICustomNode) => { @@ -95,7 +97,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup { return; } - const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6); + const callsControllerFunctionName: string = this.randomGenerator.getRandomVariableName(6); const selfDefendingUnicodeNode: ICustomNode = this.customNodeFactory(CustomNode.SelfDefendingUnicodeNode); const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode); diff --git a/src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts b/src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts index cb2aefe6..70778d84 100644 --- a/src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts +++ b/src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts @@ -5,6 +5,7 @@ import * as format from 'string-template'; import { TStatement } from '../../types/node/TStatement'; +import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder'; import { IOptions } from '../../interfaces/options/IOptions'; import { IStorage } from '../../interfaces/storages/IStorage'; @@ -27,6 +28,11 @@ import { NodeUtils } from '../../node/NodeUtils'; @injectable() export class StringArrayCallsWrapper extends AbstractCustomNode { + /** + * @type {IEscapeSequenceEncoder} + */ + private readonly escapeSequenceEncoder: IEscapeSequenceEncoder; + /** * @type {IStorage } */ @@ -46,12 +52,16 @@ export class StringArrayCallsWrapper extends AbstractCustomNode { private stringArrayCallsWrapperName: string; /** + * @param escapeSequenceEncoder * @param options */ constructor ( + @inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.escapeSequenceEncoder = escapeSequenceEncoder; } /** @@ -103,7 +113,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode { selfDefendingCode: string = ''; if (this.options.selfDefending) { - selfDefendingCode = format(SelfDefendingTemplate(), { + selfDefendingCode = format(SelfDefendingTemplate(this.escapeSequenceEncoder), { stringArrayCallsWrapperName: this.stringArrayCallsWrapperName, stringArrayName: this.stringArrayName }); diff --git a/src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts b/src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts index d3579907..9f340e7d 100644 --- a/src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts +++ b/src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts @@ -5,7 +5,9 @@ import * as format from 'string-template'; import { TStatement } from '../../types/node/TStatement'; +import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../interfaces/storages/IStorage'; import { initializable } from '../../decorators/Initializable'; @@ -18,11 +20,20 @@ import { StringArrayRotateFunctionTemplate } from '../../templates/custom-nodes/ import { AbstractCustomNode } from '../AbstractCustomNode'; import { JavaScriptObfuscator } from '../../JavaScriptObfuscator'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; import { Utils } from '../../utils/Utils'; @injectable() export class StringArrayRotateFunctionNode extends AbstractCustomNode { + /** + * @type {IEscapeSequenceEncoder} + */ + private readonly escapeSequenceEncoder: IEscapeSequenceEncoder; + + /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + /** * @type {IStorage } */ @@ -42,12 +53,19 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode { private stringArrayRotateValue: number; /** + * @param randomGenerator + * @param escapeSequenceEncoder * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, + @inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; + this.escapeSequenceEncoder = escapeSequenceEncoder; } /** @@ -76,13 +94,13 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode { * @returns {string} */ protected getTemplate (): string { - const timesName: string = RandomGeneratorUtils.getRandomVariableName(6); - const whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6); + const timesName: string = this.randomGenerator.getRandomVariableName(6); + const whileFunctionName: string = this.randomGenerator.getRandomVariableName(6); let code: string = ''; if (this.options.selfDefending) { - code = format(SelfDefendingTemplate(), { + code = format(SelfDefendingTemplate(this.escapeSequenceEncoder), { timesName, whileFunctionName }); diff --git a/src/custom-nodes/string-array-nodes/group/StringArrayCustomNodeGroup.ts b/src/custom-nodes/string-array-nodes/group/StringArrayCustomNodeGroup.ts index 63d3fecd..e9163fd6 100644 --- a/src/custom-nodes/string-array-nodes/group/StringArrayCustomNodeGroup.ts +++ b/src/custom-nodes/string-array-nodes/group/StringArrayCustomNodeGroup.ts @@ -7,6 +7,7 @@ import { TNodeWithBlockStatement } from '../../../types/node/TNodeWithBlockState import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IObfuscationEventEmitter } from '../../../interfaces/event-emitters/IObfuscationEventEmitter'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData'; import { IStorage } from '../../../interfaces/storages/IStorage'; @@ -17,7 +18,6 @@ import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup'; import { NodeAppender } from '../../../node/NodeAppender'; -import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils'; import { Utils } from '../../../utils/Utils'; @injectable() @@ -52,16 +52,18 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup { /** * @param customNodeFactory * @param obfuscationEventEmitter + * @param randomGenerator * @param stringArrayStorage * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: IStorage, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.customNodeFactory = customNodeFactory; this.obfuscationEventEmitter = obfuscationEventEmitter; @@ -112,7 +114,7 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup { let stringArrayRotateValue: number; if (this.options.rotateStringArray) { - stringArrayRotateValue = RandomGeneratorUtils.getRandomInteger(100, 500); + stringArrayRotateValue = this.randomGenerator.getRandomInteger(100, 500); } else { stringArrayRotateValue = 0; } diff --git a/src/enums/container/custom-nodes/ControlFlowCustomNode.ts b/src/enums/container/custom-nodes/ControlFlowCustomNode.ts new file mode 100644 index 00000000..b2918756 --- /dev/null +++ b/src/enums/container/custom-nodes/ControlFlowCustomNode.ts @@ -0,0 +1,11 @@ +export enum ControlFlowCustomNode { + BinaryExpressionFunctionNode, + BlockStatementControlFlowFlatteningNode, + CallExpressionControlFlowStorageCallNode, + CallExpressionFunctionNode, + ControlFlowStorageNode, + ExpressionWithOperatorControlFlowStorageCallNode, + LogicalExpressionFunctionNode, + StringLiteralControlFlowStorageCallNode, + StringLiteralNode, +} diff --git a/src/enums/container/custom-nodes/CustomNode.ts b/src/enums/container/custom-nodes/CustomNode.ts index 744b191c..340cd8f1 100644 --- a/src/enums/container/custom-nodes/CustomNode.ts +++ b/src/enums/container/custom-nodes/CustomNode.ts @@ -1,21 +1,12 @@ export enum CustomNode { - BinaryExpressionFunctionNode, - BlockStatementControlFlowFlatteningNode, - CallExpressionControlFlowStorageCallNode, - CallExpressionFunctionNode, - ControlFlowStorageNode, ConsoleOutputDisableExpressionNode, DebugProtectionFunctionCallNode, DebugProtectionFunctionIntervalNode, DebugProtectionFunctionNode, DomainLockNode, - ExpressionWithOperatorControlFlowStorageCallNode, - LogicalExpressionFunctionNode, NodeCallsControllerFunctionNode, SelfDefendingUnicodeNode, StringArrayCallsWrapper, StringArrayNode, - StringArrayRotateFunctionNode, - StringLiteralControlFlowStorageCallNode, - StringLiteralNode, + StringArrayRotateFunctionNode } diff --git a/src/interfaces/container/IInversifyContainerFacade.d.ts b/src/interfaces/container/IInversifyContainerFacade.d.ts index f8e4b151..9f0c99a0 100644 --- a/src/interfaces/container/IInversifyContainerFacade.d.ts +++ b/src/interfaces/container/IInversifyContainerFacade.d.ts @@ -1,5 +1,7 @@ import { interfaces } from 'inversify'; +import { TInputOptions } from '../../types/options/TInputOptions'; + export interface IInversifyContainerFacade { /** * @param serviceIdentifier @@ -11,4 +13,11 @@ export interface IInversifyContainerFacade { * @param named */ getNamed (serviceIdentifier: interfaces.ServiceIdentifier, named: string | number | symbol): T; + + /** + * @param options + */ + load (options: TInputOptions): void; + + unload (): void; } diff --git a/src/interfaces/utils/IArrayUtils.d.ts b/src/interfaces/utils/IArrayUtils.d.ts new file mode 100644 index 00000000..92045862 --- /dev/null +++ b/src/interfaces/utils/IArrayUtils.d.ts @@ -0,0 +1,20 @@ +export interface IArrayUtils { + /** + * @param length + * @return {number[]} + */ + arrayRange (length: number): number[]; + + /** + * @param array + * @param times + * @returns {T[]} + */ + arrayRotate (array: T[], times: number): T[]; + + /** + * @param array + * @return {T[]} + */ + arrayShuffle (array: T[]): T[]; +} diff --git a/src/interfaces/utils/ICryptUtils.d.ts b/src/interfaces/utils/ICryptUtils.d.ts new file mode 100644 index 00000000..5973bfb3 --- /dev/null +++ b/src/interfaces/utils/ICryptUtils.d.ts @@ -0,0 +1,21 @@ +export interface ICryptUtils { + /** + * @param string + */ + btoa (string: string): string; + + /** + * @param str + * @param length + * @returns {[string, string]} + */ + hideString (str: string, length: number): [string, string]; + + /** + * @param key + * @param string + * @returns {string} + */ + /* tslint:disable */ + rc4 (string: string, key: string): string; +} diff --git a/src/interfaces/utils/IEscapeSequenceEncoder.d.ts b/src/interfaces/utils/IEscapeSequenceEncoder.d.ts new file mode 100644 index 00000000..171c5f28 --- /dev/null +++ b/src/interfaces/utils/IEscapeSequenceEncoder.d.ts @@ -0,0 +1,7 @@ +export interface IEscapeSequenceEncoder { + /** + * @param string + * @param usingUnicodeEscapeSequence + */ + encode (string: string, usingUnicodeEscapeSequence: boolean): string; +} \ No newline at end of file diff --git a/src/interfaces/utils/IRandomGenerator.d.ts b/src/interfaces/utils/IRandomGenerator.d.ts new file mode 100644 index 00000000..77484041 --- /dev/null +++ b/src/interfaces/utils/IRandomGenerator.d.ts @@ -0,0 +1,40 @@ +import { Chance } from 'chance'; + +export interface IRandomGenerator { + /** + * @returns {number} + */ + getMathRandom (): number; + + /** + * @param min + * @param max + * @returns {number} + */ + getRandomFloat (min: number, max: number): number; + + /** + * @returns {Chance.Chance} + */ + getRandomGenerator (): Chance.Chance; + + /** + * @param min + * @param max + * @returns {number} + */ + getRandomInteger (min: number, max: number): number; + + /** + * @param length + * @param pool + * @returns {string} + */ + getRandomString (length: number, pool?: string): string; + + /** + * @param length + * @returns {string} + */ + getRandomVariableName (length: number): string +} diff --git a/src/node-transformers/AbstractNodeTransformer.ts b/src/node-transformers/AbstractNodeTransformer.ts index 885f78b5..fcb04ef1 100644 --- a/src/node-transformers/AbstractNodeTransformer.ts +++ b/src/node-transformers/AbstractNodeTransformer.ts @@ -5,16 +5,15 @@ import * as ESTree from 'estree'; import { INodeTransformer } from '../interfaces/node-transformers/INodeTransformer'; import { IOptions } from '../interfaces/options/IOptions'; +import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../interfaces/IVisitor'; -import { RandomGeneratorUtils } from '../utils/RandomGeneratorUtils'; - @injectable() export abstract class AbstractNodeTransformer implements INodeTransformer { /** * @type {number} */ - protected nodeIdentifier: number = RandomGeneratorUtils.getRandomInteger(0, 10000); + protected nodeIdentifier: number; /** * @type {IOptions} @@ -22,12 +21,22 @@ export abstract class AbstractNodeTransformer implements INodeTransformer { protected readonly options: IOptions; /** + * @type {IRandomGenerator} + */ + protected readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { + this.randomGenerator = randomGenerator; this.options = options; + + this.nodeIdentifier = this.randomGenerator.getRandomInteger(0, 10000); } /** diff --git a/src/node-transformers/control-flow-transformers/BlockStatementControlFlowTransformer.ts b/src/node-transformers/control-flow-transformers/BlockStatementControlFlowTransformer.ts index ed607738..447794fe 100644 --- a/src/node-transformers/control-flow-transformers/BlockStatementControlFlowTransformer.ts +++ b/src/node-transformers/control-flow-transformers/BlockStatementControlFlowTransformer.ts @@ -3,37 +3,48 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; -import { TCustomNodeFactory } from '../../types/container/custom-nodes/TCustomNodeFactory'; +import { TControlFlowCustomNodeFactory } from '../../types/container/custom-nodes/TControlFlowCustomNodeFactory'; +import { IArrayUtils } from '../../interfaces/utils/IArrayUtils'; import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; -import { CustomNode } from '../../enums/container/custom-nodes/CustomNode'; +import { ControlFlowCustomNode } from '../../enums/container/custom-nodes/ControlFlowCustomNode'; import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; import { Node } from '../../node/Node'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; -import { Utils } from '../../utils/Utils'; @injectable() export class BlockStatementControlFlowTransformer extends AbstractNodeTransformer { /** - * @type {TCustomNodeFactory} + * @type {IArrayUtils} */ - private readonly customNodeFactory: TCustomNodeFactory; + private readonly arrayUtils: IArrayUtils; /** - * @param customNodeFactory + * @type {TControlFlowCustomNodeFactory} + */ + private readonly controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory; + + /** + * @param controlFlowCustomNodeFactory + * @param arrayUtils + * @param randomGenerator * @param options */ constructor ( - @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode) + controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory, + @inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); - this.customNodeFactory = customNodeFactory; + this.controlFlowCustomNodeFactory = controlFlowCustomNodeFactory; + this.arrayUtils = arrayUtils; } /** @@ -70,7 +81,7 @@ export class BlockStatementControlFlowTransformer extends AbstractNodeTransforme */ public transformNode (blockStatementNode: ESTree.BlockStatement, parentNode: ESTree.Node): ESTree.Node { if ( - RandomGeneratorUtils.getMathRandom() > this.options.controlFlowFlatteningThreshold || + this.randomGenerator.getMathRandom() > this.options.controlFlowFlatteningThreshold || BlockStatementControlFlowTransformer.blockStatementHasProhibitedStatements(blockStatementNode) ) { return blockStatementNode; @@ -82,11 +93,11 @@ export class BlockStatementControlFlowTransformer extends AbstractNodeTransforme return blockStatementNode; } - const originalKeys: number[] = Utils.arrayRange(blockStatementBody.length); - const shuffledKeys: number[] = Utils.arrayShuffle(originalKeys); + const originalKeys: number[] = this.arrayUtils.arrayRange(blockStatementBody.length); + const shuffledKeys: number[] = this.arrayUtils.arrayShuffle(originalKeys); const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key)); - const blockStatementControlFlowFlatteningCustomNode: ICustomNode = this.customNodeFactory( - CustomNode.BlockStatementControlFlowFlatteningNode + const blockStatementControlFlowFlatteningCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.BlockStatementControlFlowFlatteningNode ); blockStatementControlFlowFlatteningCustomNode.initialize( diff --git a/src/node-transformers/control-flow-transformers/FunctionControlFlowTransformer.ts b/src/node-transformers/control-flow-transformers/FunctionControlFlowTransformer.ts index 5463f831..c3df7459 100644 --- a/src/node-transformers/control-flow-transformers/FunctionControlFlowTransformer.ts +++ b/src/node-transformers/control-flow-transformers/FunctionControlFlowTransformer.ts @@ -4,17 +4,18 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; +import { TControlFlowCustomNodeFactory } from '../../types/container/custom-nodes/TControlFlowCustomNodeFactory'; import { TControlFlowReplacerFactory } from '../../types/container/node-transformers/TControlFlowReplacerFactory'; import { TControlFlowStorageFactory } from '../../types/container/node-transformers/TControlFlowStorageFactory'; -import { TCustomNodeFactory } from '../../types/container/custom-nodes/TCustomNodeFactory'; import { TNodeWithBlockStatement } from '../../types/node/TNodeWithBlockStatement'; import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../interfaces/storages/IStorage'; import { IVisitor } from '../../interfaces/IVisitor'; -import { CustomNode } from '../../enums/container/custom-nodes/CustomNode'; +import { ControlFlowCustomNode } from '../../enums/container/custom-nodes/ControlFlowCustomNode'; import { NodeType } from '../../enums/NodeType'; import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; @@ -22,7 +23,6 @@ import { Node } from '../../node/Node'; import { NodeAppender } from '../../node/NodeAppender'; import { ControlFlowReplacer } from '../../enums/container/node-transformers/ControlFlowReplacer'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class FunctionControlFlowTransformer extends AbstractNodeTransformer { @@ -72,51 +72,32 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer { private readonly controlFlowStorageFactory: TControlFlowStorageFactory; /** - * @type {TCustomNodeFactory} + * @type {TControlFlowCustomNodeFactory} */ - private readonly customNodeFactory: TCustomNodeFactory; + private readonly controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory; /** * @param controlFlowStorageFactory * @param controlFlowReplacerFactory - * @param customNodeFactory + * @param controlFlowCustomNodeFactory + * @param randomGenerator * @param options */ constructor ( - @inject(ServiceIdentifiers.Factory__TControlFlowStorage) controlFlowStorageFactory: TControlFlowStorageFactory, - @inject(ServiceIdentifiers.Factory__IControlFlowReplacer) controlFlowReplacerFactory: TControlFlowReplacerFactory, - @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, + @inject(ServiceIdentifiers.Factory__TControlFlowStorage) + controlFlowStorageFactory: TControlFlowStorageFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowReplacer) + controlFlowReplacerFactory: TControlFlowReplacerFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode) + controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.controlFlowStorageFactory = controlFlowStorageFactory; this.controlFlowReplacerFactory = controlFlowReplacerFactory; - this.customNodeFactory = customNodeFactory; - } - - /** - * @param functionNodeBody - * @returns {TNodeWithBlockStatement} - */ - private static getHostNode (functionNodeBody: ESTree.BlockStatement): TNodeWithBlockStatement { - const blockScopesOfNode: TNodeWithBlockStatement[] = NodeUtils.getBlockScopesOfNode(functionNodeBody); - - if (blockScopesOfNode.length === 1) { - return functionNodeBody; - } else { - blockScopesOfNode.pop(); - } - - if (blockScopesOfNode.length > FunctionControlFlowTransformer.hostNodeSearchMinDepth) { - blockScopesOfNode.splice(0, FunctionControlFlowTransformer.hostNodeSearchMinDepth); - } - - if (blockScopesOfNode.length > FunctionControlFlowTransformer.hostNodeSearchMaxDepth) { - blockScopesOfNode.length = FunctionControlFlowTransformer.hostNodeSearchMaxDepth; - } - - return RandomGeneratorUtils.getRandomGenerator().pickone(blockScopesOfNode); + this.controlFlowCustomNodeFactory = controlFlowCustomNodeFactory; } /** @@ -148,7 +129,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer { return functionNode; } - const hostNode: TNodeWithBlockStatement = FunctionControlFlowTransformer.getHostNode(functionNode.body); + const hostNode: TNodeWithBlockStatement = this.getHostNode(functionNode.body); const controlFlowStorage: IStorage = this.getControlFlowStorage(hostNode); this.controlFlowData.set(hostNode, controlFlowStorage); @@ -158,7 +139,9 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer { return functionNode; } - const controlFlowStorageCustomNode: ICustomNode = this.customNodeFactory(CustomNode.ControlFlowStorageNode); + const controlFlowStorageCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.ControlFlowStorageNode + ); controlFlowStorageCustomNode.initialize(controlFlowStorage); NodeAppender.prependNode(hostNode, controlFlowStorageCustomNode.getNode()); @@ -187,6 +170,30 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer { return controlFlowStorage; } + /** + * @param functionNodeBody + * @returns {TNodeWithBlockStatement} + */ + private getHostNode (functionNodeBody: ESTree.BlockStatement): TNodeWithBlockStatement { + const blockScopesOfNode: TNodeWithBlockStatement[] = NodeUtils.getBlockScopesOfNode(functionNodeBody); + + if (blockScopesOfNode.length === 1) { + return functionNodeBody; + } else { + blockScopesOfNode.pop(); + } + + if (blockScopesOfNode.length > FunctionControlFlowTransformer.hostNodeSearchMinDepth) { + blockScopesOfNode.splice(0, FunctionControlFlowTransformer.hostNodeSearchMinDepth); + } + + if (blockScopesOfNode.length > FunctionControlFlowTransformer.hostNodeSearchMaxDepth) { + blockScopesOfNode.length = FunctionControlFlowTransformer.hostNodeSearchMaxDepth; + } + + return this.randomGenerator.getRandomGenerator().pickone(blockScopesOfNode); + } + /** * @param node * @return {boolean} @@ -214,7 +221,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer { return node; } - if (RandomGeneratorUtils.getMathRandom() > this.options.controlFlowFlatteningThreshold) { + if (this.randomGenerator.getMathRandom() > this.options.controlFlowFlatteningThreshold) { return node; } diff --git a/src/node-transformers/control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts b/src/node-transformers/control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts index 3aeddee9..854c4261 100644 --- a/src/node-transformers/control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts +++ b/src/node-transformers/control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts @@ -3,41 +3,49 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; -import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory'; +import { TControlFlowCustomNodeFactory } from '../../../types/container/custom-nodes/TControlFlowCustomNodeFactory'; import { IControlFlowReplacer } from '../../../interfaces/node-transformers/control-flow-transformers/IControlFlowReplacer'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../interfaces/storages/IStorage'; -import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils'; - @injectable() export abstract class AbstractControlFlowReplacer implements IControlFlowReplacer { /** - * @type {TCustomNodeFactory} + * @type {TControlFlowCustomNodeFactory} */ - protected readonly customNodeFactory: TCustomNodeFactory; + protected readonly controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory; /** * @type {IOptions} */ protected readonly options: IOptions; + /** + * @type {IRandomGenerator} + */ + protected readonly randomGenerator: IRandomGenerator; + /** * @type {Map>} */ protected readonly replacerDataByControlFlowStorageId: Map > = new Map(); /** - * @param customNodeFactory + * @param controlFlowCustomNodeFactory + * @param randomGenerator * @param options */ constructor ( - @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode) + controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - this.customNodeFactory = customNodeFactory; + this.controlFlowCustomNodeFactory = controlFlowCustomNodeFactory; + this.randomGenerator = randomGenerator; this.options = options; } @@ -88,15 +96,15 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace const storageKeysForCurrentId: string[] | undefined = storageKeysById.get(replacerId); if ( - RandomGeneratorUtils.getMathRandom() < usingExistingIdentifierChance && + this.randomGenerator.getMathRandom() < usingExistingIdentifierChance && storageKeysForCurrentId && storageKeysForCurrentId.length ) { - return RandomGeneratorUtils.getRandomGenerator().pickone(storageKeysForCurrentId); + return this.randomGenerator.getRandomGenerator().pickone(storageKeysForCurrentId); } const generateStorageKey: (length: number) => string = (length: number) => { - const storageKey: string = RandomGeneratorUtils.getRandomString(length); + const storageKey: string = this.randomGenerator.getRandomString(length); if (controlFlowStorage.getStorage().has(storageKey)) { return generateStorageKey(length); diff --git a/src/node-transformers/control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts b/src/node-transformers/control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts index 0ebb7303..01bb35c8 100644 --- a/src/node-transformers/control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts +++ b/src/node-transformers/control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts @@ -3,13 +3,14 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; -import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory'; +import { TControlFlowCustomNodeFactory } from '../../../types/container/custom-nodes/TControlFlowCustomNodeFactory'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../interfaces/storages/IStorage'; -import { CustomNode } from '../../../enums/container/custom-nodes/CustomNode'; +import { ControlFlowCustomNode } from '../../../enums/container/custom-nodes/ControlFlowCustomNode'; import { ExpressionWithOperatorControlFlowReplacer } from './ExpressionWithOperatorControlFlowReplacer'; @@ -21,14 +22,17 @@ export class BinaryExpressionControlFlowReplacer extends ExpressionWithOperatorC private static readonly usingExistingIdentifierChance: number = 0.5; /** - * @param customNodeFactory + * @param controlFlowCustomNodeFactory + * @param randomGenerator * @param options */ constructor ( - @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode) + controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(customNodeFactory, options); + super(controlFlowCustomNodeFactory, randomGenerator, options); } /** @@ -43,7 +47,9 @@ export class BinaryExpressionControlFlowReplacer extends ExpressionWithOperatorC controlFlowStorage: IStorage ): ESTree.Node { const replacerId: string = binaryExpressionNode.operator; - const binaryExpressionFunctionCustomNode: ICustomNode = this.customNodeFactory(CustomNode.BinaryExpressionFunctionNode); + const binaryExpressionFunctionCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.BinaryExpressionFunctionNode + ); binaryExpressionFunctionCustomNode.initialize(replacerId); diff --git a/src/node-transformers/control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer.ts b/src/node-transformers/control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer.ts index 2669862c..6be53e73 100644 --- a/src/node-transformers/control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer.ts +++ b/src/node-transformers/control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer.ts @@ -3,14 +3,15 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; -import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory'; +import { TControlFlowCustomNodeFactory } from '../../../types/container/custom-nodes/TControlFlowCustomNodeFactory'; import { TStatement } from '../../../types/node/TStatement'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../interfaces/storages/IStorage'; -import { CustomNode } from '../../../enums/container/custom-nodes/CustomNode'; +import { ControlFlowCustomNode } from '../../../enums/container/custom-nodes/ControlFlowCustomNode'; import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer'; import { Node } from '../../../node/Node'; @@ -23,14 +24,17 @@ export class CallExpressionControlFlowReplacer extends AbstractControlFlowReplac private static readonly usingExistingIdentifierChance: number = 0.5; /** - * @param customNodeFactory + * @param controlFlowCustomNodeFactory + * @param randomGenerator * @param options */ constructor ( - @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode) + controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(customNodeFactory, options); + super(controlFlowCustomNodeFactory, randomGenerator, options); } /** @@ -51,7 +55,9 @@ export class CallExpressionControlFlowReplacer extends AbstractControlFlowReplac } const replacerId: string = String(callExpressionNode.arguments.length); - const callExpressionFunctionCustomNode: ICustomNode = this.customNodeFactory(CustomNode.CallExpressionFunctionNode); + const callExpressionFunctionCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.CallExpressionFunctionNode + ); const expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[] = callExpressionNode.arguments; callExpressionFunctionCustomNode.initialize(expressionArguments); @@ -85,8 +91,8 @@ export class CallExpressionControlFlowReplacer extends AbstractControlFlowReplac callee: ESTree.Expression, expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[] ): ESTree.Node { - const controlFlowStorageCallCustomNode: ICustomNode = this.customNodeFactory( - CustomNode.CallExpressionControlFlowStorageCallNode + const controlFlowStorageCallCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.CallExpressionControlFlowStorageCallNode ); controlFlowStorageCallCustomNode.initialize(controlFlowStorageId, storageKey, callee, expressionArguments); diff --git a/src/node-transformers/control-flow-transformers/control-flow-replacers/ExpressionWithOperatorControlFlowReplacer.ts b/src/node-transformers/control-flow-transformers/control-flow-replacers/ExpressionWithOperatorControlFlowReplacer.ts index 54d2e99f..8a5a4094 100644 --- a/src/node-transformers/control-flow-transformers/control-flow-replacers/ExpressionWithOperatorControlFlowReplacer.ts +++ b/src/node-transformers/control-flow-transformers/control-flow-replacers/ExpressionWithOperatorControlFlowReplacer.ts @@ -3,23 +3,20 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; -import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory'; +import { TControlFlowCustomNodeFactory } from '../../../types/container/custom-nodes/TControlFlowCustomNodeFactory'; import { TStatement } from '../../../types/node/TStatement'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; + +import { ControlFlowCustomNode } from '../../../enums/container/custom-nodes/ControlFlowCustomNode'; import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer'; -import { CustomNode } from '../../../enums/container/custom-nodes/CustomNode'; import { Node } from '../../../node/Node'; @injectable() export abstract class ExpressionWithOperatorControlFlowReplacer extends AbstractControlFlowReplacer { - /** - * @type {TCustomNodeFactory} - */ - protected readonly customNodeFactory: TCustomNodeFactory; - /** * @type {IOptions} */ @@ -31,14 +28,17 @@ export abstract class ExpressionWithOperatorControlFlowReplacer extends Abstract protected readonly replacerDataByControlFlowStorageId: Map > = new Map(); /** - * @param customNodeFactory + * @param controlFlowCustomNodeFactory + * @param randomGenerator * @param options */ constructor ( - @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode) + controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(customNodeFactory, options); + super(controlFlowCustomNodeFactory, randomGenerator, options); } /** @@ -54,8 +54,8 @@ export abstract class ExpressionWithOperatorControlFlowReplacer extends Abstract leftExpression: ESTree.Expression, rightExpression: ESTree.Expression ): ESTree.Node { - const controlFlowStorageCallCustomNode: ICustomNode = this.customNodeFactory( - CustomNode.ExpressionWithOperatorControlFlowStorageCallNode + const controlFlowStorageCallCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.ExpressionWithOperatorControlFlowStorageCallNode ); controlFlowStorageCallCustomNode.initialize(controlFlowStorageId, storageKey, leftExpression, rightExpression); diff --git a/src/node-transformers/control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer.ts b/src/node-transformers/control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer.ts index 1b153b1e..34c716d0 100644 --- a/src/node-transformers/control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer.ts +++ b/src/node-transformers/control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer.ts @@ -3,13 +3,14 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; -import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory'; +import { TControlFlowCustomNodeFactory } from '../../../types/container/custom-nodes/TControlFlowCustomNodeFactory'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../interfaces/storages/IStorage'; -import { CustomNode } from '../../../enums/container/custom-nodes/CustomNode'; +import { ControlFlowCustomNode } from '../../../enums/container/custom-nodes/ControlFlowCustomNode'; import { ExpressionWithOperatorControlFlowReplacer } from './ExpressionWithOperatorControlFlowReplacer'; import { Node } from '../../../node/Node'; @@ -23,14 +24,17 @@ export class LogicalExpressionControlFlowReplacer extends ExpressionWithOperator private static readonly usingExistingIdentifierChance: number = 0.5; /** - * @param customNodeFactory + * @param controlFlowCustomNodeFactory + * @param randomGenerator * @param options */ constructor ( - @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode) + controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(customNodeFactory, options); + super(controlFlowCustomNodeFactory, randomGenerator, options); } /** @@ -49,7 +53,9 @@ export class LogicalExpressionControlFlowReplacer extends ExpressionWithOperator } const replacerId: string = logicalExpressionNode.operator; - const logicalExpressionFunctionCustomNode: ICustomNode = this.customNodeFactory(CustomNode.LogicalExpressionFunctionNode); + const logicalExpressionFunctionCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.LogicalExpressionFunctionNode + ); logicalExpressionFunctionCustomNode.initialize(replacerId); diff --git a/src/node-transformers/control-flow-transformers/control-flow-replacers/StringLiteralControlFlowReplacer.ts b/src/node-transformers/control-flow-transformers/control-flow-replacers/StringLiteralControlFlowReplacer.ts index 2eadab44..bb786958 100644 --- a/src/node-transformers/control-flow-transformers/control-flow-replacers/StringLiteralControlFlowReplacer.ts +++ b/src/node-transformers/control-flow-transformers/control-flow-replacers/StringLiteralControlFlowReplacer.ts @@ -3,14 +3,15 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; -import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory'; +import { TControlFlowCustomNodeFactory } from '../../../types/container/custom-nodes/TControlFlowCustomNodeFactory'; import { TStatement } from '../../../types/node/TStatement'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../interfaces/storages/IStorage'; -import { CustomNode } from '../../../enums/container/custom-nodes/CustomNode'; +import { ControlFlowCustomNode } from '../../../enums/container/custom-nodes/ControlFlowCustomNode'; import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer'; import { Node } from '../../../node/Node'; @@ -23,14 +24,17 @@ export class StringLiteralControlFlowReplacer extends AbstractControlFlowReplace private static readonly usingExistingIdentifierChance: number = 1; /** - * @param customNodeFactory + * @param controlFlowCustomNodeFactory + * @param randomGenerator * @param options */ constructor ( - @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory, + @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode) + controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(customNodeFactory, options); + super(controlFlowCustomNodeFactory, randomGenerator, options); } /** @@ -53,7 +57,9 @@ export class StringLiteralControlFlowReplacer extends AbstractControlFlowReplace } const replacerId: string = String(literalNode.value); - const literalFunctionCustomNode: ICustomNode = this.customNodeFactory(CustomNode.StringLiteralNode); + const literalFunctionCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.StringLiteralNode + ); literalFunctionCustomNode.initialize(literalNode.value); @@ -76,8 +82,8 @@ export class StringLiteralControlFlowReplacer extends AbstractControlFlowReplace controlFlowStorageId: string, storageKey: string ): ESTree.Node { - const controlFlowStorageCallCustomNode: ICustomNode = this.customNodeFactory( - CustomNode.StringLiteralControlFlowStorageCallNode + const controlFlowStorageCallCustomNode: ICustomNode = this.controlFlowCustomNodeFactory( + ControlFlowCustomNode.StringLiteralControlFlowStorageCallNode ); controlFlowStorageCallCustomNode.initialize(controlFlowStorageId, storageKey); diff --git a/src/node-transformers/converting-transformers/MemberExpressionTransformer.ts b/src/node-transformers/converting-transformers/MemberExpressionTransformer.ts index ffa2b5e1..a2afa9a7 100644 --- a/src/node-transformers/converting-transformers/MemberExpressionTransformer.ts +++ b/src/node-transformers/converting-transformers/MemberExpressionTransformer.ts @@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { NodeType } from '../../enums/NodeType'; @@ -14,12 +15,14 @@ import { Node } from '../../node/Node'; @injectable() export class MemberExpressionTransformer extends AbstractNodeTransformer { /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); } /** diff --git a/src/node-transformers/converting-transformers/MethodDefinitionTransformer.ts b/src/node-transformers/converting-transformers/MethodDefinitionTransformer.ts index da42dcc8..34ce7814 100644 --- a/src/node-transformers/converting-transformers/MethodDefinitionTransformer.ts +++ b/src/node-transformers/converting-transformers/MethodDefinitionTransformer.ts @@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { NodeType } from '../../enums/NodeType'; @@ -28,12 +29,14 @@ export class MethodDefinitionTransformer extends AbstractNodeTransformer { private static readonly ignoredNames: string[] = ['constructor']; /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); } /** diff --git a/src/node-transformers/converting-transformers/TemplateLiteralTransformer.ts b/src/node-transformers/converting-transformers/TemplateLiteralTransformer.ts index 3c2ce780..d2aaab33 100644 --- a/src/node-transformers/converting-transformers/TemplateLiteralTransformer.ts +++ b/src/node-transformers/converting-transformers/TemplateLiteralTransformer.ts @@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; @@ -17,12 +18,14 @@ import { Nodes } from '../../node/Nodes'; @injectable() export class TemplateLiteralTransformer extends AbstractNodeTransformer { /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); } /** diff --git a/src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts b/src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts index 6f8b39fa..566caba6 100644 --- a/src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts +++ b/src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts @@ -5,13 +5,13 @@ import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { AbstractNodeTransformer } from '../AbstractNodeTransformer'; import { Node } from '../../node/Node'; import { Nodes } from '../../node/Nodes'; import { NodeUtils } from '../../node/NodeUtils'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class DeadCodeInjectionTransformer extends AbstractNodeTransformer { @@ -31,19 +31,45 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer { private readonly collectedBlockStatements: ESTree.BlockStatement[] = []; /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); + } + + /** + * @return {IVisitor} + */ + public getVisitor (): IVisitor { + return { + leave: (node: ESTree.Node, parentNode: ESTree.Node) => { + if (Node.isProgramNode(node)) { + return this.transformNode(node, parentNode); + } + } + }; + } + + /** + * @param programNode + * @param parentNode + * @returns {ESTree.Node} + */ + public transformNode (programNode: ESTree.Program, parentNode: ESTree.Node): ESTree.Node { + this.transformProgramNode(programNode); + + return programNode; } /** * @param blockStatementNode * @param collectedBlockStatements */ - private static collectBlockStatementNodes ( + private collectBlockStatementNodes ( blockStatementNode: ESTree.BlockStatement, collectedBlockStatements: ESTree.BlockStatement[] ): void { @@ -80,7 +106,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer { * in current block statement */ if (Node.isIdentifierNode(node) && !Node.isMemberExpressionNode(parentNode)) { - node.name = RandomGeneratorUtils.getRandomVariableName(6); + node.name = this.randomGenerator.getRandomVariableName(6); } return node; @@ -99,16 +125,16 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer { * @param randomBlockStatementNode * @return {ESTree.BlockStatement} */ - private static replaceBlockStatementNode ( + private replaceBlockStatementNode ( blockStatementNode: ESTree.BlockStatement, randomBlockStatementNode: ESTree.BlockStatement ): ESTree.BlockStatement { - const random1: boolean = RandomGeneratorUtils.getMathRandom() > 0.5; - const random2: boolean = RandomGeneratorUtils.getMathRandom() > 0.5; + const random1: boolean = this.randomGenerator.getMathRandom() > 0.5; + const random2: boolean = this.randomGenerator.getMathRandom() > 0.5; const operator: ESTree.BinaryOperator = random1 ? '===' : '!=='; - const leftString: string = RandomGeneratorUtils.getRandomString(3); - const rightString: string = random2 ? leftString : RandomGeneratorUtils.getRandomString(3); + const leftString: string = this.randomGenerator.getRandomString(3); + const rightString: string = random2 ? leftString : this.randomGenerator.getRandomString(3); let consequent: ESTree.BlockStatement, alternate: ESTree.BlockStatement; @@ -138,30 +164,6 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer { return newBlockStatementNode; } - /** - * @return {IVisitor} - */ - public getVisitor (): IVisitor { - return { - leave: (node: ESTree.Node, parentNode: ESTree.Node) => { - if (Node.isProgramNode(node)) { - return this.transformNode(node, parentNode); - } - } - }; - } - - /** - * @param programNode - * @param parentNode - * @returns {ESTree.Node} - */ - public transformNode (programNode: ESTree.Program, parentNode: ESTree.Node): ESTree.Node { - this.transformProgramNode(programNode); - - return programNode; - } - /** * @param programNode */ @@ -172,7 +174,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer { return; } - DeadCodeInjectionTransformer.collectBlockStatementNodes(node, this.collectedBlockStatements); + this.collectBlockStatementNodes(node, this.collectedBlockStatements); } }); @@ -188,19 +190,19 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer { if ( !Node.isBlockStatementNode(node) || - RandomGeneratorUtils.getMathRandom() > this.options.deadCodeInjectionThreshold + this.randomGenerator.getMathRandom() > this.options.deadCodeInjectionThreshold ) { return node; } - const randomIndex: number = RandomGeneratorUtils.getRandomInteger(0, this.collectedBlockStatements.length - 1); + const randomIndex: number = this.randomGenerator.getRandomInteger(0, this.collectedBlockStatements.length - 1); const randomBlockStatementNode: ESTree.BlockStatement = this.collectedBlockStatements.splice(randomIndex, 1)[0]; if (randomBlockStatementNode === node) { return node; } - return DeadCodeInjectionTransformer.replaceBlockStatementNode(node, randomBlockStatementNode); + return this.replaceBlockStatementNode(node, randomBlockStatementNode); } }); } diff --git a/src/node-transformers/obfuscating-transformers/CatchClauseTransformer.ts b/src/node-transformers/obfuscating-transformers/CatchClauseTransformer.ts index e6ece5a6..dab58dce 100644 --- a/src/node-transformers/obfuscating-transformers/CatchClauseTransformer.ts +++ b/src/node-transformers/obfuscating-transformers/CatchClauseTransformer.ts @@ -8,6 +8,7 @@ import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/nod import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/IIdentifierObfuscatingReplacer'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { IdentifierObfuscatingReplacer } from '../../enums/container/node-transformers/IdentifierObfuscatingReplacer'; @@ -32,14 +33,16 @@ export class CatchClauseTransformer extends AbstractNodeTransformer { /** * @param identifierObfuscatingReplacerFactory + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__IIdentifierObfuscatingReplacer) identifierObfuscatingReplacerFactory: TIdentifierObfuscatingReplacerFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.identifierObfuscatingReplacer = identifierObfuscatingReplacerFactory( IdentifierObfuscatingReplacer.BaseIdentifierObfuscatingReplacer diff --git a/src/node-transformers/obfuscating-transformers/FunctionDeclarationTransformer.ts b/src/node-transformers/obfuscating-transformers/FunctionDeclarationTransformer.ts index f7eb8c26..6aadde1e 100644 --- a/src/node-transformers/obfuscating-transformers/FunctionDeclarationTransformer.ts +++ b/src/node-transformers/obfuscating-transformers/FunctionDeclarationTransformer.ts @@ -9,6 +9,7 @@ import { TNodeWithBlockStatement } from '../../types/node/TNodeWithBlockStatemen import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/IIdentifierObfuscatingReplacer'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { IdentifierObfuscatingReplacer } from "../../enums/container/node-transformers/IdentifierObfuscatingReplacer"; @@ -41,14 +42,16 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer { /** * @param identifierObfuscatingReplacerFactory + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__IIdentifierObfuscatingReplacer) identifierObfuscatingReplacerFactory: TIdentifierObfuscatingReplacerFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.identifierObfuscatingReplacer = identifierObfuscatingReplacerFactory( IdentifierObfuscatingReplacer.BaseIdentifierObfuscatingReplacer diff --git a/src/node-transformers/obfuscating-transformers/FunctionTransformer.ts b/src/node-transformers/obfuscating-transformers/FunctionTransformer.ts index ee990329..592df94d 100644 --- a/src/node-transformers/obfuscating-transformers/FunctionTransformer.ts +++ b/src/node-transformers/obfuscating-transformers/FunctionTransformer.ts @@ -8,6 +8,7 @@ import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/nod import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/IIdentifierObfuscatingReplacer'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { IdentifierObfuscatingReplacer } from '../../enums/container/node-transformers/IdentifierObfuscatingReplacer'; @@ -32,14 +33,16 @@ export class FunctionTransformer extends AbstractNodeTransformer { /** * @param identifierObfuscatingReplacerFactory + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__IIdentifierObfuscatingReplacer) identifierObfuscatingReplacerFactory: TIdentifierObfuscatingReplacerFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.identifierObfuscatingReplacer = identifierObfuscatingReplacerFactory( IdentifierObfuscatingReplacer.BaseIdentifierObfuscatingReplacer diff --git a/src/node-transformers/obfuscating-transformers/LabeledStatementTransformer.ts b/src/node-transformers/obfuscating-transformers/LabeledStatementTransformer.ts index 2fb0b71d..1b7474d2 100644 --- a/src/node-transformers/obfuscating-transformers/LabeledStatementTransformer.ts +++ b/src/node-transformers/obfuscating-transformers/LabeledStatementTransformer.ts @@ -8,6 +8,7 @@ import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/nod import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/IIdentifierObfuscatingReplacer'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { IdentifierObfuscatingReplacer } from '../../enums/container/node-transformers/IdentifierObfuscatingReplacer'; @@ -40,14 +41,16 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer { /** * @param identifierObfuscatingReplacerFactory + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__IIdentifierObfuscatingReplacer) identifierObfuscatingReplacerFactory: TIdentifierObfuscatingReplacerFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.identifierObfuscatingReplacer = identifierObfuscatingReplacerFactory( IdentifierObfuscatingReplacer.BaseIdentifierObfuscatingReplacer diff --git a/src/node-transformers/obfuscating-transformers/LiteralTransformer.ts b/src/node-transformers/obfuscating-transformers/LiteralTransformer.ts index 70f9aaa0..9cd181c0 100644 --- a/src/node-transformers/obfuscating-transformers/LiteralTransformer.ts +++ b/src/node-transformers/obfuscating-transformers/LiteralTransformer.ts @@ -6,6 +6,7 @@ import * as ESTree from 'estree'; import { TLiteralObfuscatingReplacerFactory } from '../../types/container/node-transformers/TLiteralObfuscatingReplacerFactory'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { LiteralObfuscatingReplacer } from '../../enums/container/node-transformers/LiteralObfuscatingReplacer'; @@ -22,14 +23,16 @@ export class LiteralTransformer extends AbstractNodeTransformer { /** * @param literalObfuscatingReplacerFactory + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__IObfuscatingReplacer) literalObfuscatingReplacerFactory: TLiteralObfuscatingReplacerFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.literalObfuscatingReplacerFactory = literalObfuscatingReplacerFactory; } diff --git a/src/node-transformers/obfuscating-transformers/ObjectExpressionTransformer.ts b/src/node-transformers/obfuscating-transformers/ObjectExpressionTransformer.ts index 49194902..9e1e667a 100644 --- a/src/node-transformers/obfuscating-transformers/ObjectExpressionTransformer.ts +++ b/src/node-transformers/obfuscating-transformers/ObjectExpressionTransformer.ts @@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { NodeType } from '../../enums/NodeType'; @@ -21,12 +22,14 @@ import { Node } from '../../node/Node'; @injectable() export class ObjectExpressionTransformer extends AbstractNodeTransformer { /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); } /** diff --git a/src/node-transformers/obfuscating-transformers/VariableDeclarationTransformer.ts b/src/node-transformers/obfuscating-transformers/VariableDeclarationTransformer.ts index 0c63d1c7..5c9613f0 100644 --- a/src/node-transformers/obfuscating-transformers/VariableDeclarationTransformer.ts +++ b/src/node-transformers/obfuscating-transformers/VariableDeclarationTransformer.ts @@ -7,8 +7,9 @@ import * as ESTree from 'estree'; import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory'; import { TNodeWithBlockStatement } from '../../types/node/TNodeWithBlockStatement'; -import { IOptions } from '../../interfaces/options/IOptions'; import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/IIdentifierObfuscatingReplacer'; +import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { IVisitor } from '../../interfaces/IVisitor'; import { IdentifierObfuscatingReplacer } from "../../enums/container/node-transformers/IdentifierObfuscatingReplacer"; @@ -42,14 +43,16 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer { /** * @param identifierObfuscatingReplacerFactory + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__IIdentifierObfuscatingReplacer) identifierObfuscatingReplacerFactory: TIdentifierObfuscatingReplacerFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(options); + super(randomGenerator, options); this.identifierObfuscatingReplacer = identifierObfuscatingReplacerFactory( IdentifierObfuscatingReplacer.BaseIdentifierObfuscatingReplacer diff --git a/src/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.ts b/src/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.ts index b378b748..131d6df5 100644 --- a/src/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.ts +++ b/src/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.ts @@ -5,10 +5,10 @@ import * as ESTree from 'estree'; import { IIdentifierObfuscatingReplacer } from '../../../../interfaces/node-transformers/obfuscating-transformers/IIdentifierObfuscatingReplacer'; import { IOptions } from '../../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../../interfaces/utils/IRandomGenerator'; import { AbstractObfuscatingReplacer } from '../AbstractObfuscatingReplacer'; import { Nodes } from '../../../../node/Nodes'; -import { RandomGeneratorUtils } from '../../../../utils/RandomGeneratorUtils'; @injectable() export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplacer implements IIdentifierObfuscatingReplacer { @@ -18,12 +18,21 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac private readonly namesMap: Map = new Map(); /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator * @param options */ constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); + + this.randomGenerator = randomGenerator; } /** @@ -50,7 +59,7 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac */ public storeNames (nodeName: string, nodeIdentifier: number): void { if (!this.isReservedName(nodeName)) { - this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, RandomGeneratorUtils.getRandomVariableName(6)); + this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, this.randomGenerator.getRandomVariableName(6)); } } diff --git a/src/node-transformers/obfuscating-transformers/obfuscating-replacers/literal-obfuscating-replacers/StringLiteralObfuscatingReplacer.ts b/src/node-transformers/obfuscating-transformers/obfuscating-replacers/literal-obfuscating-replacers/StringLiteralObfuscatingReplacer.ts index aea9492e..2940f320 100644 --- a/src/node-transformers/obfuscating-transformers/obfuscating-replacers/literal-obfuscating-replacers/StringLiteralObfuscatingReplacer.ts +++ b/src/node-transformers/obfuscating-transformers/obfuscating-replacers/literal-obfuscating-replacers/StringLiteralObfuscatingReplacer.ts @@ -3,18 +3,19 @@ import { ServiceIdentifiers } from '../../../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; +import { ICryptUtils } from '../../../../interfaces/utils/ICryptUtils'; import { ICustomNodeGroup } from '../../../../interfaces/custom-nodes/ICustomNodeGroup'; import { IEncodedValue } from '../../../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/literal-obfuscating-replacers/IEncodedValue'; +import { IEscapeSequenceEncoder } from '../../../../interfaces/utils/IEscapeSequenceEncoder'; import { IOptions } from '../../../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../../../interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../../interfaces/storages/IStorage'; import { IStringArrayIndexData } from '../../../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/literal-obfuscating-replacers/IStringArrayIndexData'; import { StringArrayEncoding } from '../../../../enums/StringArrayEncoding'; import { AbstractObfuscatingReplacer } from '../AbstractObfuscatingReplacer'; -import { CryptUtils } from '../../../../utils/CryptUtils'; import { Nodes } from '../../../../node/Nodes'; -import { RandomGeneratorUtils } from '../../../../utils/RandomGeneratorUtils'; import { Utils } from '../../../../utils/Utils'; @injectable() @@ -34,16 +35,31 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace */ private static rc4KeysCount: number = 50; + /** + * @type {ICryptUtils} + */ + private readonly cryptUtils: ICryptUtils; + /** * @type {IStorage} */ private readonly customNodeGroupStorage: IStorage; + /** + * @type {IEscapeSequenceEncoder} + */ + private readonly escapeSequenceEncoder: IEscapeSequenceEncoder; + /** * @type {Map} */ private readonly nodesCache: Map = new Map(); + /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + /** * @type {string[]} */ @@ -62,21 +78,30 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace /** * @param customNodeGroupStorage * @param stringArrayStorage + * @param escapeSequenceEncoder + * @param randomGenerator + * @param cryptUtils * @param options */ constructor ( @inject(ServiceIdentifiers.TCustomNodeGroupStorage) customNodeGroupStorage: IStorage, @inject(ServiceIdentifiers.TStringArrayStorage) stringArrayStorage: IStorage, + @inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, + @inject(ServiceIdentifiers.ICryptUtils) cryptUtils: ICryptUtils, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { super(options); this.customNodeGroupStorage = customNodeGroupStorage; this.stringArrayStorage = stringArrayStorage; + this.escapeSequenceEncoder = escapeSequenceEncoder; + this.randomGenerator = randomGenerator; + this.cryptUtils = cryptUtils; - this.rc4Keys = RandomGeneratorUtils.getRandomGenerator() + this.rc4Keys = this.randomGenerator.getRandomGenerator() .n( - () => RandomGeneratorUtils.getRandomGenerator().string({ + () => this.randomGenerator.getRandomGenerator().string({ length: StringLiteralObfuscatingReplacer.rc4KeyLength }), StringLiteralObfuscatingReplacer.rc4KeysCount @@ -137,7 +162,7 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace return ( this.options.stringArray && nodeValue.length >= StringLiteralObfuscatingReplacer.minimumLengthForStringArray && - RandomGeneratorUtils.getMathRandom() <= this.options.stringArrayThreshold + this.randomGenerator.getMathRandom() <= this.options.stringArrayThreshold ); } @@ -175,13 +200,13 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace switch (this.options.stringArrayEncoding) { case StringArrayEncoding.Rc4: - key = RandomGeneratorUtils.getRandomGenerator().pickone(this.rc4Keys); - encodedValue = CryptUtils.btoa(CryptUtils.rc4(value, key)); + key = this.randomGenerator.getRandomGenerator().pickone(this.rc4Keys); + encodedValue = this.cryptUtils.btoa(this.cryptUtils.rc4(value, key)); break; case StringArrayEncoding.Base64: - encodedValue = CryptUtils.btoa(value); + encodedValue = this.cryptUtils.btoa(value); break; @@ -198,10 +223,7 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace */ private replaceWithLiteralNode (value: string): ESTree.Node { return Nodes.getLiteralNode( - Utils.stringToUnicodeEscapeSequence( - value, - this.options.unicodeEscapeSequence - ) + this.escapeSequenceEncoder.encode(value, this.options.unicodeEscapeSequence) ); } @@ -211,7 +233,7 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace */ private replaceWithStringArrayCallNode (value: string): ESTree.Node { const { encodedValue, key }: IEncodedValue = this.getEncodedValue(value); - const escapedValue: string = Utils.stringToUnicodeEscapeSequence(encodedValue, this.options.unicodeEscapeSequence); + const escapedValue: string = this.escapeSequenceEncoder.encode(encodedValue, this.options.unicodeEscapeSequence); const stringArrayStorageLength: number = this.stringArrayStorage.getLength(); const rotatedStringArrayStorageId: string = Utils.stringRotate(this.stringArrayStorage.getStorageId(), 1); @@ -232,7 +254,7 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace if (key) { callExpressionArgs.push(StringLiteralObfuscatingReplacer.getRc4KeyLiteralNode( - Utils.stringToUnicodeEscapeSequence(key, this.options.unicodeEscapeSequence) + this.escapeSequenceEncoder.encode(key, this.options.unicodeEscapeSequence) )); } diff --git a/src/node/NodeAppender.ts b/src/node/NodeAppender.ts index 3e861658..1775c9e7 100644 --- a/src/node/NodeAppender.ts +++ b/src/node/NodeAppender.ts @@ -5,8 +5,6 @@ import { TStatement } from '../types/node/TStatement'; import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData'; -import { RandomGeneratorUtils } from '../utils/RandomGeneratorUtils'; - /** * This class appends node into a first deepest BlockStatement in order of function calls * @@ -97,13 +95,6 @@ export class NodeAppender { } } - /** - * @param stackTraceRootLength - */ - public static getRandomStackTraceIndex (stackTraceRootLength: number): number { - return RandomGeneratorUtils.getRandomInteger(0, Math.max(0, Math.round(stackTraceRootLength - 1))); - } - /** * @param blockScopeNode * @param nodeBodyStatements diff --git a/src/storages/ArrayStorage.ts b/src/storages/ArrayStorage.ts index b98f3b62..87da2122 100644 --- a/src/storages/ArrayStorage.ts +++ b/src/storages/ArrayStorage.ts @@ -1,13 +1,18 @@ -import { injectable } from 'inversify'; +import { injectable, inject } from 'inversify'; +import { ServiceIdentifiers } from '../container/ServiceIdentifiers'; +import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator'; import { IStorage } from '../interfaces/storages/IStorage'; import { initializable } from '../decorators/Initializable'; -import { RandomGeneratorUtils } from '../utils/RandomGeneratorUtils'; - @injectable() export abstract class ArrayStorage implements IStorage { + /** + * @type {IRandomGenerator} + */ + protected readonly randomGenerator: IRandomGenerator; + /** * @type {T[]} */ @@ -25,6 +30,15 @@ export abstract class ArrayStorage implements IStorage { */ private storageLength: number = 0; + /** + * @param randomGenerator + */ + constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator + ) { + this.randomGenerator = randomGenerator; + } + /** * @param key * @returns {T} @@ -75,7 +89,7 @@ export abstract class ArrayStorage implements IStorage { */ public initialize (...args: any[]): void { this.storage = []; - this.storageId = RandomGeneratorUtils.getRandomString(6); + this.storageId = this.randomGenerator.getRandomString(6); } /** diff --git a/src/storages/MapStorage.ts b/src/storages/MapStorage.ts index 5ee1b1bf..32b10a18 100644 --- a/src/storages/MapStorage.ts +++ b/src/storages/MapStorage.ts @@ -1,13 +1,18 @@ -import { injectable } from 'inversify'; +import { injectable, inject } from 'inversify'; +import { ServiceIdentifiers } from '../container/ServiceIdentifiers'; +import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator'; import { IStorage } from '../interfaces/storages/IStorage'; import { initializable } from '../decorators/Initializable'; -import { RandomGeneratorUtils } from '../utils/RandomGeneratorUtils'; - @injectable() export abstract class MapStorage implements IStorage { + /** + * @type {IRandomGenerator} + */ + protected readonly randomGenerator: IRandomGenerator; + /** * @type {string} */ @@ -20,6 +25,15 @@ export abstract class MapStorage implements IStorage { @initializable() protected storage: Map ; + /** + * @param randomGenerator + */ + constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator + ) { + this.randomGenerator = randomGenerator; + } + /** * @param key * @returns {T} @@ -74,7 +88,7 @@ export abstract class MapStorage implements IStorage { */ public initialize (...args: any[]): void { this.storage = new Map (); - this.storageId = RandomGeneratorUtils.getRandomString(6); + this.storageId = this.randomGenerator.getRandomString(6); } /** diff --git a/src/storages/control-flow/ControlFlowStorage.ts b/src/storages/control-flow/ControlFlowStorage.ts index 8b431c26..e8394ad3 100644 --- a/src/storages/control-flow/ControlFlowStorage.ts +++ b/src/storages/control-flow/ControlFlowStorage.ts @@ -1,10 +1,20 @@ +import { injectable, inject } from 'inversify'; +import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; + import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { MapStorage } from '../MapStorage'; +@injectable() export class ControlFlowStorage extends MapStorage { - constructor () { - super(); + /** + * @param randomGenerator + */ + constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator + ) { + super(randomGenerator); this.initialize(); } diff --git a/src/storages/custom-node-group/CustomNodeGroupStorage.ts b/src/storages/custom-node-group/CustomNodeGroupStorage.ts index d1c0aac8..b35e8426 100644 --- a/src/storages/custom-node-group/CustomNodeGroupStorage.ts +++ b/src/storages/custom-node-group/CustomNodeGroupStorage.ts @@ -5,11 +5,11 @@ import { TCustomNodeGroupFactory } from '../../types/container/custom-nodes/TCus import { ICustomNodeGroup } from '../../interfaces/custom-nodes/ICustomNodeGroup'; import { IOptions } from '../../interfaces/options/IOptions'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { CustomNodeGroup } from '../../enums/container/custom-nodes/CustomNodeGroup'; import { MapStorage } from '../MapStorage'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; @injectable() export class CustomNodeGroupStorage extends MapStorage { @@ -36,13 +36,15 @@ export class CustomNodeGroupStorage extends MapStorage { /** * @param customNodeGroupFactory + * @param randomGenerator * @param options */ constructor ( @inject(ServiceIdentifiers.Factory__ICustomNodeGroup) customNodeGroupFactory: TCustomNodeGroupFactory, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator, @inject(ServiceIdentifiers.IOptions) options: IOptions ) { - super(); + super(randomGenerator); this.customNodeGroupFactory = customNodeGroupFactory; this.options = options; @@ -52,7 +54,7 @@ export class CustomNodeGroupStorage extends MapStorage { public initialize (): void { this.storage = new Map (); - this.storageId = RandomGeneratorUtils.getRandomString(6); + this.storageId = this.randomGenerator.getRandomString(6); CustomNodeGroupStorage.customNodeGroupsList.forEach((customNodeGroupName: CustomNodeGroup) => { const customNodeGroup: ICustomNodeGroup = this.customNodeGroupFactory( diff --git a/src/storages/string-array/StringArrayStorage.ts b/src/storages/string-array/StringArrayStorage.ts index 768fe024..36480b3a 100644 --- a/src/storages/string-array/StringArrayStorage.ts +++ b/src/storages/string-array/StringArrayStorage.ts @@ -1,13 +1,30 @@ -import { injectable } from 'inversify'; +import { injectable, inject } from 'inversify'; +import { ServiceIdentifiers } from '../../container/ServiceIdentifiers'; + +import { IArrayUtils } from '../../interfaces/utils/IArrayUtils'; +import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator'; import { ArrayStorage } from '../ArrayStorage'; -import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils'; -import { Utils } from '../../utils/Utils'; +import { RandomGenerator } from '../../utils/RandomGenerator'; @injectable() export class StringArrayStorage extends ArrayStorage { - constructor () { - super(); + /** + * @type {IArrayUtils} + */ + private readonly arrayUtils: IArrayUtils; + + /** + * @param arrayUtils + * @param randomGenerator + */ + constructor ( + @inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils, + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator + ) { + super(randomGenerator); + + this.arrayUtils = arrayUtils; this.initialize(); } @@ -18,14 +35,14 @@ export class StringArrayStorage extends ArrayStorage { public initialize (...args: any[]): void { super.initialize(args); - this.storageId = RandomGeneratorUtils.getRandomString(4, RandomGeneratorUtils.randomGeneratorPoolHexadecimal); + this.storageId = this.randomGenerator.getRandomString(4, RandomGenerator.randomGeneratorPoolHexadecimal); } /** * @param rotationValue */ public rotateArray (rotationValue: number): void { - this.storage = Utils.arrayRotate(this.storage, rotationValue); + this.storage = this.arrayUtils.arrayRotate(this.storage, rotationValue); } /** diff --git a/src/templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts b/src/templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts index d1d59f6c..f758a661 100644 --- a/src/templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts +++ b/src/templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts @@ -1,4 +1,4 @@ -import { Utils } from '../../../../utils/Utils'; +import { IEscapeSequenceEncoder } from '../../../../interfaces/utils/IEscapeSequenceEncoder'; /** * SelfDefendingTemplate. Enters code in infinity loop. @@ -6,7 +6,7 @@ import { Utils } from '../../../../utils/Utils'; * * @returns {string} */ -export function SelfDefendingTemplate (): string { +export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEncoder): string { return ` var {selfDefendingFunctionName} = {singleNodeCallControllerFunctionName}(this, function () { var func1 = function(){return 'dev';}, @@ -16,7 +16,7 @@ export function SelfDefendingTemplate (): string { var test1 = function () { var regExp = new RegExp('${ - Utils.stringToUnicodeEscapeSequence(`\\w+ *\\(\\) *{\\w+ *['|"].+['|"];? *}`, true) + escapeSequenceEncoder.encode(`\\w+ *\\(\\) *{\\w+ *['|"].+['|"];? *}`, true) }'); return !regExp.test(func1.toString()); @@ -24,7 +24,7 @@ export function SelfDefendingTemplate (): string { var test2 = function () { var regExp = new RegExp('${ - Utils.stringToUnicodeEscapeSequence(`(\\\\[x|u](\\w){2,4})+`, true) + escapeSequenceEncoder.encode(`(\\\\[x|u](\\w){2,4})+`, true) }'); return regExp.test(func2.toString()); diff --git a/src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts b/src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts index e5cd49a0..2843e21c 100644 --- a/src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts +++ b/src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts @@ -1,19 +1,19 @@ -import { Utils } from '../../../../utils/Utils'; +import { IEscapeSequenceEncoder } from '../../../../interfaces/utils/IEscapeSequenceEncoder'; /** * @returns {string} */ -export function SelfDefendingTemplate (): string { +export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEncoder): string { return ` var StatesClass = function (rc4Bytes) { this.rc4Bytes = rc4Bytes; this.states = [1, 0, 0]; this.newState = function(){return 'newState';}; this.firstState = '${ - Utils.stringToUnicodeEscapeSequence(`\\w+ *\\(\\) *{\\w+ *`, true) + escapeSequenceEncoder.encode(`\\w+ *\\(\\) *{\\w+ *`, true) }'; this.secondState = '${ - Utils.stringToUnicodeEscapeSequence(`['|"].+['|"];? *}`, true) + escapeSequenceEncoder.encode(`['|"].+['|"];? *}`, true) }'; }; diff --git a/src/templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts b/src/templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts index e924bfc8..296477ce 100644 --- a/src/templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts +++ b/src/templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts @@ -1,11 +1,11 @@ -import { Utils } from '../../../../utils/Utils'; +import { IEscapeSequenceEncoder } from '../../../../interfaces/utils/IEscapeSequenceEncoder'; /** * SelfDefendingTemplate. Enter code in infinity loop. * * @returns {string} */ -export function SelfDefendingTemplate (): string { +export function SelfDefendingTemplate (escapeSequenceEncoder: IEscapeSequenceEncoder): string { return ` var selfDefendingFunc = function () { var object = { @@ -56,7 +56,7 @@ export function SelfDefendingTemplate (): string { var test1 = function () { var regExp = new RegExp('${ - Utils.stringToUnicodeEscapeSequence(`\\w+ *\\(\\) *{\\w+ *['|"].+['|"];? *}`, true) + escapeSequenceEncoder.encode(`\\w+ *\\(\\) *{\\w+ *['|"].+['|"];? *}`, true) }'); return regExp.test(object.removeCookie.toString()); diff --git a/src/types/container/custom-nodes/TControlFlowCustomNodeFactory.d.ts b/src/types/container/custom-nodes/TControlFlowCustomNodeFactory.d.ts new file mode 100644 index 00000000..14573999 --- /dev/null +++ b/src/types/container/custom-nodes/TControlFlowCustomNodeFactory.d.ts @@ -0,0 +1,6 @@ +import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; + +import { ControlFlowCustomNode } from '../../../enums/container/custom-nodes/ControlFlowCustomNode'; + +export type TControlFlowCustomNodeFactory = (controlFlowCustomNodeName: ControlFlowCustomNode) => ICustomNode; + diff --git a/src/utils/ArrayUtils.ts b/src/utils/ArrayUtils.ts new file mode 100644 index 00000000..1330e952 --- /dev/null +++ b/src/utils/ArrayUtils.ts @@ -0,0 +1,78 @@ +import { injectable, inject } from 'inversify'; +import { ServiceIdentifiers } from '../container/ServiceIdentifiers'; + +import { IArrayUtils } from '../interfaces/utils/IArrayUtils'; +import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator'; + +@injectable() +export class ArrayUtils implements IArrayUtils { + /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator + */ + constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator + ) { + this.randomGenerator = randomGenerator; + } + + /** + * @param length + * @return {number[]} + */ + public arrayRange (length: number): number[] { + const range: number[] = []; + + for (let i: number = 0; i < length; i++) { + range.push(i); + } + + return range; + } + + /** + * @param array + * @param times + * @returns {T[]} + */ + public arrayRotate (array: T[], times: number): T[] { + if (!array.length) { + throw new ReferenceError(`Cannot rotate empty array.`); + } + + if (times <= 0) { + return array; + } + + const newArray: T[] = array; + + let temp: T | undefined; + + while (times--) { + temp = newArray.pop()!; + newArray.unshift(temp); + } + + return newArray; + } + + /** + * @param array + * @return {T[]} + */ + public arrayShuffle (array: T[]): T[] { + const shuffledArray: T[] = [...array]; + + for (let i: number = shuffledArray.length; i; i--) { + const j: number = Math.floor(this.randomGenerator.getMathRandom() * i); + + [shuffledArray[i - 1], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i - 1]]; + } + + return shuffledArray; + } +} diff --git a/src/utils/CryptUtils.ts b/src/utils/CryptUtils.ts index 5163dba5..ee36e0b4 100644 --- a/src/utils/CryptUtils.ts +++ b/src/utils/CryptUtils.ts @@ -1,12 +1,33 @@ -import { RandomGeneratorUtils } from './RandomGeneratorUtils'; +import { injectable, inject } from 'inversify'; +import { ServiceIdentifiers } from '../container/ServiceIdentifiers'; + +import { ICryptUtils } from '../interfaces/utils/ICryptUtils'; +import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator'; + +import { RandomGenerator } from './RandomGenerator'; import { Utils } from './Utils'; -export class CryptUtils { +@injectable() +export class CryptUtils implements ICryptUtils { + /** + * @type {IRandomGenerator} + */ + private readonly randomGenerator: IRandomGenerator; + + /** + * @param randomGenerator + */ + constructor ( + @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator + ) { + this.randomGenerator = randomGenerator; + } + /** * @param string */ /* tslint:disable */ - public static btoa (string: string): string { + public btoa (string: string): string { const chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; let output: string = ''; @@ -36,9 +57,9 @@ export class CryptUtils { /** * @param str * @param length - * @returns {string[]} + * @returns {[string, string]} */ - public static hideString (str: string, length: number): [string, string] { + public hideString (str: string, length: number): [string, string] { const escapeRegExp: (s: string) => string = (s: string) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); @@ -48,7 +69,7 @@ export class CryptUtils { result: string = ''; while (i1 < s1.length || i2 < s2.length) { - if (RandomGeneratorUtils.getMathRandom() < 0.5 && i2 < s2.length) { + if (this.randomGenerator.getMathRandom() < 0.5 && i2 < s2.length) { result += s2.charAt(++i2); } else { result += s1.charAt(++i1); @@ -58,9 +79,9 @@ export class CryptUtils { return result; }; - const randomString: string = RandomGeneratorUtils.getRandomGenerator().string({ + const randomString: string = this.randomGenerator.getRandomGenerator().string({ length: length, - pool: RandomGeneratorUtils.randomGeneratorPool + pool: RandomGenerator.randomGeneratorPool }); let randomStringDiff: string = randomString.replace( @@ -69,7 +90,7 @@ export class CryptUtils { const randomStringDiffArray: string[] = randomStringDiff.split(''); - RandomGeneratorUtils.getRandomGenerator().shuffle(randomStringDiffArray); + this.randomGenerator.getRandomGenerator().shuffle(randomStringDiffArray); randomStringDiff = randomStringDiffArray.join(''); return [randomMerge(str, randomStringDiff), randomStringDiff]; @@ -84,7 +105,7 @@ export class CryptUtils { * @returns {string} */ /* tslint:disable */ - public static rc4 (string: string, key: string): string { + public rc4 (string: string, key: string): string { let s: number[] = [], j: number = 0, x: number, diff --git a/src/utils/EscapeSequenceEncoder.ts b/src/utils/EscapeSequenceEncoder.ts new file mode 100644 index 00000000..4401000c --- /dev/null +++ b/src/utils/EscapeSequenceEncoder.ts @@ -0,0 +1,52 @@ +import { injectable } from 'inversify'; + +import { IEscapeSequenceEncoder } from '../interfaces/utils/IEscapeSequenceEncoder'; + +@injectable() +export class EscapeSequenceEncoder implements IEscapeSequenceEncoder { + /** + * @type {Map} + */ + private readonly stringsCache: Map = new Map(); + + /** + * @param string + * @param encodeAllSymbols + * @returns {string} + */ + public encode (string: string, encodeAllSymbols: boolean): string { + const cacheKey: string = `${string}-${String(encodeAllSymbols)}`; + + if (this.stringsCache.has(cacheKey)) { + return this.stringsCache.get(cacheKey); + } + + const radix: number = 16; + const replaceRegExp: RegExp = new RegExp('[\\s\\S]', 'g'); + const escapeSequenceRegExp: RegExp = new RegExp('[\'\"\\\\\\s]'); + const regExp: RegExp = new RegExp('[\\x00-\\x7F]'); + + let prefix: string, + template: string; + + const result: string = string.replace(replaceRegExp, (character: string): string => { + if (!encodeAllSymbols && !escapeSequenceRegExp.exec(character)) { + return character; + } + + if (regExp.exec(character)) { + prefix = '\\x'; + template = '00'; + } else { + prefix = '\\u'; + template = '0000'; + } + + return `${prefix}${(template + character.charCodeAt(0).toString(radix)).slice(-template.length)}`; + }); + + this.stringsCache.set(cacheKey, result); + + return result; + } +} diff --git a/src/utils/RandomGenerator.ts b/src/utils/RandomGenerator.ts new file mode 100644 index 00000000..99563222 --- /dev/null +++ b/src/utils/RandomGenerator.ts @@ -0,0 +1,125 @@ +import { inject, injectable } from 'inversify'; +import { ServiceIdentifiers } from '../container/ServiceIdentifiers'; + +import { Chance } from 'chance'; + +import { IOptions } from '../interfaces/options/IOptions'; +import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator'; + +import { Utils } from './Utils'; + +@injectable() +export class RandomGenerator implements IRandomGenerator { + /** + * @type {string} + */ + public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + /** + * @type {string} + */ + public static readonly randomGeneratorPoolNumbers: string = '0123456789'; + + /** + * @type {string} + */ + public static readonly randomGeneratorPoolHexadecimal: string = `abcdef${RandomGenerator.randomGeneratorPoolNumbers}`; + + /** + * @type {IOptions} + */ + private readonly options: IOptions; + + /** + * @type {Set} + */ + private readonly randomVariableNameSet: Set = new Set(); + + /** + * @type {Chance.Chance | Chance.SeededChance} + */ + private readonly randomGenerator: Chance.Chance | Chance.SeededChance; + + /** + * @param options + */ + constructor ( + @inject(ServiceIdentifiers.IOptions) options: IOptions + ) { + this.options = options; + this.randomGenerator = options.seed !== 0 + ? new Chance(options.seed) + : new Chance(); + } + + /** + * @returns {number} + */ + public getMathRandom (): number { + return this.getRandomInteger(0, 99999) / 100000; + } + + /** + * @param min + * @param max + * @returns {number} + */ + public getRandomFloat (min: number, max: number): number { + return this.getRandomGenerator().floating({ + min: min, + max: max, + fixed: 7 + }); + } + + /** + * @returns {Chance.Chance} + */ + public getRandomGenerator (): Chance.Chance { + return this.randomGenerator; + } + + /** + * @param min + * @param max + * @returns {number} + */ + public getRandomInteger (min: number, max: number): number { + return this.getRandomGenerator().integer({ + min: min, + max: max + }); + } + + /** + * @param length + * @param pool + * @returns {string} + */ + public getRandomString (length: number, pool: string = RandomGenerator.randomGeneratorPool): string { + return this.getRandomGenerator().string({ length, pool }); + } + + /** + * @param length + * @returns {string} + */ + public getRandomVariableName (length: number): string { + const prefix: string = `_${Utils.hexadecimalPrefix}`; + const rangeMinInteger: number = 10000; + const rangeMaxInteger: number = 99999999; + const randomVariableName: string = `${prefix}${( + Utils.decToHex( + this.getRandomInteger(rangeMinInteger, rangeMaxInteger) + ) + ).substr(0, length)}`; + + if (this.randomVariableNameSet.has(randomVariableName)) { + return this.getRandomVariableName(length); + } + + this.randomVariableNameSet.add(randomVariableName); + + return randomVariableName; + } +} diff --git a/src/utils/RandomGeneratorUtils.ts b/src/utils/RandomGeneratorUtils.ts deleted file mode 100644 index 71301819..00000000 --- a/src/utils/RandomGeneratorUtils.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Chance } from 'chance'; - -import { Utils } from './Utils'; - -export class RandomGeneratorUtils { - /** - * @type {string} - */ - public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - - /** - * @type {string} - */ - public static readonly randomGeneratorPoolNumbers: string = '0123456789'; - - /** - * @type {string} - */ - public static readonly randomGeneratorPoolHexadecimal: string = `abcdef${RandomGeneratorUtils.randomGeneratorPoolNumbers}`; - - /** - * @type {string} - */ - public static readonly randomGeneratorPoolWithNumbers: string = `${RandomGeneratorUtils.randomGeneratorPool}${RandomGeneratorUtils.randomGeneratorPoolNumbers}`; - - /** - * @type {Set} - */ - public static readonly randomVariableNameSet: Set = new Set(); - - /** - * @type {Chance.Chance | Chance.SeededChance} - */ - private static randomGenerator: Chance.Chance | Chance.SeededChance; - - /** - * @param seed - */ - public static initializeRandomGenerator (seed: number): void { - if (seed !== 0) { - RandomGeneratorUtils.randomGenerator = new Chance(seed); - } else { - RandomGeneratorUtils.randomGenerator = new Chance(); - } - } - - public static clearRandomGenerator (): void { - RandomGeneratorUtils.randomVariableNameSet.clear(); - } - - /** - * @returns {number} - */ - public static getMathRandom (): number { - return RandomGeneratorUtils.getRandomInteger(0, 99999) / 100000; - } - - /** - * @param min - * @param max - * @returns {number} - */ - public static getRandomFloat (min: number, max: number): number { - return RandomGeneratorUtils.getRandomGenerator().floating({ - min: min, - max: max, - fixed: 7 - }); - } - - /** - * @returns {Chance.Chance} - */ - public static getRandomGenerator (): Chance.Chance { - const randomGenerator: Chance.Chance = RandomGeneratorUtils.randomGenerator; - - if (!randomGenerator) { - RandomGeneratorUtils.initializeRandomGenerator(0); - } - - return RandomGeneratorUtils.randomGenerator; - } - - /** - * @param min - * @param max - * @returns {number} - */ - public static getRandomInteger (min: number, max: number): number { - return RandomGeneratorUtils.getRandomGenerator().integer({ - min: min, - max: max - }); - } - - /** - * @param length - * @param pool - * @returns {string} - */ - public static getRandomString (length: number, pool: string = RandomGeneratorUtils.randomGeneratorPool): string { - return RandomGeneratorUtils.getRandomGenerator().string({ length, pool }); - } - - /** - * @param length - * @returns {string} - */ - public static getRandomVariableName (length: number): string { - const prefix: string = `_${Utils.hexadecimalPrefix}`; - const rangeMinInteger: number = 10000; - const rangeMaxInteger: number = 99999999; - const randomVariableName: string = `${prefix}${( - Utils.decToHex( - RandomGeneratorUtils.getRandomInteger(rangeMinInteger, rangeMaxInteger) - ) - ).substr(0, length)}`; - - if (RandomGeneratorUtils.randomVariableNameSet.has(randomVariableName)) { - return RandomGeneratorUtils.getRandomVariableName(length); - } - - RandomGeneratorUtils.randomVariableNameSet.add(randomVariableName); - - return randomVariableName; - } -} diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index 500337b2..9aa0877b 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -1,74 +1,11 @@ import { JSFuck } from '../enums/JSFuck'; -import { RandomGeneratorUtils } from './RandomGeneratorUtils'; - export class Utils { /** * @type {string} */ public static readonly hexadecimalPrefix: string = '0x'; - /** - * @type {Map} - */ - private static readonly stringToUnicodeEscapeSequenceCache: Map = new Map(); - - /** - * @param length - * @return {number[]} - */ - public static arrayRange (length: number): number[] { - const range: number[] = []; - - for (let i: number = 0; i < length; i++) { - range.push(i); - } - - return range; - } - - /** - * @param array - * @param times - * @returns {T[]} - */ - public static arrayRotate (array: T[], times: number): T[] { - if (!array.length) { - throw new ReferenceError(`Cannot rotate empty array.`); - } - - if (times <= 0) { - return array; - } - - const newArray: T[] = array; - - let temp: T | undefined; - - while (times--) { - temp = newArray.pop()!; - newArray.unshift(temp); - } - - return newArray; - } - - /** - * @param array - * @return {T[]} - */ - public static arrayShuffle (array: T[]): T[] { - const shuffledArray: T[] = [...array]; - - for (let i: number = shuffledArray.length; i; i--) { - const j: number = Math.floor(RandomGeneratorUtils.getMathRandom() * i); - - [shuffledArray[i - 1], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i - 1]]; - } - - return shuffledArray; - } - /** * @param dec * @returns {string} @@ -105,14 +42,6 @@ export class Utils { return number % 1 === 0; } - /** - * @param obj - * @returns {T} - */ - public static strEnumify (obj: T): T { - return obj; - } - /** * @param string * @param times @@ -142,45 +71,4 @@ export class Utils { }) .join(' + '); } - - /** - * @param string - * @param usingUnicodeEscapeSequence - * @returns {string} - */ - public static stringToUnicodeEscapeSequence (string: string, usingUnicodeEscapeSequence: boolean): string { - const cacheKey: string = `${string}-${String(usingUnicodeEscapeSequence)}`; - - if (Utils.stringToUnicodeEscapeSequenceCache.has(cacheKey)) { - return Utils.stringToUnicodeEscapeSequenceCache.get(cacheKey); - } - - const radix: number = 16; - const replaceRegExp: RegExp = new RegExp('[\\s\\S]', 'g'); - const escapeSequenceRegExp: RegExp = new RegExp('[\'\"\\\\\\s]'); - const regExp: RegExp = new RegExp('[\\x00-\\x7F]'); - - let prefix: string, - template: string; - - const result: string = string.replace(replaceRegExp, (character: string): string => { - if (!usingUnicodeEscapeSequence && !escapeSequenceRegExp.exec(character)) { - return character; - } - - if (regExp.exec(character)) { - prefix = '\\x'; - template = '00'; - } else { - prefix = '\\u'; - template = '0000'; - } - - return `${prefix}${(template + character.charCodeAt(0).toString(radix)).slice(-template.length)}`; - }); - - Utils.stringToUnicodeEscapeSequenceCache.set(cacheKey, result); - - return result; - } } diff --git a/test/functional-tests/javascript-obfuscator-internal/JavaScriptObfuscatorInternal.spec.ts b/test/functional-tests/javascript-obfuscator-internal/JavaScriptObfuscatorInternal.spec.ts index e61d3fff..027d4d1b 100644 --- a/test/functional-tests/javascript-obfuscator-internal/JavaScriptObfuscatorInternal.spec.ts +++ b/test/functional-tests/javascript-obfuscator-internal/JavaScriptObfuscatorInternal.spec.ts @@ -15,8 +15,7 @@ describe('JavaScriptObfuscatorInternal', () => { const code: string = 'var test = 1;'; const sourceMapUrl: string = 'test.js.map'; - let inversifyContainerFacade: IInversifyContainerFacade, - javaScriptObfuscator: IJavaScriptObfuscator; + let javaScriptObfuscator: IJavaScriptObfuscator; describe('variant #1: default behaviour', () => { const regExp: RegExp = new RegExp(`sourceMappingURL=${sourceMapUrl}`); @@ -25,7 +24,9 @@ describe('JavaScriptObfuscatorInternal', () => { sourceMapObject: any; before(() => { - inversifyContainerFacade = new InversifyContainerFacade({ + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({ ...NO_CUSTOM_NODES_PRESET, sourceMap: true, sourceMapFileName: sourceMapUrl @@ -56,7 +57,9 @@ describe('JavaScriptObfuscatorInternal', () => { sourceMapObject: any; before(() => { - inversifyContainerFacade = new InversifyContainerFacade({ + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({ ...NO_CUSTOM_NODES_PRESET, sourceMap: true, sourceMapBaseUrl: sourceMapBaseUrl, diff --git a/test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts b/test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts index 4937ea2b..d4b72895 100644 --- a/test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts +++ b/test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts @@ -8,14 +8,8 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../src/options/presets/NoCustomNod import { readFileAsString } from '../../helpers/readFileAsString'; -import { RandomGeneratorUtils } from '../../../src/utils/RandomGeneratorUtils'; - describe('JavaScriptObfuscator', () => { describe('obfuscate (sourceCode: string, customOptions?: IObfuscatorOptions): IObfuscationResult', () => { - beforeEach(() => { - RandomGeneratorUtils.initializeRandomGenerator(0); - }); - describe('correct source code', () => { let obfuscatedCode: string, sourceMap: string; @@ -429,9 +423,5 @@ describe('JavaScriptObfuscator', () => { assert.match(obfuscatedCode, regExp); }); }); - - afterEach(() => { - RandomGeneratorUtils.initializeRandomGenerator(0); - }); }); }); diff --git a/test/functional-tests/stack-trace-analyzer/stack-trace-analyzer/StackTraceAnalyzer.spec.ts b/test/functional-tests/stack-trace-analyzer/stack-trace-analyzer/StackTraceAnalyzer.spec.ts index 387def2b..9443e35c 100644 --- a/test/functional-tests/stack-trace-analyzer/stack-trace-analyzer/StackTraceAnalyzer.spec.ts +++ b/test/functional-tests/stack-trace-analyzer/stack-trace-analyzer/StackTraceAnalyzer.spec.ts @@ -148,13 +148,18 @@ function getObjectFunctionExpressionByName (astTree: ESTree.Node, objectName: st describe('StackTraceAnalyzer', () => { describe('extract (): IStackTraceData[]', () => { - const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade({}); - const stackTraceAnalyzer: IStackTraceAnalyzer = inversifyContainerFacade - .get(ServiceIdentifiers.IStackTraceAnalyzer); - - let expectedStackTraceData: IStackTraceData[], + let stackTraceAnalyzer: IStackTraceAnalyzer, + expectedStackTraceData: IStackTraceData[], stackTraceData: IStackTraceData[]; + before(() => { + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + stackTraceAnalyzer = inversifyContainerFacade + .get(ServiceIdentifiers.IStackTraceAnalyzer); + }); + describe('variant #1: basic-1', () => { before(() => { const code: string = readFileAsString(__dirname + '/fixtures/basic-1.js'); 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 c64b6eff..7c5bea58 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 @@ -2,9 +2,14 @@ import * as format from 'string-template'; import { assert } from 'chai'; +import { ServiceIdentifiers } from '../../../../../src/container/ServiceIdentifiers'; + +import { ICryptUtils } from '../../../../../src/interfaces/utils/ICryptUtils'; +import { IInversifyContainerFacade } from '../../../../../src/interfaces/container/IInversifyContainerFacade'; + import { DomainLockNodeTemplate } from '../../../../../src/templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate'; -import { CryptUtils } from '../../../../../src/utils/CryptUtils'; +import { InversifyContainerFacade } from '../../../../../src/container/InversifyContainerFacade'; /** * @param templateData @@ -35,6 +40,15 @@ function getFunctionFromTemplate (templateData: any, callsControllerFunctionName describe('DomainLockNodeTemplate (): string', () => { const singleNodeCallControllerFunctionName: string = 'callsController'; + let cryptUtils: ICryptUtils; + + before(() => { + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + cryptUtils = inversifyContainerFacade.get(ServiceIdentifiers.ICryptUtils); + }); + describe('variant #1: current domain matches with `domainsString`', () => { const domainsString: string = ['www.example.com'].join(';'); const currentDomain: string = 'www.example.com'; @@ -45,7 +59,7 @@ describe('DomainLockNodeTemplate (): string', () => { const [ hiddenDomainsString, diff - ] = CryptUtils.hideString(domainsString, domainsString.length * 3); + ] = cryptUtils.hideString(domainsString, domainsString.length * 3); testFunc = () => getFunctionFromTemplate({ domainLockFunctionName: 'domainLockFunction', @@ -70,7 +84,7 @@ describe('DomainLockNodeTemplate (): string', () => { const [ hiddenDomainsString, diff - ] = CryptUtils.hideString(domainsString, domainsString.length * 3); + ] = cryptUtils.hideString(domainsString, domainsString.length * 3); testFunc = () => getFunctionFromTemplate({ domainLockFunctionName: 'domainLockFunction', @@ -95,7 +109,7 @@ describe('DomainLockNodeTemplate (): string', () => { const [ hiddenDomainsString, diff - ] = CryptUtils.hideString(domainsString, domainsString.length * 3); + ] = cryptUtils.hideString(domainsString, domainsString.length * 3); testFunc = () => getFunctionFromTemplate({ domainLockFunctionName: 'domainLockFunction', 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 5f0ffbd7..4c5a8073 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 @@ -2,68 +2,32 @@ import * as format from 'string-template'; import { assert } from 'chai'; +import { ServiceIdentifiers } from '../../../../../src/container/ServiceIdentifiers'; + +import { ICryptUtils } from '../../../../../src/interfaces/utils/ICryptUtils'; +import { IInversifyContainerFacade } from '../../../../../src/interfaces/container/IInversifyContainerFacade'; + import { AtobTemplate } from '../../../../../src/templates/custom-nodes/AtobTemplate'; import { Rc4Template } from '../../../../../src/templates/custom-nodes/Rc4Template'; import { StringArrayBase64DecodeNodeTemplate } from '../../../../../src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate'; import { StringArrayCallsWrapperTemplate } from '../../../../../src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate'; import { StringArrayRc4DecodeNodeTemplate } from '../../../../../src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate'; -import { CryptUtils } from '../../../../../src/utils/CryptUtils'; - -/** - * @param templateData - * @param stringArrayName - * @param stringArrayCallsWrapperName - * @param index - * @returns {Function} - */ -function getFunctionFromTemplateBase64Encoding ( - templateData: any, - stringArrayName: string, - stringArrayCallsWrapperName: string, - index: string -) { - const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), templateData); - - return Function(` - var ${stringArrayName} = ['${CryptUtils.btoa('test1')}']; - - ${stringArrayCallsWrapperTemplate} - - return ${stringArrayCallsWrapperName}(${index}); - `)(); -} - -/** - * @param templateData - * @param stringArrayName - * @param stringArrayCallsWrapperName - * @param index - * @param key - * @returns {Function} - */ -function getFunctionFromTemplateRc4Encoding ( - templateData: any, - stringArrayName: string, - stringArrayCallsWrapperName: string, - index: string, - key: string -) { - const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), templateData); - - return Function(` - var ${stringArrayName} = ['${CryptUtils.btoa(CryptUtils.rc4('test1', key))}']; - - ${stringArrayCallsWrapperTemplate} - - return ${stringArrayCallsWrapperName}('${index}', '${key}'); - `)(); -} +import { InversifyContainerFacade } from '../../../../../src/container/InversifyContainerFacade'; describe('StringArrayCallsWrapperNodeTemplate (): string', () => { const stringArrayName: string = 'stringArrayName'; const stringArrayCallsWrapperName: string = 'stringArrayCallsWrapperName'; + let cryptUtils: ICryptUtils; + + before(() => { + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + cryptUtils = inversifyContainerFacade.get(ServiceIdentifiers.ICryptUtils); + }); + describe('variant #1: `base64` encoding', () => { const atobDecodeNodeTemplate: string = format(StringArrayBase64DecodeNodeTemplate(), { atobPolyfill: AtobTemplate(), @@ -76,11 +40,19 @@ describe('StringArrayCallsWrapperNodeTemplate (): string', () => { let decodedValue: string; before(() => { - decodedValue = getFunctionFromTemplateBase64Encoding({ + const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), { decodeNodeTemplate: atobDecodeNodeTemplate, stringArrayCallsWrapperName, stringArrayName - }, stringArrayName, stringArrayCallsWrapperName, index); + }); + + decodedValue = Function(` + var ${stringArrayName} = ['${cryptUtils.btoa('test1')}']; + + ${stringArrayCallsWrapperTemplate} + + return ${stringArrayCallsWrapperName}(${index}); + `)(); }); it('should correctly return decoded value', () => { @@ -102,11 +74,19 @@ describe('StringArrayCallsWrapperNodeTemplate (): string', () => { let decodedValue: string; before(() => { - decodedValue = getFunctionFromTemplateRc4Encoding({ + const stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), { decodeNodeTemplate: rc4DecodeNodeTemplate, stringArrayCallsWrapperName, stringArrayName - }, stringArrayName, stringArrayCallsWrapperName, index, key); + }); + + decodedValue = Function(` + var ${stringArrayName} = ['${cryptUtils.btoa(cryptUtils.rc4('test1', key))}']; + + ${stringArrayCallsWrapperTemplate} + + return ${stringArrayCallsWrapperName}('${index}', '${key}'); + `)(); }); it('should correctly return decoded value', () => { diff --git a/test/index.spec.ts b/test/index.spec.ts index b731534c..fcbac9f3 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -15,9 +15,11 @@ import './unit-tests/source-map-corrector/SourceMapCorrector.spec'; import './unit-tests/stack-trace-analyzer/stack-trace-analyzer/StackTraceAnalyzer.spec'; import './unit-tests/storages/ArrayStorage.spec'; import './unit-tests/storages/MapStorage.spec'; -import './unit-tests/utils/crypt-utils/CryptUtils.spec'; -import './unit-tests/utils/random-generator-utils/RandomGeneratorUtils.spec'; -import './unit-tests/utils/utils/Utils.spec'; +import './unit-tests/utils/ArrayUtils.spec'; +import './unit-tests/utils/CryptUtils.spec'; +import './unit-tests/utils/RandomGeneratorUtils.spec'; +import './unit-tests/utils/EscapeSequenceEncoder.spec'; +import './unit-tests/utils/Utils.spec'; /** * Functional tests diff --git a/test/unit-tests/node/node-appender/NodeAppender.spec.ts b/test/unit-tests/node/node-appender/NodeAppender.spec.ts index b24f79b4..8ab41e99 100644 --- a/test/unit-tests/node/node-appender/NodeAppender.spec.ts +++ b/test/unit-tests/node/node-appender/NodeAppender.spec.ts @@ -58,15 +58,20 @@ describe('NodeAppender', () => { }); describe('appendNodeToOptimalBlockScope (blockScopeStackTraceData: IStackTraceData[], blockScopeNode: TNodeWithBlockStatement, nodeBodyStatements: TStatement[], index: number = 0): void', () => { - const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade({}); - const stackTraceAnalyzer: IStackTraceAnalyzer = inversifyContainerFacade - .get(ServiceIdentifiers.IStackTraceAnalyzer); - - let astTree: ESTree.Program, + let stackTraceAnalyzer: IStackTraceAnalyzer, + astTree: ESTree.Program, expectedAstTree: ESTree.Program, node: TStatement[], stackTraceData: IStackTraceData[]; + before(() => { + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + stackTraceAnalyzer = inversifyContainerFacade + .get(ServiceIdentifiers.IStackTraceAnalyzer); + }); + beforeEach(() => { node = convertCodeToStructure('/fixtures/simple-input.js'); }); @@ -145,7 +150,7 @@ describe('NodeAppender', () => { stackTraceData, astTree, node, - NodeAppender.getRandomStackTraceIndex(stackTraceData.length) + stackTraceData.length - 1 ); }); @@ -157,19 +162,6 @@ describe('NodeAppender', () => { }); }); - describe('getRandomStackTraceIndex (stackTraceRootLength: number): number', () => { - it('should return random index between 0 and stack trace data root length', () => { - let index: number; - - for (let i: number = 0; i < 100; i++) { - index = NodeAppender.getRandomStackTraceIndex(100); - - assert.isAtLeast(index, 0); - assert.isAtMost(index, 100); - } - }); - }); - describe('insertNodeAtIndex (blockScopeNode: TNodeWithBlockStatement[], nodeBodyStatements: TStatement[], index: number): void', () => { let astTree: ESTree.Program, expectedAstTree: ESTree.Program, diff --git a/test/unit-tests/source-map-corrector/SourceMapCorrector.spec.ts b/test/unit-tests/source-map-corrector/SourceMapCorrector.spec.ts index 334dd3aa..b490317a 100644 --- a/test/unit-tests/source-map-corrector/SourceMapCorrector.spec.ts +++ b/test/unit-tests/source-map-corrector/SourceMapCorrector.spec.ts @@ -26,12 +26,15 @@ function getCorrectedObfuscationResult ( sourceMapFileName: string, sourceMapMode: TSourceMapMode ): IObfuscationResult { - const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade({ + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({ sourceMap: true, sourceMapBaseUrl: sourceMapBaseUrl, sourceMapFileName: sourceMapFileName, sourceMapMode: sourceMapMode }); + const sourceMapCorrector: ISourceMapCorrector = inversifyContainerFacade .get(ServiceIdentifiers.ISourceMapCorrector); diff --git a/test/unit-tests/storages/ArrayStorage.spec.ts b/test/unit-tests/storages/ArrayStorage.spec.ts index 1349079d..8d8ef198 100644 --- a/test/unit-tests/storages/ArrayStorage.spec.ts +++ b/test/unit-tests/storages/ArrayStorage.spec.ts @@ -1,12 +1,21 @@ import { assert } from 'chai'; +import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; + +import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; +import { IRandomGenerator } from '../../../src/interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../src/interfaces/storages/IStorage'; import { ArrayStorage } from '../../../src/storages/ArrayStorage'; +import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; class ConcreteStorage extends ArrayStorage { constructor () { - super(); + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + + super(inversifyContainerFacade.get(ServiceIdentifiers.IRandomGenerator)); } } diff --git a/test/unit-tests/storages/MapStorage.spec.ts b/test/unit-tests/storages/MapStorage.spec.ts index 4fd4953f..fb3de1f0 100644 --- a/test/unit-tests/storages/MapStorage.spec.ts +++ b/test/unit-tests/storages/MapStorage.spec.ts @@ -1,12 +1,21 @@ import { assert } from 'chai'; +import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; + +import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; +import { IRandomGenerator } from '../../../src/interfaces/utils/IRandomGenerator'; import { IStorage } from '../../../src/interfaces/storages/IStorage'; +import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; import { MapStorage } from '../../../src/storages/MapStorage'; class ConcreteStorage extends MapStorage { constructor () { - super(); + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + + super(inversifyContainerFacade.get(ServiceIdentifiers.IRandomGenerator)); } } diff --git a/test/unit-tests/utils/ArrayUtils.spec.ts b/test/unit-tests/utils/ArrayUtils.spec.ts new file mode 100644 index 00000000..021b69e5 --- /dev/null +++ b/test/unit-tests/utils/ArrayUtils.spec.ts @@ -0,0 +1,117 @@ +import { assert } from 'chai'; + +import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; + +import { IArrayUtils } from '../../../src/interfaces/utils/IArrayUtils'; +import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; + +import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; + +describe('Utils', () => { + let arrayUtils: IArrayUtils; + + before(() => { + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + arrayUtils = inversifyContainerFacade.get(ServiceIdentifiers.IArrayUtils); + }); + + describe('arrayRange (length: number): number[]', () => { + describe('range length more than 0', () => { + const rangeLength: number = 5; + const expectedArray: number[] = [0, 1, 2, 3, 4]; + + let array: number[]; + + before(() => { + array = arrayUtils.arrayRange(rangeLength); + }); + + it('should return array with range of numbers', () => { + assert.deepEqual(array, expectedArray); + }); + }); + + describe('range length is 0', () => { + const rangeLength: number = 0; + const expectedArray: number[] = []; + + let array: number[]; + + before(() => { + array = arrayUtils.arrayRange(rangeLength); + }); + + it('should return empty array', () => { + assert.deepEqual(array, expectedArray); + }); + }); + + describe('range length less than 0', () => { + const rangeLength: number = -5; + const expectedArray: number[] = []; + + let array: number[]; + + before(() => { + array = arrayUtils.arrayRange(rangeLength); + }); + + it('should return empty array', () => { + assert.deepEqual(array, expectedArray); + }); + }); + }); + + describe('arrayRotate (array: T[], times: number): T[]', () => { + let array: number[], + rotatedArray: number[]; + + beforeEach(() => { + array = [1, 2, 3, 4, 5, 6]; + }); + + describe('value is not 0', () => { + const rotateValue: number = 2; + const expectedArray: number[] = [5, 6, 1, 2, 3, 4]; + + beforeEach(() => { + rotatedArray = arrayUtils.arrayRotate(array, rotateValue); + }); + + it('should rotate (shift) array by a given value', () => { + assert.deepEqual(rotatedArray, expectedArray); + }); + }); + + describe('value equals or less 0', () => { + const rotateValue: number = 0; + const expectedArray: number[] = [1, 2, 3, 4, 5, 6]; + + beforeEach(() => { + rotatedArray = arrayUtils.arrayRotate(array, rotateValue); + }); + + it('shouldn\'t rotate array', () => { + assert.deepEqual(rotatedArray, expectedArray); + }); + }); + + describe('empty array', () => { + const emptyArray: number[] = []; + const rotateValue: number = 5; + const expectedError: ReferenceErrorConstructor = ReferenceError; + + let testFunc: () => void; + + beforeEach(() => { + testFunc = () => arrayUtils.arrayRotate(emptyArray, rotateValue); + }); + + it('should throw exception if array is empty', () => { + assert.throws(testFunc, expectedError); + }); + }); + }); +}); diff --git a/test/unit-tests/utils/crypt-utils/CryptUtils.spec.ts b/test/unit-tests/utils/CryptUtils.spec.ts similarity index 72% rename from test/unit-tests/utils/crypt-utils/CryptUtils.spec.ts rename to test/unit-tests/utils/CryptUtils.spec.ts index cbd9761f..c5cf74ad 100644 --- a/test/unit-tests/utils/crypt-utils/CryptUtils.spec.ts +++ b/test/unit-tests/utils/CryptUtils.spec.ts @@ -1,15 +1,29 @@ import { assert } from 'chai'; -import { CryptUtils } from '../../../../src/utils/CryptUtils'; +import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; + +import { ICryptUtils } from '../../../src/interfaces/utils/ICryptUtils'; +import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; + +import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; describe('CryptUtils', () => { + let cryptUtils: ICryptUtils; + + before(() => { + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + cryptUtils = inversifyContainerFacade.get(ServiceIdentifiers.ICryptUtils); + }); + describe('btoa (string: string): string', () => { const expectedString: string = 'c3RyaW5n'; let string: string; before(() => { - string = CryptUtils.btoa('string'); + string = cryptUtils.btoa('string'); }); it('should create a base-64 encoded string from a given string', () => { @@ -25,7 +39,7 @@ describe('CryptUtils', () => { diffString: string; before(() => { - [hiddenString, diffString] = CryptUtils.hideString(originalString, hiddenStringLength); + [hiddenString, diffString] = cryptUtils.hideString(originalString, hiddenStringLength); }); describe('hidden string length check', () => { @@ -65,8 +79,8 @@ describe('CryptUtils', () => { decodedString: string; before(() => { - encodedString = CryptUtils.rc4(string, key); - decodedString = CryptUtils.rc4(encodedString, key); + encodedString = cryptUtils.rc4(string, key); + decodedString = cryptUtils.rc4(encodedString, key); }); it('should encode string using the rc4 algorithm', () => { diff --git a/test/unit-tests/utils/EscapeSequenceEncoder.spec.ts b/test/unit-tests/utils/EscapeSequenceEncoder.spec.ts new file mode 100644 index 00000000..5e8bafe9 --- /dev/null +++ b/test/unit-tests/utils/EscapeSequenceEncoder.spec.ts @@ -0,0 +1,52 @@ +import { assert } from 'chai'; + +import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; +import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; + +import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; +import { IEscapeSequenceEncoder } from '../../../src/interfaces/utils/IEscapeSequenceEncoder'; + + +describe('EscapeSequenceEncoder', () => { + describe('encode (string: string, encodeAllSymbols: boolean = false): string', () => { + let escapeSequenceEncoder: IEscapeSequenceEncoder; + + before(() => { + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + escapeSequenceEncoder = inversifyContainerFacade + .get(ServiceIdentifiers.IEscapeSequenceEncoder); + }); + + describe('variant #1: default', () => { + const string: string = 'string'; + const expectedString: string = '\\x73\\x74\\x72\\x69\\x6e\\x67'; + + let actualString: string; + + before(() => { + actualString = escapeSequenceEncoder.encode(string, true); + }); + + it('should return a string where all characters are encoded', () => { + assert.equal(actualString, expectedString); + }); + }); + + describe('variant #2: escape `escape sequences`', () => { + const string: string = 'abc\'\\r\\n'; + const expectedString: string = 'abc\\x27\\x5cr\\x5cn'; + + let actualString: string; + + before(() => { + actualString = escapeSequenceEncoder.encode(string, false); + }); + + it('should return a string where all `escape sequences` are encoded', () => { + assert.equal(actualString, expectedString); + }); + }); + }); +}); diff --git a/test/unit-tests/utils/RandomGeneratorUtils.spec.ts b/test/unit-tests/utils/RandomGeneratorUtils.spec.ts new file mode 100644 index 00000000..dbcdccb0 --- /dev/null +++ b/test/unit-tests/utils/RandomGeneratorUtils.spec.ts @@ -0,0 +1,45 @@ +import { assert } from 'chai'; + +import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; + +import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; +import { IRandomGenerator } from '../../../src/interfaces/utils/IRandomGenerator'; + +import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; + +describe('RandomGeneratorUtils', () => { + describe('getRandomVariableName (length: number = 6): string', () => { + let randomGenerator: IRandomGenerator, + randomVariableName: string, + regExp: RegExp; + + before(() => { + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); + + inversifyContainerFacade.load({}); + randomGenerator = inversifyContainerFacade.get(ServiceIdentifiers.IRandomGenerator) + }); + + describe('variant #1: string with random variable of length `4`', () => { + before(() => { + randomVariableName = randomGenerator.getRandomVariableName(4); + regExp = /^_0x(\w){4}$/; + }); + + it('should return random variable name', () => { + assert.match(randomVariableName, regExp); + }) + }); + + describe('variant #2: string with random variable of length `6`', () => { + before(() => { + randomVariableName = randomGenerator.getRandomVariableName(6); + regExp = /^_0x(\w){4,6}$/; + }); + + it('should return random variable name', () => { + assert.match(randomVariableName, regExp); + }) + }); + }); +}); diff --git a/test/unit-tests/utils/utils/Utils.spec.ts b/test/unit-tests/utils/Utils.spec.ts similarity index 63% rename from test/unit-tests/utils/utils/Utils.spec.ts rename to test/unit-tests/utils/Utils.spec.ts index 78482957..7d91d537 100644 --- a/test/unit-tests/utils/utils/Utils.spec.ts +++ b/test/unit-tests/utils/Utils.spec.ts @@ -1,108 +1,10 @@ import { assert } from 'chai'; -import { Utils } from '../../../../src/utils/Utils'; +import { JSFuck } from '../../../src/enums/JSFuck'; -import { JSFuck } from '../../../../src/enums/JSFuck'; +import { Utils } from '../../../src/utils/Utils'; describe('Utils', () => { - describe('arrayRange (length: number): number[]', () => { - describe('range length more than 0', () => { - const rangeLength: number = 5; - const expectedArray: number[] = [0, 1, 2, 3, 4]; - - let array: number[]; - - before(() => { - array = Utils.arrayRange(rangeLength); - }); - - it('should return array with range of numbers', () => { - assert.deepEqual(array, expectedArray); - }); - }); - - describe('range length is 0', () => { - const rangeLength: number = 0; - const expectedArray: number[] = []; - - let array: number[]; - - before(() => { - array = Utils.arrayRange(rangeLength); - }); - - it('should return empty array', () => { - assert.deepEqual(array, expectedArray); - }); - }); - - describe('range length less than 0', () => { - const rangeLength: number = -5; - const expectedArray: number[] = []; - - let array: number[]; - - before(() => { - array = Utils.arrayRange(rangeLength); - }); - - it('should return empty array', () => { - assert.deepEqual(array, expectedArray); - }); - }); - }); - - describe('arrayRotate (array: T[], times: number): T[]', () => { - let array: number[], - rotatedArray: number[]; - - beforeEach(() => { - array = [1, 2, 3, 4, 5, 6]; - }); - - describe('value is not 0', () => { - const rotateValue: number = 2; - const expectedArray: number[] = [5, 6, 1, 2, 3, 4]; - - beforeEach(() => { - rotatedArray = Utils.arrayRotate(array, rotateValue); - }); - - it('should rotate (shift) array by a given value', () => { - assert.deepEqual(rotatedArray, expectedArray); - }); - }); - - describe('value equals or less 0', () => { - const rotateValue: number = 0; - const expectedArray: number[] = [1, 2, 3, 4, 5, 6]; - - beforeEach(() => { - rotatedArray = Utils.arrayRotate(array, rotateValue); - }); - - it('shouldn\'t rotate array', () => { - assert.deepEqual(rotatedArray, expectedArray); - }); - }); - - describe('empty array', () => { - const emptyArray: number[] = []; - const rotateValue: number = 5; - const expectedError: ReferenceErrorConstructor = ReferenceError; - - let testFunc: () => void; - - beforeEach(() => { - testFunc = () => Utils.arrayRotate(emptyArray, rotateValue); - }); - - it('should throw exception if array is empty', () => { - assert.throws(testFunc, expectedError); - }); - }); - }); - describe('decToHex (dec: number): string', () => { describe('variant #1: number `0`', () => { const number: number = 0; @@ -336,36 +238,4 @@ describe('Utils', () => { assert.equal(actualString, expectedString); }); }); - - describe('stringToUnicodeEscapeSequence (string: string, nonLatinAndNonDigitsOnly: boolean = false): string', () => { - describe('variant #1: default', () => { - const string: string = 'string'; - const expectedString: string = '\\x73\\x74\\x72\\x69\\x6e\\x67'; - - let actualString: string; - - before(() => { - actualString = Utils.stringToUnicodeEscapeSequence(string, true); - }); - - it('should return a unicode escape sequence based on a given string', () => { - assert.equal(actualString, expectedString); - }); - }); - - describe('variant #2: escape `escape sequences`', () => { - const string: string = 'abc\'\\r\\n'; - const expectedString: string = 'abc\\x27\\x5cr\\x5cn'; - - let actualString: string; - - before(() => { - actualString = Utils.stringToUnicodeEscapeSequence(string, false); - }); - - it('should return a string where all `escape sequences` are escaped', () => { - assert.equal(actualString, expectedString); - }); - }); - }); }); diff --git a/test/unit-tests/utils/random-generator-utils/RandomGeneratorUtils.spec.ts b/test/unit-tests/utils/random-generator-utils/RandomGeneratorUtils.spec.ts deleted file mode 100644 index ae614465..00000000 --- a/test/unit-tests/utils/random-generator-utils/RandomGeneratorUtils.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { assert } from 'chai'; - -import { RandomGeneratorUtils } from '../../../../src/utils/RandomGeneratorUtils'; - -describe('RandomGeneratorUtils', () => { - describe('getRandomVariableName (length: number = 6): string', () => { - let randomVariableName: string, - regExp: RegExp; - - describe('variant #1: string with random variable of length `4`', () => { - before(() => { - randomVariableName = RandomGeneratorUtils.getRandomVariableName(4); - regExp = /^_0x(\w){4}$/; - }); - - it('should return random variable name', () => { - assert.match(randomVariableName, regExp); - }) - }); - - describe('variant #2: string with random variable of length `6`', () => { - before(() => { - randomVariableName = RandomGeneratorUtils.getRandomVariableName(6); - regExp = /^_0x(\w){4,6}$/; - }); - - it('should return random variable name', () => { - assert.match(randomVariableName, regExp); - }) - }); - }); -}); diff --git a/yarn.lock b/yarn.lock index 49e6581e..1bc910e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/chai@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.0.tgz#4c9adabd2d04265769e6d9e847e86cc404dc7dcd" +"@types/chai@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.1.tgz#37fea779617cfec3fd2b19a0247e8bbdd5133bf6" "@types/chance@0.7.33": version "0.7.33" @@ -45,16 +45,16 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.41.tgz#e27cf0817153eb9f2713b2d3f6c68f1e1c3ca608" "@types/node@*": - version "7.0.31" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.31.tgz#80ea4d175599b2a00149c29a10a4eb2dff592e86" + version "8.0.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.1.tgz#89c271e0c3b9ebb6a3756dd601336970b6228b77" -"@types/node@8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.0.tgz#acaa89247afddc7967e9902fd11761dadea1a555" +"@types/node@8.0.3": + version "8.0.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.3.tgz#fca61c26f83e5f453166114f57d53a47feb36d45" -"@types/sinon@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-2.3.1.tgz#5e214093e9e2345219ab0f31bf310c9790ad0712" +"@types/sinon@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-2.3.2.tgz#1e1e99e67162d78e2db17816892bf93bf5209885" "@types/string-template@1.0.2": version "1.0.2" @@ -378,11 +378,11 @@ babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-loader@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.0.0.tgz#2e43a66bee1fff4470533d0402c8a4532fafbaf7" +babel-loader@7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.0.tgz#3fbf2581f085774bd9642dca9990e6d6c1491144" dependencies: - find-cache-dir "^0.1.1" + find-cache-dir "^1.0.0" loader-utils "^1.0.2" mkdirp "^0.5.1" @@ -935,6 +935,12 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" +commander@2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.10.0.tgz#e1f5d3245de246d1a5ca04702fa1ad1bd7e405fe" + dependencies: + graceful-readlink ">= 1.0.0" + commander@2.9.0, commander@^2.8.1, commander@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -1437,13 +1443,13 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" dependencies: commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" + make-dir "^1.0.0" + pkg-dir "^2.0.0" find-up@^1.0.0: version "1.1.2" @@ -1452,6 +1458,12 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2111,6 +2123,13 @@ loader-utils@^1.0.2, loader-utils@^1.1.0: emojis-list "^2.0.0" json5 "^0.5.0" +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + lodash._baseassign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" @@ -2187,6 +2206,12 @@ lru-cache@^4.0.1: pseudomap "^1.0.1" yallist "^2.0.0" +make-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978" + dependencies: + pify "^2.3.0" + make-error@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.0.tgz#52ad3a339ccf10ce62b4040b708fe707244b8b96" @@ -2502,6 +2527,16 @@ output-file-sync@^1.1.0: mkdirp "^0.5.1" object-assign "^4.1.0" +p-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + pako@~0.2.0: version "0.2.9" resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" @@ -2541,6 +2576,10 @@ path-exists@^2.0.0: dependencies: pinkie-promise "^2.0.0" +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -2581,7 +2620,7 @@ performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" -pify@^2.0.0: +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -2595,11 +2634,11 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" dependencies: - find-up "^1.0.0" + find-up "^2.1.0" pre-commit@1.2.2: version "1.2.2" @@ -2936,9 +2975,9 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sinon@2.3.4: - version "2.3.4" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.3.4.tgz#466ad8d1bae86d6db51aa218b92e997bc3e5db88" +sinon@2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.3.5.tgz#9a2fc0ff8d526da716f30953aa2c65d518917f6c" dependencies: diff "^3.1.0" formatio "1.2.0" @@ -3174,9 +3213,9 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -ts-node@3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-3.0.6.tgz#55127ff790c7eebf6ba68c1e6dde94b09aaa21e0" +ts-node@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-3.1.0.tgz#a75ec5aeb48f3058b1b945dba765f1150ba88f8c" dependencies: arrify "^1.0.0" chalk "^1.1.1"