js-confuser 1.5.9 → 1.7.0

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.
Files changed (143) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +55 -0
  3. package/README.md +346 -165
  4. package/dist/constants.js +6 -2
  5. package/dist/index.js +9 -21
  6. package/dist/obfuscator.js +19 -31
  7. package/dist/options.js +5 -5
  8. package/dist/order.js +1 -3
  9. package/dist/presets.js +6 -7
  10. package/dist/probability.js +2 -4
  11. package/dist/templates/bufferToString.js +13 -0
  12. package/dist/templates/crash.js +3 -3
  13. package/dist/templates/es5.js +18 -0
  14. package/dist/templates/functionLength.js +16 -0
  15. package/dist/transforms/calculator.js +77 -21
  16. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  17. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -1
  18. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  19. package/dist/transforms/deadCode.js +33 -25
  20. package/dist/transforms/dispatcher.js +8 -4
  21. package/dist/transforms/es5/antiDestructuring.js +2 -0
  22. package/dist/transforms/es5/es5.js +31 -34
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +92 -58
  24. package/dist/transforms/finalizer.js +82 -0
  25. package/dist/transforms/flatten.js +229 -148
  26. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  27. package/dist/transforms/identifier/globalConcealing.js +10 -83
  28. package/dist/transforms/identifier/movedDeclarations.js +35 -88
  29. package/dist/transforms/identifier/renameVariables.js +124 -59
  30. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  31. package/dist/transforms/lock/lock.js +0 -37
  32. package/dist/transforms/minify.js +60 -57
  33. package/dist/transforms/opaquePredicates.js +1 -1
  34. package/dist/transforms/preparation/preparation.js +2 -2
  35. package/dist/transforms/preparation.js +231 -0
  36. package/dist/transforms/renameLabels.js +1 -1
  37. package/dist/transforms/rgf.js +139 -247
  38. package/dist/transforms/stack.js +128 -26
  39. package/dist/transforms/string/encoding.js +150 -179
  40. package/dist/transforms/string/stringCompression.js +14 -15
  41. package/dist/transforms/string/stringConcealing.js +25 -8
  42. package/dist/transforms/string/stringEncoding.js +13 -24
  43. package/dist/transforms/transform.js +12 -19
  44. package/dist/traverse.js +24 -10
  45. package/dist/util/gen.js +17 -1
  46. package/dist/util/identifiers.js +37 -3
  47. package/dist/util/insert.js +35 -4
  48. package/dist/util/random.js +15 -0
  49. package/docs/ControlFlowFlattening.md +595 -0
  50. package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
  51. package/{Integrity.md → docs/Integrity.md} +2 -2
  52. package/docs/RGF.md +419 -0
  53. package/package.json +5 -5
  54. package/src/constants.ts +3 -0
  55. package/src/index.ts +2 -2
  56. package/src/obfuscator.ts +19 -31
  57. package/src/options.ts +14 -103
  58. package/src/order.ts +1 -5
  59. package/src/presets.ts +6 -7
  60. package/src/probability.ts +2 -3
  61. package/src/templates/bufferToString.ts +68 -0
  62. package/src/templates/crash.ts +15 -19
  63. package/src/templates/es5.ts +131 -0
  64. package/src/templates/functionLength.ts +14 -0
  65. package/src/transforms/calculator.ts +122 -59
  66. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  67. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +4 -1
  68. package/src/transforms/deadCode.ts +383 -26
  69. package/src/transforms/dispatcher.ts +9 -4
  70. package/src/transforms/es5/antiDestructuring.ts +2 -0
  71. package/src/transforms/es5/es5.ts +32 -77
  72. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +133 -129
  73. package/src/transforms/{hexadecimalNumbers.ts → finalizer.ts} +29 -13
  74. package/src/transforms/flatten.ts +357 -300
  75. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  76. package/src/transforms/identifier/globalConcealing.ts +14 -103
  77. package/src/transforms/identifier/movedDeclarations.ts +49 -102
  78. package/src/transforms/identifier/renameVariables.ts +149 -78
  79. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  80. package/src/transforms/lock/lock.ts +1 -42
  81. package/src/transforms/minify.ts +91 -75
  82. package/src/transforms/opaquePredicates.ts +2 -2
  83. package/src/transforms/preparation.ts +238 -0
  84. package/src/transforms/renameLabels.ts +2 -2
  85. package/src/transforms/rgf.ts +213 -405
  86. package/src/transforms/stack.ts +156 -36
  87. package/src/transforms/string/encoding.ts +115 -212
  88. package/src/transforms/string/stringCompression.ts +27 -18
  89. package/src/transforms/string/stringConcealing.ts +39 -9
  90. package/src/transforms/string/stringEncoding.ts +18 -18
  91. package/src/transforms/transform.ts +21 -23
  92. package/src/traverse.ts +23 -4
  93. package/src/types.ts +2 -1
  94. package/src/util/gen.ts +28 -3
  95. package/src/util/identifiers.ts +43 -2
  96. package/src/util/insert.ts +38 -3
  97. package/src/util/random.ts +13 -0
  98. package/test/code/Cash.test.ts +1 -1
  99. package/test/code/Dynamic.test.ts +12 -10
  100. package/test/code/ES6.src.js +146 -0
  101. package/test/code/ES6.test.ts +28 -2
  102. package/test/index.test.ts +2 -1
  103. package/test/probability.test.ts +44 -0
  104. package/test/templates/template.test.ts +1 -1
  105. package/test/transforms/antiTooling.test.ts +22 -0
  106. package/test/transforms/calculator.test.ts +40 -0
  107. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +702 -160
  108. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  109. package/test/transforms/deadCode.test.ts +66 -15
  110. package/test/transforms/dispatcher.test.ts +20 -1
  111. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  112. package/test/transforms/flatten.test.ts +399 -86
  113. package/test/transforms/identifier/movedDeclarations.test.ts +63 -8
  114. package/test/transforms/identifier/renameVariables.test.ts +119 -0
  115. package/test/transforms/lock/antiDebug.test.ts +2 -2
  116. package/test/transforms/lock/lock.test.ts +1 -48
  117. package/test/transforms/minify.test.ts +104 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +261 -381
  120. package/test/transforms/stack.test.ts +143 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +82 -0
  123. package/test/transforms/string/stringEncoding.test.ts +53 -2
  124. package/test/transforms/transform.test.ts +66 -0
  125. package/test/traverse.test.ts +139 -0
  126. package/test/util/identifiers.test.ts +113 -1
  127. package/test/util/insert.test.ts +57 -3
  128. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  129. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  130. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  131. package/src/transforms/eval.ts +0 -89
  132. package/src/transforms/hideInitializingCode.ts +0 -432
  133. package/src/transforms/identifier/nameRecycling.ts +0 -280
  134. package/src/transforms/label.ts +0 -64
  135. package/src/transforms/preparation/nameConflicts.ts +0 -102
  136. package/src/transforms/preparation/preparation.ts +0 -176
  137. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  138. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  139. package/test/transforms/eval.test.ts +0 -131
  140. package/test/transforms/hideInitializingCode.test.ts +0 -336
  141. package/test/transforms/identifier/nameRecycling.test.ts +0 -205
  142. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  143. package/test/transforms/preparation/preparation.test.ts +0 -62
