js-confuser 1.5.8 → 1.6.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 (139) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +69 -0
  3. package/README.md +143 -7
  4. package/dist/index.js +33 -4
  5. package/dist/obfuscator.js +30 -31
  6. package/dist/options.js +4 -5
  7. package/dist/order.js +4 -6
  8. package/dist/probability.js +2 -4
  9. package/dist/templates/bufferToString.js +13 -0
  10. package/dist/templates/crash.js +2 -2
  11. package/dist/templates/es5.js +18 -0
  12. package/dist/transforms/antiTooling.js +1 -1
  13. package/dist/transforms/calculator.js +77 -21
  14. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  15. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
  16. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  17. package/dist/transforms/deadCode.js +33 -25
  18. package/dist/transforms/dispatcher.js +7 -6
  19. package/dist/transforms/es5/antiClass.js +6 -2
  20. package/dist/transforms/es5/antiDestructuring.js +3 -1
  21. package/dist/transforms/es5/es5.js +31 -34
  22. package/dist/transforms/eval.js +11 -0
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
  24. package/dist/transforms/extraction/objectExtraction.js +6 -1
  25. package/dist/transforms/finalizer.js +82 -0
  26. package/dist/transforms/flatten.js +82 -55
  27. package/dist/transforms/hexadecimalNumbers.js +34 -9
  28. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  29. package/dist/transforms/identifier/globalConcealing.js +10 -83
  30. package/dist/transforms/identifier/movedDeclarations.js +2 -8
  31. package/dist/transforms/identifier/renameVariables.js +39 -27
  32. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  33. package/dist/transforms/minify.js +80 -61
  34. package/dist/transforms/opaquePredicates.js +1 -1
  35. package/dist/transforms/preparation/preparation.js +2 -2
  36. package/dist/transforms/preparation.js +231 -0
  37. package/dist/transforms/renameLabels.js +1 -1
  38. package/dist/transforms/rgf.js +4 -5
  39. package/dist/transforms/stack.js +87 -26
  40. package/dist/transforms/string/encoding.js +150 -179
  41. package/dist/transforms/string/stringCompression.js +14 -15
  42. package/dist/transforms/string/stringConcealing.js +25 -8
  43. package/dist/transforms/string/stringEncoding.js +13 -24
  44. package/dist/transforms/transform.js +11 -18
  45. package/dist/traverse.js +24 -18
  46. package/dist/util/compare.js +2 -2
  47. package/dist/util/gen.js +15 -0
  48. package/dist/util/insert.js +31 -7
  49. package/dist/util/random.js +15 -0
  50. package/package.json +5 -5
  51. package/src/index.ts +57 -19
  52. package/src/obfuscator.ts +26 -29
  53. package/src/options.ts +17 -21
  54. package/src/order.ts +4 -8
  55. package/src/probability.ts +2 -3
  56. package/src/templates/bufferToString.ts +68 -0
  57. package/src/templates/crash.ts +5 -9
  58. package/src/templates/es5.ts +131 -0
  59. package/src/transforms/antiTooling.ts +1 -1
  60. package/src/transforms/calculator.ts +122 -59
  61. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  62. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
  63. package/src/transforms/deadCode.ts +383 -26
  64. package/src/transforms/dispatcher.ts +8 -6
  65. package/src/transforms/es5/antiClass.ts +10 -1
  66. package/src/transforms/es5/antiDestructuring.ts +3 -1
  67. package/src/transforms/es5/es5.ts +32 -77
  68. package/src/transforms/eval.ts +18 -0
  69. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
  70. package/src/transforms/extraction/objectExtraction.ts +12 -5
  71. package/src/transforms/finalizer.ts +75 -0
  72. package/src/transforms/flatten.ts +194 -151
  73. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  74. package/src/transforms/identifier/globalConcealing.ts +14 -103
  75. package/src/transforms/identifier/movedDeclarations.ts +4 -11
  76. package/src/transforms/identifier/renameVariables.ts +37 -30
  77. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  78. package/src/transforms/minify.ts +116 -77
  79. package/src/transforms/opaquePredicates.ts +2 -2
  80. package/src/transforms/preparation.ts +238 -0
  81. package/src/transforms/renameLabels.ts +2 -2
  82. package/src/transforms/rgf.ts +6 -7
  83. package/src/transforms/stack.ts +97 -37
  84. package/src/transforms/string/encoding.ts +115 -212
  85. package/src/transforms/string/stringCompression.ts +27 -18
  86. package/src/transforms/string/stringConcealing.ts +41 -11
  87. package/src/transforms/string/stringEncoding.ts +18 -18
  88. package/src/transforms/transform.ts +15 -21
  89. package/src/traverse.ts +24 -12
  90. package/src/types.ts +11 -2
  91. package/src/util/compare.ts +2 -2
  92. package/src/util/gen.ts +21 -1
  93. package/src/util/insert.ts +49 -9
  94. package/src/util/random.ts +13 -0
  95. package/test/code/Cash.test.ts +1 -1
  96. package/test/code/Dynamic.test.ts +12 -10
  97. package/test/code/ES6.src.js +136 -0
  98. package/test/code/ES6.test.ts +28 -2
  99. package/test/code/NewFeatures.test.ts +19 -0
  100. package/test/index.test.ts +15 -2
  101. package/test/probability.test.ts +44 -0
  102. package/test/templates/template.test.ts +1 -1
  103. package/test/transforms/antiTooling.test.ts +52 -0
  104. package/test/transforms/calculator.test.ts +40 -0
  105. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
  106. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  107. package/test/transforms/deadCode.test.ts +66 -15
  108. package/test/transforms/dispatcher.test.ts +44 -1
  109. package/test/transforms/es5/antiClass.test.ts +33 -0
  110. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  111. package/test/transforms/eval.test.ts +53 -0
  112. package/test/transforms/extraction/objectExtraction.test.ts +21 -0
  113. package/test/transforms/flatten.test.ts +195 -3
  114. package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
  115. package/test/transforms/identifier/renameVariables.test.ts +108 -0
  116. package/test/transforms/lock/antiDebug.test.ts +2 -2
  117. package/test/transforms/minify.test.ts +151 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +56 -29
  120. package/test/transforms/stack.test.ts +91 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +115 -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/compare.test.ts +23 -1
  127. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  128. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  129. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  130. package/src/transforms/hexadecimalNumbers.ts +0 -31
  131. package/src/transforms/hideInitializingCode.ts +0 -432
  132. package/src/transforms/label.ts +0 -64
  133. package/src/transforms/preparation/nameConflicts.ts +0 -102
  134. package/src/transforms/preparation/preparation.ts +0 -176
  135. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  136. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  137. package/test/transforms/hideInitializingCode.test.ts +0 -336
  138. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  139. package/test/transforms/preparation/preparation.test.ts +0 -62
