@dacely/toildefender 0.1.3 → 0.1.5

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- <img src="./images/toildefender5.svg" alt="ToilDefender" width="600" />
3
+ <img src="./images/toildefender6.svg" alt="ToilDefender" width="600" />
4
4
 
5
5
 
6
6
  ### JavaScript code protection for the Toil stack.
@@ -99,6 +99,12 @@ the bytecode into encrypted BigInt streams, and executes it through a generated
99
99
  runtime VM. Instead of exposing readable JavaScript logic, your code becomes
100
100
  numeric program data consumed by a randomized virtual machine.
101
101
 
102
+ The compiler also fuses selected hot stack patterns into semantic
103
+ superinstructions, so common operation boundaries such as constant-key property
104
+ reads are not always emitted as separate primitive VM opcodes.
105
+ Constants are wrapped in access-bound cells, so encoded strings and references
106
+ are decoded lazily when bytecode reads them instead of during VM call setup.
107
+
102
108
  Original logic disappears from the output bundle. Attackers no longer reverse
103
109
  plain JavaScript; they must recover the VM, decode the bytecode format,
104
110
  reconstruct the instruction set, and emulate the protected program.
@@ -155,7 +161,8 @@ function licenseGate(input) {
155
161
  globalThis.__result = licenseGate("Veilmark");
156
162
  ```
157
163
 
158
- The demo artifact is generated with every major protection enabled:
164
+ The demo artifact is generated with every major protection enabled and
165
+ compression disabled so the runtime stays readable:
159
166
 
160
167
  ```js
161
168
  features: {
@@ -167,7 +174,7 @@ features: {
167
174
  object_packing: true,
168
175
  literals: true,
169
176
  mangle: true,
170
- compress: true
177
+ compress: false
171
178
  },
172
179
  protections: {
173
180
  virtualMachine: {
@@ -194,19 +201,20 @@ protections: {
194
201
 
195
202
  The complete beautified generated output is committed at
196
203
  [docs/all-modes-output.demo.js](./docs/all-modes-output.demo.js). It is a real
197
- 673-line artifact from the current generator and executes to:
204
+ 1019-line artifact from the current generator and executes to:
198
205
 
199
206
  Output excerpt:
200
207
 
201
208
  ```js
202
209
  (function () {
203
- function a(f, j) {
204
- var b = new Array(96);
210
+ function a(f, k) {
211
+ var b = new Array(109);
205
212
  ;
206
213
  var c = arguments;
214
+ var i;
207
215
  while (true) try {
208
216
  switch (f) {
209
- case 25271:
217
+ case 24210:
210
218
  b[11] = c[11];
211
219
  b[12] = c[10];
212
220
  b[13] = c[9];
@@ -217,69 +225,76 @@ Output excerpt:
217
225
  b[18] = c[4];
218
226
  b[19] = c[3];
219
227
  b[20] = c[2];
220
- b[21] = e(a, 26903, b, c[1]);
221
- b[22] = e(a, 13834, b, c[1]);
222
- b[23] = e(a, 24871, b, c[1]);
223
- b[24] = e(a, 3126, b, c[1]);
224
- b[25] = e(a, 24897, b, c[1]);
225
- b[26] = e(a, 32340, b, c[1]);
228
+ b[21] = e(a, 16503, b, c[1]);
229
+ b[22] = e(a, 16827, b, c[1]);
230
+ b[23] = e(a, 28881, b, c[1]);
231
+ b[24] = e(a, 27718, b, c[1]);
232
+ b[25] = e(a, 26046, b, c[1]);
233
+ b[26] = e(a, 11984, b, c[1]);
234
+ b[27] = e(a, 10989, b, c[1]);
235
+ b[28] = e(a, 10700, b, c[1]);
236
+ b[29] = e(a, 18606, b, c[1]);
237
+ b[30] = e(a, 22347, b, c[1]);
238
+ b[31] = e(a, 28683, b, c[1]);
239
+ b[32] = e(a, 11069, b, c[1]);
240
+ b[33] = e(a, 8443, b, c[1]);
241
+ b[34] = e(a, 27840, b, c[1]);
242
+ b[35] = e(a, 21656, b, c[1]);
243
+ b[36] = BigInt(b[19]);
244
+ b[37] = [1n];
245
+ b[38] = c[1][10][1];
246
+ b[39] = c[1][10][1];
226
247
  if (b[11]) {
227
- b[20] = c[1][2](b[20], b[19], b[18], b[17], b[16], b[12], b[11]);
248
+ b[38] = c[1][4](b[11], b[19], b[18], b[17], b[16], b[12]);
249
+ b[39] = b[11][c[1][10][24]] >>> c[1][10][1];
228
250
  }
229
- b[27] = [];
230
- b[28] = b[17] >>> c[1][9][1];
231
- b[29] = b[17] >>> c[1][9][1];
232
- b[30] = BigInt(b[19]);
233
- b[31] = c[1][9][1];
234
- while (b[31] < b[18]) {
235
- b[32] = Number(b[20] % b[30]);
236
- b[20] = b[20] / b[30];
237
- b[33] = c[1][9][5] + (b[28] >>> c[1][9][24]) % (b[19] - c[1][9][5]);
238
- b[34] = b[28] % b[19];
239
- b[35] = (b[32] - b[34] + b[19]) % b[19] * b[26](b[33], b[19]) % b[19];
240
- b[27][c[1][9][29]](b[35]);
241
- b[29] = b[25](b[29], b[32], b[31]);
242
- b[28] = b[25](b[28], b[32], b[31]);
243
- b[31] += c[1][9][5];
251
+ b[40] = c[1][10][1];
252
+ b[41] = b[17] >>> c[1][10][1];
253
+ while (b[40] < b[18]) {
254
+ b[42] = b[33](b[40]);
255
+ b[41] = b[34](b[41], b[42], b[40]);
256
+ b[40] += c[1][10][5];
244
257
  }
245
- if (b[29] >>> c[1][9][1] !== b[16] >>> c[1][9][1]) throw new Error(c[1][9][30]);
246
- b[36] = [];
247
- b[37] = [];
248
- b[38] = Array[c[1][9][31]][c[1][9][32]][c[1][9][33]](b[14]);
249
- b[39] = c[1][9][1];
250
- while (c[1][9][38]) {
251
- b[40] = b[24]();
252
- if (b[40] === b[12][c[1][9][1]]) continue;
253
- if (b[40] === b[12][c[1][9][5]]) {
254
- b[36][c[1][9][29]](undefined);
255
- continue;
256
- }
257
- if (b[40] === b[12][c[1][9][28]]) {
258
- b[36][c[1][9][29]](c[1][9][39]);
259
- continue;
260
- }
261
-
262
- /* 600+ more generated lines:
263
- dispatcher cases, encoded literals, VM bytecode decode,
264
- BigInt program blobs, randomized opcode tables, and Hash-Mesh unlock */
265
-
266
- case 11237:
258
+ if (b[41] >>> c[1][10][1] !== b[16] >>> c[1][10][1]) throw new Error(c[1][10][29]);
259
+ b[43] = c[1][10][1];
260
+ b[44] = b[17] >>> c[1][10][1];
261
+ b[45] = b[17] & c[1][10][5];
262
+ b[46] = b[45] ? c[1][10][30] : [];
263
+ b[47] = b[45] ? c[1][10][30] : [];
264
+ b[48] = b[45] ? g([
265
+ /* encoded layout keys */
266
+ ], [
267
+ [],
268
+ Object[c[1][10][36]](c[1][10][30])
269
+ ]) : c[1][10][30];
270
+
271
+ /* 900+ more generated lines:
272
+ dispatcher cases, encoded literals, streaming VM token reads,
273
+ lazy constant cells, seed-selected stack/local storage, BigInt program blobs,
274
+ semantic superinstructions, randomized opcode tables,
275
+ and Hash-Mesh unwrap */
276
+
277
+ case 27718:
278
+ if (c[1][50] < c[2][10][1] || c[1][50] >= c[1][18]) throw new Error(c[2][10][46]);
279
+ b[1] = c[1][31](c[1][50]);
280
+ c[1][50] += c[2][10][5];
281
+ return b[1];
282
+ case 30063:
267
283
  b[1] = '';
268
- b[1] += d(86, 101);
269
- b[1] += d(105, 108, 109, 97);
270
- b[1] += d(114);
271
- b[1] += d(107);
284
+ b[1] += d(86, 101, 105);
285
+ b[1] += d(108, 109);
286
+ b[1] += d(97, 114, 107);
272
287
  return b[1];
273
288
  }
274
289
  } catch (a) {
275
- veilmark$tobethrown = null;
290
+ i = null;
276
291
  switch (f) {
277
292
  default:
278
293
  throw a;
279
294
  }
280
295
  }
281
296
  }
282
- a(4089, {});
297
+ a(20498, {});
283
298
  })();
284
299
  ```
285
300
 
@@ -392,12 +407,26 @@ Main options:
392
407
  | `code` | Entry source code. |
393
408
  | `modulesCode` | Map of dependency filename to source code. |
394
409
  | `features` | Feature switches for the classic pipeline. |
410
+ | `babel` | Defaults to `false`; set to `true` only when you want the optional Babel downlevel transform before protection. |
411
+ | `babelPreserveAsync` | Defaults to `true`; when `babel: true`, keeps async/generator syntax native so async-aware flattening can avoid Babel regenerator helper bloat. Set to `false` for legacy async lowering. |
395
412
  | `protections.virtualMachine` | User-facing VM bytecode backend configuration. |
396
413
  | `protections.hashMesh` | User-facing hash-mesh unlock configuration. |
397
414
  | `numericVm` | Lower-level numeric VM configuration retained for internal callers. |
398
415
  | `preprocessorVariables` | Compile-time preprocessor constants. |
399
416
  | `logLevel` | `error`, `warn`, `info`, `debug`, or `log`. |
400
417
 
418
+ The default path parses modern syntax directly and normalizes the constructs
419
+ that older obfuscation passes cannot consume yet. The native AST path supports
420
+ plain classes as native islands, class fields, private fields, arrows, for-of
421
+ loops, async/generator functions, optional chaining, nullish coalescing, object
422
+ rest/spread, and spread calls.
423
+
424
+ When `babel: true` and `babelPreserveAsync` is enabled, optional Babel packages
425
+ installed by the caller can still downlevel syntax for legacy browser targets
426
+ while leaving async and generator functions for ToilDefender's async/generator
427
+ dispatchers. This avoids the large regenerator helper path for modern browser
428
+ and Node bundles.
429
+
401
430
  ## Toil Integration
402
431
 
403
432
  ToilDefender is intended to sit behind Toil build tooling. Framework packages