SCTF-cython-wp

SCTF-cython-wp

记录下打SCTF遇到的一个python题,cython编译的pyd文件如果直接用IDA分析的话会非常的复杂,可能python代码一行就会在IDA里多出几十行出来,一些参数检查和类型转换的伪代码中嵌入很多goto的奇奇怪怪的控制流,无厘头的跳转会让人头皮发麻,我尝试用IDA静态分析结合动态调试调一下午大概分析出了sub14514会调用这几个用户定义的函数sub_50804,sub50520,然后最终的加密始终没办法很好的还原,只是察觉到这是个类似TEA的加密,但是循环次数又不对,最后在这放弃了,看到站队里大佬WP使用python注入的方式还原加密处代码,感觉挺有意思的,在这里复现下解题过程

获取py源码

附件是python打包的exe,按照流程正常解包,用pyinstxtractor.py脚本解包(最好用高版本的,低版本的解包出的pyc还需要自己修补文件头),运行指令

.\pyinstxtractor2.py .\ez_cython.exe

在ez_cython.exe_extracted里找到ez_cython.pyc文件进行反编译

uncompyle6 .\ez_cython.pyc

拿到ez_cython.py源代码

1
2
3
4
5
6
7
8
9
10
import cy

def str_hex(input_str):
return [ord(char) for char in input_str]

def mainParse error at or near `COME_FROM' instruction at offset 108_0

if __name__ == "__main__":
main()

发现有个报错信息mainParse error at or near `COME_FROM’ instruction at offset 108_0,dis提取字节码分析

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
 1           0 LOAD_CONST               0 (0)       
2 LOAD_CONST 1 (None)
4 IMPORT_NAME 0 (cy)
6 STORE_NAME 0 (cy)

3 8 LOAD_CONST 2 (<code object str_hex at 0x000001E06B3C2870, file "ez_cython.py", line 3>)
10 LOAD_CONST 3 ('str_hex')
12 MAKE_FUNCTION 0
14 STORE_NAME 1 (str_hex)

6 16 LOAD_CONST 4 (<code object main at 0x000001E06B3C2920, file "ez_cython.py", line 6>)
18 LOAD_CONST 5 ('main')
20 MAKE_FUNCTION 0
22 STORE_NAME 2 (main)

34 24 LOAD_NAME 3 (__name__)
26 LOAD_CONST 6 ('__main__')
28 COMPARE_OP 2 (==)
30 POP_JUMP_IF_FALSE 38

35 32 LOAD_NAME 2 (main)
34 CALL_FUNCTION 0
36 POP_TOP
>> 38 LOAD_CONST 1 (None)
40 RETURN_VALUE

