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
package/src/transforms/rgf.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { compileJsSync } from "../compiler";
|
|
2
|
-
import { reservedIdentifiers } from "../constants";
|
|
2
|
+
import { predictableFunctionTag, reservedIdentifiers } from "../constants";
|
|
3
3
|
import Obfuscator from "../obfuscator";
|
|
4
4
|
import { ObfuscateOrder } from "../order";
|
|
5
5
|
import { ComputeProbabilityMap } from "../probability";
|
|
6
|
+
import { FunctionLengthTemplate } from "../templates/functionLength";
|
|
7
|
+
import { ObjectDefineProperty } from "../templates/globals";
|
|
8
|
+
import Template from "../templates/template";
|
|
6
9
|
import { walk } from "../traverse";
|
|
7
10
|
import {
|
|
8
11
|
ArrayExpression,
|
|
9
12
|
BlockStatement,
|
|
10
13
|
CallExpression,
|
|
14
|
+
ExpressionStatement,
|
|
11
15
|
Identifier,
|
|
12
16
|
Literal,
|
|
17
|
+
LogicalExpression,
|
|
13
18
|
MemberExpression,
|
|
14
19
|
NewExpression,
|
|
15
20
|
Node,
|
|
@@ -19,7 +24,11 @@ import {
|
|
|
19
24
|
VariableDeclarator,
|
|
20
25
|
} from "../util/gen";
|
|
21
26
|
import { getIdentifierInfo } from "../util/identifiers";
|
|
22
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
prepend,
|
|
29
|
+
getDefiningContext,
|
|
30
|
+
computeFunctionLength,
|
|
31
|
+
} from "../util/insert";
|
|
23
32
|
import Integrity from "./lock/integrity";
|
|
24
33
|
import Transform from "./transform";
|
|
25
34
|
|
|
@@ -38,6 +47,16 @@ export default class RGF extends Transform {
|
|
|
38
47
|
// The name of the array holding all the `new Function` expressions
|
|
39
48
|
arrayExpressionName: string;
|
|
40
49
|
|
|
50
|
+
functionLengthName: string;
|
|
51
|
+
|
|
52
|
+
getFunctionLengthName(parents: Node[]) {
|
|
53
|
+
if (!this.functionLengthName) {
|
|
54
|
+
this.functionLengthName = this.getPlaceholder();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return this.functionLengthName;
|
|
58
|
+
}
|
|
59
|
+
|
|
41
60
|
constructor(o) {
|
|
42
61
|
super(o, ObfuscateOrder.RGF);
|
|
43
62
|
|
|
@@ -50,14 +69,54 @@ export default class RGF extends Transform {
|
|
|
50
69
|
|
|
51
70
|
// Only add the array if there were converted functions
|
|
52
71
|
if (this.arrayExpressionElements.length > 0) {
|
|
72
|
+
var variableDeclaration = VariableDeclaration(
|
|
73
|
+
VariableDeclarator(
|
|
74
|
+
Identifier(this.arrayExpressionName),
|
|
75
|
+
ArrayExpression(this.arrayExpressionElements)
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
var nodes: Node[] = [variableDeclaration];
|
|
80
|
+
|
|
81
|
+
if (this.options.lock?.tamperProtection) {
|
|
82
|
+
// The name of the variable flag if eval is safe to use
|
|
83
|
+
var tamperProtectionCheckName = this.getPlaceholder() + "_rgfEvalCheck";
|
|
84
|
+
|
|
85
|
+
variableDeclaration.declarations[0].init = LogicalExpression(
|
|
86
|
+
"&&",
|
|
87
|
+
Identifier(tamperProtectionCheckName),
|
|
88
|
+
{ ...variableDeclaration.declarations[0].init }
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
nodes.unshift(
|
|
92
|
+
...new Template(`
|
|
93
|
+
var ${tamperProtectionCheckName} = false;
|
|
94
|
+
eval(${this.jsConfuserVar(tamperProtectionCheckName)} + "=true");
|
|
95
|
+
if(!${tamperProtectionCheckName}) {
|
|
96
|
+
{countermeasures}
|
|
97
|
+
}
|
|
98
|
+
`).compile({
|
|
99
|
+
countermeasures: this.lockTransform.getCounterMeasuresCode(
|
|
100
|
+
tree,
|
|
101
|
+
[]
|
|
102
|
+
),
|
|
103
|
+
})
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
prepend(tree, ...nodes);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// The function.length helper function must be placed last
|
|
111
|
+
if (this.functionLengthName) {
|
|
53
112
|
prepend(
|
|
54
113
|
tree,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
60
|
-
)
|
|
114
|
+
FunctionLengthTemplate.single({
|
|
115
|
+
name: this.functionLengthName,
|
|
116
|
+
ObjectDefineProperty: this.createInitVariable(ObjectDefineProperty, [
|
|
117
|
+
tree,
|
|
118
|
+
]),
|
|
119
|
+
})
|
|
61
120
|
);
|
|
62
121
|
}
|
|
63
122
|
}
|
|
@@ -141,6 +200,7 @@ export default class RGF extends Transform {
|
|
|
141
200
|
walk(object, parents, (o, p) => {
|
|
142
201
|
if (
|
|
143
202
|
o.type === "Identifier" &&
|
|
203
|
+
o.name !== this.arrayExpressionName &&
|
|
144
204
|
!reservedIdentifiers.has(o.name) &&
|
|
145
205
|
!this.options.globalVariables.has(o.name)
|
|
146
206
|
) {
|
|
@@ -200,6 +260,7 @@ export default class RGF extends Transform {
|
|
|
200
260
|
});
|
|
201
261
|
|
|
202
262
|
if (obfuscator.options.lock) {
|
|
263
|
+
obfuscator.options.lock = { ...obfuscator.options.lock };
|
|
203
264
|
delete obfuscator.options.lock.countermeasures;
|
|
204
265
|
|
|
205
266
|
// Integrity will not recursively apply to RGF'd functions. This is intended.
|
|
@@ -226,9 +287,26 @@ export default class RGF extends Transform {
|
|
|
226
287
|
generator: false,
|
|
227
288
|
};
|
|
228
289
|
|
|
290
|
+
// The new program will look like this
|
|
291
|
+
// new Function(`
|
|
292
|
+
// var rgf_array = this[0]
|
|
293
|
+
// function greet(message){
|
|
294
|
+
// console.log(message)
|
|
295
|
+
// }
|
|
296
|
+
// return greet.apply(this[1], arguments)
|
|
297
|
+
// `)
|
|
298
|
+
//
|
|
299
|
+
// And called like
|
|
300
|
+
// f.apply([ rgf_array, this ], arguments)
|
|
229
301
|
var tree = {
|
|
230
302
|
type: "Program",
|
|
231
303
|
body: [
|
|
304
|
+
VariableDeclaration(
|
|
305
|
+
VariableDeclarator(
|
|
306
|
+
this.arrayExpressionName,
|
|
307
|
+
MemberExpression(ThisExpression(), Literal(0))
|
|
308
|
+
)
|
|
309
|
+
),
|
|
232
310
|
embeddedFunction,
|
|
233
311
|
ReturnStatement(
|
|
234
312
|
CallExpression(
|
|
@@ -237,7 +315,10 @@ export default class RGF extends Transform {
|
|
|
237
315
|
Literal("apply"),
|
|
238
316
|
true
|
|
239
317
|
),
|
|
240
|
-
[
|
|
318
|
+
[
|
|
319
|
+
MemberExpression(ThisExpression(), Literal(1)),
|
|
320
|
+
Identifier("arguments"),
|
|
321
|
+
]
|
|
241
322
|
)
|
|
242
323
|
),
|
|
243
324
|
],
|
|
@@ -250,10 +331,18 @@ export default class RGF extends Transform {
|
|
|
250
331
|
var toString = compileJsSync(tree, obfuscator.options);
|
|
251
332
|
|
|
252
333
|
// new Function(code)
|
|
253
|
-
var newFunctionExpression = NewExpression(Identifier("Function"), [
|
|
334
|
+
var newFunctionExpression: Node = NewExpression(Identifier("Function"), [
|
|
254
335
|
Literal(toString),
|
|
255
336
|
]);
|
|
256
337
|
|
|
338
|
+
if (this.options.lock?.tamperProtection) {
|
|
339
|
+
// If tamper protection is enabled, wrap the function in an eval
|
|
340
|
+
var randomName = this.getGenerator("randomized").generate();
|
|
341
|
+
newFunctionExpression = CallExpression(Identifier("eval"), [
|
|
342
|
+
Literal(`function ${randomName}(){ ${toString} } ${randomName}`),
|
|
343
|
+
]);
|
|
344
|
+
}
|
|
345
|
+
|
|
257
346
|
// The index where this function is placed in the array
|
|
258
347
|
var newFunctionExpressionIndex = this.arrayExpressionElements.length;
|
|
259
348
|
|
|
@@ -261,12 +350,14 @@ export default class RGF extends Transform {
|
|
|
261
350
|
this.arrayExpressionElements.push(newFunctionExpression);
|
|
262
351
|
|
|
263
352
|
// The member expression to retrieve this function
|
|
264
|
-
var memberExpression = MemberExpression(
|
|
353
|
+
var memberExpression: Node = MemberExpression(
|
|
265
354
|
Identifier(this.arrayExpressionName),
|
|
266
355
|
Literal(newFunctionExpressionIndex),
|
|
267
356
|
true
|
|
268
357
|
);
|
|
269
358
|
|
|
359
|
+
var originalFunctionLength = computeFunctionLength(object.params);
|
|
360
|
+
|
|
270
361
|
// Replace based on type
|
|
271
362
|
|
|
272
363
|
// (1) Function Declaration:
|
|
@@ -276,19 +367,55 @@ export default class RGF extends Transform {
|
|
|
276
367
|
ReturnStatement(
|
|
277
368
|
CallExpression(
|
|
278
369
|
MemberExpression(memberExpression, Literal("apply"), true),
|
|
279
|
-
[
|
|
370
|
+
[
|
|
371
|
+
ArrayExpression([
|
|
372
|
+
Identifier(this.arrayExpressionName),
|
|
373
|
+
ThisExpression(),
|
|
374
|
+
]),
|
|
375
|
+
Identifier("arguments"),
|
|
376
|
+
]
|
|
280
377
|
)
|
|
281
378
|
),
|
|
282
379
|
]);
|
|
283
380
|
|
|
284
381
|
// The parameters are no longer needed ('arguments' is used to capture them)
|
|
285
382
|
object.params = [];
|
|
383
|
+
|
|
384
|
+
// The function is no longer guaranteed to not have extraneous parameters passed in
|
|
385
|
+
object[predictableFunctionTag] = false;
|
|
386
|
+
|
|
387
|
+
if (
|
|
388
|
+
this.options.preserveFunctionLength &&
|
|
389
|
+
originalFunctionLength !== 0
|
|
390
|
+
) {
|
|
391
|
+
var body = parents[0] as unknown as Node[];
|
|
392
|
+
|
|
393
|
+
body.splice(
|
|
394
|
+
body.indexOf(object),
|
|
395
|
+
0,
|
|
396
|
+
ExpressionStatement(
|
|
397
|
+
CallExpression(Identifier(this.getFunctionLengthName(parents)), [
|
|
398
|
+
Identifier(object.id.name),
|
|
399
|
+
Literal(originalFunctionLength),
|
|
400
|
+
])
|
|
401
|
+
)
|
|
402
|
+
);
|
|
403
|
+
}
|
|
286
404
|
return;
|
|
287
405
|
}
|
|
288
406
|
|
|
289
407
|
// (2) Function Expression:
|
|
290
408
|
// - Replace expression with member expression pointing to new function
|
|
291
409
|
if (object.type === "FunctionExpression") {
|
|
410
|
+
if (
|
|
411
|
+
this.options.preserveFunctionLength &&
|
|
412
|
+
originalFunctionLength !== 0
|
|
413
|
+
) {
|
|
414
|
+
memberExpression = CallExpression(
|
|
415
|
+
Identifier(this.getFunctionLengthName(parents)),
|
|
416
|
+
[memberExpression, Literal(originalFunctionLength)]
|
|
417
|
+
);
|
|
418
|
+
}
|
|
292
419
|
this.replace(object, memberExpression);
|
|
293
420
|
return;
|
|
294
421
|
}
|
|
@@ -37,7 +37,7 @@ var Hash = function (s) {
|
|
|
37
37
|
return ~~String(a).slice(0, 3);
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
var HashTemplate = Template(
|
|
40
|
+
var HashTemplate = new Template(
|
|
41
41
|
`
|
|
42
42
|
var {name} = function(arr) {
|
|
43
43
|
var s = arr.map(x=>x+"").join(''), a = 1, c = 0, h, o;
|
|
@@ -68,7 +68,7 @@ export default class Shuffle extends Transform {
|
|
|
68
68
|
match(object, parents) {
|
|
69
69
|
return (
|
|
70
70
|
object.type == "ArrayExpression" &&
|
|
71
|
-
!parents.find((x) => x.$
|
|
71
|
+
!parents.find((x) => x.$multiTransformSkip)
|
|
72
72
|
);
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -168,7 +168,7 @@ export default class Shuffle extends Transform {
|
|
|
168
168
|
if (mode !== "hash") {
|
|
169
169
|
var varPrefix = this.getPlaceholder();
|
|
170
170
|
code.push(
|
|
171
|
-
Template(`
|
|
171
|
+
new Template(`
|
|
172
172
|
for ( var ${varPrefix}x = 16; ${varPrefix}x%4 === 0; ${varPrefix}x++) {
|
|
173
173
|
var ${varPrefix}z = 0;
|
|
174
174
|
${
|
package/src/transforms/stack.ts
CHANGED
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
RestElement,
|
|
17
17
|
ReturnStatement,
|
|
18
18
|
SequenceExpression,
|
|
19
|
+
VariableDeclaration,
|
|
20
|
+
VariableDeclarator,
|
|
19
21
|
} from "../util/gen";
|
|
20
22
|
import { getIdentifierInfo } from "../util/identifiers";
|
|
21
23
|
import {
|
|
@@ -32,6 +34,8 @@ import { chance, choice, getRandomInteger } from "../util/random";
|
|
|
32
34
|
import Transform from "./transform";
|
|
33
35
|
import { noRenameVariablePrefix } from "../constants";
|
|
34
36
|
import { FunctionLengthTemplate } from "../templates/functionLength";
|
|
37
|
+
import { ObjectDefineProperty } from "../templates/globals";
|
|
38
|
+
import { isJSConfuserVar } from "../util/guard";
|
|
35
39
|
|
|
36
40
|
export default class Stack extends Transform {
|
|
37
41
|
mangledExpressionsMade: number;
|
|
@@ -49,7 +53,7 @@ export default class Stack extends Transform {
|
|
|
49
53
|
isFunction(object) &&
|
|
50
54
|
!object.params.find((x) => x.type !== "Identifier") &&
|
|
51
55
|
object.body.type === "BlockStatement" &&
|
|
52
|
-
!parents.find((x) => x.$
|
|
56
|
+
!parents.find((x) => x.$multiTransformSkip) &&
|
|
53
57
|
!object.$requiresEval
|
|
54
58
|
);
|
|
55
59
|
}
|
|
@@ -144,6 +148,11 @@ export default class Stack extends Transform {
|
|
|
144
148
|
illegal.add(o.name);
|
|
145
149
|
}
|
|
146
150
|
|
|
151
|
+
// Ignore __JS_CONFUSER_VAR__()
|
|
152
|
+
if (isJSConfuserVar(p)) {
|
|
153
|
+
illegal.add(o.name);
|
|
154
|
+
}
|
|
155
|
+
|
|
147
156
|
if (
|
|
148
157
|
info.isClauseParameter ||
|
|
149
158
|
info.isFunctionParameter ||
|
|
@@ -494,15 +503,21 @@ export default class Stack extends Transform {
|
|
|
494
503
|
// Ensure the array is correct length
|
|
495
504
|
prepend(
|
|
496
505
|
object.body,
|
|
497
|
-
Template(`${stackName}["length"] = ${startingSize}`).single()
|
|
506
|
+
new Template(`${stackName}["length"] = ${startingSize}`).single()
|
|
498
507
|
);
|
|
499
508
|
|
|
500
|
-
if (originalFunctionLength !== 0) {
|
|
509
|
+
if (this.options.preserveFunctionLength && originalFunctionLength !== 0) {
|
|
501
510
|
if (!this.functionLengthName) {
|
|
502
511
|
this.functionLengthName = this.getPlaceholder();
|
|
503
512
|
prepend(
|
|
504
513
|
parents[parents.length - 1] || object,
|
|
505
|
-
FunctionLengthTemplate.single({
|
|
514
|
+
FunctionLengthTemplate.single({
|
|
515
|
+
name: this.functionLengthName,
|
|
516
|
+
ObjectDefineProperty: this.createInitVariable(
|
|
517
|
+
ObjectDefineProperty,
|
|
518
|
+
parents
|
|
519
|
+
),
|
|
520
|
+
})
|
|
506
521
|
);
|
|
507
522
|
}
|
|
508
523
|
|
|
@@ -1,16 +1,48 @@
|
|
|
1
1
|
import Template from "../../templates/template";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
import { Literal } from "../../util/gen";
|
|
3
|
+
import { choice, shuffle } from "../../util/random";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Defines an encoding implementation the Obfuscator
|
|
7
|
+
*/
|
|
8
|
+
export interface EncodingImplementation {
|
|
9
|
+
identity: string;
|
|
10
|
+
|
|
11
|
+
encode(s: string): string;
|
|
12
|
+
decode(s: string): string;
|
|
13
|
+
template: Template;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let _hasAllEncodings = false;
|
|
17
|
+
export function hasAllEncodings() {
|
|
18
|
+
return _hasAllEncodings;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createEncodingImplementation(): EncodingImplementation {
|
|
22
|
+
if (_hasAllEncodings) {
|
|
23
|
+
return EncodingImplementations[
|
|
24
|
+
choice(Object.keys(EncodingImplementations))
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// create base91 encoding
|
|
29
|
+
let strTable =
|
|
30
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"';
|
|
31
|
+
|
|
32
|
+
// shuffle table
|
|
33
|
+
strTable = shuffle(strTable.split("")).join("");
|
|
34
|
+
|
|
35
|
+
let identity = "base91_" + strTable;
|
|
36
|
+
|
|
37
|
+
if (EncodingImplementations.hasOwnProperty(identity)) {
|
|
38
|
+
_hasAllEncodings = true;
|
|
39
|
+
return EncodingImplementations[identity];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var encodingImplementation = {
|
|
43
|
+
identity,
|
|
11
44
|
encode(str) {
|
|
12
|
-
const table =
|
|
13
|
-
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"';
|
|
45
|
+
const table = strTable;
|
|
14
46
|
|
|
15
47
|
const raw = Buffer.from(str, "utf-8");
|
|
16
48
|
const len = raw.length;
|
|
@@ -45,8 +77,7 @@ const Encoding: {
|
|
|
45
77
|
return ret;
|
|
46
78
|
},
|
|
47
79
|
decode(str) {
|
|
48
|
-
const table =
|
|
49
|
-
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"';
|
|
80
|
+
const table = strTable;
|
|
50
81
|
|
|
51
82
|
const raw = "" + (str || "");
|
|
52
83
|
const len = raw.length;
|
|
@@ -80,46 +111,54 @@ const Encoding: {
|
|
|
80
111
|
|
|
81
112
|
return Buffer.from(ret).toString("utf-8");
|
|
82
113
|
},
|
|
83
|
-
template: Template(`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
n
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
template: new Template(`
|
|
115
|
+
function {__fnName__}(str){
|
|
116
|
+
var table = {__strTable__};
|
|
117
|
+
|
|
118
|
+
var raw = "" + (str || "");
|
|
119
|
+
var len = raw.length;
|
|
120
|
+
var ret = [];
|
|
121
|
+
|
|
122
|
+
var b = 0;
|
|
123
|
+
var n = 0;
|
|
124
|
+
var v = -1;
|
|
125
|
+
|
|
126
|
+
for (var i = 0; i < len; i++) {
|
|
127
|
+
var p = table.indexOf(raw[i]);
|
|
128
|
+
if (p === -1) continue;
|
|
129
|
+
if (v < 0) {
|
|
130
|
+
v = p;
|
|
131
|
+
} else {
|
|
132
|
+
v += p * 91;
|
|
133
|
+
b |= v << n;
|
|
134
|
+
n += (v & 8191) > 88 ? 13 : 14;
|
|
135
|
+
do {
|
|
136
|
+
ret.push(b & 0xff);
|
|
137
|
+
b >>= 8;
|
|
138
|
+
n -= 8;
|
|
139
|
+
} while (n > 7);
|
|
140
|
+
v = -1;
|
|
141
|
+
}
|
|
111
142
|
}
|
|
143
|
+
|
|
144
|
+
if (v > -1) {
|
|
145
|
+
ret.push((b | (v << n)) & 0xff);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return {__bufferToString__}(ret);
|
|
112
149
|
}
|
|
150
|
+
`).setDefaultVariables({
|
|
151
|
+
__strTable__: Literal(strTable),
|
|
152
|
+
}),
|
|
153
|
+
};
|
|
113
154
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return {bufferToString}(ret);
|
|
119
|
-
}
|
|
120
|
-
`),
|
|
121
|
-
},
|
|
155
|
+
EncodingImplementations[identity] = encodingImplementation;
|
|
156
|
+
return encodingImplementation;
|
|
157
|
+
}
|
|
122
158
|
|
|
159
|
+
export const EncodingImplementations: {
|
|
160
|
+
[encodingIdentity: string]: EncodingImplementation;
|
|
161
|
+
} = {
|
|
123
162
|
/* ascii85: { This implementation is flaky and causes decoding errors
|
|
124
163
|
encode(a) {
|
|
125
164
|
var b, c, d, e, f, g, h, i, j, k;
|
|
@@ -209,5 +248,3 @@ const Encoding: {
|
|
|
209
248
|
`),
|
|
210
249
|
}, */
|
|
211
250
|
};
|
|
212
|
-
|
|
213
|
-
export default Encoding;
|
|
@@ -2,22 +2,36 @@ import { ok } from "assert";
|
|
|
2
2
|
import { ObfuscateOrder } from "../../order";
|
|
3
3
|
import { ComputeProbabilityMap } from "../../probability";
|
|
4
4
|
import Template from "../../templates/template";
|
|
5
|
-
import { isDirective } from "../../util/compare";
|
|
5
|
+
import { isDirective, isModuleSource } from "../../util/compare";
|
|
6
6
|
import {
|
|
7
|
+
AssignmentExpression,
|
|
8
|
+
BinaryExpression,
|
|
7
9
|
CallExpression,
|
|
10
|
+
ExpressionStatement,
|
|
8
11
|
FunctionDeclaration,
|
|
9
12
|
FunctionExpression,
|
|
10
13
|
Identifier,
|
|
14
|
+
IfStatement,
|
|
11
15
|
Literal,
|
|
12
16
|
MemberExpression,
|
|
17
|
+
ObjectExpression,
|
|
18
|
+
Property,
|
|
13
19
|
ReturnStatement,
|
|
14
20
|
VariableDeclaration,
|
|
15
21
|
VariableDeclarator,
|
|
16
22
|
} from "../../util/gen";
|
|
17
23
|
import { append, prepend } from "../../util/insert";
|
|
18
24
|
import Transform from "../transform";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
25
|
+
import { predictableFunctionTag } from "../../constants";
|
|
26
|
+
import {
|
|
27
|
+
chance,
|
|
28
|
+
choice,
|
|
29
|
+
getRandomFalseExpression,
|
|
30
|
+
getRandomInteger,
|
|
31
|
+
getRandomString,
|
|
32
|
+
splitIntoChunks,
|
|
33
|
+
} from "../../util/random";
|
|
34
|
+
|
|
21
35
|
function LZ_encode(c) {
|
|
22
36
|
ok(c);
|
|
23
37
|
var x = "charCodeAt",
|
|
@@ -58,7 +72,7 @@ function LZ_decode(b) {
|
|
|
58
72
|
return g.join("");
|
|
59
73
|
}
|
|
60
74
|
|
|
61
|
-
const DecodeTemplate = Template(
|
|
75
|
+
const DecodeTemplate = new Template(
|
|
62
76
|
`function {name}(b){
|
|
63
77
|
var o,
|
|
64
78
|
f,
|
|
@@ -94,7 +108,7 @@ export default class StringCompression extends Transform {
|
|
|
94
108
|
this.map = new Map();
|
|
95
109
|
this.ignore = new Set();
|
|
96
110
|
this.string = "";
|
|
97
|
-
this.fnName = this.getPlaceholder();
|
|
111
|
+
this.fnName = this.getPlaceholder() + predictableFunctionTag;
|
|
98
112
|
}
|
|
99
113
|
|
|
100
114
|
apply(tree) {
|
|
@@ -107,7 +121,7 @@ export default class StringCompression extends Transform {
|
|
|
107
121
|
|
|
108
122
|
var split = this.getPlaceholder();
|
|
109
123
|
var decoder = this.getPlaceholder();
|
|
110
|
-
var getStringName = this.getPlaceholder();
|
|
124
|
+
var getStringName = this.getPlaceholder() + predictableFunctionTag; // Returns the string payload
|
|
111
125
|
|
|
112
126
|
var encoded = LZ_encode(this.string);
|
|
113
127
|
if (LZ_decode(encoded) !== this.string) {
|
|
@@ -141,15 +155,72 @@ export default class StringCompression extends Transform {
|
|
|
141
155
|
)
|
|
142
156
|
);
|
|
143
157
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
158
|
+
var keys = new Set<string>();
|
|
159
|
+
var keysToMake = getRandomInteger(4, 14);
|
|
160
|
+
for (var i = 0; i < keysToMake; i++) {
|
|
161
|
+
keys.add(getRandomString(getRandomInteger(4, 14)));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
var objectExpression = ObjectExpression(
|
|
165
|
+
Array.from(keys).map((key) => {
|
|
166
|
+
return Property(Literal(key), getRandomFalseExpression(), true);
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// Get string function
|
|
171
|
+
var getStringBody = [];
|
|
172
|
+
var splits = splitIntoChunks(
|
|
173
|
+
encoded,
|
|
174
|
+
Math.floor(encoded.length / getRandomInteger(3, 6))
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
getStringBody.push(
|
|
178
|
+
VariableDeclaration(VariableDeclarator("str", Literal(splits.shift())))
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
getStringBody.push(
|
|
182
|
+
VariableDeclaration(VariableDeclarator("objectToTest", objectExpression))
|
|
151
183
|
);
|
|
152
184
|
|
|
185
|
+
const addIfStatement = (testingFor, literalValueToBeAppended) => {
|
|
186
|
+
getStringBody.push(
|
|
187
|
+
IfStatement(
|
|
188
|
+
BinaryExpression(
|
|
189
|
+
"in",
|
|
190
|
+
Literal(testingFor),
|
|
191
|
+
Identifier("objectToTest")
|
|
192
|
+
),
|
|
193
|
+
[
|
|
194
|
+
ExpressionStatement(
|
|
195
|
+
AssignmentExpression(
|
|
196
|
+
"+=",
|
|
197
|
+
Identifier("str"),
|
|
198
|
+
Literal(literalValueToBeAppended)
|
|
199
|
+
)
|
|
200
|
+
),
|
|
201
|
+
]
|
|
202
|
+
)
|
|
203
|
+
);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
for (const split of splits) {
|
|
207
|
+
if (chance(50)) {
|
|
208
|
+
var fakeKey;
|
|
209
|
+
do {
|
|
210
|
+
fakeKey = getRandomString(getRandomInteger(4, 14));
|
|
211
|
+
} while (keys.has(fakeKey) || fakeKey in {});
|
|
212
|
+
|
|
213
|
+
addIfStatement(fakeKey, getRandomString(split.length));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
addIfStatement(choice(Array.from(keys)), split);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Return computed string
|
|
220
|
+
getStringBody.push(ReturnStatement(Identifier("str")));
|
|
221
|
+
|
|
222
|
+
append(tree, FunctionDeclaration(getStringName, [], getStringBody));
|
|
223
|
+
|
|
153
224
|
append(
|
|
154
225
|
tree,
|
|
155
226
|
FunctionDeclaration(
|
|
@@ -176,7 +247,8 @@ export default class StringCompression extends Transform {
|
|
|
176
247
|
object.value &&
|
|
177
248
|
object.value.length > 3 &&
|
|
178
249
|
!isDirective(object, parents) &&
|
|
179
|
-
!isModuleSource(object, parents)
|
|
250
|
+
!isModuleSource(object, parents) &&
|
|
251
|
+
!parents.find((x) => x.$multiTransformSkip)
|
|
180
252
|
);
|
|
181
253
|
}
|
|
182
254
|
|
|
@@ -210,9 +282,6 @@ export default class StringCompression extends Transform {
|
|
|
210
282
|
return;
|
|
211
283
|
}
|
|
212
284
|
|
|
213
|
-
// HARD CODED LIMIT of 10,000 (after 1,000 elements)
|
|
214
|
-
if (this.map.size > 1000 && !chance(this.map.size / 100)) return;
|
|
215
|
-
|
|
216
285
|
var index = this.map.get(object.value);
|
|
217
286
|
|
|
218
287
|
// New string, add it!
|