js-confuser 1.7.0 → 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 +57 -0
- package/README.md +12 -29
- 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 +110 -108
- 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 +45 -79
- package/dist/transforms/extraction/objectExtraction.js +27 -54
- 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 +98 -66
- 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 +11 -74
- 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/docs/ControlFlowFlattening.md +1 -1
- package/docs/ES5.md +197 -0
- 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 +101 -69
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/extraction/classExtraction.ts +168 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +13 -10
- package/src/transforms/extraction/objectExtraction.ts +7 -14
- 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 +103 -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/identifiers.ts +6 -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 +82 -0
- package/test/transforms/extraction/classExtraction.test.ts +86 -0
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +29 -8
- package/test/transforms/extraction/objectExtraction.test.ts +37 -15
- package/test/transforms/identifier/globalConcealing.test.ts +42 -2
- package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
- package/test/transforms/lock/integrity.test.ts +24 -0
- package/test/transforms/minify.test.ts +37 -0
- package/test/transforms/rgf.test.ts +50 -0
- package/test/util/identifiers.test.ts +21 -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,105 +4,92 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _assert = require("assert");
|
|
9
|
-
|
|
10
8
|
var _order = require("../../order");
|
|
11
|
-
|
|
12
9
|
var _probability = require("../../probability");
|
|
13
|
-
|
|
14
10
|
var _template = _interopRequireDefault(require("../../templates/template"));
|
|
15
|
-
|
|
16
11
|
var _compare = require("../../util/compare");
|
|
17
|
-
|
|
18
12
|
var _gen = require("../../util/gen");
|
|
19
|
-
|
|
20
13
|
var _insert = require("../../util/insert");
|
|
21
|
-
|
|
22
14
|
var _transform = _interopRequireDefault(require("../transform"));
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
29
|
-
|
|
30
|
-
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; }
|
|
31
|
-
|
|
15
|
+
var _constants = require("../../constants");
|
|
16
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
|
+
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; }
|
|
18
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
19
|
+
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); }
|
|
32
20
|
function LZ_encode(c) {
|
|
33
21
|
(0, _assert.ok)(c);
|
|
34
22
|
var x = "charCodeAt",
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
b,
|
|
24
|
+
e = {},
|
|
25
|
+
f = c.split(""),
|
|
26
|
+
d = [],
|
|
27
|
+
a = f[0],
|
|
28
|
+
g = 256;
|
|
42
29
|
for (b = 1; b < f.length; b++) c = f[b], null != e[a + c] ? a += c : (d.push(1 < a.length ? e[a] : a[x](0)), e[a + c] = g, g++, a = c);
|
|
43
|
-
|
|
44
30
|
d.push(1 < a.length ? e[a] : a[x](0));
|
|
45
|
-
|
|
46
31
|
for (b = 0; b < d.length; b++) d[b] = String.fromCharCode(d[b]);
|
|
47
|
-
|
|
48
32
|
return d.join("");
|
|
49
33
|
}
|
|
50
|
-
|
|
51
34
|
function LZ_decode(b) {
|
|
52
35
|
(0, _assert.ok)(b);
|
|
53
36
|
var o,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
37
|
+
f,
|
|
38
|
+
a,
|
|
39
|
+
e = {},
|
|
40
|
+
d = b.split(""),
|
|
41
|
+
c = f = d[0],
|
|
42
|
+
g = [c],
|
|
43
|
+
h = o = 256;
|
|
62
44
|
for (var i = 1; i < d.length; i++) a = d[i].charCodeAt(0), a = h > a ? d[i] : e[a] ? e[a] : f + c, g.push(a), c = a.charAt(0), e[o] = f + c, o++, f = a;
|
|
63
|
-
|
|
64
45
|
return g.join("");
|
|
65
46
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
47
|
+
const DecodeTemplate = (0, _template.default)(`function {name}(b){
|
|
48
|
+
var o,
|
|
49
|
+
f,
|
|
50
|
+
a,
|
|
51
|
+
e = {},
|
|
52
|
+
d = b.split(""),
|
|
53
|
+
c = (f = d[0]),
|
|
54
|
+
g = [c],
|
|
55
|
+
h = (o = 256);
|
|
56
|
+
for (b = 1; b < d.length; b++)
|
|
57
|
+
(a = d[b].charCodeAt(0)),
|
|
58
|
+
(a = h > a ? d[b] : e[a] ? e[a] : f + c),
|
|
59
|
+
g.push(a),
|
|
60
|
+
(c = a.charAt(0)),
|
|
61
|
+
(e[o] = f + c),
|
|
62
|
+
o++,
|
|
63
|
+
(f = a);
|
|
64
|
+
return g.join("").split("{delimiter}");
|
|
65
|
+
}`);
|
|
69
66
|
class StringCompression extends _transform.default {
|
|
70
67
|
constructor(o) {
|
|
71
68
|
super(o, _order.ObfuscateOrder.StringCompression);
|
|
72
|
-
|
|
73
69
|
_defineProperty(this, "map", void 0);
|
|
74
|
-
|
|
75
70
|
_defineProperty(this, "ignore", void 0);
|
|
76
|
-
|
|
77
71
|
_defineProperty(this, "string", void 0);
|
|
78
|
-
|
|
79
72
|
_defineProperty(this, "delimiter", "|");
|
|
80
|
-
|
|
81
73
|
_defineProperty(this, "fnName", void 0);
|
|
82
|
-
|
|
83
74
|
this.map = new Map();
|
|
84
75
|
this.ignore = new Set();
|
|
85
76
|
this.string = "";
|
|
86
|
-
this.fnName = this.getPlaceholder();
|
|
77
|
+
this.fnName = this.getPlaceholder() + _constants.predictableFunctionTag;
|
|
87
78
|
}
|
|
88
|
-
|
|
89
79
|
apply(tree) {
|
|
90
80
|
super.apply(tree);
|
|
91
81
|
this.string = this.string.slice(0, this.string.length - 1);
|
|
92
|
-
|
|
93
82
|
if (!this.string.length) {
|
|
94
83
|
return;
|
|
95
84
|
}
|
|
96
|
-
|
|
97
85
|
var split = this.getPlaceholder();
|
|
98
86
|
var decoder = this.getPlaceholder();
|
|
99
|
-
var getStringName = this.getPlaceholder();
|
|
100
|
-
var encoded = LZ_encode(this.string);
|
|
87
|
+
var getStringName = this.getPlaceholder() + _constants.predictableFunctionTag; // Returns the string payload
|
|
101
88
|
|
|
89
|
+
var encoded = LZ_encode(this.string);
|
|
102
90
|
if (LZ_decode(encoded) !== this.string) {
|
|
103
91
|
this.error(new Error("String failed to be decoded. Try disabling the 'stringCompression' option."));
|
|
104
92
|
}
|
|
105
|
-
|
|
106
93
|
var getStringParamName = this.getPlaceholder();
|
|
107
94
|
var decoderParamName = this.getPlaceholder();
|
|
108
95
|
var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(decoderParamName), [(0, _gen.CallExpression)((0, _gen.Identifier)(getStringParamName), [])]);
|
|
@@ -114,50 +101,39 @@ class StringCompression extends _transform.default {
|
|
|
114
101
|
delimiter: this.delimiter
|
|
115
102
|
}));
|
|
116
103
|
}
|
|
117
|
-
|
|
118
104
|
match(object, parents) {
|
|
119
|
-
return object.type == "Literal" && typeof object.value === "string" && object.value && object.value.length > 3 && !(0, _compare.isDirective)(object, parents) && !(0,
|
|
105
|
+
return object.type == "Literal" && typeof object.value === "string" && object.value && object.value.length > 3 && !(0, _compare.isDirective)(object, parents) && !(0, _compare.isModuleSource)(object, parents);
|
|
120
106
|
}
|
|
121
|
-
|
|
122
107
|
transform(object, parents) {
|
|
123
108
|
if (!object.value) {
|
|
124
109
|
return;
|
|
125
110
|
}
|
|
126
|
-
|
|
127
111
|
if (this.ignore.has(object.value) || object.value.includes(this.delimiter)) {
|
|
128
112
|
return;
|
|
129
113
|
}
|
|
130
|
-
|
|
131
114
|
if (!parents[0] || parents[0].type == "CallExpression" && parents[0].callee.type == "Identifier" && parents[0].callee.name == this.fnName) {
|
|
132
115
|
return;
|
|
133
116
|
}
|
|
134
|
-
|
|
135
117
|
if (!(0, _probability.ComputeProbabilityMap)(this.options.stringCompression, x => x, object.value)) {
|
|
136
118
|
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (this.map.size > 1000 && !(0, _random.chance)(this.map.size / 100)) return;
|
|
141
|
-
var index = this.map.get(object.value); // New string, add it!
|
|
119
|
+
}
|
|
120
|
+
var index = this.map.get(object.value);
|
|
142
121
|
|
|
122
|
+
// New string, add it!
|
|
143
123
|
if (typeof index !== "number") {
|
|
144
124
|
// Ensure the string gets properly decoded
|
|
145
125
|
if (LZ_decode(LZ_encode(object.value)) !== object.value) {
|
|
146
126
|
this.ignore.add(object.value);
|
|
147
127
|
return;
|
|
148
128
|
}
|
|
149
|
-
|
|
150
129
|
index = this.map.size;
|
|
151
130
|
this.map.set(object.value, index);
|
|
152
131
|
this.string += object.value + this.delimiter;
|
|
153
132
|
}
|
|
154
|
-
|
|
155
133
|
(0, _assert.ok)(typeof index === "number");
|
|
156
134
|
return () => {
|
|
157
135
|
this.replaceIdentifierOrLiteral(object, (0, _gen.CallExpression)((0, _gen.Identifier)(this.fnName), [(0, _gen.Literal)(index)]), parents);
|
|
158
136
|
};
|
|
159
137
|
}
|
|
160
|
-
|
|
161
138
|
}
|
|
162
|
-
|
|
163
139
|
exports.default = StringCompression;
|
|
@@ -4,236 +4,230 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
exports.isModuleSource = isModuleSource;
|
|
8
|
-
|
|
9
7
|
var _assert = require("assert");
|
|
10
|
-
|
|
11
8
|
var _order = require("../../order");
|
|
12
|
-
|
|
13
9
|
var _template = _interopRequireDefault(require("../../templates/template"));
|
|
14
|
-
|
|
15
10
|
var _traverse = require("../../traverse");
|
|
16
|
-
|
|
17
11
|
var _compare = require("../../util/compare");
|
|
18
|
-
|
|
19
12
|
var _gen = require("../../util/gen");
|
|
20
|
-
|
|
21
13
|
var _insert = require("../../util/insert");
|
|
22
|
-
|
|
23
14
|
var _random = require("../../util/random");
|
|
24
|
-
|
|
25
15
|
var _transform = _interopRequireDefault(require("../transform"));
|
|
26
|
-
|
|
27
|
-
var _encoding = _interopRequireDefault(require("./encoding"));
|
|
28
|
-
|
|
16
|
+
var _encoding = require("./encoding");
|
|
29
17
|
var _probability = require("../../probability");
|
|
30
|
-
|
|
31
18
|
var _bufferToString = require("../../templates/bufferToString");
|
|
32
|
-
|
|
33
|
-
function _interopRequireDefault(
|
|
34
|
-
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
function isModuleSource(object, parents) {
|
|
38
|
-
if (!parents[0]) {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (parents[0].type == "ImportDeclaration" && parents[0].source == object) {
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (parents[0].type == "ImportExpression" && parents[0].source == object) {
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (parents[1] && parents[1].type == "CallExpression" && parents[1].arguments[0] === object && parents[1].callee.type == "Identifier") {
|
|
51
|
-
if (parents[1].callee.name == "require" || parents[1].callee.name == "import") {
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
|
|
19
|
+
var _constants = require("../../constants");
|
|
20
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
21
|
+
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; }
|
|
22
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
23
|
+
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); }
|
|
59
24
|
class StringConcealing extends _transform.default {
|
|
60
25
|
constructor(o) {
|
|
61
26
|
super(o, _order.ObfuscateOrder.StringConcealing);
|
|
62
|
-
|
|
63
27
|
_defineProperty(this, "arrayExpression", void 0);
|
|
64
|
-
|
|
65
28
|
_defineProperty(this, "set", void 0);
|
|
66
|
-
|
|
67
29
|
_defineProperty(this, "index", void 0);
|
|
68
|
-
|
|
30
|
+
// index, fnName, block
|
|
69
31
|
_defineProperty(this, "arrayName", this.getPlaceholder());
|
|
70
|
-
|
|
71
32
|
_defineProperty(this, "ignore", new Set());
|
|
72
|
-
|
|
73
33
|
_defineProperty(this, "variablesMade", 1);
|
|
74
|
-
|
|
75
|
-
_defineProperty(this, "encoding", Object.create(null));
|
|
76
|
-
|
|
77
34
|
_defineProperty(this, "gen", void 0);
|
|
78
|
-
|
|
79
|
-
_defineProperty(this, "hasAllEncodings", void 0);
|
|
80
|
-
|
|
35
|
+
_defineProperty(this, "functionObjects", []);
|
|
81
36
|
this.set = new Set();
|
|
82
37
|
this.index = Object.create(null);
|
|
83
38
|
this.arrayExpression = (0, _gen.ArrayExpression)([]);
|
|
84
|
-
this.
|
|
85
|
-
|
|
39
|
+
this.gen = this.getGenerator();
|
|
40
|
+
}
|
|
41
|
+
apply(tree) {
|
|
42
|
+
super.apply(tree);
|
|
86
43
|
|
|
44
|
+
// Pad array with useless strings
|
|
87
45
|
var dead = (0, _random.getRandomInteger)(5, 15);
|
|
88
|
-
|
|
89
46
|
for (var i = 0; i < dead; i++) {
|
|
90
47
|
var str = (0, _random.getRandomString)((0, _random.getRandomInteger)(5, 40));
|
|
91
|
-
var fn = this.transform((0, _gen.Literal)(str), []);
|
|
92
|
-
|
|
48
|
+
var fn = this.transform((0, _gen.Literal)(str), [tree]);
|
|
93
49
|
if (fn) {
|
|
94
50
|
fn();
|
|
95
51
|
}
|
|
96
52
|
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
apply(tree) {
|
|
100
|
-
super.apply(tree);
|
|
101
53
|
var cacheName = this.getPlaceholder();
|
|
102
|
-
var bufferToStringName = this.getPlaceholder()
|
|
54
|
+
var bufferToStringName = this.getPlaceholder() + _constants.predictableFunctionTag;
|
|
103
55
|
|
|
56
|
+
// This helper functions convert UInt8 Array to UTf-string
|
|
104
57
|
(0, _insert.prepend)(tree, ..._bufferToString.BufferToStringTemplate.compile({
|
|
105
|
-
name: bufferToStringName
|
|
58
|
+
name: bufferToStringName,
|
|
59
|
+
getGlobalFnName: this.getPlaceholder() + _constants.predictableFunctionTag
|
|
106
60
|
}));
|
|
107
|
-
|
|
61
|
+
for (var functionObject of this.functionObjects) {
|
|
108
62
|
var {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
63
|
+
block,
|
|
64
|
+
fnName: getterFnName,
|
|
65
|
+
encodingImplementation
|
|
66
|
+
} = functionObject;
|
|
67
|
+
var decodeFn = this.getPlaceholder() + _constants.predictableFunctionTag + _constants.criticalFunctionTag;
|
|
68
|
+
(0, _insert.append)(block, encodingImplementation.template.single({
|
|
69
|
+
__fnName__: decodeFn,
|
|
70
|
+
__bufferToString__: bufferToStringName
|
|
116
71
|
}));
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
72
|
+
// All these are fake and never ran
|
|
73
|
+
var ifStatements = (0, _template.default)(`if ( z == x ) {
|
|
74
|
+
return y[${cacheName}[z]] = ${getterFnName}(x, y);
|
|
75
|
+
}
|
|
76
|
+
if ( y ) {
|
|
77
|
+
[b, y] = [a(b), x || z]
|
|
78
|
+
return ${getterFnName}(x, b, z)
|
|
79
|
+
}
|
|
80
|
+
if ( z && a !== ${decodeFn} ) {
|
|
81
|
+
${getterFnName} = ${decodeFn}
|
|
82
|
+
return ${getterFnName}(x, -1, z, a, b)
|
|
83
|
+
}
|
|
84
|
+
if ( a === ${getterFnName} ) {
|
|
85
|
+
${decodeFn} = y
|
|
86
|
+
return ${decodeFn}(z)
|
|
87
|
+
}
|
|
88
|
+
if( a === undefined ) {
|
|
89
|
+
${getterFnName} = b
|
|
90
|
+
}
|
|
91
|
+
if( z == a ) {
|
|
92
|
+
return y ? x[b[y]] : ${cacheName}[x] || (z=(b[x] || a), ${cacheName}[x] = z(${this.arrayName}[x]))
|
|
93
|
+
}
|
|
94
|
+
`).compile();
|
|
122
95
|
|
|
123
|
-
|
|
124
|
-
|
|
96
|
+
// Not all fake if-statements are needed
|
|
97
|
+
ifStatements = ifStatements.filter(() => (0, _random.chance)(50));
|
|
125
98
|
|
|
126
|
-
|
|
127
|
-
|
|
99
|
+
// This one is always used
|
|
100
|
+
ifStatements.push((0, _template.default)(`
|
|
101
|
+
if ( x !== y ) {
|
|
102
|
+
return b[x] || (b[x] = a(${this.arrayName}[x]))
|
|
103
|
+
}
|
|
104
|
+
`).single());
|
|
105
|
+
(0, _random.shuffle)(ifStatements);
|
|
106
|
+
var varDeclaration = (0, _template.default)(`
|
|
107
|
+
var ${getterFnName} = (x, y, z, a, b)=>{
|
|
108
|
+
if(typeof a === "undefined") {
|
|
109
|
+
a = ${decodeFn}
|
|
110
|
+
}
|
|
111
|
+
if(typeof b === "undefined") {
|
|
112
|
+
b = ${cacheName}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
`).single();
|
|
116
|
+
varDeclaration.declarations[0].init.body.body.push(...ifStatements);
|
|
117
|
+
(0, _insert.prepend)(block, varDeclaration);
|
|
118
|
+
}
|
|
119
|
+
(0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(cacheName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)(this.arrayName, this.arrayExpression)]));
|
|
120
|
+
}
|
|
121
|
+
match(object, parents) {
|
|
122
|
+
return object.type == "Literal" && typeof object.value === "string" && object.value.length >= 3 && !(0, _compare.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents) //&&
|
|
123
|
+
/*!parents.find((x) => x.$dispatcherSkip)*/;
|
|
128
124
|
}
|
|
129
|
-
|
|
130
125
|
transform(object, parents) {
|
|
131
126
|
return () => {
|
|
132
127
|
// Empty strings are discarded
|
|
133
128
|
if (!object.value || this.ignore.has(object.value) || object.value.length == 0) {
|
|
134
129
|
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
130
|
+
}
|
|
137
131
|
|
|
132
|
+
// Allow user to choose which strings get changed
|
|
138
133
|
if (!(0, _probability.ComputeProbabilityMap)(this.options.stringConcealing, x => x, object.value)) {
|
|
139
134
|
return;
|
|
140
|
-
} // HARD CODED LIMIT of 10,000 (after 1,000 elements)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (this.set.size > 1000 && !(0, _random.chance)(this.set.size / 100)) return;
|
|
144
|
-
var types = Object.keys(this.encoding);
|
|
145
|
-
var type = (0, _random.choice)(types);
|
|
146
|
-
|
|
147
|
-
if (!type || !this.hasAllEncodings && (0, _random.chance)(10)) {
|
|
148
|
-
var allowed = Object.keys(_encoding.default).filter(type => !this.encoding[type]);
|
|
149
|
-
|
|
150
|
-
if (!allowed.length) {
|
|
151
|
-
this.hasAllEncodings = true;
|
|
152
|
-
} else {
|
|
153
|
-
var random = (0, _random.choice)(allowed);
|
|
154
|
-
type = random;
|
|
155
|
-
this.encoding[random] = this.getPlaceholder();
|
|
156
|
-
}
|
|
157
135
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
136
|
+
var currentBlock = (0, _traverse.getBlock)(object, parents);
|
|
137
|
+
|
|
138
|
+
// Find created functions
|
|
139
|
+
var functionObjects = parents.filter(node => node.$stringConcealingFunctionObject).map(item => item.$stringConcealingFunctionObject);
|
|
140
|
+
|
|
141
|
+
// Choose random functionObject to use
|
|
142
|
+
var functionObject = (0, _random.choice)(functionObjects);
|
|
143
|
+
if (!functionObject || !(0, _encoding.hasAllEncodings)() && (0, _random.chance)(25 / this.functionObjects.length) && !currentBlock.$stringConcealingFunctionObject) {
|
|
144
|
+
// No functions, create one
|
|
145
|
+
|
|
146
|
+
var newFunctionObject = {
|
|
147
|
+
block: currentBlock,
|
|
148
|
+
encodingImplementation: (0, _encoding.createEncodingImplementation)(),
|
|
149
|
+
fnName: this.getPlaceholder() + _constants.predictableFunctionTag
|
|
150
|
+
};
|
|
151
|
+
this.functionObjects.push(newFunctionObject);
|
|
152
|
+
currentBlock.$stringConcealingFunctionObject = newFunctionObject;
|
|
153
|
+
functionObject = newFunctionObject;
|
|
168
154
|
}
|
|
169
|
-
|
|
155
|
+
var {
|
|
156
|
+
fnName,
|
|
157
|
+
encodingImplementation
|
|
158
|
+
} = functionObject;
|
|
170
159
|
var index = -1;
|
|
171
160
|
|
|
172
|
-
|
|
161
|
+
// String already decoded?
|
|
162
|
+
if (this.set.has(object.value)) {
|
|
163
|
+
var row = this.index[object.value];
|
|
164
|
+
if (parents.includes(row[2])) {
|
|
165
|
+
[index, fnName] = row;
|
|
166
|
+
(0, _assert.ok)(typeof index === "number");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (index == -1) {
|
|
170
|
+
// The decode function must return correct result
|
|
171
|
+
var encoded = encodingImplementation.encode(object.value);
|
|
172
|
+
if (encodingImplementation.decode(encoded) !== object.value) {
|
|
173
|
+
this.ignore.add(object.value);
|
|
174
|
+
this.warn(encodingImplementation.identity, object.value.slice(0, 100));
|
|
175
|
+
delete _encoding.EncodingImplementations[encodingImplementation.identity];
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
173
178
|
this.arrayExpression.elements.push((0, _gen.Literal)(encoded));
|
|
174
179
|
index = this.arrayExpression.elements.length - 1;
|
|
175
|
-
this.index[object.value] = [index, fnName];
|
|
180
|
+
this.index[object.value] = [index, fnName, currentBlock];
|
|
176
181
|
this.set.add(object.value);
|
|
177
|
-
} else {
|
|
178
|
-
[index, fnName] = this.index[object.value];
|
|
179
|
-
(0, _assert.ok)(typeof index === "number");
|
|
180
182
|
}
|
|
181
|
-
|
|
182
183
|
(0, _assert.ok)(index != -1, "index == -1");
|
|
183
|
-
var callExpr = (0, _gen.CallExpression)((0, _gen.Identifier)(fnName), [(0, _gen.Literal)(index)]);
|
|
184
|
+
var callExpr = (0, _gen.CallExpression)((0, _gen.Identifier)(fnName), [(0, _gen.Literal)(index)]);
|
|
184
185
|
|
|
186
|
+
// use `.apply` to fool automated de-obfuscators
|
|
185
187
|
if ((0, _random.chance)(10)) {
|
|
186
188
|
callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Literal)("apply"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.ArrayExpression)([(0, _gen.Literal)(index)])]);
|
|
187
|
-
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// use `.call`
|
|
188
192
|
else if ((0, _random.chance)(10)) {
|
|
189
193
|
callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Literal)("call"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.Literal)(index)]);
|
|
190
194
|
}
|
|
191
|
-
|
|
192
195
|
var referenceType = "call";
|
|
193
|
-
|
|
194
196
|
if (parents.length && (0, _random.chance)(50 - this.variablesMade)) {
|
|
195
197
|
referenceType = "constantReference";
|
|
196
198
|
}
|
|
197
|
-
|
|
198
199
|
var newExpr = callExpr;
|
|
199
|
-
|
|
200
200
|
if (referenceType === "constantReference") {
|
|
201
201
|
// Define the string earlier, reference the name here
|
|
202
202
|
this.variablesMade++;
|
|
203
203
|
var constantReferenceType = (0, _random.choice)(["variable", "array", "object"]);
|
|
204
|
-
var place =
|
|
205
|
-
|
|
204
|
+
var place = currentBlock;
|
|
206
205
|
if (!place) {
|
|
207
206
|
this.error(new Error("No lexical block to insert code"));
|
|
208
207
|
}
|
|
209
|
-
|
|
210
208
|
switch (constantReferenceType) {
|
|
211
209
|
case "variable":
|
|
212
210
|
var name = this.getPlaceholder();
|
|
213
211
|
(0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, callExpr)));
|
|
214
212
|
newExpr = (0, _gen.Identifier)(name);
|
|
215
213
|
break;
|
|
216
|
-
|
|
217
214
|
case "array":
|
|
218
215
|
if (!place.$stringConcealingArray) {
|
|
219
216
|
place.$stringConcealingArray = (0, _gen.ArrayExpression)([]);
|
|
220
217
|
place.$stringConcealingArrayName = this.getPlaceholder();
|
|
221
218
|
(0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(place.$stringConcealingArrayName, place.$stringConcealingArray)));
|
|
222
219
|
}
|
|
223
|
-
|
|
224
220
|
var arrayIndex = place.$stringConcealingArray.elements.length;
|
|
225
221
|
place.$stringConcealingArray.elements.push(callExpr);
|
|
226
222
|
var memberExpression = (0, _gen.MemberExpression)((0, _gen.Identifier)(place.$stringConcealingArrayName), (0, _gen.Literal)(arrayIndex), true);
|
|
227
223
|
newExpr = memberExpression;
|
|
228
224
|
break;
|
|
229
|
-
|
|
230
225
|
case "object":
|
|
231
226
|
if (!place.$stringConcealingObject) {
|
|
232
227
|
place.$stringConcealingObject = (0, _gen.ObjectExpression)([]);
|
|
233
228
|
place.$stringConcealingObjectName = this.getPlaceholder();
|
|
234
229
|
(0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(place.$stringConcealingObjectName, place.$stringConcealingObject)));
|
|
235
230
|
}
|
|
236
|
-
|
|
237
231
|
var propName = this.gen.generate();
|
|
238
232
|
var property = (0, _gen.Property)((0, _gen.Literal)(propName), callExpr, true);
|
|
239
233
|
place.$stringConcealingObject.properties.push(property);
|
|
@@ -242,11 +236,8 @@ class StringConcealing extends _transform.default {
|
|
|
242
236
|
break;
|
|
243
237
|
}
|
|
244
238
|
}
|
|
245
|
-
|
|
246
239
|
this.replaceIdentifierOrLiteral(object, newExpr, parents);
|
|
247
240
|
};
|
|
248
241
|
}
|
|
249
|
-
|
|
250
242
|
}
|
|
251
|
-
|
|
252
243
|
exports.default = StringConcealing;
|
|
@@ -4,42 +4,28 @@ 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 _random = require("../../util/random");
|
|
11
|
-
|
|
12
9
|
var _compare = require("../../util/compare");
|
|
13
|
-
|
|
14
|
-
var _stringConcealing = require("./stringConcealing");
|
|
15
|
-
|
|
16
10
|
var _probability = require("../../probability");
|
|
17
|
-
|
|
18
11
|
var _gen = require("../../util/gen");
|
|
19
|
-
|
|
20
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
-
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
13
|
function pad(x, len) {
|
|
23
14
|
while (x.length < len) {
|
|
24
15
|
x = "0" + x;
|
|
25
16
|
}
|
|
26
|
-
|
|
27
17
|
return x;
|
|
28
18
|
}
|
|
29
|
-
|
|
30
19
|
function even(x) {
|
|
31
20
|
if (x.length % 2 != 0) {
|
|
32
21
|
return "0" + x;
|
|
33
22
|
}
|
|
34
|
-
|
|
35
23
|
return x;
|
|
36
24
|
}
|
|
37
|
-
|
|
38
25
|
function toHexRepresentation(str) {
|
|
39
26
|
var escapedString = "";
|
|
40
27
|
str.split("").forEach(char => {
|
|
41
28
|
var code = char.charCodeAt(0);
|
|
42
|
-
|
|
43
29
|
if (code < 128) {
|
|
44
30
|
escapedString += "\\x" + even(pad(code.toString(16), 2));
|
|
45
31
|
} else {
|
|
@@ -48,12 +34,10 @@ function toHexRepresentation(str) {
|
|
|
48
34
|
});
|
|
49
35
|
return escapedString;
|
|
50
36
|
}
|
|
51
|
-
|
|
52
37
|
function toUnicodeRepresentation(str) {
|
|
53
38
|
var escapedString = "";
|
|
54
39
|
str.split("").forEach(char => {
|
|
55
40
|
var code = char.charCodeAt(0);
|
|
56
|
-
|
|
57
41
|
if (code < 128) {
|
|
58
42
|
escapedString += "\\u" + even(pad(code.toString(16), 4));
|
|
59
43
|
} else {
|
|
@@ -62,6 +46,7 @@ function toUnicodeRepresentation(str) {
|
|
|
62
46
|
});
|
|
63
47
|
return escapedString;
|
|
64
48
|
}
|
|
49
|
+
|
|
65
50
|
/**
|
|
66
51
|
* [String Encoding](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-encoding) transforms a string into an encoded representation.
|
|
67
52
|
*
|
|
@@ -69,29 +54,24 @@ function toUnicodeRepresentation(str) {
|
|
|
69
54
|
* - Resilience Low
|
|
70
55
|
* - Cost Low
|
|
71
56
|
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
57
|
class StringEncoding extends _transform.default {
|
|
75
58
|
constructor(o) {
|
|
76
59
|
super(o);
|
|
77
60
|
}
|
|
78
|
-
|
|
79
61
|
match(object, parents) {
|
|
80
|
-
return object.type == "Literal" && typeof object.value === "string" && object.value.length > 0 && !(0,
|
|
62
|
+
return object.type == "Literal" && typeof object.value === "string" && object.value.length > 0 && !(0, _compare.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents);
|
|
81
63
|
}
|
|
82
|
-
|
|
83
64
|
transform(object, parents) {
|
|
84
65
|
// Allow percentages
|
|
85
66
|
if (!(0, _probability.ComputeProbabilityMap)(this.options.stringEncoding, x => x, object.value)) return;
|
|
86
67
|
var type = (0, _random.choice)(["hexadecimal", "unicode"]);
|
|
87
68
|
var escapedString = (type == "hexadecimal" ? toHexRepresentation : toUnicodeRepresentation)(object.value);
|
|
88
69
|
return () => {
|
|
89
|
-
if (object.type !== "Literal") return;
|
|
70
|
+
if (object.type !== "Literal") return;
|
|
90
71
|
|
|
91
|
-
|
|
72
|
+
// ESCodeGen tries to escape backslashes, here is a work-around
|
|
73
|
+
this.replace(object, (0, _gen.Identifier)(`'${escapedString}'`));
|
|
92
74
|
};
|
|
93
75
|
}
|
|
94
|
-
|
|
95
76
|
}
|
|
96
|
-
|
|
97
77
|
exports.default = StringEncoding;
|