Disassembly of <code object str_hex at 0x000001E06B3C2870, file "ez_cython.py", line 3>:
4 0 LOAD_CONST 1 (<code object <listcomp> at 0x000001E06B3C27C0, file "ez_cython.py", line 4>)
2 LOAD_CONST 2 ('str_hex.<locals>.<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_FAST 0 (input_str)
8 GET_ITER
10 CALL_FUNCTION 1
12 RETURN_VALUE

Disassembly of <code object <listcomp> at 0x000001E06B3C27C0, file "ez_cython.py", line 4>:
4 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 12 (to 18)
6 STORE_FAST 1 (char)
8 LOAD_GLOBAL 0 (ord)
10 LOAD_FAST 1 (char)
12 CALL_FUNCTION 1
14 LIST_APPEND 2
16 JUMP_ABSOLUTE 4
>> 18 RETURN_VALUE

Disassembly of <code object main at 0x000001E06B3C2920, file "ez_cython.py", line 6>:
7 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('欢迎来到猜谜游戏!')
4 CALL_FUNCTION 1
6 POP_TOP

8 8 LOAD_GLOBAL 0 (print)
10 LOAD_CONST 2 ("逐个输入字符进行猜测,直到 'end' 结束。")
12 CALL_FUNCTION 1
14 POP_TOP

11 >> 16 BUILD_LIST 0
18 STORE_FAST 0 (guess_chars)

13 >> 20 LOAD_GLOBAL 1 (input)
22 LOAD_CONST 3 ("请输入一个字符(输入 'end' 结束):")
24 CALL_FUNCTION 1
26 STORE_FAST 1 (char)

14 28 LOAD_FAST 1 (char)
30 LOAD_CONST 4 ('end')
32 COMPARE_OP 2 (==)
34 POP_JUMP_IF_FALSE 38

15 36 JUMP_ABSOLUTE 72

16 >> 38 LOAD_GLOBAL 2 (len)
40 LOAD_FAST 1 (char)
42 CALL_FUNCTION 1
44 LOAD_CONST 5 (1)
46 COMPARE_OP 2 (==)
48 POP_JUMP_IF_FALSE 62

17 50 LOAD_FAST 0 (guess_chars)
52 LOAD_METHOD 3 (append)
54 LOAD_FAST 1 (char)
56 CALL_METHOD 1
58 POP_TOP
60 JUMP_ABSOLUTE 20

19 >> 62 LOAD_GLOBAL 0 (print)
64 LOAD_CONST 6 ('请输入一个单独的字符。')
66 CALL_FUNCTION 1
68 POP_TOP
70 JUMP_ABSOLUTE 20

21 >> 72 LOAD_GLOBAL 4 (str_hex)
74 LOAD_CONST 7 ('')
76 LOAD_METHOD 5 (join)
78 LOAD_FAST 0 (guess_chars)
80 CALL_METHOD 1
82 CALL_FUNCTION 1
84 STORE_FAST 2 (guess_hex)

23 86 LOAD_GLOBAL 6 (cy)
88 LOAD_METHOD 7 (sub14514)
90 LOAD_FAST 2 (guess_hex)
92 CALL_METHOD 1
94 POP_JUMP_IF_FALSE 108

24 96 LOAD_GLOBAL 0 (print)
98 LOAD_CONST 8 ('真的好厉害!flag非你莫属')
100 CALL_FUNCTION 1
102 POP_TOP

25 104 JUMP_ABSOLUTE 140
106 JUMP_ABSOLUTE 16

27 >> 108 LOAD_GLOBAL 0 (print)
110 LOAD_CONST 9 ('不好意思,错了哦。')
112 CALL_FUNCTION 1
114 POP_TOP

28 116 LOAD_GLOBAL 1 (input)
118 LOAD_CONST 10 ('是否重新输入?(y/n):')
120 CALL_FUNCTION 1
122 STORE_FAST 3 (retry)

29 124 LOAD_FAST 3 (retry)
126 LOAD_METHOD 8 (lower)
128 CALL_METHOD 0
130 LOAD_CONST 11 ('y')
132 COMPARE_OP 3 (!=)
134 POP_JUMP_IF_FALSE 16

30 136 JUMP_ABSOLUTE 140
138 JUMP_ABSOLUTE 16

32 >> 140 LOAD_GLOBAL 0 (print)
142 LOAD_CONST 12 ('游戏结束')
144 CALL_FUNCTION 1
146 POP_TOP
148 LOAD_CONST 0 (None)
150 RETURN_VALUE

得到python字节码,扔给GPT要一份py源码

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
import cy

def str_hex(input_str):
return ''.join([ord(char) for char in input_str])

def main():
print("欢迎来到猜谜游戏!")
print("逐个输入字符进行猜测,直到 'end' 结束。")

guess_chars = []

while True:
char = input("请输入一个字符(输入 'end' 结束):")

if char == 'end':
break

if len(char) == 1:
guess_chars.append(char)
else:
print("请输入一个单独的字符。")

guess_hex = str_hex(''.join(guess_chars))

if cy.sub14514(guess_hex):
print("真的好厉害!flag非你莫属")
else:
print("不好意思,错了哦。")
retry = input("是否重新输入?(y/n):")
if retry.lower() == 'y':
main()

print("游戏结束")

if __name__ == "__main__":
main()

可以看到这里导入了cy这个库,在解包文件夹里找到 cy.cp38-win_amd64.pyd 文件,放到py文件的同级目录下运行,运行报错发现GPT给的str_hex函数有问题,替换成uncompyle6给的定义,成功运行

image-20241008102137691

分析程序

main函数大致运行逻辑是让用户输入一个字符,然后将字符加入到列表list中,然后在用户输入end之后对这个列表转换成十六进制,并在cy模块里的sub14514函数进行验证,不成功则提示是否重新输入。所以主要验证逻辑在cy模块中,先进入IDA里分析该pyd模块,找到字符串sub14514交叉引用定位到该函数执行入口,对应的是IDA里的sub_180009420函数

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
__int64 __fastcall sub_180009420(__int64 a1, __int64 a2)
{
__int64 v2; // rdi
__int64 v3; // r14
_QWORD *v4; // r15
_QWORD *v5; // r13
_QWORD *v6; // r12
_QWORD *Item_KnownHash; // rbx
__int64 v8; // rsi
__int64 v9; // rsi
unsigned int v10; // esi
unsigned int v11; // r14d
_QWORD *v12; // rsi
_QWORD *v13; // rax
_QWORD *v14; // rcx
bool v15; // zf
__int64 v16; // rax
__int64 v17; // rdx
__int64 v18; // r8
__int64 v19; // rbp
__int64 v20; // rdx
__int64 (__fastcall *v21)(__int64, __int64); // r8
_QWORD *Attr; // rax
__int64 v23; // rdx
_QWORD *v24; // rsi
_QWORD *v25; // r14
__int64 v26; // rax
__int64 v27; // rbp
__int64 v28; // rax
_QWORD *v29; // rbp
_QWORD *v30; // r8
__int64 v31; // rdx
__int64 (__fastcall *v32)(__int64, __int64); // r8
_QWORD *v33; // rax
__int64 v34; // rdx
_QWORD *v35; // rsi
_QWORD *v36; // r14
__int64 v37; // rax
__int64 v38; // r14
__int64 v39; // rcx
__int64 v40; // rsi
_QWORD *v41; // rsi
int v42; // ecx
_QWORD *v43; // rax
_QWORD *v44; // rcx
__int64 v45; // r14
_QWORD *v46; // rsi
__int64 v47; // rax
__int64 v48; // rdx
__int64 v49; // r8
_QWORD *v52; // [rsp+20h] [rbp-98h]
_QWORD *v53; // [rsp+28h] [rbp-90h]
_QWORD *v54; // [rsp+30h] [rbp-88h]
_QWORD *v55; // [rsp+38h] [rbp-80h] BYREF
__int64 v56; // [rsp+40h] [rbp-78h] BYREF
_QWORD *v57; // [rsp+48h] [rbp-70h] BYREF
__int64 v58; // [rsp+50h] [rbp-68h] BYREF
_QWORD *v59; // [rsp+58h] [rbp-60h] BYREF
_QWORD v60[2]; // [rsp+60h] [rbp-58h] BYREF
_QWORD v61[2]; // [rsp+70h] [rbp-48h] BYREF

v2 = 0LL;
v3 = a2;
v4 = 0LL;
v53 = 0LL;
v5 = 0LL;
v54 = 0LL;
v6 = 0LL;
if ( qword_180011EC8 == *(_QWORD *)(*(_QWORD *)off_1800108B8 + 24LL) )
{
if ( qword_180011E80 )
{
++*(_QWORD *)qword_180011E80;
Item_KnownHash = (_QWORD *)qword_180011E80;
}
else
{
v8 = *((_QWORD *)off_1800108B8 + 10);
Item_KnownHash = (_QWORD *)sub_1800067B0(*((_QWORD *)off_1800108B8 + 1), v8);
if ( !Item_KnownHash && !PyErr_Occurred() )
PyErr_Format(PyExc_NameError, aNameUIsNotDefi, v8);
}
}
else
{
v9 = *((_QWORD *)off_1800108B8 + 10);
Item_KnownHash = (_QWORD *)PyDict_GetItem_KnownHash(*(_QWORD *)off_1800108B8, v9, *(_QWORD *)(v9 + 24));
qword_180011EC8 = *(_QWORD *)(*(_QWORD *)off_1800108B8 + 24LL);
qword_180011E80 = (__int64)Item_KnownHash;
if ( Item_KnownHash )
{
++*Item_KnownHash;
}
else if ( PyErr_Occurred() )
{
Item_KnownHash = 0LL;
}
else
{
Item_KnownHash = (_QWORD *)sub_180006740(v9);
}
}
if ( !Item_KnownHash )
{
v10 = 30;
v11 = 4240;
goto LABEL_89;
}
v12 = 0LL;
if ( Item_KnownHash[1] == PyMethod_Type && (v12 = (_QWORD *)Item_KnownHash[3]) != 0LL )
{
v13 = (_QWORD *)Item_KnownHash[2];
v14 = Item_KnownHash;
++*v12;
Item_KnownHash = v13;
++*v13;
v15 = (*v14)-- == 1LL;
if ( v15 )
Py_Dealloc(v14, a2, 0LL);
v55 = v12;
v56 = 0LL;
v16 = sub_180005530(Item_KnownHash, &v55, 1LL);
v15 = (*v12)-- == 1LL;
v19 = v16;
if ( v15 )
Py_Dealloc(v12, v17, v18);
}
else
{
v55 = v12;
v56 = 0LL;
v19 = sub_180005530(Item_KnownHash, &v56, 0LL);
}
if ( !v19 )
{
v10 = 30;
v11 = 4260;
LABEL_82:
if ( Item_KnownHash )
{
v15 = (*Item_KnownHash)-- == 1LL;
if ( v15 )
Py_Dealloc(Item_KnownHash, v17, v18);
}
LABEL_89:
sub_180002700(aCySub14514, v11, v10, aCyPy_0);
v29 = v53;
v46 = v54;
if ( !v4 )
goto LABEL_94;
goto LABEL_92;
}
v15 = (*Item_KnownHash)-- == 1LL;
if ( v15 )
Py_Dealloc(Item_KnownHash, v17, v18);
v4 = (_QWORD *)v19;
v20 = *((_QWORD *)off_1800108B8 + 32);
v21 = *(__int64 (__fastcall **)(__int64, __int64))(*(_QWORD *)(v19 + 8) + 144LL);
if ( v21 )
Attr = (_QWORD *)v21(v19, v20);
else
Attr = (_QWORD *)PyObject_GetAttr(v19, v20);
Item_KnownHash = Attr;
if ( !Attr )
{
v10 = 31;
v11 = 4274;
goto LABEL_89;
}
v24 = 0LL;
if ( Attr[1] == PyMethod_Type && (v24 = (_QWORD *)Attr[3]) != 0LL )
{
v25 = (_QWORD *)Attr[2];
++*v24;
++*v25;
v15 = (*Attr)-- == 1LL;
if ( v15 )
Py_Dealloc(Attr, v23, 0LL);
v57 = v24;
v58 = 0LL;
v26 = sub_180005530(v25, &v57, 1LL);
v15 = (*v24)-- == 1LL;
v27 = v26;
Item_KnownHash = v25;
if ( v15 )
Py_Dealloc(v24, v17, v18);
v3 = a2;
}
else
{
v57 = v24;
v58 = 0LL;
v27 = sub_180005530(Attr, &v58, 0LL);
}
if ( !v27 )
{
v10 = 31;
v11 = 4294;
goto LABEL_82;
}
v15 = (*Item_KnownHash)-- == 1LL;
if ( v15 )
Py_Dealloc(Item_KnownHash, v17, v18);
v10 = 32;
v5 = (_QWORD *)v27;
v28 = PyList_New(32LL);
v29 = (_QWORD *)v28;
if ( !v28 )
{
v11 = 4308;
goto LABEL_89;
}
v30 = off_1800108B8;
++**((_QWORD **)off_1800108B8 + 107);
**(_QWORD **)(v28 + 24) = v30[107];
++*(_QWORD *)v30[104];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 8LL) = v30[104];
++*(_QWORD *)v30[87];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 16LL) = v30[87];
++*(_QWORD *)v30[83];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 24LL) = v30[83];
++*(_QWORD *)v30[88];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 32LL) = v30[88];
++*(_QWORD *)v30[82];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 40LL) = v30[82];
++*(_QWORD *)v30[89];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 48LL) = v30[89];
++*(_QWORD *)v30[108];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 56LL) = v30[108];
++*(_QWORD *)v30[99];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 64LL) = v30[99];
++*(_QWORD *)v30[101];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 72LL) = v30[101];
++*(_QWORD *)v30[90];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 80LL) = v30[90];
++*(_QWORD *)v30[96];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 88LL) = v30[96];
++*(_QWORD *)v30[95];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 96LL) = v30[95];
++*(_QWORD *)v30[84];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 104LL) = v30[84];
++*(_QWORD *)v30[86];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 112LL) = v30[86];
++*(_QWORD *)v30[91];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 120LL) = v30[91];
v53 = (_QWORD *)v28;
++*(_QWORD *)v30[105];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 128LL) = v30[105];
++*(_QWORD *)v30[97];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 136LL) = v30[97];
++*(_QWORD *)v30[106];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 144LL) = v30[106];
++*(_QWORD *)v30[81];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 152LL) = v30[81];
++*(_QWORD *)v30[77];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 160LL) = v30[77];
++*(_QWORD *)v30[102];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 168LL) = v30[102];
++*(_QWORD *)v30[109];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 176LL) = v30[109];
++*(_QWORD *)v30[92];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 184LL) = v30[92];
++*(_QWORD *)v30[78];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 192LL) = v30[78];
++*(_QWORD *)v30[100];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 200LL) = v30[100];
++*(_QWORD *)v30[93];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 208LL) = v30[93];
++*(_QWORD *)v30[79];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 216LL) = v30[79];
++*(_QWORD *)v30[103];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 224LL) = v30[103];
++*(_QWORD *)v30[80];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 232LL) = v30[80];
++*(_QWORD *)v30[85];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 240LL) = v30[85];
++*(_QWORD *)v30[94];
*(_QWORD *)(*(_QWORD *)(v28 + 24) + 248LL) = v30[94];
v31 = v30[24];
v32 = *(__int64 (__fastcall **)(__int64, __int64))(*(_QWORD *)(v3 + 8) + 144LL);
if ( v32 )
v33 = (_QWORD *)v32(v3, v31);
else
v33 = (_QWORD *)PyObject_GetAttr(v3, v31);
Item_KnownHash = v33;
if ( !v33 )
{
v10 = 33;
v11 = 4416;
goto LABEL_89;
}
v35 = 0LL;
if ( v33[1] == PyMethod_Type && (v35 = (_QWORD *)v33[3]) != 0LL )
{
v36 = (_QWORD *)v33[2];
++*v35;
v52 = v36;
++*v36;
v15 = (*v33)-- == 1LL;
if ( v15 )
Py_Dealloc(v33, v34, 0LL);
v59 = v35;
v60[0] = 0LL;
v37 = sub_180005530(v36, &v59, 1LL);
v15 = (*v35)-- == 1LL;
v38 = v37;
Item_KnownHash = v52;
if ( v15 )
Py_Dealloc(v35, v17, v18);
}
else
{
v59 = v35;
v60[0] = 0LL;
v38 = sub_180005530(v33, v60, 0LL);
}
if ( !v38 )
{
v10 = 33;
v11 = 4436;
goto LABEL_82;
}
v15 = (*Item_KnownHash)-- == 1LL;
if ( v15 )
Py_Dealloc(Item_KnownHash, v17, v18);
v6 = (_QWORD *)v38;
if ( qword_180011EA0 == *(_QWORD *)(*(_QWORD *)off_1800108B8 + 24LL) )
{
if ( qword_180011E78 )
{
++*(_QWORD *)qword_180011E78;
Item_KnownHash = (_QWORD *)qword_180011E78;
goto LABEL_70;
}
v39 = *((_QWORD *)off_1800108B8 + 56);
}
else
{
v40 = *((_QWORD *)off_1800108B8 + 56);
Item_KnownHash = (_QWORD *)PyDict_GetItem_KnownHash(*(_QWORD *)off_1800108B8, v40, *(_QWORD *)(v40 + 24));
qword_180011EA0 = *(_QWORD *)(*(_QWORD *)off_1800108B8 + 24LL);
qword_180011E78 = (__int64)Item_KnownHash;
if ( Item_KnownHash )
{
++*Item_KnownHash;
goto LABEL_70;
}
if ( PyErr_Occurred() )
{
Item_KnownHash = 0LL;
goto LABEL_70;
}
v39 = v40;
}
Item_KnownHash = (_QWORD *)sub_180006740(v39);
LABEL_70:
if ( !Item_KnownHash )
{
v10 = 34;
v11 = 4449;
goto LABEL_89;
}
v41 = 0LL;
v42 = 0;
if ( Item_KnownHash[1] == PyMethod_Type )
{
v41 = (_QWORD *)Item_KnownHash[3];
if ( v41 )
{
v43 = (_QWORD *)Item_KnownHash[2];
v44 = Item_KnownHash;
++*v41;
Item_KnownHash = v43;
++*v43;
v15 = (*v44)-- == 1LL;
if ( v15 )
Py_Dealloc(v44, v17, v18);
v42 = 1;
}
}
v60[1] = v41;
v61[0] = v38;
v61[1] = v5;
v45 = sub_180005530(Item_KnownHash, &v61[-v42], (unsigned int)(v42 + 2));
if ( v41 )
{
v15 = (*v41)-- == 1LL;
if ( v15 )
Py_Dealloc(v41, v17, v18);
}
if ( !v45 )
{
v10 = 34;
v11 = 4469;
goto LABEL_82;
}
v15 = (*Item_KnownHash)-- == 1LL;
if ( v15 )
Py_Dealloc(Item_KnownHash, v17, v18);
v54 = (_QWORD *)v45;
v46 = (_QWORD *)v45;
v47 = PyObject_RichCompare(v45, v29, 2LL);
if ( !v47 )
{
v10 = 35;
v11 = 4482;
goto LABEL_89;
}
v2 = v47;
LABEL_92:
v15 = (*v4)-- == 1LL;
if ( v15 )
Py_Dealloc(v4, v48, v49);
LABEL_94:
if ( v5 )
{
v15 = (*v5)-- == 1LL;
if ( v15 )
Py_Dealloc(v5, v48, v49);
}
if ( v29 )
{
v15 = (*v29)-- == 1LL;
if ( v15 )
Py_Dealloc(v29, v48, v49);
}
if ( v6 )
{
v15 = (*v6)-- == 1LL;
if ( v15 )
Py_Dealloc(v6, v48, v49);
}
if ( v46 )
{
v15 = (*v46)-- == 1LL;
if ( v15 )
Py_Dealloc(v46, v48, v49);
}
return v2;
}

