js-confuser 1.7.1 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +1 -1
- package/CHANGELOG.md +73 -0
- package/README.md +32 -31
- package/dist/compiler.js +2 -8
- package/dist/constants.js +22 -10
- package/dist/index.js +15 -30
- package/dist/obfuscator.js +15 -62
- package/dist/options.js +33 -40
- 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 +121 -5
- package/dist/templates/core.js +35 -0
- package/dist/templates/crash.js +22 -11
- 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 +189 -43
- package/dist/transforms/antiTooling.js +26 -22
- package/dist/transforms/calculator.js +19 -55
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +242 -333
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
- package/dist/transforms/deadCode.js +542 -31
- package/dist/transforms/dispatcher.js +112 -112
- 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 +21 -26
- package/dist/transforms/identifier/globalConcealing.js +72 -56
- package/dist/transforms/identifier/movedDeclarations.js +66 -38
- package/dist/transforms/identifier/renameVariables.js +36 -68
- package/dist/transforms/identifier/variableAnalysis.js +21 -48
- package/dist/transforms/lock/antiDebug.js +20 -25
- package/dist/transforms/lock/integrity.js +53 -52
- package/dist/transforms/lock/lock.js +161 -126
- package/dist/transforms/minify.js +77 -108
- package/dist/transforms/opaquePredicates.js +12 -49
- package/dist/transforms/preparation.js +28 -49
- package/dist/transforms/renameLabels.js +5 -22
- package/dist/transforms/rgf.js +125 -72
- package/dist/transforms/shuffle.js +42 -47
- package/dist/transforms/stack.js +41 -98
- package/dist/transforms/string/encoding.js +76 -27
- package/dist/transforms/string/stringCompression.js +75 -68
- package/dist/transforms/string/stringConcealing.js +127 -135
- package/dist/transforms/string/stringEncoding.js +6 -26
- package/dist/transforms/string/stringSplitting.js +5 -30
- package/dist/transforms/transform.js +76 -104
- 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 +5 -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 +31 -36
- package/dist/util/scope.js +6 -3
- package/docs/Countermeasures.md +13 -6
- package/docs/Integrity.md +35 -28
- package/docs/RGF.md +6 -1
- package/docs/RenameVariables.md +116 -0
- package/docs/TamperProtection.md +100 -0
- package/docs/Template.md +117 -0
- package/package.json +3 -3
- package/src/constants.ts +17 -0
- package/src/index.ts +7 -5
- package/src/options.ts +60 -7
- package/src/order.ts +2 -2
- package/src/templates/bufferToString.ts +79 -11
- package/src/templates/core.ts +29 -0
- package/src/templates/crash.ts +6 -38
- package/src/templates/es5.ts +1 -1
- package/src/templates/functionLength.ts +21 -3
- package/src/templates/globals.ts +3 -0
- package/src/templates/template.ts +205 -46
- package/src/transforms/antiTooling.ts +33 -11
- package/src/transforms/calculator.ts +4 -2
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +12 -5
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
- package/src/transforms/deadCode.ts +74 -42
- package/src/transforms/dispatcher.ts +99 -73
- package/src/transforms/es5/antiClass.ts +25 -12
- package/src/transforms/es5/antiDestructuring.ts +1 -1
- package/src/transforms/es5/antiES6Object.ts +2 -2
- package/src/transforms/es5/antiTemplate.ts +1 -1
- package/src/transforms/extraction/classExtraction.ts +168 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +11 -16
- package/src/transforms/extraction/objectExtraction.ts +4 -15
- package/src/transforms/flatten.ts +20 -5
- package/src/transforms/identifier/globalAnalysis.ts +18 -1
- package/src/transforms/identifier/globalConcealing.ts +119 -72
- package/src/transforms/identifier/movedDeclarations.ts +90 -24
- package/src/transforms/identifier/renameVariables.ts +16 -1
- package/src/transforms/lock/antiDebug.ts +2 -2
- package/src/transforms/lock/integrity.ts +13 -11
- package/src/transforms/lock/lock.ts +122 -30
- package/src/transforms/minify.ts +28 -13
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +16 -0
- package/src/transforms/rgf.ts +139 -12
- package/src/transforms/shuffle.ts +3 -3
- package/src/transforms/stack.ts +19 -4
- package/src/transforms/string/encoding.ts +88 -51
- package/src/transforms/string/stringCompression.ts +86 -17
- package/src/transforms/string/stringConcealing.ts +148 -118
- package/src/transforms/string/stringEncoding.ts +1 -2
- package/src/transforms/string/stringSplitting.ts +1 -2
- package/src/transforms/transform.ts +63 -46
- package/src/types.ts +2 -0
- package/src/util/compare.ts +39 -5
- package/src/util/gen.ts +10 -3
- package/src/util/guard.ts +10 -0
- package/src/util/insert.ts +17 -0
- package/src/util/random.ts +81 -1
- package/src/util/scope.ts +14 -2
- package/test/code/Cash.test.ts +94 -5
- 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 +129 -55
- package/test/templates/template.test.ts +211 -1
- 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 +89 -0
- package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
- package/test/transforms/identifier/renameVariables.test.ts +75 -1
- package/test/transforms/lock/tamperProtection.test.ts +336 -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
|
@@ -34,14 +34,20 @@ import {
|
|
|
34
34
|
isVarContext,
|
|
35
35
|
prepend,
|
|
36
36
|
append,
|
|
37
|
+
computeFunctionLength,
|
|
38
|
+
isFunction,
|
|
37
39
|
} from "../util/insert";
|
|
38
40
|
import Transform from "./transform";
|
|
39
41
|
import { isInsideType } from "../util/compare";
|
|
40
42
|
import { choice, shuffle } from "../util/random";
|
|
41
43
|
import { ComputeProbabilityMap } from "../probability";
|
|
42
|
-
import { reservedIdentifiers } from "../constants";
|
|
44
|
+
import { predictableFunctionTag, reservedIdentifiers } from "../constants";
|
|
43
45
|
import { ObfuscateOrder } from "../order";
|
|
44
46
|
import Template from "../templates/template";
|
|
47
|
+
import { FunctionLengthTemplate } from "../templates/functionLength";
|
|
48
|
+
import { ObjectDefineProperty } from "../templates/globals";
|
|
49
|
+
import { getLexicalScope } from "../util/scope";
|
|
50
|
+
import { isJSConfuserVar } from "../util/guard";
|
|
45
51
|
|
|
46
52
|
/**
|
|
47
53
|
* A Dispatcher processes function calls. All the function declarations are brought into a dictionary.
|
|
@@ -72,12 +78,30 @@ export default class Dispatcher extends Transform {
|
|
|
72
78
|
isDebug = false;
|
|
73
79
|
count: number;
|
|
74
80
|
|
|
81
|
+
functionLengthName: string;
|
|
82
|
+
|
|
75
83
|
constructor(o) {
|
|
76
84
|
super(o, ObfuscateOrder.Dispatcher);
|
|
77
85
|
|
|
78
86
|
this.count = 0;
|
|
79
87
|
}
|
|
80
88
|
|
|
89
|
+
apply(tree: Node): void {
|
|
90
|
+
super.apply(tree);
|
|
91
|
+
|
|
92
|
+
if (this.options.preserveFunctionLength && this.functionLengthName) {
|
|
93
|
+
prepend(
|
|
94
|
+
tree,
|
|
95
|
+
FunctionLengthTemplate.single({
|
|
96
|
+
name: this.functionLengthName,
|
|
97
|
+
ObjectDefineProperty: this.createInitVariable(ObjectDefineProperty, [
|
|
98
|
+
tree,
|
|
99
|
+
]),
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
81
105
|
match(object: Node, parents: Node[]) {
|
|
82
106
|
if (isInsideType("AwaitExpression", object, parents)) {
|
|
83
107
|
return false;
|
|
@@ -86,8 +110,8 @@ export default class Dispatcher extends Transform {
|
|
|
86
110
|
return (
|
|
87
111
|
isVarContext(object) &&
|
|
88
112
|
object.type !== "ArrowFunctionExpression" &&
|
|
89
|
-
!object.$
|
|
90
|
-
!parents.find((x) => x.$
|
|
113
|
+
!object.$multiTransformSkip &&
|
|
114
|
+
!parents.find((x) => x.$multiTransformSkip)
|
|
91
115
|
);
|
|
92
116
|
}
|
|
93
117
|
|
|
@@ -113,6 +137,8 @@ export default class Dispatcher extends Transform {
|
|
|
113
137
|
? object
|
|
114
138
|
: getVarContext(object, parents);
|
|
115
139
|
|
|
140
|
+
var lexicalScope = isFunction(context) ? context.body : context;
|
|
141
|
+
|
|
116
142
|
walk(object, parents, (o: Node, p: Node[]) => {
|
|
117
143
|
if (object == o) {
|
|
118
144
|
// Fix 1
|
|
@@ -133,11 +159,20 @@ export default class Dispatcher extends Transform {
|
|
|
133
159
|
o.async ||
|
|
134
160
|
o.generator ||
|
|
135
161
|
p.find(
|
|
136
|
-
(x) => x.$
|
|
162
|
+
(x) => x.$multiTransformSkip || x.type == "MethodDefinition"
|
|
137
163
|
) ||
|
|
138
164
|
o.body.type != "BlockStatement"
|
|
139
165
|
) {
|
|
140
166
|
illegalFnNames.add(name);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Must defined in the same block as the current function being scanned
|
|
171
|
+
// Solves 'let' and 'class' declaration issue
|
|
172
|
+
var ls = getLexicalScope(o, p);
|
|
173
|
+
if (ls !== lexicalScope) {
|
|
174
|
+
illegalFnNames.add(name);
|
|
175
|
+
return;
|
|
141
176
|
}
|
|
142
177
|
|
|
143
178
|
// If dupe, no routing
|
|
@@ -181,6 +216,9 @@ export default class Dispatcher extends Transform {
|
|
|
181
216
|
if (!info.spec.isReferenced) {
|
|
182
217
|
return;
|
|
183
218
|
}
|
|
219
|
+
if (isJSConfuserVar(p)) {
|
|
220
|
+
illegalFnNames.add(o.name);
|
|
221
|
+
}
|
|
184
222
|
if (info.spec.isDefined) {
|
|
185
223
|
if (info.isFunctionDeclaration) {
|
|
186
224
|
if (
|
|
@@ -217,11 +255,18 @@ export default class Dispatcher extends Transform {
|
|
|
217
255
|
|
|
218
256
|
// Only make a dispatcher function if it caught any functions
|
|
219
257
|
if (set.size > 0) {
|
|
258
|
+
if (!this.functionLengthName) {
|
|
259
|
+
this.functionLengthName = this.getPlaceholder();
|
|
260
|
+
}
|
|
261
|
+
|
|
220
262
|
var payloadArg =
|
|
221
263
|
this.getPlaceholder() + "_dispatcher_" + this.count + "_payload";
|
|
222
264
|
|
|
223
265
|
var dispatcherFnName =
|
|
224
|
-
this.getPlaceholder() +
|
|
266
|
+
this.getPlaceholder() +
|
|
267
|
+
"_dispatcher_" +
|
|
268
|
+
this.count +
|
|
269
|
+
predictableFunctionTag;
|
|
225
270
|
|
|
226
271
|
this.log(dispatcherFnName, set);
|
|
227
272
|
this.count++;
|
|
@@ -253,6 +298,8 @@ export default class Dispatcher extends Transform {
|
|
|
253
298
|
expression: false,
|
|
254
299
|
type: "FunctionExpression",
|
|
255
300
|
id: null,
|
|
301
|
+
params: [],
|
|
302
|
+
[predictableFunctionTag]: true,
|
|
256
303
|
};
|
|
257
304
|
this.addComment(functionExpression, name);
|
|
258
305
|
|
|
@@ -272,48 +319,6 @@ export default class Dispatcher extends Transform {
|
|
|
272
319
|
);
|
|
273
320
|
|
|
274
321
|
prepend(def.body, variableDeclaration);
|
|
275
|
-
|
|
276
|
-
// replace params with random identifiers
|
|
277
|
-
var args = [0, 1, 2].map((x) => this.getPlaceholder());
|
|
278
|
-
functionExpression.params = args.map((x) => Identifier(x));
|
|
279
|
-
|
|
280
|
-
var deadCode = choice(["fakeReturn", "ifStatement"]);
|
|
281
|
-
|
|
282
|
-
switch (deadCode) {
|
|
283
|
-
case "fakeReturn":
|
|
284
|
-
// Dead code...
|
|
285
|
-
var ifStatement = IfStatement(
|
|
286
|
-
UnaryExpression("!", Identifier(args[0])),
|
|
287
|
-
[
|
|
288
|
-
ReturnStatement(
|
|
289
|
-
CallExpression(Identifier(args[1]), [
|
|
290
|
-
ThisExpression(),
|
|
291
|
-
Identifier(args[2]),
|
|
292
|
-
])
|
|
293
|
-
),
|
|
294
|
-
],
|
|
295
|
-
null
|
|
296
|
-
);
|
|
297
|
-
|
|
298
|
-
body.unshift(ifStatement);
|
|
299
|
-
break;
|
|
300
|
-
|
|
301
|
-
case "ifStatement":
|
|
302
|
-
var test = LogicalExpression(
|
|
303
|
-
"||",
|
|
304
|
-
Identifier(args[0]),
|
|
305
|
-
AssignmentExpression(
|
|
306
|
-
"=",
|
|
307
|
-
Identifier(args[1]),
|
|
308
|
-
CallExpression(Identifier(args[2]), [])
|
|
309
|
-
)
|
|
310
|
-
);
|
|
311
|
-
def.body = BlockStatement([
|
|
312
|
-
IfStatement(test, [...body], null),
|
|
313
|
-
ReturnStatement(Identifier(args[1])),
|
|
314
|
-
]);
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
322
|
}
|
|
318
323
|
|
|
319
324
|
// For logging purposes
|
|
@@ -380,6 +385,48 @@ export default class Dispatcher extends Transform {
|
|
|
380
385
|
null
|
|
381
386
|
),
|
|
382
387
|
|
|
388
|
+
VariableDeclaration(
|
|
389
|
+
VariableDeclarator(
|
|
390
|
+
Identifier("lengths"),
|
|
391
|
+
ObjectExpression(
|
|
392
|
+
!this.options.preserveFunctionLength
|
|
393
|
+
? []
|
|
394
|
+
: shuffledKeys
|
|
395
|
+
.map((name) => {
|
|
396
|
+
var [def, defParents] = functionDeclarations[name];
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
key: newFnNames[name],
|
|
400
|
+
value: computeFunctionLength(def.params),
|
|
401
|
+
};
|
|
402
|
+
})
|
|
403
|
+
.filter((item) => item.value !== 0)
|
|
404
|
+
.map((item) =>
|
|
405
|
+
Property(Literal(item.key), Literal(item.value))
|
|
406
|
+
)
|
|
407
|
+
)
|
|
408
|
+
)
|
|
409
|
+
),
|
|
410
|
+
|
|
411
|
+
new Template(`
|
|
412
|
+
function makeFn${predictableFunctionTag}(){
|
|
413
|
+
var fn = function(...args){
|
|
414
|
+
${payloadArg} = args;
|
|
415
|
+
return ${mapName}[${x}].call(this)
|
|
416
|
+
}, a = lengths[${x}]
|
|
417
|
+
|
|
418
|
+
${
|
|
419
|
+
this.options.preserveFunctionLength
|
|
420
|
+
? `if(a){
|
|
421
|
+
return ${this.functionLengthName}(fn, a)
|
|
422
|
+
}`
|
|
423
|
+
: ""
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return fn
|
|
427
|
+
}
|
|
428
|
+
`).single(),
|
|
429
|
+
|
|
383
430
|
// Arg to get a function reference
|
|
384
431
|
IfStatement(
|
|
385
432
|
BinaryExpression("==", Identifier(y), Literal(expectedGet)),
|
|
@@ -403,30 +450,9 @@ export default class Dispatcher extends Transform {
|
|
|
403
450
|
Identifier(x),
|
|
404
451
|
true
|
|
405
452
|
),
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
[
|
|
409
|
-
// Arg setter
|
|
410
|
-
ExpressionStatement(
|
|
411
|
-
AssignmentExpression(
|
|
412
|
-
"=",
|
|
413
|
-
Identifier(payloadArg),
|
|
414
|
-
Identifier(getterArgName)
|
|
415
|
-
)
|
|
416
|
-
),
|
|
417
|
-
|
|
418
|
-
// Call fn & return
|
|
419
|
-
ReturnStatement(
|
|
420
|
-
CallExpression(
|
|
421
|
-
MemberExpression(
|
|
422
|
-
getAccessor(),
|
|
423
|
-
Identifier("call"),
|
|
424
|
-
false
|
|
425
|
-
),
|
|
426
|
-
[ThisExpression(), Literal(gen.generate())]
|
|
427
|
-
)
|
|
428
|
-
),
|
|
429
|
-
]
|
|
453
|
+
CallExpression(
|
|
454
|
+
Identifier(`makeFn${predictableFunctionTag}`),
|
|
455
|
+
[]
|
|
430
456
|
)
|
|
431
457
|
)
|
|
432
458
|
)
|
|
@@ -439,7 +465,7 @@ export default class Dispatcher extends Transform {
|
|
|
439
465
|
AssignmentExpression(
|
|
440
466
|
"=",
|
|
441
467
|
Identifier(returnProp),
|
|
442
|
-
CallExpression(getAccessor(), [
|
|
468
|
+
CallExpression(getAccessor(), [])
|
|
443
469
|
)
|
|
444
470
|
),
|
|
445
471
|
]
|
|
@@ -603,7 +629,7 @@ export default class Dispatcher extends Transform {
|
|
|
603
629
|
VariableDeclaration(
|
|
604
630
|
VariableDeclarator(
|
|
605
631
|
Identifier(cacheName),
|
|
606
|
-
Template(`Object.create(null)`).single().expression
|
|
632
|
+
new Template(`Object.create(null)`).single().expression
|
|
607
633
|
)
|
|
608
634
|
)
|
|
609
635
|
);
|
|
@@ -46,8 +46,10 @@ export default class AntiClass extends Transform {
|
|
|
46
46
|
var thisName = "this" + this.getPlaceholder();
|
|
47
47
|
|
|
48
48
|
// self this
|
|
49
|
-
virtualBody.push(Template(`var ${thisName} = this;`).single());
|
|
50
|
-
virtualBody.push(
|
|
49
|
+
virtualBody.push(new Template(`var ${thisName} = this;`).single());
|
|
50
|
+
virtualBody.push(
|
|
51
|
+
new Template(`${thisName}["constructor"] = null;`).single()
|
|
52
|
+
);
|
|
51
53
|
var superArguments;
|
|
52
54
|
var superBody = [];
|
|
53
55
|
|
|
@@ -60,14 +62,14 @@ export default class AntiClass extends Transform {
|
|
|
60
62
|
|
|
61
63
|
// getters/setters
|
|
62
64
|
virtualBody.push(
|
|
63
|
-
Template(
|
|
65
|
+
new Template(
|
|
64
66
|
`var ${virtualDescriptorsName} = {getters: {}, setters: {}}`
|
|
65
67
|
).single()
|
|
66
68
|
);
|
|
67
69
|
|
|
68
70
|
// getters/setters
|
|
69
71
|
staticBody.push(
|
|
70
|
-
Template(
|
|
72
|
+
new Template(
|
|
71
73
|
`var ${staticDescriptorsName} = {getters: {}, setters: {}}`
|
|
72
74
|
).single()
|
|
73
75
|
);
|
|
@@ -94,8 +96,17 @@ export default class AntiClass extends Transform {
|
|
|
94
96
|
first.expression.type == "CallExpression"
|
|
95
97
|
) {
|
|
96
98
|
if (first.expression.callee.type == "Super") {
|
|
99
|
+
/// super(...args)
|
|
97
100
|
superArguments = first.expression.arguments;
|
|
98
101
|
value.body.body.shift();
|
|
102
|
+
} else if (
|
|
103
|
+
// F(super(...args))
|
|
104
|
+
first.expression.arguments[0] &&
|
|
105
|
+
first.expression.arguments[0].type === "CallExpression" &&
|
|
106
|
+
first.expression.arguments[0].callee.type === "Super"
|
|
107
|
+
) {
|
|
108
|
+
superArguments = first.expression.arguments[0].arguments;
|
|
109
|
+
first.expression.arguments[0] = Identifier("undefined");
|
|
99
110
|
}
|
|
100
111
|
}
|
|
101
112
|
|
|
@@ -160,7 +171,7 @@ export default class AntiClass extends Transform {
|
|
|
160
171
|
});
|
|
161
172
|
|
|
162
173
|
virtualBody.push(
|
|
163
|
-
Template(`
|
|
174
|
+
new Template(`
|
|
164
175
|
[...Object.keys(${virtualDescriptorsName}.getters), ...Object.keys(${virtualDescriptorsName}.setters)].forEach(key=>{
|
|
165
176
|
|
|
166
177
|
if( !${thisName}.hasOwnProperty(key) ) {
|
|
@@ -179,7 +190,7 @@ export default class AntiClass extends Transform {
|
|
|
179
190
|
);
|
|
180
191
|
|
|
181
192
|
staticBody.push(
|
|
182
|
-
Template(`
|
|
193
|
+
new Template(`
|
|
183
194
|
[...Object.keys(${staticDescriptorsName}.getters), ...Object.keys(${staticDescriptorsName}.setters)].forEach(key=>{
|
|
184
195
|
|
|
185
196
|
if( !${virtualName}.hasOwnProperty(key) ) {
|
|
@@ -198,11 +209,11 @@ export default class AntiClass extends Transform {
|
|
|
198
209
|
);
|
|
199
210
|
|
|
200
211
|
if (superName) {
|
|
201
|
-
ok(superArguments, "
|
|
212
|
+
ok(superArguments, "Failed to find super() arguments");
|
|
202
213
|
|
|
203
214
|
// save the super state
|
|
204
215
|
virtualBody.unshift(
|
|
205
|
-
Template(
|
|
216
|
+
new Template(
|
|
206
217
|
`
|
|
207
218
|
Object.keys(this).forEach(key=>{
|
|
208
219
|
var descriptor = Object.getOwnPropertyDescriptor(this, key);
|
|
@@ -224,17 +235,17 @@ export default class AntiClass extends Transform {
|
|
|
224
235
|
)
|
|
225
236
|
);
|
|
226
237
|
|
|
227
|
-
virtualBody.unshift(Template(`var ${superName} = {}`).single());
|
|
238
|
+
virtualBody.unshift(new Template(`var ${superName} = {}`).single());
|
|
228
239
|
}
|
|
229
240
|
|
|
230
241
|
virtualBody.push(
|
|
231
|
-
Template(
|
|
242
|
+
new Template(
|
|
232
243
|
`if(!this["constructor"]){this["constructor"] = ()=>{}};`
|
|
233
244
|
).single()
|
|
234
245
|
);
|
|
235
246
|
if (object.id && object.id.name) {
|
|
236
247
|
virtualBody.push(
|
|
237
|
-
Template(`Object.defineProperty(this["constructor"], 'name', {
|
|
248
|
+
new Template(`Object.defineProperty(this["constructor"], 'name', {
|
|
238
249
|
writable: true,
|
|
239
250
|
configurable: true,
|
|
240
251
|
value: '${object.id.name}'
|
|
@@ -242,7 +253,9 @@ export default class AntiClass extends Transform {
|
|
|
242
253
|
);
|
|
243
254
|
}
|
|
244
255
|
|
|
245
|
-
virtualBody.push(
|
|
256
|
+
virtualBody.push(
|
|
257
|
+
new Template(`this["constructor"](...arguments)`).single()
|
|
258
|
+
);
|
|
246
259
|
|
|
247
260
|
var virtualFunction = FunctionExpression([], virtualBody);
|
|
248
261
|
|
|
@@ -126,7 +126,7 @@ class AntiDestructuringParameters extends Transform {
|
|
|
126
126
|
VariableDeclaration(
|
|
127
127
|
VariableDeclarator(
|
|
128
128
|
arrayPattern,
|
|
129
|
-
Template(`Array.prototype.slice.call(arguments)`).single()
|
|
129
|
+
new Template(`Array.prototype.slice.call(arguments)`).single()
|
|
130
130
|
.expression
|
|
131
131
|
)
|
|
132
132
|
)
|
|
@@ -14,7 +14,7 @@ import { prepend } from "../../util/insert";
|
|
|
14
14
|
import { getBlock } from "../../traverse";
|
|
15
15
|
import Template from "../../templates/template";
|
|
16
16
|
|
|
17
|
-
var HelperFunctions = Template(
|
|
17
|
+
var HelperFunctions = new Template(
|
|
18
18
|
`
|
|
19
19
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
20
20
|
|
|
@@ -187,7 +187,7 @@ export default class AntiES6Object extends Transform {
|
|
|
187
187
|
|
|
188
188
|
prepend(
|
|
189
189
|
parents[parents.length - 1] || block,
|
|
190
|
-
Template(`
|
|
190
|
+
new Template(`
|
|
191
191
|
function {name}(base, computedProps, getters, setters){
|
|
192
192
|
|
|
193
193
|
for ( var i = 0; i < computedProps.length; i++ ) {
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { ok } from "assert";
|
|
2
|
+
import { ExitCallback, getBlock, walk } from "../../traverse";
|
|
3
|
+
import {
|
|
4
|
+
CallExpression,
|
|
5
|
+
FunctionDeclaration,
|
|
6
|
+
FunctionExpression,
|
|
7
|
+
Identifier,
|
|
8
|
+
Literal,
|
|
9
|
+
MemberExpression,
|
|
10
|
+
MethodDefinition,
|
|
11
|
+
Node,
|
|
12
|
+
ReturnStatement,
|
|
13
|
+
Super,
|
|
14
|
+
ThisExpression,
|
|
15
|
+
} from "../../util/gen";
|
|
16
|
+
import { isStringLiteral } from "../../util/guard";
|
|
17
|
+
import { isClass, prepend } from "../../util/insert";
|
|
18
|
+
import { getLexicalScope } from "../../util/scope";
|
|
19
|
+
import Transform from "../transform";
|
|
20
|
+
|
|
21
|
+
export default class ClassExtraction extends Transform {
|
|
22
|
+
constructor(o) {
|
|
23
|
+
super(o);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
match(object: Node, parents: Node[]): boolean {
|
|
27
|
+
return (
|
|
28
|
+
object.type === "ClassDeclaration" || object.type === "ClassExpression"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
extractKeyString(property: Node): string | null {
|
|
33
|
+
if (property.key.type === "Identifier" && !property.key.computed) {
|
|
34
|
+
return property.key.name;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isStringLiteral(property.key)) {
|
|
38
|
+
return property.key.value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
transform(object: Node, parents: Node[]): void | ExitCallback {
|
|
45
|
+
return () => {
|
|
46
|
+
var classBody = object.body;
|
|
47
|
+
var className = object.id?.type === "Identifier" && object.id?.name;
|
|
48
|
+
|
|
49
|
+
if (!className) className = this.getPlaceholder();
|
|
50
|
+
|
|
51
|
+
var lexicalScope = getLexicalScope(object, parents);
|
|
52
|
+
|
|
53
|
+
var superMethodName: string;
|
|
54
|
+
|
|
55
|
+
for (var methodDefinition of classBody.body) {
|
|
56
|
+
if (
|
|
57
|
+
methodDefinition.type === "MethodDefinition" &&
|
|
58
|
+
methodDefinition.value.type === "FunctionExpression"
|
|
59
|
+
) {
|
|
60
|
+
// Don't change constructors calling super()
|
|
61
|
+
if (methodDefinition.kind === "constructor" && object.superClass)
|
|
62
|
+
continue;
|
|
63
|
+
|
|
64
|
+
var functionExpression: Node = methodDefinition.value;
|
|
65
|
+
|
|
66
|
+
var fnName =
|
|
67
|
+
className +
|
|
68
|
+
"_" +
|
|
69
|
+
methodDefinition.kind +
|
|
70
|
+
"_" +
|
|
71
|
+
this.extractKeyString(methodDefinition) || this.getPlaceholder();
|
|
72
|
+
|
|
73
|
+
walk(
|
|
74
|
+
functionExpression,
|
|
75
|
+
[methodDefinition, object, ...parents],
|
|
76
|
+
(o, p) => {
|
|
77
|
+
if (o.type === "Super") {
|
|
78
|
+
var classContext = p.find((node) => isClass(node));
|
|
79
|
+
if (classContext !== object) return;
|
|
80
|
+
|
|
81
|
+
return () => {
|
|
82
|
+
if (!superMethodName) {
|
|
83
|
+
superMethodName =
|
|
84
|
+
this.getGenerator("randomized").generate();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var memberExpression = p[0];
|
|
88
|
+
if (memberExpression.type === "CallExpression") {
|
|
89
|
+
throw new Error("Failed to detect super() usage");
|
|
90
|
+
}
|
|
91
|
+
ok(memberExpression.type === "MemberExpression");
|
|
92
|
+
|
|
93
|
+
var propertyArg = memberExpression.computed
|
|
94
|
+
? memberExpression.property
|
|
95
|
+
: (ok(memberExpression.property.type === "Identifier"),
|
|
96
|
+
Literal(memberExpression.property.name));
|
|
97
|
+
|
|
98
|
+
var getSuperExpression = CallExpression(
|
|
99
|
+
MemberExpression(
|
|
100
|
+
ThisExpression(),
|
|
101
|
+
Literal(superMethodName),
|
|
102
|
+
true
|
|
103
|
+
),
|
|
104
|
+
[propertyArg]
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (p[1].type === "CallExpression" && p[1].callee === p[0]) {
|
|
108
|
+
getSuperExpression = CallExpression(
|
|
109
|
+
MemberExpression(
|
|
110
|
+
getSuperExpression,
|
|
111
|
+
Literal("bind"),
|
|
112
|
+
true
|
|
113
|
+
),
|
|
114
|
+
[ThisExpression()]
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.replace(p[0], getSuperExpression);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
var originalParams = functionExpression.params;
|
|
125
|
+
var originalBody = functionExpression.body.body;
|
|
126
|
+
|
|
127
|
+
functionExpression.body.body = [
|
|
128
|
+
ReturnStatement(
|
|
129
|
+
CallExpression(
|
|
130
|
+
MemberExpression(Identifier(fnName), Literal("apply"), true),
|
|
131
|
+
[ThisExpression(), Identifier("arguments")]
|
|
132
|
+
)
|
|
133
|
+
),
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
functionExpression.params = [];
|
|
137
|
+
if (methodDefinition.kind === "set") {
|
|
138
|
+
functionExpression.params = [Identifier(this.getPlaceholder())];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
prepend(
|
|
142
|
+
lexicalScope,
|
|
143
|
+
FunctionDeclaration(fnName, [...originalParams], [...originalBody])
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (superMethodName) {
|
|
149
|
+
classBody.body.push(
|
|
150
|
+
MethodDefinition(
|
|
151
|
+
Literal(superMethodName),
|
|
152
|
+
FunctionExpression(
|
|
153
|
+
[Identifier("key")],
|
|
154
|
+
[
|
|
155
|
+
ReturnStatement(
|
|
156
|
+
MemberExpression(Super(), Identifier("key"), true)
|
|
157
|
+
),
|
|
158
|
+
]
|
|
159
|
+
),
|
|
160
|
+
"method",
|
|
161
|
+
false,
|
|
162
|
+
true
|
|
163
|
+
)
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -12,19 +12,17 @@ import {
|
|
|
12
12
|
CallExpression,
|
|
13
13
|
BinaryExpression,
|
|
14
14
|
FunctionDeclaration,
|
|
15
|
-
ThisExpression,
|
|
16
15
|
ConditionalExpression,
|
|
17
16
|
} from "../../util/gen";
|
|
18
17
|
import { append, clone, prepend } from "../../util/insert";
|
|
19
|
-
import { isDirective, isPrimitive } from "../../util/compare";
|
|
20
|
-
|
|
18
|
+
import { isDirective, isModuleSource, isPrimitive } from "../../util/compare";
|
|
21
19
|
import { ObfuscateOrder } from "../../order";
|
|
22
|
-
import { isModuleSource } from "../string/stringConcealing";
|
|
23
20
|
import { ComputeProbabilityMap } from "../../probability";
|
|
24
21
|
import { ok } from "assert";
|
|
25
22
|
import { chance, choice, getRandomInteger } from "../../util/random";
|
|
26
23
|
import { getBlock } from "../../traverse";
|
|
27
24
|
import { getIdentifierInfo } from "../../util/identifiers";
|
|
25
|
+
import { predictableFunctionTag } from "../../constants";
|
|
28
26
|
|
|
29
27
|
/**
|
|
30
28
|
* [Duplicate Literals Removal](https://docs.jscrambler.com/code-integrity/documentation/transformations/duplicate-literals-removal) replaces duplicate literals with a variable name.
|
|
@@ -95,10 +93,7 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
95
93
|
VariableDeclaration(
|
|
96
94
|
VariableDeclarator(
|
|
97
95
|
this.arrayName,
|
|
98
|
-
CallExpression(
|
|
99
|
-
MemberExpression(Identifier(getArrayFn), Literal("call"), true),
|
|
100
|
-
[ThisExpression()]
|
|
101
|
-
)
|
|
96
|
+
CallExpression(Identifier(getArrayFn), [])
|
|
102
97
|
)
|
|
103
98
|
)
|
|
104
99
|
);
|
|
@@ -119,7 +114,7 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
119
114
|
];
|
|
120
115
|
|
|
121
116
|
// The function uses mangling to hide the index being accessed
|
|
122
|
-
var mangleCount = getRandomInteger(1,
|
|
117
|
+
var mangleCount = getRandomInteger(1, 5);
|
|
123
118
|
for (var i = 0; i < mangleCount; i++) {
|
|
124
119
|
var operator = choice([">", "<"]);
|
|
125
120
|
var compareValue = choice(indexRangeInclusive);
|
|
@@ -170,7 +165,7 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
170
165
|
isPrimitive(object) &&
|
|
171
166
|
!isDirective(object, parents) &&
|
|
172
167
|
!isModuleSource(object, parents) &&
|
|
173
|
-
!parents.find((x) => x.$
|
|
168
|
+
!parents.find((x) => x.$multiTransformSkip)
|
|
174
169
|
);
|
|
175
170
|
}
|
|
176
171
|
|
|
@@ -188,7 +183,7 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
188
183
|
var root = parents[parents.length - 1];
|
|
189
184
|
var rootFunctionName = this.getPlaceholder() + "_dLR_0";
|
|
190
185
|
this.functions.set(root, {
|
|
191
|
-
functionName: rootFunctionName,
|
|
186
|
+
functionName: rootFunctionName + predictableFunctionTag,
|
|
192
187
|
indexShift: getRandomInteger(-100, 100),
|
|
193
188
|
});
|
|
194
189
|
|
|
@@ -199,7 +194,10 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
199
194
|
var block = getBlock(object, parents);
|
|
200
195
|
if (!this.functions.has(block) && chance(50 - this.functions.size)) {
|
|
201
196
|
var newFunctionName =
|
|
202
|
-
this.getPlaceholder() +
|
|
197
|
+
this.getPlaceholder() +
|
|
198
|
+
"_dLR_" +
|
|
199
|
+
this.functions.size +
|
|
200
|
+
predictableFunctionTag;
|
|
203
201
|
|
|
204
202
|
this.functions.set(block, {
|
|
205
203
|
functionName: newFunctionName,
|
|
@@ -224,7 +222,7 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
224
222
|
return () => {
|
|
225
223
|
if (object.type === "Identifier") {
|
|
226
224
|
var info = getIdentifierInfo(object, parents);
|
|
227
|
-
if (info.isLabel || info.spec.isDefined) return;
|
|
225
|
+
if (info.isLabel || info.spec.isDefined || info.spec.isModified) return;
|
|
228
226
|
}
|
|
229
227
|
if (object.regex) {
|
|
230
228
|
return;
|
|
@@ -234,9 +232,6 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
234
232
|
return;
|
|
235
233
|
}
|
|
236
234
|
|
|
237
|
-
// HARD CODED LIMIT of 10,000 (after 1,000 elements)
|
|
238
|
-
if (this.map.size > 1000 && chance(this.map.size / 100)) return;
|
|
239
|
-
|
|
240
235
|
if (
|
|
241
236
|
this.arrayName &&
|
|
242
237
|
parents[0].object &&
|