周末在家,突然王同学发给我一个链接腾讯极客技术挑战赛-码上种树。于是一拍即合,开启了这场逆向破解竞赛。

竞赛的操作上很简单,点击网页上的按钮一次就可以种一棵树。实质上每次先从服务器拉取一道题目,浏览器用本地脚本计算出答案,然后再将答案发送到服务器。整个竞赛的核心在于逆向破解计算答案的脚本,并优化其中的算法,越快越好。每种树到一定数量,题目就会发生变化,也就是进入了下一题,需要继续破解新的脚本文件。

整体上来说,后面的题目很有难度,需要有汇编计算机操作系统编译原理的功力。

0x01

题目 1 A274075A.js

1
2
3
window.A274075A = async function ({ a }) {
return new Promise((_) => setTimeout((__) => _(a[0]), 2000));
};

不必多说,将 setTimeout 时间改成 0,然后循环点击按钮就可以了。还要重写页面代码中的 sleep 函数,设置为 0 秒。

1
2
3
4
5
6
7
8
9
10
11
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, 0));
}
for (let i = 0; i < 10000; i++) {
setTimeout(() => {
document.getElementById('plant_btn').click();
}, 50 * i);
}
window.A274075A = async function ({ a }) {
return new Promise((_) => setTimeout((__) => _(a[0]), 0));
};

可以刷到 10 万棵树。然后速度变慢,进入下一题。

0x02 base64 + 变量名混淆逆向

题目 2 A5473788.js

1
2
3
4
5
eval(
atob(
'dmFyIF8weGU5MzY9WydBNTQ3Mzc4OCddOyhmdW5jdGlvbihfMHg0OGU4NWMsXzB4ZTkzNmQ4KXt2YXIgXzB4MjNmYzVhPWZ1bmN0aW9uKF8weDI4NThkOSl7d2hpbGUoLS1fMHgyODU4ZDkpe18weDQ4ZTg1Y1sncHVzaCddKF8weDQ4ZTg1Y1snc2hpZnQnXSgpKTt9fTtfMHgyM2ZjNWEoKytfMHhlOTM2ZDgpO30oXzB4ZTkzNiwweDE5NikpO3ZhciBfMHgyM2ZjPWZ1bmN0aW9uKF8weDQ4ZTg1YyxfMHhlOTM2ZDgpe18weDQ4ZTg1Yz1fMHg0OGU4NWMtMHgwO3ZhciBfMHgyM2ZjNWE9XzB4ZTkzNltfMHg0OGU4NWNdO3JldHVybiBfMHgyM2ZjNWE7fTt3aW5kb3dbXzB4MjNmYygnMHgwJyldPWZ1bmN0aW9uKF8weDMzNTQzNyl7dmFyIF8weDFhYWMwMj0weDMwZDNmO2Zvcih2YXIgXzB4M2JlZDZhPTB4MzBkM2Y7XzB4M2JlZDZhPjB4MDtfMHgzYmVkNmEtLSl7dmFyIF8weDM3NTM0MD0weDA7Zm9yKHZhciBfMHgxZGRiNzc9MHgwO18weDFkZGI3NzxfMHgzYmVkNmE7XzB4MWRkYjc3Kyspe18weDM3NTM0MCs9XzB4MzM1NDM3WydhJ11bMHgwXTt9XzB4Mzc1MzQwJV8weDMzNTQzN1snYSddWzB4Ml09PV8weDMzNTQzN1snYSddWzB4MV0mJl8weDNiZWQ2YTxfMHgxYWFjMDImJihfMHgxYWFjMDI9XzB4M2JlZDZhKTt9cmV0dXJuIF8weDFhYWMwMjt9Ow=='
)
);

首先将 base64 解码,得到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var _0xe936 = ['A5473788'];
(function (_0x48e85c, _0xe936d8) {
var _0x23fc5a = function (_0x2858d9) {
while (--_0x2858d9) {
_0x48e85c['push'](_0x48e85c['shift']());
}
};
_0x23fc5a(++_0xe936d8);
})(_0xe936, 0x196);
var _0x23fc = function (_0x48e85c, _0xe936d8) {
_0x48e85c = _0x48e85c - 0x0;
var _0x23fc5a = _0xe936[_0x48e85c];
return _0x23fc5a;
};
window[_0x23fc('0x0')] = function (_0x335437) {
var _0x1aac02 = 0x30d3f;
for (var _0x3bed6a = 0x30d3f; _0x3bed6a > 0x0; _0x3bed6a--) {
var _0x375340 = 0x0;
for (var _0x1ddb77 = 0x0; _0x1ddb77 < _0x3bed6a; _0x1ddb77++) {
_0x375340 += _0x335437['a'][0x0];
}
_0x375340 % _0x335437['a'][0x2] == _0x335437['a'][0x1] && _0x3bed6a < _0x1aac02 && (_0x1aac02 = _0x3bed6a);
}
return _0x1aac02;
};

将变量全部语义化替换,将十六进制数转成十进制数,可以变成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var arr = ['A5473788'];
(function (a, b) {
var f = function (j) {
while (--j) {
a['push'](a['shift']());
}
};
f(++b);
})(arr, 406);
var g = function (a, b) {
a = a - 0;
var f = arr[a];
return f;
};
window[g('0x0')] = function (params) {
var res = 199999;
for (var i = 199999; i > 0; i--) {
var t = 0;
for (var j = 0; j < i; j++) {
t += params['a'][0];
}
t % params['a'][2] == params['a'][1] && i < res && (res = i);
}
return res;
};

通过运行 g('0x0') 可以发现 g('0x0') 就是 'A5473788'。发现第二重循环做了 i 次加法,直接改成乘法,复杂度降为 O(1)。最终代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
window['A5473788'] = function a(params) {
var k = 199999;
for (var i = 199999; i > 0; i--) {
var res = 0;
res = params['a'][0] * i;
if (res % params['a'][2] == params['a'][1] && i < k) {
k = i;
}
}
return k;
};
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, 0));
}
for (let i = 0; i < 10000; i++) {
setTimeout(() => {
document.getElementById('plant_btn').click();
}, 50 * i);
}

顺利种树到 25 万棵。

0x03 jsfuck 逆向