在这里可以看出这个pyd的编写应该也是用python写的,而不是C,根据GPT描述,

虽然.pyd文件通常是用C或C++编写的,但你可以使用Python来生成.pyd文件,通过使用工具和库如Cython或pybind11,它们允许你将Python代码编译成C扩展,从而生成.pyd文件。

既然源码是用python写的,而且这个sub_14514接受的参数是python里的list类,那么就可以考虑自己定义一个类似list的类,然后重写list的成员函数,从而在加密过程的时候如果调用了这个成员函数,那么就会进入到我们自己定义的函数中,如果我们自己在定义的时候打印调试信息显示这一步在干什么,我们是不是就能通过调试信息获取整个加密流程呢?

怎么重写呢?在C++里我们可以先父类继承,子类定义同名函数(参数列表也必须相同),从而实现重写函数,那么在python中也可以通过类似的方法实现重写,比如说定义一个自己的AList类继承自list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class AList(list):
def __init__(self, nums):
self.nums = [Symbol(str(num)) for num in nums]
def __getitem__(self, key):
return self.nums[key]
def copy(self):
return AList(self.nums)
def __len__(self):
return len(self.nums)
def __setitem__(self, key, value):
print(f"new_{self.nums[key]} = {value}")
self.nums[key] = Symbol(f"new_{self.nums[key].name}")
def __eq__(self, other):
print(f"{self.nums} == {other}")
return self.nums == other

随后在定义一个列表里的数据类型,重写数据间的运算方法

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
class Symbol:
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
def __rshift__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} >> {other.name})")
else:
expression = Symbol(f"({self.name} >> {other})")
return expression
def __lshift__(self, other):
if isinstance(other, Symbol):#判断数据是否是Symbol类,如果不是说明是常数
expression = Symbol(f"({self.name} << {other.name})")
else:
expression = Symbol(f"({self.name} << {other})")
return expression
def __rxor__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} ^ {other.name})")
else:
expression = Symbol(f"({self.name} ^ {other})")
return expression
def __xor__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} ^ {other.name})")
else:
expression = Symbol(f"({self.name} ^ {other})")
return expression
def __add__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} + {other.name})")
else:
expression = Symbol(f"({self.name} + {other})")
return expression
def __and__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} & {other.name})")
else:
expression = Symbol(f"({self.name} & {other})")
return expression

把列表类和数据类定义好之后,准备注入到sub14514函数。注入前我们还需要知道明文(str2hex之后的)长度,在IDA里动调分析一下,xdbg附加,下断,定位,发现程序验证的时候会首先调用某个get_key函数

image-20241008203923170

直接动调或者源码调用这个函数可以看到该函数返回了一个list的类型,值为SyC10VeRf0RVer,接着往下定位到对比函数

image-20241008210332510

把参数密文copy下来,发现刚好32个

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
00000212D2E33 00000212D329B850 P¸)Ó.... 
00000212D2E33 00000212D329B7F0 ð·)Ó....
00000212D2E33 00000212D329B5D0 е)Ó....
00000212D2E33 00000212D329B530 0µ)Ó....
00000212D2E33 00000212D329B5F0 ðµ)Ó....
00000212D2E33 00000212D329B510 .µ)Ó....
00000212D2E33 00000212D329B610 .¶)Ó....
00000212D2E33 00000212D329B870 p¸)Ó....
00000212D2E33 00000212D329B750 P·)Ó....
00000212D2E33 00000212D329B790 .·)Ó....
00000212D2E33 00000212D329B630 0¶)Ó....
00000212D2E33 00000212D329B6F0 ð¶)Ó....
00000212D2E33 00000212D329B6D0 ж)Ó....
00000212D2E33 00000212D329B570 pµ)Ó....
00000212D2E33 00000212D329B5B0 °µ)Ó....
00000212D2E33 00000212D329B650 P¶)Ó....
00000212D2E33 00000212D329B810 .¸)Ó....
00000212D2E33 00000212D329B710 .·)Ó....
00000212D2E33 00000212D329B830 0¸)Ó....
00000212D2E33 00000212D329B4F0 ð´)Ó....
00000212D2E33 00000212D328C5B0 °Å(Ó....
00000212D2E33 00000212D329B7B0 °·)Ó....
00000212D2E33 00000212D329B890 .¸)Ó....
00000212D2E33 00000212D329B670 p¶)Ó....
00000212D2E33 00000212D329B490 .´)Ó....
00000212D2E33 00000212D329B770 p·)Ó....
00000212D2E33 00000212D329B690 .¶)Ó....
00000212D2E33 00000212D329B4B0 °´)Ó....
00000212D2E33 00000212D329B7D0 з)Ó....
00000212D2E33 00000212D329B4D0 д)Ó....
00000212D2E33 00000212D329B590 .µ)Ó....
00000212D2E33 00000212D329B6B0 °¶)Ó....

有此信息我们就可以编写脚本注入函数查看32个值的加密流程,运行的脚本如下

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
import cy

class Symbol:
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
def __rshift__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} >> {other.name})")
else:
expression = Symbol(f"({self.name} >> {other})")
return expression
def __lshift__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} << {other.name})")
else:
expression = Symbol(f"({self.name} << {other})")
return expression
def __rxor__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} ^ {other.name})")
else:
expression = Symbol(f"({self.name} ^ {other})")
return expression
def __xor__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} ^ {other.name})")
else:
expression = Symbol(f"({self.name} ^ {other})")
return expression
def __add__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} + {other.name})")
else:
expression = Symbol(f"({self.name} + {other})")
return expression
def __and__(self, other):
if isinstance(other, Symbol):
expression = Symbol(f"({self.name} & {other.name})")
else:
expression = Symbol(f"({self.name} & {other})")
return expression

