js-confuser 1.5.8 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +2 -2
- package/CHANGELOG.md +69 -0
- package/README.md +143 -7
- package/dist/index.js +33 -4
- package/dist/obfuscator.js +30 -31
- package/dist/options.js +4 -5
- package/dist/order.js +4 -6
- package/dist/probability.js +2 -4
- package/dist/templates/bufferToString.js +13 -0
- package/dist/templates/crash.js +2 -2
- package/dist/templates/es5.js +18 -0
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/calculator.js +77 -21
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
- package/dist/transforms/deadCode.js +33 -25
- package/dist/transforms/dispatcher.js +7 -6
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +3 -1
- package/dist/transforms/es5/es5.js +31 -34
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/finalizer.js +82 -0
- package/dist/transforms/flatten.js +82 -55
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/globalAnalysis.js +88 -0
- package/dist/transforms/identifier/globalConcealing.js +10 -83
- package/dist/transforms/identifier/movedDeclarations.js +2 -8
- package/dist/transforms/identifier/renameVariables.js +39 -27
- package/dist/transforms/identifier/variableAnalysis.js +58 -62
- package/dist/transforms/minify.js +80 -61
- package/dist/transforms/opaquePredicates.js +1 -1
- package/dist/transforms/preparation/preparation.js +2 -2
- package/dist/transforms/preparation.js +231 -0
- package/dist/transforms/renameLabels.js +1 -1
- package/dist/transforms/rgf.js +4 -5
- package/dist/transforms/stack.js +87 -26
- package/dist/transforms/string/encoding.js +150 -179
- package/dist/transforms/string/stringCompression.js +14 -15
- package/dist/transforms/string/stringConcealing.js +25 -8
- package/dist/transforms/string/stringEncoding.js +13 -24
- package/dist/transforms/transform.js +11 -18
- package/dist/traverse.js +24 -18
- package/dist/util/compare.js +2 -2
- package/dist/util/gen.js +15 -0
- package/dist/util/insert.js +31 -7
- package/dist/util/random.js +15 -0
- package/package.json +5 -5
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +26 -29
- package/src/options.ts +17 -21
- package/src/order.ts +4 -8
- package/src/probability.ts +2 -3
- package/src/templates/bufferToString.ts +68 -0
- package/src/templates/crash.ts +5 -9
- package/src/templates/es5.ts +131 -0
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/calculator.ts +122 -59
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
- package/src/transforms/deadCode.ts +383 -26
- package/src/transforms/dispatcher.ts +8 -6
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +3 -1
- package/src/transforms/es5/es5.ts +32 -77
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/finalizer.ts +75 -0
- package/src/transforms/flatten.ts +194 -151
- package/src/transforms/identifier/globalAnalysis.ts +85 -0
- package/src/transforms/identifier/globalConcealing.ts +14 -103
- package/src/transforms/identifier/movedDeclarations.ts +4 -11
- package/src/transforms/identifier/renameVariables.ts +37 -30
- package/src/transforms/identifier/variableAnalysis.ts +66 -73
- package/src/transforms/minify.ts +116 -77
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +238 -0
- package/src/transforms/renameLabels.ts +2 -2
- package/src/transforms/rgf.ts +6 -7
- package/src/transforms/stack.ts +97 -37
- package/src/transforms/string/encoding.ts +115 -212
- package/src/transforms/string/stringCompression.ts +27 -18
- package/src/transforms/string/stringConcealing.ts +41 -11
- package/src/transforms/string/stringEncoding.ts +18 -18
- package/src/transforms/transform.ts +15 -21
- package/src/traverse.ts +24 -12
- package/src/types.ts +11 -2
- package/src/util/compare.ts +2 -2
- package/src/util/gen.ts +21 -1
- package/src/util/insert.ts +49 -9
- package/src/util/random.ts +13 -0
- package/test/code/Cash.test.ts +1 -1
- package/test/code/Dynamic.test.ts +12 -10
- package/test/code/ES6.src.js +136 -0
- package/test/code/ES6.test.ts +28 -2
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +15 -2
- package/test/probability.test.ts +44 -0
- package/test/templates/template.test.ts +1 -1
- package/test/transforms/antiTooling.test.ts +52 -0
- package/test/transforms/calculator.test.ts +40 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
- package/test/transforms/deadCode.test.ts +66 -15
- package/test/transforms/dispatcher.test.ts +44 -1
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/es5/antiDestructuring.test.ts +16 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +195 -3
- package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
- package/test/transforms/identifier/renameVariables.test.ts +108 -0
- package/test/transforms/lock/antiDebug.test.ts +2 -2
- package/test/transforms/minify.test.ts +151 -0
- package/test/transforms/preparation.test.ts +157 -0
- package/test/transforms/rgf.test.ts +56 -29
- package/test/transforms/stack.test.ts +91 -21
- package/test/transforms/string/stringCompression.test.ts +39 -0
- package/test/transforms/string/stringConcealing.test.ts +115 -0
- package/test/transforms/string/stringEncoding.test.ts +53 -2
- package/test/transforms/transform.test.ts +66 -0
- package/test/traverse.test.ts +139 -0
- package/test/util/compare.test.ts +23 -1
- package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
- package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
- package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
- package/src/transforms/hexadecimalNumbers.ts +0 -31
- package/src/transforms/hideInitializingCode.ts +0 -432
- package/src/transforms/label.ts +0 -64
- package/src/transforms/preparation/nameConflicts.ts +0 -102
- package/src/transforms/preparation/preparation.ts +0 -176
- package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
- package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
- package/test/transforms/hideInitializingCode.test.ts +0 -336
- package/test/transforms/preparation/nameConflicts.test.ts +0 -52
- package/test/transforms/preparation/preparation.test.ts +0 -62
|
@@ -13,6 +13,9 @@ var _transform = _interopRequireDefault(require("../transform"));
|
|
|
13
13
|
|
|
14
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Expression Obfuscation runs before Control Flow Flattening
|
|
18
|
+
*/
|
|
16
19
|
class ExpressionObfuscation extends _transform.default {
|
|
17
20
|
constructor(o) {
|
|
18
21
|
super(o);
|
|
@@ -27,10 +30,11 @@ class ExpressionObfuscation extends _transform.default {
|
|
|
27
30
|
var exprs = [];
|
|
28
31
|
var deleteExprs = [];
|
|
29
32
|
object.body.forEach((stmt, i) => {
|
|
30
|
-
if (stmt.type == "ExpressionStatement") {
|
|
33
|
+
if (stmt.type == "ExpressionStatement" && !stmt.directive) {
|
|
31
34
|
var expr = stmt.expression;
|
|
32
35
|
|
|
33
|
-
if (expr.type == "UnaryExpression" && exprs.length
|
|
36
|
+
if (expr.type == "UnaryExpression" && !(expr.operator === "typeof" && expr.argument.type === "Identifier") && exprs.length // typeof is special
|
|
37
|
+
) {
|
|
34
38
|
expr.argument = (0, _gen.SequenceExpression)([...exprs, { ...expr.argument
|
|
35
39
|
}]);
|
|
36
40
|
deleteExprs.push(...exprs);
|
|
@@ -42,7 +46,8 @@ class ExpressionObfuscation extends _transform.default {
|
|
|
42
46
|
if (exprs.length) {
|
|
43
47
|
if (stmt.type == "IfStatement") {
|
|
44
48
|
if (stmt.test.type == "BinaryExpression" && stmt.test.operator !== "**") {
|
|
45
|
-
if (stmt.test.left.type == "UnaryExpression")
|
|
49
|
+
if (stmt.test.left.type == "UnaryExpression" && !(stmt.test.left.operator === "typeof" && stmt.test.left.argument.type === "Identifier") // typeof is special
|
|
50
|
+
) {
|
|
46
51
|
stmt.test.left.argument = (0, _gen.SequenceExpression)([...exprs, { ...stmt.test.left.argument
|
|
47
52
|
}]);
|
|
48
53
|
} else {
|
|
@@ -28,22 +28,23 @@ class SwitchCaseObfuscation extends _transform.default {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
match(object, parents) {
|
|
31
|
-
return object.type == "SwitchStatement" && !object.cases.find(x => !(x.test && typeof x.test === "object" && x.test.type == "Literal" && typeof x.test.value === "number" && Math.abs(x.test.value) < 100000));
|
|
31
|
+
return object.type == "SwitchStatement" && (object.$controlFlowFlattening || !object.cases.find(x => !(x.test && typeof x.test === "object" && x.test.type == "Literal" && typeof x.test.value === "number" && Math.abs(x.test.value) < 100000)));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
transform(object, parents) {
|
|
35
35
|
var types = new Set();
|
|
36
36
|
(0, _traverse.walk)(object.discriminant, [object, ...parents], (o, p) => {
|
|
37
37
|
if (o.type) {
|
|
38
|
-
|
|
39
|
-
types.add(o.type);
|
|
40
|
-
}
|
|
38
|
+
types.add(o.type);
|
|
41
39
|
}
|
|
42
40
|
});
|
|
43
|
-
types.delete("Identifier");
|
|
44
41
|
|
|
45
|
-
if (
|
|
46
|
-
|
|
42
|
+
if (!object.$controlFlowFlattening) {
|
|
43
|
+
types.delete("Identifier");
|
|
44
|
+
|
|
45
|
+
if (types.size) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
var body = parents[0];
|
|
@@ -64,33 +65,25 @@ class SwitchCaseObfuscation extends _transform.default {
|
|
|
64
65
|
return;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
var factor = (0, _random.getRandomInteger)(
|
|
68
|
-
|
|
69
|
-
if (factor == 0) {
|
|
70
|
-
factor = 2;
|
|
71
|
-
}
|
|
72
|
-
|
|
68
|
+
var factor = (0, _random.getRandomInteger)(2, 100);
|
|
73
69
|
var offset = (0, _random.getRandomInteger)(-250, 250);
|
|
74
70
|
var newVar = this.getPlaceholder();
|
|
75
71
|
var newStates = [];
|
|
76
72
|
var max;
|
|
77
|
-
object.cases.forEach(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
max
|
|
73
|
+
object.cases.forEach((caseObject, i) => {
|
|
74
|
+
if (caseObject.test && caseObject.test.type === "Literal" && typeof caseObject.test.value === "number") {
|
|
75
|
+
var current = caseObject.test.value;
|
|
76
|
+
var value = current * factor + offset;
|
|
77
|
+
newStates[i] = value;
|
|
78
|
+
|
|
79
|
+
if (!max || Math.abs(value) > max) {
|
|
80
|
+
max = Math.abs(value);
|
|
81
|
+
}
|
|
84
82
|
}
|
|
85
83
|
});
|
|
86
84
|
|
|
87
85
|
if (max > 100000) {
|
|
88
86
|
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (new Set(newStates).size !== newStates.length) {
|
|
92
|
-
// not possible because of clashing case test
|
|
93
|
-
return;
|
|
94
87
|
} // State variable declaration
|
|
95
88
|
|
|
96
89
|
|
|
@@ -98,7 +91,13 @@ class SwitchCaseObfuscation extends _transform.default {
|
|
|
98
91
|
object.discriminant = (0, _gen.Identifier)(newVar); // possible so override
|
|
99
92
|
|
|
100
93
|
object.cases.forEach((x, i) => {
|
|
101
|
-
x.test
|
|
94
|
+
if (x.test) {
|
|
95
|
+
if (x.test.type === "Literal" && typeof x.test.value === "number") {
|
|
96
|
+
x.test = (0, _gen.Literal)(newStates[i]);
|
|
97
|
+
} else {
|
|
98
|
+
x.test = (0, _gen.BinaryExpression)("+", (0, _gen.BinaryExpression)("*", x.test, (0, _gen.Literal)(factor)), (0, _gen.Literal)(offset));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
102
101
|
});
|
|
103
102
|
}
|
|
104
103
|
|
|
@@ -25,7 +25,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
25
25
|
|
|
26
26
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
27
27
|
|
|
28
|
-
const templates = [(0, _template.default)("\n function curCSS( elem, name, computed ) {\n var ret;\n \n computed = computed || getStyles( elem );\n \n if ( computed ) {\n ret = computed.getPropertyValue( name ) || computed[ name ];\n \n if ( ret === \"\" && !isAttached( elem ) ) {\n ret = redacted.style( elem, name );\n }\n }\n \n return ret !== undefined ?\n \n // Support: IE <=9 - 11+\n // IE returns zIndex value as an integer.\n ret + \"\" :\n ret;\n }"), (0, _template.default)("\n function Example() {\n var state = redacted.useState(false);\n return x(\n ErrorBoundary,\n null,\n x(\n DisplayName,\n null,\n )\n );\n }"), (0, _template.default)("\n const path = require('path');\nconst { version } = require('../../package');\nconst { version: dashboardPluginVersion } = require('@redacted/enterprise-plugin/package');\nconst { version: componentsVersion } = require('@redacted/components/package');\nconst { sdkVersion } = require('@redacted/enterprise-plugin');\nconst isStandaloneExecutable = require('../utils/isStandaloneExecutable');\nconst resolveLocalRedactedPath = require('./resolve-local-redacted-path');\n\nconst redactedPath = path.resolve(__dirname, '../redacted.js');"), (0, _template.default)("\nmodule.exports = async (resolveLocalRedactedPath = ()=>{throw new Error(\"No redacted path provided\")}) => {\n const cliParams = new Set(process.argv.slice(2));\n if (!cliParams.has('--version')) {\n if (cliParams.size !== 1) return false;\n if (!cliParams.has('-v')) return false;\n }\n\n const installationModePostfix = await (async (isStandaloneExecutable, redactedPath) => {\n if (isStandaloneExecutable) return ' (standalone)';\n if (redactedPath === (await resolveLocalRedactedPath())) return ' (local)';\n return '';\n })();\n\n return true;\n};"), (0, _template.default)("\nfunction setCookie(cname, cvalue, exdays) {\n var d = new Date();\n d.setTime(d.getTime() + (exdays*24*60*60*1000));\n var expires = \"expires=\"+ d.toUTCString();\n document.cookie = cname + \"=\" + cvalue + \";\" + expires + \";path=/\";\n}"), (0, _template.default)("function getCookie(cname) {\n var name = cname + \"=\";\n var decodedCookie = decodeURIComponent(document.cookie);\n var ca = decodedCookie.split(';');\n for(var i = 0; i <ca.length; i++) {\n var c = ca[i];\n while (c.charAt(0) == ' ') {\n c = c.substring(1);\n }\n if (c.indexOf(name) == 0) {\n return c.substring(name.length, c.length);\n }\n }\n return \"\";\n}"), (0, _template.default)("function getLocalStorageValue(key, cb){\n if ( typeof key !== \"string\" ) {\n throw new Error(\"Invalid data key provided (not type string)\")\n }\n if ( !key ) {\n throw new Error(\"Invalid data key provided (empty string)\")\n }\n var value = window.localStorage.getItem(key)\n try {\n value = JSON.parse(value)\n } catch ( e ) {\n cb(new Error(\"Serialization error for data '\" + key + \"': \" + e.message))\n }\n\n cb(null, value)\n }"), (0, _template.default)("\n \n var __ = \"(c=ak(<~F$VU'9f)~><&85dBPL-module/from\";\n var s = \"q:function(){var ad=ad=>b(ad-29);if(!T.r[(typeof ab==ad(123)?\";\n var g = \"return U[c[c[d(-199)]-b(205)]]||V[ae(b(166))];case T.o[c[c[c[d(-199)]+d(-174)]-(c[b(119)]-(c[d(-199)]-163))]+ae(b(146))](0)==b(167)?d(-130):-d(-144)\";\n\n __.match(s + g);\n "), (0, _template.default)("\n function vec_pack(vec) {\n return vec[1] * 67108864 + (vec[0] < 0 ? 33554432 | vec[0] : vec[0]);\n }\n \n function vec_unpack(number) {\n switch (((number & 33554432) !== 0) * 1 + (number < 0) * 2) {\n case 0:\n return [number % 33554432, Math.trunc(number / 67108864)];\n case 1:\n return [\n (number % 33554432) - 33554432,\n Math.trunc(number / 67108864) + 1,\n ];\n case 2:\n return [\n (((number + 33554432) % 33554432) + 33554432) % 33554432,\n Math.round(number / 67108864),\n ];\n case 3:\n return [number % 33554432, Math.trunc(number / 67108864)];\n }\n }\n \n let a = vec_pack([2, 4]);\n let b = vec_pack([1, 2]);\n \n let c = a + b; // Vector addition\n let d = c - b; // Vector subtraction\n let e = d * 2; // Scalar multiplication\n let f = e / 2; // Scalar division\n \n console.log(vec_unpack(c)); // [3, 6]\n console.log(vec_unpack(d)); // [2, 4]\n console.log(vec_unpack(e)); // [4, 8]\n console.log(vec_unpack(f)); // [2, 4]\n "), (0, _template.default)("\n function buildCharacterMap(str) {\n const characterMap = {};\n \n for (let char of str.replace(/[^w]/g, \"\").toLowerCase())\n characterMap[char] = characterMap[char] + 1 || 1;\n \n return characterMap;\n }\n \n function isAnagrams(stringA, stringB) {\n const stringAMap = buildCharMap(stringA);\n const stringBMap = buildCharMap(stringB);\n \n for (let char in stringAMap) {\n if (stringAMap[char] !== stringBMap[char]) {\n return false;\n }\n }\n \n if (Object.keys(stringAMap).length !== Object.keys(stringBMap).length) {\n return false;\n }\n \n return true;\n }\n \n /**\n * @param {TreeNode} root\n * @return {boolean}\n */\n function isBalanced(root) {\n const height = getHeightBalanced(root);\n return height !== Infinity;\n }\n \n function getHeightBalanced(node) {\n if (!node) {\n return -1;\n }\n \n const leftTreeHeight = getHeightBalanced(node.left);\n const rightTreeHeight = getHeightBalanced(node.right);\n \n const heightDiff = Math.abs(leftTreeHeight - rightTreeHeight);\n \n if (\n leftTreeHeight === Infinity ||\n rightTreeHeight === Infinity ||\n heightDiff > 1\n ) {\n return Infinity;\n }\n \n const currentHeight = Math.max(leftTreeHeight, rightTreeHeight) + 1;\n return currentHeight;\n }\n \n window[\"__GLOBAL__HELPERS__\"] = {\n buildCharacterMap,\n isAnagrams,\n isBalanced,\n getHeightBalanced,\n };\n ")];
|
|
28
|
+
const templates = [(0, _template.default)("\n function curCSS( elem, name, computed ) {\n var ret;\n \n computed = computed || getStyles( elem );\n \n if ( computed ) {\n ret = computed.getPropertyValue( name ) || computed[ name ];\n \n if ( ret === \"\" && !isAttached( elem ) ) {\n ret = redacted.style( elem, name );\n }\n }\n \n return ret !== undefined ?\n \n // Support: IE <=9 - 11+\n // IE returns zIndex value as an integer.\n ret + \"\" :\n ret;\n }"), (0, _template.default)("\n function Example() {\n var state = redacted.useState(false);\n return x(\n ErrorBoundary,\n null,\n x(\n DisplayName,\n null,\n )\n );\n }"), (0, _template.default)("\n const path = require('path');\nconst { version } = require('../../package');\nconst { version: dashboardPluginVersion } = require('@redacted/enterprise-plugin/package');\nconst { version: componentsVersion } = require('@redacted/components/package');\nconst { sdkVersion } = require('@redacted/enterprise-plugin');\nconst isStandaloneExecutable = require('../utils/isStandaloneExecutable');\nconst resolveLocalRedactedPath = require('./resolve-local-redacted-path');\n\nconst redactedPath = path.resolve(__dirname, '../redacted.js');"), (0, _template.default)("\nmodule.exports = async (resolveLocalRedactedPath = ()=>{throw new Error(\"No redacted path provided\")}) => {\n const cliParams = new Set(process.argv.slice(2));\n if (!cliParams.has('--version')) {\n if (cliParams.size !== 1) return false;\n if (!cliParams.has('-v')) return false;\n }\n\n const installationModePostfix = await (async (isStandaloneExecutable, redactedPath) => {\n if (isStandaloneExecutable) return ' (standalone)';\n if (redactedPath === (await resolveLocalRedactedPath())) return ' (local)';\n return '';\n })();\n\n return true;\n};"), (0, _template.default)("\nfunction setCookie(cname, cvalue, exdays) {\n var d = new Date();\n d.setTime(d.getTime() + (exdays*24*60*60*1000));\n var expires = \"expires=\"+ d.toUTCString();\n document.cookie = cname + \"=\" + cvalue + \";\" + expires + \";path=/\";\n}"), (0, _template.default)("function getCookie(cname) {\n var name = cname + \"=\";\n var decodedCookie = decodeURIComponent(document.cookie);\n var ca = decodedCookie.split(';');\n for(var i = 0; i <ca.length; i++) {\n var c = ca[i];\n while (c.charAt(0) == ' ') {\n c = c.substring(1);\n }\n if (c.indexOf(name) == 0) {\n return c.substring(name.length, c.length);\n }\n }\n return \"\";\n}"), (0, _template.default)("function getLocalStorageValue(key, cb){\n if ( typeof key !== \"string\" ) {\n throw new Error(\"Invalid data key provided (not type string)\")\n }\n if ( !key ) {\n throw new Error(\"Invalid data key provided (empty string)\")\n }\n var value = window.localStorage.getItem(key)\n try {\n value = JSON.parse(value)\n } catch ( e ) {\n cb(new Error(\"Serialization error for data '\" + key + \"': \" + e.message))\n }\n\n cb(null, value)\n }"), (0, _template.default)("\n \n var __ = \"(c=ak(<~F$VU'9f)~><&85dBPL-module/from\";\n var s = \"q:function(){var ad=ad=>b(ad-29);if(!T.r[(typeof ab==ad(123)?\";\n var g = \"return U[c[c[d(-199)]-b(205)]]||V[ae(b(166))];case T.o[c[c[c[d(-199)]+d(-174)]-(c[b(119)]-(c[d(-199)]-163))]+ae(b(146))](0)==b(167)?d(-130):-d(-144)\";\n\n __.match(s + g);\n "), (0, _template.default)("\n function vec_pack(vec) {\n return vec[1] * 67108864 + (vec[0] < 0 ? 33554432 | vec[0] : vec[0]);\n }\n \n function vec_unpack(number) {\n switch (((number & 33554432) !== 0) * 1 + (number < 0) * 2) {\n case 0:\n return [number % 33554432, Math.trunc(number / 67108864)];\n case 1:\n return [\n (number % 33554432) - 33554432,\n Math.trunc(number / 67108864) + 1,\n ];\n case 2:\n return [\n (((number + 33554432) % 33554432) + 33554432) % 33554432,\n Math.round(number / 67108864),\n ];\n case 3:\n return [number % 33554432, Math.trunc(number / 67108864)];\n }\n }\n \n let a = vec_pack([2, 4]);\n let b = vec_pack([1, 2]);\n \n let c = a + b; // Vector addition\n let d = c - b; // Vector subtraction\n let e = d * 2; // Scalar multiplication\n let f = e / 2; // Scalar division\n \n console.log(vec_unpack(c)); // [3, 6]\n console.log(vec_unpack(d)); // [2, 4]\n console.log(vec_unpack(e)); // [4, 8]\n console.log(vec_unpack(f)); // [2, 4]\n "), (0, _template.default)("\n function buildCharacterMap(str) {\n const characterMap = {};\n \n for (let char of str.replace(/[^w]/g, \"\").toLowerCase())\n characterMap[char] = characterMap[char] + 1 || 1;\n \n return characterMap;\n }\n \n function isAnagrams(stringA, stringB) {\n const stringAMap = buildCharMap(stringA);\n const stringBMap = buildCharMap(stringB);\n \n for (let char in stringAMap) {\n if (stringAMap[char] !== stringBMap[char]) {\n return false;\n }\n }\n \n if (Object.keys(stringAMap).length !== Object.keys(stringBMap).length) {\n return false;\n }\n \n return true;\n }\n \n /**\n * @param {TreeNode} root\n * @return {boolean}\n */\n function isBalanced(root) {\n const height = getHeightBalanced(root);\n return height !== Infinity;\n }\n \n function getHeightBalanced(node) {\n if (!node) {\n return -1;\n }\n \n const leftTreeHeight = getHeightBalanced(node.left);\n const rightTreeHeight = getHeightBalanced(node.right);\n \n const heightDiff = Math.abs(leftTreeHeight - rightTreeHeight);\n \n if (\n leftTreeHeight === Infinity ||\n rightTreeHeight === Infinity ||\n heightDiff > 1\n ) {\n return Infinity;\n }\n \n const currentHeight = Math.max(leftTreeHeight, rightTreeHeight) + 1;\n return currentHeight;\n }\n \n window[\"__GLOBAL__HELPERS__\"] = {\n buildCharacterMap,\n isAnagrams,\n isBalanced,\n getHeightBalanced,\n };\n "), (0, _template.default)("\n function ListNode(){}\n var addTwoNumbers = function(l1, l2) {\n var carry = 0;\n var sum = 0;\n var head = new ListNode(0);\n var now = head;\n var a = l1;\n var b = l2;\n while (a !== null || b !== null) {\n sum = (a ? a.val : 0) + (b ? b.val : 0) + carry;\n carry = Math.floor(sum / 10);\n now.next = new ListNode(sum % 10);\n now = now.next;\n a = a ? a.next : null;\n b = b ? b.next : null;\n }\n if (carry) now.next = new ListNode(carry);\n return head.next;\n };\n\n console.log(addTwoNumbers)\n "), (0, _template.default)("\n var threeSum = function(nums) {\n var len = nums.length;\n var res = [];\n var l = 0;\n var r = 0;\n nums.sort((a, b) => (a - b));\n for (var i = 0; i < len; i++) {\n if (i > 0 && nums[i] === nums[i - 1]) continue;\n l = i + 1;\n r = len - 1;\n while (l < r) {\n if (nums[i] + nums[l] + nums[r] < 0) {\n l++;\n } else if (nums[i] + nums[l] + nums[r] > 0) {\n r--;\n } else {\n res.push([nums[i], nums[l], nums[r]]);\n while (l < r && nums[l] === nums[l + 1]) l++;\n while (l < r && nums[r] === nums[r - 1]) r--;\n l++;\n r--;\n }\n }\n }\n return res;\n };\n console.log(threeSum)\n "), (0, _template.default)("\n var combinationSum2 = function(candidates, target) {\n var res = [];\n var len = candidates.length;\n candidates.sort((a, b) => (a - b));\n dfs(res, [], 0, len, candidates, target);\n return res;\n };\n\n var dfs = function (res, stack, index, len, candidates, target) {\n var tmp = null;\n if (target < 0) return;\n if (target === 0) return res.push(stack);\n for (var i = index; i < len; i++) {\n if (candidates[i] > target) break;\n if (i > index && candidates[i] === candidates[i - 1]) continue;\n tmp = Array.from(stack);\n tmp.push(candidates[i]);\n dfs(res, tmp, i + 1, len, candidates, target - candidates[i]);\n }\n };\n\n console.log(combinationSum2);\n "), (0, _template.default)("\n var isScramble = function(s1, s2) {\n return helper({}, s1, s2);\n };\n \n var helper = function (dp, s1, s2) {\n var map = {};\n \n if (dp[s1 + s2] !== undefined) return dp[s1 + s2];\n if (s1 === s2) return true;\n \n for (var j = 0; j < s1.length; j++) {\n if (map[s1[j]] === undefined) map[s1[j]] = 0;\n if (map[s2[j]] === undefined) map[s2[j]] = 0;\n map[s1[j]]++;\n map[s2[j]]--;\n }\n \n for (var key in map) {\n if (map[key] !== 0) {\n dp[s1 + s2] = false;\n return false;\n }\n }\n \n for (var i = 1; i < s1.length; i++) {\n if ((helper(dp, s1.substr(0, i), s2.substr(0, i))\n && helper(dp, s1.substr(i), s2.substr(i))) ||\n (helper(dp, s1.substr(0, i), s2.substr(s2.length - i))\n && helper(dp, s1.substr(i), s2.substr(0, s2.length - i)))) {\n dp[s1 + s2] = true;\n return true;\n }\n }\n \n dp[s1 + s2] = false;\n return false;\n };\n\n console.log(isScramble);\n "), (0, _template.default)("\n var candy = function(ratings) {\n var len = ratings.length;\n var res = [];\n var sum = 0;\n for (var i = 0; i < len; i++) {\n res.push((i !== 0 && ratings[i] > ratings[i - 1]) ? (res[i - 1] + 1) : 1);\n }\n for (var j = len - 1; j >= 0; j--) {\n if (j !== len - 1 && ratings[j] > ratings[j + 1]) res[j] = Math.max(res[j], res[j + 1] + 1);\n sum += res[j];\n }\n return sum;\n };\n \n console.log(candy)\n "), (0, _template.default)("\n var maxPoints = function(points) {\n var max = 0;\n var map = {};\n var localMax = 0;\n var samePoint = 0;\n var k = 0;\n var len = points.length;\n for (var i = 0; i < len; i++) {\n map = {};\n localMax = 0;\n samePoint = 1;\n for (var j = i + 1; j < len; j++) {\n if (points[i].x === points[j].x && points[i].y === points[j].y) {\n samePoint++;\n continue;\n }\n if (points[i].y === points[j].y) k = Number.MAX_SAFE_INTEGER;\n else k = (points[i].x - points[j].x) / (points[i].y - points[j].y);\n if (!map[k]) map[k] = 0;\n map[k]++;\n localMax = Math.max(localMax, map[k]);\n }\n localMax += samePoint;\n max = Math.max(max, localMax);\n }\n return max;\n };\n \n console.log(maxPoints)\n "), (0, _template.default)("\n var maximumGap = function(nums) {\n var len = nums.length;\n if (len < 2) return 0;\n \n var max = Math.max(...nums);\n var min = Math.min(...nums);\n if (max === min) return 0;\n \n var minBuckets = Array(len - 1).fill(Number.MAX_SAFE_INTEGER);\n var maxBuckets = Array(len - 1).fill(Number.MIN_SAFE_INTEGER);\n var gap = Math.ceil((max - min) / (len - 1));\n var index = 0;\n for (var i = 0; i < len; i++) {\n if (nums[i] === min || nums[i] === max) continue;\n index = Math.floor((nums[i] - min) / gap);\n minBuckets[index] = Math.min(minBuckets[index], nums[i]);\n maxBuckets[index] = Math.max(maxBuckets[index], nums[i]);\n }\n \n var maxGap = Number.MIN_SAFE_INTEGER;\n var preVal = min;\n for (var j = 0; j < len - 1; j++) {\n if (minBuckets[j] === Number.MAX_SAFE_INTEGER && maxBuckets[j] === Number.MIN_SAFE_INTEGER) continue;\n maxGap = Math.max(maxGap, minBuckets[j] - preVal);\n preVal = maxBuckets[j];\n }\n maxGap = Math.max(maxGap, max - preVal);\n \n return maxGap;\n };\n\n console.log(maximumGap);\n "), (0, _template.default)("\n /**\n * @param {number} capacity\n */\n var LRUCache = function(capacity) {\n this.capacity = capacity;\n this.length = 0;\n this.map = {};\n this.head = null;\n this.tail = null;\n };\n \n /** \n * @param {number} key\n * @return {number}\n */\n LRUCache.prototype.get = function(key) {\n var node = this.map[key];\n if (node) {\n this.remove(node);\n this.insert(node.key, node.val);\n return node.val;\n } else {\n return -1;\n }\n };\n \n /** \n * @param {number} key \n * @param {number} value\n * @return {void}\n */\n LRUCache.prototype.put = function(key, value) {\n if (this.map[key]) {\n this.remove(this.map[key]);\n this.insert(key, value);\n } else {\n if (this.length === this.capacity) {\n this.remove(this.head);\n this.insert(key, value);\n } else {\n this.insert(key, value);\n this.length++;\n }\n }\n };\n \n /** \n * Your LRUCache object will be instantiated and called as such:\n * var obj = Object.create(LRUCache).createNew(capacity)\n * var param_1 = obj.get(key)\n * obj.put(key,value)\n */\n \n LRUCache.prototype.remove = function (node) {\n var prev = node.prev;\n var next = node.next;\n if (next) next.prev = prev;\n if (prev) prev.next = next;\n if (this.head === node) this.head = next;\n if (this.tail === node) this.tail = prev;\n delete this.map[node.key];\n };\n \n LRUCache.prototype.insert = function (key, val) {\n var node = new List(key, val);\n if (!this.tail) {\n this.tail = node;\n this.head = node;\n } else {\n this.tail.next = node;\n node.prev = this.tail;\n this.tail = node;\n }\n this.map[key] = node;\n };\n\n console.log(LRUCache);\n "), (0, _template.default)("\n var isInterleave = function(s1, s2, s3) {\n var dp = {};\n if (s3.length !== s1.length + s2.length) return false;\n return helper(s1, s2, s3, 0, 0, 0, dp);\n };\n \n var helper = function (s1, s2, s3, i, j, k, dp) {\n var res = false;\n \n if (k >= s3.length) return true;\n if (dp['' + i + j + k] !== undefined) return dp['' + i + j + k];\n \n if (s3[k] === s1[i] && s3[k] === s2[j]) {\n res = helper(s1, s2, s3, i + 1, j, k + 1, dp) || helper(s1, s2, s3, i, j + 1, k + 1, dp);\n } else if (s3[k] === s1[i]) {\n res = helper(s1, s2, s3, i + 1, j, k + 1, dp);\n } else if (s3[k] === s2[j]) {\n res = helper(s1, s2, s3, i, j + 1, k + 1, dp);\n }\n \n dp['' + i + j + k] = res;\n \n return res;\n };\n\n console.log(isInterleave);\n "), (0, _template.default)("\n var solveNQueens = function(n) {\n var res = [];\n if (n === 1 || n >= 4) dfs(res, [], n, 0);\n return res;\n };\n \n var dfs = function (res, points, n, index) {\n for (var i = index; i < n; i++) {\n if (points.length !== i) return;\n for (var j = 0; j < n; j++) {\n if (isValid(points, [i, j])) {\n points.push([i, j]);\n dfs(res, points, n, i + 1);\n if (points.length === n) res.push(buildRes(points));\n points.pop();\n }\n }\n }\n };\n \n var buildRes = function (points) {\n var res = [];\n var n = points.length;\n for (var i = 0; i < n; i++) {\n res[i] = '';\n for (var j = 0; j < n; j++) {\n res[i] += (points[i][1] === j ? 'Q' : '.');\n }\n }\n return res;\n };\n \n var isValid = function (oldPoints, newPoint) {\n var len = oldPoints.length;\n for (var i = 0; i < len; i++) {\n if (oldPoints[i][0] === newPoint[0] || oldPoints[i][1] === newPoint[1]) return false;\n if (Math.abs((oldPoints[i][0] - newPoint[0]) / (oldPoints[i][1] - newPoint[1])) === 1) return false;\n }\n return true;\n };\n\n console.log(solveNQueens);\n ")];
|
|
29
29
|
/**
|
|
30
30
|
* Adds dead code to blocks.
|
|
31
31
|
*
|
|
@@ -37,8 +37,6 @@ class DeadCode extends _transform.default {
|
|
|
37
37
|
constructor(o) {
|
|
38
38
|
super(o, _order.ObfuscateOrder.DeadCode);
|
|
39
39
|
|
|
40
|
-
_defineProperty(this, "usedNames", void 0);
|
|
41
|
-
|
|
42
40
|
_defineProperty(this, "made", void 0);
|
|
43
41
|
|
|
44
42
|
this.made = 0;
|
|
@@ -49,29 +47,39 @@ class DeadCode extends _transform.default {
|
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
transform(object, parents) {
|
|
52
|
-
if ((0, _probability.ComputeProbabilityMap)(this.options.deadCode)) {
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
var variableDeclaration = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, (0, _gen.Literal)(false)));
|
|
62
|
-
var body = (0, _insert.getBlockBody)(object);
|
|
63
|
-
var index = (0, _random.getRandomInteger)(0, body.length);
|
|
64
|
-
var template;
|
|
65
|
-
|
|
66
|
-
do {
|
|
67
|
-
template = (0, _random.choice)(templates);
|
|
68
|
-
} while (this.options.es5 && template.source.includes("async"));
|
|
69
|
-
|
|
70
|
-
var ifStatement = (0, _gen.IfStatement)((0, _gen.Identifier)(name), template.compile(), null);
|
|
71
|
-
body.splice(index, 0, ifStatement);
|
|
72
|
-
(0, _insert.prepend)(object, variableDeclaration);
|
|
73
|
-
};
|
|
50
|
+
if (!(0, _probability.ComputeProbabilityMap)(this.options.deadCode)) {
|
|
51
|
+
return;
|
|
52
|
+
} // Hard-coded limit of 100 Dead Code insertions
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
this.made++;
|
|
56
|
+
|
|
57
|
+
if (this.made > 100) {
|
|
58
|
+
return;
|
|
74
59
|
}
|
|
60
|
+
|
|
61
|
+
return () => {
|
|
62
|
+
var body = (0, _insert.getBlockBody)(object); // Do not place code before Import statements or 'use strict' directives
|
|
63
|
+
|
|
64
|
+
var safeOffset = 0;
|
|
65
|
+
|
|
66
|
+
for (var node of body) {
|
|
67
|
+
if (node.type === "ImportDeclaration" || node.directive) safeOffset++;else break;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var index = (0, _random.getRandomInteger)(safeOffset, body.length);
|
|
71
|
+
var name = this.getPlaceholder();
|
|
72
|
+
var variableDeclaration = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, (0, _gen.Literal)(false)));
|
|
73
|
+
var template;
|
|
74
|
+
|
|
75
|
+
do {
|
|
76
|
+
template = (0, _random.choice)(templates);
|
|
77
|
+
} while (this.options.es5 && template.source.includes("async"));
|
|
78
|
+
|
|
79
|
+
var ifStatement = (0, _gen.IfStatement)((0, _gen.Identifier)(name), template.compile(), null);
|
|
80
|
+
body.splice(index, 0, ifStatement);
|
|
81
|
+
(0, _insert.prepend)(object, variableDeclaration);
|
|
82
|
+
};
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
}
|
|
@@ -80,12 +80,12 @@ class Dispatcher extends _transform.default {
|
|
|
80
80
|
} // Map of FunctionDeclarations
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
var functionDeclarations =
|
|
83
|
+
var functionDeclarations = Object.create(null); // Array of Identifier nodes
|
|
84
84
|
|
|
85
85
|
var identifiers = [];
|
|
86
86
|
var illegalFnNames = new Set(); // New Names for Functions
|
|
87
87
|
|
|
88
|
-
var newFnNames =
|
|
88
|
+
var newFnNames = Object.create(null); // [old name]: randomized name
|
|
89
89
|
|
|
90
90
|
var context = (0, _insert.isVarContext)(object) ? object : (0, _insert.getVarContext)(object, parents);
|
|
91
91
|
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
@@ -102,11 +102,12 @@ class Dispatcher extends _transform.default {
|
|
|
102
102
|
|
|
103
103
|
if (context === c) {
|
|
104
104
|
if (o.type == "FunctionDeclaration" && o.id.name) {
|
|
105
|
+
var name = o.id.name;
|
|
106
|
+
|
|
105
107
|
if (o.$requiresEval || o.async || o.generator || p.find(x => x.$dispatcherSkip || x.type == "MethodDefinition") || o.body.type != "BlockStatement") {
|
|
106
108
|
illegalFnNames.add(name);
|
|
107
|
-
}
|
|
109
|
+
} // If dupe, no routing
|
|
108
110
|
|
|
109
|
-
var name = o.id.name; // If dupe, no routing
|
|
110
111
|
|
|
111
112
|
if (functionDeclarations[name]) {
|
|
112
113
|
illegalFnNames.add(name);
|
|
@@ -163,7 +164,7 @@ class Dispatcher extends _transform.default {
|
|
|
163
164
|
var set = new Set(Object.keys(newFnNames)); // Only make a dispatcher function if it caught any functions
|
|
164
165
|
|
|
165
166
|
if (set.size > 0) {
|
|
166
|
-
var payloadArg = "
|
|
167
|
+
var payloadArg = this.getPlaceholder() + "_dispatcher_" + this.count + "_payload";
|
|
167
168
|
var dispatcherFnName = this.getPlaceholder() + "_dispatcher_" + this.count;
|
|
168
169
|
this.log(dispatcherFnName, set);
|
|
169
170
|
this.count++;
|
|
@@ -264,7 +265,7 @@ class Dispatcher extends _transform.default {
|
|
|
264
265
|
|
|
265
266
|
var newName = newFnNames[o.name];
|
|
266
267
|
|
|
267
|
-
if (!newName) {
|
|
268
|
+
if (!newName || typeof newName !== "string") {
|
|
268
269
|
return;
|
|
269
270
|
}
|
|
270
271
|
|
|
@@ -85,9 +85,13 @@ class AntiClass extends _transform.default {
|
|
|
85
85
|
this.replace(o, (0, _gen.Identifier)(superName));
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
|
-
}
|
|
88
|
+
} // Support class fields
|
|
89
|
+
|
|
89
90
|
|
|
90
|
-
if (methodDefinition.
|
|
91
|
+
if (methodDefinition.type === "PropertyDefinition") {
|
|
92
|
+
var assignmentExpression = (0, _gen.AssignmentExpression)("=", key, value || (0, _gen.Identifier)("undefined"));
|
|
93
|
+
pushingTo.push((0, _gen.ExpressionStatement)(assignmentExpression));
|
|
94
|
+
} else if (methodDefinition.kind == "constructor" || methodDefinition.kind == "method") {
|
|
91
95
|
pushingTo.push((0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", key, value)));
|
|
92
96
|
} else if (methodDefinition.kind == "get" || methodDefinition.kind == "set") {
|
|
93
97
|
var id = (0, _gen.Identifier)(methodDefinition.kind == "get" ? "getters" : "setters");
|
|
@@ -158,6 +158,8 @@ class AntiDestructuring extends _transform.default {
|
|
|
158
158
|
if (x.type == "Identifier") {
|
|
159
159
|
exprs.push((0, _gen.AssignmentExpression)(operator, (0, _insert.clone)(x), realm));
|
|
160
160
|
names.add(x.name);
|
|
161
|
+
} else if (x.type == "MemberExpression") {
|
|
162
|
+
exprs.push((0, _gen.AssignmentExpression)(operator, (0, _insert.clone)(x), realm));
|
|
161
163
|
} else if (x.type == "ObjectPattern") {
|
|
162
164
|
x.properties.forEach(property => {
|
|
163
165
|
recursive(property.value, (0, _gen.MemberExpression)(realm, property.key, property.computed));
|
|
@@ -189,7 +191,7 @@ class AntiDestructuring extends _transform.default {
|
|
|
189
191
|
var seq = (0, _gen.SequenceExpression)([(0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(temp), (0, _insert.clone)(extracting) || (0, _gen.Identifier)("undefined")), ...exprs]);
|
|
190
192
|
|
|
191
193
|
if (object.type == "VariableDeclarator") {
|
|
192
|
-
var i = (0, _insert.getIndexDirect)(object, parents);
|
|
194
|
+
var i = (0, _insert.getIndexDirect)(object, parents[0]);
|
|
193
195
|
var extra = Array.from(names).map(x => {
|
|
194
196
|
return {
|
|
195
197
|
type: "VariableDeclarator",
|
|
@@ -13,8 +13,6 @@ var _insert = require("../../util/insert");
|
|
|
13
13
|
|
|
14
14
|
var _traverse = require("../../traverse");
|
|
15
15
|
|
|
16
|
-
var _template = _interopRequireDefault(require("../../templates/template"));
|
|
17
|
-
|
|
18
16
|
var _order = require("../../order");
|
|
19
17
|
|
|
20
18
|
var _assert = require("assert");
|
|
@@ -31,6 +29,8 @@ var _antiES6Object = _interopRequireDefault(require("./antiES6Object"));
|
|
|
31
29
|
|
|
32
30
|
var _antiSpreadOperator = _interopRequireDefault(require("./antiSpreadOperator"));
|
|
33
31
|
|
|
32
|
+
var _es = require("../../templates/es5");
|
|
33
|
+
|
|
34
34
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
35
|
|
|
36
36
|
/**
|
|
@@ -93,24 +93,44 @@ class AntiArrowFunction extends _transform.default {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* The ES5 options aims to convert ES6 and up features down to ES5-compatible code.
|
|
98
|
+
*
|
|
99
|
+
* The obfuscator regularly adds ES6 code (variable destructuring, spread element, etc.)
|
|
100
|
+
* This transformations goal is undo only these things.
|
|
101
|
+
*/
|
|
102
|
+
|
|
96
103
|
|
|
97
104
|
exports.AntiArrowFunction = AntiArrowFunction;
|
|
98
105
|
|
|
99
|
-
class
|
|
106
|
+
class ES5 extends _transform.default {
|
|
100
107
|
constructor(o) {
|
|
101
|
-
super(o);
|
|
108
|
+
super(o, _order.ObfuscateOrder.ES5);
|
|
109
|
+
this.before.push(new _antiClass.default(o));
|
|
110
|
+
this.before.push(new _antiTemplate.default(o));
|
|
111
|
+
this.before.push(new _antiSpreadOperator.default(o));
|
|
112
|
+
this.before.push(new _antiES6Object.default(o));
|
|
113
|
+
this.before.push(new AntiArrowFunction(o));
|
|
114
|
+
this.before.push(new _antiDestructuring.default(o));
|
|
115
|
+
this.before.push(new AntiConstLet(o));
|
|
102
116
|
}
|
|
103
117
|
|
|
118
|
+
apply(tree) {
|
|
119
|
+
super.apply(tree);
|
|
120
|
+
|
|
121
|
+
var nodesToAdd = _es.ES5Template.compile();
|
|
122
|
+
|
|
123
|
+
(0, _insert.prepend)(tree, ...nodesToAdd);
|
|
124
|
+
} // FixedExpressions
|
|
125
|
+
|
|
126
|
+
|
|
104
127
|
match(object, parents) {
|
|
105
|
-
return
|
|
128
|
+
return !!object.type;
|
|
106
129
|
}
|
|
107
130
|
|
|
108
131
|
transform(object, parents) {
|
|
109
132
|
return () => {
|
|
110
|
-
|
|
111
|
-
object.init = object.init.expression;
|
|
112
|
-
}
|
|
113
|
-
|
|
133
|
+
// Object.keyword -> Object["keyword"]
|
|
114
134
|
if (object.type == "MemberExpression") {
|
|
115
135
|
if (!object.computed && object.property.type == "Identifier") {
|
|
116
136
|
if (_constants.reservedKeywords.has(object.property.name)) {
|
|
@@ -118,7 +138,8 @@ class FixedExpressions extends _transform.default {
|
|
|
118
138
|
object.computed = true;
|
|
119
139
|
}
|
|
120
140
|
}
|
|
121
|
-
}
|
|
141
|
+
} // { keyword: ... } -> { "keyword": ... }
|
|
142
|
+
|
|
122
143
|
|
|
123
144
|
if (object.type == "Property") {
|
|
124
145
|
if (!object.computed && object.key.type == "Identifier") {
|
|
@@ -132,28 +153,4 @@ class FixedExpressions extends _transform.default {
|
|
|
132
153
|
|
|
133
154
|
}
|
|
134
155
|
|
|
135
|
-
class ES5 extends _transform.default {
|
|
136
|
-
constructor(o) {
|
|
137
|
-
super(o, _order.ObfuscateOrder.ES5);
|
|
138
|
-
this.before.push(new _antiClass.default(o));
|
|
139
|
-
this.before.push(new _antiTemplate.default(o));
|
|
140
|
-
this.before.push(new _antiSpreadOperator.default(o));
|
|
141
|
-
this.before.push(new _antiES6Object.default(o));
|
|
142
|
-
this.before.push(new AntiArrowFunction(o));
|
|
143
|
-
this.before.push(new _antiDestructuring.default(o));
|
|
144
|
-
this.before.push(new AntiConstLet(o));
|
|
145
|
-
this.concurrent.push(new FixedExpressions(o));
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
match(object, parents) {
|
|
149
|
-
return object.type == "Program";
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
transform(object, parents) {
|
|
153
|
-
var block = (0, _traverse.getBlock)(object, parents);
|
|
154
|
-
(0, _insert.getBlockBody)(block).splice(0, 0, ...(0, _template.default)("\n !Array.prototype.forEach ? Array.prototype.forEach = function (callback, thisArg) {\n thisArg = thisArg;\n for (var i = 0; i < this.length; i++) {\n callback.call(thisArg, this[i], i, this);\n }\n } : 0;\n \n !Array.prototype.map ? Array.prototype.map = function (callback, thisArg) {\n thisArg = thisArg;\n var array=[];\n for (var i = 0; i < this.length; i++) {\n array.push( callback.call(thisArg, this[i], i, this) );\n }\n return array;\n } : 0;\n\n !Array.prototype.reduce ? Array.prototype.reduce = function(fn, initial) {\n var values = this;\n if ( typeof initial === \"undefined\" ) {\n initial = 0;\n }\n\n values.forEach(function(item, index){\n initial = fn(initial, item, index, this);\n });\n\n return initial;\n } : 0;\n ").compile());
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
156
|
exports.default = ES5;
|
package/dist/transforms/eval.js
CHANGED
|
@@ -31,6 +31,17 @@ class Eval extends _transform.default {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
transform(object, parents) {
|
|
34
|
+
// Don't apply to getter/setters or class methods
|
|
35
|
+
if (parents[0]) {
|
|
36
|
+
if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (parents[0].type === "Property" && parents[0].value === object && (parents[0].kind !== "init" || parents[0].method)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
34
45
|
if (!(0, _probability.ComputeProbabilityMap)(this.options.eval, x => x, object.id && object.id.name)) {
|
|
35
46
|
return;
|
|
36
47
|
}
|
|
@@ -113,7 +113,7 @@ class DuplicateLiteralsRemoval extends _transform.default {
|
|
|
113
113
|
var body = [];
|
|
114
114
|
var thisShift = (0, _random.getRandomInteger)(-250, 250); // the name of the getter
|
|
115
115
|
|
|
116
|
-
getterName = this.getPlaceholder();
|
|
116
|
+
getterName = this.getPlaceholder() + "_dLR_" + this.fnGetters.size;
|
|
117
117
|
|
|
118
118
|
if (basedOn) {
|
|
119
119
|
var shift = this.fnShifts.get(basedOn);
|
|
@@ -144,7 +144,10 @@ class DuplicateLiteralsRemoval extends _transform.default {
|
|
|
144
144
|
|
|
145
145
|
if (!(0, _probability.ComputeProbabilityMap)(this.options.duplicateLiteralsRemoval)) {
|
|
146
146
|
return;
|
|
147
|
-
}
|
|
147
|
+
} // HARD CODED LIMIT of 10,000 (after 1,000 elements)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
if (this.map.size > 1000 && !(0, _random.chance)(this.map.size / 100)) return;
|
|
148
151
|
|
|
149
152
|
if (this.arrayName && parents[0].object && parents[0].object.name == this.arrayName) {
|
|
150
153
|
return;
|
|
@@ -179,17 +182,17 @@ class DuplicateLiteralsRemoval extends _transform.default {
|
|
|
179
182
|
this.arrayExpression = (0, _gen.ArrayExpression)([]);
|
|
180
183
|
}
|
|
181
184
|
|
|
182
|
-
var
|
|
185
|
+
var firstLocation = this.first.get(value);
|
|
183
186
|
|
|
184
|
-
if (
|
|
187
|
+
if (firstLocation) {
|
|
185
188
|
this.first.set(value, null);
|
|
186
189
|
var index = this.map.size;
|
|
187
190
|
(0, _assert.ok)(!this.map.has(value));
|
|
188
191
|
this.map.set(value, index);
|
|
189
|
-
this.toCaller(first[0], first[1], index);
|
|
190
192
|
var pushing = (0, _insert.clone)(object);
|
|
191
193
|
this.arrayExpression.elements.push(pushing);
|
|
192
194
|
(0, _assert.ok)(this.arrayExpression.elements[index] === pushing);
|
|
195
|
+
this.toCaller(firstLocation[0], firstLocation[1], index);
|
|
193
196
|
}
|
|
194
197
|
|
|
195
198
|
var index = this.map.get(value);
|
|
@@ -97,7 +97,12 @@ class ObjectExtraction extends _transform.default {
|
|
|
97
97
|
var nonInitOrComputed = object.properties.find(x => x.kind !== "init" || x.computed);
|
|
98
98
|
|
|
99
99
|
if (nonInitOrComputed) {
|
|
100
|
-
|
|
100
|
+
if (nonInitOrComputed.key) {
|
|
101
|
+
this.log(name + " has non-init/computed property: " + nonInitOrComputed.key.name || nonInitOrComputed.key.value);
|
|
102
|
+
} else {
|
|
103
|
+
this.log(name + " has spread-element or other type of property");
|
|
104
|
+
}
|
|
105
|
+
|
|
101
106
|
illegal.add(name);
|
|
102
107
|
return;
|
|
103
108
|
} else {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _order = require("../order");
|
|
9
|
+
|
|
10
|
+
var _gen = require("../util/gen");
|
|
11
|
+
|
|
12
|
+
var _stringEncoding = _interopRequireDefault(require("./string/stringEncoding"));
|
|
13
|
+
|
|
14
|
+
var _transform = _interopRequireDefault(require("./transform"));
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The Finalizer is the last transformation before the code is ready to be generated.
|
|
22
|
+
*
|
|
23
|
+
* Hexadecimal numbers:
|
|
24
|
+
* - Convert integer literals into `Identifier` nodes with the name being a hexadecimal number
|
|
25
|
+
*
|
|
26
|
+
* BigInt support:
|
|
27
|
+
* - Convert BigInt literals into `Identifier` nodes with the name being the raw BigInt string value + "n"
|
|
28
|
+
*
|
|
29
|
+
* String Encoding:
|
|
30
|
+
* - Convert String literals into `Identifier` nodes with the name being a unicode escaped string
|
|
31
|
+
*/
|
|
32
|
+
class Finalizer extends _transform.default {
|
|
33
|
+
constructor(o) {
|
|
34
|
+
super(o, _order.ObfuscateOrder.Finalizer);
|
|
35
|
+
|
|
36
|
+
_defineProperty(this, "stringEncoding", void 0);
|
|
37
|
+
|
|
38
|
+
this.stringEncoding = new _stringEncoding.default(o);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
isNumberLiteral(object) {
|
|
42
|
+
return object.type === "Literal" && typeof object.value === "number" && Math.floor(object.value) === object.value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
isBigIntLiteral(object) {
|
|
46
|
+
return object.type === "Literal" && typeof object.value === "bigint";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
match(object, parents) {
|
|
50
|
+
return object.type === "Literal";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
transform(object, parents) {
|
|
54
|
+
// Hexadecimal Numbers
|
|
55
|
+
if (this.options.hexadecimalNumbers && this.isNumberLiteral(object)) {
|
|
56
|
+
return () => {
|
|
57
|
+
// Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
|
|
58
|
+
// This code handles it regardless
|
|
59
|
+
var isNegative = object.value < 0;
|
|
60
|
+
var hex = Math.abs(object.value).toString(16);
|
|
61
|
+
var newStr = (isNegative ? "-" : "") + "0x" + hex;
|
|
62
|
+
this.replace(object, (0, _gen.Identifier)(newStr));
|
|
63
|
+
};
|
|
64
|
+
} // BigInt support
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if (this.isBigIntLiteral(object)) {
|
|
68
|
+
// https://github.com/MichaelXF/js-confuser/issues/79
|
|
69
|
+
return () => {
|
|
70
|
+
// Use an Identifier with the raw string
|
|
71
|
+
this.replace(object, (0, _gen.Identifier)(object.raw));
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (this.options.stringEncoding && this.stringEncoding.match(object, parents)) {
|
|
76
|
+
return this.stringEncoding.transform(object, parents);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
exports.default = Finalizer;
|