瀏覽代碼

rc4 and base64 decoding performance update

sanex3339 8 年之前
父節點
當前提交
b077c74f69

+ 85 - 8
dist/index.js

@@ -224,10 +224,10 @@ var Utils = function () {
                 j = 0,
                 x = void 0,
                 result = '';
-            for (var i = 0; i < 256; i++) {
+            for (var i = 0; i < 255; i++) {
                 s[i] = i;
             }
-            for (i = 0; i < 256; i++) {
+            for (i = 0; i < 255; i++) {
                 j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
                 x = s[i];
                 s[i] = s[j];
@@ -988,7 +988,7 @@ var StringLiteralReplacer = function (_AbstractReplacer_1$A) {
     _createClass(StringLiteralReplacer, [{
         key: 'replace',
         value: function replace(nodeValue) {
-            var replaceWithUnicodeArrayFlag = nodeValue.length > StringLiteralReplacer.minimumLengthForUnicodeArray && Math.random() <= this.options.unicodeArrayThreshold;
+            var replaceWithUnicodeArrayFlag = nodeValue.length >= StringLiteralReplacer.minimumLengthForUnicodeArray && Math.random() <= this.options.unicodeArrayThreshold;
             if (this.options.unicodeArray && replaceWithUnicodeArrayFlag) {
                 return this.replaceStringLiteralWithUnicodeArrayCall(nodeValue);
             }
@@ -1037,7 +1037,7 @@ var StringLiteralReplacer = function (_AbstractReplacer_1$A) {
     return StringLiteralReplacer;
 }(AbstractReplacer_1.AbstractReplacer);
 
-StringLiteralReplacer.minimumLengthForUnicodeArray = 2;
+StringLiteralReplacer.minimumLengthForUnicodeArray = 3;
 StringLiteralReplacer.rc4Keys = Utils_1.Utils.getRandomGenerator().n(function () {
     return Utils_1.Utils.getRandomGenerator().string({ length: 4 });
 }, 50);
@@ -1360,13 +1360,14 @@ var NodeUtils_1 = __webpack_require__(1);
 var ObjectExpressionObfuscator_1 = __webpack_require__(52);
 var SelfDefendingNodesGroup_1 = __webpack_require__(44);
 var UnicodeArrayNodesGroup_1 = __webpack_require__(45);
+var VariableDeclarationObfuscator_1 = __webpack_require__(53);
 var StackTraceAnalyzer_1 = __webpack_require__(58);
 
 var Obfuscator = function () {
     function Obfuscator(options) {
         _classCallCheck(this, Obfuscator);
 
-        this.nodeObfuscators = new Map([[NodeType_1.NodeType.ArrowFunctionExpression, [FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.ClassDeclaration, [FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator]], [NodeType_1.NodeType.CatchClause, [CatchClauseObfuscator_1.CatchClauseObfuscator]], [NodeType_1.NodeType.MemberExpression, [MemberExpressionObfuscator_1.MemberExpressionObfuscator]], [NodeType_1.NodeType.MethodDefinition, [MethodDefinitionObfuscator_1.MethodDefinitionObfuscator]], [NodeType_1.NodeType.ObjectExpression, [ObjectExpressionObfuscator_1.ObjectExpressionObfuscator]], [NodeType_1.NodeType.Literal, [LiteralObfuscator_1.LiteralObfuscator]]]);
+        this.nodeObfuscators = new Map([[NodeType_1.NodeType.ArrowFunctionExpression, [FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.ClassDeclaration, [FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator]], [NodeType_1.NodeType.CatchClause, [CatchClauseObfuscator_1.CatchClauseObfuscator]], [NodeType_1.NodeType.FunctionDeclaration, [FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator, FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.FunctionExpression, [FunctionObfuscator_1.FunctionObfuscator]], [NodeType_1.NodeType.MemberExpression, [MemberExpressionObfuscator_1.MemberExpressionObfuscator]], [NodeType_1.NodeType.MethodDefinition, [MethodDefinitionObfuscator_1.MethodDefinitionObfuscator]], [NodeType_1.NodeType.ObjectExpression, [ObjectExpressionObfuscator_1.ObjectExpressionObfuscator]], [NodeType_1.NodeType.VariableDeclaration, [VariableDeclarationObfuscator_1.VariableDeclarationObfuscator]], [NodeType_1.NodeType.Literal, [LiteralObfuscator_1.LiteralObfuscator]]]);
         this.options = options;
         this.nodes = new Map([].concat(_toConsumableArray(new DomainLockNodesGroup_1.DomainLockNodesGroup(this.options).getNodes()), _toConsumableArray(new SelfDefendingNodesGroup_1.SelfDefendingNodesGroup(this.options).getNodes()), _toConsumableArray(new ConsoleOutputNodesGroup_1.ConsoleOutputNodesGroup(this.options).getNodes()), _toConsumableArray(new DebugProtectionNodesGroup_1.DebugProtectionNodesGroup(this.options).getNodes()), _toConsumableArray(new UnicodeArrayNodesGroup_1.UnicodeArrayNodesGroup(this.options).getNodes())));
     }
@@ -3147,7 +3148,83 @@ var ObjectExpressionObfuscator = function (_AbstractNodeObfuscat) {
 exports.ObjectExpressionObfuscator = ObjectExpressionObfuscator;
 
 /***/ },
-/* 53 */,
+/* 53 */
+/***/ function(module, exports, __webpack_require__) {
+
+"use strict";
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var estraverse = __webpack_require__(3);
+var NodeType_1 = __webpack_require__(5);
+var AbstractNodeObfuscator_1 = __webpack_require__(7);
+var IdentifierReplacer_1 = __webpack_require__(14);
+var Nodes_1 = __webpack_require__(2);
+var NodeUtils_1 = __webpack_require__(1);
+
+var VariableDeclarationObfuscator = function (_AbstractNodeObfuscat) {
+    _inherits(VariableDeclarationObfuscator, _AbstractNodeObfuscat);
+
+    function VariableDeclarationObfuscator(nodes, options) {
+        _classCallCheck(this, VariableDeclarationObfuscator);
+
+        var _this = _possibleConstructorReturn(this, (VariableDeclarationObfuscator.__proto__ || Object.getPrototypeOf(VariableDeclarationObfuscator)).call(this, nodes, options));
+
+        _this.identifierReplacer = new IdentifierReplacer_1.IdentifierReplacer(_this.nodes, _this.options);
+        return _this;
+    }
+
+    _createClass(VariableDeclarationObfuscator, [{
+        key: 'obfuscateNode',
+        value: function obfuscateNode(variableDeclarationNode, parentNode) {
+            if (parentNode.type === NodeType_1.NodeType.Program) {
+                return;
+            }
+            this.storeVariableNames(variableDeclarationNode);
+            this.replaceVariableNames(variableDeclarationNode, parentNode);
+        }
+    }, {
+        key: 'storeVariableNames',
+        value: function storeVariableNames(variableDeclarationNode) {
+            var _this2 = this;
+
+            variableDeclarationNode.declarations.forEach(function (declarationNode) {
+                NodeUtils_1.NodeUtils.typedReplace(declarationNode.id, NodeType_1.NodeType.Identifier, {
+                    enter: function enter(node) {
+                        return _this2.identifierReplacer.storeNames(node.name);
+                    }
+                });
+            });
+        }
+    }, {
+        key: 'replaceVariableNames',
+        value: function replaceVariableNames(variableDeclarationNode, variableParentNode) {
+            var _this3 = this;
+
+            var scopeNode = variableDeclarationNode.kind === 'var' ? NodeUtils_1.NodeUtils.getBlockScopeOfNode(variableDeclarationNode) : variableParentNode;
+            estraverse.replace(scopeNode, {
+                enter: function enter(node, parentNode) {
+                    if (!node.obfuscated && Nodes_1.Nodes.isReplaceableIdentifierNode(node, parentNode)) {
+                        node.name = _this3.identifierReplacer.replace(node.name);
+                    }
+                }
+            });
+        }
+    }]);
+
+    return VariableDeclarationObfuscator;
+}(AbstractNodeObfuscator_1.AbstractNodeObfuscator);
+
+exports.VariableDeclarationObfuscator = VariableDeclarationObfuscator;
+
+/***/ },
 /* 54 */
 /***/ function(module, exports, __webpack_require__) {
 
@@ -3857,7 +3934,7 @@ exports.AtobTemplate = AtobTemplate;
 "use strict";
 
 function Rc4Template() {
-    return "\n        function rc4 (str, key) {\n\t        var s = [], j = 0, x, res = '';\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    ";
+    return "\n        function rc4 (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 < 255; i++) {\n                s[i] = i;\n            }\n \n            for (i = 0; i < 255; 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    ";
 }
 exports.Rc4Template = Rc4Template;
 
@@ -3979,7 +4056,7 @@ exports.UnicodeArrayCallsWrapperTemplate = UnicodeArrayCallsWrapperTemplate;
 "use strict";
 
 function UnicodeArrayRc4DecodeNodeTemplate() {
-    return "\n        if (!{unicodeArrayCallsWrapperName}.atobPolyfillAppended) {            \n            {atobPolyfill}\n            \n            {unicodeArrayCallsWrapperName}.atobPolyfillAppended = true;\n        }\n        \n        if (!{unicodeArrayCallsWrapperName}.rc4) {            \n            {rc4Polyfill}\n            \n            {unicodeArrayCallsWrapperName}.rc4 = rc4;\n        }\n        \n        if (!{unicodeArrayCallsWrapperName}.base64DecodeUnicode) {                \n            {unicodeArrayCallsWrapperName}.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                        \n        if (!{unicodeArrayCallsWrapperName}.data) {\n            {unicodeArrayCallsWrapperName}.data = {};\n        }\n\n        if ({unicodeArrayCallsWrapperName}.data[index] === undefined) {\n            if (!{unicodeArrayCallsWrapperName}.once) {\n                {selfDefendingCode}\n                \n                {unicodeArrayCallsWrapperName}.once = true;\n            }\n            \n            value = {unicodeArrayCallsWrapperName}.rc4(\n                {unicodeArrayCallsWrapperName}.base64DecodeUnicode(value), \n                key\n            );\n            {unicodeArrayCallsWrapperName}.data[index] = value;\n        } else {\n            value = {unicodeArrayCallsWrapperName}.data[index];\n        }\n    ";
+    return "\n        if (!{unicodeArrayCallsWrapperName}.atobPolyfillAppended) {            \n            {atobPolyfill}\n            \n            {unicodeArrayCallsWrapperName}.atobPolyfillAppended = true;\n        }\n        \n        if (!{unicodeArrayCallsWrapperName}.rc4) {            \n            {rc4Polyfill}\n            \n            {unicodeArrayCallsWrapperName}.rc4 = rc4;\n        }\n                        \n        if (!{unicodeArrayCallsWrapperName}.data) {\n            {unicodeArrayCallsWrapperName}.data = {};\n        }\n\n        if ({unicodeArrayCallsWrapperName}.data[index] === undefined) {\n            if (!{unicodeArrayCallsWrapperName}.once) {\n                {selfDefendingCode}\n                \n                {unicodeArrayCallsWrapperName}.once = true;\n            }\n            \n            value = {unicodeArrayCallsWrapperName}.rc4(value, key);\n            {unicodeArrayCallsWrapperName}.data[index] = value;\n        } else {\n            value = {unicodeArrayCallsWrapperName}.data[index];\n        }\n    ";
 }
 exports.UnicodeArrayRc4DecodeNodeTemplate = UnicodeArrayRc4DecodeNodeTemplate;
 

+ 2 - 2
src/Utils.ts

@@ -187,11 +187,11 @@ export class Utils {
             x: number,
             result: string = '';
 
-        for (var i = 0; i < 256; i++) {
+        for (var i = 0; i < 255; i++) {
             s[i] = i;
         }
 
-        for (i = 0; i < 256; i++) {
+        for (i = 0; i < 255; i++) {
             j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
             x = s[i];
             s[i] = s[j];

+ 2 - 2
src/node-obfuscators/replacers/StringLiteralReplacer.ts

@@ -12,7 +12,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
     /**
      * @type {number}
      */
-    private static minimumLengthForUnicodeArray: number = 2;
+    private static minimumLengthForUnicodeArray: number = 3;
 
     /**
      * @type {string[]}
@@ -26,7 +26,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
      */
     public replace (nodeValue: string): string {
         const replaceWithUnicodeArrayFlag: boolean = (
-            nodeValue.length > StringLiteralReplacer.minimumLengthForUnicodeArray
+            nodeValue.length >= StringLiteralReplacer.minimumLengthForUnicodeArray
             && Math.random() <= this.options.unicodeArrayThreshold
         );
 

+ 14 - 6
src/templates/custom-nodes/Rc4Template.ts

@@ -4,13 +4,21 @@
 export function Rc4Template (): string {
     return `
         function rc4 (str, key) {
-	        var s = [], j = 0, x, res = '';
-	        
-	        for (var i = 0; i < 256; i++) {
+            var s = [], j = 0, x, res = '', newStr = '';
+           
+            str = atob(str);
+                
+            for (var k = 0, length = str.length; k < length; k++) {
+                newStr += '%' + ('00' + str.charCodeAt(k).toString(16)).slice(-2);
+            }
+        
+            str = decodeURIComponent(newStr);
+                    	        
+	        for (var i = 0; i < 255; i++) {
                 s[i] = i;
             }
-            
-            for (i = 0; i < 256; i++) {
+ 
+            for (i = 0; i < 255; i++) {
                 j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
                 x = s[i];
                 s[i] = s[j];
@@ -28,7 +36,7 @@ export function Rc4Template (): string {
                 s[j] = x;
                 res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
             }
-            
+                      
             return res;
         }
     `;

+ 1 - 17
src/templates/custom-nodes/unicode-array-nodes/unicode-array-calls-wrapper/UnicodeArrayRC4DecodeNodeTemplate.ts

@@ -14,19 +14,6 @@ export function UnicodeArrayRc4DecodeNodeTemplate (): string {
             
             {unicodeArrayCallsWrapperName}.rc4 = rc4;
         }
-        
-        if (!{unicodeArrayCallsWrapperName}.base64DecodeUnicode) {                
-            {unicodeArrayCallsWrapperName}.base64DecodeUnicode = function (str) {
-                var string = atob(str);
-                var newStringChars = [];
-                
-                for (var i = 0, length = string.length; i < length; i++) {
-                    newStringChars += '%' + ('00' + string.charCodeAt(i).toString(16)).slice(-2);
-                }
-                
-                return decodeURIComponent(newStringChars);
-            };
-        }
                         
         if (!{unicodeArrayCallsWrapperName}.data) {
             {unicodeArrayCallsWrapperName}.data = {};
@@ -39,10 +26,7 @@ export function UnicodeArrayRc4DecodeNodeTemplate (): string {
                 {unicodeArrayCallsWrapperName}.once = true;
             }
             
-            value = {unicodeArrayCallsWrapperName}.rc4(
-                {unicodeArrayCallsWrapperName}.base64DecodeUnicode(value), 
-                key
-            );
+            value = {unicodeArrayCallsWrapperName}.rc4(value, key);
             {unicodeArrayCallsWrapperName}.data[index] = value;
         } else {
             value = {unicodeArrayCallsWrapperName}.data[index];