class AList(list):
def __init__(self, nums):
self.nums = [Symbol(str(num)) for num in nums]
def __getitem__(self, key):
return self.nums[key]
def copy(self):
return AList(self.nums)
def __len__(self):
return len(self.nums)
def __setitem__(self, key, value):
print(f"new_{self.nums[key]} = {value}")
self.nums[key] = Symbol(f"new_{self.nums[key].name}")
def __eq__(self, other):
print(f"{self.nums} == {other}")
return self.nums == other

inp = AList([f"a[{i}]" for i in range(32)])
res = cy.sub14514(inp)

if __name__ == '__main__':
print(res)

有关列表的加密流程:

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
s5[0] = ((a[0] + ((((a[31] >> 3) ^ (a[1] << 3)) + ((a[1] >> 4) ^ (a[31] << 2))) ^ ((a[1] ^ 2654435769) + (a[31] ^ 49)))) & 4294967295)
s5[1] = ((a[1] + ((((s5[0] >> 3) ^ (a[2] << 3)) + ((a[2] >> 4) ^ (s5[0] << 2))) ^ ((a[2] ^ 2654435769) + (s5[0] ^ 49)))) & 4294967295)
s5[2] = ((a[2] + ((((s5[1] >> 3) ^ (a[3] << 3)) + ((a[3] >> 4) ^ (s5[1] << 2))) ^ ((a[3] ^ 2654435769) + (s5[1] ^ 121)))) & 4294967295)
s5[3] = ((a[3] + ((((s5[2] >> 3) ^ (a[4] << 3)) + ((a[4] >> 4) ^ (s5[2] << 2))) ^ ((a[4] ^ 2654435769) + (s5[2] ^ 121)))) & 4294967295)
s5[4] = ((a[4] + ((((s5[3] >> 3) ^ (a[5] << 3)) + ((a[5] >> 4) ^ (s5[3] << 2))) ^ ((a[5] ^ 2654435769) + (s5[3] ^ 49)))) & 4294967295)
s5[5] = ((a[5] + ((((s5[4] >> 3) ^ (a[6] << 3)) + ((a[6] >> 4) ^ (s5[4] << 2))) ^ ((a[6] ^ 2654435769) + (s5[4] ^ 49)))) & 4294967295)
s5[6] = ((a[6] + ((((s5[5] >> 3) ^ (a[7] << 3)) + ((a[7] >> 4) ^ (s5[5] << 2))) ^ ((a[7] ^ 2654435769) + (s5[5] ^ 121)))) & 4294967295)
s5[7] = ((a[7] + ((((s5[6] >> 3) ^ (a[8] << 3)) + ((a[8] >> 4) ^ (s5[6] << 2))) ^ ((a[8] ^ 2654435769) + (s5[6] ^ 121)))) & 4294967295)
s5[8] = ((a[8] + ((((s5[7] >> 3) ^ (a[9] << 3)) + ((a[9] >> 4) ^ (s5[7] << 2))) ^ ((a[9] ^ 2654435769) + (s5[7] ^ 49)))) & 4294967295)
s5[9] = ((a[9] + ((((s5[8] >> 3) ^ (a[10] << 3)) + ((a[10] >> 4) ^ (s5[8] << 2))) ^ ((a[10] ^ 2654435769) + (s5[8] ^ 49)))) & 4294967295)
s5[10] = ((a[10] + ((((s5[9] >> 3) ^ (a[11] << 3)) + ((a[11] >> 4) ^ (s5[9] << 2))) ^ ((a[11] ^ 2654435769) + (s5[9] ^ 121)))) & 4294967295)
s5[11] = ((a[11] + ((((s5[10] >> 3) ^ (a[12] << 3)) + ((a[12] >> 4) ^ (s5[10] << 2))) ^ ((a[12] ^ 2654435769) + (s5[10] ^ 121)))) & 4294967295)
s5[12] = ((a[12] + ((((s5[11] >> 3) ^ (a[13] << 3)) + ((a[13] >> 4) ^ (s5[11] << 2))) ^ ((a[13] ^ 2654435769) + (s5[11] ^ 49)))) & 4294967295)
s5[13] = ((a[13] + ((((s5[12] >> 3) ^ (a[14] << 3)) + ((a[14] >> 4) ^ (s5[12] << 2))) ^ ((a[14] ^ 2654435769) + (s5[12] ^ 49)))) & 4294967295)
s5[14] = ((a[14] + ((((s5[13] >> 3) ^ (a[15] << 3)) + ((a[15] >> 4) ^ (s5[13] << 2))) ^ ((a[15] ^ 2654435769) + (s5[13] ^ 121)))) & 4294967295)
s5[15] = ((a[15] + ((((s5[14] >> 3) ^ (a[16] << 3)) + ((a[16] >> 4) ^ (s5[14] << 2))) ^ ((a[16] ^ 2654435769) + (s5[14] ^ 121)))) & 4294967295)
s5[16] = ((a[16] + ((((s5[15] >> 3) ^ (a[17] << 3)) + ((a[17] >> 4) ^ (s5[15] << 2))) ^ ((a[17] ^ 2654435769) + (s5[15] ^ 49)))) & 4294967295)
s5[17] = ((a[17] + ((((s5[16] >> 3) ^ (a[18] << 3)) + ((a[18] >> 4) ^ (s5[16] << 2))) ^ ((a[18] ^ 2654435769) + (s5[16] ^ 49)))) & 4294967295)
s5[18] = ((a[18] + ((((s5[17] >> 3) ^ (a[19] << 3)) + ((a[19] >> 4) ^ (s5[17] << 2))) ^ ((a[19] ^ 2654435769) + (s5[17] ^ 121)))) & 4294967295)
s5[19] = ((a[19] + ((((s5[18] >> 3) ^ (a[20] << 3)) + ((a[20] >> 4) ^ (s5[18] << 2))) ^ ((a[20] ^ 2654435769) + (s5[18] ^ 121)))) & 4294967295)
s5[20] = ((a[20] + ((((s5[19] >> 3) ^ (a[21] << 3)) + ((a[21] >> 4) ^ (s5[19] << 2))) ^ ((a[21] ^ 2654435769) + (s5[19] ^ 49)))) & 4294967295)
s5[21] = ((a[21] + ((((s5[20] >> 3) ^ (a[22] << 3)) + ((a[22] >> 4) ^ (s5[20] << 2))) ^ ((a[22] ^ 2654435769) + (s5[20] ^ 49)))) & 4294967295)
s5[22] = ((a[22] + ((((s5[21] >> 3) ^ (a[23] << 3)) + ((a[23] >> 4) ^ (s5[21] << 2))) ^ ((a[23] ^ 2654435769) + (s5[21] ^ 121)))) & 4294967295)
s5[23] = ((a[23] + ((((s5[22] >> 3) ^ (a[24] << 3)) + ((a[24] >> 4) ^ (s5[22] << 2))) ^ ((a[24] ^ 2654435769) + (s5[22] ^ 121)))) & 4294967295)
s5[24] = ((a[24] + ((((s5[23] >> 3) ^ (a[25] << 3)) + ((a[25] >> 4) ^ (s5[23] << 2))) ^ ((a[25] ^ 2654435769) + (s5[23] ^ 49)))) & 4294967295)
s5[25] = ((a[25] + ((((s5[24] >> 3) ^ (a[26] << 3)) + ((a[26] >> 4) ^ (s5[24] << 2))) ^ ((a[26] ^ 2654435769) + (s5[24] ^ 49)))) & 4294967295)
s5[26] = ((a[26] + ((((s5[25] >> 3) ^ (a[27] << 3)) + ((a[27] >> 4) ^ (s5[25] << 2))) ^ ((a[27] ^ 2654435769) + (s5[25] ^ 121)))) & 4294967295)
s5[27] = ((a[27] + ((((s5[26] >> 3) ^ (a[28] << 3)) + ((a[28] >> 4) ^ (s5[26] << 2))) ^ ((a[28] ^ 2654435769) + (s5[26] ^ 121)))) & 4294967295)
s5[28] = ((a[28] + ((((s5[27] >> 3) ^ (a[29] << 3)) + ((a[29] >> 4) ^ (s5[27] << 2))) ^ ((a[29] ^ 2654435769) + (s5[27] ^ 49)))) & 4294967295)
s5[29] = ((a[29] + ((((s5[28] >> 3) ^ (a[30] << 3)) + ((a[30] >> 4) ^ (s5[28] << 2))) ^ ((a[30] ^ 2654435769) + (s5[28] ^ 49)))) & 4294967295)
s5[30] = ((a[30] + ((((s5[29] >> 3) ^ (a[31] << 3)) + ((a[31] >> 4) ^ (s5[29] << 2))) ^ ((a[31] ^ 2654435769) + (s5[29] ^ 121)))) & 4294967295)
s5[31] = ((a[31] + ((((s5[30] >> 3) ^ (s5[0] << 3)) + ((s5[0] >> 4) ^ (s5[30] << 2))) ^ ((s5[0] ^ 2654435769) + (s5[30] ^ 121)))) & 4294967295)
s4[0] = ((s5[0] + ((((s5[31] >> 3) ^ (s5[1] << 3)) + ((s5[1] >> 4) ^ (s5[31] << 2))) ^ ((s5[1] ^ 1013904242) + (s5[31] ^ 67)))) & 4294967295)
s4[1] = ((s5[1] + ((((s4[0] >> 3) ^ (s5[2] << 3)) + ((s5[2] >> 4) ^ (s4[0] << 2))) ^ ((s5[2] ^ 1013904242) + (s4[0] ^ 67)))) & 4294967295)
s4[2] = ((s5[2] + ((((s4[1] >> 3) ^ (s5[3] << 3)) + ((s5[3] >> 4) ^ (s4[1] << 2))) ^ ((s5[3] ^ 1013904242) + (s4[1] ^ 83)))) & 4294967295)
s4[3] = ((s5[3] + ((((s4[2] >> 3) ^ (s5[4] << 3)) + ((s5[4] >> 4) ^ (s4[2] << 2))) ^ ((s5[4] ^ 1013904242) + (s4[2] ^ 83)))) & 4294967295)
s4[4] = ((s5[4] + ((((s4[3] >> 3) ^ (s5[5] << 3)) + ((s5[5] >> 4) ^ (s4[3] << 2))) ^ ((s5[5] ^ 1013904242) + (s4[3] ^ 67)))) & 4294967295)
s4[5] = ((s5[5] + ((((s4[4] >> 3) ^ (s5[6] << 3)) + ((s5[6] >> 4) ^ (s4[4] << 2))) ^ ((s5[6] ^ 1013904242) + (s4[4] ^ 67)))) & 4294967295)
s4[6] = ((s5[6] + ((((s4[5] >> 3) ^ (s5[7] << 3)) + ((s5[7] >> 4) ^ (s4[5] << 2))) ^ ((s5[7] ^ 1013904242) + (s4[5] ^ 83)))) & 4294967295)
s4[7] = ((s5[7] + ((((s4[6] >> 3) ^ (s5[8] << 3)) + ((s5[8] >> 4) ^ (s4[6] << 2))) ^ ((s5[8] ^ 1013904242) + (s4[6] ^ 83)))) & 4294967295)
s4[8] = ((s5[8] + ((((s4[7] >> 3) ^ (s5[9] << 3)) + ((s5[9] >> 4) ^ (s4[7] << 2))) ^ ((s5[9] ^ 1013904242) + (s4[7] ^ 67)))) & 4294967295)
s4[9] = ((s5[9] + ((((s4[8] >> 3) ^ (s5[10] << 3)) + ((s5[10] >> 4) ^ (s4[8] << 2))) ^ ((s5[10] ^ 1013904242) + (s4[8] ^ 67)))) & 4294967295)
s4[10] = ((s5[10] + ((((s4[9] >> 3) ^ (s5[11] << 3)) + ((s5[11] >> 4) ^ (s4[9] << 2))) ^ ((s5[11] ^ 1013904242) + (s4[9] ^ 83)))) & 4294967295)
s4[11] = ((s5[11] + ((((s4[10] >> 3) ^ (s5[12] << 3)) + ((s5[12] >> 4) ^ (s4[10] << 2))) ^ ((s5[12] ^ 1013904242) + (s4[10] ^ 83)))) & 4294967295)
s4[12] = ((s5[12] + ((((s4[11] >> 3) ^ (s5[13] << 3)) + ((s5[13] >> 4) ^ (s4[11] << 2))) ^ ((s5[13] ^ 1013904242) + (s4[11] ^ 67)))) & 4294967295)
s4[13] = ((s5[13] + ((((s4[12] >> 3) ^ (s5[14] << 3)) + ((s5[14] >> 4) ^ (s4[12] << 2))) ^ ((s5[14] ^ 1013904242) + (s4[12] ^ 67)))) & 4294967295)
s4[14] = ((s5[14] + ((((s4[13] >> 3) ^ (s5[15] << 3)) + ((s5[15] >> 4) ^ (s4[13] << 2))) ^ ((s5[15] ^ 1013904242) + (s4[13] ^ 83)))) & 4294967295)
s4[15] = ((s5[15] + ((((s4[14] >> 3) ^ (s5[16] << 3)) + ((s5[16] >> 4) ^ (s4[14] << 2))) ^ ((s5[16] ^ 1013904242) + (s4[14] ^ 83)))) & 4294967295)
s4[16] = ((s5[16] + ((((s4[15] >> 3) ^ (s5[17] << 3)) + ((s5[17] >> 4) ^ (s4[15] << 2))) ^ ((s5[17] ^ 1013904242) + (s4[15] ^ 67)))) & 4294967295)
s4[17] = ((s5[17] + ((((s4[16] >> 3) ^ (s5[18] << 3)) + ((s5[18] >> 4) ^ (s4[16] << 2))) ^ ((s5[18] ^ 1013904242) + (s4[16] ^ 67)))) & 4294967295)
s4[18] = ((s5[18] + ((((s4[17] >> 3) ^ (s5[19] << 3)) + ((s5[19] >> 4) ^ (s4[17] << 2))) ^ ((s5[19] ^ 1013904242) + (s4[17] ^ 83)))) & 4294967295)
s4[19] = ((s5[19] + ((((s4[18] >> 3) ^ (s5[20] << 3)) + ((s5[20] >> 4) ^ (s4[18] << 2))) ^ ((s5[20] ^ 1013904242) + (s4[18] ^ 83)))) & 4294967295)
s4[20] = ((s5[20] + ((((s4[19] >> 3) ^ (s5[21] << 3)) + ((s5[21] >> 4) ^ (s4[19] << 2))) ^ ((s5[21] ^ 1013904242) + (s4[19] ^ 67)))) & 4294967295)
s4[21] = ((s5[21] + ((((s4[20] >> 3) ^ (s5[22] << 3)) + ((s5[22] >> 4) ^ (s4[20] << 2))) ^ ((s5[22] ^ 1013904242) + (s4[20] ^ 67)))) & 4294967295)
s4[22] = ((s5[22] + ((((s4[21] >> 3) ^ (s5[23] << 3)) + ((s5[23] >> 4) ^ (s4[21] << 2))) ^ ((s5[23] ^ 1013904242) + (s4[21] ^ 83)))) & 4294967295)
s4[23] = ((s5[23] + ((((s4[22] >> 3) ^ (s5[24] << 3)) + ((s5[24] >> 4) ^ (s4[22] << 2))) ^ ((s5[24] ^ 1013904242) + (s4[22] ^ 83)))) & 4294967295)
s4[24] = ((s5[24] + ((((s4[23] >> 3) ^ (s5[25] << 3)) + ((s5[25] >> 4) ^ (s4[23] << 2))) ^ ((s5[25] ^ 1013904242) + (s4[23] ^ 67)))) & 4294967295)
s4[25] = ((s5[25] + ((((s4[24] >> 3) ^ (s5[26] << 3)) + ((s5[26] >> 4) ^ (s4[24] << 2))) ^ ((s5[26] ^ 1013904242) + (s4[24] ^ 67)))) & 4294967295)
s4[26] = ((s5[26] + ((((s4[25] >> 3) ^ (s5[27] << 3)) + ((s5[27] >> 4) ^ (s4[25] << 2))) ^ ((s5[27] ^ 1013904242) + (s4[25] ^ 83)))) & 4294967295)
s4[27] = ((s5[27] + ((((s4[26] >> 3) ^ (s5[28] << 3)) + ((s5[28] >> 4) ^ (s4[26] << 2))) ^ ((s5[28] ^ 1013904242) + (s4[26] ^ 83)))) & 4294967295)
s4[28] = ((s5[28] + ((((s4[27] >> 3) ^ (s5[29] << 3)) + ((s5[29] >> 4) ^ (s4[27] << 2))) ^ ((s5[29] ^ 1013904242) + (s4[27] ^ 67)))) & 4294967295)
s4[29] = ((s5[29] + ((((s4[28] >> 3) ^ (s5[30] << 3)) + ((s5[30] >> 4) ^ (s4[28] << 2))) ^ ((s5[30] ^ 1013904242) + (s4[28] ^ 67)))) & 4294967295)
s4[30] = ((s5[30] + ((((s4[29] >> 3) ^ (s5[31] << 3)) + ((s5[31] >> 4) ^ (s4[29] << 2))) ^ ((s5[31] ^ 1013904242) + (s4[29] ^ 83)))) & 4294967295)
s4[31] = ((s5[31] + ((((s4[30] >> 3) ^ (s4[0] << 3)) + ((s4[0] >> 4) ^ (s4[30] << 2))) ^ ((s4[0] ^ 1013904242) + (s4[30] ^ 83)))) & 4294967295)
s3[0] = ((s4[0] + ((((s4[31] >> 3) ^ (s4[1] << 3)) + ((s4[1] >> 4) ^ (s4[31] << 2))) ^ ((s4[1] ^ 3668340011) + (s4[31] ^ 121)))) & 4294967295)
s3[1] = ((s4[1] + ((((s3[0] >> 3) ^ (s4[2] << 3)) + ((s4[2] >> 4) ^ (s3[0] << 2))) ^ ((s4[2] ^ 3668340011) + (s3[0] ^ 121)))) & 4294967295)
s3[2] = ((s4[2] + ((((s3[1] >> 3) ^ (s4[3] << 3)) + ((s4[3] >> 4) ^ (s3[1] << 2))) ^ ((s4[3] ^ 3668340011) + (s3[1] ^ 49)))) & 4294967295)
s3[3] = ((s4[3] + ((((s3[2] >> 3) ^ (s4[4] << 3)) + ((s4[4] >> 4) ^ (s3[2] << 2))) ^ ((s4[4] ^ 3668340011) + (s3[2] ^ 49)))) & 4294967295)
s3[4] = ((s4[4] + ((((s3[3] >> 3) ^ (s4[5] << 3)) + ((s4[5] >> 4) ^ (s3[3] << 2))) ^ ((s4[5] ^ 3668340011) + (s3[3] ^ 121)))) & 4294967295)
s3[5] = ((s4[5] + ((((s3[4] >> 3) ^ (s4[6] << 3)) + ((s4[6] >> 4) ^ (s3[4] << 2))) ^ ((s4[6] ^ 3668340011) + (s3[4] ^ 121)))) & 4294967295)
s3[6] = ((s4[6] + ((((s3[5] >> 3) ^ (s4[7] << 3)) + ((s4[7] >> 4) ^ (s3[5] << 2))) ^ ((s4[7] ^ 3668340011) + (s3[5] ^ 49)))) & 4294967295)
s3[7] = ((s4[7] + ((((s3[6] >> 3) ^ (s4[8] << 3)) + ((s4[8] >> 4) ^ (s3[6] << 2))) ^ ((s4[8] ^ 3668340011) + (s3[6] ^ 49)))) & 4294967295)
s3[8] = ((s4[8] + ((((s3[7] >> 3) ^ (s4[9] << 3)) + ((s4[9] >> 4) ^ (s3[7] << 2))) ^ ((s4[9] ^ 3668340011) + (s3[7] ^ 121)))) & 4294967295)
s3[9] = ((s4[9] + ((((s3[8] >> 3) ^ (s4[10] << 3)) + ((s4[10] >> 4) ^ (s3[8] << 2))) ^ ((s4[10] ^ 3668340011) + (s3[8] ^ 121)))) & 4294967295)
s3[10] = ((s4[10] + ((((s3[9] >> 3) ^ (s4[11] << 3)) + ((s4[11] >> 4) ^ (s3[9] << 2))) ^ ((s4[11] ^ 3668340011) + (s3[9] ^ 49)))) & 4294967295)
s3[11] = ((s4[11] + ((((s3[10] >> 3) ^ (s4[12] << 3)) + ((s4[12] >> 4) ^ (s3[10] << 2))) ^ ((s4[12] ^ 3668340011) + (s3[10] ^ 49)))) & 4294967295)
s3[12] = ((s4[12] + ((((s3[11] >> 3) ^ (s4[13] << 3)) + ((s4[13] >> 4) ^ (s3[11] << 2))) ^ ((s4[13] ^ 3668340011) + (s3[11] ^ 121)))) & 4294967295)
s3[13] = ((s4[13] + ((((s3[12] >> 3) ^ (s4[14] << 3)) + ((s4[14] >> 4) ^ (s3[12] << 2))) ^ ((s4[14] ^ 3668340011) + (s3[12] ^ 121)))) & 4294967295)
s3[14] = ((s4[14] + ((((s3[13] >> 3) ^ (s4[15] << 3)) + ((s4[15] >> 4) ^ (s3[13] << 2))) ^ ((s4[15] ^ 3668340011) + (s3[13] ^ 49)))) & 4294967295)
s3[15] = ((s4[15] + ((((s3[14] >> 3) ^ (s4[16] << 3)) + ((s4[16] >> 4) ^ (s3[14] << 2))) ^ ((s4[16] ^ 3668340011) + (s3[14] ^ 49)))) & 4294967295)
s3[16] = ((s4[16] + ((((s3[15] >> 3) ^ (s4[17] << 3)) + ((s4[17] >> 4) ^ (s3[15] << 2))) ^ ((s4[17] ^ 3668340011) + (s3[15] ^ 121)))) & 4294967295)
s3[17] = ((s4[17] + ((((s3[16] >> 3) ^ (s4[18] << 3)) + ((s4[18] >> 4) ^ (s3[16] << 2))) ^ ((s4[18] ^ 3668340011) + (s3[16] ^ 121)))) & 4294967295)
s3[18] = ((s4[18] + ((((s3[17] >> 3) ^ (s4[19] << 3)) + ((s4[19] >> 4) ^ (s3[17] << 2))) ^ ((s4[19] ^ 3668340011) + (s3[17] ^ 49)))) & 4294967295)
s3[19] = ((s4[19] + ((((s3[18] >> 3) ^ (s4[20] << 3)) + ((s4[20] >> 4) ^ (s3[18] << 2))) ^ ((s4[20] ^ 3668340011) + (s3[18] ^ 49)))) & 4294967295)
s3[20] = ((s4[20] + ((((s3[19] >> 3) ^ (s4[21] << 3)) + ((s4[21] >> 4) ^ (s3[19] << 2))) ^ ((s4[21] ^ 3668340011) + (s3[19] ^ 121)))) & 4294967295)
s3[21] = ((s4[21] + ((((s3[20] >> 3) ^ (s4[22] << 3)) + ((s4[22] >> 4) ^ (s3[20] << 2))) ^ ((s4[22] ^ 3668340011) + (s3[20] ^ 121)))) & 4294967295)
s3[22] = ((s4[22] + ((((s3[21] >> 3) ^ (s4[23] << 3)) + ((s4[23] >> 4) ^ (s3[21] << 2))) ^ ((s4[23] ^ 3668340011) + (s3[21] ^ 49)))) & 4294967295)
s3[23] = ((s4[23] + ((((s3[22] >> 3) ^ (s4[24] << 3)) + ((s4[24] >> 4) ^ (s3[22] << 2))) ^ ((s4[24] ^ 3668340011) + (s3[22] ^ 49)))) & 4294967295)
s3[24] = ((s4[24] + ((((s3[23] >> 3) ^ (s4[25] << 3)) + ((s4[25] >> 4) ^ (s3[23] << 2))) ^ ((s4[25] ^ 3668340011) + (s3[23] ^ 121)))) & 4294967295)
s3[25] = ((s4[25] + ((((s3[24] >> 3) ^ (s4[26] << 3)) + ((s4[26] >> 4) ^ (s3[24] << 2))) ^ ((s4[26] ^ 3668340011) + (s3[24] ^ 121)))) & 4294967295)
s3[26] = ((s4[26] + ((((s3[25] >> 3) ^ (s4[27] << 3)) + ((s4[27] >> 4) ^ (s3[25] << 2))) ^ ((s4[27] ^ 3668340011) + (s3[25] ^ 49)))) & 4294967295)
s3[27] = ((s4[27] + ((((s3[26] >> 3) ^ (s4[28] << 3)) + ((s4[28] >> 4) ^ (s3[26] << 2))) ^ ((s4[28] ^ 3668340011) + (s3[26] ^ 49)))) & 4294967295)
s3[28] = ((s4[28] + ((((s3[27] >> 3) ^ (s4[29] << 3)) + ((s4[29] >> 4) ^ (s3[27] << 2))) ^ ((s4[29] ^ 3668340011) + (s3[27] ^ 121)))) & 4294967295)
s3[29] = ((s4[29] + ((((s3[28] >> 3) ^ (s4[30] << 3)) + ((s4[30] >> 4) ^ (s3[28] << 2))) ^ ((s4[30] ^ 3668340011) + (s3[28] ^ 121)))) & 4294967295)
s3[30] = ((s4[30] + ((((s3[29] >> 3) ^ (s4[31] << 3)) + ((s4[31] >> 4) ^ (s3[29] << 2))) ^ ((s4[31] ^ 3668340011) + (s3[29] ^ 49)))) & 4294967295)
s3[31] = ((s4[31] + ((((s3[30] >> 3) ^ (s3[0] << 3)) + ((s3[0] >> 4) ^ (s3[30] << 2))) ^ ((s3[0] ^ 3668340011) + (s3[30] ^ 49)))) & 4294967295)
s2[0] = ((s3[0] + ((((s3[31] >> 3) ^ (s3[1] << 3)) + ((s3[1] >> 4) ^ (s3[31] << 2))) ^ ((s3[1] ^ 2027808484) + (s3[31] ^ 83)))) & 4294967295)
s2[1] = ((s3[1] + ((((s2[0] >> 3) ^ (s3[2] << 3)) + ((s3[2] >> 4) ^ (s2[0] << 2))) ^ ((s3[2] ^ 2027808484) + (s2[0] ^ 83)))) & 4294967295)
s2[2] = ((s3[2] + ((((s2[1] >> 3) ^ (s3[3] << 3)) + ((s3[3] >> 4) ^ (s2[1] << 2))) ^ ((s3[3] ^ 2027808484) + (s2[1] ^ 67)))) & 4294967295)
s2[3] = ((s3[3] + ((((s2[2] >> 3) ^ (s3[4] << 3)) + ((s3[4] >> 4) ^ (s2[2] << 2))) ^ ((s3[4] ^ 2027808484) + (s2[2] ^ 67)))) & 4294967295)
s2[4] = ((s3[4] + ((((s2[3] >> 3) ^ (s3[5] << 3)) + ((s3[5] >> 4) ^ (s2[3] << 2))) ^ ((s3[5] ^ 2027808484) + (s2[3] ^ 83)))) & 4294967295)
s2[5] = ((s3[5] + ((((s2[4] >> 3) ^ (s3[6] << 3)) + ((s3[6] >> 4) ^ (s2[4] << 2))) ^ ((s3[6] ^ 2027808484) + (s2[4] ^ 83)))) & 4294967295)
s2[6] = ((s3[6] + ((((s2[5] >> 3) ^ (s3[7] << 3)) + ((s3[7] >> 4) ^ (s2[5] << 2))) ^ ((s3[7] ^ 2027808484) + (s2[5] ^ 67)))) & 4294967295)
s2[7] = ((s3[7] + ((((s2[6] >> 3) ^ (s3[8] << 3)) + ((s3[8] >> 4) ^ (s2[6] << 2))) ^ ((s3[8] ^ 2027808484) + (s2[6] ^ 67)))) & 4294967295)
s2[8] = ((s3[8] + ((((s2[7] >> 3) ^ (s3[9] << 3)) + ((s3[9] >> 4) ^ (s2[7] << 2))) ^ ((s3[9] ^ 2027808484) + (s2[7] ^ 83)))) & 4294967295)
s2[9] = ((s3[9] + ((((s2[8] >> 3) ^ (s3[10] << 3)) + ((s3[10] >> 4) ^ (s2[8] << 2))) ^ ((s3[10] ^ 2027808484) + (s2[8] ^ 83)))) & 4294967295)
s2[10] = ((s3[10] + ((((s2[9] >> 3) ^ (s3[11] << 3)) + ((s3[11] >> 4) ^ (s2[9] << 2))) ^ ((s3[11] ^ 2027808484) + (s2[9] ^ 67)))) & 4294967295)
s2[11] = ((s3[11] + ((((s2[10] >> 3) ^ (s3[12] << 3)) + ((s3[12] >> 4) ^ (s2[10] << 2))) ^ ((s3[12] ^ 2027808484) + (s2[10] ^ 67)))) & 4294967295)
s2[12] = ((s3[12] + ((((s2[11] >> 3) ^ (s3[13] << 3)) + ((s3[13] >> 4) ^ (s2[11] << 2))) ^ ((s3[13] ^ 2027808484) + (s2[11] ^ 83)))) & 4294967295)
s2[13] = ((s3[13] + ((((s2[12] >> 3) ^ (s3[14] << 3)) + ((s3[14] >> 4) ^ (s2[12] << 2))) ^ ((s3[14] ^ 2027808484) + (s2[12] ^ 83)))) & 4294967295)
s2[14] = ((s3[14] + ((((s2[13] >> 3) ^ (s3[15] << 3)) + ((s3[15] >> 4) ^ (s2[13] << 2))) ^ ((s3[15] ^ 2027808484) + (s2[13] ^ 67)))) & 4294967295)
s2[15] = ((s3[15] + ((((s2[14] >> 3) ^ (s3[16] << 3)) + ((s3[16] >> 4) ^ (s2[14] << 2))) ^ ((s3[16] ^ 2027808484) + (s2[14] ^ 67)))) & 4294967295)
s2[16] = ((s3[16] + ((((s2[15] >> 3) ^ (s3[17] << 3)) + ((s3[17] >> 4) ^ (s2[15] << 2))) ^ ((s3[17] ^ 2027808484) + (s2[15] ^ 83)))) & 4294967295)
s2[17] = ((s3[17] + ((((s2[16] >> 3) ^ (s3[18] << 3)) + ((s3[18] >> 4) ^ (s2[16] << 2))) ^ ((s3[18] ^ 2027808484) + (s2[16] ^ 83)))) & 4294967295)
s2[18] = ((s3[18] + ((((s2[17] >> 3) ^ (s3[19] << 3)) + ((s3[19] >> 4) ^ (s2[17] << 2))) ^ ((s3[19] ^ 2027808484) + (s2[17] ^ 67)))) & 4294967295)
s2[19] = ((s3[19] + ((((s2[18] >> 3) ^ (s3[20] << 3)) + ((s3[20] >> 4) ^ (s2[18] << 2))) ^ ((s3[20] ^ 2027808484) + (s2[18] ^ 67)))) & 4294967295)
s2[20] = ((s3[20] + ((((s2[19] >> 3) ^ (s3[21] << 3)) + ((s3[21] >> 4) ^ (s2[19] << 2))) ^ ((s3[21] ^ 2027808484) + (s2[19] ^ 83)))) & 4294967295)
s2[21] = ((s3[21] + ((((s2[20] >> 3) ^ (s3[22] << 3)) + ((s3[22] >> 4) ^ (s2[20] << 2))) ^ ((s3[22] ^ 2027808484) + (s2[20] ^ 83)))) & 4294967295)
s2[22] = ((s3[22] + ((((s2[21] >> 3) ^ (s3[23] << 3)) + ((s3[23] >> 4) ^ (s2[21] << 2))) ^ ((s3[23] ^ 2027808484) + (s2[21] ^ 67)))) & 4294967295)
s2[23] = ((s3[23] + ((((s2[22] >> 3) ^ (s3[24] << 3)) + ((s3[24] >> 4) ^ (s2[22] << 2))) ^ ((s3[24] ^ 2027808484) + (s2[22] ^ 67)))) & 4294967295)
s2[24] = ((s3[24] + ((((s2[23] >> 3) ^ (s3[25] << 3)) + ((s3[25] >> 4) ^ (s2[23] << 2))) ^ ((s3[25] ^ 2027808484) + (s2[23] ^ 83)))) & 4294967295)
s2[25] = ((s3[25] + ((((s2[24] >> 3) ^ (s3[26] << 3)) + ((s3[26] >> 4) ^ (s2[24] << 2))) ^ ((s3[26] ^ 2027808484) + (s2[24] ^ 83)))) & 4294967295)
s2[26] = ((s3[26] + ((((s2[25] >> 3) ^ (s3[27] << 3)) + ((s3[27] >> 4) ^ (s2[25] << 2))) ^ ((s3[27] ^ 2027808484) + (s2[25] ^ 67)))) & 4294967295)
s2[27] = ((s3[27] + ((((s2[26] >> 3) ^ (s3[28] << 3)) + ((s3[28] >> 4) ^ (s2[26] << 2))) ^ ((s3[28] ^ 2027808484) + (s2[26] ^ 67)))) & 4294967295)
s2[28] = ((s3[28] + ((((s2[27] >> 3) ^ (s3[29] << 3)) + ((s3[29] >> 4) ^ (s2[27] << 2))) ^ ((s3[29] ^ 2027808484) + (s2[27] ^ 83)))) & 4294967295)
s2[29] = ((s3[29] + ((((s2[28] >> 3) ^ (s3[30] << 3)) + ((s3[30] >> 4) ^ (s2[28] << 2))) ^ ((s3[30] ^ 2027808484) + (s2[28] ^ 83)))) & 4294967295)
s2[30] = ((s3[30] + ((((s2[29] >> 3) ^ (s3[31] << 3)) + ((s3[31] >> 4) ^ (s2[29] << 2))) ^ ((s3[31] ^ 2027808484) + (s2[29] ^ 67)))) & 4294967295)
s2[31] = ((s3[31] + ((((s2[30] >> 3) ^ (s2[0] << 3)) + ((s2[0] >> 4) ^ (s2[30] << 2))) ^ ((s2[0] ^ 2027808484) + (s2[30] ^ 67)))) & 4294967295)
s1[0] = ((s2[0] + ((((s2[31] >> 3) ^ (s2[1] << 3)) + ((s2[1] >> 4) ^ (s2[31] << 2))) ^ ((s2[1] ^ 387276957) + (s2[31] ^ 49)))) & 4294967295)
s1[1] = ((s2[1] + ((((s1[0] >> 3) ^ (s2[2] << 3)) + ((s2[2] >> 4) ^ (s1[0] << 2))) ^ ((s2[2] ^ 387276957) + (s1[0] ^ 49)))) & 4294967295)
s1[2] = ((s2[2] + ((((s1[1] >> 3) ^ (s2[3] << 3)) + ((s2[3] >> 4) ^ (s1[1] << 2))) ^ ((s2[3] ^ 387276957) + (s1[1] ^ 121)))) & 4294967295)
s1[3] = ((s2[3] + ((((s1[2] >> 3) ^ (s2[4] << 3)) + ((s2[4] >> 4) ^ (s1[2] << 2))) ^ ((s2[4] ^ 387276957) + (s1[2] ^ 121)))) & 4294967295)
s1[4] = ((s2[4] + ((((s1[3] >> 3) ^ (s2[5] << 3)) + ((s2[5] >> 4) ^ (s1[3] << 2))) ^ ((s2[5] ^ 387276957) + (s1[3] ^ 49)))) & 4294967295)
s1[5] = ((s2[5] + ((((s1[4] >> 3) ^ (s2[6] << 3)) + ((s2[6] >> 4) ^ (s1[4] << 2))) ^ ((s2[6] ^ 387276957) + (s1[4] ^ 49)))) & 4294967295)
s1[6] = ((s2[6] + ((((s1[5] >> 3) ^ (s2[7] << 3)) + ((s2[7] >> 4) ^ (s1[5] << 2))) ^ ((s2[7] ^ 387276957) + (s1[5] ^ 121)))) & 4294967295)
s1[7] = ((s2[7] + ((((s1[6] >> 3) ^ (s2[8] << 3)) + ((s2[8] >> 4) ^ (s1[6] << 2))) ^ ((s2[8] ^ 387276957) + (s1[6] ^ 121)))) & 4294967295)
s1[8] = ((s2[8] + ((((s1[7] >> 3) ^ (s2[9] << 3)) + ((s2[9] >> 4) ^ (s1[7] << 2))) ^ ((s2[9] ^ 387276957) + (s1[7] ^ 49)))) & 4294967295)
s1[9] = ((s2[9] + ((((s1[8] >> 3) ^ (s2[10] << 3)) + ((s2[10] >> 4) ^ (s1[8] << 2))) ^ ((s2[10] ^ 387276957) + (s1[8] ^ 49)))) & 4294967295)
s1[10] = ((s2[10] + ((((s1[9] >> 3) ^ (s2[11] << 3)) + ((s2[11] >> 4) ^ (s1[9] << 2))) ^ ((s2[11] ^ 387276957) + (s1[9] ^ 121)))) & 4294967295)
s1[11] = ((s2[11] + ((((s1[10] >> 3) ^ (s2[12] << 3)) + ((s2[12] >> 4) ^ (s1[10] << 2))) ^ ((s2[12] ^ 387276957) + (s1[10] ^ 121)))) & 4294967295)
s1[12] = ((s2[12] + ((((s1[11] >> 3) ^ (s2[13] << 3)) + ((s2[13] >> 4) ^ (s1[11] << 2))) ^ ((s2[13] ^ 387276957) + (s1[11] ^ 49)))) & 4294967295)
s1[13] = ((s2[13] + ((((s1[12] >> 3) ^ (s2[14] << 3)) + ((s2[14] >> 4) ^ (s1[12] << 2))) ^ ((s2[14] ^ 387276957) + (s1[12] ^ 49)))) & 4294967295)
s1[14] = ((s2[14] + ((((s1[13] >> 3) ^ (s2[15] << 3)) + ((s2[15] >> 4) ^ (s1[13] << 2))) ^ ((s2[15] ^ 387276957) + (s1[13] ^ 121)))) & 4294967295)
s1[15] = ((s2[15] + ((((s1[14] >> 3) ^ (s2[16] << 3)) + ((s2[16] >> 4) ^ (s1[14] << 2))) ^ ((s2[16] ^ 387276957) + (s1[14] ^ 121)))) & 4294967295)
s1[16] = ((s2[16] + ((((s1[15] >> 3) ^ (s2[17] << 3)) + ((s2[17] >> 4) ^ (s1[15] << 2))) ^ ((s2[17] ^ 387276957) + (s1[15] ^ 49)))) & 4294967295)
s1[17] = ((s2[17] + ((((s1[16] >> 3) ^ (s2[18] << 3)) + ((s2[18] >> 4) ^ (s1[16] << 2))) ^ ((s2[18] ^ 387276957) + (s1[16] ^ 49)))) & 4294967295)
s1[18] = ((s2[18] + ((((s1[17] >> 3) ^ (s2[19] << 3)) + ((s2[19] >> 4) ^ (s1[17] << 2))) ^ ((s2[19] ^ 387276957) + (s1[17] ^ 121)))) & 4294967295)
s1[19] = ((s2[19] + ((((s1[18] >> 3) ^ (s2[20] << 3)) + ((s2[20] >> 4) ^ (s1[18] << 2))) ^ ((s2[20] ^ 387276957) + (s1[18] ^ 121)))) & 4294967295)
s1[20] = ((s2[20] + ((((s1[19] >> 3) ^ (s2[21] << 3)) + ((s2[21] >> 4) ^ (s1[19] << 2))) ^ ((s2[21] ^ 387276957) + (s1[19] ^ 49)))) & 4294967295)
s1[21] = ((s2[21] + ((((s1[20] >> 3) ^ (s2[22] << 3)) + ((s2[22] >> 4) ^ (s1[20] << 2))) ^ ((s2[22] ^ 387276957) + (s1[20] ^ 49)))) & 4294967295)
s1[22] = ((s2[22] + ((((s1[21] >> 3) ^ (s2[23] << 3)) + ((s2[23] >> 4) ^ (s1[21] << 2))) ^ ((s2[23] ^ 387276957) + (s1[21] ^ 121)))) & 4294967295)
s1[23] = ((s2[23] + ((((s1[22] >> 3) ^ (s2[24] << 3)) + ((s2[24] >> 4) ^ (s1[22] << 2))) ^ ((s2[24] ^ 387276957) + (s1[22] ^ 121)))) & 4294967295)
s1[24] = ((s2[24] + ((((s1[23] >> 3) ^ (s2[25] << 3)) + ((s2[25] >> 4) ^ (s1[23] << 2))) ^ ((s2[25] ^ 387276957) + (s1[23] ^ 49)))) & 4294967295)
s1[25] = ((s2[25] + ((((s1[24] >> 3) ^ (s2[26] << 3)) + ((s2[26] >> 4) ^ (s1[24] << 2))) ^ ((s2[26] ^ 387276957) + (s1[24] ^ 49)))) & 4294967295)
s1[26] = ((s2[26] + ((((s1[25] >> 3) ^ (s2[27] << 3)) + ((s2[27] >> 4) ^ (s1[25] << 2))) ^ ((s2[27] ^ 387276957) + (s1[25] ^ 121)))) & 4294967295)
s1[27] = ((s2[27] + ((((s1[26] >> 3) ^ (s2[28] << 3)) + ((s2[28] >> 4) ^ (s1[26] << 2))) ^ ((s2[28] ^ 387276957) + (s1[26] ^ 121)))) & 4294967295)
s1[28] = ((s2[28] + ((((s1[27] >> 3) ^ (s2[29] << 3)) + ((s2[29] >> 4) ^ (s1[27] << 2))) ^ ((s2[29] ^ 387276957) + (s1[27] ^ 49)))) & 4294967295)
s1[29] = ((s2[29] + ((((s1[28] >> 3) ^ (s2[30] << 3)) + ((s2[30] >> 4) ^ (s1[28] << 2))) ^ ((s2[30] ^ 387276957) + (s1[28] ^ 49)))) & 4294967295)
s1[30] = ((s2[30] + ((((s1[29] >> 3) ^ (s2[31] << 3)) + ((s2[31] >> 4) ^ (s1[29] << 2))) ^ ((s2[31] ^ 387276957) + (s1[29] ^ 121)))) & 4294967295)
s1[31] = ((s2[31] + ((((s1[30] >> 3) ^ (s1[0] << 3)) + ((s1[0] >> 4) ^ (s1[30] << 2))) ^ ((s1[0] ^ 387276957) + (s1[30] ^ 121)))) & 4294967295)
[s1[0], s1[1], s1[2], s1[3], s1[4], s1[5], s1[6], s1[7], s1[8], s1[9], s1[10], s1[11], s1[12], s1[13], s1[14], s1[15], s1[16], s1[17], s1[18], s1[19], s1[20], s1[21], s1[22], s1[23], s1[24], s1[25], s1[26], s1[27], s1[28], s1[29], s1[30], s1[31]] == [4108944556, 3404732701, 1466956825, 788072761, 1482427973, 782926647, 1635740553, 4115935911, 2820454423, 3206473923, 1700989382, 2460803532, 2399057278, 968884411, 1298467094, 1786305447, 3953508515, 2466099443, 4105559714, 779131097, 288224004, 3322844775, 4122289132, 2089726849, 656452727, 3096682206, 2217255962, 680183044, 3394288893, 697481839, 1109578150, 2272036063]

