js-confuser 1.5.7 → 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 +51 -0
- package/dist/index.js +45 -4
- package/dist/obfuscator.js +10 -5
- package/dist/options.js +6 -7
- package/dist/order.js +3 -3
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +16 -2
- 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/identifier/nameRecycling.js +8 -2
- package/dist/transforms/identifier/renameVariables.js +9 -0
- package/dist/transforms/lock/antiDebug.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 +77 -40
- package/dist/transforms/transform.js +1 -1
- package/dist/traverse.js +0 -8
- package/dist/util/compare.js +2 -2
- package/dist/util/insert.js +20 -6
- package/package.json +2 -2
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +6 -1
- package/src/options.ts +20 -6
- package/src/order.ts +3 -3
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +16 -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/identifier/nameRecycling.ts +14 -3
- package/src/transforms/identifier/renameVariables.ts +19 -0
- package/src/transforms/lock/antiDebug.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 +120 -56
- package/src/transforms/transform.ts +1 -1
- 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 +58 -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/nameRecycling.test.ts +39 -0
- package/test/transforms/identifier/renameVariables.test.ts +64 -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
|
@@ -330,3 +330,27 @@ it("should apply to every level of the code", async () => {
|
|
|
330
330
|
|
|
331
331
|
expect(value).toStrictEqual(100);
|
|
332
332
|
});
|
|
333
|
+
|
|
334
|
+
// https://github.com/MichaelXF/js-confuser/issues/77
|
|
335
|
+
it("should work with code that uses toString() function", async () => {
|
|
336
|
+
var output = await JsConfuser(
|
|
337
|
+
`
|
|
338
|
+
function myFunction(){
|
|
339
|
+
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
TEST_OUTPUT = toString();
|
|
343
|
+
`,
|
|
344
|
+
{
|
|
345
|
+
target: "node",
|
|
346
|
+
dispatcher: true,
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
var toString = () => "Correct Value";
|
|
351
|
+
var TEST_OUTPUT;
|
|
352
|
+
|
|
353
|
+
eval(output);
|
|
354
|
+
|
|
355
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
356
|
+
});
|
|
@@ -392,3 +392,36 @@ it("should work with stringConcealing and hide method names", async () => {
|
|
|
392
392
|
|
|
393
393
|
expect(TEST_VALUE).toStrictEqual(100);
|
|
394
394
|
});
|
|
395
|
+
|
|
396
|
+
// https://github.com/MichaelXF/js-confuser/issues/72
|
|
397
|
+
it("should support class fields", async () => {
|
|
398
|
+
var output = await JsConfuser(
|
|
399
|
+
`
|
|
400
|
+
class MyClass {
|
|
401
|
+
myField = 1;
|
|
402
|
+
["myComputedField"] = 2;
|
|
403
|
+
|
|
404
|
+
static myStaticField = 3;
|
|
405
|
+
static ["myComputedStaticField"] = 4;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
var myObject = new MyClass();
|
|
409
|
+
TEST_OUTPUT_1 = myObject.myField;
|
|
410
|
+
TEST_OUTPUT_2 = myObject.myComputedField;
|
|
411
|
+
TEST_OUTPUT_3 = MyClass.myStaticField;
|
|
412
|
+
TEST_OUTPUT_4 = MyClass.myComputedStaticField;
|
|
413
|
+
`,
|
|
414
|
+
{
|
|
415
|
+
target: "node",
|
|
416
|
+
es5: true,
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
var TEST_OUTPUT_1, TEST_OUTPUT_2, TEST_OUTPUT_3, TEST_OUTPUT_4;
|
|
421
|
+
|
|
422
|
+
eval(output);
|
|
423
|
+
expect(TEST_OUTPUT_1).toStrictEqual(1);
|
|
424
|
+
expect(TEST_OUTPUT_2).toStrictEqual(2);
|
|
425
|
+
expect(TEST_OUTPUT_3).toStrictEqual(3);
|
|
426
|
+
expect(TEST_OUTPUT_4).toStrictEqual(4);
|
|
427
|
+
});
|
|
@@ -76,3 +76,56 @@ it("should work with Integrity also enabled", async () => {
|
|
|
76
76
|
|
|
77
77
|
expect(value).toStrictEqual("Hello World");
|
|
78
78
|
});
|
|
79
|
+
|
|
80
|
+
it("should work on async functions", async () => {
|
|
81
|
+
var output = await JsConfuser(
|
|
82
|
+
`
|
|
83
|
+
async function myFunction(){
|
|
84
|
+
return "Correct Value";
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
(async ()=>{
|
|
88
|
+
TEST_FUNCTION( await myFunction() );
|
|
89
|
+
})();
|
|
90
|
+
`,
|
|
91
|
+
{ target: "node", eval: true }
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
expect(output).toContain("eval");
|
|
95
|
+
|
|
96
|
+
var wasCalled = false;
|
|
97
|
+
|
|
98
|
+
function TEST_FUNCTION(value) {
|
|
99
|
+
wasCalled = true;
|
|
100
|
+
expect(value).toStrictEqual("Correct Value");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
eval(output);
|
|
104
|
+
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
expect(wasCalled).toStrictEqual(true);
|
|
107
|
+
}, 1000);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("should work on generator functions", async () => {
|
|
111
|
+
var output = await JsConfuser(
|
|
112
|
+
`
|
|
113
|
+
function* myFunction(){
|
|
114
|
+
yield "Correct Value";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const gen = myFunction();
|
|
118
|
+
|
|
119
|
+
TEST_OUTPUT = gen.next().value;
|
|
120
|
+
`,
|
|
121
|
+
{ target: "node", eval: true }
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
expect(output).toContain("eval");
|
|
125
|
+
|
|
126
|
+
var TEST_OUTPUT;
|
|
127
|
+
|
|
128
|
+
eval(output);
|
|
129
|
+
|
|
130
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
131
|
+
});
|
|
@@ -446,3 +446,24 @@ it("should not apply to objects with non-init properties (method, set, get)", as
|
|
|
446
446
|
expect(output).toContain("TEST_OBJECT");
|
|
447
447
|
expect(output).toContain("set ");
|
|
448
448
|
});
|
|
449
|
+
|
|
450
|
+
// https://github.com/MichaelXF/js-confuser/issues/78
|
|
451
|
+
it("should handle objects with spread elements", async () => {
|
|
452
|
+
var output = await JsConfuser(
|
|
453
|
+
`
|
|
454
|
+
var x = { firstName: "John", lastName: "Doe" }
|
|
455
|
+
var y = { ...x };
|
|
456
|
+
|
|
457
|
+
TEST_OUTPUT = y;
|
|
458
|
+
`,
|
|
459
|
+
{
|
|
460
|
+
target: "node",
|
|
461
|
+
objectExtraction: true,
|
|
462
|
+
}
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
var TEST_OUTPUT;
|
|
466
|
+
eval(output);
|
|
467
|
+
|
|
468
|
+
expect(TEST_OUTPUT).toStrictEqual({ firstName: "John", lastName: "Doe" });
|
|
469
|
+
});
|
|
@@ -4,7 +4,7 @@ it("should bring independent to the global level", async () => {
|
|
|
4
4
|
var output = await JsConfuser.obfuscate(
|
|
5
5
|
`
|
|
6
6
|
function container(){
|
|
7
|
-
function nested(){
|
|
7
|
+
function nested(param){
|
|
8
8
|
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -17,7 +17,8 @@ it("should bring independent to the global level", async () => {
|
|
|
17
17
|
}
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// Ensure flatten was applied
|
|
21
|
+
expect(output).toContain("[param]");
|
|
21
22
|
});
|
|
22
23
|
|
|
23
24
|
it("should have correct return values", async () => {
|
|
@@ -255,7 +256,8 @@ it("should work when pattern-based assignment expressions are involved", async (
|
|
|
255
256
|
}
|
|
256
257
|
);
|
|
257
258
|
|
|
258
|
-
|
|
259
|
+
// Ensure flatten was applied
|
|
260
|
+
expect(output).toContain("[i],[]");
|
|
259
261
|
|
|
260
262
|
var value = "never_called",
|
|
261
263
|
input = (x) => (value = x);
|
|
@@ -263,3 +265,144 @@ it("should work when pattern-based assignment expressions are involved", async (
|
|
|
263
265
|
eval(output);
|
|
264
266
|
expect(value).toStrictEqual(1);
|
|
265
267
|
});
|
|
268
|
+
|
|
269
|
+
it("should work on async functions", async () => {
|
|
270
|
+
var output = await JsConfuser.obfuscate(
|
|
271
|
+
`
|
|
272
|
+
async function timeout(ms){
|
|
273
|
+
return await new Promise((resolve, reject)=>{
|
|
274
|
+
setTimeout(()=>{
|
|
275
|
+
resolve();
|
|
276
|
+
}, ms);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
(async ()=>{
|
|
281
|
+
var startTime = Date.now();
|
|
282
|
+
|
|
283
|
+
await timeout(1000);
|
|
284
|
+
|
|
285
|
+
var endTime = Date.now();
|
|
286
|
+
|
|
287
|
+
var duration = endTime - startTime;
|
|
288
|
+
|
|
289
|
+
TEST_CALLBACK(duration);
|
|
290
|
+
})();
|
|
291
|
+
`,
|
|
292
|
+
{
|
|
293
|
+
target: "node",
|
|
294
|
+
flatten: true,
|
|
295
|
+
}
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
expect(output).toContain("_flat_timeout");
|
|
299
|
+
|
|
300
|
+
var wasCalled = false;
|
|
301
|
+
var TEST_CALLBACK = (time) => {
|
|
302
|
+
expect(time).toBeGreaterThan(500);
|
|
303
|
+
wasCalled = true;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
eval(output);
|
|
307
|
+
|
|
308
|
+
setTimeout(() => {
|
|
309
|
+
expect(wasCalled).toStrictEqual(true);
|
|
310
|
+
}, 2000);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("should work on Function Expressions", async () => {
|
|
314
|
+
var output = await JsConfuser.obfuscate(
|
|
315
|
+
`
|
|
316
|
+
var outsideVar = "Correct Value";
|
|
317
|
+
|
|
318
|
+
var myFunctionExpression = function(){
|
|
319
|
+
return outsideVar;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
TEST_OUTPUT = myFunctionExpression();
|
|
323
|
+
`,
|
|
324
|
+
{
|
|
325
|
+
target: "node",
|
|
326
|
+
flatten: true,
|
|
327
|
+
}
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
// Ensure flatten applied
|
|
331
|
+
expect(output).toContain("_flat_myFunctionExpression");
|
|
332
|
+
|
|
333
|
+
var TEST_OUTPUT;
|
|
334
|
+
eval(output);
|
|
335
|
+
|
|
336
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it("should work on Properties", async () => {
|
|
340
|
+
var output = await JsConfuser.obfuscate(
|
|
341
|
+
`
|
|
342
|
+
var outsideVar = "Incorrect Value";
|
|
343
|
+
|
|
344
|
+
var myObject = {
|
|
345
|
+
myInitProperty: function(){
|
|
346
|
+
return outsideVar;
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
myMethodProperty(){
|
|
350
|
+
return;
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
get myGetProperty(){
|
|
354
|
+
return;
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
set mySetProperty(val){
|
|
358
|
+
outsideVar = val;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
myObject.mySetProperty = "Correct Value";
|
|
363
|
+
TEST_OUTPUT = myObject.myInitProperty();
|
|
364
|
+
`,
|
|
365
|
+
{
|
|
366
|
+
target: "node",
|
|
367
|
+
flatten: true,
|
|
368
|
+
}
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
// Ensure flatten applied
|
|
372
|
+
expect(output).toContain("_flat_myInitProperty");
|
|
373
|
+
|
|
374
|
+
var TEST_OUTPUT;
|
|
375
|
+
eval(output);
|
|
376
|
+
|
|
377
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it("should work with RGF enabled", async () => {
|
|
381
|
+
var output = await JsConfuser.obfuscate(
|
|
382
|
+
`
|
|
383
|
+
var outsideVar = "Correct Value";
|
|
384
|
+
|
|
385
|
+
function myFunction(){
|
|
386
|
+
return outsideVar;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
TEST_OUTPUT = myFunction();
|
|
390
|
+
`,
|
|
391
|
+
{
|
|
392
|
+
target: "node",
|
|
393
|
+
flatten: true,
|
|
394
|
+
rgf: true,
|
|
395
|
+
}
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
// Ensure flatten applied
|
|
399
|
+
expect(output).toContain("_flat_myFunction");
|
|
400
|
+
|
|
401
|
+
// Ensure RGF applied
|
|
402
|
+
expect(output).toContain("new Function");
|
|
403
|
+
|
|
404
|
+
var TEST_OUTPUT;
|
|
405
|
+
eval(output);
|
|
406
|
+
|
|
407
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
408
|
+
});
|
|
@@ -164,3 +164,42 @@ it("should convert variable declarations in for loop initializers properly", asy
|
|
|
164
164
|
expect(TEST_VAR_1).toStrictEqual("Hello World");
|
|
165
165
|
expect(TEST_VAR_2).toStrictEqual("Number: 0");
|
|
166
166
|
});
|
|
167
|
+
|
|
168
|
+
// https://github.com/MichaelXF/js-confuser/issues/68
|
|
169
|
+
it("should work on Function Declarations that are defined later in the code", async () => {
|
|
170
|
+
var output = await JsConfuser(
|
|
171
|
+
`
|
|
172
|
+
var result = MyFunction();
|
|
173
|
+
TEST_VAR = result;
|
|
174
|
+
|
|
175
|
+
function MyFunction(b) {
|
|
176
|
+
return "Hello World";
|
|
177
|
+
}
|
|
178
|
+
`,
|
|
179
|
+
{ target: "node", nameRecycling: true }
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
var TEST_VAR;
|
|
183
|
+
eval(output);
|
|
184
|
+
|
|
185
|
+
expect(TEST_VAR).toStrictEqual("Hello World");
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// https://github.com/MichaelXF/js-confuser/issues/71
|
|
189
|
+
it("should work on Import Declarations", async () => {
|
|
190
|
+
var output = await JsConfuser(
|
|
191
|
+
`
|
|
192
|
+
import crypto from 'node:crypto'
|
|
193
|
+
|
|
194
|
+
var x = 1;
|
|
195
|
+
|
|
196
|
+
console.log(x);
|
|
197
|
+
`,
|
|
198
|
+
{
|
|
199
|
+
target: "node",
|
|
200
|
+
nameRecycling: true,
|
|
201
|
+
}
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
expect(output).not.toContain("crypto=");
|
|
205
|
+
});
|
|
@@ -436,3 +436,67 @@ test("Variant #18: Catch parameter and lexical variable clash", async () => {
|
|
|
436
436
|
|
|
437
437
|
eval(output);
|
|
438
438
|
});
|
|
439
|
+
|
|
440
|
+
// https://github.com/MichaelXF/js-confuser/issues/69
|
|
441
|
+
test("Variant #19: Don't break Import Declarations", async () => {
|
|
442
|
+
var output = await JsConfuser(
|
|
443
|
+
`
|
|
444
|
+
import { createHash } from 'node:crypto'
|
|
445
|
+
|
|
446
|
+
function sha256(content) {
|
|
447
|
+
return createHash('sha256').update(content).digest('hex')
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
TEST_OUTPUT = sha256("Hash this string");
|
|
451
|
+
`,
|
|
452
|
+
{
|
|
453
|
+
target: "node",
|
|
454
|
+
renameVariables: true,
|
|
455
|
+
}
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
// Ensure the createHash got renamed
|
|
459
|
+
expect(output).toContain("createHash as ");
|
|
460
|
+
|
|
461
|
+
// Convert to runnable code
|
|
462
|
+
// This smartly changes the `import` statement to a require call, keeping the new variable name intact
|
|
463
|
+
var newVarName = output.split("createHash as ")[1].split("}")[0];
|
|
464
|
+
output = output
|
|
465
|
+
.split(";")
|
|
466
|
+
.filter((s) => !s.startsWith("import"))
|
|
467
|
+
.join(";");
|
|
468
|
+
output = `var {createHash: ${newVarName}}=require('crypto');` + output;
|
|
469
|
+
|
|
470
|
+
var TEST_OUTPUT;
|
|
471
|
+
eval(output);
|
|
472
|
+
|
|
473
|
+
expect(TEST_OUTPUT).toStrictEqual(
|
|
474
|
+
"1cac63f39fd68d8c531f27b807610fb3d50f0fc3f186995767fb6316e7200a3e"
|
|
475
|
+
);
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
// https://github.com/MichaelXF/js-confuser/issues/80
|
|
479
|
+
test("Variant #20: Don't break code with var and let variables in same scope", async () => {
|
|
480
|
+
var output = await JsConfuser(
|
|
481
|
+
`
|
|
482
|
+
function log(param) {
|
|
483
|
+
let message = param;
|
|
484
|
+
var isWarning = false;
|
|
485
|
+
var isError = false;
|
|
486
|
+
|
|
487
|
+
TEST_OUTPUT = message;
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
log("Correct Value");
|
|
491
|
+
`,
|
|
492
|
+
{
|
|
493
|
+
target: "node",
|
|
494
|
+
renameVariables: true,
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
var TEST_OUTPUT;
|
|
499
|
+
eval(output);
|
|
500
|
+
|
|
501
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
502
|
+
});
|
|
@@ -269,6 +269,7 @@ test("Variant #15: Removing implied 'return'", async () => {
|
|
|
269
269
|
function MyFunction(){
|
|
270
270
|
var output = "Hello World";
|
|
271
271
|
console.log(output);
|
|
272
|
+
this; // Stop arrow function conversion
|
|
272
273
|
return;
|
|
273
274
|
}
|
|
274
275
|
|
|
@@ -366,3 +367,68 @@ test("Variant #19: Remove unreachable code following a throw statement", async (
|
|
|
366
367
|
|
|
367
368
|
expect(output).not.toContain("unreachableStmt");
|
|
368
369
|
});
|
|
370
|
+
|
|
371
|
+
// https://github.com/MichaelXF/js-confuser/issues/76
|
|
372
|
+
test("Variant #20: Properly handle objects with `, ^, [, ] as keys", async () => {
|
|
373
|
+
var output = await JsConfuser(
|
|
374
|
+
`
|
|
375
|
+
TEST_OBJECT = {
|
|
376
|
+
"\`": true,
|
|
377
|
+
"^": true,
|
|
378
|
+
"]": true,
|
|
379
|
+
"[": true
|
|
380
|
+
};
|
|
381
|
+
`,
|
|
382
|
+
{
|
|
383
|
+
target: "node",
|
|
384
|
+
minify: true,
|
|
385
|
+
}
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
var TEST_OBJECT;
|
|
389
|
+
eval(output);
|
|
390
|
+
|
|
391
|
+
expect(TEST_OBJECT).toStrictEqual({
|
|
392
|
+
"`": true,
|
|
393
|
+
"^": true,
|
|
394
|
+
"]": true,
|
|
395
|
+
"[": true,
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// https://github.com/MichaelXF/js-confuser/issues/75
|
|
400
|
+
test("Variant #21: Properly handle Object constructor (Function Declaration)", async () => {
|
|
401
|
+
var output = await JsConfuser(
|
|
402
|
+
`
|
|
403
|
+
function MyClass() {};
|
|
404
|
+
|
|
405
|
+
var myObject = new MyClass();
|
|
406
|
+
|
|
407
|
+
TEST_OUTPUT = myObject instanceof MyClass;
|
|
408
|
+
`,
|
|
409
|
+
{ target: "node", minify: true }
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
var TEST_OUTPUT = false;
|
|
413
|
+
eval(output);
|
|
414
|
+
|
|
415
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
test("Variant #22: Properly handle Object constructor (Function Expression)", async () => {
|
|
419
|
+
var output = await JsConfuser(
|
|
420
|
+
`
|
|
421
|
+
var MyClass = function() {};
|
|
422
|
+
|
|
423
|
+
var myObject = new MyClass();
|
|
424
|
+
|
|
425
|
+
TEST_OUTPUT = myObject instanceof MyClass;
|
|
426
|
+
`,
|
|
427
|
+
{ target: "node", minify: true }
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
var TEST_OUTPUT = false;
|
|
431
|
+
eval(output);
|
|
432
|
+
|
|
433
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
434
|
+
});
|
|
@@ -288,6 +288,62 @@ input(console.log, result)
|
|
|
288
288
|
|
|
289
289
|
expect(output).not.toContain("new Function");
|
|
290
290
|
});
|
|
291
|
+
|
|
292
|
+
it("should work with Control Flow Flattening and Duplicate Literals Removal enabled", async () => {
|
|
293
|
+
var output = await JsConfuser.obfuscate(
|
|
294
|
+
`
|
|
295
|
+
var x = [1,1,1,1,1,1,1,1,1,1];
|
|
296
|
+
|
|
297
|
+
function myFunction(){
|
|
298
|
+
return 1;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
input( myFunction() ); // 1
|
|
302
|
+
`,
|
|
303
|
+
{
|
|
304
|
+
target: "node",
|
|
305
|
+
controlFlowFlattening: true,
|
|
306
|
+
duplicateLiteralsRemoval: true,
|
|
307
|
+
rgf: true,
|
|
308
|
+
}
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
var value = "never_called";
|
|
312
|
+
function input(valueIn) {
|
|
313
|
+
value = valueIn;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
eval(output);
|
|
317
|
+
|
|
318
|
+
expect(value).toStrictEqual(1);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
it("should work with String Encoding enabled", async () => {
|
|
322
|
+
var output = await JsConfuser.obfuscate(
|
|
323
|
+
`
|
|
324
|
+
function myFunction(){
|
|
325
|
+
var val1 = "\\x43\\x6F\\x72\\x72\\x65\\x63\\x74\\x20\\x56\\x61\\x6C\\x75\\x65"; // "Correct Value"
|
|
326
|
+
var val2 = "Correct Value";
|
|
327
|
+
return val1 === val2;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
TEST_OUTPUT = myFunction(); // true
|
|
331
|
+
`,
|
|
332
|
+
{
|
|
333
|
+
target: "node",
|
|
334
|
+
rgf: true,
|
|
335
|
+
stringEncoding: true,
|
|
336
|
+
}
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
// Ensure RGF applied
|
|
340
|
+
expect(output).toContain("new Function");
|
|
341
|
+
|
|
342
|
+
var TEST_OUTPUT;
|
|
343
|
+
eval(output);
|
|
344
|
+
|
|
345
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
346
|
+
});
|
|
291
347
|
});
|
|
292
348
|
|
|
293
349
|
describe("RGF with the 'all' mode", () => {
|
|
@@ -182,3 +182,36 @@ it("should not encode constructor key", async () => {
|
|
|
182
182
|
|
|
183
183
|
expect(TEST_VAR).toStrictEqual(100);
|
|
184
184
|
});
|
|
185
|
+
|
|
186
|
+
// https://github.com/MichaelXF/js-confuser/issues/82
|
|
187
|
+
it("should work inside the Class Constructor function", async () => {
|
|
188
|
+
var code = `
|
|
189
|
+
class MyClass1 {}
|
|
190
|
+
class MyClass2 extends MyClass1 {
|
|
191
|
+
constructor(){
|
|
192
|
+
super();
|
|
193
|
+
this["myString1"] = true;
|
|
194
|
+
this["myString2"] = true;
|
|
195
|
+
this["myString3"] = true;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
var instance = new MyClass2();
|
|
200
|
+
|
|
201
|
+
TEST_OUTPUT = instance.myString1 === true; // true
|
|
202
|
+
`;
|
|
203
|
+
|
|
204
|
+
var output = await JsConfuser(code, {
|
|
205
|
+
target: "node",
|
|
206
|
+
stringConcealing: true,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Ensure the strings got encrypted properly
|
|
210
|
+
expect(output).not.toContain("myString");
|
|
211
|
+
|
|
212
|
+
// Ensure the code works
|
|
213
|
+
var TEST_OUTPUT = false;
|
|
214
|
+
eval(output);
|
|
215
|
+
|
|
216
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
217
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isEquivalent } from "../../src/util/compare";
|
|
1
|
+
import { isEquivalent, isValidIdentifier } from "../../src/util/compare";
|
|
2
2
|
import { Identifier } from "../../src/util/gen";
|
|
3
3
|
|
|
4
4
|
it("should compare nodes correctly", () => {
|
|
@@ -10,3 +10,25 @@ it("should compare nodes correctly", () => {
|
|
|
10
10
|
isEquivalent(Identifier("name"), Identifier("different_name"))
|
|
11
11
|
).toStrictEqual(false);
|
|
12
12
|
});
|
|
13
|
+
|
|
14
|
+
describe("isValidIdentifier", () => {
|
|
15
|
+
test("Variant #1: Basic examples", () => {
|
|
16
|
+
// true examples
|
|
17
|
+
expect(isValidIdentifier("myClass")).toStrictEqual(true);
|
|
18
|
+
expect(isValidIdentifier("MyClass")).toStrictEqual(true);
|
|
19
|
+
expect(isValidIdentifier("$myObject")).toStrictEqual(true);
|
|
20
|
+
expect(isValidIdentifier("_myObject")).toStrictEqual(true);
|
|
21
|
+
expect(isValidIdentifier("myObject2")).toStrictEqual(true);
|
|
22
|
+
expect(isValidIdentifier("_0")).toStrictEqual(true);
|
|
23
|
+
|
|
24
|
+
// false examples
|
|
25
|
+
expect(isValidIdentifier("0")).toStrictEqual(false);
|
|
26
|
+
expect(isValidIdentifier("0myInvalidVar")).toStrictEqual(false);
|
|
27
|
+
expect(isValidIdentifier("^")).toStrictEqual(false);
|
|
28
|
+
expect(isValidIdentifier("%")).toStrictEqual(false);
|
|
29
|
+
expect(isValidIdentifier("invalid*Var")).toStrictEqual(false);
|
|
30
|
+
expect(isValidIdentifier("invalid!")).toStrictEqual(false);
|
|
31
|
+
expect(isValidIdentifier("my invalid var")).toStrictEqual(false);
|
|
32
|
+
expect(isValidIdentifier("my-invalid-var")).toStrictEqual(false);
|
|
33
|
+
});
|
|
34
|
+
});
|