@@ -1,448 +1,328 @@
1
1
  import { writeFileSync } from "fs";
2
2
  import JsConfuser from "../../src/index";
3
3
 
4
- describe("RGF", () => {
5
- it("should contain `new Function` in the output and work", async () => {
6
- var output = await JsConfuser.obfuscate(
7
- `
8
- function add(a,b){
9
- return a + b;
10
- }
11
-
12
- input(add(10, 5))
13
- `,
14
- {
15
- target: "node",
16
- rgf: true,
17
- }
18
- );
19
-
20
- expect(output).toContain("new Function");
21
- var value = "never_called";
22
- function input(valueIn) {
23
- value = valueIn;
4
+ test("Variant #1: Convert Function Declaration into 'new Function' code", async () => {
5
+ var output = await JsConfuser.obfuscate(
6
+ `
7
+ function addTwoNumbers(a, b){
8
+ return a + b;
24
9
  }
10
+
11
+ TEST_OUTPUT = addTwoNumbers(10, 5);
12
+ `,
13
+ {
14
+ target: "node",
15
+ rgf: true,
16
+ }
17
+ );
25
18
 
26
- eval(output);
27
- expect(value).toStrictEqual(15);
28
- });
19
+ expect(output).toContain("new Function");
29
20
 
30
- it("should work with multiple functions", async () => {
31
- var output = await JsConfuser.obfuscate(
32
- `
33
- function add(a,b){
34
- return a + b;
35
- }
36
-
37
- function parse(str){
38
- return parseInt(str);
39
- }
40
-
41
- input(add(parse("20"), 5))
42
- `,
43
- {
44
- target: "node",
45
- rgf: true,
46
- }
47
- );
21
+ var TEST_OUTPUT;
22
+ eval(output);
48
23
 
49
- expect(output).toContain("new Function");
50
- var value = "never_called";
51
- function input(valueIn) {
52
- value = valueIn;
53
- }
54
-
55
- eval(output);
56
- expect(value).toStrictEqual(25);
57
- });
24
+ expect(TEST_OUTPUT).toStrictEqual(15);
25
+ });
58
26
 
59
- it("should not change functions that have references to parent scopes", async () => {
60
- var output = await JsConfuser.obfuscate(
61
- `
62
- var parentScope = 0;
63
- function add(a,b){
27
+ test("Variant #2: Convert Function Expression into 'new Function' code", async () => {
28
+ var output = await JsConfuser.obfuscate(
29
+ `
30
+ var addTwoNumbers = function(a, b){
31
+ return a + b;
32
+ }
33
+
34
+ TEST_OUTPUT = addTwoNumbers(10, 5);
35
+ `,
36
+ {
37
+ target: "node",
38
+ rgf: true,
39
+ }
40
+ );
64
41
 
65
- // reference to parent scope
66
- return a + parentScope;
67
- }
68
-
69
- input(add(10, 5))
70
- `,
71
- {
72
- target: "node",
73
- rgf: true,
74
- }
75
- );
42
+ expect(output).toContain("new Function");
76
43
 
77
- expect(output).not.toContain("new Function");
78
- });
44
+ var TEST_OUTPUT;
45
+ eval(output);
79
46
 
80
- it("should not change functions that have mutate their parent scopes", async () => {
81
- var output = await JsConfuser.obfuscate(
82
- `
83
- var parentScope = 0;
84
- function add(a,b){
47
+ expect(TEST_OUTPUT).toStrictEqual(15);
48
+ });
85
49
 
86
- // modifies parent scope
87
- parentScope = 1;
88
- return a + b;
89
- }
90
-
91
- input(add(10, 5))
92
- `,
93
- {
94
- target: "node",
95
- rgf: true,
96
- }
97
- );
98
-
99
- expect(output).not.toContain("new Function");
100
- });
101
-
102
- it("should work with High Preset", async () => {
103
- var output = await JsConfuser.obfuscate(
104
- `
105
- function log2(){
106
- var inputFn = input;
107
- var inputString = "Hello World";
108
- inputFn(inputString)
50
+ test("Variant #3: Convert functions that use global variables", async () => {
51
+ var output = await JsConfuser.obfuscate(
52
+ `
53
+ function floorNumber(num){
54
+ return Math.floor(num);
109
55
  }
110
- log2()
56
+
57
+ TEST_OUTPUT = floorNumber(1.9);
111
58
  `,
112
- {
113
- target: "node",
114
- preset: "high",
115
- globalConcealing: false,
116
- }
117
- );
118
-
119
- var value = "never_called";
120
- function input(valueIn) {
121
- value = valueIn;
59
+ {
60
+ target: "node",
61
+ rgf: true,
122
62
  }
63
+ );
123
64
 
124
- eval(output);
125
-
126
- expect(value).toStrictEqual("Hello World");
127
- });
128
-
129
- it("should work with hideInitializingCode enabled", async () => {
130
- var output = await JsConfuser.obfuscate(
131
- `
132
- function abc(x, y){
133
- return x + y;
134
- }
135
-
136
- var result = abc(10, 50);
137
- input(console.log, result)
138
- `,
139
- {
140
- target: "node",
141
- identifierGenerator: "randomized",
142
- hideInitializingCode: true,
143
- rgf: true,
144
- compact: false,
145
- renameVariables: true,
146
- }
147
- );
65
+ expect(output).toContain("new Function");
66
+
67
+ var TEST_OUTPUT;
68
+ eval(output);
69
+
70
+ expect(TEST_OUTPUT).toStrictEqual(1);
71
+ });
72
+
73
+ test("Variant #4: Don't convert functions that rely on outside-scoped variables", async () => {
74
+ var output = await JsConfuser.obfuscate(
75
+ `
76
+ var _Math = Math;
148
77
 
149
- var value = "never_called";
150
- function input(_, valueIn) {
151
- value = valueIn;
78
+ function floorNumber(num){
79
+ return _Math.floor(num);
152
80
  }
81
+
82
+ TEST_OUTPUT = floorNumber(1.9);
83
+ `,
84
+ {
85
+ target: "node",
86
+ rgf: true,
87
+ }
88
+ );
153
89
 
154
- eval(output);
155
- expect(value).toStrictEqual(60);
156
- });
157
-
158
- // https://github.com/MichaelXF/js-confuser/issues/64
159
- it("should work on Arrow Functions", async () => {
160
- var output = await JsConfuser.obfuscate(
161
- `
162
- var double = (num)=>num*2;
163
- TEST_VALUE = double(10);
164
- `,
165
- {
166
- target: "node",
167
- rgf: true,
168
- }
169
- );
170
-
171
- expect(output).toContain("new Function");
172
-
173
- var TEST_VALUE;
174
-
175
- eval(output);
176
- expect(TEST_VALUE).toStrictEqual(20);
177
- });
178
-
179
- it("should work on Function Expressions", async () => {
180
- var output = await JsConfuser.obfuscate(
181
- `
182
- var double = function(num){
183
- return num * 2
184
- };
185
- TEST_VALUE = double(10);
186
- `,
187
- {
188
- target: "node",
189
- rgf: true,
190
- }
191
- );
90
+ expect(output).not.toContain("new Function");
192
91
 
193
- expect(output).toContain("new Function");
92
+ var TEST_OUTPUT;
93
+ eval(output);
194
94
 
195
- var TEST_VALUE;
95
+ expect(TEST_OUTPUT).toStrictEqual(1);
96
+ });
196
97
 
197
- eval(output);
198
- expect(TEST_VALUE).toStrictEqual(20);
199
- });
98
+ test("Variant #5: Don't convert functions that rely on outside-scoped variables (trap)", async () => {
99
+ var output = await JsConfuser.obfuscate(
100
+ `
101
+ var _Math = Math;
200
102
 
201
- it("should work on re-assigned functions", async () => {
202
- var output = await JsConfuser.obfuscate(
203
- `
204
- var fn1 = ()=>{
205
- return "FN1";
206
- }
207
- var fn2 = ()=>{
208
- fn1 = ()=>{
209
- return "FN1 - Modified"
210
- }
211
- }
212
- fn2();
213
- TEST_VALUE = fn1();
214
- `,
215
- {
216
- target: "node",
217
- rgf: true,
218
- }
219
- );
103
+ function floorNumber(num){
104
+ (()=>{
105
+ var _Math;
106
+ })();
107
+ return _Math.floor(num);
108
+ }
109
+
110
+ TEST_OUTPUT = floorNumber(1.9);
111
+ `,
112
+ {
113
+ target: "node",
114
+ rgf: true,
115
+ }
116
+ );
220
117
 
221
- expect(output).toContain("new Function");
118
+ expect(output).not.toContain("new Function");
222
119
 
223
- var TEST_VALUE;
120
+ var TEST_OUTPUT;
121
+ eval(output);
224
122
 
225
- eval(output);
226
- expect(TEST_VALUE).toStrictEqual("FN1 - Modified");
227
- });
123
+ expect(TEST_OUTPUT).toStrictEqual(1);
124
+ });
228
125
 
229
- it("should work on re-assigned functions to non-function values", async () => {
230
- var output = await JsConfuser.obfuscate(
231
- `
232
- var fn1 = ()=>{
233
- return "FN1";
234
- }
235
- var fn2 = ()=>{
236
- fn1 = undefined;
237
- }
238
- fn2();
239
- TEST_VALUE = typeof fn1;
240
- `,
241
- {
242
- target: "node",
243
- rgf: true,
244
- }
245
- );
126
+ test("Variant #6: Work on High Preset", async () => {
127
+ var output = await JsConfuser.obfuscate(
128
+ `
129
+ function addTwoNumbers(a, b){
130
+ return a + b;
131
+ }
132
+
133
+ TEST_OUTPUT = addTwoNumbers(10, 5);
134
+ `,
135
+ {
136
+ target: "node",
137
+ preset: "high",
138
+ rgf: true,
139
+ }
140
+ );
246
141
 
247
- expect(output).toContain("new Function");
142
+ var TEST_OUTPUT;
143
+ eval(output);
248
144
 
249
- var TEST_VALUE;
145
+ expect(TEST_OUTPUT).toStrictEqual(15);
146
+ });
250
147
 
251
- eval(output);
252
- expect(TEST_VALUE).toStrictEqual("undefined");
253
- });
148
+ test("Variant #7: Don't convert arrow, async, or generator functions", async () => {
149
+ var output = await JsConfuser.obfuscate(
150
+ `
151
+ var arrowFunction = ()=>{};
152
+ async function asyncFunction(){
254
153
 
255
- it("should not apply to functions that reference their parent scope in the parameters", async () => {
256
- var output = await JsConfuser.obfuscate(
257
- `
258
- var outsideVar = 0;
259
- function myFunction(insideVar = outsideVar){
260
- }
261
- `,
262
- {
263
- target: "node",
264
- rgf: true,
265
- }
266
- );
154
+ };
155
+ function* generatorFunction(){
156
+ yield "Correct Value";
157
+ };
267
158
 
268
- expect(output).not.toContain("new Function");
269
- });
159
+ TEST_OUTPUT = generatorFunction().next().value;
160
+ `,
161
+ {
162
+ target: "node",
163
+ rgf: true,
164
+ }
165
+ );
270
166
 
271
- it("should not apply to functions that reference their parent scope in previously defined names", async () => {
272
- var output = await JsConfuser.obfuscate(
273
- `
274
- var outsideVar = 0;
275
- function myFunction(){
276
- (function (){
277
- var outsideVar;
278
- })();
167
+ expect(output).not.toContain("new Function");
279
168
 
280
- console.log(outsideVar);
281
- }
282
- `,
283
- {
284
- target: "node",
285
- rgf: true,
286
- }
287
- );
169
+ var TEST_OUTPUT;
170
+ eval(output);
288
171
 
289
- expect(output).not.toContain("new Function");
290
- });
172
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
173
+ });
291
174
 
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];
175
+ test("Variant #8: Modified Function", async () => {
176
+ var output = await JsConfuser.obfuscate(
177
+ `
178
+ function addTwoNumbers(x,y){
179
+ return x + y;
180
+ }
296
181
 
297
- function myFunction(){
298
- return 1;
299
- };
182
+ addTwoNumbers = function(){
183
+ return "Incorrect Value";
184
+ }
300
185
 
301
- input( myFunction() ); // 1
302
- `,
303
- {
304
- target: "node",
305
- controlFlowFlattening: true,
306
- duplicateLiteralsRemoval: true,
307
- rgf: true,
308
- }
309
- );
186
+ addTwoNumbers = ()=>{
187
+ return "Correct Value";
188
+ }
310
189
 
311
- var value = "never_called";
312
- function input(valueIn) {
313
- value = valueIn;
190
+ TEST_OUTPUT = addTwoNumbers(10, 5);
191
+ `,
192
+ {
193
+ target: "node",
194
+ rgf: true,
314
195
  }
196
+ );
315
197
 
316
- eval(output);
198
+ expect(output).toContain("new Function");
317
199
 
318
- expect(value).toStrictEqual(1);
319
- });
200
+ var TEST_OUTPUT;
201
+ eval(output);
320
202
 
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
- }
203
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
204
+ });
205
+
206
+ test("Variant #8: Modified Function (non function value)", async () => {
207
+ var output = await JsConfuser.obfuscate(
208
+ `
209
+ function addTwoNumbers(x,y){
210
+ return x+y;
211
+ }
212
+
213
+ addTwoNumbers = "Correct Value";
329
214
 
330
- TEST_OUTPUT = myFunction(); // true
215
+ TEST_OUTPUT = addTwoNumbers;
331
216
  `,
332
- {
333
- target: "node",
334
- rgf: true,
335
- stringEncoding: true,
336
- }
337
- );
217
+ {
218
+ target: "node",
219
+ rgf: true,
220
+ }
221
+ );
338
222
 
339
- // Ensure RGF applied
340
- expect(output).toContain("new Function");
223
+ expect(output).toContain("new Function");
341
224
 
342
- var TEST_OUTPUT;
343
- eval(output);
225
+ var TEST_OUTPUT;
226
+ eval(output);
344
227
 
345
- expect(TEST_OUTPUT).toStrictEqual(true);
346
- });
228
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
347
229
  });
