js-confuser 1.7.1 → 1.7.2
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/CHANGELOG.md +38 -0
- package/README.md +12 -27
- package/dist/compiler.js +2 -8
- package/dist/constants.js +17 -10
- package/dist/index.js +7 -30
- package/dist/obfuscator.js +15 -62
- package/dist/options.js +21 -38
- package/dist/order.js +4 -7
- package/dist/parser.js +5 -13
- package/dist/precedence.js +6 -8
- package/dist/presets.js +4 -6
- package/dist/probability.js +13 -24
- package/dist/templates/bufferToString.js +100 -5
- package/dist/templates/crash.js +51 -9
- package/dist/templates/es5.js +125 -6
- package/dist/templates/functionLength.js +24 -6
- package/dist/templates/globals.js +9 -0
- package/dist/templates/template.js +71 -30
- package/dist/transforms/antiTooling.js +26 -22
- package/dist/transforms/calculator.js +18 -54
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +236 -333
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
- package/dist/transforms/deadCode.js +528 -27
- package/dist/transforms/dispatcher.js +106 -110
- package/dist/transforms/es5/antiClass.js +70 -44
- package/dist/transforms/es5/antiDestructuring.js +14 -38
- package/dist/transforms/es5/antiES6Object.js +39 -48
- package/dist/transforms/es5/antiSpreadOperator.js +5 -14
- package/dist/transforms/es5/antiTemplate.js +10 -19
- package/dist/transforms/es5/es5.js +7 -40
- package/dist/transforms/extraction/classExtraction.js +83 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +41 -80
- package/dist/transforms/extraction/objectExtraction.js +24 -56
- package/dist/transforms/finalizer.js +6 -20
- package/dist/transforms/flatten.js +51 -99
- package/dist/transforms/identifier/globalAnalysis.js +8 -26
- package/dist/transforms/identifier/globalConcealing.js +35 -54
- package/dist/transforms/identifier/movedDeclarations.js +66 -38
- package/dist/transforms/identifier/renameVariables.js +29 -68
- package/dist/transforms/identifier/variableAnalysis.js +21 -48
- package/dist/transforms/lock/antiDebug.js +20 -25
- package/dist/transforms/lock/integrity.js +48 -47
- package/dist/transforms/lock/lock.js +62 -113
- package/dist/transforms/minify.js +77 -108
- package/dist/transforms/opaquePredicates.js +11 -48
- package/dist/transforms/preparation.js +17 -50
- package/dist/transforms/renameLabels.js +5 -22
- package/dist/transforms/rgf.js +93 -69
- package/dist/transforms/shuffle.js +41 -46
- package/dist/transforms/stack.js +35 -98
- package/dist/transforms/string/encoding.js +73 -27
- package/dist/transforms/string/stringCompression.js +44 -68
- package/dist/transforms/string/stringConcealing.js +125 -134
- package/dist/transforms/string/stringEncoding.js +6 -26
- package/dist/transforms/string/stringSplitting.js +5 -30
- package/dist/transforms/transform.js +50 -100
- package/dist/traverse.js +11 -18
- package/dist/util/compare.js +27 -29
- package/dist/util/gen.js +32 -86
- package/dist/util/guard.js +0 -1
- package/dist/util/identifiers.js +9 -72
- package/dist/util/insert.js +27 -77
- package/dist/util/math.js +0 -3
- package/dist/util/object.js +3 -7
- package/dist/util/random.js +5 -36
- package/dist/util/scope.js +6 -3
- package/package.json +3 -3
- package/src/constants.ts +12 -0
- package/src/options.ts +13 -0
- package/src/order.ts +2 -2
- package/src/templates/bufferToString.ts +49 -11
- package/src/templates/functionLength.ts +21 -3
- package/src/templates/globals.ts +3 -0
- package/src/templates/template.ts +85 -25
- package/src/transforms/antiTooling.ts +33 -11
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +2 -2
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
- package/src/transforms/deadCode.ts +0 -16
- package/src/transforms/dispatcher.ts +91 -69
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/extraction/classExtraction.ts +168 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -10
- package/src/transforms/extraction/objectExtraction.ts +4 -15
- package/src/transforms/flatten.ts +20 -5
- package/src/transforms/identifier/globalConcealing.ts +29 -65
- package/src/transforms/identifier/movedDeclarations.ts +90 -24
- package/src/transforms/minify.ts +27 -12
- package/src/transforms/rgf.ts +94 -5
- package/src/transforms/stack.ts +12 -3
- package/src/transforms/string/encoding.ts +85 -51
- package/src/transforms/string/stringCompression.ts +5 -8
- package/src/transforms/string/stringConcealing.ts +139 -113
- package/src/transforms/string/stringEncoding.ts +1 -2
- package/src/transforms/string/stringSplitting.ts +1 -2
- package/src/transforms/transform.ts +30 -1
- package/src/util/compare.ts +39 -5
- package/src/util/gen.ts +10 -3
- package/src/util/insert.ts +17 -0
- package/src/util/scope.ts +14 -2
- package/test/code/Cash.test.ts +10 -4
- package/test/code/StrictMode.src.js +65 -0
- package/test/code/StrictMode.test.js +37 -0
- package/test/compare.test.ts +62 -2
- package/test/options.test.ts +111 -55
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
- package/test/transforms/dispatcher.test.ts +55 -0
- package/test/transforms/extraction/classExtraction.test.ts +86 -0
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +8 -0
- package/test/transforms/extraction/objectExtraction.test.ts +2 -0
- package/test/transforms/identifier/globalConcealing.test.ts +19 -0
- package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
- package/test/transforms/minify.test.ts +37 -0
- package/test/transforms/rgf.test.ts +50 -0
- package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
- package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
- package/dist/transforms/eval.js +0 -84
- package/dist/transforms/hexadecimalNumbers.js +0 -63
- package/dist/transforms/hideInitializingCode.js +0 -270
- package/dist/transforms/identifier/nameRecycling.js +0 -218
- package/dist/transforms/label.js +0 -67
- package/dist/transforms/preparation/nameConflicts.js +0 -116
- package/dist/transforms/preparation/preparation.js +0 -188
|
@@ -4,25 +4,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _transform = _interopRequireDefault(require("../transform"));
|
|
9
|
-
|
|
10
8
|
var _template = _interopRequireDefault(require("../../templates/template"));
|
|
11
|
-
|
|
12
9
|
var _gen = require("../../util/gen");
|
|
13
|
-
|
|
14
10
|
var _insert = require("../../util/insert");
|
|
15
|
-
|
|
16
11
|
var _random = require("../../util/random");
|
|
17
|
-
|
|
18
12
|
var _assert = require("assert");
|
|
19
|
-
|
|
20
13
|
var _compiler = require("../../compiler");
|
|
21
|
-
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
function
|
|
25
|
-
|
|
14
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
16
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
17
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
26
18
|
/**
|
|
27
19
|
* Hashing Algorithm for function integrity
|
|
28
20
|
* @param str
|
|
@@ -31,25 +23,55 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
31
23
|
function cyrb53(str) {
|
|
32
24
|
let seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
33
25
|
let h1 = 0xdeadbeef ^ seed,
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
h2 = 0x41c6ce57 ^ seed;
|
|
36
27
|
for (let i = 0, ch; i < str.length; i++) {
|
|
37
28
|
ch = str.charCodeAt(i);
|
|
38
29
|
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
39
30
|
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
40
31
|
}
|
|
41
|
-
|
|
42
32
|
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
43
33
|
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
44
34
|
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const HashTemplate = (0, _template.default)("\nfunction {name}(str, seed) {\n var h1 = 0xdeadbeef ^ seed;\n var h2 = 0x41c6ce57 ^ seed;\n for (var i = 0, ch; i < str.length; i++) {\n ch = str.charCodeAt(i);\n h1 = {imul}(h1 ^ ch, 2654435761);\n h2 = {imul}(h2 ^ ch, 1597334677);\n }\n h1 = {imul}(h1 ^ (h1>>>16), 2246822507) ^ {imul}(h2 ^ (h2>>>13), 3266489909);\n h2 = {imul}(h2 ^ (h2>>>16), 2246822507) ^ {imul}(h1 ^ (h1>>>13), 3266489909);\n return 4294967296 * (2097151 & h2) + (h1>>>0);\n};"); // Math.imul polyfill for ES5
|
|
35
|
+
}
|
|
49
36
|
|
|
50
|
-
|
|
37
|
+
// In template form to be inserted into code
|
|
38
|
+
const HashTemplate = (0, _template.default)(`
|
|
39
|
+
function {name}(str, seed) {
|
|
40
|
+
var h1 = 0xdeadbeef ^ seed;
|
|
41
|
+
var h2 = 0x41c6ce57 ^ seed;
|
|
42
|
+
for (var i = 0, ch; i < str.length; i++) {
|
|
43
|
+
ch = str.charCodeAt(i);
|
|
44
|
+
h1 = {imul}(h1 ^ ch, 2654435761);
|
|
45
|
+
h2 = {imul}(h2 ^ ch, 1597334677);
|
|
46
|
+
}
|
|
47
|
+
h1 = {imul}(h1 ^ (h1>>>16), 2246822507) ^ {imul}(h2 ^ (h2>>>13), 3266489909);
|
|
48
|
+
h2 = {imul}(h2 ^ (h2>>>16), 2246822507) ^ {imul}(h1 ^ (h1>>>13), 3266489909);
|
|
49
|
+
return 4294967296 * (2097151 & h2) + (h1>>>0);
|
|
50
|
+
};`);
|
|
51
|
+
|
|
52
|
+
// Math.imul polyfill for ES5
|
|
53
|
+
const ImulTemplate = (0, _template.default)(`
|
|
54
|
+
var {name} = Math.imul || function(opA, opB){
|
|
55
|
+
opB |= 0; // ensure that opB is an integer. opA will automatically be coerced.
|
|
56
|
+
// floating points give us 53 bits of precision to work with plus 1 sign bit
|
|
57
|
+
// automatically handled for our convienence:
|
|
58
|
+
// 1. 0x003fffff /*opA & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001
|
|
59
|
+
// 0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/
|
|
60
|
+
var result = (opA & 0x003fffff) * opB;
|
|
61
|
+
// 2. We can remove an integer coersion from the statement above because:
|
|
62
|
+
// 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001
|
|
63
|
+
// 0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/
|
|
64
|
+
if (opA & 0xffc00000 /*!== 0*/) result += (opA & 0xffc00000) * opB |0;
|
|
65
|
+
return result |0;
|
|
66
|
+
};`);
|
|
67
|
+
|
|
68
|
+
// Simple function that returns .toString() value with spaces replaced out
|
|
69
|
+
const StringTemplate = (0, _template.default)(`
|
|
70
|
+
function {name}(x){
|
|
71
|
+
return x.toString().replace(/ |\\n|;|,|\\{|\\}|\\(|\\)|\\.|\\[|\\]/g, "");
|
|
72
|
+
}
|
|
73
|
+
`);
|
|
51
74
|
|
|
52
|
-
const StringTemplate = (0, _template.default)("\n function {name}(x){\n return x.toString().replace(/ |\\n|;|,|\\{|\\}|\\(|\\)|\\.|\\[|\\]/g, \"\");\n }\n");
|
|
53
75
|
/**
|
|
54
76
|
* Integrity protects functions by using checksum techniques to verify their code has not changed.
|
|
55
77
|
*
|
|
@@ -69,30 +91,21 @@ const StringTemplate = (0, _template.default)("\n function {name}(x){\n retu
|
|
|
69
91
|
* - The hashing function is placed during this transformation,
|
|
70
92
|
* - A hidden identifier is placed to keep track of the name.
|
|
71
93
|
*/
|
|
72
|
-
|
|
73
94
|
class Integrity extends _transform.default {
|
|
74
95
|
constructor(o, lock) {
|
|
75
96
|
super(o);
|
|
76
|
-
|
|
77
97
|
_defineProperty(this, "hashFn", void 0);
|
|
78
|
-
|
|
79
98
|
_defineProperty(this, "imulFn", void 0);
|
|
80
|
-
|
|
81
99
|
_defineProperty(this, "stringFn", void 0);
|
|
82
|
-
|
|
83
100
|
_defineProperty(this, "seed", void 0);
|
|
84
|
-
|
|
85
101
|
_defineProperty(this, "lock", void 0);
|
|
86
|
-
|
|
87
102
|
this.lock = lock;
|
|
88
103
|
this.seed = (0, _random.getRandomInteger)(0, 1000);
|
|
89
104
|
}
|
|
90
|
-
|
|
91
105
|
match(object, parents) {
|
|
92
106
|
// ArrowFunctions are excluded!
|
|
93
107
|
return object.type == "Program" || (0, _insert.isFunction)(object) && object.type !== "ArrowFunctionExpression";
|
|
94
108
|
}
|
|
95
|
-
|
|
96
109
|
transform(object, parents) {
|
|
97
110
|
if (object.type == "Program") {
|
|
98
111
|
return () => {
|
|
@@ -124,36 +137,30 @@ class Integrity extends _transform.default {
|
|
|
124
137
|
object.$dispatcherSkip = true;
|
|
125
138
|
object._hiddenHashingUtils = hashingUtils;
|
|
126
139
|
var ok = this.transform(functionExpression, [object.body[0], object.body, object]);
|
|
127
|
-
|
|
128
140
|
if (ok) {
|
|
129
141
|
ok();
|
|
130
142
|
}
|
|
131
|
-
|
|
132
143
|
object.$eval = () => {
|
|
133
144
|
if ((0, _insert.isFunction)(functionExpression) && functionExpression.body.type == "BlockStatement") {
|
|
134
145
|
if (this.lock.counterMeasuresNode) {
|
|
135
146
|
functionExpression.body.body.unshift((0, _insert.clone)(this.lock.counterMeasuresNode[0]));
|
|
136
147
|
}
|
|
137
|
-
|
|
138
148
|
functionExpression.body.body.unshift(...hashingUtils);
|
|
139
149
|
}
|
|
140
150
|
};
|
|
141
151
|
};
|
|
142
152
|
}
|
|
143
|
-
|
|
144
153
|
(0, _assert.ok)((0, _insert.isFunction)(object));
|
|
145
|
-
|
|
146
154
|
if (object.generator || object.async) {
|
|
147
155
|
return;
|
|
148
156
|
}
|
|
149
|
-
|
|
150
157
|
return () => {
|
|
151
158
|
object.__hiddenCountermeasures = this.lock.getCounterMeasuresCode(object, parents);
|
|
152
|
-
|
|
153
159
|
object.$eval = () => {
|
|
154
160
|
var functionName = this.generateIdentifier();
|
|
155
161
|
var hashName = this.generateIdentifier();
|
|
156
|
-
var functionDeclaration = {
|
|
162
|
+
var functionDeclaration = {
|
|
163
|
+
...(0, _insert.clone)(object),
|
|
157
164
|
type: "FunctionDeclaration",
|
|
158
165
|
id: (0, _gen.Identifier)(functionName),
|
|
159
166
|
params: object.params || [],
|
|
@@ -162,28 +169,24 @@ class Integrity extends _transform.default {
|
|
|
162
169
|
$dispatcherSkip: true
|
|
163
170
|
};
|
|
164
171
|
var toString = (0, _compiler.compileJsSync)(functionDeclaration, this.options);
|
|
165
|
-
|
|
166
172
|
if (!toString) {
|
|
167
173
|
return;
|
|
168
174
|
}
|
|
169
|
-
|
|
170
175
|
var minified = toString.replace(/ |\n|;|,|\{|\}|\(|\)|\.|\[|\]/g, "");
|
|
171
176
|
var hash = cyrb53(minified, this.seed);
|
|
172
177
|
this.log((object.id ? object.id.name : "function") + " -> " + hash, minified);
|
|
173
|
-
var ifStatement = (0, _gen.IfStatement)((0, _gen.BinaryExpression)("==", (0, _gen.Identifier)(hashName), (0, _gen.Literal)(hash)), [(0, _template.default)(
|
|
178
|
+
var ifStatement = (0, _gen.IfStatement)((0, _gen.BinaryExpression)("==", (0, _gen.Identifier)(hashName), (0, _gen.Literal)(hash)), [(0, _template.default)(`return {functionName}.apply(this, arguments)`).single({
|
|
174
179
|
functionName: functionName
|
|
175
180
|
})]);
|
|
176
|
-
|
|
177
181
|
if (object.__hiddenCountermeasures && object.__hiddenCountermeasures.length) {
|
|
178
182
|
ifStatement.alternate = (0, _gen.BlockStatement)(object.__hiddenCountermeasures);
|
|
179
183
|
}
|
|
184
|
+
object.body = (0, _gen.BlockStatement)([functionDeclaration, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(hashName, (0, _gen.CallExpression)((0, _insert.clone)(this.hashFn), [(0, _gen.CallExpression)((0, _insert.clone)(this.stringFn), [(0, _gen.Identifier)(functionName)]), (0, _gen.Literal)(this.seed)]))), ifStatement]);
|
|
180
185
|
|
|
181
|
-
|
|
182
|
-
|
|
186
|
+
// Make sure the countermeasures activation variable is present
|
|
183
187
|
if (this.lock.counterMeasuresActivated) {
|
|
184
188
|
object.body.body.unshift((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.lock.counterMeasuresActivated)));
|
|
185
189
|
}
|
|
186
|
-
|
|
187
190
|
if (object.type == "ArrowFunctionExpression") {
|
|
188
191
|
object.type = "FunctionExpression";
|
|
189
192
|
object.expression = false;
|
|
@@ -191,7 +194,5 @@ class Integrity extends _transform.default {
|
|
|
191
194
|
};
|
|
192
195
|
};
|
|
193
196
|
}
|
|
194
|
-
|
|
195
197
|
}
|
|
196
|
-
|
|
197
198
|
exports.default = Integrity;
|
|
@@ -4,272 +4,226 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _transform = _interopRequireDefault(require("../transform"));
|
|
9
|
-
|
|
10
8
|
var _gen = require("../../util/gen");
|
|
11
|
-
|
|
12
9
|
var _traverse = _interopRequireWildcard(require("../../traverse"));
|
|
13
|
-
|
|
14
10
|
var _random = require("../../util/random");
|
|
15
|
-
|
|
16
11
|
var _crash = require("../../templates/crash");
|
|
17
|
-
|
|
18
12
|
var _insert = require("../../util/insert");
|
|
19
|
-
|
|
20
13
|
var _template = _interopRequireDefault(require("../../templates/template"));
|
|
21
|
-
|
|
22
14
|
var _order = require("../../order");
|
|
23
|
-
|
|
24
15
|
var _integrity = _interopRequireDefault(require("./integrity"));
|
|
25
|
-
|
|
26
16
|
var _antiDebug = _interopRequireDefault(require("./antiDebug"));
|
|
27
|
-
|
|
28
17
|
var _identifiers = require("../../util/identifiers");
|
|
29
|
-
|
|
30
18
|
var _compare = require("../../util/compare");
|
|
31
|
-
|
|
32
19
|
var _assert = require("assert");
|
|
33
|
-
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
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; }
|
|
41
|
-
|
|
20
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
21
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
22
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
23
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
24
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
25
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
42
26
|
/**
|
|
43
27
|
* Applies browser & date locks.
|
|
44
28
|
*/
|
|
45
29
|
class Lock extends _transform.default {
|
|
46
|
-
/**
|
|
47
|
-
* This is a boolean variable injected into the source code determining wether the countermeasures function has been called.
|
|
48
|
-
* This is used to prevent infinite loops from happening
|
|
49
|
-
*/
|
|
50
30
|
constructor(o) {
|
|
51
|
-
super(o, _order.ObfuscateOrder.Lock);
|
|
31
|
+
super(o, _order.ObfuscateOrder.Lock);
|
|
32
|
+
|
|
33
|
+
// Removed feature
|
|
52
34
|
// if (this.options.lock.startDate && this.options.lock.endDate) {
|
|
53
35
|
// this.before.push(new LockStrings(o));
|
|
54
36
|
// }
|
|
55
|
-
|
|
56
37
|
_defineProperty(this, "globalVar", void 0);
|
|
57
|
-
|
|
58
38
|
_defineProperty(this, "counterMeasuresNode", void 0);
|
|
59
|
-
|
|
60
39
|
_defineProperty(this, "iosDetectFn", void 0);
|
|
61
|
-
|
|
40
|
+
/**
|
|
41
|
+
* This is a boolean variable injected into the source code determining wether the countermeasures function has been called.
|
|
42
|
+
* This is used to prevent infinite loops from happening
|
|
43
|
+
*/
|
|
62
44
|
_defineProperty(this, "counterMeasuresActivated", void 0);
|
|
63
|
-
|
|
64
45
|
_defineProperty(this, "made", void 0);
|
|
65
|
-
|
|
66
46
|
if (this.options.lock.integrity) {
|
|
67
47
|
this.before.push(new _integrity.default(o, this));
|
|
68
48
|
}
|
|
69
|
-
|
|
70
49
|
if (this.options.lock.antiDebug) {
|
|
71
50
|
this.before.push(new _antiDebug.default(o, this));
|
|
72
51
|
}
|
|
73
|
-
|
|
74
52
|
this.made = 0;
|
|
75
53
|
}
|
|
76
|
-
|
|
77
54
|
apply(tree) {
|
|
78
55
|
if (typeof this.options.lock.countermeasures === "string" && (0, _compare.isValidIdentifier)(this.options.lock.countermeasures)) {
|
|
79
56
|
(0, _traverse.default)(tree, (object, parents) => {
|
|
80
57
|
if (object.type == "Identifier" && object.name === this.options.lock.countermeasures) {
|
|
81
58
|
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
82
|
-
|
|
83
59
|
if (info.spec.isDefined) {
|
|
84
60
|
if (this.counterMeasuresNode) {
|
|
85
61
|
throw new Error("Countermeasures function was already defined, it must have a unique name from the rest of your code");
|
|
86
62
|
} else {
|
|
87
63
|
var definingContext = (0, _insert.getVarContext)(parents[0], parents.slice(1));
|
|
88
|
-
|
|
89
64
|
if (definingContext != tree) {
|
|
90
65
|
throw new Error("Countermeasures function must be defined at the global level");
|
|
91
66
|
}
|
|
92
|
-
|
|
93
67
|
var chain = [object, parents];
|
|
94
|
-
|
|
95
68
|
if (info.isFunctionDeclaration) {
|
|
96
69
|
chain = [parents[0], parents.slice(1)];
|
|
97
70
|
} else if (info.isVariableDeclaration) {
|
|
98
71
|
chain = [parents[1], parents.slice(2)];
|
|
99
72
|
}
|
|
100
|
-
|
|
101
73
|
this.counterMeasuresNode = chain;
|
|
102
74
|
}
|
|
103
75
|
}
|
|
104
76
|
}
|
|
105
77
|
});
|
|
106
|
-
|
|
107
78
|
if (!this.counterMeasuresNode) {
|
|
108
79
|
throw new Error("Countermeasures function named '" + this.options.lock.countermeasures + "' was not found.");
|
|
109
80
|
}
|
|
110
81
|
}
|
|
111
|
-
|
|
112
82
|
super.apply(tree);
|
|
113
83
|
}
|
|
114
|
-
|
|
115
84
|
getCounterMeasuresCode(object, parents) {
|
|
116
85
|
var opt = this.options.lock.countermeasures;
|
|
117
|
-
|
|
118
86
|
if (opt === false) {
|
|
119
87
|
return null;
|
|
120
|
-
}
|
|
121
|
-
|
|
88
|
+
}
|
|
122
89
|
|
|
90
|
+
// Call function
|
|
123
91
|
if (typeof opt === "string") {
|
|
124
92
|
if (!this.counterMeasuresActivated) {
|
|
125
93
|
this.counterMeasuresActivated = this.getPlaceholder();
|
|
126
94
|
(0, _insert.prepend)(parents[parents.length - 1] || object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.counterMeasuresActivated)));
|
|
127
|
-
}
|
|
128
|
-
|
|
95
|
+
}
|
|
129
96
|
|
|
97
|
+
// Since Lock occurs before variable renaming, we are using the pre-obfuscated function name
|
|
130
98
|
return [(0, _gen.ExpressionStatement)((0, _gen.LogicalExpression)("||", (0, _gen.Identifier)(this.counterMeasuresActivated), (0, _gen.SequenceExpression)([(0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(this.counterMeasuresActivated), (0, _gen.Literal)(true)), (0, _gen.CallExpression)((0, _template.default)(opt).single().expression, [])])))];
|
|
131
99
|
}
|
|
132
|
-
|
|
133
100
|
var type = (0, _random.choice)(["crash", "exit"]);
|
|
134
|
-
|
|
135
101
|
switch (type) {
|
|
136
102
|
case "crash":
|
|
137
103
|
var varName = this.getPlaceholder();
|
|
138
104
|
return (0, _random.choice)([_crash.CrashTemplate1, _crash.CrashTemplate2, _crash.CrashTemplate3]).compile({
|
|
139
105
|
var: varName
|
|
140
106
|
});
|
|
141
|
-
|
|
142
107
|
case "exit":
|
|
143
108
|
if (this.options.target == "browser") {
|
|
144
109
|
return (0, _template.default)("document.documentElement.innerHTML = '';").compile();
|
|
145
110
|
}
|
|
146
|
-
|
|
147
111
|
return (0, _template.default)("process.exit()").compile();
|
|
148
112
|
}
|
|
149
113
|
}
|
|
114
|
+
|
|
150
115
|
/**
|
|
151
116
|
* Converts Dates to numbers, then applies some randomness
|
|
152
117
|
* @param object
|
|
153
118
|
*/
|
|
154
|
-
|
|
155
|
-
|
|
156
119
|
getTime(object) {
|
|
157
120
|
if (!object) {
|
|
158
121
|
return 0;
|
|
159
122
|
}
|
|
160
|
-
|
|
161
123
|
if (object instanceof Date) {
|
|
162
124
|
return this.getTime(object.getTime());
|
|
163
125
|
}
|
|
164
|
-
|
|
165
126
|
return object + (0, _random.getRandomInteger)(-4000, 4000);
|
|
166
127
|
}
|
|
167
|
-
|
|
168
128
|
match(object, parents) {
|
|
169
129
|
return (0, _traverse.isBlock)(object);
|
|
170
130
|
}
|
|
171
|
-
|
|
172
131
|
transform(object, parents) {
|
|
173
132
|
if (parents.find(x => (0, _compare.isLoop)(x) && x.type != "SwitchStatement")) {
|
|
174
133
|
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
134
|
+
}
|
|
177
135
|
|
|
136
|
+
// no check in countermeasures code, otherwise it will infinitely call itself
|
|
178
137
|
if (this.counterMeasuresNode && (object == this.counterMeasuresNode[0] || parents.indexOf(this.counterMeasuresNode[0]) !== -1)) {
|
|
179
138
|
return;
|
|
180
139
|
}
|
|
181
|
-
|
|
182
140
|
var block = (0, _traverse.getBlock)(object, parents);
|
|
183
141
|
var choices = [];
|
|
184
|
-
|
|
185
142
|
if (this.options.lock.startDate) {
|
|
186
143
|
choices.push("startDate");
|
|
187
144
|
}
|
|
188
|
-
|
|
189
145
|
if (this.options.lock.endDate) {
|
|
190
146
|
choices.push("endDate");
|
|
191
147
|
}
|
|
192
|
-
|
|
193
148
|
if (this.options.lock.domainLock && this.options.lock.domainLock.length) {
|
|
194
149
|
choices.push("domainLock");
|
|
195
150
|
}
|
|
196
|
-
|
|
197
151
|
if (this.options.lock.context && this.options.lock.context.length) {
|
|
198
152
|
choices.push("context");
|
|
199
153
|
}
|
|
200
|
-
|
|
201
154
|
if (this.options.lock.browserLock && this.options.lock.browserLock.length) {
|
|
202
155
|
choices.push("browserLock");
|
|
203
156
|
}
|
|
204
|
-
|
|
205
157
|
if (this.options.lock.osLock && this.options.lock.osLock.length) {
|
|
206
158
|
choices.push("osLock");
|
|
207
159
|
}
|
|
208
|
-
|
|
209
160
|
if (this.options.lock.selfDefending) {
|
|
210
161
|
choices.push("selfDefending");
|
|
211
162
|
}
|
|
212
|
-
|
|
213
163
|
if (!choices.length) {
|
|
214
164
|
return;
|
|
215
165
|
}
|
|
216
|
-
|
|
217
166
|
return () => {
|
|
218
167
|
this.made++;
|
|
219
|
-
|
|
220
168
|
if (this.made > 150) {
|
|
221
169
|
return;
|
|
222
170
|
}
|
|
223
|
-
|
|
224
171
|
var type = (0, _random.choice)(choices);
|
|
225
172
|
var nodes = [];
|
|
226
173
|
var dateNow = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)("Date"), (0, _gen.Literal)("now"), true), []);
|
|
227
|
-
|
|
228
174
|
if (Math.random() > 0.5) {
|
|
229
175
|
dateNow = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.NewExpression)((0, _gen.Identifier)("Date"), []), (0, _gen.Literal)("getTime")), []);
|
|
230
176
|
}
|
|
231
|
-
|
|
232
177
|
if (Math.random() > 0.5) {
|
|
233
178
|
dateNow = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)("Date"), (0, _gen.Literal)("prototype"), true), (0, _gen.Literal)("getTime"), true), (0, _gen.Literal)("call"), true), [(0, _gen.NewExpression)((0, _gen.Identifier)("Date"), [])]);
|
|
234
179
|
}
|
|
235
|
-
|
|
236
180
|
var test;
|
|
237
181
|
var offset = 0;
|
|
238
|
-
|
|
239
182
|
switch (type) {
|
|
240
183
|
case "selfDefending":
|
|
241
184
|
// A very simple mechanism inspired from https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/src/custom-code-helpers/self-defending/templates/SelfDefendingNoEvalTemplate.ts
|
|
242
185
|
// regExp checks for a newline, formatters add these
|
|
243
|
-
var callExpression = (0, _template.default)(
|
|
186
|
+
var callExpression = (0, _template.default)(`
|
|
187
|
+
(
|
|
188
|
+
function(){
|
|
189
|
+
// Breaks JSNice.org, beautifier.io
|
|
190
|
+
var namedFunction = function(){
|
|
191
|
+
const test = function(){
|
|
192
|
+
const regExp=new RegExp('\\n');
|
|
193
|
+
return regExp['test'](namedFunction)
|
|
194
|
+
};
|
|
195
|
+
return test()
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return namedFunction();
|
|
199
|
+
}
|
|
200
|
+
)()
|
|
201
|
+
`).single().expression;
|
|
244
202
|
nodes.push((0, _gen.IfStatement)(callExpression, this.getCounterMeasuresCode(object, parents) || [], null));
|
|
245
203
|
break;
|
|
246
|
-
|
|
247
204
|
case "startDate":
|
|
248
205
|
test = (0, _gen.BinaryExpression)("<", dateNow, (0, _gen.Literal)(this.getTime(this.options.lock.startDate)));
|
|
249
206
|
nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
|
|
250
207
|
break;
|
|
251
|
-
|
|
252
208
|
case "endDate":
|
|
253
209
|
test = (0, _gen.BinaryExpression)(">", dateNow, (0, _gen.Literal)(this.getTime(this.options.lock.endDate)));
|
|
254
210
|
nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
|
|
255
211
|
break;
|
|
256
|
-
|
|
257
212
|
case "context":
|
|
258
213
|
var prop = (0, _random.choice)(this.options.lock.context);
|
|
259
|
-
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
214
|
+
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
260
215
|
|
|
216
|
+
// Todo: Alternative to `this`
|
|
261
217
|
if (!this.globalVar) {
|
|
262
218
|
offset = 1;
|
|
263
219
|
this.globalVar = this.getPlaceholder();
|
|
264
220
|
(0, _insert.prepend)(parents[parents.length - 1] || block, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.globalVar, (0, _gen.LogicalExpression)("||", (0, _gen.Identifier)(this.options.globalVariables.keys().next().value), (0, _gen.ThisExpression)()))));
|
|
265
221
|
}
|
|
266
|
-
|
|
267
222
|
test = (0, _gen.UnaryExpression)("!", (0, _gen.MemberExpression)((0, _gen.Identifier)(this.globalVar), (0, _gen.Literal)(prop), true));
|
|
268
223
|
nodes.push((0, _gen.IfStatement)(test, code, null));
|
|
269
224
|
break;
|
|
270
|
-
|
|
271
225
|
case "osLock":
|
|
272
|
-
var navigatorUserAgent = (0, _template.default)(
|
|
226
|
+
var navigatorUserAgent = (0, _template.default)(`window.navigator.userAgent.toLowerCase()`).single().expression;
|
|
273
227
|
(0, _assert.ok)(this.options.lock.osLock);
|
|
274
228
|
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
275
229
|
this.options.lock.osLock.forEach(osName => {
|
|
@@ -281,74 +235,76 @@ class Lock extends _transform.default {
|
|
|
281
235
|
ios: "---"
|
|
282
236
|
}[osName];
|
|
283
237
|
var thisTest = (0, _gen.CallExpression)((0, _gen.MemberExpression)(navigatorUserAgent, (0, _gen.Literal)("match"), true), [(0, _gen.Literal)(agentMatcher.toLowerCase())]);
|
|
284
|
-
|
|
285
238
|
if (osName == "ios" && this.options.target === "browser") {
|
|
286
239
|
if (!this.iosDetectFn) {
|
|
287
240
|
this.iosDetectFn = this.getPlaceholder();
|
|
288
|
-
(0, _insert.prepend)(parents[parents.length - 1] || object, (0, _template.default)(
|
|
241
|
+
(0, _insert.prepend)(parents[parents.length - 1] || object, (0, _template.default)(`function ${this.iosDetectFn}() {
|
|
242
|
+
return [
|
|
243
|
+
'iPad Simulator',
|
|
244
|
+
'iPhone Simulator',
|
|
245
|
+
'iPod Simulator',
|
|
246
|
+
'iPad',
|
|
247
|
+
'iPhone',
|
|
248
|
+
'iPod'
|
|
249
|
+
].includes(navigator.platform)
|
|
250
|
+
// iPad on iOS 13 detection
|
|
251
|
+
|| (navigator.userAgent.includes("Mac") && "ontouchend" in document)
|
|
252
|
+
}`).single());
|
|
289
253
|
}
|
|
290
|
-
|
|
291
254
|
thisTest = (0, _gen.CallExpression)((0, _gen.Identifier)(this.iosDetectFn), []);
|
|
292
255
|
}
|
|
293
|
-
|
|
294
256
|
if (this.options.target === "node") {
|
|
295
257
|
var platformName = {
|
|
296
258
|
windows: "win32",
|
|
297
259
|
osx: "darwin",
|
|
298
260
|
ios: "darwin"
|
|
299
261
|
}[osName] || osName;
|
|
300
|
-
thisTest = (0, _template.default)(
|
|
262
|
+
thisTest = (0, _template.default)(`require('os').platform()==="${platformName}"`).single().expression;
|
|
301
263
|
}
|
|
302
|
-
|
|
303
264
|
if (!test) {
|
|
304
265
|
test = thisTest;
|
|
305
266
|
} else {
|
|
306
|
-
test = (0, _gen.LogicalExpression)("||", {
|
|
267
|
+
test = (0, _gen.LogicalExpression)("||", {
|
|
268
|
+
...test
|
|
307
269
|
}, thisTest);
|
|
308
270
|
}
|
|
309
271
|
});
|
|
310
|
-
test = (0, _gen.UnaryExpression)("!", {
|
|
272
|
+
test = (0, _gen.UnaryExpression)("!", {
|
|
273
|
+
...test
|
|
311
274
|
});
|
|
312
275
|
nodes.push((0, _gen.IfStatement)(test, code, null));
|
|
313
276
|
break;
|
|
314
|
-
|
|
315
277
|
case "browserLock":
|
|
316
|
-
var navigatorUserAgent = (0, _template.default)(
|
|
278
|
+
var navigatorUserAgent = (0, _template.default)(`window.navigator.userAgent.toLowerCase()`).single().expression;
|
|
317
279
|
(0, _assert.ok)(this.options.lock.browserLock);
|
|
318
280
|
this.options.lock.browserLock.forEach(browserName => {
|
|
319
281
|
var thisTest = (0, _gen.CallExpression)((0, _gen.MemberExpression)(navigatorUserAgent, (0, _gen.Literal)("match"), true), [(0, _gen.Literal)(browserName == "iexplorer" ? "msie" : browserName.toLowerCase())]);
|
|
320
|
-
|
|
321
282
|
if (browserName === "safari") {
|
|
322
|
-
thisTest = (0, _template.default)(
|
|
283
|
+
thisTest = (0, _template.default)(`/^((?!chrome|android).)*safari/i.test(navigator.userAgent)`).single().expression;
|
|
323
284
|
}
|
|
324
|
-
|
|
325
285
|
if (!test) {
|
|
326
286
|
test = thisTest;
|
|
327
287
|
} else {
|
|
328
|
-
test = (0, _gen.LogicalExpression)("||", {
|
|
288
|
+
test = (0, _gen.LogicalExpression)("||", {
|
|
289
|
+
...test
|
|
329
290
|
}, thisTest);
|
|
330
291
|
}
|
|
331
292
|
});
|
|
332
|
-
test = (0, _gen.UnaryExpression)("!", {
|
|
293
|
+
test = (0, _gen.UnaryExpression)("!", {
|
|
294
|
+
...test
|
|
333
295
|
});
|
|
334
296
|
nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
|
|
335
297
|
break;
|
|
336
|
-
|
|
337
298
|
case "domainLock":
|
|
338
299
|
function removeSlashes(path) {
|
|
339
300
|
var count = path.length - 1;
|
|
340
301
|
var index = 0;
|
|
341
|
-
|
|
342
302
|
while (path.charCodeAt(index) === 47 && ++index);
|
|
343
|
-
|
|
344
303
|
while (path.charCodeAt(count) === 47 && --count);
|
|
345
|
-
|
|
346
304
|
return path.slice(index, count + 1);
|
|
347
305
|
}
|
|
348
|
-
|
|
349
306
|
var locationHref = (0, _gen.MemberExpression)((0, _gen.Identifier)("location"), (0, _gen.Literal)("href"), true);
|
|
350
307
|
var random = (0, _random.choice)(this.options.lock.domainLock);
|
|
351
|
-
|
|
352
308
|
if (random) {
|
|
353
309
|
test = (0, _gen.CallExpression)((0, _gen.MemberExpression)(locationHref, (0, _gen.Literal)("match"), true), [{
|
|
354
310
|
type: "Literal",
|
|
@@ -358,21 +314,16 @@ class Lock extends _transform.default {
|
|
|
358
314
|
}
|
|
359
315
|
}]);
|
|
360
316
|
test = (0, _gen.UnaryExpression)("!", test);
|
|
361
|
-
|
|
362
317
|
if (Math.random() > 0.5) {
|
|
363
318
|
test = (0, _gen.LogicalExpression)("||", (0, _gen.BinaryExpression)("==", (0, _gen.UnaryExpression)("typeof", (0, _gen.Identifier)("location")), (0, _gen.Literal)("undefined")), test);
|
|
364
319
|
}
|
|
365
|
-
|
|
366
320
|
nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
|
|
367
321
|
}
|
|
368
|
-
|
|
369
322
|
break;
|
|
370
323
|
}
|
|
371
|
-
|
|
372
324
|
if (nodes.length) {
|
|
373
325
|
var body = (0, _insert.getBlockBody)(block);
|
|
374
326
|
var randomIndex = (0, _random.getRandomInteger)(0, body.length) + offset;
|
|
375
|
-
|
|
376
327
|
if (randomIndex >= body.length) {
|
|
377
328
|
body.push(...nodes);
|
|
378
329
|
} else {
|
|
@@ -381,7 +332,5 @@ class Lock extends _transform.default {
|
|
|
381
332
|
}
|
|
382
333
|
};
|
|
383
334
|
}
|
|
384
|
-
|
|
385
335
|
}
|
|
386
|
-
|
|
387
336
|
exports.default = Lock;
|