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
package/dist/util/insert.js
CHANGED
|
@@ -17,18 +17,20 @@ exports.getIndexDirect = getIndexDirect;
|
|
|
17
17
|
exports.getLexContext = getLexContext;
|
|
18
18
|
exports.getReferencingContexts = getReferencingContexts;
|
|
19
19
|
exports.getVarContext = getVarContext;
|
|
20
|
+
exports.isClass = isClass;
|
|
20
21
|
exports.isContext = isContext;
|
|
21
22
|
exports.isForInitialize = isForInitialize;
|
|
22
23
|
exports.isFunction = isFunction;
|
|
23
24
|
exports.isLexContext = isLexContext;
|
|
25
|
+
exports.isStrictModeFunction = isStrictModeFunction;
|
|
24
26
|
exports.isVarContext = isVarContext;
|
|
25
27
|
exports.prepend = prepend;
|
|
26
|
-
|
|
27
28
|
var _assert = require("assert");
|
|
28
|
-
|
|
29
29
|
var _traverse = require("../traverse");
|
|
30
|
-
|
|
31
30
|
var _identifiers = require("./identifiers");
|
|
31
|
+
function isClass(object) {
|
|
32
|
+
return object.type === "ClassDeclaration" || object.type === "ClassExpression";
|
|
33
|
+
}
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
36
|
* - `FunctionDeclaration`
|
|
@@ -40,6 +42,11 @@ var _identifiers = require("./identifiers");
|
|
|
40
42
|
function isFunction(object) {
|
|
41
43
|
return ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"].includes(object && object.type);
|
|
42
44
|
}
|
|
45
|
+
function isStrictModeFunction(object) {
|
|
46
|
+
(0, _assert.ok)(isFunction(object));
|
|
47
|
+
return object.body.type === "BlockStatement" && object.body.body[0] && object.body.body[0].type === "ExpressionStatement" && object.body.body[0].directive === "use strict";
|
|
48
|
+
}
|
|
49
|
+
|
|
43
50
|
/**
|
|
44
51
|
* The function context where the object is.
|
|
45
52
|
*
|
|
@@ -49,189 +56,154 @@ function isFunction(object) {
|
|
|
49
56
|
* @param object
|
|
50
57
|
* @param parents
|
|
51
58
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
59
|
function getFunction(object, parents) {
|
|
55
60
|
return parents.find(x => isFunction(x));
|
|
56
61
|
}
|
|
62
|
+
|
|
57
63
|
/**
|
|
58
64
|
* Refers to the current function or Root node
|
|
59
65
|
* @param parents
|
|
60
66
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
67
|
function getVarContext(object, parents) {
|
|
64
68
|
var fn = getFunction(object, parents);
|
|
65
|
-
|
|
66
69
|
if (fn) {
|
|
67
70
|
return fn;
|
|
68
71
|
}
|
|
69
|
-
|
|
70
72
|
var top = parents[parents.length - 1] || object;
|
|
71
|
-
|
|
72
73
|
if (top) {
|
|
73
74
|
(0, _assert.ok)(top.type == "Program", "Root node not program, its " + top.type);
|
|
74
75
|
return top;
|
|
75
76
|
}
|
|
76
|
-
|
|
77
77
|
throw new Error("Missing root node");
|
|
78
78
|
}
|
|
79
|
+
|
|
79
80
|
/**
|
|
80
81
|
* `Function` or root node
|
|
81
82
|
* @param object
|
|
82
83
|
* @returns
|
|
83
84
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
85
|
function isVarContext(object) {
|
|
87
86
|
return isFunction(object) || object.type == "Program" || object.type == "DoExpression"; // Stage 1
|
|
88
87
|
}
|
|
88
|
+
|
|
89
89
|
/**
|
|
90
90
|
* `Block` or root node
|
|
91
91
|
* @param object
|
|
92
92
|
* @returns
|
|
93
93
|
*/
|
|
94
|
-
|
|
95
|
-
|
|
96
94
|
function isLexContext(object) {
|
|
97
95
|
return (0, _traverse.isBlock)(object) || object.type == "Program";
|
|
98
96
|
}
|
|
97
|
+
|
|
99
98
|
/**
|
|
100
99
|
* Either a `var context` or `lex context`
|
|
101
100
|
* @param object
|
|
102
101
|
* @returns
|
|
103
102
|
*/
|
|
104
|
-
|
|
105
|
-
|
|
106
103
|
function isContext(object) {
|
|
107
104
|
return isVarContext(object) || isLexContext(object);
|
|
108
105
|
}
|
|
109
|
-
|
|
110
106
|
function getContexts(object, parents) {
|
|
111
107
|
return [object, ...parents].filter(x => isContext(x));
|
|
112
108
|
}
|
|
109
|
+
|
|
113
110
|
/**
|
|
114
111
|
* Refers to the current lexical block or Root node.
|
|
115
112
|
* @param parents
|
|
116
113
|
*/
|
|
117
|
-
|
|
118
|
-
|
|
119
114
|
function getLexContext(object, parents) {
|
|
120
115
|
var block = (0, _traverse.getBlock)(object, parents);
|
|
121
|
-
|
|
122
116
|
if (block) {
|
|
123
117
|
return block;
|
|
124
118
|
}
|
|
125
|
-
|
|
126
119
|
var top = parents[parents.length - 1];
|
|
127
|
-
|
|
128
120
|
if (!top) {
|
|
129
121
|
throw new Error("Missing root node");
|
|
130
122
|
}
|
|
131
123
|
}
|
|
132
|
-
|
|
133
124
|
function getDefiningContext(o, p) {
|
|
134
125
|
(0, _identifiers.validateChain)(o, p);
|
|
135
126
|
(0, _assert.ok)(o.type == "Identifier");
|
|
136
127
|
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
137
128
|
(0, _assert.ok)(info.spec.isDefined);
|
|
138
|
-
|
|
139
129
|
if (info.isVariableDeclaration) {
|
|
140
130
|
var variableDeclaration = p.find(x => x.type == "VariableDeclaration");
|
|
141
131
|
(0, _assert.ok)(variableDeclaration);
|
|
142
|
-
|
|
143
132
|
if (variableDeclaration.kind === "let" || variableDeclaration.kind === "const") {
|
|
144
133
|
var context = getVarContext(o, p);
|
|
145
|
-
|
|
146
134
|
if (context && context.type === "Program") {
|
|
147
135
|
return getLexContext(o, p);
|
|
148
136
|
}
|
|
149
137
|
}
|
|
150
138
|
}
|
|
151
|
-
|
|
152
139
|
if (info.isFunctionDeclaration) {
|
|
153
140
|
return getVarContext(p[0], p.slice(1));
|
|
154
141
|
}
|
|
155
|
-
|
|
156
142
|
return getVarContext(o, p);
|
|
157
143
|
}
|
|
144
|
+
|
|
158
145
|
/**
|
|
159
146
|
* A more accurate context finding function.
|
|
160
147
|
* @param o Object
|
|
161
148
|
* @param p Parents
|
|
162
149
|
* @returns Contexts
|
|
163
150
|
*/
|
|
164
|
-
|
|
165
|
-
|
|
166
151
|
function getAllDefiningContexts(o, p) {
|
|
167
152
|
var contexts = [getDefiningContext(o, p)];
|
|
168
153
|
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
169
|
-
|
|
170
154
|
if (info.isFunctionParameter) {
|
|
171
155
|
// Get Function
|
|
172
|
-
var fn = getFunction(o, p);
|
|
173
|
-
}
|
|
156
|
+
var fn = getFunction(o, p);
|
|
174
157
|
|
|
158
|
+
// contexts.push(fn.body);
|
|
159
|
+
}
|
|
175
160
|
if (info.isClauseParameter) {
|
|
176
161
|
var catchClause = p.find(x => x.type === "CatchClause");
|
|
177
|
-
|
|
178
162
|
if (catchClause) {
|
|
179
163
|
return [catchClause];
|
|
180
164
|
}
|
|
181
165
|
}
|
|
182
|
-
|
|
183
166
|
return contexts;
|
|
184
167
|
}
|
|
185
|
-
|
|
186
168
|
function getReferencingContexts(o, p, info) {
|
|
187
169
|
(0, _identifiers.validateChain)(o, p);
|
|
188
170
|
(0, _assert.ok)(o.type == "Identifier");
|
|
189
|
-
|
|
190
171
|
if (!info) {
|
|
191
172
|
info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
192
173
|
}
|
|
193
|
-
|
|
194
174
|
(0, _assert.ok)(info.spec.isReferenced);
|
|
195
175
|
return [getVarContext(o, p), getLexContext(o, p)];
|
|
196
176
|
}
|
|
197
|
-
|
|
198
177
|
function getBlockBody(block) {
|
|
199
178
|
if (!block) {
|
|
200
179
|
throw new Error("no block body");
|
|
201
180
|
}
|
|
202
|
-
|
|
203
181
|
if (Array.isArray(block)) {
|
|
204
182
|
return block;
|
|
205
183
|
}
|
|
206
|
-
|
|
207
184
|
return getBlockBody(block.body);
|
|
208
185
|
}
|
|
209
|
-
|
|
210
186
|
function getIndexDirect(object, parent) {
|
|
211
187
|
return Object.keys(parent).find(x => parent[x] == object);
|
|
212
188
|
}
|
|
189
|
+
|
|
213
190
|
/**
|
|
214
191
|
* Attempts to a delete a variable/functions declaration.
|
|
215
192
|
* @param object
|
|
216
193
|
* @param parents
|
|
217
194
|
*/
|
|
218
|
-
|
|
219
|
-
|
|
220
195
|
function deleteDeclaration(object, parents) {
|
|
221
|
-
(0, _identifiers.validateChain)(object, parents);
|
|
196
|
+
(0, _identifiers.validateChain)(object, parents);
|
|
222
197
|
|
|
198
|
+
// variables
|
|
223
199
|
var list = [object, ...parents];
|
|
224
200
|
var declaratorIndex = list.findIndex(x => x.type == "VariableDeclarator");
|
|
225
|
-
|
|
226
201
|
if (declaratorIndex != -1) {
|
|
227
202
|
var declarator = list[declaratorIndex]; // {type: VariableDeclarator, id: Identifier, init: Literal|Expression...}
|
|
228
|
-
|
|
229
203
|
var declarations = list[declaratorIndex + 1]; // declarator[]
|
|
230
|
-
|
|
231
204
|
var VariableDeclaration = list[declaratorIndex + 2];
|
|
232
205
|
var body = list[declaratorIndex + 3];
|
|
233
206
|
deleteDirect(declarator, declarations);
|
|
234
|
-
|
|
235
207
|
if (VariableDeclaration.declarations.length == 0) {
|
|
236
208
|
deleteDirect(VariableDeclaration, body);
|
|
237
209
|
}
|
|
@@ -239,30 +211,24 @@ function deleteDeclaration(object, parents) {
|
|
|
239
211
|
if (object.type != "FunctionDeclaration") {
|
|
240
212
|
throw new Error("No method to delete: " + object.type);
|
|
241
213
|
}
|
|
242
|
-
|
|
243
214
|
deleteDirect(object, parents[0]);
|
|
244
215
|
}
|
|
245
216
|
}
|
|
217
|
+
|
|
246
218
|
/**
|
|
247
219
|
* Object must be directly nested in parent
|
|
248
220
|
*/
|
|
249
|
-
|
|
250
|
-
|
|
251
221
|
function deleteDirect(object, parent) {
|
|
252
222
|
if (!object) {
|
|
253
223
|
throw new Error("object undefined");
|
|
254
224
|
}
|
|
255
|
-
|
|
256
225
|
if (!parent) {
|
|
257
226
|
throw new Error("parent undefined");
|
|
258
227
|
}
|
|
259
|
-
|
|
260
228
|
(0, _identifiers.validateChain)(object, [parent]);
|
|
261
|
-
|
|
262
229
|
if (typeof parent === "object") {
|
|
263
230
|
if (Array.isArray(parent)) {
|
|
264
231
|
var index = parent.indexOf(object);
|
|
265
|
-
|
|
266
232
|
if (index != -1) {
|
|
267
233
|
// delete
|
|
268
234
|
parent.splice(index, 1);
|
|
@@ -273,7 +239,6 @@ function deleteDirect(object, parent) {
|
|
|
273
239
|
}
|
|
274
240
|
} else {
|
|
275
241
|
var keyName = Object.keys(parent).find(x => parent[x] == object);
|
|
276
|
-
|
|
277
242
|
if (keyName) {
|
|
278
243
|
delete parent[keyName];
|
|
279
244
|
} else {
|
|
@@ -282,14 +247,11 @@ function deleteDirect(object, parent) {
|
|
|
282
247
|
}
|
|
283
248
|
}
|
|
284
249
|
}
|
|
285
|
-
|
|
286
250
|
function prepend(block) {
|
|
287
251
|
(0, _assert.ok)(!Array.isArray(block), "block should not be array");
|
|
288
|
-
|
|
289
252
|
for (var _len = arguments.length, nodes = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
290
253
|
nodes[_key - 1] = arguments[_key];
|
|
291
254
|
}
|
|
292
|
-
|
|
293
255
|
if (block.type == "Program") {
|
|
294
256
|
var moveBy = 0;
|
|
295
257
|
block.body.forEach((stmt, i) => {
|
|
@@ -298,7 +260,6 @@ function prepend(block) {
|
|
|
298
260
|
moveBy++;
|
|
299
261
|
}
|
|
300
262
|
}
|
|
301
|
-
|
|
302
263
|
if (stmt.type === "ExpressionStatement" && typeof stmt.directive === "string") {
|
|
303
264
|
if (moveBy == i) {
|
|
304
265
|
moveBy++;
|
|
@@ -309,8 +270,9 @@ function prepend(block) {
|
|
|
309
270
|
} else if (block.type === "SwitchCase") {
|
|
310
271
|
block.consequent.unshift(...nodes);
|
|
311
272
|
} else {
|
|
312
|
-
var bodyArray = getBlockBody(block);
|
|
273
|
+
var bodyArray = getBlockBody(block);
|
|
313
274
|
|
|
275
|
+
// Check for 'use strict'
|
|
314
276
|
if (bodyArray[0] && bodyArray[0].directive) {
|
|
315
277
|
// Insert under 'use strict' directive
|
|
316
278
|
bodyArray.splice(1, 0, ...nodes);
|
|
@@ -320,17 +282,13 @@ function prepend(block) {
|
|
|
320
282
|
}
|
|
321
283
|
}
|
|
322
284
|
}
|
|
323
|
-
|
|
324
285
|
function append(block) {
|
|
325
286
|
(0, _assert.ok)(!Array.isArray(block), "block should not be array");
|
|
326
|
-
|
|
327
287
|
for (var _len2 = arguments.length, nodes = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
328
288
|
nodes[_key2 - 1] = arguments[_key2];
|
|
329
289
|
}
|
|
330
|
-
|
|
331
290
|
getBlockBody(block).push(...nodes);
|
|
332
291
|
}
|
|
333
|
-
|
|
334
292
|
function clone(object) {
|
|
335
293
|
if (typeof object === "object" && object) {
|
|
336
294
|
if (Array.isArray(object)) {
|
|
@@ -349,9 +307,9 @@ function clone(object) {
|
|
|
349
307
|
return newObject;
|
|
350
308
|
}
|
|
351
309
|
}
|
|
352
|
-
|
|
353
310
|
return object;
|
|
354
311
|
}
|
|
312
|
+
|
|
355
313
|
/**
|
|
356
314
|
* | Return Value | Description |
|
|
357
315
|
* | --- | --- |
|
|
@@ -365,16 +323,12 @@ function clone(object) {
|
|
|
365
323
|
* @param p
|
|
366
324
|
* @returns
|
|
367
325
|
*/
|
|
368
|
-
|
|
369
|
-
|
|
370
326
|
function isForInitialize(o, p) {
|
|
371
327
|
(0, _identifiers.validateChain)(o, p);
|
|
372
328
|
var forIndex = p.findIndex(x => x.type == "ForStatement" || x.type == "ForInStatement" || x.type == "ForOfStatement");
|
|
373
|
-
|
|
374
329
|
if (p.slice(0, forIndex).find(x => ["ArrowFunctionExpression", "BlockStatement"].includes(x.type))) {
|
|
375
330
|
return false;
|
|
376
331
|
}
|
|
377
|
-
|
|
378
332
|
if (forIndex !== -1) {
|
|
379
333
|
if (p[forIndex].type == "ForStatement") {
|
|
380
334
|
if (p[forIndex].init == (p[forIndex - 1] || o)) {
|
|
@@ -386,20 +340,17 @@ function isForInitialize(o, p) {
|
|
|
386
340
|
}
|
|
387
341
|
}
|
|
388
342
|
}
|
|
389
|
-
|
|
390
343
|
return false;
|
|
391
344
|
}
|
|
345
|
+
|
|
392
346
|
/**
|
|
393
347
|
* Computes the `function.length` property given the parameter nodes.
|
|
394
348
|
*
|
|
395
349
|
* @param params
|
|
396
350
|
* @returns
|
|
397
351
|
*/
|
|
398
|
-
|
|
399
|
-
|
|
400
352
|
function computeFunctionLength(params) {
|
|
401
353
|
var count = 0;
|
|
402
|
-
|
|
403
354
|
for (var parameterNode of params) {
|
|
404
355
|
if (parameterNode.type === "Identifier" || parameterNode.type === "ObjectPattern" || parameterNode.type === "ArrayPattern") {
|
|
405
356
|
count++;
|
|
@@ -407,6 +358,5 @@ function computeFunctionLength(params) {
|
|
|
407
358
|
break;
|
|
408
359
|
}
|
|
409
360
|
}
|
|
410
|
-
|
|
411
361
|
return count;
|
|
412
362
|
}
|
package/dist/util/math.js
CHANGED
|
@@ -4,19 +4,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getFactors = getFactors;
|
|
7
|
-
|
|
8
7
|
function getFactors(num) {
|
|
9
8
|
const isEven = num % 2 === 0;
|
|
10
9
|
const max = Math.sqrt(num);
|
|
11
10
|
const inc = isEven ? 1 : 2;
|
|
12
11
|
let factors = [1, num];
|
|
13
|
-
|
|
14
12
|
for (let curFactor = isEven ? 2 : 3; curFactor <= max; curFactor += inc) {
|
|
15
13
|
if (num % curFactor !== 0) continue;
|
|
16
14
|
factors.push(curFactor);
|
|
17
15
|
let compliment = num / curFactor;
|
|
18
16
|
if (compliment !== curFactor) factors.push(compliment);
|
|
19
17
|
}
|
|
20
|
-
|
|
21
18
|
return factors;
|
|
22
19
|
}
|
package/dist/util/object.js
CHANGED
|
@@ -5,33 +5,29 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.createObject = createObject;
|
|
7
7
|
exports.remove$Properties = remove$Properties;
|
|
8
|
-
|
|
9
8
|
function createObject(keys, values) {
|
|
10
9
|
if (keys.length != values.length) {
|
|
11
10
|
throw new Error("length mismatch");
|
|
12
11
|
}
|
|
13
|
-
|
|
14
12
|
var newObject = {};
|
|
15
13
|
keys.forEach((x, i) => {
|
|
16
14
|
newObject[x] = values[i];
|
|
17
15
|
});
|
|
18
16
|
return newObject;
|
|
19
17
|
}
|
|
18
|
+
|
|
20
19
|
/**
|
|
21
20
|
* Removes all `$`-prefixed properties on a deeply nested object.
|
|
22
21
|
*
|
|
23
22
|
* - Modifies the object.
|
|
24
23
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
24
|
function remove$Properties(object) {
|
|
28
25
|
let seen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
|
|
29
|
-
|
|
30
26
|
if (typeof object === "object" && object) {
|
|
31
|
-
if (seen.has(object)) {
|
|
27
|
+
if (seen.has(object)) {
|
|
28
|
+
// console.log(object);
|
|
32
29
|
// throw new Error("Already seen");
|
|
33
30
|
}
|
|
34
|
-
|
|
35
31
|
seen.add(object);
|
|
36
32
|
Object.keys(object).forEach(key => {
|
|
37
33
|
if (key.charAt(0) == "$") {
|
package/dist/util/random.js
CHANGED
|
@@ -13,11 +13,8 @@ exports.getRandomString = getRandomString;
|
|
|
13
13
|
exports.getRandomTrueExpression = getRandomTrueExpression;
|
|
14
14
|
exports.shuffle = shuffle;
|
|
15
15
|
exports.splitIntoChunks = splitIntoChunks;
|
|
16
|
-
|
|
17
16
|
var _assert = require("assert");
|
|
18
|
-
|
|
19
17
|
var _gen = require("./gen");
|
|
20
|
-
|
|
21
18
|
/**
|
|
22
19
|
* Returns a random element from the given array
|
|
23
20
|
* @param choices Array of items
|
|
@@ -27,135 +24,107 @@ function choice(choices) {
|
|
|
27
24
|
var index = Math.floor(Math.random() * choices.length);
|
|
28
25
|
return choices[index];
|
|
29
26
|
}
|
|
27
|
+
|
|
30
28
|
/**
|
|
31
29
|
* Returns a true/false based on the percent chance (0%-100%)
|
|
32
30
|
* @param percentChance AS A PERCENTAGE 0 - 100%
|
|
33
31
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
32
|
function chance(percentChance) {
|
|
37
33
|
return Math.random() < percentChance / 100;
|
|
38
34
|
}
|
|
35
|
+
|
|
39
36
|
/**
|
|
40
37
|
* **Mutates the given array**
|
|
41
38
|
* @param array
|
|
42
39
|
*/
|
|
43
|
-
|
|
44
|
-
|
|
45
40
|
function shuffle(array) {
|
|
46
41
|
array.sort(() => Math.random() - 0.5);
|
|
47
42
|
return array;
|
|
48
43
|
}
|
|
44
|
+
|
|
49
45
|
/**
|
|
50
46
|
* Returns a random string.
|
|
51
47
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
48
|
function getRandomString(length) {
|
|
55
49
|
var result = "";
|
|
56
50
|
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
57
51
|
var charactersLength = characters.length;
|
|
58
|
-
|
|
59
52
|
for (var i = 0; i < length; i++) {
|
|
60
53
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
61
54
|
}
|
|
62
|
-
|
|
63
55
|
return result;
|
|
64
56
|
}
|
|
65
|
-
|
|
66
57
|
function getRandom(min, max) {
|
|
67
58
|
return Math.random() * (max - min) + min;
|
|
68
59
|
}
|
|
69
|
-
|
|
70
60
|
function getRandomInteger(min, max) {
|
|
71
61
|
return Math.floor(getRandom(min, max));
|
|
72
62
|
}
|
|
73
|
-
|
|
74
63
|
function splitIntoChunks(str, size) {
|
|
75
64
|
(0, _assert.ok)(typeof str === "string", "str must be typeof string");
|
|
76
65
|
(0, _assert.ok)(typeof size === "number", "size must be typeof number");
|
|
77
66
|
(0, _assert.ok)(Math.floor(size) === size, "size must be integer");
|
|
78
67
|
const numChunks = Math.ceil(str.length / size);
|
|
79
68
|
const chunks = new Array(numChunks);
|
|
80
|
-
|
|
81
69
|
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
|
|
82
70
|
chunks[i] = str.substr(o, size);
|
|
83
71
|
}
|
|
84
|
-
|
|
85
72
|
return chunks;
|
|
86
73
|
}
|
|
74
|
+
|
|
87
75
|
/**
|
|
88
76
|
* Returns a random expression that will test to `false`.
|
|
89
77
|
*/
|
|
90
|
-
|
|
91
|
-
|
|
92
78
|
function getRandomFalseExpression() {
|
|
93
79
|
var type = choice(["0", "false", "null", "undefined", "NaN", "emptyString"]);
|
|
94
|
-
|
|
95
80
|
switch (type) {
|
|
96
81
|
case "0":
|
|
97
82
|
return (0, _gen.Literal)(0);
|
|
98
|
-
|
|
99
83
|
case "false":
|
|
100
84
|
return (0, _gen.Literal)(false);
|
|
101
|
-
|
|
102
85
|
case "null":
|
|
103
86
|
return (0, _gen.Identifier)("null");
|
|
104
|
-
|
|
105
87
|
case "undefined":
|
|
106
88
|
return (0, _gen.Identifier)("undefined");
|
|
107
|
-
|
|
108
89
|
case "NaN":
|
|
109
90
|
return (0, _gen.Identifier)("NaN");
|
|
110
|
-
|
|
111
91
|
default:
|
|
112
92
|
// case "emptyString":
|
|
113
93
|
return (0, _gen.Literal)("");
|
|
114
94
|
}
|
|
115
95
|
}
|
|
96
|
+
|
|
116
97
|
/**
|
|
117
98
|
* Returns a random expression that will test to `true`
|
|
118
99
|
*/
|
|
119
|
-
|
|
120
|
-
|
|
121
100
|
function getRandomTrueExpression() {
|
|
122
101
|
var type = choice(["number", "true", "Infinity", "nonEmptyString", "array", "object"]);
|
|
123
|
-
|
|
124
102
|
switch (type) {
|
|
125
103
|
case "number":
|
|
126
104
|
return (0, _gen.Literal)(getRandomInteger(1, 100));
|
|
127
|
-
|
|
128
105
|
case "true":
|
|
129
106
|
return (0, _gen.Identifier)("true");
|
|
130
|
-
|
|
131
107
|
case "Infinity":
|
|
132
108
|
return (0, _gen.Identifier)("Infinity");
|
|
133
|
-
|
|
134
109
|
case "nonEmptyString":
|
|
135
110
|
return (0, _gen.Literal)(getRandomString(getRandomInteger(3, 9)));
|
|
136
|
-
|
|
137
111
|
case "array":
|
|
138
112
|
return (0, _gen.ArrayExpression)([]);
|
|
139
|
-
|
|
140
113
|
default:
|
|
141
114
|
//case "object":
|
|
142
115
|
return (0, _gen.ObjectExpression)([]);
|
|
143
116
|
}
|
|
144
117
|
}
|
|
145
|
-
|
|
146
118
|
function alphabeticalGenerator(index) {
|
|
147
119
|
let name = "";
|
|
148
|
-
|
|
149
120
|
while (index > 0) {
|
|
150
121
|
var t = (index - 1) % 52;
|
|
151
122
|
var thisChar = t >= 26 ? String.fromCharCode(65 + t - 26) : String.fromCharCode(97 + t);
|
|
152
123
|
name = thisChar + name;
|
|
153
124
|
index = (index - t) / 52 | 0;
|
|
154
125
|
}
|
|
155
|
-
|
|
156
126
|
if (!name) {
|
|
157
127
|
name = "_";
|
|
158
128
|
}
|
|
159
|
-
|
|
160
129
|
return name;
|
|
161
130
|
}
|
package/dist/util/scope.js
CHANGED
|
@@ -4,14 +4,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getLexicalScope = getLexicalScope;
|
|
7
|
+
exports.getLexicalScopeBody = getLexicalScopeBody;
|
|
7
8
|
exports.isLexicalScope = isLexicalScope;
|
|
8
|
-
|
|
9
|
+
var _assert = require("assert");
|
|
9
10
|
var _traverse = require("../traverse");
|
|
10
|
-
|
|
11
11
|
function isLexicalScope(object) {
|
|
12
12
|
return (0, _traverse.isBlock)(object) || object.type == "SwitchCase";
|
|
13
13
|
}
|
|
14
|
-
|
|
15
14
|
function getLexicalScope(object, parents) {
|
|
16
15
|
return [object, ...parents].find(node => isLexicalScope(node));
|
|
16
|
+
}
|
|
17
|
+
function getLexicalScopeBody(object) {
|
|
18
|
+
(0, _assert.ok)(isLexicalScope(object));
|
|
19
|
+
return (0, _traverse.isBlock)(object) ? object.body : object.type === "SwitchCase" ? object.consequent : (0, _assert.ok)("Unhandled case");
|
|
17
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js-confuser",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "JavaScript Obfuscation Tool.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"author": "MichaelXF",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"acorn": "^8.
|
|
26
|
-
"escodegen": "^2.
|
|
25
|
+
"acorn": "^8.12.1",
|
|
26
|
+
"escodegen": "^2.1.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@babel/cli": "^7.17.6",
|
package/src/constants.ts
CHANGED
|
@@ -82,3 +82,15 @@ export const reservedIdentifiers = new Set([
|
|
|
82
82
|
|
|
83
83
|
export const noRenameVariablePrefix = "__NO_JS_CONFUSER_RENAME__";
|
|
84
84
|
export const placeholderVariablePrefix = "__p_";
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Tells the obfuscator this function is predictable:
|
|
88
|
+
* - Never called with extraneous parameters
|
|
89
|
+
*/
|
|
90
|
+
export const predictableFunctionTag = "__JS_PREDICT__";
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Tells the obfuscator this function is critical for the Obfuscated code.
|
|
94
|
+
* - Example: string decryption function
|
|
95
|
+
*/
|
|
96
|
+
export const criticalFunctionTag = "__JS_CRITICAL__";
|
package/src/options.ts
CHANGED
|
@@ -585,6 +585,15 @@ export interface ObfuscateOptions {
|
|
|
585
585
|
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
|
|
586
586
|
*/
|
|
587
587
|
debugComments?: boolean;
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* ### `preserveFunctionLength`
|
|
591
|
+
*
|
|
592
|
+
* Modified functions will retain the correct `function.length` property. Enabled by default. (`true/false`)
|
|
593
|
+
*
|
|
594
|
+
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
|
|
595
|
+
*/
|
|
596
|
+
preserveFunctionLength?: boolean;
|
|
588
597
|
}
|
|
589
598
|
|
|
590
599
|
const validProperties = new Set([
|
|
@@ -619,6 +628,7 @@ const validProperties = new Set([
|
|
|
619
628
|
"verbose",
|
|
620
629
|
"globalVariables",
|
|
621
630
|
"debugComments",
|
|
631
|
+
"preserveFunctionLength",
|
|
622
632
|
]);
|
|
623
633
|
|
|
624
634
|
const validOses = new Set(["windows", "linux", "osx", "ios", "android"]);
|
|
@@ -764,6 +774,9 @@ export async function correctOptions(
|
|
|
764
774
|
if (!options.hasOwnProperty("renameGlobals")) {
|
|
765
775
|
options.renameGlobals = true; // RenameGlobals is on by default
|
|
766
776
|
}
|
|
777
|
+
if (!options.hasOwnProperty("preserveFunctionLength")) {
|
|
778
|
+
options.preserveFunctionLength = true; // preserveFunctionLength is on by default
|
|
779
|
+
}
|
|
767
780
|
|
|
768
781
|
if (options.globalVariables && !(options.globalVariables instanceof Set)) {
|
|
769
782
|
options.globalVariables = new Set(Object.keys(options.globalVariables));
|