SUCTF2025 re wp

checkin

suctf{welcome_to_suctf_you_can_really_dance}

SU_BBRE

Deepseek直接梭

一个很明显的rc4,提交发现不对,还有俩功能没用上,后面还有个隐藏校验,如何触发这个校验?设计一些pwn的简单只是,栈溢出,因此输入[buffer] + p32(溢出到的地址) + 溢出值即可

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
def rc4_decrypt(key, ciphertext):
# Key Scheduling Algorithm (KSA)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]

# Pseudo-Random Generation Algorithm (PRGA)
i = j = 0
plaintext = []
for byte in ciphertext:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
k = S[(S[i] + S[j]) % 256]
plaintext.append(byte ^ k)
return bytes(plaintext)


# 密文(小端序转换后的字节)
cipher = bytes.fromhex('2F5A5765148F69CD93291A551840E45E')
key = b'suctf'

# 解密
plain = rc4_decrypt(key, cipher)
print("Flag:", plain.decode())

enc1 = [ 0x41, 0x6D, 0x62, 0x4D, 0x53, 0x49, 0x4E, 0x29, 0x28]
print(bytes([enc1[i] + i for i in range(len(enc1))]))
print(chr(0x40) + chr(0x22) + chr(0x3d))
# suctf{We1com3ToReWorld@"=AndPWNT00}

1
payload = b'suctf{xxx}' + p32(0x40223D) + b'AndPWNT00'

c

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
#include <cstdio>
#include <cstring>
#include <cstdlib>

// 对应 function3 (RC4的KSA密钥调度算法)
void rc4_ksa(const uint8_t* key, int key_len, uint8_t* S) {
int j = 0;
for (int i = 0; i < 256; i++) {
S[i] = i;
}
for (int i = 0; i < 256; i++) {
j = (j + S[i] + key[i % key_len]) % 256;
std::swap(S[i], S[j]); // 对应汇编中的交换操作
}
}

// 对应 function4 (RC4的PRGA伪随机生成算法)
void rc4_prga(uint8_t* S, const uint8_t* input, uint8_t* output, int len) {
int i = 0, j = 0;
for (int k = 0; k < len; k++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
std::swap(S[i], S[j]);
int t = (S[i] + S[j]) % 256;
output[k] = input[k] ^ S[t]; // 异或加密/解密
}
}

// 对应 function5 (整合KSA和PRGA)
void rc4_encrypt(const uint8_t* key, int key_len, const uint8_t* plaintext, uint8_t* ciphertext, int text_len) {
uint8_t S[256];
rc4_ksa(key, key_len, S);
rc4_prga(S, plaintext, ciphertext, text_len);
}

// 对应 function2 (校验加密后的数据)
bool check_encrypted(const char* input) {
// 预设的加密后数据(小端序)
const uint8_t encrypted[16] = {
0x2F, 0x5A, 0x57, 0x65, 0x14, 0x8F, 0x69, 0xCD,
0x93, 0x29, 0x1A, 0x55, 0x18, 0x40, 0xE4, 0x5E
};

uint8_t ciphertext[16];
// 使用RC4加密,密钥为"suctf"
rc4_encrypt((uint8_t*)"suctf", 5, (uint8_t*)input, ciphertext, 16);

// 对比加密结果
return memcmp(ciphertext, encrypted, 16) == 0;
}

// 对应 function1 (隐藏验证函数)
void hidden_check() {
char buffer[16];
printf("hhh,you find me:");
scanf("%s", buffer); // 存在缓冲区溢出风险

// 预期字符:input[i] - i == secret[i]
const char secret[] = ""; // 4D626D41 294E4953 28...
for (int i = 0; i <= 8; i++) {
if (buffer[i] - i != secret[i]) {
exit(0); // 验证失败退出
}
}
printf("congratulate!!!\n");
exit(0);
}

// 对应 function0 (存在缓冲区溢出漏洞)
void vulnerable_copy(char* dest, const char* src) {
strcpy(dest, src); // 未检查长度,dest只有12字节
}

int main() {
char input[20]; // 原始输入缓冲区

printf("please input your flag:");
scanf("%19s", input); // 限制输入长度

check_encrypted(input)
vulnerable_copy(overflow_buf, input);
return 0;
}

SU_minesweeper

搜索到一个字符串,跟进一下,发现个20*20的矩阵

中间有一系列规则大概就是输入长度xxx然后处理成长度50的然后去进行校验看看每个3*3的格子是否符合某种规则,这里为什么是50个变量呢,其实为了方便,能直接用原来的逻辑逆向,跟400个变量(50x8)的道理是一样的,但是需要重新处理

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
from z3 import *
import hashlib

byte_4020_data = [
0x03, 0x04, 0xFF, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xFF, 0xFF,
0x04, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x04, 0x06, 0x06, 0xFF,
0xFF, 0xFF, 0xFF, 0x06, 0x05, 0x06, 0x04, 0xFF, 0x05, 0xFF,
0x04, 0x07, 0xFF, 0x08, 0xFF, 0x06, 0xFF, 0xFF, 0x06, 0x06,
0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0x03,
0xFF, 0x05, 0x06, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x05,
0x04, 0x05, 0x07, 0x06, 0xFF, 0xFF, 0x04, 0xFF, 0x02, 0x01,
0xFF, 0xFF, 0xFF, 0x03, 0x04, 0xFF, 0xFF, 0x05, 0x04, 0x03,
0xFF, 0xFF, 0x07, 0x04, 0x03, 0xFF, 0xFF, 0x01, 0x01, 0xFF,
0xFF, 0x04, 0x03, 0xFF, 0x02, 0xFF, 0x04, 0x03, 0xFF, 0xFF,
0x02, 0xFF, 0x05, 0x04, 0xFF, 0xFF, 0x02, 0x02, 0xFF, 0xFF,
0x04, 0xFF, 0x04, 0xFF, 0x03, 0x05, 0x06, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0x01, 0x04, 0xFF,
0xFF, 0x07, 0x05, 0xFF, 0xFF, 0x03, 0x03, 0x02, 0xFF, 0xFF,
0x04, 0xFF, 0xFF, 0x05, 0x07, 0xFF, 0x03, 0x02, 0x04, 0x04,
0xFF, 0x07, 0x05, 0x04, 0x03, 0xFF, 0xFF, 0x04, 0xFF, 0x02,
0x04, 0x05, 0xFF, 0xFF, 0x06, 0x05, 0x04, 0xFF, 0x02, 0xFF,
0xFF, 0x07, 0x04, 0xFF, 0xFF, 0x03, 0xFF, 0x04, 0x04, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x03, 0x02, 0x02,
0xFF, 0xFF, 0x02, 0x04, 0x03, 0x05, 0xFF, 0xFF, 0x05, 0xFF,
0x04, 0xFF, 0x06, 0xFF, 0xFF, 0x06, 0xFF, 0xFF, 0xFF, 0xFF,
0x03, 0x03, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06,
0xFF, 0x06, 0x06, 0xFF, 0x07, 0x06, 0x04, 0xFF, 0x04, 0x03,
0xFF, 0x04, 0x03, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x04, 0x06, 0x07, 0xFF, 0xFF, 0x04, 0xFF, 0xFF,
0xFF, 0x07, 0xFF, 0x05, 0xFF, 0x05, 0xFF, 0xFF, 0x06, 0x07,
0x07, 0xFF, 0x05, 0x06, 0x06, 0xFF, 0xFF, 0x02, 0x04, 0x04,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0xFF, 0xFF, 0x07, 0x07,
0x06, 0xFF, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x03,
0x05, 0xFF, 0x07, 0xFF, 0x05, 0xFF, 0x06, 0xFF, 0x05, 0xFF,
0xFF, 0x07, 0x08, 0xFF, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x06, 0x05, 0x03, 0xFF, 0x04, 0x05, 0x05, 0x03, 0xFF,
0xFF, 0x06, 0x05, 0x05, 0x06, 0xFF, 0x06, 0x05, 0x02, 0x04,
0x03, 0x04, 0xFF, 0xFF, 0x03, 0x04, 0x04, 0x06, 0x05, 0xFF,
0x03, 0xFF, 0x05, 0x05, 0x05, 0xFF, 0xFF, 0x05, 0xFF, 0xFF,
0x04, 0xFF, 0xFF, 0x04, 0xFF, 0x07, 0x07, 0x08, 0x06, 0xFF,
0xFF, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0x04, 0xFF, 0x03,
0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x03
]

byte_4020 = [byte_4020_data[i*20 : (i+1)*20] for i in range(20)]


solver = Solver()
v = [BitVec(f'v{i}',8) for i in range(50)]

