js-confuser 1.5.8 → 1.5.9
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 +37 -0
- package/dist/index.js +45 -4
- package/dist/obfuscator.js +10 -5
- package/dist/options.js +2 -3
- package/dist/order.js +3 -3
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -2
- package/dist/transforms/dispatcher.js +3 -3
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +1 -1
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +4 -4
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/flatten.js +73 -50
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/movedDeclarations.js +1 -1
- package/dist/transforms/minify.js +22 -6
- package/dist/transforms/rgf.js +4 -4
- package/dist/transforms/stack.js +1 -1
- package/dist/transforms/string/stringConcealing.js +2 -2
- package/dist/traverse.js +0 -8
- package/dist/util/compare.js +2 -2
- package/dist/util/insert.js +20 -6
- package/package.json +1 -1
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +6 -1
- package/src/options.ts +10 -2
- package/src/order.ts +3 -3
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +14 -2
- package/src/transforms/dispatcher.ts +4 -3
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +1 -1
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +5 -5
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/flatten.ts +181 -128
- package/src/transforms/hexadecimalNumbers.ts +37 -9
- package/src/transforms/identifier/movedDeclarations.ts +1 -1
- package/src/transforms/minify.ts +37 -5
- package/src/transforms/rgf.ts +4 -3
- package/src/transforms/stack.ts +3 -1
- package/src/transforms/string/stringConcealing.ts +2 -2
- package/src/traverse.ts +1 -8
- package/src/types.ts +9 -1
- package/src/util/compare.ts +2 -2
- package/src/util/insert.ts +37 -8
- package/test/code/ES6.src.js +14 -0
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +13 -1
- package/test/transforms/antiTooling.test.ts +30 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +22 -0
- package/test/transforms/dispatcher.test.ts +24 -0
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +146 -3
- package/test/transforms/identifier/renameVariables.test.ts +26 -0
- package/test/transforms/minify.test.ts +66 -0
- package/test/transforms/rgf.test.ts +56 -0
- package/test/transforms/string/stringConcealing.test.ts +33 -0
- package/test/util/compare.test.ts +23 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ok } from "assert";
|
|
1
2
|
import { reservedIdentifiers } from "../constants";
|
|
2
3
|
import { ObfuscateOrder } from "../order";
|
|
3
4
|
import traverse, { walk } from "../traverse";
|
|
@@ -24,6 +25,8 @@ import {
|
|
|
24
25
|
IfStatement,
|
|
25
26
|
ThrowStatement,
|
|
26
27
|
NewExpression,
|
|
28
|
+
AwaitExpression,
|
|
29
|
+
UnaryExpression,
|
|
27
30
|
} from "../util/gen";
|
|
28
31
|
import { getIdentifierInfo } from "../util/identifiers";
|
|
29
32
|
import {
|
|
@@ -46,20 +49,19 @@ import Transform from "./transform";
|
|
|
46
49
|
* return [ref1, ref2, refN, returnValue];
|
|
47
50
|
* }
|
|
48
51
|
* ```
|
|
52
|
+
*
|
|
53
|
+
* Flatten is used to make functions eligible for the RGF transformation.
|
|
49
54
|
*/
|
|
50
55
|
export default class Flatten extends Transform {
|
|
51
56
|
definedNames: Map<Node, Set<string>>;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
flatNode: Node;
|
|
55
|
-
gen: any;
|
|
57
|
+
flattenedFns: Node[];
|
|
58
|
+
gen: ReturnType<Transform["getGenerator"]>;
|
|
56
59
|
|
|
57
60
|
constructor(o) {
|
|
58
61
|
super(o, ObfuscateOrder.Flatten);
|
|
59
62
|
|
|
60
63
|
this.definedNames = new Map();
|
|
61
|
-
this.
|
|
62
|
-
this.flatNode = null;
|
|
64
|
+
this.flattenedFns = [];
|
|
63
65
|
this.gen = this.getGenerator();
|
|
64
66
|
}
|
|
65
67
|
|
|
@@ -87,33 +89,64 @@ export default class Flatten extends Transform {
|
|
|
87
89
|
});
|
|
88
90
|
|
|
89
91
|
super.apply(tree);
|
|
92
|
+
|
|
93
|
+
if (this.flattenedFns.length) {
|
|
94
|
+
prepend(tree, VariableDeclaration(this.flattenedFns));
|
|
95
|
+
}
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
match(object: Node, parents: Node[]) {
|
|
93
99
|
return (
|
|
94
|
-
object.type == "FunctionDeclaration"
|
|
100
|
+
(object.type == "FunctionDeclaration" ||
|
|
101
|
+
object.type === "FunctionExpression") &&
|
|
95
102
|
object.body.type == "BlockStatement" &&
|
|
96
103
|
!object.generator &&
|
|
97
|
-
!object.async &&
|
|
98
104
|
!object.params.find((x) => x.type !== "Identifier")
|
|
99
105
|
);
|
|
100
106
|
}
|
|
101
107
|
|
|
102
108
|
transform(object: Node, parents: Node[]) {
|
|
103
109
|
return () => {
|
|
104
|
-
|
|
110
|
+
if (parents[0]) {
|
|
111
|
+
// Don't change class methods
|
|
112
|
+
if (
|
|
113
|
+
parents[0].type === "MethodDefinition" &&
|
|
114
|
+
parents[0].value === object
|
|
115
|
+
) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
105
118
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return;
|
|
119
|
+
// Don't change getter/setter methods
|
|
120
|
+
if (
|
|
121
|
+
parents[0].type === "Property" &&
|
|
122
|
+
parents[0].value === object &&
|
|
123
|
+
parents[0].kind !== "init"
|
|
124
|
+
) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
115
127
|
}
|
|
116
128
|
|
|
129
|
+
ok(
|
|
130
|
+
object.type === "FunctionDeclaration" ||
|
|
131
|
+
object.type === "FunctionExpression"
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// The name is purely for debugging purposes
|
|
135
|
+
var currentFnName =
|
|
136
|
+
object.type === "FunctionDeclaration"
|
|
137
|
+
? object.id?.name
|
|
138
|
+
: parents[0]?.type === "VariableDeclarator" &&
|
|
139
|
+
parents[0].id?.type === "Identifier" &&
|
|
140
|
+
parents[0].id?.name;
|
|
141
|
+
|
|
142
|
+
if (parents[0]?.type === "Property" && parents[0]?.key) {
|
|
143
|
+
currentFnName =
|
|
144
|
+
currentFnName ||
|
|
145
|
+
String(parents[0]?.key?.name || parents[0]?.key?.value);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!currentFnName) currentFnName = "unnamed";
|
|
149
|
+
|
|
117
150
|
var defined = new Set<string>();
|
|
118
151
|
var references = new Set<string>();
|
|
119
152
|
var modified = new Set<string>();
|
|
@@ -147,9 +180,7 @@ export default class Flatten extends Transform {
|
|
|
147
180
|
|
|
148
181
|
if (o.hidden) {
|
|
149
182
|
illegal.add(o.name);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (info.spec.isDefined) {
|
|
183
|
+
} else if (info.spec.isDefined) {
|
|
153
184
|
defined.add(o.name);
|
|
154
185
|
} else if (info.spec.isModified) {
|
|
155
186
|
modified.add(o.name);
|
|
@@ -198,9 +229,6 @@ export default class Flatten extends Transform {
|
|
|
198
229
|
return;
|
|
199
230
|
}
|
|
200
231
|
|
|
201
|
-
illegal.forEach((name) => {
|
|
202
|
-
defined.delete(name);
|
|
203
|
-
});
|
|
204
232
|
defined.forEach((name) => {
|
|
205
233
|
references.delete(name);
|
|
206
234
|
modified.delete(name);
|
|
@@ -216,16 +244,35 @@ export default class Flatten extends Transform {
|
|
|
216
244
|
|
|
217
245
|
var output = Array.from(modified);
|
|
218
246
|
|
|
219
|
-
var newName = this.
|
|
220
|
-
var valName = this.getPlaceholder();
|
|
247
|
+
var newName = this.getPlaceholder() + "_flat_" + currentFnName;
|
|
221
248
|
var resultName = this.getPlaceholder();
|
|
222
249
|
var propName = this.gen.generate();
|
|
223
250
|
|
|
251
|
+
var newOutputNames: { [originalName: string]: string } =
|
|
252
|
+
Object.create(null);
|
|
253
|
+
output.forEach((name) => {
|
|
254
|
+
newOutputNames[name] = this.gen.generate();
|
|
255
|
+
});
|
|
256
|
+
var returnOutputName = this.gen.generate();
|
|
257
|
+
|
|
224
258
|
getBlockBody(object.body).push(ReturnStatement());
|
|
225
259
|
walk(object.body, [object, ...parents], (o, p) => {
|
|
226
260
|
return () => {
|
|
261
|
+
// Change return statements from
|
|
262
|
+
// return (argument)
|
|
263
|
+
// to
|
|
264
|
+
// return [ [modifiedRefs], ]
|
|
227
265
|
if (o.type == "ReturnStatement" && getVarContext(o, p) === object) {
|
|
228
|
-
var
|
|
266
|
+
var returnObject = ObjectExpression(
|
|
267
|
+
output.map((outputName) =>
|
|
268
|
+
Property(
|
|
269
|
+
Literal(newOutputNames[outputName]),
|
|
270
|
+
Identifier(outputName),
|
|
271
|
+
true
|
|
272
|
+
)
|
|
273
|
+
)
|
|
274
|
+
);
|
|
275
|
+
|
|
229
276
|
if (
|
|
230
277
|
o.argument &&
|
|
231
278
|
!(
|
|
@@ -233,11 +280,11 @@ export default class Flatten extends Transform {
|
|
|
233
280
|
o.argument.name == "undefined"
|
|
234
281
|
)
|
|
235
282
|
) {
|
|
236
|
-
|
|
283
|
+
returnObject.properties.push(
|
|
284
|
+
Property(Literal(returnOutputName), clone(o.argument), true)
|
|
285
|
+
);
|
|
237
286
|
}
|
|
238
287
|
|
|
239
|
-
o.argument = ArrayExpression(elements);
|
|
240
|
-
|
|
241
288
|
o.argument = AssignmentExpression(
|
|
242
289
|
"=",
|
|
243
290
|
MemberExpression(
|
|
@@ -245,7 +292,7 @@ export default class Flatten extends Transform {
|
|
|
245
292
|
Identifier(propName),
|
|
246
293
|
false
|
|
247
294
|
),
|
|
248
|
-
|
|
295
|
+
returnObject
|
|
249
296
|
);
|
|
250
297
|
}
|
|
251
298
|
};
|
|
@@ -253,35 +300,12 @@ export default class Flatten extends Transform {
|
|
|
253
300
|
|
|
254
301
|
var newBody = getBlockBody(object.body);
|
|
255
302
|
|
|
256
|
-
newBody.unshift(
|
|
257
|
-
VariableDeclaration(
|
|
258
|
-
VariableDeclarator(
|
|
259
|
-
ArrayPattern([
|
|
260
|
-
ArrayPattern(input.map(Identifier)),
|
|
261
|
-
ArrayPattern(clone(object.params)),
|
|
262
|
-
Identifier(resultName),
|
|
263
|
-
]),
|
|
264
|
-
|
|
265
|
-
Identifier(valName)
|
|
266
|
-
)
|
|
267
|
-
)
|
|
268
|
-
);
|
|
269
|
-
|
|
270
|
-
if (!this.flatMapName) {
|
|
271
|
-
this.flatMapName = this.getPlaceholder();
|
|
272
|
-
prepend(
|
|
273
|
-
parents[parents.length - 1],
|
|
274
|
-
VariableDeclaration(
|
|
275
|
-
VariableDeclarator(
|
|
276
|
-
this.flatMapName,
|
|
277
|
-
(this.flatNode = ObjectExpression([]))
|
|
278
|
-
)
|
|
279
|
-
)
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
303
|
var newFunctionExpression = FunctionExpression(
|
|
284
|
-
[
|
|
304
|
+
[
|
|
305
|
+
ArrayPattern(input.map(Identifier)),
|
|
306
|
+
ArrayPattern(clone(object.params)),
|
|
307
|
+
Identifier(resultName),
|
|
308
|
+
],
|
|
285
309
|
newBody
|
|
286
310
|
);
|
|
287
311
|
|
|
@@ -295,134 +319,163 @@ export default class Flatten extends Transform {
|
|
|
295
319
|
);
|
|
296
320
|
property.kind = "set";
|
|
297
321
|
|
|
298
|
-
this.
|
|
299
|
-
|
|
300
|
-
var identifier = MemberExpression(
|
|
301
|
-
Identifier(this.flatMapName),
|
|
302
|
-
Identifier(newName),
|
|
303
|
-
false
|
|
322
|
+
this.flattenedFns.push(
|
|
323
|
+
VariableDeclarator(newName, newFunctionExpression)
|
|
304
324
|
);
|
|
305
325
|
|
|
306
326
|
var newParamNodes = object.params.map(() =>
|
|
307
327
|
Identifier(this.getPlaceholder())
|
|
308
328
|
);
|
|
309
329
|
|
|
310
|
-
// var result = newFn.call([...refs], ...arguments)
|
|
311
|
-
var call = VariableDeclaration([
|
|
312
|
-
VariableDeclarator(resultName, ArrayExpression([])),
|
|
313
|
-
VariableDeclarator(
|
|
314
|
-
"_",
|
|
315
|
-
AssignmentExpression(
|
|
316
|
-
"=",
|
|
317
|
-
identifier,
|
|
318
|
-
ArrayExpression([
|
|
319
|
-
ArrayExpression(input.map(Identifier)),
|
|
320
|
-
ArrayExpression([...newParamNodes]),
|
|
321
|
-
Identifier(resultName),
|
|
322
|
-
])
|
|
323
|
-
)
|
|
324
|
-
),
|
|
325
|
-
]);
|
|
326
|
-
|
|
327
330
|
// result.pop()
|
|
328
|
-
var
|
|
331
|
+
var getOutputMemberExpression = (outputName) =>
|
|
329
332
|
MemberExpression(
|
|
330
|
-
MemberExpression(Identifier(resultName),
|
|
331
|
-
Literal(
|
|
333
|
+
MemberExpression(Identifier(resultName), Literal(propName), true),
|
|
334
|
+
Literal(outputName),
|
|
332
335
|
true
|
|
333
|
-
)
|
|
334
|
-
[]
|
|
335
|
-
);
|
|
336
|
+
);
|
|
336
337
|
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
338
|
+
// newFn.call([...refs], ...arguments, resultObject)
|
|
339
|
+
var callExpression = CallExpression(Identifier(newName), [
|
|
340
|
+
ArrayExpression(input.map(Identifier)),
|
|
341
|
+
ArrayExpression([...newParamNodes]),
|
|
342
|
+
Identifier(resultName),
|
|
343
|
+
]);
|
|
344
|
+
|
|
345
|
+
var newObjectBody: Node[] = [
|
|
346
|
+
// var resultObject = {};
|
|
347
|
+
VariableDeclaration([
|
|
348
|
+
VariableDeclarator(resultName, ObjectExpression([])),
|
|
349
|
+
]),
|
|
350
|
+
|
|
351
|
+
ExpressionStatement(
|
|
352
|
+
newFunctionExpression.async
|
|
353
|
+
? AwaitExpression(callExpression)
|
|
354
|
+
: callExpression
|
|
355
|
+
),
|
|
356
|
+
];
|
|
343
357
|
|
|
344
|
-
var newObjectBody: Node[] = [call];
|
|
345
358
|
var outputReversed = [...output].reverse();
|
|
346
359
|
|
|
360
|
+
// realVar
|
|
361
|
+
outputReversed.forEach((outputName) => {
|
|
362
|
+
newObjectBody.push(
|
|
363
|
+
ExpressionStatement(
|
|
364
|
+
AssignmentExpression(
|
|
365
|
+
"=",
|
|
366
|
+
Identifier(outputName),
|
|
367
|
+
getOutputMemberExpression(newOutputNames[outputName])
|
|
368
|
+
)
|
|
369
|
+
)
|
|
370
|
+
);
|
|
371
|
+
});
|
|
372
|
+
|
|
347
373
|
// DECOY STATEMENTS
|
|
348
374
|
var decoyKey = this.gen.generate();
|
|
349
375
|
var decoyNodes = [
|
|
376
|
+
// if (result.random) throw result.prop.random
|
|
350
377
|
IfStatement(
|
|
351
378
|
MemberExpression(
|
|
352
379
|
Identifier(resultName),
|
|
353
|
-
|
|
354
|
-
|
|
380
|
+
Literal(this.gen.generate()),
|
|
381
|
+
true
|
|
355
382
|
),
|
|
356
383
|
[
|
|
357
384
|
ThrowStatement(
|
|
358
385
|
NewExpression(Identifier("Error"), [
|
|
359
|
-
|
|
386
|
+
getOutputMemberExpression(this.gen.generate()),
|
|
360
387
|
])
|
|
361
388
|
),
|
|
362
389
|
]
|
|
363
390
|
),
|
|
391
|
+
// if (result.random) return true;
|
|
364
392
|
IfStatement(
|
|
365
393
|
MemberExpression(
|
|
366
394
|
Identifier(resultName),
|
|
367
|
-
|
|
368
|
-
|
|
395
|
+
Literal(this.gen.generate()),
|
|
396
|
+
true
|
|
369
397
|
),
|
|
370
|
-
[ReturnStatement(
|
|
398
|
+
[ReturnStatement(Literal(true))]
|
|
371
399
|
),
|
|
400
|
+
// if (result.random) return result;
|
|
372
401
|
IfStatement(
|
|
373
402
|
MemberExpression(
|
|
374
403
|
Identifier(resultName),
|
|
375
|
-
|
|
376
|
-
|
|
404
|
+
Literal(this.gen.generate()),
|
|
405
|
+
true
|
|
377
406
|
),
|
|
378
407
|
[ReturnStatement(Identifier(resultName))]
|
|
379
408
|
),
|
|
409
|
+
// if (result.random) return result.random;
|
|
380
410
|
IfStatement(
|
|
381
|
-
MemberExpression(Identifier(resultName),
|
|
411
|
+
MemberExpression(Identifier(resultName), Literal(decoyKey), true),
|
|
382
412
|
[
|
|
383
413
|
ReturnStatement(
|
|
384
|
-
MemberExpression(
|
|
385
|
-
Identifier(resultName),
|
|
386
|
-
Identifier(decoyKey),
|
|
387
|
-
false
|
|
388
|
-
)
|
|
414
|
+
MemberExpression(Identifier(resultName), Literal(decoyKey), true)
|
|
389
415
|
),
|
|
390
416
|
]
|
|
391
417
|
),
|
|
418
|
+
// if(result.random1) return result.random2;
|
|
392
419
|
IfStatement(
|
|
393
420
|
MemberExpression(
|
|
394
421
|
Identifier(resultName),
|
|
395
|
-
|
|
396
|
-
|
|
422
|
+
Literal(this.gen.generate()),
|
|
423
|
+
true
|
|
397
424
|
),
|
|
398
425
|
[
|
|
399
426
|
ReturnStatement(
|
|
400
427
|
MemberExpression(
|
|
401
428
|
Identifier(resultName),
|
|
402
|
-
|
|
403
|
-
|
|
429
|
+
Literal(this.gen.generate()),
|
|
430
|
+
true
|
|
404
431
|
)
|
|
405
432
|
),
|
|
406
433
|
]
|
|
407
434
|
),
|
|
408
|
-
|
|
435
|
+
// if(result.random) return flatFn;
|
|
436
|
+
IfStatement(
|
|
437
|
+
MemberExpression(
|
|
438
|
+
Identifier(resultName),
|
|
439
|
+
Literal(this.gen.generate()),
|
|
440
|
+
true
|
|
441
|
+
),
|
|
442
|
+
[ReturnStatement(Identifier(newName))]
|
|
443
|
+
),
|
|
444
|
+
// if(result.random) flatFn = undefined;
|
|
445
|
+
IfStatement(
|
|
446
|
+
MemberExpression(
|
|
447
|
+
Identifier(resultName),
|
|
448
|
+
Literal(this.gen.generate()),
|
|
449
|
+
true
|
|
450
|
+
),
|
|
451
|
+
[
|
|
452
|
+
ExpressionStatement(
|
|
453
|
+
AssignmentExpression(
|
|
454
|
+
"=",
|
|
455
|
+
Identifier(newName),
|
|
456
|
+
Identifier("undefined")
|
|
457
|
+
)
|
|
458
|
+
),
|
|
459
|
+
]
|
|
460
|
+
),
|
|
461
|
+
// if(!result) return;
|
|
462
|
+
IfStatement(UnaryExpression("!", Identifier(resultName)), [
|
|
463
|
+
ReturnStatement(),
|
|
464
|
+
]),
|
|
465
|
+
].filter(() => Math.random() > 0.25);
|
|
466
|
+
|
|
467
|
+
// if (result.output) return result.output.returnValue;
|
|
468
|
+
// this is the real return statement, it is always added
|
|
469
|
+
decoyNodes.push(
|
|
470
|
+
IfStatement(
|
|
471
|
+
MemberExpression(Identifier(resultName), Literal(propName), true),
|
|
472
|
+
[ReturnStatement(getOutputMemberExpression(returnOutputName))]
|
|
473
|
+
)
|
|
474
|
+
);
|
|
409
475
|
|
|
410
476
|
shuffle(decoyNodes);
|
|
411
|
-
decoyNodes.forEach((decoyNode) => {
|
|
412
|
-
if (Math.random() < 0.5) {
|
|
413
|
-
newObjectBody.push(decoyNode);
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
477
|
|
|
417
|
-
newObjectBody.push(
|
|
418
|
-
...outputReversed.map((name) => {
|
|
419
|
-
return ExpressionStatement(
|
|
420
|
-
AssignmentExpression("=", Identifier(name), clone(pop))
|
|
421
|
-
);
|
|
422
|
-
}),
|
|
423
|
-
|
|
424
|
-
ReturnStatement(clone(pop))
|
|
425
|
-
);
|
|
478
|
+
newObjectBody.push(...decoyNodes);
|
|
426
479
|
|
|
427
480
|
object.body = BlockStatement(newObjectBody);
|
|
428
481
|
|
|
@@ -3,12 +3,19 @@ import { ObfuscateOrder } from "../order";
|
|
|
3
3
|
import { ExitCallback } from "../traverse";
|
|
4
4
|
import { Identifier, Node } from "../util/gen";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* The HexadecimalNumbers transformation converts number literals into the hexadecimal form.
|
|
8
|
+
*
|
|
9
|
+
* This is done by replacing the number literal with an Identifier to ensure escodegen properly outputs it as such
|
|
10
|
+
*
|
|
11
|
+
* This transformation also handles BigInt support, so its always enabled for this reason.
|
|
12
|
+
*/
|
|
6
13
|
export default class HexadecimalNumbers extends Transform {
|
|
7
14
|
constructor(o) {
|
|
8
15
|
super(o, ObfuscateOrder.HexadecimalNumbers);
|
|
9
16
|
}
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
isNumberLiteral(object: Node) {
|
|
12
19
|
return (
|
|
13
20
|
object.type === "Literal" &&
|
|
14
21
|
typeof object.value === "number" &&
|
|
@@ -16,16 +23,37 @@ export default class HexadecimalNumbers extends Transform {
|
|
|
16
23
|
);
|
|
17
24
|
}
|
|
18
25
|
|
|
26
|
+
isBigIntLiteral(object: Node) {
|
|
27
|
+
return object.type === "Literal" && typeof object.value === "bigint";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
match(object: Node, parents: Node[]): boolean {
|
|
31
|
+
return (
|
|
32
|
+
(this.options.hexadecimalNumbers && this.isNumberLiteral(object)) ||
|
|
33
|
+
this.isBigIntLiteral(object)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
19
37
|
transform(object: Node, parents: Node[]): void | ExitCallback {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
38
|
+
if (this.isNumberLiteral(object)) {
|
|
39
|
+
return () => {
|
|
40
|
+
// Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
|
|
41
|
+
// This code handles it regardless
|
|
42
|
+
var isNegative = object.value < 0;
|
|
43
|
+
var hex = Math.abs(object.value).toString(16);
|
|
44
|
+
|
|
45
|
+
var newStr = (isNegative ? "-" : "") + "0x" + hex;
|
|
25
46
|
|
|
26
|
-
|
|
47
|
+
this.replace(object, Identifier(newStr));
|
|
48
|
+
};
|
|
49
|
+
}
|
|
27
50
|
|
|
28
|
-
|
|
29
|
-
|
|
51
|
+
// https://github.com/MichaelXF/js-confuser/issues/79
|
|
52
|
+
if (this.isBigIntLiteral(object)) {
|
|
53
|
+
return () => {
|
|
54
|
+
// Use an Identifier with the raw string
|
|
55
|
+
this.replace(object, Identifier(object.raw));
|
|
56
|
+
};
|
|
57
|
+
}
|
|
30
58
|
}
|
|
31
59
|
}
|
|
@@ -46,7 +46,7 @@ export default class MovedDeclarations extends Transform {
|
|
|
46
46
|
|
|
47
47
|
walk(object, parents, (o, p) => {
|
|
48
48
|
if (o.type == "Identifier") {
|
|
49
|
-
if (getLexicalScope(o, p) !== object) {
|
|
49
|
+
if (o.hidden || getLexicalScope(o, p) !== object) {
|
|
50
50
|
illegal.add(o.name);
|
|
51
51
|
} else {
|
|
52
52
|
var info = getIdentifierInfo(o, p);
|
package/src/transforms/minify.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
AssignmentExpression,
|
|
16
16
|
VariableDeclarator,
|
|
17
17
|
Identifier,
|
|
18
|
+
CallExpression,
|
|
18
19
|
} from "../util/gen";
|
|
19
20
|
import {
|
|
20
21
|
getBlockBody,
|
|
@@ -22,11 +23,14 @@ import {
|
|
|
22
23
|
isForInitialize,
|
|
23
24
|
isLexContext,
|
|
24
25
|
getFunction,
|
|
26
|
+
prepend,
|
|
27
|
+
append,
|
|
25
28
|
} from "../util/insert";
|
|
26
29
|
import { isValidIdentifier, isEquivalent } from "../util/compare";
|
|
27
30
|
import { walk, isBlock } from "../traverse";
|
|
28
31
|
import { ok } from "assert";
|
|
29
32
|
import { isLexicalScope } from "../util/scope";
|
|
33
|
+
import Template from "../templates/template";
|
|
30
34
|
|
|
31
35
|
/**
|
|
32
36
|
* Basic transformations to reduce code size.
|
|
@@ -37,12 +41,13 @@ import { isLexicalScope } from "../util/scope";
|
|
|
37
41
|
* - `x['y']` **->** `x.y`
|
|
38
42
|
*/
|
|
39
43
|
export default class Minify extends Transform {
|
|
40
|
-
|
|
44
|
+
/**
|
|
45
|
+
* A helper function that is introduced preserve function semantics
|
|
46
|
+
*/
|
|
47
|
+
arrowFunctionName: string;
|
|
41
48
|
|
|
42
49
|
constructor(o) {
|
|
43
50
|
super(o, ObfuscateOrder.Minify);
|
|
44
|
-
|
|
45
|
-
this.variables = new Map();
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
match(object: Node, parents: Node[]) {
|
|
@@ -239,17 +244,42 @@ export default class Minify extends Transform {
|
|
|
239
244
|
});
|
|
240
245
|
|
|
241
246
|
if (canTransform) {
|
|
247
|
+
if (!this.arrowFunctionName) {
|
|
248
|
+
this.arrowFunctionName = this.getPlaceholder();
|
|
249
|
+
|
|
250
|
+
append(
|
|
251
|
+
parents[parents.length - 1] || object,
|
|
252
|
+
Template(`
|
|
253
|
+
function ${this.arrowFunctionName}(arrowFn){
|
|
254
|
+
return function(){ return arrowFn(...arguments) }
|
|
255
|
+
}
|
|
256
|
+
`).single()
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const wrap = (object: Node) => {
|
|
261
|
+
return CallExpression(Identifier(this.arrowFunctionName), [
|
|
262
|
+
clone(object),
|
|
263
|
+
]);
|
|
264
|
+
};
|
|
265
|
+
|
|
242
266
|
if (object.type == "FunctionExpression") {
|
|
243
267
|
object.type = "ArrowFunctionExpression";
|
|
268
|
+
|
|
269
|
+
this.replace(object, wrap(clone(object)));
|
|
244
270
|
} else {
|
|
245
271
|
var arrow = { ...clone(object), type: "ArrowFunctionExpression" };
|
|
246
272
|
this.replace(
|
|
247
273
|
object,
|
|
248
|
-
VariableDeclaration(
|
|
274
|
+
VariableDeclaration(
|
|
275
|
+
VariableDeclarator(object.id.name, wrap(arrow))
|
|
276
|
+
)
|
|
249
277
|
);
|
|
250
278
|
|
|
251
279
|
var x = this.transform(arrow, []);
|
|
252
|
-
x
|
|
280
|
+
if (typeof x === "function") {
|
|
281
|
+
x();
|
|
282
|
+
}
|
|
253
283
|
}
|
|
254
284
|
}
|
|
255
285
|
};
|
|
@@ -442,6 +472,8 @@ export default class Minify extends Transform {
|
|
|
442
472
|
}
|
|
443
473
|
|
|
444
474
|
if (
|
|
475
|
+
object.consequent &&
|
|
476
|
+
object.consequent.body &&
|
|
445
477
|
object.consequent.body.length == 1 &&
|
|
446
478
|
object.alternate &&
|
|
447
479
|
object.alternate.body.length == 1
|
package/src/transforms/rgf.ts
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
isFunction,
|
|
32
32
|
prepend,
|
|
33
33
|
getDefiningContext,
|
|
34
|
+
clone,
|
|
34
35
|
} from "../util/insert";
|
|
35
36
|
import { getRandomString } from "../util/random";
|
|
36
37
|
import Transform from "./transform";
|
|
@@ -300,7 +301,8 @@ export default class RGF extends Transform {
|
|
|
300
301
|
[],
|
|
301
302
|
[
|
|
302
303
|
ReturnStatement(
|
|
303
|
-
|
|
304
|
+
// clone() is required!
|
|
305
|
+
CallExpression(clone(memberExpression), [
|
|
304
306
|
Identifier(referenceArray),
|
|
305
307
|
SpreadElement(Identifier("arguments")),
|
|
306
308
|
])
|
|
@@ -328,8 +330,6 @@ export default class RGF extends Transform {
|
|
|
328
330
|
|
|
329
331
|
queue.forEach(([object, parents]) => {
|
|
330
332
|
var name = object?.id?.name;
|
|
331
|
-
var hasName = !!name;
|
|
332
|
-
var params = object.params.map((x) => x.name) || [];
|
|
333
333
|
var signature = referenceSignatures[names.get(name)];
|
|
334
334
|
|
|
335
335
|
var embeddedName = name || this.getPlaceholder();
|
|
@@ -349,6 +349,7 @@ export default class RGF extends Transform {
|
|
|
349
349
|
},
|
|
350
350
|
eval: false,
|
|
351
351
|
hideInitializingCode: false,
|
|
352
|
+
stringEncoding: false,
|
|
352
353
|
});
|
|
353
354
|
var transforms = Object.values(obfuscator.transforms).filter(
|
|
354
355
|
(x) => x.priority > this.priority
|
package/src/transforms/stack.ts
CHANGED
|
@@ -55,7 +55,9 @@ export default class Stack extends Transform {
|
|
|
55
55
|
return () => {
|
|
56
56
|
// Uncaught SyntaxError: Getter must not have any formal parameters.
|
|
57
57
|
// Uncaught SyntaxError: Setter must have exactly one formal parameter
|
|
58
|
-
var propIndex = parents.findIndex(
|
|
58
|
+
var propIndex = parents.findIndex(
|
|
59
|
+
(x) => x.type === "Property" || x.type === "MethodDefinition"
|
|
60
|
+
);
|
|
59
61
|
if (propIndex !== -1) {
|
|
60
62
|
if (parents[propIndex].value === (parents[propIndex - 1] || object)) {
|
|
61
63
|
if (parents[propIndex].kind !== "init" || parents[propIndex].method) {
|