@@ -15,7 +15,7 @@ jobs:
15
15
 
16
16
  strategy:
17
17
  matrix:
18
- node-version: [10.x, 12.x, 14.x, 15.x]
18
+ node-version: [14.15, 16.10, 18.0]
19
19
  # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
20
20
 
21
21
  steps:
@@ -24,5 +24,5 @@ jobs:
24
24
  uses: actions/setup-node@v2
25
25
  with:
26
26
  node-version: ${{ matrix.node-version }}
27
- - run: npm ci
27
+ - run: npm install
28
28
  - run: npm test
package/CHANGELOG.md CHANGED
@@ -1,3 +1,72 @@
1
+ # `1.6.0`
2
+ Website Redesign + Updates
3
+
4
+ The website is now redesigned and live at [js-confuser.com](https://wwww.js-confuser.com)!
5
+
6
+ - Check out the source code for the website here: https://github.com/MichaelXF/js-confuser-website
7
+
8
+ #### New feature
9
+
10
+ ### `selfDefending`
11
+
12
+ Prevents the use of code beautifiers or formatters against your code.
13
+
14
+ [Identical to Obfuscator.io's Self Defending](https://github.com/javascript-obfuscator/javascript-obfuscator#selfdefending)
15
+
16
+ #### Improvements
17
+
18
+ - Fixed [#56](https://github.com/MichaelXF/js-confuser/issues/56)
19
+ - - Calculator improved to apply to more operators
20
+
21
+ - ES5 to handle destructuring member expressions
22
+
23
+ - Improved Control Flow Flattening techniques
24
+
25
+ - - Outlining expressions
26
+
27
+ - - Control object to store numbers and strings
28
+
29
+ - Updated the String concealing encoding algorithm
30
+
31
+ - Optimizations / Small fixes
32
+
33
+ # `1.5.9`
34
+ Big update
35
+
36
+ This updates comes with many bug fixes:
37
+
38
+ - Fixed [#72](https://github.com/MichaelXF/js-confuser/issues/72)
39
+ - - ES5 to handle Class Fields
40
+
41
+ Note: The `ES5` option is not meant to replace Babel. It is only intended to undo ES6 features the obfuscator may have added to your code.
42
+
43
+ - Fixed [#74](https://github.com/MichaelXF/js-confuser/issues/74)
44
+ - - Anti Tooling to not break Symbols
45
+
46
+ - Fixed [#75](https://github.com/MichaelXF/js-confuser/issues/75)
47
+ - - Minify to properly handle Object constructors
48
+
49
+ - Fixed [#76](https://github.com/MichaelXF/js-confuser/issues/76)
50
+ - - Minify to not cause syntax errors when objects used `^`, `` ` ``, `[`, `]` as property keys
51
+
52
+ - Fixed [#77](https://github.com/MichaelXF/js-confuser/issues/77)
53
+ - - Dispatcher to not break code that uses generic names like `toString` and `hasOwnProperty`
54
+
55
+ - Fixed [#78](https://github.com/MichaelXF/js-confuser/issues/78)
56
+ - - Object Extraction to not error on objects with spread elements
57
+
58
+ - Fixed [#79](https://github.com/MichaelXF/js-confuser/issues/79)
59
+ - - JsConfuser now supports `BigInt` literals
60
+
61
+ - Fixed [#80](https://github.com/MichaelXF/js-confuser/issues/80)
62
+ - - Rename Variables to not break code that had `var` and `let` variables in the same scope
63
+
64
+ - Fixed [#81](https://github.com/MichaelXF/js-confuser/issues/81)
65
+ - - Control Flow Flattening to not break `typeof` expressions
66
+
67
+ - Fixed [#82](https://github.com/MichaelXF/js-confuser/issues/82)
68
+ - - String Concealing to not break class constructors
69
+
1
70
  # `1.5.8`
2
71
  Several fixes
3
72
 
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # JS Confuser
2
2
 
3
- JS-Confuser is a JavaScript obfuscation tool to make your programs _impossible_ to read. [Try the web version](https://master--hungry-shannon-c1ce6b.netlify.app/).
3
+ JS-Confuser is a JavaScript obfuscation tool to make your programs _impossible_ to read. [Try the web version](https://js-confuser.com).
4
4
 
5
- [![NPM](https://img.shields.io/badge/NPM-%23000000.svg?style=for-the-badge&logo=npm&logoColor=white)](https://npmjs.com/package/js-confuser) [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/MichaelXF/js-confuser) [![Netlify](https://img.shields.io/badge/netlify-%23000000.svg?style=for-the-badge&logo=netlify&logoColor=#00C7B7)](https://master--hungry-shannon-c1ce6b.netlify.app/)
5
+ [![NPM](https://img.shields.io/badge/NPM-%23000000.svg?style=for-the-badge&logo=npm&logoColor=white)](https://npmjs.com/package/js-confuser) [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/MichaelXF/js-confuser) [![Netlify](https://img.shields.io/badge/netlify-%23000000.svg?style=for-the-badge&logo=netlify&logoColor=#00C7B7)](https://js-confuser.com)
6
6
 
7
7
  ## Key features
8
8
 
@@ -19,9 +19,9 @@ JS-Confuser comes with three presets built into the obfuscator.
19
19
 
20
20
  | Preset | Transforms | Performance Reduction | Sample |
21
21
  | --- | --- | --- | --- |
22
- | High | 21/22 | 98% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/high.js) |
23
- | Medium | 15/22 | 52% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/medium.js) |
24
- | Low | 10/22 | 30% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/low.js) |
22
+ | High | 22/25 | 98% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/high.js) |
23
+ | Medium | 19/25 | 52% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/medium.js) |
24
+ | Low | 15/25 | 30% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/low.js) |
25
25
 
26
26
  You can extend each preset or all go without them entirely.
27
27
 
@@ -109,7 +109,7 @@ JsConfuser.obfuscate(`<source code>`, {
109
109
  target: "node",
110
110
  preset: "high" // | "medium" | "low"
111
111
  }).then(obfuscated=>{
112
- console.log(obfuscated) // obfuscated is a string
112
+ console.log(obfuscated); // obfuscated is a string
113
113
  })
114
114
  ```
115
115
 
@@ -119,7 +119,7 @@ Remove's whitespace from the final output. Enabled by default. (`true/false`)
119
119
 
120
120
  ### `hexadecimalNumbers`
121
121
 
122
- Uses the hexadecimal representation (`50` -> `0x32`) for numbers. (`true/false`)
122
+ Uses the hexadecimal representation for numbers. (`true/false`)
123
123
 
124
124
  ### `minify`
125
125
 
@@ -219,6 +219,131 @@ Use a number to control the percentage from 0 to 1.
219
219
  - Resilience High
220
220
  - Cost High
221
221
 
222
+ ```js
223
+ // Input
224
+ function countTo(num){
225
+ for ( var i = 1; i <= num; i++ ) {
226
+ console.log(i);
227
+ }
228
+ }
229
+
230
+ var number = 10;
231
+ countTo(number); // 1,2,3,4,5,6,7,8,9,10
232
+
233
+ // Output
234
+ var n2DUka,
235
+ O7yZ0oU,
236
+ mJMdMhJ = -337,
237
+ A1Nyvv = -94,
238
+ xDwpOk6 = 495,
239
+ uKcJl2 = {
240
+ TGCpW6t: "log",
241
+ qUrjFe: function () {
242
+ return xDwpOk6 == (126 > mJMdMhJ ? -16 : 34);
243
+ },
244
+ YN20IBx: function () {
245
+ return (A1Nyvv -= 53);
246
+ },
247
+ CTW4vwx: -73,
248
+ PLzWYDx: function () {
249
+ return (O7yZ0oU = [[385, -94, -282], [10]]);
250
+ },
251
+ bW2FK2: function () {
252
+ return (mJMdMhJ *= 2), (mJMdMhJ += 366);
253
+ },
254
+ AfOoRT: function () {
255
+ return xDwpOk6 == xDwpOk6 + 867;
256
+ },
257
+ KTNMdj: function () {
258
+ if (uKcJl2.AfOoRT()) {
259
+ typeof ((mJMdMhJ += 0), uKcJl2.Q0I6e4f(), (xDwpOk6 += 0));
260
+ return "cobTe8G";
261
+ }
262
+ typeof (uKcJl2.htRXYx(),
263
+ (mJMdMhJ += 59),
264
+ (A1Nyvv -= 537),
265
+ (xDwpOk6 += uKcJl2.mLuSzZ < mJMdMhJ ? 449 : -33));
266
+ return "cobTe8G";
267
+ },
268
+ };
269
+ while (mJMdMhJ + A1Nyvv + xDwpOk6 != 83) {
270
+ var yQNDJh = (mJMdMhJ + A1Nyvv + xDwpOk6) * 58 + 54;
271
+ switch (yQNDJh) {
272
+ case 750:
273
+ if (A1Nyvv == 24) {
274
+ uKcJl2.FxREGd6();
275
+ break;
276
+ }
277
+ case 1214:
278
+ if (uKcJl2.qUrjFe()) {
279
+ typeof ((mJMdMhJ *= -8 > xDwpOk6 ? -109 : 2),
280
+ (mJMdMhJ += 1168),
281
+ (xDwpOk6 += xDwpOk6 - 1290));
282
+ break;
283
+ }
284
+ function _VSsIw() {
285
+ var [yQNDJh, _VSsIw] = O7yZ0oU,
286
+ [L9B14E] = _VSsIw,
287
+ uTyFFb = 322;
288
+ while (uTyFFb != 23) {
289
+ var cBx3ysg = uTyFFb * 48 - 77;
290
+ switch (cBx3ysg) {
291
+ case 15379:
292
+ var IOoqIZ = 1;
293
+ uTyFFb -= 306;
294
+ break;
295
+ case 691:
296
+ uTyFFb += IOoqIZ <= L9B14E ? 976 : 7;
297
+ break;
298
+ case 47539:
299
+ typeof (console[uKcJl2.TGCpW6t](IOoqIZ), (uTyFFb -= 795));
300
+ break;
301
+ case 9379:
302
+ !(IOoqIZ++, (uTyFFb -= 181));
303
+ }
304
+ }
305
+ return ([mJMdMhJ, A1Nyvv, xDwpOk6] = yQNDJh), (n2DUka = void 0);
306
+ }
307
+ (xDwpOk6 == -73 ? parseInt : _VSsIw)();
308
+ break;
309
+ case 576:
310
+ typeof (mJMdMhJ == -4 ? clearImmediate : void 0,
311
+ uKcJl2.bky8kL(),
312
+ (xDwpOk6 -= 463));
313
+ break;
314
+ case 4172:
315
+ var L9B14E = 10;
316
+ void ((O7yZ0oU = [[385, -94, -282], [10]]),
317
+ (mJMdMhJ -= 187),
318
+ uKcJl2.YN20IBx(),
319
+ (xDwpOk6 += 189));
320
+ break;
321
+ case 3766:
322
+ !((uKcJl2.Fpp8x5 = -167),
323
+ (uKcJl2.mLuSzZ = 144),
324
+ (uKcJl2.FxREGd6 = function () {
325
+ return (mJMdMhJ += uKcJl2.Fpp8x5), (xDwpOk6 += 164);
326
+ }),
327
+ (uKcJl2.bky8kL = function () {
328
+ return (A1Nyvv += 537);
329
+ }),
330
+ (uKcJl2.Q0I6e4f = function () {
331
+ return (A1Nyvv += 0);
332
+ }),
333
+ (uKcJl2.htRXYx = function () {
334
+ return (xDwpOk6 = -82);
335
+ }));
336
+ var L9B14E = 10;
337
+ void (uKcJl2.PLzWYDx(), uKcJl2.bW2FK2(), (xDwpOk6 += uKcJl2.CTW4vwx));
338
+ break;
339
+ default:
340
+ if (uKcJl2.KTNMdj() == "cobTe8G") {
341
+ break;
342
+ }
343
+ }
344
+ }
345
+ ```
346
+
222
347
  ### `globalConcealing`
223
348
 
224
349
  Global Concealing hides global variables being accessed. (`true/false`)
@@ -455,6 +580,16 @@ Set to `true` to use the default set of native functions. (`string[]/true/false`
455
580
  - Resilience Medium
456
581
  - Cost Medium
457
582
 
583
+ ### `lock.selfDefending`
584
+
585
+ Prevents the use of code beautifiers or formatters against your code.
586
+
587
+ [Identical to Obfuscator.io's Self Defending](https://github.com/javascript-obfuscator/javascript-obfuscator#selfdefending)
588
+
589
+ - Potency Low
590
+ - Resilience Low
591
+ - Cost Low
592
+
458
593
  ### `lock.integrity`
459
594
 
460
595
  Integrity ensures the source code is unchanged. (`true/false/0-1`)
@@ -623,6 +758,7 @@ You must enable locks yourself, and configure them to your needs.
623
758
  target: "node",
624
759
  lock: {
625
760
  integrity: true,
761
+ selfDefending: true,
626
762
  domainLock: ["mywebsite.com"],
627
763
  osLock: ["windows", "linux"],
628
764
  browserLock: ["firefox"],
package/dist/index.js CHANGED
@@ -103,7 +103,7 @@ var JsConfuser = async function (code, options) {
103
103
  return result;
104
104
  };
105
105
 
106
- var debugTransformations = async function debugTransformations(code, options) {
106
+ const debugTransformations = async function (code, options) {
107
107
  (0, _options.validateOptions)(options);
108
108
  options = await (0, _options.correctOptions)(options);
109
109
  var frames = [];
@@ -121,21 +121,50 @@ var debugTransformations = async function debugTransformations(code, options) {
121
121
  await obfuscator.apply(tree, true);
122
122
  return frames;
123
123
  };
124
+ /**
125
+ * This method is used by the obfuscator website to display a progress bar and additional information
126
+ * about the obfuscation.
127
+ *
128
+ * @param code - Source code to obfuscate
129
+ * @param options - Options
130
+ * @param callback - Progress callback, called after each transformation
131
+ * @returns
132
+ */
133
+
124
134
 
125
135
  exports.debugTransformations = debugTransformations;
126
136
 
127
- var debugObfuscation = async function debugTransformations(code, options, callback) {
137
+ const debugObfuscation = async function (code, options, callback, performance) {
138
+ const startTime = performance.now();
128
139
  (0, _options.validateOptions)(options);
129
140
  options = await (0, _options.correctOptions)(options);
141
+ const beforeParseTime = performance.now();
130
142
  var tree = (0, _parser.parseSync)(code);
143
+ const parseTime = performance.now() - beforeParseTime;
131
144
  var obfuscator = new _obfuscator.default(options);
132
145
  var totalTransforms = obfuscator.array.length;
146
+ var transformationTimes = Object.create(null);
147
+ var currentTransformTime = performance.now();
133
148
  obfuscator.on("debug", (name, tree, i) => {
149
+ var nowTime = performance.now();
150
+ transformationTimes[name] = nowTime - currentTransformTime;
151
+ currentTransformTime = nowTime;
134
152
  callback(name, i, totalTransforms);
135
153
  });
136
154
  await obfuscator.apply(tree, true);
137
- var output = (0, _compiler.default)(tree, options);
138
- return output;
155
+ const beforeCompileTime = performance.now();
156
+ var output = await (0, _compiler.default)(tree, options);
157
+ const compileTime = performance.now() - beforeCompileTime;
158
+ const endTime = performance.now();
159
+ return {
160
+ obfuscated: output,
161
+ transformationTimes: transformationTimes,
162
+ obfuscationTime: endTime - startTime,
163
+ parseTime: parseTime,
164
+ compileTime: compileTime,
165
+ totalTransforms: totalTransforms,
166
+ totalPossibleTransforms: obfuscator.totalPossibleTransforms
167
+ };
139
168
  };
140
169
 
141
170
  exports.debugObfuscation = debugObfuscation;
@@ -13,7 +13,7 @@ var _traverse = _interopRequireDefault(require("./traverse"));
13
13
 
14
14
  var _probability = require("./probability");
15
15
 
16
- var _preparation = _interopRequireDefault(require("./transforms/preparation/preparation"));
16
+ var _preparation = _interopRequireDefault(require("./transforms/preparation"));
17
17
 
18
18
  var _objectExtraction = _interopRequireDefault(require("./transforms/extraction/objectExtraction"));
19
19
 
@@ -33,9 +33,11 @@ var _eval = _interopRequireDefault(require("./transforms/eval"));
33
33
 
34
34
  var _globalConcealing = _interopRequireDefault(require("./transforms/identifier/globalConcealing"));
35
35
 
36
+ var _stringSplitting = _interopRequireDefault(require("./transforms/string/stringSplitting"));
37
+
36
38
  var _stringConcealing = _interopRequireDefault(require("./transforms/string/stringConcealing"));
37
39
 
38
- var _stringSplitting = _interopRequireDefault(require("./transforms/string/stringSplitting"));
40
+ var _stringCompression = _interopRequireDefault(require("./transforms/string/stringCompression"));
39
41
 
40
42
  var _duplicateLiteralsRemoval = _interopRequireDefault(require("./transforms/extraction/duplicateLiteralsRemoval"));
41
43
 
@@ -51,23 +53,17 @@ var _minify = _interopRequireDefault(require("./transforms/minify"));
51
53
 
52
54
  var _es = _interopRequireDefault(require("./transforms/es5/es5"));
53
55
 
54
- var _stringEncoding = _interopRequireDefault(require("./transforms/string/stringEncoding"));
55
-
56
56
  var _rgf = _interopRequireDefault(require("./transforms/rgf"));
57
57
 
58
58
  var _flatten = _interopRequireDefault(require("./transforms/flatten"));
59
59
 
60
60
  var _stack = _interopRequireDefault(require("./transforms/stack"));
61
61
 
62
- var _stringCompression = _interopRequireDefault(require("./transforms/string/stringCompression"));
63
-
64
62
  var _nameRecycling = _interopRequireDefault(require("./transforms/identifier/nameRecycling"));
65
63
 
66
64
  var _antiTooling = _interopRequireDefault(require("./transforms/antiTooling"));
67
65
 
68
- var _hideInitializingCode = _interopRequireDefault(require("./transforms/hideInitializingCode"));
69
-
70
- var _hexadecimalNumbers = _interopRequireDefault(require("./transforms/hexadecimalNumbers"));
66
+ var _finalizer = _interopRequireDefault(require("./transforms/finalizer"));
71
67
 
72
68
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
73
69
 
@@ -94,18 +90,21 @@ class Obfuscator extends _events.EventEmitter {
94
90
 
95
91
  _defineProperty(this, "generated", void 0);
96
92
 
93
+ _defineProperty(this, "totalPossibleTransforms", void 0);
94
+
97
95
  this.varCount = 0;
98
96
  this.transforms = Object.create(null);
99
97
  this.generated = new Set();
100
- this.push(new _preparation.default(this));
101
- this.push(new _renameLabels.default(this));
98
+ this.totalPossibleTransforms = 0;
102
99
 
103
100
  const test = function (map) {
104
- if ((0, _probability.isProbabilityMapProbable)(map)) {
105
- for (var _len = arguments.length, transformers = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
106
- transformers[_key - 1] = arguments[_key];
107
- }
101
+ for (var _len = arguments.length, transformers = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
102
+ transformers[_key - 1] = arguments[_key];
103
+ }
104
+
105
+ _this.totalPossibleTransforms += transformers.length;
108
106
 
107
+ if ((0, _probability.isProbabilityMapProbable)(map)) {
109
108
  // options.verbose && console.log("+ Added " + transformer.name);
110
109
  transformers.forEach(Transformer => _this.push(new Transformer(_this)));
111
110
  } else {// options.verbose && console.log("- Skipped adding " + transformer.name);
@@ -113,31 +112,31 @@ class Obfuscator extends _events.EventEmitter {
113
112
  }; // Optimization: Only add needed transformers. If a probability always return false, no need in running that extra code.
114
113
 
115
114
 
115
+ test(true, _preparation.default);
116
+ test(true, _renameLabels.default);
116
117
  test(options.objectExtraction, _objectExtraction.default);
117
- test(options.deadCode, _deadCode.default);
118
+ test(options.flatten, _flatten.default);
119
+ test(options.rgf, _rgf.default);
118
120
  test(options.dispatcher, _dispatcher.default);
121
+ test(options.deadCode, _deadCode.default);
122
+ test(options.calculator, _calculator.default);
119
123
  test(options.controlFlowFlattening, _controlFlowFlattening.default);
120
- test(options.globalConcealing, _globalConcealing.default);
121
- test(options.stringCompression, _stringCompression.default);
122
- test(options.stringConcealing, _stringConcealing.default);
123
- test(options.stringEncoding, _stringEncoding.default);
124
- test(options.stringSplitting, _stringSplitting.default);
125
- test(options.renameVariables, _renameVariables.default);
126
- test(options.nameRecycling, _nameRecycling.default);
127
124
  test(options.eval, _eval.default);
125
+ test(options.globalConcealing, _globalConcealing.default);
128
126
  test(options.opaquePredicates, _opaquePredicates.default);
127
+ test(options.stringSplitting, _stringSplitting.default);
128
+ test(options.stringConcealing, _stringConcealing.default);
129
+ test(options.stringCompression, _stringCompression.default);
130
+ test(options.stack, _stack.default);
129
131
  test(options.duplicateLiteralsRemoval, _duplicateLiteralsRemoval.default);
130
- test(options.minify, _minify.default);
131
- test(options.calculator, _calculator.default);
132
+ test(options.shuffle, _shuffle.default);
133
+ test(options.nameRecycling, _nameRecycling.default);
132
134
  test(options.movedDeclarations, _movedDeclarations.default);
135
+ test(options.minify, _minify.default);
136
+ test(options.renameVariables, _renameVariables.default);
133
137
  test(options.es5, _es.default);
134
- test(options.shuffle, _shuffle.default);
135
- test(options.flatten, _flatten.default);
136
- test(options.rgf, _rgf.default);
137
- test(options.stack, _stack.default);
138
138
  test(true, _antiTooling.default);
139
- test(options.hideInitializingCode, _hideInitializingCode.default);
140
- test(options.hexadecimalNumbers, _hexadecimalNumbers.default);
139
+ test(true, _finalizer.default); // String Encoding, Hexadecimal Numbers, BigInt support is included
141
140
 
142
141
  if (options.lock && Object.keys(options.lock).filter(x => x == "domainLock" ? options.lock.domainLock && options.lock.domainLock.length : options.lock[x]).length) {
143
142
  test(true, _lock.default);
package/dist/options.js CHANGED
@@ -12,12 +12,12 @@ var _presets = _interopRequireDefault(require("./presets"));
12
12
 
13
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
14
 
15
- const validProperties = new Set(["preset", "target", "indent", "compact", "hexadecimalNumbers", "minify", "es5", "renameVariables", "renameGlobals", "identifierGenerator", "nameRecycling", "controlFlowFlattening", "hideInitializingCode", "globalConcealing", "stringCompression", "stringConcealing", "stringEncoding", "stringSplitting", "duplicateLiteralsRemoval", "dispatcher", "eval", "rgf", "objectExtraction", "flatten", "deadCode", "calculator", "lock", "movedDeclarations", "opaquePredicates", "shuffle", "stack", "verbose", "globalVariables", "debugComments"]);
15
+ const validProperties = new Set(["preset", "target", "indent", "compact", "hexadecimalNumbers", "minify", "es5", "renameVariables", "renameGlobals", "identifierGenerator", "nameRecycling", "controlFlowFlattening", "globalConcealing", "stringCompression", "stringConcealing", "stringEncoding", "stringSplitting", "duplicateLiteralsRemoval", "dispatcher", "eval", "rgf", "objectExtraction", "flatten", "deadCode", "calculator", "lock", "movedDeclarations", "opaquePredicates", "shuffle", "stack", "verbose", "globalVariables", "debugComments"]);
16
16
  const validOses = new Set(["windows", "linux", "osx", "ios", "android"]);
17
17
  const validBrowsers = new Set(["firefox", "chrome", "iexplorer", "edge", "safari", "opera"]);
18
18
 
19
19
  function validateOptions(options) {
20
- if (Object.keys(options).length <= 1) {
20
+ if (!options || Object.keys(options).length <= 1) {
21
21
  /**
22
22
  * Give a welcoming introduction to those who skipped the documentation.
23
23
  */
@@ -109,8 +109,7 @@ async function correctOptions(options) {
109
109
 
110
110
  if (options.lock && options.lock.selfDefending) {
111
111
  options.compact = true; // self defending forcibly enables this
112
- } // options.globalVariables was never used.
113
- // GlobalConcealing implicitly determines a global to be a variable referenced but never defined or modified.
112
+ } // options.globalVariables outlines generic globals that should be present in the execution context
114
113
 
115
114
 
116
115
  if (!options.hasOwnProperty("globalVariables")) {
@@ -124,7 +123,7 @@ async function correctOptions(options) {
124
123
  ["global", "Buffer", "require", "process", "__dirname", "__filename"].forEach(x => options.globalVariables.add(x));
125
124
  }
126
125
 
127
- ["globalThis", "console", "parseInt", "parseFloat", "Math", "Promise", "String", "Boolean", "Function", "Object", "Array", "Proxy", "Error", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate", "queueMicrotask", "exports", "module", "isNaN", "isFinite"].forEach(x => options.globalVariables.add(x));
126
+ ["globalThis", "console", "parseInt", "parseFloat", "Math", "Promise", "String", "Boolean", "Function", "Object", "Array", "Proxy", "Error", "TypeError", "ReferenceError", "RangeError", "EvalError", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate", "queueMicrotask", "exports", "module", "isNaN", "isFinite", "Set", "Map", "WeakSet", "WeakMap", "Symbol"].forEach(x => options.globalVariables.add(x));
128
127
  }
129
128
 
130
129
  return options;
package/dist/order.js CHANGED
@@ -27,17 +27,15 @@ exports.ObfuscateOrder = ObfuscateOrder;
27
27
  ObfuscateOrder[ObfuscateOrder["StringSplitting"] = 16] = "StringSplitting";
28
28
  ObfuscateOrder[ObfuscateOrder["StringConcealing"] = 17] = "StringConcealing";
29
29
  ObfuscateOrder[ObfuscateOrder["StringCompression"] = 18] = "StringCompression";
30
- ObfuscateOrder[ObfuscateOrder["HideInitializingCode"] = 19] = "HideInitializingCode";
31
30
  ObfuscateOrder[ObfuscateOrder["Stack"] = 20] = "Stack";
32
31
  ObfuscateOrder[ObfuscateOrder["DuplicateLiteralsRemoval"] = 22] = "DuplicateLiteralsRemoval";
33
32
  ObfuscateOrder[ObfuscateOrder["Shuffle"] = 24] = "Shuffle";
34
33
  ObfuscateOrder[ObfuscateOrder["NameRecycling"] = 25] = "NameRecycling";
35
34
  ObfuscateOrder[ObfuscateOrder["MovedDeclarations"] = 26] = "MovedDeclarations";
36
- ObfuscateOrder[ObfuscateOrder["RenameVariables"] = 27] = "RenameVariables";
37
- ObfuscateOrder[ObfuscateOrder["RenameLabels"] = 28] = "RenameLabels";
38
- ObfuscateOrder[ObfuscateOrder["Minify"] = 30] = "Minify";
35
+ ObfuscateOrder[ObfuscateOrder["RenameLabels"] = 27] = "RenameLabels";
36
+ ObfuscateOrder[ObfuscateOrder["Minify"] = 28] = "Minify";
37
+ ObfuscateOrder[ObfuscateOrder["RenameVariables"] = 30] = "RenameVariables";
39
38
  ObfuscateOrder[ObfuscateOrder["ES5"] = 31] = "ES5";
40
- ObfuscateOrder[ObfuscateOrder["StringEncoding"] = 32] = "StringEncoding";
41
39
  ObfuscateOrder[ObfuscateOrder["AntiTooling"] = 34] = "AntiTooling";
42
- ObfuscateOrder[ObfuscateOrder["HexadecimalNumbers"] = 35] = "HexadecimalNumbers";
40
+ ObfuscateOrder[ObfuscateOrder["Finalizer"] = 35] = "Finalizer";
43
41
  })(ObfuscateOrder || (exports.ObfuscateOrder = ObfuscateOrder = {}));
@@ -77,6 +77,8 @@ function ComputeProbabilityMap(map) {
77
77
 
78
78
 
79
79
  function isProbabilityMapProbable(map) {
80
+ (0, _assert.ok)(!Number.isNaN(map), "Numbers cannot be NaN");
81
+
80
82
  if (!map || typeof map === "undefined") {
81
83
  return false;
82
84
  }
@@ -89,10 +91,6 @@ function isProbabilityMapProbable(map) {
89
91
  if (map > 1 || map < 0) {
90
92
  throw new Error("Numbers must be between 0 and 1 for 0% - 100%");
91
93
  }
92
-
93
- if (isNaN(map)) {
94
- throw new Error("Numbers cannot be NaN");
95
- }
96
94
  }
97
95
 
98
96
  if (Array.isArray(map)) {
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BufferToStringTemplate = void 0;
7
+
8
+ var _template = _interopRequireDefault(require("./template"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ const BufferToStringTemplate = (0, _template.default)("\n function __getGlobal(){\n try {\n return global||window|| ( new Function(\"return this\") )();\n } catch ( e ) {\n try {\n return this;\n } catch ( e ) {\n return {};\n }\n }\n }\n\n var __globalObject = __getGlobal() || {};\n var __TextDecoder = __globalObject[\"TextDecoder\"];\n var __Uint8Array = __globalObject[\"Uint8Array\"];\n var __Buffer = __globalObject[\"Buffer\"];\n var __String = __globalObject[\"String\"] || String;\n var __Array = __globalObject[\"Array\"] || Array;\n\n var utf8ArrayToStr = (function () {\n var charCache = new __Array(128); // Preallocate the cache for the common single byte chars\n var charFromCodePt = __String[\"fromCodePoint\"] || __String[\"fromCharCode\"];\n var result = [];\n\n return function (array) {\n var codePt, byte1;\n var buffLen = array[\"length\"];\n\n result[\"length\"] = 0;\n\n for (var i = 0; i < buffLen;) {\n byte1 = array[i++];\n\n if (byte1 <= 0x7F) {\n codePt = byte1;\n } else if (byte1 <= 0xDF) {\n codePt = ((byte1 & 0x1F) << 6) | (array[i++] & 0x3F);\n } else if (byte1 <= 0xEF) {\n codePt = ((byte1 & 0x0F) << 12) | ((array[i++] & 0x3F) << 6) | (array[i++] & 0x3F);\n } else if (__String[\"fromCodePoint\"]) {\n codePt = ((byte1 & 0x07) << 18) | ((array[i++] & 0x3F) << 12) | ((array[i++] & 0x3F) << 6) | (array[i++] & 0x3F);\n } else {\n codePt = 63; // Cannot convert four byte code points, so use \"?\" instead\n i += 3;\n }\n\n result[\"push\"](charCache[codePt] || (charCache[codePt] = charFromCodePt(codePt)));\n }\n\n return result[\"join\"]('');\n };\n })();\n\n function {name}(buffer){\n if(typeof __TextDecoder !== \"undefined\" && __TextDecoder) {\n return new __TextDecoder()[\"decode\"](new __Uint8Array(buffer));\n } else if(typeof __Buffer !== \"undefined\" && __Buffer) {\n return __Buffer[\"from\"](buffer)[\"toString\"](\"utf-8\");\n } else { \n return utf8ArrayToStr(buffer);\n }\n }\n\n \n");
13
+ exports.BufferToStringTemplate = BufferToStringTemplate;
@@ -9,9 +9,9 @@ var _template = _interopRequireDefault(require("./template"));
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- const CrashTemplate1 = (0, _template.default)("\ntry {\n if(typeof process !== \"undefined\") {\n Math.random() > 0.5 && process && process.exit();\n }\n} catch ( e ) {\n \n}\n\nvar {var} = \"a\";\nwhile(1){\n {var} = {var} += \"a\"; //add as much as the browser can handle\n}\n");
12
+ const CrashTemplate1 = (0, _template.default)("\nvar {var} = \"a\";\nwhile(1){\n {var} = {var} += \"a\"; //add as much as the browser can handle\n}\n");
13
13
  exports.CrashTemplate1 = CrashTemplate1;
14
- const CrashTemplate2 = (0, _template.default)("\nwhile(true) {\n for(var {var} = 99; {var} == {var}; {var} *= {var}) {\n !{var} && console.log({var});\n if ({var} <= 10){\n break;\n }\n };\n };");
14
+ const CrashTemplate2 = (0, _template.default)("\nwhile(true) {\n var {var} = 99;\n for({var} = 99; {var} == {var}; {var} *= {var}) {\n !{var} && console.log({var});\n if ({var} <= 10){\n break;\n }\n };\n if({var} === 100) {\n {var}--\n }\n };");
15
15
  exports.CrashTemplate2 = CrashTemplate2;
16
16
  const CrashTemplate3 = (0, _template.default)("\ntry {\n function {$2}(y, x){\n return x;\n }\n \n var {$1} = {$2}(this, function () {\n var {$3} = function () {\n var regExp = {$3}\n .constructor('return /\" + this + \"/')()\n .constructor('^([^ ]+( +[^ ]+)+)+[^ ]}');\n \n return !regExp.call({$1});\n };\n \n return {$3}();\n });\n \n {$1}();\n} catch ( e ) {\n while(e ? e : !e){\n var b;\n var c = 0;\n (e ? !e : e) ? (function(e){\n c = e ? 0 : !e ? 1 : 0;\n })(e) : b = 1;\n\n if(b&&c){break;}\n if(b){continue;}\n }\n}\n");
17
17
  exports.CrashTemplate3 = CrashTemplate3;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ES5Template = void 0;
7
+
8
+ var _template = _interopRequireDefault(require("./template"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ /**
13
+ * Provides ES5 polyfills for Array methods
14
+ *
15
+ * Source: https://vanillajstoolkit.com/polyfills/
16
+ */
17
+ const ES5Template = (0, _template.default)("\nif (!Array.prototype.forEach) {\n Array.prototype.forEach = function forEach (callback, thisArg) {\n if (typeof callback !== 'function') {\n throw new TypeError(callback + ' is not a function');\n }\n var array = this;\n thisArg = thisArg || this;\n for (var i = 0, l = array.length; i !== l; ++i) {\n callback.call(thisArg, array[i], i, array);\n }\n };\n}\nif (!Array.prototype.filter)\n Array.prototype.filter = function(func, thisArg) {\n\t'use strict';\n\tif ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )\n\t\tthrow new TypeError();\n\n\tvar len = this.length >>> 0,\n\t\tres = new Array(len), // preallocate array\n\t\tt = this, c = 0, i = -1;\n\tif (thisArg === undefined)\n\t while (++i !== len)\n\t\t// checks to see if the key was set\n\t\tif (i in this)\n\t\t if (func(t[i], i, t))\n\t\t\tres[c++] = t[i];\n\telse\n\t while (++i !== len)\n\t\t// checks to see if the key was set\n\t\tif (i in this)\n\t\t if (func.call(thisArg, t[i], i, t))\n\t\t\tres[c++] = t[i];\n\n\tres.length = c; // shrink down array to proper size\n\treturn res;\n};\nif (!Array.prototype.map) {\n Array.prototype.map = function(callback, thisArg) {\n var T, A, k;\n\n if (this == null) {\n throw new TypeError('this is null or not defined');\n }\n\n // 1. Let O be the result of calling ToObject passing the |this|\n // value as the argument.\n var O = Object(this);\n\n // 2. Let lenValue be the result of calling the Get internal\n // method of O with the argument \"length\".\n // 3. Let len be ToUint32(lenValue).\n var len = O.length >>> 0;\n\n // 4. If IsCallable(callback) is false, throw a TypeError exception.\n // See: http://es5.github.com/#x9.11\n if (typeof callback !== 'function') {\n throw new TypeError(callback + ' is not a function');\n }\n\n // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.\n if (arguments.length > 1) {\n T = arguments[1];\n }\n\n // 6. Let A be a new array created as if by the expression new Array(len)\n // where Array is the standard built-in constructor with that name and\n // len is the value of len.\n A = new Array(len);\n\n // 7. Let k be 0\n k = 0;\n\n // 8. Repeat, while k < len\n while (k < len) {\n\n var kValue, mappedValue;\n\n // a. Let Pk be ToString(k).\n // This is implicit for LHS operands of the in operator\n // b. Let kPresent be the result of calling the HasProperty internal\n // method of O with argument Pk.\n // This step can be combined with c\n // c. If kPresent is true, then\n if (k in O) {\n\n // i. Let kValue be the result of calling the Get internal\n // method of O with argument Pk.\n kValue = O[k];\n\n // ii. Let mappedValue be the result of calling the Call internal\n // method of callback with T as the this value and argument\n // list containing kValue, k, and O.\n mappedValue = callback.call(T, kValue, k, O);\n\n // iii. Call the DefineOwnProperty internal method of A with arguments\n // Pk, Property Descriptor\n // { Value: mappedValue,\n // Writable: true,\n // Enumerable: true,\n // Configurable: true },\n // and false.\n\n // In browsers that support Object.defineProperty, use the following:\n // Object.defineProperty(A, k, {\n // value: mappedValue,\n // writable: true,\n // enumerable: true,\n // configurable: true\n // });\n\n // For best browser support, use the following:\n A[k] = mappedValue;\n }\n // d. Increase k by 1.\n k++;\n }\n\n // 9. return A\n return A;\n };\n}\n");
18
+ exports.ES5Template = ES5Template;
@@ -50,7 +50,7 @@ class AntiTooling extends _transform.default {
50
50
  if (flattened.length > 1) {
51
51
  flattened[0] = { ...flattened[0]
52
52
  };
53
- this.replace(exprs[0], (0, _gen.ExpressionStatement)((0, _gen.UnaryExpression)((0, _random.choice)(["typeof", "void", "~", "!", "+"]), (0, _gen.SequenceExpression)(flattened))));
53
+ this.replace(exprs[0], (0, _gen.ExpressionStatement)((0, _gen.UnaryExpression)((0, _random.choice)(["typeof", "void", "!"]), (0, _gen.SequenceExpression)(flattened))));
54
54
  deleteExprs.push(...exprs.slice(1));
55
55
  }
56
56