def sub_1352(a1,a2,a3):
if a2 >= 0 and a3 >= 0 and a2 <= 19 and a3 <= 19:
return ((a1[(20 * a2 + a3) // 8] & 0xff) >> ((20 * a2 + a3) & 7)) & 1
else:
return 0

def sub_13C9(a1,a2,a3):
sum = 0
for i in range(-1,2):
for j in range(-1,2):
sum += sub_1352(a1,a2+i,a3+j)
return sum

# 迷宫约束
for i in range(20):
for j in range(20):
c = byte_4020[i][j]
if c == 0xff:
continue
sum = sub_13C9(v,i,j)
solver.add(sum == c)

if solver.check() == sat:
model = solver.model()
res = ''
for k in range(50):
val = hex(model[v[k]].as_long())[2:]
res += val
print(res)

mapping = {
'0': 'a', '1': 'b', '2': 'c', '3': 'd', '4': 'e', '5': 'f',
'6': '0', '7': '1', '8': '2', '9': '3',
'a': '4', 'b': '5', 'c': '6', 'd': '7', 'e': '8', 'f': '9'
}

# 执行转换操作
converted = ''.join([mapping[c] for c in res])
print(converted)
print( hashlib.md5(converted.encode()).hexdigest())
else:
print('No solution')

for i in range(20):
for j in range(20):
if byte_4020_data[i * 20 + j] == 0xff:
print("?", end="\t")
else:
print(byte_4020_data[i * 20 + j], end="\t")
print()


SU_Harmony

abc-decompiler看看这些代码,发现输入到so层了

image-20250401190141384

跟进到so层的sub_3750

函数很复杂,我们发现很多3,0,9等等数值变成了函数,我们从左侧随便选个函数网上交叉引用最后跟到了

image-20250401195840748

v101的值直接影响这v215

image-20250401195922166

输不输出error,因此我猜测57b0是比较函数,v15可能是密文

这里,m 是一个循环变量,从 0 到 7,每次取 64 字节的块。因此,a99927228993060 数组被分为 8 个 64 字节的块,每个块对应输入的一部分处理后的结果。

1
2
3
4
5
6
7
8
第一个块:999272289930604998
第二个块:1332475531266467542
第三个块:107438803071116830
第四个块:1419324015697459326
第五个块:978270870200633520
第六个块:369789474534896558
第七个块:344214162681978048
第八个块:2213954953857181622

跟进后deepseek给了解释

1
2
3
4
5
6
sub_62F0(a1, (__int64)v64);         // 初始化
sub_6D20(v64, v64, s); // 数据填充
sub_8270(v64, 2LL, v62); // 分块处理
sub_9890(s, v62, v61); // 加密运算
sub_A8F0(v61, "3", v60); // 添加盐值"3"
sub_C160(v60, s1); // 生成最终哈希

我把这些函数喂给了ai,让它解释,虽然不一定准,但我大致了解了他们在做什么,类似大数的计算,最后要为给出的那些enc值

1
2
3
4
5
6
7
8
9
10
11
input_str = "32位字符串"
salt = "3"

# 流程
step1 = sub_62F0(input_str) # 字符串转大整数
step2 = sub_6D20(step1, salt) # 乘以盐值
step3 = sub_8270(step2, 2) # 乘以2
step4 = sub_9890(step3, step2) # 加法
step5 = sub_A8F0(step4, salt) # 减法
step6 = sub_C160(step5) # 除以2
final = step6.split_to_blocks() # 分割为8块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sub_62F0
功能:将输入的 32 字节字符串转换为大整数(ASCII 数字字符串形式)
示例:输入 "1234" → 转换为字符串 "1234"
sub_6D20
功能:实现大整数乘法
代码特征:双重循环模拟竖式乘法,进位处理
示例:"123" * "45" = "5535"
sub_8270
功能:大整数乘以一个单数字(参数a2)
示例:"123" * 2 = "246"
sub_9890
功能:大整数加法
代码特征:逐位相加并处理进位
示例:"123" + "45" = "168"
sub_A8F0
功能:大整数减法
代码特征:逐位相减并处理借位
示例:"123" - "45" = "78"
sub_C160
功能:大整数除以 2
用途:将十进制字符串转换为二进制(但保留为 ASCII 形式)

sub_62F0 的主要作用是将 32 字节的输入字符串 转换为一个 大整数的十进制字符串表示形式

1
2
3
4
5
6
7
8
9
10
11
12
  sub_62F0(a1, (__int64)v64);
sub_6D20(v64, v64, s);
sub_8270(v64, 2LL, v62);
sub_9890(s, v62, v61);
sub_A8F0(v61, "3", v60);
sub_C160(v60, s1);
s初始化
a=s*s
b=s*2
c=b+a
d=c-3
e=d/2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import math
from Crypto.Util.number import long_to_bytes

enc = [
999272289930604998,
1332475531266467542,
1074388003071116830,
1419324015697459326,
978270870200633520,
369789474534896558,
344214162681978048,
2213954953857181622,
]

for i in enc:
a = i * 2 + 3
flag = int(math.sqrt(a))
print(long_to_bytes(flag).decode(), end="")

解出来好像不太对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import math
from Crypto.Util.number import long_to_bytes

enc = [
999272289930604998,
1332475531266467542,
1074388003071116830,
1419324015697459326,
978270870200633520,
369789474534896558,
344214162681978048,
2213954953857181622,
]

for i in enc:
a = i * 2 + 3
flag = int(math.sqrt(a))
print(long_to_bytes(flag)[::-1].decode(), end="")

调整下TUCTG{Ma8h_WprldJs_S1_B3but1gul}

感觉很接近了第一个是SUCTF还有点不对,让deepseek检查下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import math
from Crypto.Util.number import long_to_bytes

enc = [
999272289930604998,
1332475531266467542,
1074388003071116830,
1419324015697459326,
978270870200633520,
369789474534896558,
344214162681978048,
2213954953857181622,
]

for i in enc:
a = i * 2 + 3
flag = int(math.sqrt(a)) - 1
print(long_to_bytes(flag)[::-1].decode(), end="")

SUCTF{Ma7h_WorldIs_S0_B3aut1ful}

最后看了其它师傅的wp发现我这还是写错了没有+1

应该是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import math
from Crypto.Util.number import long_to_bytes

enc = [
999272289930604998,
1332475531266467542,
1074388003071116830,
1419324015697459326,
978270870200633520,
369789474534896558,
344214162681978048,
2213954953857181622,
]

for i in enc:
a = i * 2 + 3
flag = int(math.sqrt(a + 1)) - 1
print(long_to_bytes(flag)[::-1].decode(), end="")

但是答案对了

记录下还有一种n2s的转化方法

1
2
3
4
5
6
7
8
import math
import libnum
enc = [999272289930604998,1332475531266467542,1074388003071116830,1419324015697459326,978270870200633520,369789474534896558,344214162681978048,2213954953857181622]

for i in range(len(enc)):
a = enc[i] * 2 + 3
flag = int(math.sqrt(a + 1) - 1)
print(libnum.n2s(flag)[::-1].decode(),end="")
1
s = (√(4 + 4c) - 2) / 2 = √(c + 1) - 1

SU_mapmap2

法1

1
2
v0 = ord('w') - ord('a')
print(((0x440009 >> v0) & 1) == 0)

测一下就知道输入长268,必须为wasd,前面有一个too long不能反编译的,可能是生成迷宫?

sub_4631C2 是一个树结构操作函数,其核心逻辑是通过输入的 a2(例如字符的高四位值,如 a 对应 0x6)在树中进行节点查找或插入,最终返回一个调整后的树节点指针

理了下逻辑

image-20250403133944224

中间一个4631C2和4632EE不太懂

调试下,发现33C0经常出现

记录一下各个状态v1->v8的变化

a:B3DA3C0->B3DA3C0

w:191023C0->191023C0

d:329933C0->32993400

这里我四个都试了下,只有d的时候会变化,因为是个类似迷宫的题,我猜测只有正确时状态才会变,因此第一次应该走d

da的时候又时329933C0了

这里下断点

image-20250403152940072

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
from idaapi import *

origin_status = get_qword(0x63F530)
final_status = get_qword(0x63F538)

# 获取相关数据的地址
rbp = get_reg_val('rbp')
input_addr = rbp - 0x40
i_addr = rbp - 0x48
status_addr = rbp - 0x50
path = get_qword(input_addr)# 路径数组
flag = ''
isVisited = dict()# 存储状态被访问的情况,防止走回头路

def get_status():
return get_qword(status_addr)

def set_status(status):
patch_qword(status_addr,status)

def get_i():
return get_qword(i_addr)

def set_i(i):
patch_qword(i_addr,i)

def get_code(pos):
return get_byte(path + pos)

def set_code(off,code):
patch_byte(path + off,ord(code))

# 判断指定状态向指定方向移动后的状态
def run_is_legal(status, code):
# 设置初始状态
set_status(status)
set_code(0,code)
set_i(0) # 无限循环

# 运行,获取新状态
continue_process()
wait_for_next_event(WFNE_SUSP,-1)# 等待下一个调试事件
new_status=get_status()# 获取新的状态

print(f'code:{code} new_status:{hex(new_status)}')
return new_status

# 搜索指定状态的路径,DFS深搜
def search(status):
global flag
global isVisited
print("search status:",hex(status))
if status == final_status:
return True
if status in isVisited:
return False
else:
isVisited[status]=True

new_status = run_is_legal(status, 'w')
if new_status != origin_status and new_status!=status:
if search(new_status):
flag+='w'
return True

new_status = run_is_legal(status, 'd')
if new_status != origin_status and new_status!=status:
if search(new_status):
flag += 'd'
return True

new_status = run_is_legal(status, 's')
if new_status != origin_status and new_status!=status:
if search(new_status):
flag += 's'
return True

new_status = run_is_legal(status, 'a')
if new_status != origin_status and new_status!=status:
if search(new_status):
flag += 'a'
return True
return False

print(f'original status:{hex(origin_status)},final_status:{hex(final_status)}')
search(origin_status)
print("flag:",flag[::-1])# 递归需要倒序flag才是正确结果

ddssaassddddssddssssaassaawwwwwwaassssssssssddssssssddwwddddssssddssssddwwwwddssddwwddssddwwwwwwwwwwaawwaawwddwwaaaawwwwddwwddssddddddssaassaassddssddwwddwwwwwwwwwwwwddssssssssssddddssssssddwwwwwwddssddssaassssddssssaaaawwwwaassssaawwaassssssddddssssddssssssaassdddddd

suctf{8b587367b99e5e2fcbdb6598da14b9bc}

法2

标记一下其它解法

2025 SUCTF - Reverse 全题解 | Carbo

以下题解Exp来自上面的师傅

bn确实可以出,学到了

image-20250403153407819

这段代码是二进制程序初始化数据结构的关键部分,主要功能是构建一个复杂的树形结构,并设置初始状态和最终状态。


1. 内存分配与初始化

1
2
00404802        void* rax_2 = sub_4670d0(0x30)  ; 分配0x30字节内存
0040480d sub_463154(rax_2) ; 初始化结构体
  • sub_4670d0 可能是类似 malloc 的函数,用于分配内存块(此处大小为 0x30 字节)。
  • sub_463154 是初始化函数,推测为设置树节点结构体的初始值(如父节点、左右子节点指针归零)。

2. 树节点的构建

后续代码重复调用上述函数,生成多个树节点:

1
2
3
4
5
0040481e        void* rax_3 = sub_4670d0(0x30)  ; rax_3 = 新节点
00404829 sub_463154(rax_3) ; 初始化节点
...
00462d3e data_63f530 = rax_2 ; 保存初始状态
00462d49 data_63f538 = rax_800 ; 保存最终状
1
2
3
4
5
6
7
struct TreeNode {
int32_t key; // 节点键值
TreeNode* parent; // +0x8
TreeNode* left; // +0x10
TreeNode* right; // +0x18
// 其他字段(如校验值、标志位)...
};

3. 节点间的链接逻辑

通过 sub_4631c2sub_4632ee 设置节点关系:

1
2
00409f5f        int64_t* rax_802 = sub_4631c2(rax_2, &var_1920)  ; 根据键值查找/插入节点
00409f83 *sub_4632ee(rax_802, &var_191c) = rax_2 ; 设置节点指针

sub_4631c2 的作用:

  • 参数 1:当前节点指针(如 rax_2)。
  • 参数 2:键值(如 var_1920 = 7)。
  • 功能:根据键值在当前节点的子树中查找或插入新节点,返回目标节点的指针。

sub_4632ee 的作用:

  • 参数 1:目标节点指针(如 rax_802)。
  • 参数 2:操作类型(如 var_191c = 7)。
  • 功能:修改目标节点的指针(如设置左 / 右子节点),将 rax_2 链接到树中。

4. 键值与操作类型

1
2
00409f48        int32_t var_1920 = 7       ; 键值 = 7
00409f5f sub_4631c2(rax_2, &var_1920)
1
2
00409f67        int32_t var_191c = 7       ; 操作类型 = 7
00409f83 *sub_4632ee(rax_802, &var_191c) = rax_2

推测操作类型定义如下:

含义
0 设置左子节点
1 设置右子节点
3 设置父节点
4 设置校验值

5. 初始状态与最终状态

代码末尾将构建好的树结构保存到全局变量:

1
2
00462d3e        data_63f530 = rax_2    ; 初始状态指针
00462d49 data_63f538 = rax_800 ; 最终状态指针
  • data_63f530 是树的根节点,程序从这里开始遍历。
  • data_63f538 是验证成功的终止节点。
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
import re

codes = open("source.c", "r").read().split("\n")

parms = {}
selected = None

for code in codes:
if code.startswith("void*"):
# 初始化 map
name = re.findall(" (.*) =", code)[0].strip()
parms[name] = dict()
elif code.startswith("var"):
# 变量赋值
name = re.findall("(.*) =", code)[0].strip()
value = int(re.findall("= (.*);", code)[0].strip(), 16)
parms[name] = value
elif code.startswith("int64_t*"):
# 获取子字典
name = re.findall("int64_t\\* (.*) =", code)[0].strip()
args = re.findall(r"map_index\((.*), &(.*)\);", code)[0]
target = parms[args[1]]
if target not in parms[args[0]]:
parms[args[0]][target] = dict()
parms[name] = parms[args[0]][target]
elif code.startswith("*unordered_map_index"):
# 赋值
args = re.findall(r"unordered_map_index\((.*), &(.*)\) = (.*);", code)[0]
target = parms[args[1]]
parms[args[0]][target] = args[2]

walked = {}

def search(cur, paths):
if cur == "rax_800":
print(len(paths), paths)
return True
target = parms[cur]
for k1 in target.keys():
for k2 in target[k1].keys():
goto = target[k1][k2]
if not walked.get(goto, False):
val = k1 << 4 | k2
v0 = val - 97
if v0 > 0x16 or v0 < 0:
continue
new_path = paths + chr(val)
# print(goto, new_path)
walked[goto] = True
result = search(goto, new_path)
walked[goto] = False
walked["rax_2"] = True
search("rax_2", "")

# ddssaassddddssddssssaassaawwwwwwaassssssssssddssssssddwwddddssssddssssddwwwwddssddwwddssddwwwwwwwwwwaawwaawwddwwaaaawwwwddwwddssddddddssaassaassddssddwwddwwwwwwwwwwwwddssssssssssddddssssssddwwwwwwddssddssaassssddssssaaaawwwwaassssaawwaassssssddddssssddssssssaassdddddd

# SUCTF{8b587367b99e5e2fcbdb6598da14b9bc}

法3

使用qiling

思路来自

2025 SUCTF 逆向部分Writeup - lrhtony 的小站

通过一道CTF题学习Qiling框架 |

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
from qiling import *
from qiling.extensions import pipe
from qiling.const import QL_VERBOSE

addr_list = []
start_addr = 0
end_addr = 0

def get_start_and_end(ql: Qiling):
global start_addr, end_addr
start_addr = int.from_bytes(ql.mem.read(0x063F530, 8), 'little')
end_addr = int.from_bytes(ql.mem.read(0x63F538, 8), 'little')
print('[+] start:',hex(start_addr))
print('[+] end: ',hex(end_addr))

def hook(ql: Qiling):
now_addr = ql.stack_read(0x10)
global addr_list
addr_list.append(now_addr)
# print(hex(now_addr))

def find(flag, length):
if length >= 268:
# print(flag)
return
# a
flag_tmp = flag + 'a'
if run(flag_tmp.ljust(268, 'o'), length+1):
find(flag_tmp, length + 1)
# s
flag_tmp = flag + 's'
if run(flag_tmp.ljust(268, 'o'), length+1):
find(flag_tmp, length + 1)
# d
flag_tmp = flag + 'd'
if run(flag_tmp.ljust(268, 'o'), length+1):
find(flag_tmp, length + 1)
# w
flag_tmp = flag + 'w'
if run(flag_tmp.ljust(268, 'o'), length+1):
find(flag_tmp, length + 1)

def run(input_str:str, length:int):
global addr_list
addr_list = []
path = ['./rootfs/rootfs-master/x8664_linux/mapmap2']
rootfs = "./rootfs/rootfs-master/x8664_linux/"
ql = Qiling(path, rootfs, multithread=True, verbose=QL_VERBOSE.DISABLED)
ql.os.stdin = pipe.SimpleInStream(0)
ql.os.stdin.write((input_str+'\n').encode())
ql.os.stdout = pipe.SimpleOutStream(0)
# ql.hook_address(get_start_and_end, 0x462DD0)
ql.hook_address(hook, 0x462eaa)
ql.run()
check_path = addr_list[:length+1]
# 判断里面是否有重复的地址或0
# print(input_str)
# print(check_path)
print('[*] length:', length)
if len(check_path) != len(set(check_path)) or 0 in check_path:
return False
if length >= 268:
output = ql.os.stdout.read().decode()
if 'SUCTF' in output:
print('[+] find flag:', input_str)
exit(0)
return True

if __name__ == '__main__':
find('', 0)

SU_vm_master

找到一个func,交叉引用,找到opcode

image-20250503152213057

随便点几个函数发现

image-20250503153305441

image-20250503154613455

1
2
3
4
5
6
7
0x6a5e: "^",
0x6a78: ">>",
0x6a6a: "<<",
0x6a46: "&",
0x6a52: "|",
0x6a3a: "-",
0x6a30: "+"

我们就可可以用刚学的qiling来hook

2025 SUCTF - Reverse 全题解 | Carbo

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
from qiling import *
from qiling.const import QL_VERBOSE
from ctypes import c_uint32

num_operates = {
0x6A68: "^",
0x6A84: ">>",
0x6A76: "<<",
0x6A50: "&",
0x6A5C: "|",
0x6A44: "-",
0x6A38: "+"
}

operators = ""

def hook_call(ql: Qiling):
global operators
pc = ql.arch.regs.arch_pc
op = num_operates[pc - program_base]
num1 = ql.arch.regs.read("rsi")
num2 = ql.arch.regs.read("rdx")
val = ql.arch.regs.read("rax")
operators += f"{num1:#x} {op} {num2:#x} = {val:#x}\n"

ql = Qiling(["./vm_master"], "/home/carbo/rootfs/x8664_linux_glibc2.39/", verbose=QL_VERBOSE.OFF, profile="linux.ql", multithread=True)

program_base = ql.loader.images[0].base

for addr in num_operates.keys():
ql.hook_address(hook_call, program_base + addr)

ql.run()

with open("operators.txt", "w") as f:
f.write(operators)

一直卡住,非常慢,不知道为啥(知道了原来再等待我输入….)

image-20250503163513205

image-20250503171418246

image-20250503171428022

image-20250503172641898

上面是S盒,综合看出来是个SM4算法

做了魔改

image-20250503204613230

image-20250503204700232

后面还异或了0xdeadbeef

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
S_BOX = [
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
]

FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]
CK = [
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
]

def wd_to_byte(wd):
t = [(wd >> i) & 0xff for i in range(16, -1, -8)] + [(wd >> 24) & 0xff]
return t


def bys_to_wd(bys):
ret = 0
for i in range(4):
bits = (16 - i * 8)%32
ret |= (bys[i] << bits)
return ret

def s_box(wd):
"""
进行非线性变换,查S盒
:param wd: 输入一个32bits字
:return: 返回一个32bits字 ->int
"""
ret = []
for i in range(0, 4):
byte = (wd >> (24 - i * 8)) & 0xff
row = byte >> 4
col = byte & 0x0f
index = (row * 16 + col)
ret.append(S_BOX[index])
return int.from_bytes(bytes(ret),"big")


def rotate_left(wd, bit):
"""
:param wd: 待移位的字
:param bit: 循环左移位数
:return:
"""
return (wd << bit & 0xffffffff) | (wd >> (32 - bit))



def Linear_transformation(wd):
"""
进行线性变换L
:param wd: 32bits输入
"""
return wd ^ rotate_left(wd, 2) ^ rotate_left(wd, 10) ^ rotate_left(wd, 18) ^ rotate_left(wd, 24)


def Tx(k1, k2, k3, ck):
"""
密钥扩展算法的合成变换
"""
t = s_box(k1 ^ k2 ^ k3 ^ ck)
return t ^ rotate_left(t, 13) ^ rotate_left(t, 23)


def T(x1, x2, x3, rk):
"""
加密算法轮函数的合成变换
"""
t = x1 ^ x2 ^ x3 ^ rk
t = s_box(t)
return t ^ rotate_left(t, 2) ^ rotate_left(t, 10) ^ rotate_left(t, 18) ^ rotate_left(t, 24)


def key_extend(main_key):
X = bytes.fromhex(main_key)
MK = [bys_to_wd(X[i * 4:i * 4 + 4]) for i in range(4)]
# 将128bits分为4个字
keys = [FK[i] ^ MK[i] for i in range(4)]
# 生成K0~K3
RK = []
for i in range(32):
t = Tx(keys[i + 1], keys[i + 2], keys[i + 3], CK[i])
k = keys[i] ^ t
keys.append(k)
RK.append(k)
return RK


def R(x0, x1, x2, x3):
# 使用位运算符将数值限制在32位范围内
x0 &= 0xffffffff
x1 &= 0xffffffff
x2 &= 0xffffffff
x3 &= 0xffffffff
s = f"{bytes(wd_to_byte(x3)).hex().zfill(8)}{bytes(wd_to_byte(x2)).hex().zfill(8)}{bytes(wd_to_byte(x1)).hex().zfill(8)}{bytes(wd_to_byte(x0)).hex().zfill(8)}"
return s


def encode(plaintext, rk):
X = bytes.fromhex(plaintext)
X = [bys_to_wd(X[i*4:i*4+4]) for i in range(4)]
for i in range(32):
t = T(X[1], X[2], X[3], rk[i])
c = (t ^ X[0])
c ^= 0xdeadbeef
X = X[1:] + [c]
ciphertext = R(X[0], X[1], X[2], X[3])

# 进行反序处理
return ciphertext


def decode(ciphertext, rk):
X = bytes.fromhex(ciphertext)
X = [bys_to_wd(X[i * 4:i * 4 + 4]) for i in range(4)]
for i in range(32):
t = T(X[1], X[2], X[3], rk[31 - i])
c = (t ^ X[0]) ^ 0xdeadbeef
X = X[1:] + [c]
m = R(X[0], X[1], X[2], X[3])
return m

def xor_iv(a,iv):
pt = bytes.fromhex(a)
iv = bytes.fromhex(iv)
pt = bytearray(pt)
iv = bytearray(iv)
pt = [pt[i] ^ iv[i] for i in range(16)]
pt = bytes(pt).hex()
return pt

if __name__ == '__main__':

pt = "30303030303030303030303030303030"
iv = "736F6D657468696E676E6F74676F6F64"
pt = xor_iv(pt,iv)

main_key = "736F6D657468696E6776657279626164"
rk = key_extend(main_key)
enc2 = "8EB9A5ADD272DE2F4672F24C6D413438"
enc = "F0A8BC50D93AF7CE4928EA7733B417B0"
enc2 = decode(enc2, rk)
enc2 = xor_iv(enc2, enc)

enc = decode(enc, rk)
enc = xor_iv(enc, iv)
print(bytes.fromhex(enc).decode() + bytes.fromhex(enc2).decode())

为什么这里要xor_iv因为这里是CBC模式

在解密过程中,每个明文块需要用当前密文块解密后再与上一个密文块(或 IV)异或,才能还原出原始明文

SU_ezlua

一个文件名是 lua(通常是自带的 Lua 虚拟机或魔改版的解释器)

一个是 chall.luac(通常是已经编译好的 Lua 字节码)

lua 逆向学习 & RCTF复盘 picstore 还原代码块 - TLSN - 博客园

5.1版本

image-20250504103206473

说明被魔改过

image-20250504111044606

首先交叉引用header,看到很多校验函数,一个个看下去,关注到sub_173F0函数

改版 lua 虚拟机,改了 string 和 code,需要解密

参考2025 SUCTF 部分题解 - S1uM4i

一些函数内的string:

1
2
3
4
5
6
7
8
9
10
11
if (n32[0] )
{
v5 = 0LL;
do
{
*((_BYTE *)&str_ + v5) = __ROL1__(*((_BYTE *)&str_ + v5), 3);
++v5;
}
while (n32[0] > v5 );
l = n32[0] - 1;
}

code:

1
*v23 = (int)__ROL4__(_byteswap_ulong(v24 ^ 0x32547698), 15);

单独的 loadint,类型枚举为 63:

1
*(double *)v23 = (double)(int)__ROL4__(_byteswap_ulong(v24 ^ 0x32547698), 15);

str_byte 魔改了(异或偏移然后 +35):

1
2
3
4
5
6
7
do
{
v11 = v9 ^ *((_BYTE *)&retaddr + v9);
++v9;
lua_pushinteger(L, (unsigned __int8)(v11 + 35));
}
while (v10 != v9);

Lua 字节码在编译后通常以明文形式存储,无需额外运算。而此处出现了:

  • 异或固定值 0x32547698
  • 字节交换 (_byteswap_ulong)
  • 循环左移 15 位 (__ROL4__ 15)

这些操作在标准 Lua 编译流程中不存在,属于人为添加的加密或混淆逻辑。

要看出来其实还是有点困难的

又参考了Lua 逆向总结—Sink | iSEAL

对于这种文件结构上的调整,这里我们有一个通杀的方法,那就是在 load 完成之后,执行之前(此时加载后的程序位于栈顶),调用同版本的、标准的(也就是未经任何修改的)lua_dump 函数,即可得到标准格式的 luac文件。简单来说,先用题目给的 load 然后用标准的 dump

编译阶段:Lua 源码(.lua)被编译为字节码(.luac),字节码包含操作码和常量表等。

加载阶段loadloadfile函数读取字节码,解析并生成可执行的函数对象。

执行阶段:虚拟机执行加载后的函数。

题目中的魔改操作

  • 加密字节码chall.luac的字节码在编译后被异或、字节交换和循环位移加密。
  • 修改的load函数:题目提供的lua(解释器或库)中的load函数会在加载时解密字节码,恢复为正常的函数对象。

内存中的函数对象状态

  • 加密仅发生在文件存储加载阶段,一旦完成load,内存中的函数对象已是解密后的标准结构。
  • 此时若调用标准版lua_dump,会直接序列化内存中的正常结构,生成未加密的.luac

然后修改下Makefile函数(卡了很久,最后还是没解决…)

hook出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var luac = Module.load("/home/matriy/liblua.so")
var func_ptr = luac.findExportByName("luaL_dumpfile")
var dumpLua = new NativeFunction(func_ptr, "int", ["pointer", "pointer"]);
var output = Memory.allocUtf8String("/home/matriy/dump.luac")

Memory.protect(ptr(luac.base), luac.size, 'rwx');

var module = Process.getModuleByName("lua")
Interceptor.attach(module.base.add(0x1CB70), {
onEnter: function(args) {
console.log("Hooked! Dumping...")
this.L_object = args[0]
},
onLeave: function() {
console.log(this.L_object, output)
dumpLua(this.L_object, output)
}
})
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
local L0_1, L1_1

function L0_1(A0_2)
local L1_2, L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2, L13_2, L14_2, L15_2
L2_2 = ""
L1_2 = "0123456789abcdef"
L6_2 = 1
L7_2 = string
L7_2 = L7_2.len
L8_2 = A0_2
L7_2 = L7_2(L8_2)
L8_2 = 1
for L9_2 = L6_2, L7_2, L8_2 do
L10_2 = string
L10_2 = L10_2.byte
L11_2 = A0_2
L12_2 = L9_2
L10_2 = L10_2(L11_2, L12_2)
L3_2 = L10_2
L10_2 = And
L11_2 = Shr
L12_2 = L3_2
L13_2 = 4
L11_2 = L11_2(L12_2, L13_2)
L12_2 = 15
L10_2 = L10_2(L11_2, L12_2)
L4_2 = L10_2
L10_2 = And
L11_2 = L3_2
L12_2 = 15
L10_2 = L10_2(L11_2, L12_2)
L5_2 = L10_2
L10_2 = L2_2
L11_2 = string
L11_2 = L11_2.sub
L12_2 = L1_2
L13_2 = L4_2 + 1
L14_2 = L4_2 + 1
L11_2 = L11_2(L12_2, L13_2, L14_2)
L12_2 = string
L12_2 = L12_2.sub
L13_2 = L1_2
L14_2 = L5_2 + 1
L15_2 = L5_2 + 1
L12_2 = L12_2(L13_2, L14_2, L15_2)
L2_2 = L10_2 .. L11_2 .. L12_2
end
return L2_2
end

hex = L0_1

function L0_1(A0_2)
local L1_2, L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2
L1_2 = string
L1_2 = L1_2.char
L2_2 = And
L3_2 = A0_2
L4_2 = 255
L2_2 = L2_2(L3_2, L4_2)
L3_2 = And
L4_2 = Shr
L5_2 = A0_2
L6_2 = 8
L4_2 = L4_2(L5_2, L6_2)
L5_2 = 255
L3_2 = L3_2(L4_2, L5_2)
L4_2 = And
L5_2 = Shr
L6_2 = A0_2
L7_2 = 16
L5_2 = L5_2(L6_2, L7_2)
L6_2 = 255
L4_2 = L4_2(L5_2, L6_2)
L5_2 = And
L6_2 = Shr
L7_2 = A0_2
L8_2 = 24
L6_2 = L6_2(L7_2, L8_2)
L7_2 = 255
L5_2, L6_2, L7_2, L8_2 = L5_2(L6_2, L7_2)
return L1_2(L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2)
end

from_uint = L0_1

function L0_1(A0_2, A1_2)
local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2
if A1_2 == nil then
A1_2 = 1
end
L2_2 = string
L2_2 = L2_2.byte
L3_2 = A0_2
L4_2 = A1_2
L2_2 = L2_2(L3_2, L4_2)
L3_2 = Or
L4_2 = L2_2
L5_2 = Shl
L6_2 = string
L6_2 = L6_2.byte
L7_2 = A0_2
L8_2 = A1_2 + 1
L6_2 = L6_2(L7_2, L8_2)
L7_2 = 8
L5_2, L6_2, L7_2, L8_2 = L5_2(L6_2, L7_2)
L3_2 = L3_2(L4_2, L5_2, L6_2, L7_2, L8_2)
L2_2 = L3_2
L3_2 = Or
L4_2 = L2_2
L5_2 = Shl
L6_2 = string
L6_2 = L6_2.byte
L7_2 = A0_2
L8_2 = A1_2 + 2
L6_2 = L6_2(L7_2, L8_2)
L7_2 = 16
L5_2, L6_2, L7_2, L8_2 = L5_2(L6_2, L7_2)
L3_2 = L3_2(L4_2, L5_2, L6_2, L7_2, L8_2)
L2_2 = L3_2
L3_2 = Or
L4_2 = L2_2
L5_2 = Shl
L6_2 = string
L6_2 = L6_2.byte
L7_2 = A0_2
L8_2 = A1_2 + 3
L6_2 = L6_2(L7_2, L8_2)
L7_2 = 24
L5_2, L6_2, L7_2, L8_2 = L5_2(L6_2, L7_2)
L3_2 = L3_2(L4_2, L5_2, L6_2, L7_2, L8_2)
L2_2 = L3_2
return L2_2
end

to_uint = L0_1

function L0_1(A0_2, A1_2)
local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2, L13_2
L6_2 = string
L6_2 = L6_2.len
L7_2 = A1_2
L6_2 = L6_2(L7_2)
L4_2 = L6_2
L6_2 = 0
L7_2 = 255
L8_2 = 1
for L9_2 = L6_2, L7_2, L8_2 do
A0_2[L9_2] = L9_2
end
L3_2 = 0
L6_2 = 0
L7_2 = 255
L8_2 = 1
for L9_2 = L6_2, L7_2, L8_2 do
L10_2 = A0_2[L9_2]
L10_2 = L3_2 + L10_2
L11_2 = string
L11_2 = L11_2.byte
L12_2 = A1_2
L13_2 = L9_2 % L4_2
L13_2 = L13_2 + 1
L11_2 = L11_2(L12_2, L13_2)
L10_2 = L10_2 + L11_2
L3_2 = L10_2 % 256
L5_2 = A0_2[L9_2]
L10_2 = A0_2[L3_2]
A0_2[L9_2] = L10_2
A0_2[L3_2] = L5_2
end
end

rc4init = L0_1

function L0_1(A0_2, A1_2)
local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2, L13_2, L14_2, L15_2, L16_2
L7_2 = ""
L2_2 = 0
L3_2 = 0
L8_2 = 0
L9_2 = string
L9_2 = L9_2.len
L10_2 = A1_2
L9_2 = L9_2(L10_2)
L9_2 = L9_2 - 1
L10_2 = 1
for L11_2 = L8_2, L9_2, L10_2 do
L12_2 = L2_2 + 1
L2_2 = L12_2 % 256
L12_2 = A0_2[L2_2]
L12_2 = L3_2 + L12_2
L3_2 = L12_2 % 256
L5_2 = A0_2[L2_2]
L12_2 = A0_2[L3_2]
A0_2[L2_2] = L12_2
A0_2[L3_2] = L5_2
L12_2 = Xor
L13_2 = string
L13_2 = L13_2.byte
L14_2 = A1_2
L15_2 = L11_2 + 1
L13_2 = L13_2(L14_2, L15_2)
L14_2 = And
L15_2 = A0_2[L2_2]
L16_2 = A0_2[L3_2]
L15_2 = L15_2 - L16_2
L16_2 = 255
L14_2 = L14_2(L15_2, L16_2)
L14_2 = A0_2[L14_2]
L12_2 = L12_2(L13_2, L14_2)
L6_2 = L12_2
L12_2 = L7_2
L13_2 = string
L13_2 = L13_2.char
L14_2 = L6_2
L13_2 = L13_2(L14_2)
L7_2 = L12_2 .. L13_2
L12_2 = L3_2 + L6_2
L3_2 = L12_2 % 256
end
return L7_2
end

rc4crypt = L0_1

function L0_1(A0_2, A1_2)
local L2_2, L3_2, L4_2, L5_2
L3_2 = {}
L2_2 = L3_2
L3_2 = rc4init
L4_2 = L2_2
L5_2 = A1_2
L3_2(L4_2, L5_2)
L3_2 = rc4crypt
L4_2 = L2_2
L5_2 = A0_2
return L3_2(L4_2, L5_2)
end

rc4 = L0_1

function L0_1()
local L0_2, L1_2
L0_2 = print
L1_2 = "wrong"
L0_2(L1_2)
L0_2 = os
L0_2 = L0_2.exit
L1_2 = 0
L0_2(L1_2)
end

fail = L0_1

function L0_1(A0_2, A1_2, A2_2)
local L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2, L13_2, L14_2, L15_2, L16_2, L17_2, L18_2, L19_2
L10_2 = to_uint
L11_2 = A2_2
L12_2 = 1
L10_2 = L10_2(L11_2, L12_2)
L6_2 = L10_2
L10_2 = to_uint
L11_2 = A2_2
L12_2 = 5
L10_2 = L10_2(L11_2, L12_2)
L7_2 = L10_2
L10_2 = to_uint
L11_2 = A2_2
L12_2 = 9
L10_2 = L10_2(L11_2, L12_2)
L8_2 = L10_2
L10_2 = to_uint
L11_2 = A2_2
L12_2 = 13
L10_2 = L10_2(L11_2, L12_2)
L9_2 = L10_2
L4_2 = 305419896
L5_2 = 0
L10_2 = 1
L11_2 = 32
L12_2 = 1
for L13_2 = L10_2, L11_2, L12_2 do
L14_2 = to_uint
L15_2 = rc4
L16_2 = from_uint
L17_2 = L4_2
L16_2 = L16_2(L17_2)
L17_2 = A2_2
L15_2, L16_2, L17_2, L18_2, L19_2 = L15_2(L16_2, L17_2)
L14_2 = L14_2(L15_2, L16_2, L17_2, L18_2, L19_2)
L4_2 = L14_2
L14_2 = And
L15_2 = L5_2 + L4_2
L16_2 = 4294967295
L14_2 = L14_2(L15_2, L16_2)
L5_2 = L14_2
L14_2 = And
L15_2 = Xor
L16_2 = Xor
L17_2 = Shl
L18_2 = A1_2
L19_2 = 4
L17_2 = L17_2(L18_2, L19_2)
L17_2 = L17_2 + L6_2
L18_2 = A1_2 + L5_2
L16_2 = L16_2(L17_2, L18_2)
L17_2 = Shr
L18_2 = A1_2
L19_2 = 5
L17_2 = L17_2(L18_2, L19_2)
L17_2 = L17_2 + L7_2
L15_2 = L15_2(L16_2, L17_2)
L15_2 = A0_2 + L15_2
L16_2 = 4294967295
L14_2 = L14_2(L15_2, L16_2)
A0_2 = L14_2
L14_2 = And
L15_2 = Xor
L16_2 = Xor
L17_2 = Shl
L18_2 = A0_2
L19_2 = 4
L17_2 = L17_2(L18_2, L19_2)
L17_2 = L17_2 + L8_2
L18_2 = A0_2 + L5_2
L16_2 = L16_2(L17_2, L18_2)
L17_2 = Shr
L18_2 = A0_2
L19_2 = 5
L17_2 = L17_2(L18_2, L19_2)
L17_2 = L17_2 + L9_2
L15_2 = L15_2(L16_2, L17_2)
L15_2 = A1_2 + L15_2
L16_2 = 4294967295
L14_2 = L14_2(L15_2, L16_2)
A1_2 = L14_2
end
L10_2 = A0_2
L11_2 = A1_2
return L10_2, L11_2
end

encrypt = L0_1

function L0_1(A0_2)
local L1_2, L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2, L13_2
L2_2 = ""
L3_2 = "thisshouldbeakey"
L6_2 = rc4
L7_2 = A0_2
L8_2 = L3_2
L6_2 = L6_2(L7_2, L8_2)
A0_2 = L6_2
L6_2 = 0
L7_2 = 3
L8_2 = 1
for L9_2 = L6_2, L7_2, L8_2 do
L10_2 = to_uint
L11_2 = A0_2
L12_2 = 8 * L9_2
L12_2 = 1 + L12_2
L10_2 = L10_2(L11_2, L12_2)
L4_2 = L10_2
L10_2 = to_uint
L11_2 = A0_2
L12_2 = 8 * L9_2
L12_2 = 1 + L12_2
L12_2 = L12_2 + 4
L10_2 = L10_2(L11_2, L12_2)
L5_2 = L10_2
L10_2 = encrypt
L11_2 = L4_2
L12_2 = L5_2
L13_2 = L3_2
L10_2, L11_2 = L10_2(L11_2, L12_2, L13_2)
L5_2 = L11_2
L4_2 = L10_2
L10_2 = L2_2
L11_2 = from_uint
L12_2 = L4_2
L11_2 = L11_2(L12_2)
L12_2 = from_uint
L13_2 = L5_2
L12_2 = L12_2(L13_2)
L2_2 = L10_2 .. L11_2 .. L12_2
end
L6_2 = hex
L7_2 = L2_2
L6_2 = L6_2(L7_2)
L2_2 = L6_2
L6_2 = L2_2 == "ac0c0027f0e4032acf7bd2c37b252a933091a06aeebc072c980fa62c24f486c6"
return L6_2
end

check = L0_1

function L0_1()
local L0_2, L1_2, L2_2, L3_2, L4_2, L5_2
L0_2 = print
L1_2 = "input flag: "
L0_2(L1_2)
L0_2 = io
L0_2 = L0_2.read
L0_2 = L0_2()
L1_2 = string
L1_2 = L1_2.len
L2_2 = L0_2
L1_2 = L1_2(L2_2)
if L1_2 ~= 39 then
L1_2 = fail
L1_2()
end
L1_2 = string
L1_2 = L1_2.sub
L2_2 = L0_2
L3_2 = 1
L4_2 = 6
L1_2 = L1_2(L2_2, L3_2, L4_2)
if L1_2 ~= "SUCTF{" then
L1_2 = fail
L1_2()
end
L1_2 = string
L1_2 = L1_2.sub
L2_2 = L0_2
L3_2 = 39
L1_2 = L1_2(L2_2, L3_2)
if L1_2 ~= "}" then
L1_2 = fail
L1_2()
end
L1_2 = check
L2_2 = string
L2_2 = L2_2.sub
L3_2 = L0_2
L4_2 = 7
L5_2 = 38
L2_2, L3_2, L4_2, L5_2 = L2_2(L3_2, L4_2, L5_2)
L1_2 = L1_2(L2_2, L3_2, L4_2, L5_2)
if L1_2 then
L1_2 = print
L2_2 = "correct"
L1_2(L2_2)
else
L1_2 = fail
L1_2()
end
end

main = L0_1
L0_1 = main
L0_1()

EXP:

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
def getbyte(R0, R1):
return ((ord(R0[R1]) ^ R1) + 35) & 0xFF

def from_uint(R0):
return chr(R0 & 0xFF) + chr((R0 >> 8) & 0xFF) + chr((R0 >> 16) & 0xFF) + chr((R0 >> 24) & 0xFF)

def to_uint(R0, R1 = 0):
return getbyte(R0, R1) | (getbyte(R0, R1 + 1) << 8) | (getbyte(R0, R1 + 2) << 16) | (getbyte(R0, R1 + 3) << 24)

def rc4init(R0, R1):
while len(R0) < 256:
R0.append(0)
for i in range(256):
R0[i] = i
R3 = 0
for i in range(256):
R3 = (R3 + R0[i] + getbyte(R1, i % len(R1))) & 0xFF
R5 = R0[i]
R0[i] = R0[R3]
R0[R3] = R5

def byte_dec(x, i):
x = x - 35 if x >= 35 else 0x100 + x - 35
return x ^ i

def decrypt(R0, R1, R2):
r5_list = [3603410768, 3994032664, 1754214155, 794075743, 1976517078, 3471763126, 1957850369, 1599897197, 3784224572, 1802991924, 2794371991, 2014510171, 495317058, 2651527826, 1667027981, 2614829033, 2717182440, 2731507984, 4121469091, 4093031767, 3436801646, 1543785646, 2927475993, 2026297061, 2321426900, 497655852, 2200244399, 2694992467, 394628698, 1637983114, 3214985509, 3167109857]
R6 = to_uint(R2, 0)
R7 = to_uint(R2, 4)
R8 = to_uint(R2, 8)
R9 = to_uint(R2, 12)
for i in range(32):
R5 = r5_list[i]
term = ((R0 + R5) ^ ((R0 << 4) + R8) ^ ((R0 >> 5) + R9)) & 0xFFFFFFFF
R1 = R1 - term if R1 >= term else 0x100000000 + R1 - term
term = ((R1 + R5) ^ ((R1 << 4) + R6) ^ ((R1 >> 5) + R7)) & 0xFFFFFFFF
R0 = R0 - term if R0 >= term else 0x100000000 + R0 - term
return R0, R1

def rc4decrypt(R0, R1):
R7 = ""
R2 = 0
R3 = 0
R8 = 0
for i in range(len(R1)):
R2 = (R2 + 1) & 0xFF
R3 = (R3 + R0[R2]) % 256
R5 = R0[R2]
R0[R2] = R0[R3]
R0[R3] = R5
R13 = R1[i]
R14 = R0[R2] - R0[R3] if R0[R2] >= R0[R3] else 0x100 + R0[R2] - R0[R3]
R14 = R0[R14]
R6 = R13 ^ R14
R7 += chr(byte_dec(R6, i))
R3 = (R3 + R13) % 256
return R7

ans = "ac0c0027f0e4032acf7bd2c37b252a933091a06aeebc072c980fa62c24f486c6"
ans = [hex(byte_dec(int(ans[x:(x+2)], 16), x // 2))[2:].zfill(2) for x in range(0, 64, 2)]
ans = [int("".join(ans[x:(x+4)][::-1]), 16) for x in range(0, 32, 4)]
terms = ""
R3 = "thisshouldbeakey"
for i in range(4):
R4, R5 = decrypt(ans[i * 2], ans[i * 2 + 1], R3)
terms += from_uint(R4) + from_uint(R5)

terms = [byte_dec(ord(terms[x]), x) for x in range(32)]
R2 = []
rc4init(R2, R3)
print("SUCTF{" + rc4decrypt(R2, terms) + "}")
#SUCTF{341528c2bde511efade200155d8503ef}

SU_APP

必须是安卓9-11且是arm64,很多虚拟机用不了了,还要降级刷机,懒得搞了看看wp

2025 SUCTF - Reverse 全题解 | Carbo

2025 SUCTF 部分题解 - S1uM4i

先干掉几个反调试,写frida脚本把修改后的so库dump出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var dump_so_func = function (soname, packageName) {
var module = Process.getModuleByName(soname);
var buffer = module.base.readByteArray(module.size);
console.log(`base: ${module.base}`);

const fileName = `/data/data/${packageName}/dump_so_${Date.now()}.so`;
const file = new File(fileName, "wb");
file.write(buffer);
file.flush();
file.close();

console.log(`[+] Saved ${soname} to file: ${fileName}`);
console.log(`[+] Bytecode size: ${module.size} bytes`);
};

function start_dump() {
var so_name = "libsuapp.so"
var package_name = "com.swdd.suapp"
dump_so_func(so_name, package_name)
}

image-20250504154621687

为了解决这个 可以先尝试 dump 出 app 的整个内存,然后搜索 SUCTF{You_Find_Me}

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
Java.perform(function() {
setTimeout(function() {

let allMemoryData = [];
let totalSize = 0;

const ranges = Process.enumerateRangesSync({
protection: '---',
coalesce: true
});

for (const range of ranges) {
try {
const current = range.base;
const size = range.size;
console.log(current, size)

const memoryData = Memory.readByteArray(current, size);
if (memoryData) {
allMemoryData.push(memoryData);
totalSize += size;
}
} catch {}
}

const finalBuffer = new ArrayBuffer(totalSize);
const finalArray = new Uint8Array(finalBuffer);
let offset = 0;

for (const data of allMemoryData) {
const tempArray = new Uint8Array(data);
finalArray.set(tempArray, offset);
offset += tempArray.length;
}

const timestamp = new Date().getTime();
const filename = `/data/data/com.swdd.suapp/memory_dump_${timestamp}.bin`;

const file = new File(filename, "wb");
file.write(finalBuffer);
file.flush();
file.close();
console.log(`[+] Saved ${finalBuffer.byteLength} bytes to ${filename}`);
}, 3000)
})

搜索到两个结果,其中一个结果只有前 64 个字节被抹了,接下来把这里未被覆盖的后64字节加上 apk 里的那个 so 加载器的前 64 个字节覆盖进dump出来的so,然后修复一下 so 就可以还原了

找到主函数,简单重命名一下函数名和字段名后可以发现,这是利用了 libffi 库,根据 rc4 加密的前半步骤选取用于加密的函数,然后用 ffi_call 调用,一共有 256 种加密函数 每个加密函数有不同的参数个数,在调用前使用 j_ffi_prep_cif 预包装好参数

exp:

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
cin = 'a'*32
print(cin)
ii,jj = 0,0
tt =0
sbox=[0xd4,0x72,0xab,0x2a,0x46,0x5f,0xf8,0xc3,0x96,0xd6,0x32,0xd7,0x3d,0x69,0xd9,0x64,0xe1,0x65,0x41,0x24,0x3,0xd8,0x5c,0xec,0x7c,0x73,0xc4,0x43,0x8d,0x26,0x68,0xdc,0x3f,0x2c,0xe5,0x39,0x6b,0x4d,0x21,0xf4,0x4e,0x85,0xdd,0x13,0x8e,0xb4,0x3a,0x11,0xd0,0xf9,0xf3,0x9e,0xd1,0x5d,0x37,0x61,0x95,0xea,0x5b,0x99,0x9c,0xb3,0x7,0x2e,0x4,0xf,0x89,0x57,0x5a,0xa7,0x4f,0x82,0x76,0xa0,0xe6,0x63,0xf1,0x15,0x3e,0x1b,0xfd,0xc7,0xa8,0x31,0x6a,0xc6,0x8b,0xd5,0x59,0x6d,0xe9,0x87,0x74,0x5,0x1e,0xb1,0x97,0xa,0xce,0x52,0xb9,0x8f,0xe7,0xac,0x8,0xa6,0x16,0xc2,0xf2,0x42,0x9a,0xfa,0xe2,0x86,0x53,0xff,0x55,0x23,0x71,0xb6,0x44,0xbd,0x8a,0xb2,0x28,0x54,0xc8,0xf0,0x7a,0x90,0xa4,0x7d,0xd3,0xdb,0x1a,0x22,0x20,0xb5,0x83,0xb0,0xa1,0xa5,0x84,0xb7,0x6,0x70,0xaa,0xbc,0xda,0x4b,0x34,0x67,0xd2,0x60,0x0,0xc5,0xd,0x56,0xa3,0x98,0x2d,0x7f,0x1d,0x3b,0xaf,0xe3,0x7b,0x93,0x7e,0x6f,0x6c,0xa9,0x36,0xde,0xbe,0xc9,0x2,0x48,0x8c,0xe8,0xfe,0x62,0x3c,0xca,0x33,0xfc,0xdf,0xee,0x40,0xf5,0xcb,0x47,0x79,0xb,0x2b,0x29,0x94,0xcd,0xba,0x51,0xae,0x58,0x12,0x14,0x88,0xeb,0x9b,0x77,0x1c,0x27,0xe0,0x4c,0x38,0x91,0x49,0xcc,0xa2,0xc1,0x25,0xcf,0xf7,0x9d,0x2f,0xc0,0x45,0x17,0x35,0x92,0x9f,0x4a,0x78,0x66,0xf6,0x5e,0xfb,0xbb,0x10,0x81,0x1,0xe,0x6e,0x9,0xb8,0x18,0x50,0xad,0xe4,0x30,0x80,0x75,0xef,0xed,0x19,0xbf,0xc,0x1f]


def a224(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def a264(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def a2b0(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def a2f0(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def a33c(a1, a2, a3):
return (a1 ^ a3) + a2
def a370(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def a3bc(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def a3fc(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def a43c(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def a47c(a1, a2, a3):
return (a1 ^ a3) + a2
def a4b0(a1, a2, a3):
return (a1 ^ a3) + a2
def a4e4(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def a524(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def a564(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def a5a4(a1, a2, a3):
return (a1 ^ a3) + a2
def a5d8(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def a618(a1, a2, a3):
return (a1 + a3 + a2)
def a64c(a1, a2, a3):
return (a1 + a3 + a2)
def a680(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ (a4 + a5)) + a2
def a6cc(a1, a2, a3):
return (a1 + a3 + a2)
def a700(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def a74c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def a78c(a1, a2, a3):
return (a1 ^ a3) + a2
def a7c0(a1, a2, a3):
return (a1 ^ a3) + a2
def a7f4(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def a840(a1, a2, a3):
return (a1 ^ a3) + a2
def a874(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def a8b4(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def a900(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def a940(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def a980(a1, a2, a3):
return (a1 + a3 + a2)
def a9b4(a1, a2, a3):
return (a1 ^ a3) + a2
def a9e8(a1, a2, a3):
return (a1 ^ a3) + a2
def aa1c(a1, a2, a3):
return (a1 ^ a3) + a2
def aa50(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def aa9c(a1, a2, a3):
return (a1 + a3 + a2)
def aad0(a1, a2, a3):
return (a1 + a3 + a2)
def ab04(a1, a2, a3):
return (a1 + a3 + a2)
def ab38(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def ab84(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def abc4(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def ac10(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ a4 ^ a5) + a2
def ac5c(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def aca8(a1, a2, a3):
return (a1 + a3 + a2)
def acdc(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def ad1c(a1, a2, a3):
return (a1 ^ a3) + a2
def ad50(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def ad90(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def add0(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def ae10(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def ae5c(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def ae9c(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def aedc(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def af28(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def af68(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def afa8(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def afe8(a1, a2, a3):
return (a1 + a3 + a2)
def b01c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b05c(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def b0a8(a1, a2, a3):
return (a1 + a3 + a2)
def b0dc(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def b11c(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4) ^ a5) + a2
def b168(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b1a8(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b1e8(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def b234(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def b274(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def b2c0(a1, a2, a3):
return (a1 + a3 + a2)
def b2f4(a1, a2, a3):
return (a1 + a3 + a2)
def b328(a1, a2, a3):
return (a1 ^ a3) + a2
def b35c(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def b3a8(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def b3f4(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b434(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def b480(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b4c0(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ a4 ^ a5) + a2
def b50c(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def b54c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b58c(a1, a2, a3):
return (a1 + a3 + a2)
def b5c0(a1, a2, a3):
return (a1 + a3 + a2)
def b5f4(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def b634(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b674(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def b6c0(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ a4 ^ a5) + a2
def b70c(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def b758(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def b798(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def b7e4(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ a4 ^ a5) + a2
def b830(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def b870(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def b8b0(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b8f0(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4) ^ a5) + a2
def b93c(a1, a2, a3):
return (a1 ^ a3) + a2
def b970(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def b9bc(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def b9fc(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def ba48(a1, a2, a3):
return (a1 + a3 + a2)
def ba7c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def babc(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def bafc(a1, a2, a3):
return (a1 ^ a3) + a2
def bb30(a1, a2, a3):
return (a1 + a3 + a2)
def bb64(a1, a2, a3):
return (a1 + a3 + a2)
def bb98(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4) ^ a5) + a2
def bbe4(a1, a2, a3):
return (a1 ^ a3) + a2
def bc18(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def bc64(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ a4 ^ a5) + a2
def bcb0(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def bcf0(a1, a2, a3):
return (a1 + a3 + a2)
def bd24(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def bd64(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def bdb0(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def bdfc(a1, a2, a3):
return (a1 ^ a3) + a2
def be30(a1, a2, a3):
return (a1 + a3 + a2)
def be64(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def bea4(a1, a2, a3):
return (a1 + a3 + a2)
def bed8(a1, a2, a3):
return (a1 ^ a3) + a2
def bf0c(a1, a2, a3):
return (a1 + a3 + a2)
def bf40(a1, a2, a3):
return (a1 ^ a3) + a2
def bf74(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def bfb4(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def bff4(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def c034(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def c074(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def c0b4(a1, a2, a3):
return (a1 + a3 + a2)
def c0e8(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def c134(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def c174(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def c1b4(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def c1f4(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def c240(a1, a2, a3):
return (a1 ^ a3) + a2
def c274(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def c2c0(a1, a2, a3):
return (a1 + a3 + a2)
def c2f4(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def c340(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def c380(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ (a4 + a5)) + a2
def c3cc(a1, a2, a3):
return (a1 + a3 + a2)
def c400(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ (a4 + a5)) + a2
def c44c(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4) ^ a5) + a2
def c498(a1, a2, a3):
return (a1 + a3 + a2)
def c4cc(a1, a2, a3):
return (a1 + a3 + a2)
def c500(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ (a4 + a5)) + a2
def c54c(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def c598(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def c5d8(a1, a2, a3):
return (a1 + a3 + a2)
def c60c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def c64c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def c68c(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def c6d8(a1, a2, a3):
return (a1 ^ a3) + a2
def c70c(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def c74c(a1, a2, a3):
return (a1 ^ a3) + a2
def c780(a1, a2, a3):
return (a1 ^ a3) + a2
def c7b4(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def c7f4(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def c840(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def c88c(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def c8d8(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def c924(a1, a2, a3):
return (a1 ^ a3) + a2
def c958(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def c9a4(a1, a2, a3):
return (a1 + a3 + a2)
def c9d8(a1, a2, a3):
return (a1 + a3 + a2)
def ca0c(a1, a2, a3):
return (a1 + a3 + a2)
def ca40(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def ca80(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def cac0(a1, a2, a3):
return (a1 + a3 + a2)
def caf4(a1, a2, a3):
return (a1 ^ a3) + a2
def cb28(a1, a2, a3):
return (a1 ^ a3) + a2
def cb5c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def cb9c(a1, a2, a3):
return (a1 + a3 + a2)
def cbd0(a1, a2, a3):
return (a1 + a3 + a2)
def cc04(a1, a2, a3):
return (a1 + a3 + a2)
def cc38(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def cc78(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def ccb8(a1, a2, a3):
return (a1 ^ a3) + a2
def ccec(a1, a2, a3):
return (a1 + a3 + a2)
def cd20(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ (a4 + a5)) + a2
def cd6c(a1, a2, a3):
return (a1 ^ a3) + a2
def cda0(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def cdec(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def ce2c(a1, a2, a3):
return (a1 + a3 + a2)
def ce60(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def ceac(a1, a2, a3):
return (a1 + a3 + a2)
def cee0(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def cf20(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def cf60(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def cfa0(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def cfec(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def d02c(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4) ^ a5) + a2
def d078(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4) ^ a5) + a2
def d0c4(a1, a2, a3):
return (a1 + a3 + a2)
def d0f8(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def d144(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4) ^ a5) + a2
def d190(a1, a2, a3):
return (a1 + a3 + a2)
def d1c4(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def d204(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def d244(a1, a2, a3):
return (a1 + a3 + a2)
def d278(a1, a2, a3):
return (a1 + a3 + a2)
def d2ac(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def d2f8(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def d338(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def d378(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def d3b8(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ a4 ^ a5) + a2
def d404(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ a4 ^ a5) + a2
def d450(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def d49c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def d4dc(a1, a2, a3):
return (a1 + a3 + a2)
def d510(a1, a2, a3):
return (a1 + a3 + a2)
def d544(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def d590(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def d5dc(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def d61c(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def d668(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def d6a8(a1, a2, a3):
return (a1 + a3 + a2)
def d6dc(a1, a2, a3):
return (a1 + a3 + a2)
def d710(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ (a4 + a5)) + a2
def d75c(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4) ^ a5) + a2
def d7a8(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def d7e8(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def d834(a1, a2, a3, a4, a5):
return ((a1 + a3 + a4) ^ a5) + a2
def d880(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def d8c0(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def d900(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def d94c(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def d98c(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def d9cc(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def da18(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def da64(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def dab0(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def daf0(a1, a2, a3):
return (a1 + a3 + a2)
def db24(a1, a2, a3):
return (a1 + a3 + a2)
def db58(a1, a2, a3):
return (a1 + a3 + a2)
def db8c(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def dbcc(a1, a2, a3, a4, a5):
return ((a1 + a3) ^ (a4 + a5)) + a2
def dc18(a1, a2, a3, a4, a5):
return (a1 ^ a3 ^ (a4 + a5)) + a2
def dc64(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def dca4(a1, a2, a3):
return (a1 + a3 + a2)
def dcd8(a1, a2, a3):
return (a1 + a3 + a2)
def dd0c(a1, a2, a3, a4):
return (a1 ^ (a3 + a4)) + a2
def dd4c(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)
def dd98(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def ddd8(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def de24(a1, a2, a3, a4):
return (a1 ^ a3 ^ a4) + a2
def de64(a1, a2, a3):
return (a1 ^ a3) + a2
def de98(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def ded8(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def df24(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def df64(a1, a2, a3):
return (a1 + a3 + a2)
def df98(a1, a2, a3, a4, a5):
return (a1 ^ (a3 + a4 + a5)) + a2
def dfe4(a1, a2, a3, a4):
return (a1 + a3 + a4 + a2)
def e024(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def e064(a1, a2, a3):
return (a1 + a3 + a2)
def e098(a1, a2, a3):
return (a1 ^ a3) + a2
def e0cc(a1, a2, a3):
return (a1 + a3 + a2)
def e100(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def e140(a1, a2, a3, a4):
return ((a1 + a3) ^ a4) + a2
def e180(a1, a2, a3):
return (a1 ^ a3) + a2
def e1b4(a1, a2, a3, a4, a5):
return (a1 + a3 + a4 + a5 + a2)

func_list = [a224,a264,a2b0,a2f0,a33c,a370,a3bc,a3fc,a43c,a47c,a4b0,a4e4,a524,a564,a5a4,a5d8,a618,a64c,a680,a6cc,a700,a74c,a78c,a7c0,a7f4,a840,a874,a8b4,a900,a940,a980,a9b4,a9e8,aa1c,aa50,aa9c,aad0,ab04,ab38,ab84,abc4,ac10,ac5c,aca8,acdc,ad1c,ad50,ad90,add0,ae10,ae5c,ae9c,aedc,af28,af68,afa8,afe8,b01c,b05c,b0a8,b0dc,b11c,b168,b1a8,b1e8,b234,b274,b2c0,b2f4,b328,b35c,b3a8,b3f4,b434,b480,b4c0,b50c,b54c,b58c,b5c0,b5f4,b634,b674,b6c0,b70c,b758,b798,b7e4,b830,b870,b8b0,b8f0,b93c,b970,b9bc,b9fc,ba48,ba7c,babc,bafc,bb30,bb64,bb98,bbe4,bc18,bc64,bcb0,bcf0,bd24,bd64,bdb0,bdfc,be30,be64,bea4,bed8,bf0c,bf40,bf74,bfb4,bff4,c034,c074,c0b4,c0e8,c134,c174,c1b4,c1f4,c240,c274,c2c0,c2f4,c340,c380,c3cc,c400,c44c,c498,c4cc,c500,c54c,c598,c5d8,c60c,c64c,c68c,c6d8,c70c,c74c,c780,c7b4,c7f4,c840,c88c,c8d8,c924,c958,c9a4,c9d8,ca0c,ca40,ca80,cac0,caf4,cb28,cb5c,cb9c,cbd0,cc04,cc38,cc78,ccb8,ccec,cd20,cd6c,cda0,cdec,ce2c,ce60,ceac,cee0,cf20,cf60,cfa0,cfec,d02c,d078,d0c4,d0f8,d144,d190,d1c4,d204,d244,d278,d2ac,d2f8,d338,d378,d3b8,d404,d450,d49c,d4dc,d510,d544,d590,d5dc,d61c,d668,d6a8,d6dc,d710,d75c,d7a8,d7e8,d834,d880,d8c0,d900,d94c,d98c,d9cc,da18,da64,dab0,daf0,db24,db58,db8c,dbcc,dc18,dc64,dca4,dcd8,dd0c,dd4c,dd98,ddd8,de24,de64,de98,ded8,df24,df64,df98,dfe4,e024,e064,e098,e0cc,e100,e140,e180,e1b4,]
func_arg_number = [0x2,0x3,0x2,0x3,0x1,0x3,0x2,0x2,0x2,0x1,0x1,0x2,0x2,0x2,0x1,0x2,0x1,0x1,0x3,0x1,0x3,0x2,0x1,0x1,0x3,0x1,0x2,0x3,0x2,0x2,0x1,0x1,0x1,0x1,0x3,0x1,0x1,0x1,0x3,0x2,0x3,0x3,0x3,0x1,0x2,0x1,0x2,0x2,0x2,0x3,0x2,0x2,0x3,0x2,0x2,0x2,0x1,0x2,0x3,0x1,0x2,0x3,0x2,0x2,0x3,0x2,0x3,0x1,0x1,0x1,0x3,0x3,0x2,0x3,0x2,0x3,0x2,0x2,0x1,0x1,0x2,0x2,0x3,0x3,0x3,0x2,0x3,0x3,0x2,0x2,0x2,0x3,0x1,0x3,0x2,0x3,0x1,0x2,0x2,0x1,0x1,0x1,0x3,0x1,0x3,0x3,0x2,0x1,0x2,0x3,0x3,0x1,0x1,0x2,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x1,0x3,0x2,0x2,0x2,0x3,0x1,0x3,0x1,0x3,0x2,0x3,0x1,0x3,0x3,0x1,0x1,0x3,0x3,0x2,0x1,0x2,0x2,0x3,0x1,0x2,0x1,0x1,0x2,0x3,0x3,0x3,0x3,0x1,0x3,0x1,0x1,0x1,0x2,0x2,0x1,0x1,0x1,0x2,0x1,0x1,0x1,0x2,0x2,0x1,0x1,0x3,0x1,0x3,0x2,0x1,0x3,0x1,0x2,0x2,0x2,0x3,0x2,0x3,0x3,0x1,0x3,0x3,0x1,0x2,0x2,0x1,0x1,0x3,0x2,0x2,0x2,0x3,0x3,0x3,0x2,0x1,0x1,0x3,0x3,0x2,0x3,0x2,0x1,0x1,0x3,0x3,0x2,0x3,0x3,0x2,0x2,0x3,0x2,0x2,0x3,0x3,0x3,0x2,0x1,0x1,0x1,0x2,0x3,0x3,0x2,0x1,0x1,0x2,0x3,0x2,0x3,0x2,0x1,0x2,0x3,0x2,0x1,0x3,0x2,0x2,0x1,0x1,0x1,0x2,0x2,0x1,0x3,]
def gen_rand():
global ii
global jj

ii = (ii+1)%256
jj = (jj + sbox[ii])%256
v2 = (sbox[ii]+sbox[jj])% 256
return v2


def check(data):
global ii
global jj
result = "a"
ii = 0
jj = 0
len1 = len(data)
assert(len1 == 0x20)
s = [i for i in data]
for i in range(8*len1):
rnum0 = gen_rand()
rnum1 = gen_rand()
rnum2 = gen_rand()
ridx1 = gen_rand() % len1
ridx2 = gen_rand() % len1
r_offset = gen_rand()
arr = [hex(rnum0),hex(rnum1),hex(rnum2),hex(ridx1),hex(ridx2),hex(r_offset)]

if(func_arg_number[r_offset]==1):
a1= rnum0
a2 = s[ridx1]
a3 = s[ridx2]
result = func_list[r_offset](a1,a2,a3)

if(func_arg_number[r_offset]==2):
a1= rnum0
a2= rnum1
a3 = s[ridx1]
a4 = s[ridx2]
result = func_list[r_offset](a1,a2,a3,a4)

if(func_arg_number[r_offset]==3):
a1= rnum0
a2= rnum1
a3 =rnum2
a4 = s[ridx1]
a5 = s[ridx2]
result = func_list[r_offset](a1,a2,a3,a4,a5)
s[ridx1] = result


return s
# for m in s:
# print(hex(m),end=',')


result = [0x6e179,0x10a34,0x353c2,0x1174b,0x70bda,0xb015,0x3bfeb,0x2d16,0x4a320,0x1f1ac,0x8f6b,0x2098e,0x8d4,0x2428f,0x1fb5f,0x10bd5,0x10e7,0x3171b,0x1b19d,0x168,0x8dcf,0x246ba,0x7ae5d,0x6f10,0x6e11,0x13d8a,0x169b,0x3701,0x321d6,0x465f6,0x106bc,0x1298e,]

from z3 import *
cin = [i for i in b"aaaaa"]+[BitVec('x[%d]'%i,8) for i in range(32-5)]

result = [0x000D7765, 0x00011EBD, 0x00032D12, 0x00013778, 0x0008A428, 0x0000B592, 0x0003FA57, 0x00001616,
0x0003659E, 0x0002483A, 0x00002882, 0x000508F4, 0x00000BAD, 0x00027920, 0x0000F821, 0x00019F83,
0x00000F97, 0x00033904, 0x000170D5, 0x0000016C, 0x0000CF5D, 0x000280D2, 0x000A8ADE, 0x00009EAA,
0x00009DAB, 0x0001F45E, 0x00003214, 0x000052FA, 0x0006D57A, 0x000460ED, 0x000124FF, 0x00013936, ]
cin = [i for i in b"SUCTF"]+[BitVec('x[%d]'%i,8) for i in range(32-5)]

ans = check(cin)
#print(ans[0])
S = Solver()
for i in range(0x20):
S.add(ans[i] == result[i])
print(S.check())
flag = S.model()
print(flag)

x = [9]*100
x[0] = 123
x[16] = 95
x[14] = 105
x[17] = 77
x[22] = 114
x[24] = 33
x[21] = 51
x[25] = 33
x[18] = 52
x[11] = 100
x[1] = 89
x[19] = 115
x[9] = 65
x[8] = 95
x[7] = 51
x[2] = 48
x[20] = 116
x[26] = 125
x[12] = 114
x[3] = 117
x[6] = 114
x[13] = 48
x[23] = 33
x[5] = 65
x[4] = 95
x[10] = 110
x[15] = 100
print(bytes(x))
# check(b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab")
# print(len(func_list))
# print(len(func_arg_number))