可以看到就是一个类似TEA的加密,把算法逆过来就行,解密脚本

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var1 = [2654435769,1013904242,3668340011,2027808484,387276957]
var2 = [[49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121],[67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83],[121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49],[83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67, 83, 83, 67, 67],[49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121, 49, 49, 121, 121]]
ans = [4108944556, 3404732701, 1466956825, 788072761, 1482427973, 782926647, 1635740553, 4115935911, 2820454423, 3206473923, 1700989382, 2460803532, 2399057278, 968884411, 1298467094, 1786305447, 3953508515, 2466099443, 4105559714, 779131097, 288224004, 3322844775, 4122289132, 2089726849, 656452727, 3096682206, 2217255962, 680183044, 3394288893, 697481839, 1109578150, 2272036063]
for j in list(range(5))[::-1]:
for i in list(range(32))[::-1]:
id = [i, i-1, i+1]
if i-1 < 0:
id[1] = 31
if i+1 > 31:
id[2] = 0
tt = (((ans[id[1]] >> 3) ^ (ans[id[2]] << 3)) + ((ans[id[2]] >> 4) ^ (ans[id[1]] << 2))) ^ ((ans[id[2]] ^ var1[j]) + (ans[id[1]] ^ var2[j][i]))
ans[id[0]] -= tt & 0xFFFFFFFF
if ans[id[0]] < 0:
ans[id[0]] += 0x100000000

print("".join([chr(x) for x in ans]))
#SCTF{w0w_y0U_wE1_kNOw_of_cYtH0N}

学习使用Cython编译pyd

安装

1
pip install cython

编写一个py脚本实现pyd里加密的函数

1
2
3
4
#main2.py
def myPrint():
print("hello world")
print("hello cython")

创建一个编译脚本setup.py

1
2
3
4
from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules=cythonize(["main2.py"]))

命令行运行编译指令

1
python setup.py build_ext --inplace

生成main2.cp311-win_amd64.pyd文件,再取一个python文件import即可调用里面的myPrint函数

1
2
import main2
main2.myPrint()

{6DAA3738-1880-445C-9000-93AB9C2F12F9}

参考链接:

Cython 二进制库逆向分析全面指南

SCTF-WP

利用cython将.py文件编译为.pyd文件