348
230
 
349
- describe("RGF with the 'all' mode", () => {
350
- it("should contain `new Function` in the output and work", async () => {
351
- var output = await JsConfuser.obfuscate(
352
- `
353
- function add(a,b){
354
- return a + b;
355
- }
356
-
357
- input(add(10, 5))
358
- `,
359
- {
360
- target: "node",
361
- rgf: "all",
231
+ test("Variant #9: Work with Flatten on any function", async () => {
232
+ var output = await JsConfuser.obfuscate(
233
+ `
234
+ var outsideCounter = 0;
235
+ var outsideFlag = false;
236
+
237
+ function incrementOutsideCounter(){
238
+ outsideCounter++;
239
+ }
240
+
241
+ function incrementTimes(times){
242
+ for( var i = 0; i < times; i++ ) {
243
+ incrementOutsideCounter();
362
244
  }
363
- );
245
+ if( outsideFlag ) {
246
+ TEST_OUTPUT = times === 1 && outsideCounter === 10 ? "Correct Value" : "Incorrect Value";
247
+ }
248
+ outsideFlag = true;
249
+ }
364
250
 
365
- expect(output).toContain("new Function");
366
- var value = "never_called";
367
- function input(valueIn) {
368
- value = valueIn;
251
+ incrementOutsideCounter();
252
+ incrementTimes(8);
253
+ incrementTimes(1);
254
+ `,
255
+ {
256
+ target: "node",
257
+ rgf: true,
258
+ flatten: true,
369
259
  }
260
+ );
370
261
 
371
- eval(output);
372
- expect(value).toStrictEqual(15);
373
- });
262
+ expect(output).toContain("new Function");
374
263
 
375
- it("should work with multiple functions", async () => {
376
- var output = await JsConfuser.obfuscate(
377
- `
378
- function add(a,b){
379
- return a + b;
380
- }
381
-
382
- function parse(str){
383
- return parseInt(str);
384
- }
385
-
386
- input(add(parse("20"), 5))
387
- `,
388
- {
389
- target: "node",
390
- rgf: "all",
391
- }
392
- );
264
+ var TEST_OUTPUT;
265
+ eval(output);
393
266
 
394
- expect(output).toContain("new Function");
395
- var value = "never_called";
396
- function input(valueIn) {
397
- value = valueIn;
267
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
268
+ });
269
+
270
+ test("Variant #10: Configurable by custom function option", async () => {
271
+ var functionNames: string[] = [];
272
+
273
+ var output = await JsConfuser(
274
+ `
275
+ "use strict";
276
+
277
+ // By checking strict-mode, we can check if the function was RGF or not
278
+ function rgfThisFunction(){
279
+ var isStrictMode = () => {
280
+ try {
281
+ undefined = true;
282
+ } catch (E) {
283
+ return true;
284
+ }
285
+ return false;
398
286
  }
399
287
 
400
- eval(output);
401
- expect(value).toStrictEqual(25);
402
- });
403
-
404
- it("should work with multiple, deeply-nested, functions", async () => {
405
- var output = await JsConfuser.obfuscate(
406
- `
407
-
408
- function getNumbers(){
409
- return [5, 10];
410
- }
411
-
412
- function multiply(x,y){
413
- return x*y;
414
- }
415
-
416
- function testFunction(){
417
- function add(x,y){
418
- return x+y;
288
+ return isStrictMode();
419
289
  }
420
290
 
421
- function testInnerFunction(){
422
- var numbers = getNumbers();
291
+ function doNotRgfThisFunction(){
292
+ var isStrictMode = () => {
293
+ try {
294
+ undefined = true;
295
+ } catch (E) {
296
+ return true;
297
+ }
298
+ return false;
299
+ }
423
300
 
424
- // 5*10 + 10 = 60
425
- return add(multiply(numbers[0], numbers[1]), numbers[1])
301
+ return isStrictMode();
426
302
  }
427
303
 
428
- input( testInnerFunction() );
429
- }
304
+ TEST_OUTPUT_1 = rgfThisFunction();
305
+ TEST_OUTPUT_2 = doNotRgfThisFunction();
306
+ `,
307
+ {
308
+ target: "node",
309
+ rgf: (name) => {
310
+ functionNames.push(name);
311
+ return name !== "doNotRgfThisFunction";
312
+ },
313
+ }
314
+ );
430
315
 
431
- testFunction();
432
- `,
433
- {
434
- target: "node",
435
- rgf: "all",
436
- }
437
- );
316
+ expect(functionNames).toStrictEqual([
317
+ "rgfThisFunction",
318
+ "doNotRgfThisFunction",
319
+ ]);
320
+ expect(output).toContain("new Function");
438
321
 
439
- expect(output).toContain("new Function");
440
- var value = "never_called";
441
- function input(valueIn) {
442
- value = valueIn;
443
- }
322
+ var TEST_OUTPUT_1;
323
+ var TEST_OUTPUT_2;
444
324
 
445
- eval(output);
446
- expect(value).toStrictEqual(60);
447
- });
325
+ eval(output);
326
+ expect(TEST_OUTPUT_1).toStrictEqual(false);
327
+ expect(TEST_OUTPUT_2).toStrictEqual(true);
448
328
  });