题目 3 A593C8B8.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
window.A593C8B8 = async (_) =>
(($, _, __, ___, ____) => {
let _____ = (function* () {
while ([])
yield [(_, __) => _ + __, (_, __) => _ - __, (_, __) => _ * __][++__ % (!+[] + !+[] + !+[])][
(+(+!+[] + [+!+[]]))[
(!![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(+![] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(+![] +
[![]] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[!+[] + !+[] + [+[]]]
](!+[] + !+[] + [+[]]) +
([![]] + [][[]])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
([][[]] + [])[!+[] + !+[]]
](+[], ___, ____);
})();
let ______ = function (_____, ______, _______) {
____ = _____;
___ = ______[
([][[]] + '')[+!+[]] +
(!![] + '')[+!+[] + !+[] + !+[]] +
(+(+!+[] + [+[]] + [+!+[]]))[
(!![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(+![] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(+![] +
[![]] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[!+[] + !+[] + [+[]]]
](!+[] + !+[] + !+[] + [!+[] + !+[] + !+[] + !+[]])[+!+[]] +
(!![] + '')[+[]]
]()[
(+(!+[] + !+[] + !+[] + [+!+[]]))[
(!![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(+![] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(+![] +
[![]] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[!+[] + !+[] + [+[]]]
](!+[] + !+[] + !+[] + [!+[] + !+[]]) +
(![] + [])[+!+[]] +
(![] + [])[!+[] + !+[]] +
([][[]] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]]
]();
__ ==
_[(![] + '')[+!+[]]][
(![] + [])[!+[] + !+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
([][[]] + [])[+!+[]] +
(+![] +
[![]] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[!+[] + !+[] + [+[]]] +
(!![] + [])[+[]] +
(+(+!+[] + [+[]] + [+!+[]]))[
(!![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(+![] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(+![] +
[![]] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[!+[] + !+[] + [+[]]]
](!+[] + !+[] + [+!+[]])[+!+[]]
] && _______(-___);
};
return new Promise((__) =>
_[(![] + '')[+!+[]]][
(![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]][
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
](
(!![] + [])[+!+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
([][[]] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+!+[]] +
(![] + [+![]])[
([![]] + [][[]])[+!+[] + [+[]]] +
(!![] + [])[+[]] +
(![] + [])[+!+[]] +
(![] + [])[!+[] + !+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(![] + [])[!+[] + !+[] + !+[]]
]()[+!+[] + [+[]]] +
[+[]] +
(![] + [+![]])[
([![]] + [][[]])[+!+[] + [+[]]] +
(!![] + [])[+[]] +
(![] + [])[+!+[]] +
(![] + [])[!+[] + !+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(![] + [])[!+[] + !+[] + !+[]]
]()[+!+[] + [+[]]]
)()[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
] + [])[+!+[] + [!+[] + !+[]]] +
(![] + [])[+!+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(+(+!+[] + [+[]] + [+!+[]]))[
(!![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(+![] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(+![] +
[![]] +
([] + [])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
])[!+[] + !+[] + [+[]]]
](!+[] + !+[] + [+!+[]])[+!+[]]
]((___) =>
$[
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(+[![]] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]][
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
](
(!![] + [])[+!+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
([][[]] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+!+[]] +
(+[![]] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+!+[]]
] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]][
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
](
(!![] + [])[+!+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
([][[]] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+!+[]] +
(+[![]] +
[][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+!+[]]
] +
(!![] + [])[!+[] + !+[] + !+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(![] + [])[+!+[]] +
(+(!+[] + !+[] + [+!+[]] + [+!+[]]))[
(!![] + [])[+[]] +
(!![] +
[][
(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(+![] +
([] + [])[
([][
(![] + [])[+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+!+[]]
] + [])[!+[] + !+[] + !+[]] +
(!![] +
[][
(![] + [])[+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][
(![] + [])[+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+!+[]]
] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][
(![] + [])[+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(+![] +
[![]] +
([] + [])[
([][
(![] + [])[+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+!+[]]
] + [])[!+[] + !+[] + !+[]] +
(!![] +
[][
(![] + [])[+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][
(![] + [])[+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+!+[]]
] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] +
[][
(![] + [])[+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+!+[]]
])[!+[] + !+[] + [+[]]]
](!+[] + !+[] + !+[] + [+!+[]])[+!+[]] +
(!![] + [])[!+[] + !+[] + !+[]]
)()(
([] + [])[
(![] + [])[+[]] +
(!![] +
[][
(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
([][[]] + [])[+!+[]] +
(!![] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] +
[])[!+[] + !+[] + !+[]] +
(!![] +
[][
(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]] +
(!![] +
[][
(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]
])[+!+[] + [+[]]] +
(!![] + [])[+!+[]]
]()[+!+[] + [+!+[]]]
)[!+[] + !+[]] +
(![] + [])[+!+[]] +
(!![] + [])[+[]] +
(!![] + [])[!+[] + !+[] + !+[]]
)()())[!+[] + !+[] + !+[] + [+[]]] +
([![]] + [][[]])[+!+[] + [+[]]] +
((+[])[
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+!+[]] +
(![] + [])[!+[] + !+[] + !+[]] +
(!![] + [])[+[]] +
(!![] + [])[+!+[]] +
([][[]] + [])[+[]] +
([][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]] + [])[
!+[] + !+[] + !+[]
] +
(!![] + [])[+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
(!![] + [])[+!+[]]
] + [])[+!+[] + [+!+[]]] +
(!![] + [])[!+[] + !+[] + !+[]] +
(!![] + [][(![] + [])[+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]] + (!![] + [])[+[]] + (!![] + [])[!+[] + !+[] + !+[]] + (!![] + [])[+!+[]]])[
+!+[] + [+[]]
] +
([][[]] + [])[+[]] +
(!![] + [])[+[]]
]((____) => ______(___, _____, __), ___)
)
);
})(window, _, +[], +[], +[]);

没有找到太好的办法,尝试过 jsunfuck 但是不好用。首先先将代码格式化,然后通过在终端里面一段段运行两个加号之间的代码,然后机械替换所有的模式,可以得到结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
window.A593C8B8 = async (param) =>
(($, param, m, e, d) => {
let a = (function* () {
while (true) {
let f1 = (param, m) => param + m;
let f2 = (param, m) => param - m;
let f3 = (param, m) => param * m;
yield [f1, f2, f3][++m % 3].bind(0, e, d);
}
})();
let b = function (a, b, c) {
d = a;
e = b['next']()['value']();
m == param.a.length && c(-e);
};
return new Promise((m) => param.a.forEach((e) => $.setTimeout((d) => b(e, a, m), e)));
})(window, param, 0, 0, 0);

发现 setTimeoute 相关,尝试将 e 改成 0,结果报错,后来王同学用 e/100 代换 e。但跑了几个之后开始报错,我尝试了 e/10e/50e/99,最终选择 e/99,最终代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
window.A593C8B8 = async (param) =>
(($, param, m, e, d) => {
let a = (function* () {
while (true) {
let f1 = (param, m) => param + m;
let f2 = (param, m) => param - m;
let f3 = (param, m) => param * m;
yield [f1, f2, f3][++m % 3].bind(0, e, d);
}
})();
let b = function (a, b, c) {
d = a;
e = b['next']()['value']();
m == param.a.length && c(-e);
};
return new Promise((m) => param.a.forEach((e) => $.setTimeout((d) => b(e, a, m), e / 99)));
})(window, param, 0, 0, 0);
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, 0));
}
for (let i = 0; i < 10000; i++) {
setTimeout(() => {
document.getElementById('plant_btn').click();
}, 50 * i);
}

后知后觉,这是睡眠排序,顺利种树到 50 万棵。

0x04 WebAssembly 汇编逆向

题目 4 A661E542.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
window.A661E542 = async function ({ a: A }) {
return (
await WebAssembly.instantiate(
await WebAssembly.compile(
await (
await fetch(
'data:application/octet-binary;base64,AGFzbQEAAAABBwFgAn9/AX8CFwIETWF0aANtaW4AAARNYXRoA21heAAAAwIBAAcHAQNSdW4AAgpgAV4BBn8gACECIAFBAWsiBARAA0AgAiEDQQAhBkEKIQcDQCADQQpwIQUgA0EKbiEDIAUgBhABIQYgBSAHEAAhByADQQBLDQALIAIgBiAHbGohAiAEQQFrIgQNAAsLIAIL'
)
).arrayBuffer()
),
{ Math: Math }
)
).exports.Run(...A);
};

这道题是一个 WebAssembly 的逆向,连夜补了 WebAssembly 的知识,后来发现输出和输入数字相差不大,于是在睡觉前写了一个 100 并发的暴力破解程序,挂在服务器上就去睡觉了,第二天已经成功种树到 100 万棵,遂不再研究。

暴力破解,其实可以不用 Promise.all,不必等所有请求都完毕,只要有一个返回成功就可以继续切换下一题,但时间已晚,不想再费精力。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const axios = require('axios').default;
// 对于 t 这道题目,并发尝试 [i, j] 之间的答案
async function find(i, j, t) {
let arr = [];
for (let k = i; k <= j; k++) {
arr.push(k);
}
let p = arr.map((item) => {
return axios.get('http://服务器地址:8081/push', {
params: {
t: t,
a: item,
},
});
});
return Promise.all(p).then((res) => {
if (
res.some((item) => {
if (item.data.success === 1) {
console.log(item.data.score);
return true;
}
return item.data.success === 1;
})
) {
return true;
}
});
}
async function go() {
let result = await axios.get('http://服务器地址:8081/pull?u=用户ID');
let i = result.data.a[0];
let t = i + 100;
let res = await find(i, t, result.data.t);
while (res !== true) {
i = t + 1;
t += 100;
res = await find(i, t, result.data.t);
}
if (res) {
await go();
}
}

go();

感谢第二天王同学进行反汇编还原出代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function myfunc(a1, a2) {
let maxd, mind;
let a1_back = a1;

for (let i = 1; a2 - i > 0; i++) {
maxd = 0;
mind = 10;
let temp = a1_back;
while (a1_back > 0) {
let d = a1_back % 10;
a1_back = parseInt(a1_back / 10);
maxd = Math.max(d, maxd);
mind = Math.min(d, mind);
}
a1_back = temp + maxd * mind;
}
return a1_back;
}

观察到每次运算后结果的数值某一位有 0 就可以直接 break,因为最大数位乘以最小数位一定等于零,不必再累加这些无用的 0,优化之后完美通过:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function myfunc2(a1, cnt) {
let maxd, mind;
let x = a1;
for (let i = 1; i < cnt; i++) {
maxd = 0;
mind = 10;
// 备份 x
let temp = x;
// 求 x 中最大的位和最小的位
while (x > 0) {
let d = x % 10;
x = parseInt(x / 10);
maxd = Math.max(d, maxd);
mind = Math.min(d, mind);
}
// 将乘积加到 x 上
x = temp + maxd * mind;
if (i !== 1 && (mind === 0 || maxd === 0)) break;
}
return x;
}

0x05 JS 栈式虚拟机

题目 5 CA1807EB.js

通过在浏览器虚拟一个栈式机器来运行字节码,从而保护代码,这样的思想是第一次见到。后来才知道早就听过名字的 JVM 就是做这个事情的。整段代码运行速度非常慢,大概要 2 分钟才能计算出一个结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
var __TENCENT_CHAOS_STACK = function () {
function __TENCENT_CHAOS_VM(f, e, c, r, l, g, s, a) {
var n = !r;
f = +f, e = e || [0], r = r || [[this], [{}]], l = l || {};
var t = [],
o = null,
u = [function () {
r[r.length - 2] = r[r.length - 2] | r.pop()
}, , , function () {
for (var o = e[f++], u = [], n = e[f++], t = e[f++], p = [], h = 0; h < n; h++) u[e[f++]] = r[e[
f++]];
for (h = 0; h < t; h++) p[h] = e[f++];
r.push(function i() {
var n = u.slice(0);
n[0] = [this], n[1] = [arguments], n[2] = [i];
for (var t = 0; t < p.length && t < arguments.length; t++) 0 < p[t] && (n[p[t]] = [
arguments[t]]);
return __TENCENT_CHAOS_VM(o, e, c, n, l, g, s, a)
})
}, , function () {
r.push(undefined)
}, , function () {
return !0
}, function () {
var n = r[r.length - 2];
n[0][n[1]] = r[r.length - 1]
}, function () {
r.push(!r.pop())
}, , , function () {
r.push([e[f++]])
}, function () {
r[r.length - 1] = e[f++]
}, , function () {
r[r.length - 2] = r[r.length - 2] % r.pop()
}, function () {
r.push("")
}, function () {
f = e[f++]
}, , , , , , , function () {
var n = r.pop();
r.push([r[r.pop()][0], n])
}, function () {
var n = e[f++];
r[n] = r[n] === undefined ? [] : r[n]
}, , , , , , function () {
var n = e[f++],
t = r[r.length - 2 - n];
r[r.length - 2 - n] = r.pop(), r.push(t)
}, function () {
var n = e[f++];
r[r.length - 1] && (f = n)
}, function () {
r.length = e[f++]
}, function () {
r[r.length - 2] = r[r.length - 2] >= r.pop()
}, , , function () {
r.pop()
}, , , , function () {
r[r[r.length - 2][0]][0] = r[r.length - 1]
}, , , function () {
r[r.length - 2] = r[r.length - 2] * r.pop()
}, function () {
r.push([c, r.pop()])
}, , , function () {
r.push(r[r.pop()[0]][0])
}, , , , function () {
var n = e[f++],
t = n ? r.slice(-n) : [];
r.length -= n;
var o = r.pop();
r.push(o[0][o[1]].apply(o[0], t))
}, function () {
r.push(r[e[f++]][0])
}, , function () {
r.push(e[f++])
}, , function () {
var n = r.pop();
r.push(n[0][n[1]])
}, function () {
r.push(r[r.length - 1])
}, , , , , function () {
r.length -= e[f++]
}, , function () {
var n = r.pop(),
t = r.pop();
r.push([t[0][t[1]], n])
}, function () {
r[r.length - 2] = r[r.length - 2] + r.pop()
}, , function () {
r[r.length - 1] += String.fromCharCode(e[f++])
}];
for (0;;) try {
for (var p = !1; !p;) p = u[e[f++]]();
if (0, o) throw o;
return n ? (r.pop(), r.slice(3 + __TENCENT_CHAOS_VM.v)) : r.pop()
} catch (i) {
0;
var h = t.pop();
if (h === undefined) throw i;
o = i, f = h[0], r.length = h[1], h[2] && (r[h[2]][0] = o)
}
}
__TENCENT_CHAOS_VM.v = 0;
return __TENCENT_CHAOS_VM(0, [33, 3, 25, 2, 16, 68, 119, 68, 105, 68, 110, 68, 100, 68, 111, 68, 119, 45, 16,
68, 67, 68, 65, 68, 49, 68, 56, 68, 48, 68, 55, 68, 69, 68, 66, 65, 17, 2426, 33, 7, 25, 2, 25, 3,
25, 4, 25, 5, 25, 6, 12, 4, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 0, 52,
1, 41, 12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45,
55, 1, 52, 1, 41, 31, 0, 63, 6, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 0, 65, 57, 34, 9, 32, 123, 37,
17, 243, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68,
54, 68, 54, 68, 49, 68, 53, 68, 57, 68, 52, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68,
105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68,
57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0,
12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 103, 12, 5, 55,
0, 41, 31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 1, 65, 57, 34, 9, 32, 272, 37, 17, 392,
12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 50, 68, 52, 68,
55, 68, 55, 68, 54, 68, 50, 68, 55, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68,
103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68,
57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58,
48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 252, 12, 4, 58, 48, 53, 6,
66, 41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68,
49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50,
68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66, 68, 105,
68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 1, 52, 1, 41, 31, 0, 63, 8, 12, 5, 48, 12, 3, 16, 68, 97,
24, 55, 2, 65, 57, 34, 9, 32, 511, 37, 17, 631, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73,
68, 110, 68, 116, 45, 16, 68, 54, 68, 56, 68, 55, 68, 56, 68, 55, 68, 57, 68, 52, 52, 1, 44, 41, 31,
0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49,
68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68,
57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0,
0, 63, 5, 37, 17, 491, 12, 5, 55, 0, 41, 31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 3, 65,
57, 34, 9, 32, 660, 37, 17, 780, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68,
116, 45, 16, 68, 55, 68, 53, 68, 52, 68, 54, 68, 51, 68, 54, 68, 52, 52, 1, 44, 41, 31, 0, 12, 6,
58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68,
53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55,
52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5,
37, 17, 640, 12, 4, 58, 48, 53, 6, 66, 41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68,
73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68,
48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 55, 0, 41,
31, 0, 12, 6, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 1, 52, 1, 41, 31, 0,
63, 8, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 4, 65, 57, 34, 9, 32, 899, 37, 17, 1019, 12, 6, 58, 48,
16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 50, 68, 57, 68, 57, 68, 49, 68,
57, 68, 49, 68, 57, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68,
110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68,
54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1,
31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 879, 12, 5, 55, 0, 41, 31, 0, 37, 37, 12,
5, 48, 12, 3, 16, 68, 97, 24, 55, 5, 65, 57, 34, 9, 32, 1048, 37, 17, 1168, 12, 6, 58, 48, 16, 68,
66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 50, 68, 49, 68, 56, 68, 50, 68, 54, 68,
52, 68, 51, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68,
116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56,
68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55,
1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 1028, 12, 4, 58, 48, 53, 6, 66, 41, 31, 0, 12, 4, 58,
48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53,
68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52,
1, 15, 41, 31, 0, 12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68,
116, 45, 55, 1, 52, 1, 41, 31, 0, 63, 8, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 6, 65, 57, 34, 9, 32,
1287, 37, 17, 1407, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16,
68, 55, 68, 57, 68, 51, 68, 48, 68, 48, 68, 57, 68, 52, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68,
66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68,
57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41,
31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 1267, 12,
5, 55, 0, 41, 31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 7, 65, 57, 34, 9, 32, 1436, 37,
17, 1556, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68,
52, 68, 52, 68, 52, 68, 56, 68, 54, 68, 49, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68,
105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68,
57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0,
12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 1416, 12, 4, 58,
48, 53, 6, 66, 41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45,
16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52,
68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66,
68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 1, 52, 1, 41, 31, 0, 63, 8, 12, 5, 48, 12, 3,
16, 68, 97, 24, 55, 8, 65, 57, 34, 9, 32, 1675, 37, 17, 1795, 12, 6, 58, 48, 16, 68, 66, 68, 105,
68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 53, 68, 53, 68, 57, 68, 54, 68, 48, 68, 50, 68, 52,
52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16,
68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68,
50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41,
37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 1655, 12, 5, 55, 0, 41, 31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68,
97, 24, 55, 9, 65, 57, 34, 9, 32, 1824, 37, 17, 1944, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103,
68, 73, 68, 110, 68, 116, 45, 16, 68, 54, 68, 50, 68, 52, 68, 54, 68, 56, 68, 55, 68, 51, 52, 1, 44,
41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49,
68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68,
53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0,
31, 0, 0, 63, 5, 37, 17, 1804, 12, 4, 58, 48, 53, 6, 66, 41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68,
105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68,
57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0,
12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 1,
52, 1, 41, 31, 0, 63, 8, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 10, 65, 57, 34, 9, 32, 2063, 37, 17,
2183, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 56, 68, 55,
68, 50, 68, 54, 68, 57, 68, 48, 68, 57, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105,
68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57,
68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5,
58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 2043, 12, 5, 55, 0, 41,
31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 11, 65, 57, 34, 9, 32, 2212, 37, 17, 2332, 12,
6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 53, 68, 56, 68, 49,
68, 49, 68, 55, 68, 55, 68, 51, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103,
68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57,
68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48,
58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 2192, 12, 4, 58, 48, 53, 6, 66,
41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49,
68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68,
53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 16, 68, 112, 68, 97, 68, 114, 68, 115, 68, 101, 68, 73,
68, 110, 68, 116, 45, 53, 4, 52, 1, 7, 5, 7, 63, 4, 3, 38, 0, 1, 3, 8, 31, 0, 5, 7, 37, 37], window)
}();
__TENCENT_CHAOS_STACK.g = function () {
return __TENCENT_CHAOS_STACK.shift()[0]
};

学过操作系统课程,看到上面的代码能够反应出来是在进行取指执行,指令就是上面大数组里的内容。首先需要破译所有的操作符编码的含义,对虚拟机的所有操作符进行 log:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
let cnt = 0
var __TENCENT_CHAOS_STACK = function () {
function __TENCENT_CHAOS_VM(f, e, c, r, l, g, s, a) {
var n = !r;
f = +f, e = e || [0], r = r || [[this], [{}]], l = l || {};
console.log('初始栈:', r)
var t = [],
o = null,
u = [function () {
// console.log('u0')
// console.log(r)
let tmp = r.pop()
console.log(`将栈顶两个元素弹出,将 ${r[r.length - 1]}${tmp} 按位与,结果 ${r[r.length - 1] | tmp} 入栈`)
r[r.length - 1] = r[r.length - 1] | tmp
}, , , function () {
//console.log('u3')
console.log('开始函数调用')
console.log('读入三个指令', o, n, t)
var o = e[f++], u = [], n = e[f++], t = e[f++], p = [], h = 0;
console.log(`遍历 ${n} 次`)
for (; h < n; h++) {
console.log('将', r[e[f]], `放入u[${e[f]}]`)
u[e[f++]] = r[e[f++]];
}
for (h = 0; h < t; h++) {
console.log(`遍历 ${t} 次`)
console.log('将', e[f], `放入p[${h}]`)
p[h] = e[f++];
}
console.log(u, p)
console.log('栈中压入需要调用的函数')
r.push(function i() {
var n = u.slice(0);
n[0] = [this], n[1] = [arguments], n[2] = [i];
for (var t = 0; t < p.length && t < arguments.length; t++) 0 < p[t] && (n[p[t]] = [arguments[t]]);
return __TENCENT_CHAOS_VM(o, e, c, n, l, g, s, a)
})
}, , function () {
//console.log('u5')
console.log('栈中压入一个 undefined')
r.push(undefined)
}, , function () {
//console.log('u7')
console.log('终止取值运行操作')
return !0
}, function () {
//console.log('u8')
var n = r[r.length - 2];
console.log('取出栈中第二个元素', n)
console.log('将', n[0], '[', n[1], '] 赋值为', r[r.length - 1], '栈最后一个元素')
n[0][n[1]] = r[r.length - 1]
}, function () {
//console.log('u9')
let tmp = r.pop();
console.log(`栈顶取反,结果为 ${!tmp}`)
r.push(!tmp)
}, , , function () {
//console.log('u12')
console.log('指令', [e[f]], '入栈')

r.push([e[f++]])
}, function () {
//console.log('u13')

console.log('栈顶元素修改为', e[f])
r[r.length - 1] = e[f++]
}, , function () {
//console.log('u15')
let tmp = r.pop()
console.log(`将栈顶两个元素弹出,将 ${r[r.length - 1]} mod ${tmp} ,结果 ${r[r.length - 1] % tmp} 入栈`)

r[r.length - 1] = r[r.length - 1] % tmp
}, function () {
//console.log('u16')
console.log('向栈末尾压入一个空字符串')
r.push("")
}, function () {
//console.log('u17')
console.log('指针跳转到' + (e[f]))
f = e[f++]
}, , , , , , , function () {
//console.log('u24')

var top1 = r.pop();
let top2 = r.pop()
console.log('将', [r[top2][0], top1], '入栈')
r.push([r[top2][0], top1])
}, function () {
//console.log('u25')
var n = e[f++];
if (r[n] === undefined) {
console.log(`r[${n}] 初始化为 []`)
r[n] = []
} else {
console.log(`r[${n}] 不变,值为:`, r[n])
}
}, , , , , , function () {
//console.log('u31')

var n = e[f++], t = r[r.length - 2 - n];
console.log('取出当前指针所指的值', n)
console.log('取出栈中第', 2 + n, '个元素', t)
console.log('与栈顶元素交换位置')
r[r.length - 2 - n] = r.pop(), r.push(t)
}, function () {
//console.log('u32')

var n = e[f++];
if (r[r.length - 1]) {
f = n
console.log('栈顶条件为 true,指针跳转到 ', n)
} else {
console.log('栈顶条件为 false,什么也不做')
}
}, function () {
//console.log('u33')
console.log('改变栈的大小为:', e[f])
r.length = e[f++]
}, function () {
//console.log('u34')
let top1 = r.pop();
if (r[r.length - 1] >= top1) {
console.log('栈顶第二个元素比栈顶大')
r[r.length - 1] = true
} else {
console.log('栈顶第二个元素比栈顶小')
r[r.length - 1] = false
}
}, , , function () {
//console.log('u37')
console.log('单纯弹栈')
r.pop()
}, , , , function () {
//console.log('u41')
console.log('栈顶元素复制到位置 ', r[r.length - 2][0])
r[r[r.length - 2][0]][0] = r[r.length - 1]
}, , , function () {
//console.log('u44')
let top1 = r.pop()
console.log(`计算 ${top1}${r[r.length - 1]} 的乘积,结果为 ${r[r.length - 1] * top1}`)
r[r.length - 1] = r[r.length - 1] * top1
}, function () {
//console.log('u45')
let tmp = r.pop();
console.log('栈顶元素', tmp, '出栈,将 ', [c, tmp], '压栈')
r.push([c, tmp])
}, , , function () {
//console.log('u48')
let top1 = r.pop()
console.log('取 r[' + top1[0] + '] 即:', r[top1[0]], '的第一个,结果为', r[top1[0]][0], '并压栈')
r.push(r[top1[0]][0])
}, , , , function () {
//console.log('u52')

var n = e[f++], t = n ? r.slice(-n) : [];
console.log('调用函数的参数个数为', n, '分别是:', t)
r.length -= n;
var top1 = r.pop();
console.log('调用函数为', top1)
console.log('函数调用结果为:', top1[0][top1[1]].apply(top1[0], t))
r.push(top1[0][top1[1]].apply(top1[0], t))
}, function () {
//console.log('u53')
console.log(`取 r[${e[f]}]`, r[e[f]], '的第一个', '结果为', r[e[f]][0], '并压栈')

r.push(r[e[f++]][0])
}, , function () {
//console.log('u55')
console.log(`将指令 ${e[f]} 压栈`)
r.push(e[f++])
}, , function () {
//console.log('u57')

var n = r.pop();
console.log('取', n[0], '的', n[1], '结果为:', n[0][n[1]], '并压栈')
r.push(n[0][n[1]])
}, function () {
//console.log('u58')
console.log('复制栈顶元素', r[r.length - 1])
r.push(r[r.length - 1])
}, , , , , function () {
//console.log('u63')
console.log(`删掉栈顶 ${e[f]} 个元素`)

r.length -= e[f++]
}, , function () {
//console.log('u65')

var n = r.pop(),
t = r.pop();
console.log('弹出两个元素', n, t)
console.log('取', t[0], '上的', t[1])
console.log('压入', [t[0][t[1]], n])
r.push([t[0][t[1]], n])
}, function () {
//console.log('u66')
let top1 = r.pop();
console.log(`栈顶两数相加 ${top1} + ${r[r.length - 1]} = ${r[r.length - 1] + top1}`)
r[r.length - 1] = r[r.length - 1] + top1
}, , function () {
//console.log('u68')
console.log('读入字符', String.fromCharCode(e[f]))
r[r.length - 1] += String.fromCharCode(e[f++])
}];
for (0; ;) try {
// 取值执行直到遇到终止标记
for (var p = !1; !p;) {
console.log('指针位置:', f, '指令:', e[f])
// f 是 PC 指针,e[f] 是函数
p = u[e[f++]]();
console.log('stack:', r)
console.log(' ')
cnt++;
}
if (0, o) throw o;
return n ? (r.pop(), r.slice(3 + __TENCENT_CHAOS_VM.v)) : r.pop()
} catch (i) {
0;
var h = t.pop();
if (h === undefined) throw i;
o = i, f = h[0], r.length = h[1], h[2] && (r[h[2]][0] = o)
}
}
__TENCENT_CHAOS_VM.v = 0;
return __TENCENT_CHAOS_VM(0, [33, 3, 25, 2, 16, 68, 119, 68, 105, 68, 110, 68, 100, 68, 111, 68, 119, 45, 16,
68, 67, 68, 65, 68, 49, 68, 56, 68, 48, 68, 55, 68, 69, 68, 66, 65, 17, 2426, 33, 7, 25, 2, 25, 3,
25, 4, 25, 5, 25, 6, 12, 4, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 0, 52,
1, 41, 12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45,
55, 1, 52, 1, 41, 31, 0, 63, 6, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 0, 65, 57, 34, 9, 32, 123, 37,
17, 243, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68,
54, 68, 54, 68, 49, 68, 53, 68, 57, 68, 52, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68,
105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68,
57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0,
12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 103, 12, 5, 55,
0, 41, 31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 1, 65, 57, 34, 9, 32, 272, 37, 17, 392,
12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 50, 68, 52, 68,
55, 68, 55, 68, 54, 68, 50, 68, 55, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68,
103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68,
57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58,
48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 252, 12, 4, 58, 48, 53, 6,
66, 41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68,
49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50,
68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66, 68, 105,
68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 1, 52, 1, 41, 31, 0, 63, 8, 12, 5, 48, 12, 3, 16, 68, 97,
24, 55, 2, 65, 57, 34, 9, 32, 511, 37, 17, 631, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73,
68, 110, 68, 116, 45, 16, 68, 54, 68, 56, 68, 55, 68, 56, 68, 55, 68, 57, 68, 52, 52, 1, 44, 41, 31,
0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49,
68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68,
57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0,
0, 63, 5, 37, 17, 491, 12, 5, 55, 0, 41, 31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 3, 65,
57, 34, 9, 32, 660, 37, 17, 780, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68,
116, 45, 16, 68, 55, 68, 53, 68, 52, 68, 54, 68, 51, 68, 54, 68, 52, 52, 1, 44, 41, 31, 0, 12, 6,
58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68,
53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55,
52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5,
37, 17, 640, 12, 4, 58, 48, 53, 6, 66, 41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68,
73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68,
48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 55, 0, 41,
31, 0, 12, 6, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 1, 52, 1, 41, 31, 0,
63, 8, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 4, 65, 57, 34, 9, 32, 899, 37, 17, 1019, 12, 6, 58, 48,
16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 50, 68, 57, 68, 57, 68, 49, 68,
57, 68, 49, 68, 57, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68,
110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68,
54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1,
31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 879, 12, 5, 55, 0, 41, 31, 0, 37, 37, 12,
5, 48, 12, 3, 16, 68, 97, 24, 55, 5, 65, 57, 34, 9, 32, 1048, 37, 17, 1168, 12, 6, 58, 48, 16, 68,
66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 50, 68, 49, 68, 56, 68, 50, 68, 54, 68,
52, 68, 51, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68,
116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56,
68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55,
1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 1028, 12, 4, 58, 48, 53, 6, 66, 41, 31, 0, 12, 4, 58,
48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53,
68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52,
1, 15, 41, 31, 0, 12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68,
116, 45, 55, 1, 52, 1, 41, 31, 0, 63, 8, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 6, 65, 57, 34, 9, 32,
1287, 37, 17, 1407, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16,
68, 55, 68, 57, 68, 51, 68, 48, 68, 48, 68, 57, 68, 52, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68,
66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68,
57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41,
31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 1267, 12,
5, 55, 0, 41, 31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 7, 65, 57, 34, 9, 32, 1436, 37,
17, 1556, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68,
52, 68, 52, 68, 52, 68, 56, 68, 54, 68, 49, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68,
105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68,
57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0,
12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 1416, 12, 4, 58,
48, 53, 6, 66, 41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45,
16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52,
68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66,
68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 1, 52, 1, 41, 31, 0, 63, 8, 12, 5, 48, 12, 3,
16, 68, 97, 24, 55, 8, 65, 57, 34, 9, 32, 1675, 37, 17, 1795, 12, 6, 58, 48, 16, 68, 66, 68, 105,
68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 53, 68, 53, 68, 57, 68, 54, 68, 48, 68, 50, 68, 52,
52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16,
68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68,
50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41,
37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 1655, 12, 5, 55, 0, 41, 31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68,
97, 24, 55, 9, 65, 57, 34, 9, 32, 1824, 37, 17, 1944, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103,
68, 73, 68, 110, 68, 116, 45, 16, 68, 54, 68, 50, 68, 52, 68, 54, 68, 56, 68, 55, 68, 51, 52, 1, 44,
41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49,
68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68,
53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0,
31, 0, 0, 63, 5, 37, 17, 1804, 12, 4, 58, 48, 53, 6, 66, 41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68,
105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68,
57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0,
12, 5, 55, 0, 41, 31, 0, 12, 6, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 55, 1,
52, 1, 41, 31, 0, 63, 8, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 10, 65, 57, 34, 9, 32, 2063, 37, 17,
2183, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 56, 68, 55,
68, 50, 68, 54, 68, 57, 68, 48, 68, 57, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105,
68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57,
68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5,
58, 48, 58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 2043, 12, 5, 55, 0, 41,
31, 0, 37, 37, 12, 5, 48, 12, 3, 16, 68, 97, 24, 55, 11, 65, 57, 34, 9, 32, 2212, 37, 17, 2332, 12,
6, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 53, 68, 56, 68, 49,
68, 49, 68, 55, 68, 55, 68, 51, 52, 1, 44, 41, 31, 0, 12, 6, 58, 48, 16, 68, 66, 68, 105, 68, 103,
68, 73, 68, 110, 68, 116, 45, 16, 68, 49, 68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57,
68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68, 53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 12, 5, 58, 48,
58, 31, 1, 31, 0, 55, 1, 66, 41, 37, 13, 0, 31, 0, 0, 63, 5, 37, 17, 2192, 12, 4, 58, 48, 53, 6, 66,
41, 31, 0, 12, 4, 58, 48, 16, 68, 66, 68, 105, 68, 103, 68, 73, 68, 110, 68, 116, 45, 16, 68, 49,
68, 49, 68, 50, 68, 53, 68, 56, 68, 57, 68, 57, 68, 57, 68, 48, 68, 54, 68, 56, 68, 52, 68, 50, 68,
53, 68, 57, 68, 55, 52, 1, 15, 41, 31, 0, 16, 68, 112, 68, 97, 68, 114, 68, 115, 68, 101, 68, 73,
68, 110, 68, 116, 45, 53, 4, 52, 1, 7, 5, 7, 63, 4, 3, 38, 0, 1, 3, 8, 31, 0, 5, 7, 37, 37], window)
}();
__TENCENT_CHAOS_STACK.g = function () {
return __TENCENT_CHAOS_STACK.shift()[0]
};

在 211 行打断点,让 PC 指针每次走一步,观察栈内数据以及输出信息。通过分析栈的数据变化可以还原出代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
window['CA1807EB'] = function (data) {
a = data.a
const c = [1661594, 2477627, 6878794, 7546364, 2991919,
2182643, 7930094, 1444861, 5596024, 6246873, 8726909, 5811773]
const mod = BigInt(1125899906842597)
let sum = BigInt(0)
let r = BigInt(1)
for (let i = 0; i < a.length; i++) {
if (i % 2 == 0) {
r = BigInt(1)
}
// 性能瓶颈
for (let j = 0; j < a[i]; j++) {
r = (BigInt(r) * BigInt(c[i])) % BigInt(mod)
}
if (i % 2) {
sum = (BigInt(sum) + BigInt(r)) % BigInt(mod);
}
}
return sum
}

发现程序的性能瓶颈在每次需要计算 c[i]a[i] 次幂,而且 a[i] 非常大:

1
2
3
4
5
6
7
{
"c": "CA1807EB",
"a": [
5486064, 8511586, 9476945, 4080739, 7386016, 5704516, 3957220, 3339369, 8809038, 2122839, 6764674, 8321732
],
"t": "00000770010000065AD93A837A9B19BE"
}

并且使用了高精度乘法,整体运算次数:sum(a)digits(a[i])digits(a[i])=7396073877=517725166sum(a) * digits(a[i]) * digits(a[i]) = 73960738 * 7 * 7 = 517725166,5 亿次需要 c++ 算 5 秒,更别说 js 加上虚拟机模拟运行字节码了。

使用快速幂进行优化,整体运算次数:log(sum(a))digits(a[i])=2677=1274log(sum(a)) * digits(a[i]) = 26 * 7 * 7 = 1274,脱离虚拟机,直接跑代码,完全可以在毫秒级别完成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function qmi(a, k, p) {
let res = BigInt(1);
while (BigInt(k)) {
if (BigInt(k) & BigInt(1)) res = (BigInt(res) * BigInt(a)) % BigInt(p);
a = (BigInt(a) * BigInt(a)) % BigInt(p);
k >>= BigInt(1);
}
return res;
}

window['CF40E3BB'] = function (data) {
a = data.a
const c = [
7743913, 3731977,
7867972, 8113101,
9391795, 8491495,
1619587, 8591126,
7049453, 4447947,
9340950, 6751127
]
const mod = BigInt(1125899906842597)
let sum = BigInt(0)
let r = BigInt(1)
for (let i = 0; i < a.length; i++) {
// r = 1
if (i % 2 == 0) {
r = BigInt(1)
}
r = r * qmi(c[i], BigInt(a[i]), BigInt(mod))
if (i % 2) {
sum = (BigInt(sum) + BigInt(r)) % BigInt(mod);
}
}
return sum
}

事情并不简单,每种树 1 万次,其中的 c 数组都会变化,如果完全手动修改,需要改 100 次。继续想办法自动化。

每次从服务器拉取问题的时候,c 的值是脚本名称,于是可以在发生答案错误之后,到服务器重新拉取最新的脚本:

1
2
3
4
5
6
7
{
"c": "CA1807EB",
"a": [
5486064, 8511586, 9476945, 4080739, 7386016, 5704516, 3957220, 3339369, 8809038, 2122839, 6764674, 8321732
],
"t": "00000770010000065AD93A837A9B19BE"
}

然后需要解决如何从字节码数组中读取 c 数组的所有值。可以使用正则表达式从脚本中取出字节码数组。

现在重头戏来了,需要从字节码数组中直接找出常数数组。

首先在指令 68 对应的虚拟机操作:读取 PC 指针处的数据,然后 PC 指针递增。在代码处打印 PC 指针的位置。

1
2
3
4
5
6
function () {
// console.log('u68')
console.log(f)
console.log('读入字符', String.fromCharCode(e[f]))
r[r.length - 1] += String.fromCharCode(e[f++])
}

再通过简单数据,执行一遍虚拟机代码:

1
2
3
4
5
6
7
{
"c": "CA1807EB",
"a": [
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
],
"t": "00000770010000065AD93A837A9B19BE"
}

找出所有虚拟机读取 7 位数字时的 PC 指针位置,PC 指针位置对应字节码数组中的元素下标。

经过观察,可以得到下表:

字节码数组下标 j 常数数组下标 i
143 0
292 1
531 2
680 3
919 4
1068 5
1307 6
1456 7
1695 8
1844 9
2083 10
2232 11

关系:c[i] = String.fromCharCode(e[j])

到此,可以自动化完成计算答案,自动更新常数数组的所有操作,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// utils.js
function getConst(e) {
let c = []
let map = {
0: 143,
1: 292,
2: 531,
3: 680,
4: 919,
5: 1068,
6: 1307,
7: 1456,
8: 1695,
9: 1844,
10: 2083,
11: 2232
}
for (let i = 0; i <= 11; i++) {
let j = map[i], cnt = 12;
let tmp = ''
while (cnt--) {
tmp += String.fromCharCode(e[j]);
j += 2;
}
c.push(parseInt(tmp))
}
return c
}

module.exports = getConst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// index.js
const axios = require('axios')
const getConst = require('./utils');
function qmi(a, k, p) {
let res = BigInt(1);
while (BigInt(k)) {
if (BigInt(k) & BigInt(1)) res = (BigInt(res) * BigInt(a)) % BigInt(p);
a = (BigInt(a) * BigInt(a)) % BigInt(p);
k >>= BigInt(1);
}
return res;
}
function calc(data, c) {
a = data.a

const mod = BigInt(1125899906842597)
let sum = BigInt(0)
let r = BigInt(1)
for (let i = 0; i < a.length; i++) {
if (i % 2 == 0) {
r = BigInt(1)
}
r = r * qmi(c[i], BigInt(a[i]), BigInt(mod))
if (i % 2) {
sum = (BigInt(sum) + BigInt(r)) % BigInt(mod);
}
}
return sum
}
let needUpdate = true
let c, e
async function go() {
while (true) {
let res = await axios.get('http://服务器地址:8081/pull?u=用户ID')
let data = res.data
// console.log(data)
if (needUpdate) {
let result = await axios.get('http://服务器地址:8080/' + data.c + '.js')
// console.log(result.data)
let exp = /__TENCENT_CHAOS_VM\(0\,\[(.*)\]\,window\)\}\(\)/
e = exp.exec(result.data)[1].split(',').map(item => parseInt(item))
c = getConst(e)
}
needUpdate = false
let ans = calc(data, c)

let res2 = await axios.get('http://服务器地址:8081/push', {
params: {
t: data.t,
a: parseInt(ans)
}
})
console.log(res2.data)
if (!res2.data.success) { needUpdate = true }
}
}

go()

成功种树到 2 百万棵,这时排名 28。

0x06 JS 栈式虚拟机

题目 6 F3B9B832.js

干不动了,字节码数组有 1.6MB。能做的也只是在服务器上挂个浏览器,点击一下按钮了。

写在最后

在比赛中经常看到有趣的现象,当大家没有进展的时候,就会用脚本傻瓜式点击提交按钮。虽然效率极慢,CPU 也会飙升 100%,但是为了获取当下靠前的名次,也只能靠这样的办法。内卷的根源在于大家都差不多,没有突破。在资源有限的情况下,依靠低效、自我压榨的方式汲取利益。高手不屑于内卷,高手只要破解题目,一跃而上,上了之后就有机会在更高层次内卷。

高端人才稀缺,低端人才过剩,无论属于哪个段位,无法突破时都在内卷

起初感觉这个闯关游戏很有意思,这也是很久以来为数不多的能够获得思维乐趣的事儿。我每天刷算法,一是防止自己变笨,二是要获得思维上的乐趣。须知参差多态,乃是幸福的本源。如果一个人每天都吃一样的饭,干一样的活,做表单、写接口、回答传参问题,他就能得到我的同情。

为了解出谜底千方百计地思考采取什么策略,如何破解还原题目,再优化算法,最后进行自动化。这种感觉似曾相识,让我联想起了 2019 年初刚刚参与创业的时候,那时候也是这样的心态。

第三题是一个 jsfuck 混淆后的代码。当一项技能不熟练的时候,用机械的方法和完善技能再用巧法解决问题的时间是差不多的。我和王同学分工,王同学去找巧法,我用机械方法,手动分批执行代码表达式,机械替换。当代码越来越清晰,一千行的代码缩短到 10 行,那种答案马上就要浮现的幻觉让我非常激动,后来莫名的答案错误,又让我非常沮丧,有一个微小的替换错误,经过修正之后能够完美运行。这让我联想到了 2019 下半年在创业公司的垃圾代码上屎上雕花痛不欲生,后来重构却只是把一坨屎搬到另一坨屎上。顺便发生系统故障,又没日没夜改的过程,好在是改回来了,改来改去,他风儿依旧拂过山岗,花开花落,春去秋来。直到 2020 年初完成第一轮融资,才算进入下一题。

第四题是一道汇编逆向题,我通过观察输入与输出数据的关系,绕过还原汇编代码的过程,直接挂在服务器上暴力破解一晚上种到 1 百万段位。这样的取巧让我会心一笑,这就是不走寻常路吧,有时候就是这样幻想。自以为取巧聪明,该来的还是会来。

出来混迟早要还的,下一题直接一道 JS 栈式虚拟机,别说汇编了,这就是在浏览器模拟操作系统运行机器码。首先将每个操作符的含义先破解出来,打上 log,然后在每次取指执行后打印堆栈信息。经过若干小时的记录、尝试,终于还原出了源码的部分意图,然而计算结果并不正确。再次研究那个混沌的堆栈虚拟机,有了之前的经验,结合条件断点调试起来就非常快了。终于逆向出全部的源码,提交通过的那一刻,就像考上清华一样高兴。

清华里面也要分个三六九等,脱离虚拟机后计算速度还是太慢了,经过观察,以及前些日子做过的快速幂算法,发现可以用快速幂来计算。这样一下要运行十几秒的代码可以在毫秒级别完成。开心提交,感觉这下能够到达终点,那终点是什么呢?好景不长,只种了一万棵树,后面题目脚本又变了,打开一看,还他娘的是虚拟机的题目,一直这么搞就没意思了吧?读了他妈 20 年书,到头来终点就是没日没夜的干,996,007?民以食为天,天大的事儿先吃饭。经过王同学的情报得知,题目应该只是变化了常数,算法本身没有变。经过一番折腾,发现确实只是变了常数数组。然后开始继续通过条件断点与打 log 的方式从代码中找出了的常数数组,替换常数后提交成功。一万棵树后脚本又变了,没劲,糟践人,此时只想说三个字,第一个字的读音和洗澡的澡字有些像。

为了不让出题人糟践我,手动操作一百次要累死,手动是不可能手动的,遂起一个 node 项目。这又让我联想到在公司赶时间上线的的日子,不禁叹了一口气。准备直接抓请求,自动拉取题目、计算、提交、判断脚本是否需要更换、正则匹配抓出机器码数组、在机器码中找出常数数组。经过一轮调试,可以自动化操作,大概过了半小时,种到了 2 百万段位。期间王同学听说 2 百万后面没有题目了,我松了一口气,不想再搞了,再也不想搞了。但看到排行榜上有人有 2 百万零 2 棵树,莫非是腾讯的 bug,区分谁是第一名?虽然心里可能已经知道了答案,但是还骗自己,后面应该没了。我又开始想入非非,联想到我曾经自己在心里给别人找借口,只是不愿相信那个结果罢了。也可以说是作为韭菜同情镰刀多么多么辛苦和不容易。

从 1 百万到 2 百万刷种树量的时候,看到我前面有一个人也在刷,比我多 8 万棵树。期间一直在刷新排行榜,看着差距慢慢缩小,最后只差几千棵,我能不能超过他呢?排行榜就是激发了我的攀比心理,我又联想到某多,绩效排名完全公示,心智越是不成熟的人越容易陷入其中。人性真是捉摸不透,人性真是简单直白。

2 百万段位达到之后,我再次点了种树按钮,结果又一个题目出现了。究竟什么时候才能完呢?我先看看内容,又他娘的的是一道虚拟机的题目,字节码有 1.6 MB,非要搞到所有人都精疲力竭不可?本来想终于结束,可以安心写写博客、做做饭、出去运动运动了,结果还在这没完没了,我合上电脑,去床上躺了一会儿,让自己的内心平复一下,再也没有能够刺激我神经的事物,神情麻木好似一个橡皮人。

这他妈简直就一个现实经历和人性的缩影。内心有些不甘,但我知道自己必须停下,卷不动,从虚拟世界退出,去现实世界生活。我要下楼买菜,回来做饭。此时排名 28。如果后来人有神仙把那道题做出来了呢?如果做自己想做的事情而收入下降了呢?如果我再坚持一下是不是能做的更好?谁给这个世界的节奏上了一个加速器?我还能保持在前 30 名吗?中国石油大楼里不舒服吗?我的脑子一片混乱,像极了混沌的执行栈和混沌的代码脚本。

欲望是没有尽头的,不管爬到哪座高峰,总会发现前面有人坐在更高的山峰,于是喘口气后接着攀登。最后爬到山顶的时候,不是累死,就是哀叹一声:原来不过如此。如果我这一生能参与点有趣的事,遇到点有趣的人就算没白活。就怕 20 多岁已死,等到 80 岁再埋。

完。

P.S. 后来一个排名靠后的人干掉了 2 百万 +1 题,跑到了前面,我和上一名差距太接近,每次刷新页面排名会随机前后颠倒。封榜排名 29。

P.S. 第六题服务器算了一个星期还没算出来。现在已经不再尝试。

榜单

榜单