N1CTF2024-RE

逆向部分两道多线程题目,究极折磨

IDAPython魅力时刻

Txt2AsciiArt

题目分析

main函数先输入144个16进制字符,逐bit保存到qword_14007D190,共576bit

接下来创建两轮子线程,每一轮576个线程

创建完线程根据输入的bit位和掩码输出一幅图像,不重要

接下来校验,猜测这里的校验和输入的数据有关

1
2
3
4
5
6
7
8
9
for ( n = 0i64; n < 16; ++n )
{
if ( qword_14007AC30[n] != *(_QWORD *)((char *)&unk_140076B20 + n * 8)
|| qword_14007BEF0[n] != *(_QWORD *)((char *)&unk_140076BE0 + n * 8) )
{
sub_1400531B0("There's something to hide.\n");
return 0;
}
}

接下来的部分解密flag,这里的密钥肯定跟输入的字符串有关,可以不用分析,重点关注创建的子线程

如图是其中一个子线程的反编译代码,首先等待qword_140079A30值不为0,随后将该值与qword_14007D190进行一系列运算,计算结构保存到qword_14007A9C8

qword_14007D190是输入数据的一个bit

交叉引用查看qword_140079A30qword_14007A9C8

可以发现一个线程的输入依赖另一个线程的输出,且其输出被另一个线程依赖,线程前后执行的顺序由依赖关系确定

观察数据部分发现部分数据不为0,且只作为线程输入,因此当线程依赖该不为0数据时,线程立即执行,因此这类线程为控制流的入口

另外还观察到main中最后校验的数据只作为线程的输出,不被其他线程依赖,因此可以猜测到这类线程为控制流出口

解题思路

根据上面的分析,首先可以找到初始值不为0的数据,交叉引用找到将该数据作为输入的线程函数,即一条控制流的入口,再通过交叉引用线程函数的输出数据找到控制流的下一个部分,重复上述过程,直到输出数据不作为其他线程函数的输入,即为控制流的出口

通过IDAPython脚本可以比较容易地实现上述逻辑

这里主要使用ida_xref查找交叉引用

和上面思路不同的是,这里是通过对数据进行交叉引用找到依赖该数据的函数和写该数据的函数

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
import idc
import ida_xref

ImageBase = 0x140000000

# 第一部分
# read_data->addr
read_table = {}
# write_data->addr
write_table = {}

ea = ImageBase + 0x79A30
for i in range(600):
xref1 = ida_xref.get_first_dref_to(ea)
xref2 = ida_xref.get_next_dref_to(ea, xref1)
if (xref1 != 0xffffffffffffffff):
if (ea == idc.get_operand_value(xref1, 0)):
# 写引用
write_table[ea] = xref1
elif (ea == idc.get_operand_value(xref1, 1)):
# 读引用
read_table[ea] = xref1
if (xref2 != 0xffffffffffffffff):
idc.create_insn(xref2)
if (ea == idc.get_operand_value(xref2, 0)):
# 写引用
write_table[ea] = xref2
elif (ea == idc.get_operand_value(xref2, 1)):
# 读引用
read_table[ea] = xref2
ea += 8

接下来计算前后依赖关系,并找到每个函数依赖的输入bit位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 输入: (所在函数, 输出, 依赖的bit位)
rely_table = {}
# 计算依赖关系
for addr in read_table:
func = idc.get_func_attr(read_table[adr], FUNCATTR_START)
rely_bit_ea = func+0x27
idc.create_insn(rely_bit_ea)
ins = idc.generate_disasm_line(rely_bit_ea, 0)
assert(ins.startswith("mov rcx, cs:"))
rely_bit = idc.get_operand_value(rely_bit_ea, 1)
for write_addr in write_table:
if (func == idc.get_func_attr(write_table[write_addr], FUNCATTR_START)):
break
rely_table[addr] = [func, write_addr, rely_bit]
print(f"{hex(addr)} {hex(func)} {hex(write_addr)}, {hex(rely_bit)}")

计算出依赖关系后,可以继续找出所有的入口函数,入口数据、出口数据,以及一条控制流中依赖的所有bit位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 找到真实入口,入口数据,出口数据,依赖的bit位
blocks = []
for addr in read_table:
if (addr in write_table):
continue
in_data = addr
out_data = addr
bits = []
while (out_data in read_table):
bits.append(rely_table[out_data][2])
out_data = rely_table[out_data][1]
assert(len(bits) == 24)
blocks.append((rely_table[in_data][0], in_data, out_data, bits))

for block in blocks:
print("{", end='')
print(f"(uint64_t *){hex(block[0])}, (uint64_t *){hex(block[1])}, (uint64_t *){hex(block[2])}, (uint64_t *){hex(block[2]-0x4110)}, ", end='')
print("{", end='')
for bit in block[3]:
print(f"(uint64_t *){hex(bit)}, ", end='')
print("}", end='')
print("},")

可以发现第一部分的576个线程函数刚好组成了24条链,每条链分别依赖24个输入bit位,并且输出的24个数据都位于main函数的校验中(main中只校验了16个,但是数据区域连续储存有24各数据)

再根据校验数据,就可以得到每条链的正确数据,其输出依赖于24个输入bit,且每条链相互独立

由于只有24个bit,可以考虑对每条链进行爆破

进行爆破需要提取程序的算法,但是函数较多提取复杂,这里可以考虑使用程序中的代码片段直接进行计算,将代码段和数据段映射到内存,按照顺序调用每一个线程函数(当然也有更简单的方式,直接使用jmp连接前后代码片段,只需要调用入口函数即可完成整条链的调用)

通过patch程序,使用jmp连接前后代码块,并patch掉多余的Sleep

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
# patch程序去掉Sleep
for addr in read_table:
ea = read_table[addr]
ea += idc.create_insn(ea)
ins1_len = idc.create_insn(ea)
ins1 = idc.generate_disasm_line(ea, 0)
if (not ins1.startswith("mov ecx, 0Ah")):
continue
ins2_len = idc.create_insn(ea+ins1_len)
ins2 = idc.generate_disasm_line(ea+ins1_len, 0)
if (not ins2.startswith("call cs:Sleep")):
continue
for i in range(ins1_len+ins2_len):
idc.patch_byte(ea+i, 0x90)
idc.create_insn(ea+i)

# 修改跳转关系
for addr in write_table:
ea = write_table[addr]
ea += idc.create_insn(ea)
if (addr not in read_table):
break
next = read_table[addr]
off = (0x100000000+next-ea-5)&0xffffffff
# jmp next
idc.patch_byte(ea+0, 0xE9)
idc.patch_byte(ea+1, (off>>0)&0xff)
idc.patch_byte(ea+2, (off>>8)&0xff)
idc.patch_byte(ea+3, (off>>16)&0xff)
idc.patch_byte(ea+4, (off>>24)&0xff)

上面的脚本只处理第一部分576个线程函数,第二部分处理方式相同,只需要修改初始的地址

由于需要将程序加载到内存,直接加载exe文件需要考虑不同段的加载位置,因此直接在IDA中把程序的内存dump下来,后续只需要将dump文件加载到固定的内存位置,不需要进行分段

1
2
3
4
5
6
7
8
9
import idc

start = 0x140001000
end = 0x14007F000

with open("dump.bin", "wb") as f:
for ea in range(start, end):
b = idc.get_db_byte(ea)
f.write(b.to_bytes(1, byteorder='little'))

爆破代码如下,实际上只需要爆破第一部分就能得到完整的576个bit

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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define DUMP_SIZE 516096
#define DATA_OFF 0x6B250
#define DATA_SIZE 0x12db0

struct CrackStruct {
uint64_t *func;
uint64_t *in;
uint64_t *out;
uint64_t *ans;
uint64_t *bits[24];
int right;
};

struct CrackStruct crack[48] = {
{(uint64_t *)0x140002a60, (uint64_t *)0x140079ae8, (uint64_t *)0x14007ac90, (uint64_t *)0x140076b80, {(uint64_t *)0x14007d248, (uint64_t *)0x14007d920, (uint64_t *)0x14007e0c8, (uint64_t *)0x14007de20, (uint64_t *)0x14007dc48, (uint64_t *)0x14007dcd0, (uint64_t *)0x14007dac0, (uint64_t *)0x14007d4f0, (uint64_t *)0x14007d198, (uint64_t *)0x14007d240, (uint64_t *)0x14007d730, (uint64_t *)0x14007d400, (uint64_t *)0x14007d4a0, (uint64_t *)0x14007d228, (uint64_t *)0x14007d9b0, (uint64_t *)0x14007dfa8, (uint64_t *)0x14007d458, (uint64_t *)0x14007df00, (uint64_t *)0x14007d2f8, (uint64_t *)0x14007d288, (uint64_t *)0x14007daf8, (uint64_t *)0x14007df48, (uint64_t *)0x14007dbc0, (uint64_t *)0x14007d680, }},
{(uint64_t *)0x1400066d0, (uint64_t *)0x140079c90, (uint64_t *)0x14007ac78, (uint64_t *)0x140076b68, {(uint64_t *)0x14007d3f0, (uint64_t *)0x14007d960, (uint64_t *)0x14007dde8, (uint64_t *)0x14007db68, (uint64_t *)0x14007d5e0, (uint64_t *)0x14007dc40, (uint64_t *)0x14007e070, (uint64_t *)0x14007d470, (uint64_t *)0x14007d968, (uint64_t *)0x14007dd00, (uint64_t *)0x14007dcb8, (uint64_t *)0x14007d478, (uint64_t *)0x14007d448, (uint64_t *)0x14007e090, (uint64_t *)0x14007d800, (uint64_t *)0x14007dee8, (uint64_t *)0x14007e2b8, (uint64_t *)0x14007d2b8, (uint64_t *)0x14007e378, (uint64_t *)0x14007d3e0, (uint64_t *)0x14007d1b8, (uint64_t *)0x14007d5a0, (uint64_t *)0x14007d7b0, (uint64_t *)0x14007d908, }},
{(uint64_t *)0x14000bdd0, (uint64_t *)0x140079ef0, (uint64_t *)0x14007ace8, (uint64_t *)0x140076bd8, {(uint64_t *)0x14007d650, (uint64_t *)0x14007db00, (uint64_t *)0x14007da18, (uint64_t *)0x14007e1f0, (uint64_t *)0x14007d4c8, (uint64_t *)0x14007de28, (uint64_t *)0x14007dc70, (uint64_t *)0x14007d630, (uint64_t *)0x14007dc88, (uint64_t *)0x14007dda0, (uint64_t *)0x14007dba8, (uint64_t *)0x14007ddf8, (uint64_t *)0x14007d1f8, (uint64_t *)0x14007d568, (uint64_t *)0x14007db40, (uint64_t *)0x14007dc98, (uint64_t *)0x14007d748, (uint64_t *)0x14007d208, (uint64_t *)0x14007dd68, (uint64_t *)0x14007d388, (uint64_t *)0x14007d4b0, (uint64_t *)0x14007e138, (uint64_t *)0x14007da80, (uint64_t *)0x14007d480, }},
{(uint64_t *)0x14000ced0, (uint64_t *)0x140079f68, (uint64_t *)0x14007ac58, (uint64_t *)0x140076b48, {(uint64_t *)0x14007d6c8, (uint64_t *)0x14007d7f8, (uint64_t *)0x14007d1c8, (uint64_t *)0x14007df78, (uint64_t *)0x14007dd48, (uint64_t *)0x14007d978, (uint64_t *)0x14007e2b0, (uint64_t *)0x14007d958, (uint64_t *)0x14007d590, (uint64_t *)0x14007d298, (uint64_t *)0x14007e098, (uint64_t *)0x14007d788, (uint64_t *)0x14007d9e8, (uint64_t *)0x14007d9d0, (uint64_t *)0x14007d9a8, (uint64_t *)0x14007e238, (uint64_t *)0x14007d7d0, (uint64_t *)0x14007d220, (uint64_t *)0x14007d938, (uint64_t *)0x14007dbc8, (uint64_t *)0x14007dee0, (uint64_t *)0x14007d688, (uint64_t *)0x14007d850, (uint64_t *)0x14007d640, }},
{(uint64_t *)0x14000dff0, (uint64_t *)0x140079fe0, (uint64_t *)0x14007acd8, (uint64_t *)0x140076bc8, {(uint64_t *)0x14007d740, (uint64_t *)0x14007d8f8, (uint64_t *)0x14007d888, (uint64_t *)0x14007d358, (uint64_t *)0x14007e320, (uint64_t *)0x14007e370, (uint64_t *)0x14007dc38, (uint64_t *)0x14007da00, (uint64_t *)0x14007e2d0, (uint64_t *)0x14007dff8, (uint64_t *)0x14007dad8, (uint64_t *)0x14007dd98, (uint64_t *)0x14007d8c8, (uint64_t *)0x14007dba0, (uint64_t *)0x14007d2f0, (uint64_t *)0x14007d2c0, (uint64_t *)0x14007e1d0, (uint64_t *)0x14007e1d8, (uint64_t *)0x14007dc80, (uint64_t *)0x14007e2c0, (uint64_t *)0x14007e0f8, (uint64_t *)0x14007df58, (uint64_t *)0x14007d898, (uint64_t *)0x14007e008, }},
{(uint64_t *)0x140011af0, (uint64_t *)0x14007a180, (uint64_t *)0x14007acc0, (uint64_t *)0x140076bb0, {(uint64_t *)0x14007d8e0, (uint64_t *)0x14007d390, (uint64_t *)0x14007d720, (uint64_t *)0x14007e2c8, (uint64_t *)0x14007d9c0, (uint64_t *)0x14007d3b0, (uint64_t *)0x14007e1e0, (uint64_t *)0x14007d330, (uint64_t *)0x14007d488, (uint64_t *)0x14007d830, (uint64_t *)0x14007d570, (uint64_t *)0x14007e258, (uint64_t *)0x14007e1f8, (uint64_t *)0x14007e110, (uint64_t *)0x14007e228, (uint64_t *)0x14007db90, (uint64_t *)0x14007d6a0, (uint64_t *)0x14007df98, (uint64_t *)0x14007d910, (uint64_t *)0x14007d870, (uint64_t *)0x14007d790, (uint64_t *)0x14007d860, (uint64_t *)0x14007d718, (uint64_t *)0x14007dd70, }},
{(uint64_t *)0x140012890, (uint64_t *)0x14007a1e0, (uint64_t *)0x14007acd0, (uint64_t *)0x140076bc0, {(uint64_t *)0x14007d940, (uint64_t *)0x14007d360, (uint64_t *)0x14007e298, (uint64_t *)0x14007e200, (uint64_t *)0x14007d428, (uint64_t *)0x14007d8d0, (uint64_t *)0x14007d350, (uint64_t *)0x14007e318, (uint64_t *)0x14007da60, (uint64_t *)0x14007dec0, (uint64_t *)0x14007dd40, (uint64_t *)0x14007d2d8, (uint64_t *)0x14007d578, (uint64_t *)0x14007e0d0, (uint64_t *)0x14007d6b8, (uint64_t *)0x14007db18, (uint64_t *)0x14007dbd8, (uint64_t *)0x14007d758, (uint64_t *)0x14007d398, (uint64_t *)0x14007d260, (uint64_t *)0x14007d3d8, (uint64_t *)0x14007dd28, (uint64_t *)0x14007d678, (uint64_t *)0x14007d820, }},
{(uint64_t *)0x140014600, (uint64_t *)0x14007a2b0, (uint64_t *)0x14007ac60, (uint64_t *)0x140076b50, {(uint64_t *)0x14007da10, (uint64_t *)0x14007e0f0, (uint64_t *)0x14007d660, (uint64_t *)0x14007d6e8, (uint64_t *)0x14007db60, (uint64_t *)0x14007e308, (uint64_t *)0x14007d658, (uint64_t *)0x14007df70, (uint64_t *)0x14007d878, (uint64_t *)0x14007e210, (uint64_t *)0x14007d3a0, (uint64_t *)0x14007e038, (uint64_t *)0x14007e328, (uint64_t *)0x14007d840, (uint64_t *)0x14007d6e0, (uint64_t *)0x14007d838, (uint64_t *)0x14007d1e0, (uint64_t *)0x14007d280, (uint64_t *)0x14007d948, (uint64_t *)0x14007d408, (uint64_t *)0x14007e1c0, (uint64_t *)0x14007daa0, (uint64_t *)0x14007d1b0, (uint64_t *)0x14007e040, }},
{(uint64_t *)0x140014f10, (uint64_t *)0x14007a2f0, (uint64_t *)0x14007acb0, (uint64_t *)0x140076ba0, {(uint64_t *)0x14007da50, (uint64_t *)0x14007e2e8, (uint64_t *)0x14007dff0, (uint64_t *)0x14007e0a0, (uint64_t *)0x14007dfd0, (uint64_t *)0x14007db20, (uint64_t *)0x14007d608, (uint64_t *)0x14007dcc0, (uint64_t *)0x14007de98, (uint64_t *)0x14007de00, (uint64_t *)0x14007dbd0, (uint64_t *)0x14007d200, (uint64_t *)0x14007dc50, (uint64_t *)0x14007e108, (uint64_t *)0x14007de08, (uint64_t *)0x14007d8d8, (uint64_t *)0x14007d868, (uint64_t *)0x14007e268, (uint64_t *)0x14007d7e0, (uint64_t *)0x14007dcd8, (uint64_t *)0x14007def0, (uint64_t *)0x14007d7f0, (uint64_t *)0x14007dfe8, (uint64_t *)0x14007e088, }},
{(uint64_t *)0x140015830, (uint64_t *)0x14007a330, (uint64_t *)0x14007ac50, (uint64_t *)0x140076b40, {(uint64_t *)0x14007da90, (uint64_t *)0x14007d810, (uint64_t *)0x14007d230, (uint64_t *)0x14007d5f8, (uint64_t *)0x14007e208, (uint64_t *)0x14007d338, (uint64_t *)0x14007e0e8, (uint64_t *)0x14007e270, (uint64_t *)0x14007e068, (uint64_t *)0x14007db28, (uint64_t *)0x14007e150, (uint64_t *)0x14007d9e0, (uint64_t *)0x14007dbf8, (uint64_t *)0x14007d648, (uint64_t *)0x14007e118, (uint64_t *)0x14007d1c0, (uint64_t *)0x14007d510, (uint64_t *)0x14007d518, (uint64_t *)0x14007d2d0, (uint64_t *)0x14007dc18, (uint64_t *)0x14007e188, (uint64_t *)0x14007e1b8, (uint64_t *)0x14007e100, (uint64_t *)0x14007d4c0, }},
{(uint64_t *)0x140015960, (uint64_t *)0x14007a338, (uint64_t *)0x14007acb8, (uint64_t *)0x140076ba8, {(uint64_t *)0x14007da98, (uint64_t *)0x14007d9f8, (uint64_t *)0x14007e148, (uint64_t *)0x14007daf0, (uint64_t *)0x14007d5d8, (uint64_t *)0x14007e010, (uint64_t *)0x14007da28, (uint64_t *)0x14007d708, (uint64_t *)0x14007d998, (uint64_t *)0x14007d668, (uint64_t *)0x14007dcc8, (uint64_t *)0x14007d258, (uint64_t *)0x14007d290, (uint64_t *)0x14007d858, (uint64_t *)0x14007e028, (uint64_t *)0x14007db08, (uint64_t *)0x14007df10, (uint64_t *)0x14007d528, (uint64_t *)0x14007dc10, (uint64_t *)0x14007d770, (uint64_t *)0x14007d308, (uint64_t *)0x14007e280, (uint64_t *)0x14007de80, (uint64_t *)0x14007d7b8, }},
{(uint64_t *)0x14001afe0, (uint64_t *)0x14007a598, (uint64_t *)0x14007ac98, (uint64_t *)0x140076b88, {(uint64_t *)0x14007dcf8, (uint64_t *)0x14007d818, (uint64_t *)0x14007dc30, (uint64_t *)0x14007e030, (uint64_t *)0x14007d2e0, (uint64_t *)0x14007d498, (uint64_t *)0x14007d5e8, (uint64_t *)0x14007e250, (uint64_t *)0x14007d548, (uint64_t *)0x14007d4f8, (uint64_t *)0x14007d450, (uint64_t *)0x14007e2d8, (uint64_t *)0x14007ddd0, (uint64_t *)0x14007df20, (uint64_t *)0x14007df80, (uint64_t *)0x14007d310, (uint64_t *)0x14007de38, (uint64_t *)0x14007d6b0, (uint64_t *)0x14007df40, (uint64_t *)0x14007db78, (uint64_t *)0x14007d5f0, (uint64_t *)0x14007d1e8, (uint64_t *)0x14007db50, (uint64_t *)0x14007d1a8, }},
{(uint64_t *)0x14001b220, (uint64_t *)0x14007a5a8, (uint64_t *)0x14007ac48, (uint64_t *)0x140076b38, {(uint64_t *)0x14007dd08, (uint64_t *)0x14007de18, (uint64_t *)0x14007d520, (uint64_t *)0x14007da88, (uint64_t *)0x14007d5b0, (uint64_t *)0x14007e340, (uint64_t *)0x14007e178, (uint64_t *)0x14007dc58, (uint64_t *)0x14007db58, (uint64_t *)0x14007dea8, (uint64_t *)0x14007d468, (uint64_t *)0x14007d4d8, (uint64_t *)0x14007e1e8, (uint64_t *)0x14007d4e0, (uint64_t *)0x14007d320, (uint64_t *)0x14007e338, (uint64_t *)0x14007d5a8, (uint64_t *)0x14007df60, (uint64_t *)0x14007d530, (uint64_t *)0x14007dca8, (uint64_t *)0x14007d728, (uint64_t *)0x14007d2e8, (uint64_t *)0x14007d500, (uint64_t *)0x14007e260, }},
{(uint64_t *)0x14001e200, (uint64_t *)0x14007a6f8, (uint64_t *)0x14007ac38, (uint64_t *)0x140076b28, {(uint64_t *)0x14007de58, (uint64_t *)0x14007d698, (uint64_t *)0x14007db38, (uint64_t *)0x14007dd38, (uint64_t *)0x14007e050, (uint64_t *)0x14007dd78, (uint64_t *)0x14007ded0, (uint64_t *)0x14007dfc0, (uint64_t *)0x14007dac8, (uint64_t *)0x14007d190, (uint64_t *)0x14007e128, (uint64_t *)0x14007d7c0, (uint64_t *)0x14007e360, (uint64_t *)0x14007d2c8, (uint64_t *)0x14007d3d0, (uint64_t *)0x14007de10, (uint64_t *)0x14007d460, (uint64_t *)0x14007e130, (uint64_t *)0x14007d768, (uint64_t *)0x14007db88, (uint64_t *)0x14007d620, (uint64_t *)0x14007d598, (uint64_t *)0x14007ddb8, (uint64_t *)0x14007e158, }},
{(uint64_t *)0x14001ea00, (uint64_t *)0x14007a730, (uint64_t *)0x14007ac70, (uint64_t *)0x140076b60, {(uint64_t *)0x14007de90, (uint64_t *)0x14007d2a8, (uint64_t *)0x14007d7a0, (uint64_t *)0x14007e120, (uint64_t *)0x14007d8a8, (uint64_t *)0x14007de78, (uint64_t *)0x14007dec8, (uint64_t *)0x14007d7c8, (uint64_t *)0x14007dc28, (uint64_t *)0x14007dc68, (uint64_t *)0x14007dea0, (uint64_t *)0x14007d368, (uint64_t *)0x14007e1c8, (uint64_t *)0x14007e048, (uint64_t *)0x14007d438, (uint64_t *)0x14007e290, (uint64_t *)0x14007e288, (uint64_t *)0x14007da40, (uint64_t *)0x14007d4e8, (uint64_t *)0x14007d4a8, (uint64_t *)0x14007db10, (uint64_t *)0x14007e160, (uint64_t *)0x14007e2a0, (uint64_t *)0x14007d2a0, }},
{(uint64_t *)0x14001ee80, (uint64_t *)0x14007a750, (uint64_t *)0x14007ac30, (uint64_t *)0x140076b20, {(uint64_t *)0x14007deb0, (uint64_t *)0x14007def8, (uint64_t *)0x14007da48, (uint64_t *)0x14007dce0, (uint64_t *)0x14007d628, (uint64_t *)0x14007d250, (uint64_t *)0x14007dab8, (uint64_t *)0x14007e190, (uint64_t *)0x14007d900, (uint64_t *)0x14007d268, (uint64_t *)0x14007d890, (uint64_t *)0x14007d3c0, (uint64_t *)0x14007e248, (uint64_t *)0x14007e0d8, (uint64_t *)0x14007e300, (uint64_t *)0x14007e0b8, (uint64_t *)0x14007d210, (uint64_t *)0x14007ddc0, (uint64_t *)0x14007d6f0, (uint64_t *)0x14007d738, (uint64_t *)0x14007deb8, (uint64_t *)0x14007dcb0, (uint64_t *)0x14007e020, (uint64_t *)0x14007dd58, }},
{(uint64_t *)0x140020870, (uint64_t *)0x14007a808, (uint64_t *)0x14007aca8, (uint64_t *)0x140076b98, {(uint64_t *)0x14007df68, (uint64_t *)0x14007dc90, (uint64_t *)0x14007dab0, (uint64_t *)0x14007dfe0, (uint64_t *)0x14007da78, (uint64_t *)0x14007e240, (uint64_t *)0x14007d808, (uint64_t *)0x14007d8f0, (uint64_t *)0x14007dd90, (uint64_t *)0x14007d798, (uint64_t *)0x14007d588, (uint64_t *)0x14007d6c0, (uint64_t *)0x14007e2f8, (uint64_t *)0x14007df28, (uint64_t *)0x14007d3a8, (uint64_t *)0x14007de70, (uint64_t *)0x14007d8a0, (uint64_t *)0x14007dfa0, (uint64_t *)0x14007dad0, (uint64_t *)0x14007d638, (uint64_t *)0x14007df38, (uint64_t *)0x14007d278, (uint64_t *)0x14007d780, (uint64_t *)0x14007d238, }},
{(uint64_t *)0x1400212a0, (uint64_t *)0x14007a850, (uint64_t *)0x14007ac40, (uint64_t *)0x140076b30, {(uint64_t *)0x14007dfb0, (uint64_t *)0x14007d8c0, (uint64_t *)0x14007e080, (uint64_t *)0x14007dc08, (uint64_t *)0x14007e170, (uint64_t *)0x14007d710, (uint64_t *)0x14007e198, (uint64_t *)0x14007d418, (uint64_t *)0x14007da58, (uint64_t *)0x14007d5b8, (uint64_t *)0x14007d6d0, (uint64_t *)0x14007d930, (uint64_t *)0x14007df30, (uint64_t *)0x14007d8e8, (uint64_t *)0x14007e078, (uint64_t *)0x14007d950, (uint64_t *)0x14007d550, (uint64_t *)0x14007dc78, (uint64_t *)0x14007d828, (uint64_t *)0x14007dd50, (uint64_t *)0x14007d600, (uint64_t *)0x14007d6a8, (uint64_t *)0x14007d760, (uint64_t *)0x14007e2a8, }},
{(uint64_t *)0x140021620, (uint64_t *)0x14007a868, (uint64_t *)0x14007aca0, (uint64_t *)0x140076b90, {(uint64_t *)0x14007dfc8, (uint64_t *)0x14007d378, (uint64_t *)0x14007d670, (uint64_t *)0x14007e348, (uint64_t *)0x14007de88, (uint64_t *)0x14007d580, (uint64_t *)0x14007dd80, (uint64_t *)0x14007d3b8, (uint64_t *)0x14007de48, (uint64_t *)0x14007e058, (uint64_t *)0x14007dc60, (uint64_t *)0x14007e2f0, (uint64_t *)0x14007dce8, (uint64_t *)0x14007db30, (uint64_t *)0x14007dd10, (uint64_t *)0x14007de50, (uint64_t *)0x14007ddc8, (uint64_t *)0x14007d8b8, (uint64_t *)0x14007dcf0, (uint64_t *)0x14007e0a8, (uint64_t *)0x14007d328, (uint64_t *)0x14007da38, (uint64_t *)0x14007d750, (uint64_t *)0x14007e140, }},
{(uint64_t *)0x1400251c0, (uint64_t *)0x14007aa08, (uint64_t *)0x14007ace0, (uint64_t *)0x140076bd0, {(uint64_t *)0x14007e168, (uint64_t *)0x14007d440, (uint64_t *)0x14007d300, (uint64_t *)0x14007de60, (uint64_t *)0x14007e310, (uint64_t *)0x14007df88, (uint64_t *)0x14007e1a8, (uint64_t *)0x14007dd30, (uint64_t *)0x14007dbe0, (uint64_t *)0x14007e350, (uint64_t *)0x14007d9f0, (uint64_t *)0x14007e000, (uint64_t *)0x14007de30, (uint64_t *)0x14007d1d8, (uint64_t *)0x14007e0e0, (uint64_t *)0x14007d3e8, (uint64_t *)0x14007da68, (uint64_t *)0x14007d420, (uint64_t *)0x14007db98, (uint64_t *)0x14007d1f0, (uint64_t *)0x14007e218, (uint64_t *)0x14007d690, (uint64_t *)0x14007d9b8, (uint64_t *)0x14007dfd8, }},
{(uint64_t *)0x1400259d0, (uint64_t *)0x14007aa40, (uint64_t *)0x14007ac88, (uint64_t *)0x140076b78, {(uint64_t *)0x14007e1a0, (uint64_t *)0x14007dd20, (uint64_t *)0x14007e230, (uint64_t *)0x14007ddf0, (uint64_t *)0x14007d430, (uint64_t *)0x14007d700, (uint64_t *)0x14007d538, (uint64_t *)0x14007e330, (uint64_t *)0x14007e380, (uint64_t *)0x14007d380, (uint64_t *)0x14007d7a8, (uint64_t *)0x14007d7e8, (uint64_t *)0x14007d980, (uint64_t *)0x14007d4b8, (uint64_t *)0x14007d990, (uint64_t *)0x14007d988, (uint64_t *)0x14007dd60, (uint64_t *)0x14007e368, (uint64_t *)0x14007d3f8, (uint64_t *)0x14007d3c8, (uint64_t *)0x14007daa8, (uint64_t *)0x14007dc00, (uint64_t *)0x14007d618, (uint64_t *)0x14007d1a0, }},
{(uint64_t *)0x140025c20, (uint64_t *)0x14007aa50, (uint64_t *)0x14007acc8, (uint64_t *)0x140076bb8, {(uint64_t *)0x14007e1b0, (uint64_t *)0x14007da30, (uint64_t *)0x14007df08, (uint64_t *)0x14007e0b0, (uint64_t *)0x14007d610, (uint64_t *)0x14007e0c0, (uint64_t *)0x14007e278, (uint64_t *)0x14007df90, (uint64_t *)0x14007d5d0, (uint64_t *)0x14007dae8, (uint64_t *)0x14007d340, (uint64_t *)0x14007ded8, (uint64_t *)0x14007dca0, (uint64_t *)0x14007da20, (uint64_t *)0x14007d5c0, (uint64_t *)0x14007d9c8, (uint64_t *)0x14007d928, (uint64_t *)0x14007da08, (uint64_t *)0x14007e358, (uint64_t *)0x14007d880, (uint64_t *)0x14007db80, (uint64_t *)0x14007dd18, (uint64_t *)0x14007d9d8, (uint64_t *)0x14007d9a0, }},
{(uint64_t *)0x140026c20, (uint64_t *)0x14007aac0, (uint64_t *)0x14007ac80, (uint64_t *)0x140076b70, {(uint64_t *)0x14007e220, (uint64_t *)0x14007de68, (uint64_t *)0x14007e2e0, (uint64_t *)0x14007d970, (uint64_t *)0x14007db70, (uint64_t *)0x14007d8b0, (uint64_t *)0x14007da70, (uint64_t *)0x14007dc20, (uint64_t *)0x14007d270, (uint64_t *)0x14007df50, (uint64_t *)0x14007d348, (uint64_t *)0x14007de40, (uint64_t *)0x14007d6d8, (uint64_t *)0x14007d778, (uint64_t *)0x14007d318, (uint64_t *)0x14007dfb8, (uint64_t *)0x14007dd88, (uint64_t *)0x14007e180, (uint64_t *)0x14007d490, (uint64_t *)0x14007dbb0, (uint64_t *)0x14007dda8, (uint64_t *)0x14007ddb0, (uint64_t *)0x14007e018, (uint64_t *)0x14007d5c8, }},
{(uint64_t *)0x140029f40, (uint64_t *)0x14007ac28, (uint64_t *)0x14007ac68, (uint64_t *)0x140076b58, {(uint64_t *)0x14007e388, (uint64_t *)0x14007d7d8, (uint64_t *)0x14007dbb8, (uint64_t *)0x14007dbf0, (uint64_t *)0x14007dbe8, (uint64_t *)0x14007e060, (uint64_t *)0x14007d918, (uint64_t *)0x14007d410, (uint64_t *)0x14007dde0, (uint64_t *)0x14007d218, (uint64_t *)0x14007d540, (uint64_t *)0x14007d370, (uint64_t *)0x14007d6f8, (uint64_t *)0x14007d560, (uint64_t *)0x14007d558, (uint64_t *)0x14007d4d0, (uint64_t *)0x14007d1d0, (uint64_t *)0x14007d2b0, (uint64_t *)0x14007d508, (uint64_t *)0x14007db48, (uint64_t *)0x14007d848, (uint64_t *)0x14007ddd8, (uint64_t *)0x14007df18, (uint64_t *)0x14007dae0, }},
{(uint64_t *)0x14002b2e0, (uint64_t *)0x14007ad70, (uint64_t *)0x14007bf70, (uint64_t *)0x140076c60, {(uint64_t *)0x14007d210, (uint64_t *)0x14007d460, (uint64_t *)0x14007d550, (uint64_t *)0x14007d5a8, (uint64_t *)0x14007d510, (uint64_t *)0x14007d7d0, (uint64_t *)0x14007d1e0, (uint64_t *)0x14007d1d0, (uint64_t *)0x14007e288, (uint64_t *)0x14007e2b8, (uint64_t *)0x14007dd88, (uint64_t *)0x14007dd60, (uint64_t *)0x14007d458, (uint64_t *)0x14007de38, (uint64_t *)0x14007ddc8, (uint64_t *)0x14007d8a0, (uint64_t *)0x14007d868, (uint64_t *)0x14007df10, (uint64_t *)0x14007d6a0, (uint64_t *)0x14007d928, (uint64_t *)0x14007dbd8, (uint64_t *)0x14007e1d0, (uint64_t *)0x14007da68, (uint64_t *)0x14007d748, }},
{(uint64_t *)0x14002bc00, (uint64_t *)0x14007adb0, (uint64_t *)0x14007bf18, (uint64_t *)0x140076c08, {(uint64_t *)0x14007d250, (uint64_t *)0x14007dd78, (uint64_t *)0x14007d710, (uint64_t *)0x14007e340, (uint64_t *)0x14007d338, (uint64_t *)0x14007d978, (uint64_t *)0x14007e308, (uint64_t *)0x14007e060, (uint64_t *)0x14007de78, (uint64_t *)0x14007dc40, (uint64_t *)0x14007d8b0, (uint64_t *)0x14007d700, (uint64_t *)0x14007dcd0, (uint64_t *)0x14007d498, (uint64_t *)0x14007d580, (uint64_t *)0x14007e240, (uint64_t *)0x14007db20, (uint64_t *)0x14007e010, (uint64_t *)0x14007d3b0, (uint64_t *)0x14007e0c0, (uint64_t *)0x14007d8d0, (uint64_t *)0x14007e370, (uint64_t *)0x14007df88, (uint64_t *)0x14007de28, }},
{(uint64_t *)0x14002bf60, (uint64_t *)0x14007adc8, (uint64_t *)0x14007bf38, (uint64_t *)0x140076c28, {(uint64_t *)0x14007d268, (uint64_t *)0x14007d190, (uint64_t *)0x14007d5b8, (uint64_t *)0x14007dea8, (uint64_t *)0x14007db28, (uint64_t *)0x14007d298, (uint64_t *)0x14007e210, (uint64_t *)0x14007d218, (uint64_t *)0x14007dc68, (uint64_t *)0x14007dd00, (uint64_t *)0x14007df50, (uint64_t *)0x14007d380, (uint64_t *)0x14007d240, (uint64_t *)0x14007d4f8, (uint64_t *)0x14007e058, (uint64_t *)0x14007d798, (uint64_t *)0x14007de00, (uint64_t *)0x14007d668, (uint64_t *)0x14007d830, (uint64_t *)0x14007dae8, (uint64_t *)0x14007dec0, (uint64_t *)0x14007dff8, (uint64_t *)0x14007e350, (uint64_t *)0x14007dda0, }},
{(uint64_t *)0x14002f050, (uint64_t *)0x14007af20, (uint64_t *)0x14007bf48, (uint64_t *)0x140076c38, {(uint64_t *)0x14007d3c0, (uint64_t *)0x14007d7c0, (uint64_t *)0x14007d930, (uint64_t *)0x14007d4d8, (uint64_t *)0x14007d9e0, (uint64_t *)0x14007d788, (uint64_t *)0x14007e038, (uint64_t *)0x14007d370, (uint64_t *)0x14007d368, (uint64_t *)0x14007d478, (uint64_t *)0x14007de40, (uint64_t *)0x14007d7e8, (uint64_t *)0x14007d400, (uint64_t *)0x14007e2d8, (uint64_t *)0x14007e2f0, (uint64_t *)0x14007d6c0, (uint64_t *)0x14007d200, (uint64_t *)0x14007d258, (uint64_t *)0x14007e258, (uint64_t *)0x14007ded8, (uint64_t *)0x14007d2d8, (uint64_t *)0x14007dd98, (uint64_t *)0x14007e000, (uint64_t *)0x14007ddf8, }},
{(uint64_t *)0x140034850, (uint64_t *)0x14007b188, (uint64_t *)0x14007bf10, (uint64_t *)0x140076c00, {(uint64_t *)0x14007d628, (uint64_t *)0x14007e050, (uint64_t *)0x14007e170, (uint64_t *)0x14007d5b0, (uint64_t *)0x14007e208, (uint64_t *)0x14007dd48, (uint64_t *)0x14007db60, (uint64_t *)0x14007dbe8, (uint64_t *)0x14007d8a8, (uint64_t *)0x14007d5e0, (uint64_t *)0x14007db70, (uint64_t *)0x14007d430, (uint64_t *)0x14007dc48, (uint64_t *)0x14007d2e0, (uint64_t *)0x14007de88, (uint64_t *)0x14007da78, (uint64_t *)0x14007dfd0, (uint64_t *)0x14007d5d8, (uint64_t *)0x14007d9c0, (uint64_t *)0x14007d610, (uint64_t *)0x14007d428, (uint64_t *)0x14007e320, (uint64_t *)0x14007e310, (uint64_t *)0x14007d4c8, }},
{(uint64_t *)0x1400364c0, (uint64_t *)0x14007b250, (uint64_t *)0x14007bf80, (uint64_t *)0x140076c70, {(uint64_t *)0x14007d6f0, (uint64_t *)0x14007d768, (uint64_t *)0x14007d828, (uint64_t *)0x14007d530, (uint64_t *)0x14007d2d0, (uint64_t *)0x14007d938, (uint64_t *)0x14007d948, (uint64_t *)0x14007d508, (uint64_t *)0x14007d4e8, (uint64_t *)0x14007e378, (uint64_t *)0x14007d490, (uint64_t *)0x14007d3f8, (uint64_t *)0x14007d2f8, (uint64_t *)0x14007df40, (uint64_t *)0x14007dcf0, (uint64_t *)0x14007dad0, (uint64_t *)0x14007d7e0, (uint64_t *)0x14007dc10, (uint64_t *)0x14007d910, (uint64_t *)0x14007e358, (uint64_t *)0x14007d398, (uint64_t *)0x14007dc80, (uint64_t *)0x14007db98, (uint64_t *)0x14007dd68, }},
{(uint64_t *)0x140036f10, (uint64_t *)0x14007b298, (uint64_t *)0x14007bf88, (uint64_t *)0x140076c78, {(uint64_t *)0x14007d738, (uint64_t *)0x14007db88, (uint64_t *)0x14007dd50, (uint64_t *)0x14007dca8, (uint64_t *)0x14007dc18, (uint64_t *)0x14007dbc8, (uint64_t *)0x14007d408, (uint64_t *)0x14007db48, (uint64_t *)0x14007d4a8, (uint64_t *)0x14007d3e0, (uint64_t *)0x14007dbb0, (uint64_t *)0x14007d3c8, (uint64_t *)0x14007d288, (uint64_t *)0x14007db78, (uint64_t *)0x14007e0a8, (uint64_t *)0x14007d638, (uint64_t *)0x14007dcd8, (uint64_t *)0x14007d770, (uint64_t *)0x14007d870, (uint64_t *)0x14007d880, (uint64_t *)0x14007d260, (uint64_t *)0x14007e2c0, (uint64_t *)0x14007d1f0, (uint64_t *)0x14007d388, }},
{(uint64_t *)0x14003a060, (uint64_t *)0x14007b3f0, (uint64_t *)0x14007bf40, (uint64_t *)0x140076c30, {(uint64_t *)0x14007d890, (uint64_t *)0x14007e128, (uint64_t *)0x14007d6d0, (uint64_t *)0x14007d468, (uint64_t *)0x14007e150, (uint64_t *)0x14007e098, (uint64_t *)0x14007d3a0, (uint64_t *)0x14007d540, (uint64_t *)0x14007dea0, (uint64_t *)0x14007dcb8, (uint64_t *)0x14007d348, (uint64_t *)0x14007d7a8, (uint64_t *)0x14007d730, (uint64_t *)0x14007d450, (uint64_t *)0x14007dc60, (uint64_t *)0x14007d588, (uint64_t *)0x14007dbd0, (uint64_t *)0x14007dcc8, (uint64_t *)0x14007d570, (uint64_t *)0x14007d340, (uint64_t *)0x14007dd40, (uint64_t *)0x14007dad8, (uint64_t *)0x14007d9f0, (uint64_t *)0x14007dba8, }},
{(uint64_t *)0x14003b040, (uint64_t *)0x14007b460, (uint64_t *)0x14007bf30, (uint64_t *)0x140076c20, {(uint64_t *)0x14007d900, (uint64_t *)0x14007dac8, (uint64_t *)0x14007da58, (uint64_t *)0x14007db58, (uint64_t *)0x14007e068, (uint64_t *)0x14007d590, (uint64_t *)0x14007d878, (uint64_t *)0x14007dde0, (uint64_t *)0x14007dc28, (uint64_t *)0x14007d968, (uint64_t *)0x14007d270, (uint64_t *)0x14007e380, (uint64_t *)0x14007d198, (uint64_t *)0x14007d548, (uint64_t *)0x14007de48, (uint64_t *)0x14007dd90, (uint64_t *)0x14007de98, (uint64_t *)0x14007d998, (uint64_t *)0x14007d488, (uint64_t *)0x14007d5d0, (uint64_t *)0x14007da60, (uint64_t *)0x14007e2d0, (uint64_t *)0x14007dbe0, (uint64_t *)0x14007dc88, }},
{(uint64_t *)0x14003dfc0, (uint64_t *)0x14007b5a8, (uint64_t *)0x14007bf00, (uint64_t *)0x140076bf0, {(uint64_t *)0x14007da48, (uint64_t *)0x14007db38, (uint64_t *)0x14007e080, (uint64_t *)0x14007d520, (uint64_t *)0x14007d230, (uint64_t *)0x14007d1c8, (uint64_t *)0x14007d660, (uint64_t *)0x14007dbb8, (uint64_t *)0x14007d7a0, (uint64_t *)0x14007dde8, (uint64_t *)0x14007e2e0, (uint64_t *)0x14007e230, (uint64_t *)0x14007e0c8, (uint64_t *)0x14007dc30, (uint64_t *)0x14007d670, (uint64_t *)0x14007dab0, (uint64_t *)0x14007dff0, (uint64_t *)0x14007e148, (uint64_t *)0x14007d720, (uint64_t *)0x14007df08, (uint64_t *)0x14007e298, (uint64_t *)0x14007d888, (uint64_t *)0x14007d300, (uint64_t *)0x14007da18, }},
{(uint64_t *)0x14003efb0, (uint64_t *)0x14007b618, (uint64_t *)0x14007bf20, (uint64_t *)0x140076c10, {(uint64_t *)0x14007dab8, (uint64_t *)0x14007ded0, (uint64_t *)0x14007e198, (uint64_t *)0x14007e178, (uint64_t *)0x14007e0e8, (uint64_t *)0x14007e2b0, (uint64_t *)0x14007d658, (uint64_t *)0x14007d918, (uint64_t *)0x14007dec8, (uint64_t *)0x14007e070, (uint64_t *)0x14007da70, (uint64_t *)0x14007d538, (uint64_t *)0x14007dac0, (uint64_t *)0x14007d5e8, (uint64_t *)0x14007dd80, (uint64_t *)0x14007d808, (uint64_t *)0x14007d608, (uint64_t *)0x14007da28, (uint64_t *)0x14007e1e0, (uint64_t *)0x14007e278, (uint64_t *)0x14007d350, (uint64_t *)0x14007dc38, (uint64_t *)0x14007e1a8, (uint64_t *)0x14007dc70, }},
{(uint64_t *)0x140043750, (uint64_t *)0x14007b810, (uint64_t *)0x14007bf98, (uint64_t *)0x140076c88, {(uint64_t *)0x14007dcb0, (uint64_t *)0x14007d598, (uint64_t *)0x14007d6a8, (uint64_t *)0x14007d2e8, (uint64_t *)0x14007e1b8, (uint64_t *)0x14007d688, (uint64_t *)0x14007daa0, (uint64_t *)0x14007ddd8, (uint64_t *)0x14007e160, (uint64_t *)0x14007d5a0, (uint64_t *)0x14007ddb0, (uint64_t *)0x14007dc00, (uint64_t *)0x14007df48, (uint64_t *)0x14007d1e8, (uint64_t *)0x14007da38, (uint64_t *)0x14007d278, (uint64_t *)0x14007d7f0, (uint64_t *)0x14007e280, (uint64_t *)0x14007d860, (uint64_t *)0x14007dd18, (uint64_t *)0x14007dd28, (uint64_t *)0x14007df58, (uint64_t *)0x14007d690, (uint64_t *)0x14007e138, }},
{(uint64_t *)0x140043e20, (uint64_t *)0x14007b840, (uint64_t *)0x14007bf08, (uint64_t *)0x140076bf8, {(uint64_t *)0x14007dce0, (uint64_t *)0x14007dd38, (uint64_t *)0x14007dc08, (uint64_t *)0x14007da88, (uint64_t *)0x14007d5f8, (uint64_t *)0x14007df78, (uint64_t *)0x14007d6e8, (uint64_t *)0x14007dbf0, (uint64_t *)0x14007e120, (uint64_t *)0x14007db68, (uint64_t *)0x14007d970, (uint64_t *)0x14007ddf0, (uint64_t *)0x14007de20, (uint64_t *)0x14007e030, (uint64_t *)0x14007e348, (uint64_t *)0x14007dfe0, (uint64_t *)0x14007e0a0, (uint64_t *)0x14007daf0, (uint64_t *)0x14007e2c8, (uint64_t *)0x14007e0b0, (uint64_t *)0x14007e200, (uint64_t *)0x14007d358, (uint64_t *)0x14007de60, (uint64_t *)0x14007e1f0, }},
{(uint64_t *)0x140044f40, (uint64_t *)0x14007b8b8, (uint64_t *)0x14007bfa8, (uint64_t *)0x140076c98, {(uint64_t *)0x14007dd58, (uint64_t *)0x14007e158, (uint64_t *)0x14007e2a8, (uint64_t *)0x14007e260, (uint64_t *)0x14007d4c0, (uint64_t *)0x14007d640, (uint64_t *)0x14007e040, (uint64_t *)0x14007dae0, (uint64_t *)0x14007d2a0, (uint64_t *)0x14007d908, (uint64_t *)0x14007d5c8, (uint64_t *)0x14007d1a0, (uint64_t *)0x14007d680, (uint64_t *)0x14007d1a8, (uint64_t *)0x14007e140, (uint64_t *)0x14007d238, (uint64_t *)0x14007e088, (uint64_t *)0x14007d7b8, (uint64_t *)0x14007dd70, (uint64_t *)0x14007d9a0, (uint64_t *)0x14007d820, (uint64_t *)0x14007e008, (uint64_t *)0x14007dfd8, (uint64_t *)0x14007d480, }},
{(uint64_t *)0x140045e40, (uint64_t *)0x14007b920, (uint64_t *)0x14007bf78, (uint64_t *)0x140076c68, {(uint64_t *)0x14007ddc0, (uint64_t *)0x14007e130, (uint64_t *)0x14007dc78, (uint64_t *)0x14007df60, (uint64_t *)0x14007d518, (uint64_t *)0x14007d220, (uint64_t *)0x14007d280, (uint64_t *)0x14007d2b0, (uint64_t *)0x14007da40, (uint64_t *)0x14007d2b8, (uint64_t *)0x14007e180, (uint64_t *)0x14007e368, (uint64_t *)0x14007df00, (uint64_t *)0x14007d6b0, (uint64_t *)0x14007d8b8, (uint64_t *)0x14007dfa0, (uint64_t *)0x14007e268, (uint64_t *)0x14007d528, (uint64_t *)0x14007df98, (uint64_t *)0x14007da08, (uint64_t *)0x14007d758, (uint64_t *)0x14007e1d8, (uint64_t *)0x14007d420, (uint64_t *)0x14007d208, }},
{(uint64_t *)0x140048040, (uint64_t *)0x14007ba10, (uint64_t *)0x14007bef0, (uint64_t *)0x140076be0, {(uint64_t *)0x14007deb0, (uint64_t *)0x14007de58, (uint64_t *)0x14007dfb0, (uint64_t *)0x14007dd08, (uint64_t *)0x14007da90, (uint64_t *)0x14007d6c8, (uint64_t *)0x14007da10, (uint64_t *)0x14007e388, (uint64_t *)0x14007de90, (uint64_t *)0x14007d3f0, (uint64_t *)0x14007e220, (uint64_t *)0x14007e1a0, (uint64_t *)0x14007d248, (uint64_t *)0x14007dcf8, (uint64_t *)0x14007dfc8, (uint64_t *)0x14007df68, (uint64_t *)0x14007da50, (uint64_t *)0x14007da98, (uint64_t *)0x14007d8e0, (uint64_t *)0x14007e1b0, (uint64_t *)0x14007d940, (uint64_t *)0x14007d740, (uint64_t *)0x14007e168, (uint64_t *)0x14007d650, }},
{(uint64_t *)0x140048160, (uint64_t *)0x14007ba18, (uint64_t *)0x14007bf90, (uint64_t *)0x140076c80, {(uint64_t *)0x14007deb8, (uint64_t *)0x14007d620, (uint64_t *)0x14007d600, (uint64_t *)0x14007d728, (uint64_t *)0x14007e188, (uint64_t *)0x14007dee0, (uint64_t *)0x14007e1c0, (uint64_t *)0x14007d848, (uint64_t *)0x14007db10, (uint64_t *)0x14007d1b8, (uint64_t *)0x14007dda8, (uint64_t *)0x14007daa8, (uint64_t *)0x14007daf8, (uint64_t *)0x14007d5f0, (uint64_t *)0x14007d328, (uint64_t *)0x14007df38, (uint64_t *)0x14007def0, (uint64_t *)0x14007d308, (uint64_t *)0x14007d790, (uint64_t *)0x14007db80, (uint64_t *)0x14007d3d8, (uint64_t *)0x14007e0f8, (uint64_t *)0x14007e218, (uint64_t *)0x14007d4b0, }},
{(uint64_t *)0x140048a80, (uint64_t *)0x14007ba58, (uint64_t *)0x14007bef8, (uint64_t *)0x140076be8, {(uint64_t *)0x14007def8, (uint64_t *)0x14007d698, (uint64_t *)0x14007d8c0, (uint64_t *)0x14007de18, (uint64_t *)0x14007d810, (uint64_t *)0x14007d7f8, (uint64_t *)0x14007e0f0, (uint64_t *)0x14007d7d8, (uint64_t *)0x14007d2a8, (uint64_t *)0x14007d960, (uint64_t *)0x14007de68, (uint64_t *)0x14007dd20, (uint64_t *)0x14007d920, (uint64_t *)0x14007d818, (uint64_t *)0x14007d378, (uint64_t *)0x14007dc90, (uint64_t *)0x14007e2e8, (uint64_t *)0x14007d9f8, (uint64_t *)0x14007d390, (uint64_t *)0x14007da30, (uint64_t *)0x14007d360, (uint64_t *)0x14007d8f8, (uint64_t *)0x14007d440, (uint64_t *)0x14007db00, }},
{(uint64_t *)0x14004b4c0, (uint64_t *)0x14007bb80, (uint64_t *)0x14007bfa0, (uint64_t *)0x140076c90, {(uint64_t *)0x14007e020, (uint64_t *)0x14007ddb8, (uint64_t *)0x14007d760, (uint64_t *)0x14007d500, (uint64_t *)0x14007e100, (uint64_t *)0x14007d850, (uint64_t *)0x14007d1b0, (uint64_t *)0x14007df18, (uint64_t *)0x14007e2a0, (uint64_t *)0x14007d7b0, (uint64_t *)0x14007e018, (uint64_t *)0x14007d618, (uint64_t *)0x14007dbc0, (uint64_t *)0x14007db50, (uint64_t *)0x14007d750, (uint64_t *)0x14007d780, (uint64_t *)0x14007dfe8, (uint64_t *)0x14007de80, (uint64_t *)0x14007d718, (uint64_t *)0x14007d9d8, (uint64_t *)0x14007d678, (uint64_t *)0x14007d898, (uint64_t *)0x14007d9b8, (uint64_t *)0x14007da80, }},
{(uint64_t *)0x14004ca70, (uint64_t *)0x14007bc18, (uint64_t *)0x14007bf68, (uint64_t *)0x140076c58, {(uint64_t *)0x14007e0b8, (uint64_t *)0x14007de10, (uint64_t *)0x14007d950, (uint64_t *)0x14007e338, (uint64_t *)0x14007d1c0, (uint64_t *)0x14007e238, (uint64_t *)0x14007d838, (uint64_t *)0x14007d4d0, (uint64_t *)0x14007e290, (uint64_t *)0x14007dee8, (uint64_t *)0x14007dfb8, (uint64_t *)0x14007d988, (uint64_t *)0x14007dfa8, (uint64_t *)0x14007d310, (uint64_t *)0x14007de50, (uint64_t *)0x14007de70, (uint64_t *)0x14007d8d8, (uint64_t *)0x14007db08, (uint64_t *)0x14007db90, (uint64_t *)0x14007d9c8, (uint64_t *)0x14007db18, (uint64_t *)0x14007d2c0, (uint64_t *)0x14007d3e8, (uint64_t *)0x14007dc98, }},
{(uint64_t *)0x14004cef0, (uint64_t *)0x14007bc38, (uint64_t *)0x14007bf58, (uint64_t *)0x140076c48, {(uint64_t *)0x14007e0d8, (uint64_t *)0x14007d2c8, (uint64_t *)0x14007d8e8, (uint64_t *)0x14007d4e0, (uint64_t *)0x14007d648, (uint64_t *)0x14007d9d0, (uint64_t *)0x14007d840, (uint64_t *)0x14007d560, (uint64_t *)0x14007e048, (uint64_t *)0x14007e090, (uint64_t *)0x14007d778, (uint64_t *)0x14007d4b8, (uint64_t *)0x14007d228, (uint64_t *)0x14007df20, (uint64_t *)0x14007db30, (uint64_t *)0x14007df28, (uint64_t *)0x14007e108, (uint64_t *)0x14007d858, (uint64_t *)0x14007e110, (uint64_t *)0x14007da20, (uint64_t *)0x14007e0d0, (uint64_t *)0x14007dba0, (uint64_t *)0x14007d1d8, (uint64_t *)0x14007d568, }},
{(uint64_t *)0x14004e920, (uint64_t *)0x14007bcf0, (uint64_t *)0x14007bf28, (uint64_t *)0x140076c18, {(uint64_t *)0x14007e190, (uint64_t *)0x14007dfc0, (uint64_t *)0x14007d418, (uint64_t *)0x14007dc58, (uint64_t *)0x14007e270, (uint64_t *)0x14007d958, (uint64_t *)0x14007df70, (uint64_t *)0x14007d410, (uint64_t *)0x14007d7c8, (uint64_t *)0x14007d470, (uint64_t *)0x14007dc20, (uint64_t *)0x14007e330, (uint64_t *)0x14007d4f0, (uint64_t *)0x14007e250, (uint64_t *)0x14007d3b8, (uint64_t *)0x14007d8f0, (uint64_t *)0x14007dcc0, (uint64_t *)0x14007d708, (uint64_t *)0x14007d330, (uint64_t *)0x14007df90, (uint64_t *)0x14007e318, (uint64_t *)0x14007da00, (uint64_t *)0x14007dd30, (uint64_t *)0x14007d630, }},
{(uint64_t *)0x140050320, (uint64_t *)0x14007bda8, (uint64_t *)0x14007bf50, (uint64_t *)0x140076c40, {(uint64_t *)0x14007e248, (uint64_t *)0x14007e360, (uint64_t *)0x14007df30, (uint64_t *)0x14007e1e8, (uint64_t *)0x14007dbf8, (uint64_t *)0x14007d9e8, (uint64_t *)0x14007e328, (uint64_t *)0x14007d6f8, (uint64_t *)0x14007e1c8, (uint64_t *)0x14007d448, (uint64_t *)0x14007d6d8, (uint64_t *)0x14007d980, (uint64_t *)0x14007d4a0, (uint64_t *)0x14007ddd0, (uint64_t *)0x14007dce8, (uint64_t *)0x14007e2f8, (uint64_t *)0x14007dc50, (uint64_t *)0x14007d290, (uint64_t *)0x14007e1f8, (uint64_t *)0x14007dca0, (uint64_t *)0x14007d578, (uint64_t *)0x14007d8c8, (uint64_t *)0x14007de30, (uint64_t *)0x14007d1f8, }},
{(uint64_t *)0x140051d20, (uint64_t *)0x14007be60, (uint64_t *)0x14007bf60, (uint64_t *)0x140076c50, {(uint64_t *)0x14007e300, (uint64_t *)0x14007d3d0, (uint64_t *)0x14007e078, (uint64_t *)0x14007d320, (uint64_t *)0x14007e118, (uint64_t *)0x14007d9a8, (uint64_t *)0x14007d6e0, (uint64_t *)0x14007d558, (uint64_t *)0x14007d438, (uint64_t *)0x14007d800, (uint64_t *)0x14007d318, (uint64_t *)0x14007d990, (uint64_t *)0x14007d9b0, (uint64_t *)0x14007df80, (uint64_t *)0x14007dd10, (uint64_t *)0x14007d3a8, (uint64_t *)0x14007de08, (uint64_t *)0x14007e028, (uint64_t *)0x14007e228, (uint64_t *)0x14007d5c0, (uint64_t *)0x14007d6b8, (uint64_t *)0x14007d2f0, (uint64_t *)0x14007e0e0, (uint64_t *)0x14007db40, }},
};

uint8_t bits1[576];
uint8_t bits2[576];

int main()
{
int fd = open("dump.bin", O_RDWR);
if (fd == -1) {
perror("Error opening file");
return 1;
}
void *dump = mmap(NULL, DUMP_SIZE, PROT_READ, MAP_SHARED, fd, 0);
if (dump == NULL) {
perror("mmap");
close(fd);
return EXIT_FAILURE;
}
void *mem = mmap((void *)0x140001000, DUMP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_SHARED, 0, 0);
if (mem == MAP_FAILED) {
perror("mmap");
close(fd);
return EXIT_FAILURE;
}
memcpy(mem, dump, DUMP_SIZE);


for (int k = 0; k < 0x1000000; k++) {
for (int i = 0; i < 48; i++) {
for (int j = 0; j < 24; j++) {
*(crack[i].bits[j]) = (k >> j) & 1;
}
void (*func)() = (void (*)())crack[i].func;
// 字节码里面会操作栈,预留空间
char stack_buf[16];
func();
if (*(crack[i].out) == *(crack[i].ans)) {
printf("i=%d k=0x%x\n", i, k);
crack[i].right = k;
}
}
memcpy(mem+DATA_OFF, dump+DATA_OFF, DATA_SIZE);
}

// 输出结果
uint64_t *bit = (uint64_t *)0x14007D190;
for (int i = 0; i < 24; i++) {
for (int j = 0; j < 24; j++) {
int idx = (int)(crack[i].bits[j] - bit);
bits1[idx] = (crack[i].right >> j) & 1;
}
}

for (int i = 24; i < 48; i++) {
for (int j = 0; j < 24; j++) {
int idx = (int)(crack[i].bits[j] - bit);
bits2[idx] = (crack[i].right >> j) & 1;
}
}

for (int i = 0; i < 576; i++) {
if (bits1[i] != bits2[i]) {
printf("i=%d, unmatch\n", i);
}
}

for (int i = 0; i < 144; i++) {
int k = 0;
for (int j = 0; j < 4; j++) {
k = k | (bits1[i*4+j] << j);
}
printf("%x", k);
}
printf("\n");

for (int i = 0; i < 144; i++) {
int k = 0;
for (int j = 0; j < 4; j++) {
k = k | (bits2[i*4+j] << j);
}
printf("%x", k);
}
printf("\n");

close(fd);
return 0;
}

爆破结果

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
i=3 k=0x2e0f
i=21 k=0x1683e
i=10 k=0xd0ea1
i=1 k=0x11805e
i=25 k=0x1f3d9b
i=42 k=0x20b49b
i=29 k=0x225dd0
i=18 k=0x2fddd6
i=2 k=0x333ec9
i=20 k=0x34f4ee
i=17 k=0x39fbcc
i=47 k=0x3cd88f
i=12 k=0x407bee
i=13 k=0x42c8e8
i=4 k=0x4dd89f
i=32 k=0x50e0dd
i=37 k=0x55b1d1
i=22 k=0x5fbcef
i=43 k=0x64ff17
i=33 k=0x6c7e6c
i=41 k=0x6cdf28
i=28 k=0x6cf341
i=30 k=0x7345c4
i=31 k=0x836df1
i=44 k=0x890cbd
i=26 k=0x92b1fd
i=34 k=0x94ef4f
i=35 k=0x95d984
i=19 k=0x9a811e
i=7 k=0x9d0f5d
i=39 k=0xa684f0
i=45 k=0xa7dc9e
i=27 k=0xabe47f
i=5 k=0xb2d0f7
i=46 k=0xb5dd0d
i=8 k=0xb83ca8
i=24 k=0xbad644
i=6 k=0xbb5368
i=14 k=0xbe967a
i=11 k=0xc08f74
i=9 k=0xc6afa1
i=15 k=0xd2ff70
i=38 k=0xd44593
i=40 k=0xd58f45
i=0 k=0xe5d2b6
i=23 k=0xee67a1
i=16 k=0xf1dbdb
i=36 k=0xf98f6e
8e4f26f2e5575b32d7ba7430f7ef6ef206c499f58eac4c2fb40b404afbd7c95d1554576bb240d8f0957c59f51cb1d23ffee33cdbceb93b82a66076cfef2c43562cd7f90116675508
8e4f26f2e5575b32d7ba7430f7ef6ef206c499f58eac4c2fb40b404afbd7c95d1554576bb240d8f0957c59f51cb1d23ffee33cdbceb93b82a66076cfef2c43562cd7f90116675508

Context

题目分析

同样是多线程题目,但是CPP,反编译一坨

先根据程序运行打印的input找到main函数

要求输入长度16

中间是一堆看不懂的神秘操作

等待一个全局变量不为0

交叉引用找一下done在哪被修改,能找到done的修改位置,但是分析不出该函数是如何被调用的,先放一边继续往下看

结尾是校验

那么可以确定中间会有将输入进行加密的部分,input是全局变量,交叉引用找input在哪被使用,除了main以外还有三个函数,断点跑一下

通过断点可以确认是sub_67EBB0

在调试的适合发现程序创建了大量线程

分析一下sub_67EBB0

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
int __usercall sub_6C3010@<eax>(int a1@<ebx>, int a2@<edi>, int a3@<esi>, __int128 a4, int a5)
{
_BYTE *v5; // edi
_BYTE *v6; // esi
int i; // ecx
int v8; // ebx
int v9; // ecx
_BYTE *v10; // edi
_BYTE *v11; // esi
int j; // ecx
int v13; // ebp
int v15[32]; // [esp-8h] [ebp-90h]
_BYTE v16[16]; // [esp+78h] [ebp-10h] BYREF
int savedregs; // [esp+88h] [ebp+0h] BYREF

dword_915190 = (int)&savedregs;
dword_915194 = a1;
dword_915198 = a3;
dword_91519C = a2;
v5 = &v16[15];
v6 = &unk_915173;
for ( i = dword_914C70; i; --i )
*v5-- = *v6--;
v8 = r_ebx;
qmemcpy(v16, &a4, sizeof(v16));
v15[26] = -697354140;
v15[27] = 132995405;
/*......*/
HIBYTE(v15[-15]) = 74;
v15[-114] = v15[18] ^ v15[22];
v15[-113] = v15[19] ^ v15[23];
v15[-112] = v15[20] ^ v15[24];
v9 = v15[21] ^ v15[25];
v15[-111] = v15[21] ^ v15[25];
v15[-115] = 0;
r_eax = 12;
r_ebx = v8;
r_ecx = v9;
r_edx = 4;
r_esi = (int)&a5;
r_edi = (int)&savedregs;
v10 = &unk_915173;
v11 = &v16[15];
for ( j = dword_914C70; j; --j )
*v10-- = *v11--;
v13 = dword_915190;
*(_DWORD *)(dword_915190 - 116) = 3;
v15[1] = v13 - 116;
*(_DWORD *)(v13 - 120) = sub_56C951(v13 - 112);
*(_DWORD *)(v13 - 124) = *(_DWORD *)(v13 - 120);
*(_DWORD *)(v13 - 4) = 0;
sub_56E459(v15[1]);
*(_DWORD *)(v13 - 4) = -1;
return sub_56737F((void *)(v13 - 112));
}

反编译看起来比较奇怪,分析一下汇编代码

首先是保存寄存器和堆栈

接下来从全局变量加载寄存器

中间一堆神秘代码,神秘代码跑完将寄存器写回全局变量,并将保持的寄存器和堆栈恢复

末尾神秘代码

在前面看done这个全局变量的适合也有一个奇怪的函数,分析发现其结构和这里的结构类似,都是先保存寄存器和堆栈,从全局变量加载寄存器,执行一段汇编指令,将寄存器写回全局变量,恢复寄存器和堆栈,末尾神秘代码

中间的指令,这里进行比较,并保存eflags寄存器

发现末尾取保存的eflags寄存器数据进行了与运算并jnz跳转

eflags & 0x80 SF eflags & 0x800 OF

这里检查SF和CF标志位,结合前面的cmp指令,可以知道这里实际上是js跳转,小于比较

当cmp比较结果是小于时,进入和input处相似的结尾,否则done = 1

程序中存在大量与上述结构相似的函数,猜测每个函数单独被一个线程执行,每个线程的核心部分在 从全局变量恢复寄存器后 到 保存寄存器到全局变量 之间,如下

每个函数末尾存在相似的函数调用,这部分与eflags寄存器相关,猜测这部分函数调用与分支、跳转逻辑相关,分析发现,这部分结构中只有一个参数有较大区别,例如下图的94 97,该参数可能与跳转逻辑相关

交叉引用相关函数,发现如下switch case结构

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
int __thiscall sub_679620(void *this, int a2)
{
v2 = alloca(4924);
v224 = this;
switch ( a2 )
{
case 1:
v222 = 1;
sub_56C951((int)v223);
v225 = 0;
sub_56E459((int)&v222);
v225 = -1;
sub_56737F(v223);
break;
case 2:
v220 = 2;
sub_56C951((int)v221);
v225 = 1;
sub_56E459((int)&v220);
v225 = -1;
sub_56737F(v221);
break;
case 3:
/* ...... */
case 110:
v4 = 110;
sub_56C951((int)v5);
v225 = 109;
sub_56E459((int)&v4);
v225 = -1;
sub_56737F(v5);
break;
default:
cout(&unk_915C90, "something error");
sub_56FEA3((int)sub_5675E6);
break;
}
return a2;
}

大胆猜一波,这个值指定各个线程的调用顺序

解题思路

进行断点跟踪,首先需要获取到每次调用时的值,选择在sub_56E459函数内下断点

1
2
3
4
5
6
7
# 0x620E1A
import idc
import ida_dbg

ecx = ida_dbg.get_reg_val("ecx")

print("[TRACE] next =", hex(ecx))

其次需要在每个线程函数内断下,追踪线程函数的调用,由于函数较多,这里可以选择内存断点,对保存寄存器的全局变量下断点,例如r_eax

1
2
3
4
5
6
7
8
# 0x915174
import idc
import ida_dbg

rip = ida_dbg.get_reg_val("eip")
func=idc.get_func_attr(rip, FUNCATTR_START)

print("[TRACE] func =", hex(func))

利用IDAPython的断点脚本读取相关数据进行跟踪

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
[TRACE] next = 0x2
[TRACE] next = 0x2
[TRACE] func = 0x6c4ec0
[TRACE] func = 0x6c4ec0
[TRACE] next = 0x3
[TRACE] next = 0x3
[TRACE] func = 0x6c6190
[TRACE] func = 0x6c6190
[TRACE] func = 0x6c6190
[TRACE] func = 0x6c6190
[TRACE] next = 0x4
[TRACE] next = 0x4
[TRACE] func = 0x6c7650
[TRACE] func = 0x6c7650
[TRACE] func = 0x6c7650
[TRACE] func = 0x6c7650
[TRACE] next = 0x6
[TRACE] next = 0x6
[TRACE] func = 0x6c9e00
[TRACE] func = 0x6c9e00
[TRACE] func = 0x6c9e00
[TRACE] func = 0x6c9e00
[TRACE] next = 0x8
[TRACE] next = 0x8
[TRACE] func = 0x6cc550
[TRACE] func = 0x6cc550
[TRACE] func = 0x6cc550
[TRACE] func = 0x6cc550
[TRACE] next = 0xa
[TRACE] next = 0xa
[TRACE] func = 0x6c1bc0
[TRACE] func = 0x6c1bc0
[TRACE] func = 0x6c1bc0
[TRACE] func = 0x6c1bc0
[TRACE] next = 0xc
[TRACE] next = 0xc
[TRACE] func = 0x6c2210
[TRACE] func = 0x6c2210
[TRACE] func = 0x6c2210
[TRACE] func = 0x6c2210
[TRACE] next = 0xe
[TRACE] next = 0xe
[TRACE] func = 0x6c25c0
[TRACE] func = 0x6c25c0
[TRACE] func = 0x6c25c0
[TRACE] func = 0x6c25c0
[TRACE] next = 0x10
[TRACE] next = 0x10
[TRACE] func = 0x6c2960
[TRACE] func = 0x6c2960
[TRACE] next = 0x2
[TRACE] next = 0x2
[TRACE] func = 0x6c4ec0
[TRACE] func = 0x6c4ec0
[TRACE] next = 0x3
[TRACE] next = 0x3
[TRACE] func = 0x6c6190
[TRACE] func = 0x6c6190
[TRACE] func = 0x6c6190
[TRACE] func = 0x6c6190
[TRACE] next = 0x4
[TRACE] next = 0x4
[TRACE] func = 0x6c7650
[TRACE] func = 0x6c7650
[TRACE] func = 0x6c7650
[TRACE] func = 0x6c7650
[TRACE] next = 0x6
[TRACE] next = 0x6
[TRACE] func = 0x6c9e00
[TRACE] func = 0x6c9e00
[TRACE] func = 0x6c9e00
[TRACE] func = 0x6c9e00
[TRACE] next = 0x8
[TRACE] next = 0x8
[TRACE] func = 0x6cc550
[TRACE] func = 0x6cc550
[TRACE] func = 0x6cc550
[TRACE] func = 0x6cc550
[TRACE] next = 0xa
[TRACE] next = 0xa
[TRACE] func = 0x6c1bc0
[TRACE] func = 0x6c1bc0
[TRACE] func = 0x6c1bc0
[TRACE] func = 0x6c1bc0
[TRACE] next = 0xc
[TRACE] next = 0xc
[TRACE] func = 0x6c2210
[TRACE] func = 0x6c2210
[TRACE] func = 0x6c2210
[TRACE] func = 0x6c2210

追踪发现,相同的next值对应的线程函数相同

修改一下追踪脚本,每次修改next的值,得到完整的对应关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import idc
import ida_dbg

global start_trace
global next
global skip

if (start_trace == True):
ida_dbg.set_reg_val("ecx", next)
if (skip):
next += 1
skip = not skip

ecx = ida_dbg.get_reg_val("ecx")

print("[TRACE] next =", hex(ecx))
1
{0x1: 0x6c3010, 0x2: 0x6c4ec0, 0x3: 0x6c6190, 0x4: 0x6c7650, 0x5: 0x6c8a20, 0x6: 0x6c9e00, 0x7: 0x6cb1f0, 0x8: 0x6cc550, 0x9: 0x6cda90, 0xa: 0x6c1bc0, 0xb: 0x6c20a0, 0xc: 0x6c2210, 0xd: 0x6c2450, 0xe: 0x6c25c0, 0xf: 0x6c27f0, 0x10: 0x6c2960, 0x11: 0x6c2ae0, 0x12: 0x6c2c50, 0x13: 0x6c2dd0, 0x14: 0x6c3cc0, 0x15: 0x6c3e50, 0x16: 0x6c3fe0, 0x17: 0x6c4160, 0x18: 0x6c43a0, 0x19: 0x6c45d0, 0x1a: 0x6c4740, 0x1b: 0x6c48d0, 0x1c: 0x6c4a50, 0x1d: 0x6c4c90, 0x1e: 0x6c5040, 0x1f: 0x6c51b0, 0x20: 0x6c5330, 0x21: 0x6c5560, 0x22: 0x6c56d0, 0x23: 0x6c5860, 0x24: 0x6c59e0, 0x25: 0x6c5c20, 0x26: 0x6c5db0, 0x27: 0x6c5ff0, 0x28: 0x6c63d0, 0x29: 0x6c6620, 0x2a: 0x6c67b0, 0x2b: 0x6c6920, 0x2c: 0x6c6aa0, 0x2d: 0x6c6ce0, 0x2e: 0x6c6f10, 0x2f: 0x6c7080, 0x30: 0x6c72b0, 0x31: 0x6c74e0, 0x32: 0x6c7880, 0x33: 0x6c7a00, 0x34: 0x6c7c30, 0x35: 0x6c7da0, 0x36: 0x6c7fd0, 0x37: 0x6c8160, 0x38: 0x6c8390, 0x39: 0x6c8500, 0x3a: 0x6c8740, 0x3b: 0x6c88b0, 0x3c: 0x6c8b90, 0x3d: 0x6c8d20, 0x3e: 0x6c8ea0, 0x3f: 0x6c90e0, 0x40: 0x6c9310, 0x41: 0x6c9480, 0x42: 0x6c96b0, 0x43: 0x6c98e0, 0x44: 0x6c9a50, 0x45: 0x6c9bd0, 0x46: 0x6ca030, 0x47: 0x6ca1a0, 0x48: 0x6ca3d0, 0x49: 0x6ca560, 0x4a: 0x6ca790, 0x4b: 0x6ca900, 0x4c: 0x6cab40, 0x4d: 0x6cacb0, 0x4e: 0x6cae20, 0x4f: 0x6cb060, 0x50: 0x6cb360, 0x51: 0x6cb5a0, 0x52: 0x6cb730, 0x53: 0x6cb970, 0x54: 0x6cbb00, 0x55: 0x6cbd30, 0x56: 0x6cbea0, 0x57: 0x6cc0e0, 0x58: 0x6cc250, 0x59: 0x6cc3d0, 0x5a: 0x6cc790, 0x5b: 0x6cc9d0, 0x5c: 0x6ccc00, 0x5d: 0x6ccd70, 0x5e: 0x6ccfa0, 0x5f: 0x6cd1d0, 0x60: 0x6cd340, 0x61: 0x6cd4c0, 0x62: 0x6cd6f0, 0x63: 0x6cd860, 0x64: 0x6c0b50, 0x65: 0x6c0ce0, 0x66: 0x6c0f10, 0x67: 0x6c1080, 0x68: 0x6c12c0, 0x69: 0x6c1430, 0x6a: 0x6c15a0, 0x6b: 0x6c1710, 0x6c: 0x6c1880, 0x6d: 0x6c1a00, 0x6e: 0x6c1f10}

接下来提取每个线程函数的核心汇编代码,以及每个线程函数末尾的跳转next值,如果存在eflags则保留eflags相关操作

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

trace = {
0x1: 0x6c3010,
0x2: 0x6c4ec0,
0x3: 0x6c6190,
0x4: 0x6c7650,
0x5: 0x6c8a20,
0x6: 0x6c9e00,
0x7: 0x6cb1f0,
0x8: 0x6cc550,
0x9: 0x6cda90,
0xa: 0x6c1bc0,
0xb: 0x6c20a0,
0xc: 0x6c2210,
0xd: 0x6c2450,
0xe: 0x6c25c0,
0xf: 0x6c27f0,
0x10: 0x6c2960,
0x11: 0x6c2ae0,
0x12: 0x6c2c50,
0x13: 0x6c2dd0,
0x14: 0x6c3cc0,
0x15: 0x6c3e50,
0x16: 0x6c3fe0,
0x17: 0x6c4160,
0x18: 0x6c43a0,
0x19: 0x6c45d0,
0x1a: 0x6c4740,
0x1b: 0x6c48d0,
0x1c: 0x6c4a50,
0x1d: 0x6c4c90,
0x1e: 0x6c5040,
0x1f: 0x6c51b0,
0x20: 0x6c5330,
0x21: 0x6c5560,
0x22: 0x6c56d0,
0x23: 0x6c5860,
0x24: 0x6c59e0,
0x25: 0x6c5c20,
0x26: 0x6c5db0,
0x27: 0x6c5ff0,
0x28: 0x6c63d0,
0x29: 0x6c6620,
0x2a: 0x6c67b0,
0x2b: 0x6c6920,
0x2c: 0x6c6aa0,
0x2d: 0x6c6ce0,
0x2e: 0x6c6f10,
0x2f: 0x6c7080,
0x30: 0x6c72b0,
0x31: 0x6c74e0,
0x32: 0x6c7880,
0x33: 0x6c7a00,
0x34: 0x6c7c30,
0x35: 0x6c7da0,
0x36: 0x6c7fd0,
0x37: 0x6c8160,
0x38: 0x6c8390,
0x39: 0x6c8500,
0x3a: 0x6c8740,
0x3b: 0x6c88b0,
0x3c: 0x6c8b90,
0x3d: 0x6c8d20,
0x3e: 0x6c8ea0,
0x3f: 0x6c90e0,
0x40: 0x6c9310,
0x41: 0x6c9480,
0x42: 0x6c96b0,
0x43: 0x6c98e0,
0x44: 0x6c9a50,
0x45: 0x6c9bd0,
0x46: 0x6ca030,
0x47: 0x6ca1a0,
0x48: 0x6ca3d0,
0x49: 0x6ca560,
0x4a: 0x6ca790,
0x4b: 0x6ca900,
0x4c: 0x6cab40,
0x4d: 0x6cacb0,
0x4e: 0x6cae20,
0x4f: 0x6cb060,
0x50: 0x6cb360,
0x51: 0x6cb5a0,
0x52: 0x6cb730,
0x53: 0x6cb970,
0x54: 0x6cbb00,
0x55: 0x6cbd30,
0x56: 0x6cbea0,
0x57: 0x6cc0e0,
0x58: 0x6cc250,
0x59: 0x6cc3d0,
0x5a: 0x6cc790,
0x5b: 0x6cc9d0,
0x5c: 0x6ccc00,
0x5d: 0x6ccd70,
0x5e: 0x6ccfa0,
0x5f: 0x6cd1d0,
0x60: 0x6cd340,
0x61: 0x6cd4c0,
0x62: 0x6cd6f0,
0x63: 0x6cd860,
0x64: 0x6c0b50,
0x65: 0x6c0ce0,
0x66: 0x6c0f10,
0x67: 0x6c1080,
0x68: 0x6c12c0,
0x69: 0x6c1430,
0x6a: 0x6c15a0,
0x6b: 0x6c1710,
0x6c: 0x6c1880,
0x6d: 0x6c1a00,
0x6e: 0x6c1f10
}

blocks = {}

for idx in trace:
codes = [f".block_{idx}:"]
ea = trace[idx]
real_code = False
next = 0
jmp_k = 0

while (True):
ins_len = idc.create_insn(ea)
ins = idc.generate_disasm_line(ea, 0).split(";")[0]
if (ins == "mov eax, r_eax"):
real_code = True
# eflags条件跳转
if (ins == "mov eax, r_eflags"):
real_code = True
if (ins.startswith("jnz")):
real_code = False
codes.append(f" jnz .jmp_{idx}_1")
if (ins.startswith("jz")):
real_code = False
codes.append(f" jz .jmp_{idx}_1")
if (real_code):
codes.append(f" {ins}")
if (ins == "mov r_edi, edi"):
real_code = False
# 根据jmp_ctx定位跳转
if (ins.startswith("mov dword ptr [")):
next = idc.get_operand_value(ea, 1)
if (ins == "mov ecx, offset jmp_ctx"):
codes.append(f".jmp_{idx}_{jmp_k}:")
codes.append(f" jmp .block_{next}")
jmp_k += 1
if (ins == "retn"):
break
ea += ins_len
blocks[idx] = codes

for idx in blocks:
for line in blocks[idx]:
print(line)
print("")

dump得到汇编代码,安装nasm格式进行优化 dump.s

编译为二进制后IDA分析

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
int start(int a1, int a2, int a3, int a4, int a5, int a6, int arg18, int a8, int a7, int a10, ...)
{
int mm; // [esp+160h] [ebp-2A0h]
int kk; // [esp+168h] [ebp-298h]
int jj; // [esp+174h] [ebp-28Ch]
int ii; // [esp+17Ch] [ebp-284h]
unsigned int v15; // [esp+180h] [ebp-280h]
int n; // [esp+184h] [ebp-27Ch]
int m; // [esp+188h] [ebp-278h]
int v18; // [esp+18Ch] [ebp-274h]
int v19; // [esp+18Ch] [ebp-274h]
int k; // [esp+190h] [ebp-270h]
unsigned int sum; // [esp+198h] [ebp-268h]
int j; // [esp+19Ch] [ebp-264h]
int _flag[4]; // [esp+1A0h] [ebp-260h]
unsigned int v24; // [esp+1B0h] [ebp-250h]
unsigned int v25; // [esp+1B4h] [ebp-24Ch]
int v26; // [esp+1B8h] [ebp-248h]
int i; // [esp+1BCh] [ebp-244h]
int v28[4]; // [esp+1C0h] [ebp-240h]
int v29[32]; // [esp+1D0h] [ebp-230h]
char v30[17]; // [esp+250h] [ebp-1B0h]
char v31[239]; // [esp+261h] [ebp-19Fh] BYREF
int v32[40]; // [esp+350h] [ebp-B0h]
int v33[4]; // [esp+3F0h] [ebp-10h]

qmemcpy(&a1, &arg18, 0x10u);
v33[0] = 0xD66F3864;
v33[1] = 0x7ED594D;
v33[2] = 0x621C3F18;
v33[3] = 0xBED317E1;
v32[36] = -839856591;
v32[37] = 1675847684;
v32[38] = 1058947066;
v32[39] = -269673768;
v32[32] = 1913540885;
v32[33] = -1208335669;
v32[34] = -889076480;
v32[35] = -1740231050;
v32[0] = -848645950;
v32[1] = -2003529398;
v32[2] = -1676540991;
v32[3] = -1188115689;
v32[4] = 58027675;
v32[5] = 359557627;
v32[6] = 587892347;
v32[7] = -748623069;
v32[8] = 2003140489;
v32[9] = 895831202;
v32[10] = -461923967;
v32[11] = 2053312768;
v32[12] = -564349677;
v32[13] = -152839449;
v32[14] = -1327420049;
v32[15] = -1559499318;
v32[16] = 1200009394;
v32[17] = -474018770;
v32[18] = 1342215497;
v32[19] = -388850652;
v32[20] = -269286563;
v32[21] = 203751933;
v32[22] = 388657421;
v32[23] = 582034955;
v32[24] = 977641849;
v32[25] = -815040561;
v32[26] = -1959785576;
v32[27] = -1268424022;
v32[28] = 709356384;
v32[29] = 1428218464;
v32[30] = -2142320863;
v32[31] = -370784307;
v30[0] = -55;
v30[1] = 111;
v30[2] = -11;
v30[3] = 29;
v30[4] = -34;
v30[5] = -9;
v30[6] = 85;
v30[7] = -93;
v30[8] = 98;
v30[9] = 118;
v30[10] = -83;
v30[11] = -40;
v30[12] = -44;
v30[13] = -112;
v30[14] = 87;
v30[15] = -63;
v30[16] = 12;
qmemcpy(v31, "KC", 2);
v31[2] = 127;
v31[3] = 54;
v31[4] = 21;
v31[5] = -32;
v31[6] = -88;
v31[7] = 44;
v31[8] = -59;
v31[9] = -18;
v31[10] = 43;
v31[11] = -92;
v31[12] = -122;
v31[13] = -18;
v31[14] = -113;
v31[15] = -67;
v31[16] = 123;
v31[17] = -20;
v31[18] = -121;
v31[19] = -17;
v31[20] = -17;
v31[21] = -110;
v31[22] = 84;
v31[23] = 57;
v31[24] = 98;
v31[25] = 74;
v31[26] = 117;
v31[27] = -103;
v31[28] = 64;
v31[29] = 80;
v31[30] = 78;
v31[31] = -34;
v31[32] = -125;
v31[33] = 1;
v31[34] = 104;
v31[35] = 8;
v31[36] = 19;
v31[37] = 61;
v31[38] = -125;
v31[39] = 0;
v31[40] = 18;
v31[41] = 72;
v31[42] = 114;
v31[43] = 52;
v31[44] = -116;
v31[45] = 60;
v31[46] = -109;
v31[47] = -47;
v31[48] = -49;
v31[49] = 104;
v31[50] = 32;
v31[51] = 10;
v31[52] = 10;
v31[53] = -68;
v31[54] = -68;
v31[55] = 29;
v31[56] = 59;
v31[57] = -79;
v31[58] = 88;
v31[59] = 5;
v31[60] = -95;
v31[61] = 16;
v31[62] = 46;
v31[63] = -117;
v31[64] = 57;
v31[65] = -52;
v31[66] = 94;
v31[67] = -58;
v31[68] = 12;
v31[69] = -2;
v31[70] = -28;
v31[71] = -22;
v31[72] = -51;
v31[73] = -30;
v31[74] = -49;
v31[75] = 18;
v31[76] = 85;
v31[77] = -34;
v31[78] = -125;
v31[79] = -54;
v31[80] = -64;
v31[81] = -51;
v31[82] = 92;
v31[83] = -117;
v31[84] = -14;
v31[85] = 112;
v31[86] = 98;
v31[87] = -75;
v31[88] = -119;
v31[89] = -23;
v31[90] = 49;
v31[91] = -7;
v31[92] = 3;
v31[93] = 19;
v31[94] = 47;
v31[95] = -121;
v31[96] = 1;
v31[97] = -70;
v31[98] = -3;
v31[99] = 63;
v31[100] = 88;
v31[101] = 63;
v31[102] = 94;
v31[103] = -86;
v31[104] = -27;
v31[105] = 58;
v31[106] = 76;
v31[107] = -50;
v31[108] = 113;
v31[109] = 75;
v31[110] = 71;
v31[111] = -92;
v31[112] = -95;
v31[113] = 126;
v31[114] = -50;
v31[115] = 73;
v31[116] = 21;
v31[117] = -68;
v31[118] = -40;
v31[119] = -62;
v31[120] = -12;
v31[121] = 64;
v31[122] = 60;
v31[123] = -114;
v31[124] = -87;
v31[125] = -91;
v31[126] = -102;
v31[127] = -7;
v31[128] = 126;
v31[129] = 75;
v31[130] = -54;
v31[131] = -54;
v31[132] = 72;
v31[133] = -49;
v31[134] = -83;
v31[135] = 74;
v31[136] = -72;
v31[137] = 40;
v31[138] = 10;
v31[139] = -21;
v31[140] = -13;
v31[141] = -6;
v31[142] = -120;
v31[143] = 116;
v31[144] = 23;
v31[145] = -8;
v31[146] = -74;
v31[147] = 75;
v31[148] = -122;
v31[149] = -73;
v31[150] = -35;
v31[151] = 100;
v31[152] = -94;
v31[153] = -5;
v31[154] = -25;
v31[155] = 31;
v31[156] = 116;
v31[157] = -117;
v31[158] = -10;
v31[159] = 98;
v31[160] = -104;
v31[161] = 21;
v31[162] = 74;
v31[163] = 102;
v31[164] = 28;
v31[165] = -88;
v31[166] = -30;
v31[167] = 110;
v31[168] = 71;
v31[169] = 51;
v31[170] = -118;
v31[171] = 93;
v31[172] = 59;
v31[173] = -115;
v31[174] = 70;
v31[175] = 68;
v31[176] = 40;
v31[177] = -3;
v31[178] = -67;
v31[179] = -98;
v31[180] = 52;
v31[181] = 109;
v31[182] = -92;
v31[183] = -39;
v31[184] = -121;
v31[185] = 99;
v31[186] = -88;
v31[187] = 110;
v31[188] = -54;
v31[189] = -50;
v31[190] = 61;
v31[191] = -97;
v31[192] = -73;
v31[193] = -60;
v31[194] = -56;
v31[195] = 55;
v31[196] = 21;
v31[197] = 81;
v31[198] = -107;
v31[199] = -80;
v31[200] = 67;
v31[201] = 33;
v31[202] = 50;
v31[203] = -83;
v31[204] = -26;
v31[205] = -29;
v31[206] = 112;
v31[207] = -75;
v31[208] = 65;
v31[209] = -23;
v31[210] = 100;
v31[211] = -74;
v31[212] = 37;
v31[213] = 27;
v31[214] = -29;
v31[215] = 29;
v31[216] = -46;
v31[217] = 44;
v31[218] = 74;
v31[219] = 12;
v31[220] = 15;
v31[221] = 15;
v31[222] = -44;
v31[223] = -13;
v31[224] = 73;
v31[225] = -28;
v31[226] = 15;
v31[227] = 19;
v31[228] = -119;
v31[229] = 110;
v31[230] = -107;
v31[231] = 103;
v31[232] = 27;
v31[233] = 42;
v31[234] = 52;
v31[235] = 27;
v31[236] = 81;
v31[237] = -121;
v31[238] = 74;
v28[0] = -1073832156;
v28[1] = -736548145;
v28[2] = -199230726;
v28[3] = 2007708846;
for ( i = 0; i < 32; ++i )
{
v26 = v32[i] ^ v28[((_BYTE)i + 2) & 3] ^ v28[((_BYTE)i + 1) & 3] ^ v28[((_BYTE)i + 3) & 3];
v25 = (unsigned __int8)v30[HIBYTE(v26)] | ((unsigned __int8)v30[BYTE2(v26)] << 8) | ((unsigned __int8)v30[BYTE1(v26)] << 16) | ((unsigned __int8)v30[(unsigned __int8)v26] << 24);
v24 = ((v25 >> 8) | (v25 << 24)) ^ ((v25 >> 14) | (v25 << 18)) ^ ((v25 >> 22) | (v25 << 10)) ^ v25 ^ ((v25 >> 30) | (4 * v25));
v28[((_BYTE)i + 4) & 3] ^= v24;
v29[i] = v28[((_BYTE)i + 4) & 3];
}
for ( j = 0; j < 4; ++j )
_flag[j] = *(_DWORD *)(a1 + 4 * j);
sum = 0;
for ( k = 0; k < 32; ++k )
{
v18 = _flag[((_BYTE)k + 1) & 3];
for ( m = 0; m < 1; ++m )
v18 ^= _flag[((_BYTE)k + 2) & 3];
v19 = _flag[((_BYTE)k + 3) & 3] ^ v18;
for ( n = 0; n < 1; ++n )
v19 ^= v29[k];
v15 = ((unsigned __int8)v30[(unsigned __int8)v19] << 24) | ((unsigned __int8)v30[BYTE1(v19)] << 16) | ((unsigned __int8)v30[BYTE2(v19)] << 8) | (unsigned __int8)v30[HIBYTE(v19)];
for ( ii = 0; ii < 2; ++ii )
_flag[((_BYTE)k + 3) & 3] += (_flag[((_BYTE)k + 1) & 3]
+ ((16 * _flag[((_BYTE)k + 1) & 3]) ^ ((unsigned int)_flag[((_BYTE)k + 1) & 3] >> 5))) ^ (v33[sum & 3] + sum);
sum -= 0x4E75314C;
for ( jj = 0; jj < 4; ++jj )
_flag[((_BYTE)k + 1) & 3] += (_flag[((_BYTE)k + 2) & 3]
+ ((16 * _flag[((_BYTE)k + 2) & 3]) ^ ((unsigned int)_flag[((_BYTE)k + 2) & 3] >> 5))) ^ (v33[(sum >> 11) & 3] + sum);
_flag[((_BYTE)k + 4) & 3] ^= v15 ^ ((v15 >> 30) | (4 * v15)) ^ ((v15 >> 22) | (v15 << 10)) ^ ((v15 >> 14) | (v15 << 18)) ^ ((v15 >> 8) | (v15 << 24)) ^ ((v15 >> 30) | (4 * v15)) ^ ((v15 >> 9) | (v15 << 23));
for ( kk = 0; kk < 3; ++kk )
_flag[((_BYTE)k + 2) & 3] -= (_flag[((_BYTE)k + 3) & 3]
+ ((16 * _flag[((_BYTE)k + 3) & 3]) ^ ((unsigned int)_flag[((_BYTE)k + 3) & 3] >> 5))) ^ (v33[(sum >> 22) & 3] + sum);
}
for ( mm = 0; mm < 4; ++mm )
*(_DWORD *)(a1 + 4 * mm) = _flag[mm];
return 0;
}

tea魔改,抄一遍再求解

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
#!/usr/bin/env python3

flag = [0x31313131, 0x31313131, 0x31313131, 0x31313131]

key = [0xD66F3864, 0x7ED594D, 0x621C3F18, 0xBED317E1]

v55 = [0xe7dcf926, 0x6a2ed836, 0x3c99fd8d, 0xde4334ed, 0xa238417f, 0x37d5c459, 0x428e4421, 0xdc2d2c0, 0x82927eae, 0x650a8d3b, 0x4733ea0e, 0xe0c1a01e, 0xe37f333a, 0x4b51998, 0x896a001c, 0xe77eaa76, 0x12946c1c, 0xfdf2d87, 0x77e4d718, 0x42853e41, 0xe5bf8057, 0x95d7f440, 0x33bf101b, 0xce2e6adf, 0x72ded0ca, 0xeb79a502, 0xab62a1f6, 0xe1ccbd6f, 0x7e01221f, 0x83129780, 0x25486be4, 0x66dc7c9b]
v56 = [ 0xC9, 0x6F, 0xF5, 0x1D, 0xDE, 0xF7, 0x55, 0xA3, 0x62, 0x76,
0xAD, 0xD8, 0xD4, 0x90, 0x57, 0xC1, 0x0C, 0x4B, 0x43, 0x7F,
0x36, 0x15, 0xE0, 0xA8, 0x2C, 0xC5, 0xEE, 0x2B, 0xA4, 0x86,
0xEE, 0x8F, 0xBD, 0x7B, 0xEC, 0x87, 0xEF, 0xEF, 0x92, 0x54,
0x39, 0x62, 0x4A, 0x75, 0x99, 0x40, 0x50, 0x4E, 0xDE, 0x83,
0x01, 0x68, 0x08, 0x13, 0x3D, 0x83, 0x00, 0x12, 0x48, 0x72,
0x34, 0x8C, 0x3C, 0x93, 0xD1, 0xCF, 0x68, 0x20, 0x0A, 0x0A,
0xBC, 0xBC, 0x1D, 0x3B, 0xB1, 0x58, 0x05, 0xA1, 0x10, 0x2E,
0x8B, 0x39, 0xCC, 0x5E, 0xC6, 0x0C, 0xFE, 0xE4, 0xEA, 0xCD,
0xE2, 0xCF, 0x12, 0x55, 0xDE, 0x83, 0xCA, 0xC0, 0xCD, 0x5C,
0x8B, 0xF2, 0x70, 0x62, 0xB5, 0x89, 0xE9, 0x31, 0xF9, 0x03,
0x13, 0x2F, 0x87, 0x01, 0xBA, 0xFD, 0x3F, 0x58, 0x3F, 0x5E,
0xAA, 0xE5, 0x3A, 0x4C, 0xCE, 0x71, 0x4B, 0x47, 0xA4, 0xA1,
0x7E, 0xCE, 0x49, 0x15, 0xBC, 0xD8, 0xC2, 0xF4, 0x40, 0x3C,
0x8E, 0xA9, 0xA5, 0x9A, 0xF9, 0x7E, 0x4B, 0xCA, 0xCA, 0x48,
0xCF, 0xAD, 0x4A, 0xB8, 0x28, 0x0A, 0xEB, 0xF3, 0xFA, 0x88,
0x74, 0x17, 0xF8, 0xB6, 0x4B, 0x86, 0xB7, 0xDD, 0x64, 0xA2,
0xFB, 0xE7, 0x1F, 0x74, 0x8B, 0xF6, 0x62, 0x98, 0x15, 0x4A,
0x66, 0x1C, 0xA8, 0xE2, 0x6E, 0x47, 0x33, 0x8A, 0x5D, 0x3B,
0x8D, 0x46, 0x44, 0x28, 0xFD, 0xBD, 0x9E, 0x34, 0x6D, 0xA4,
0xD9, 0x87, 0x63, 0xA8, 0x6E, 0xCA, 0xCE, 0x3D, 0x9F, 0xB7,
0xC4, 0xC8, 0x37, 0x15, 0x51, 0x95, 0xB0, 0x43, 0x21, 0x32,
0xAD, 0xE6, 0xE3, 0x70, 0xB5, 0x41, 0xE9, 0x64, 0xB6, 0x25,
0x1B, 0xE3, 0x1D, 0xD2, 0x2C, 0x4A, 0x0C, 0x0F, 0x0F, 0xD4,
0xF3, 0x49, 0xE4, 0x0F, 0x13, 0x89, 0x6E, 0x95, 0x67, 0x1B,
0x2A, 0x34, 0x1B, 0x51, 0x87, 0x4A
]

print("enc:")
sums = 0
for k in range(32):
v48 = flag[(k+1)%4]
v48 ^= flag[(k+2)%4]
v49 = flag[(k+3)%4] ^ v48

v49 ^= v55[k]
v15 = (v56[v49&0xff] << 24) | (v56[(v49>>8)&0xff] << 16) | (v56[(v49>>16)&0xff] << 8) | v56[(v49>>24)&0xff]
v15 &= 0xffffffff

flag[(k+3)%4] += (flag[(k+1)%4] + ((flag[(k+1)%4] << 4) ^ (flag[(k+1)%4] >> 5))) ^ (key[sums&3] + sums)
flag[(k+3)%4] += (flag[(k+1)%4] + ((flag[(k+1)%4] << 4) ^ (flag[(k+1)%4] >> 5))) ^ (key[sums&3] + sums)
flag[(k+3)%4] = (0x100000000 + flag[(k+3)%4]) & 0xffffffff

print(hex(sums))
sums = (0x100000000 + sums - 0x4E75314C) & 0xffffffff

flag[(k+1)%4] += (flag[(k+2)%4] + ((flag[(k+2)%4] << 4) ^ (flag[(k+2)%4] >> 5))) ^ (key[(sums>>11)&3] + sums)
flag[(k+1)%4] += (flag[(k+2)%4] + ((flag[(k+2)%4] << 4) ^ (flag[(k+2)%4] >> 5))) ^ (key[(sums>>11)&3] + sums)
flag[(k+1)%4] += (flag[(k+2)%4] + ((flag[(k+2)%4] << 4) ^ (flag[(k+2)%4] >> 5))) ^ (key[(sums>>11)&3] + sums)
flag[(k+1)%4] += (flag[(k+2)%4] + ((flag[(k+2)%4] << 4) ^ (flag[(k+2)%4] >> 5))) ^ (key[(sums>>11)&3] + sums)
flag[(k+1)%4] = (0x100000000 + flag[(k+1)%4]) & 0xffffffff

flag[k%4] ^= v15 ^ ((v15 >> 30) | (4 * v15)) ^ ((v15 >> 22) | (v15 << 10)) ^ ((v15 >> 14) | (v15 << 18)) ^ ((v15 >> 8) | (v15 << 24)) ^ ((v15 >> 30) | (4 * v15)) ^ ((v15 >> 9) | (v15 << 23))
flag[k%4] = (0x100000000 + flag[k%4]) & 0xffffffff

flag[(k+2)%4] -= (flag[(k+3)%4] + ((flag[(k+3)%4] << 4) ^ (flag[(k+3)%4] >> 5))) ^ (key[(sums>>22)&3] + sums)
flag[(k+2)%4] -= (flag[(k+3)%4] + ((flag[(k+3)%4] << 4) ^ (flag[(k+3)%4] >> 5))) ^ (key[(sums>>22)&3] + sums)
flag[(k+2)%4] -= (flag[(k+3)%4] + ((flag[(k+3)%4] << 4) ^ (flag[(k+3)%4] >> 5))) ^ (key[(sums>>22)&3] + sums)
flag[(k+2)%4] = (0x100000000 + flag[(k+2)%4]) & 0xffffffff

# print(flag)

print("dec:")
# 解密
# flag = [326818289, 2180656741, 3545149769, 1263889461]
flag = [0x80EE17B9, 0x1145A56F, 0xCA2A5593, 0xBA486D1E]
sums = 0
for i in range(32):
sums = (0x100000000 + sums - 0x4E75314C) & 0xffffffff

for k in range(31, -1, -1):
flag[(k+2)%4] += (flag[(k+3)%4] + ((flag[(k+3)%4] << 4) ^ (flag[(k+3)%4] >> 5))) ^ (key[(sums>>22)&3] + sums)
flag[(k+2)%4] += (flag[(k+3)%4] + ((flag[(k+3)%4] << 4) ^ (flag[(k+3)%4] >> 5))) ^ (key[(sums>>22)&3] + sums)
flag[(k+2)%4] += (flag[(k+3)%4] + ((flag[(k+3)%4] << 4) ^ (flag[(k+3)%4] >> 5))) ^ (key[(sums>>22)&3] + sums)
flag[(k+2)%4] = (0x100000000 + flag[(k+2)%4]) & 0xffffffff

flag[(k+1)%4] -= (flag[(k+2)%4] + ((flag[(k+2)%4] << 4) ^ (flag[(k+2)%4] >> 5))) ^ (key[(sums>>11)&3] + sums)
flag[(k+1)%4] -= (flag[(k+2)%4] + ((flag[(k+2)%4] << 4) ^ (flag[(k+2)%4] >> 5))) ^ (key[(sums>>11)&3] + sums)
flag[(k+1)%4] -= (flag[(k+2)%4] + ((flag[(k+2)%4] << 4) ^ (flag[(k+2)%4] >> 5))) ^ (key[(sums>>11)&3] + sums)
flag[(k+1)%4] -= (flag[(k+2)%4] + ((flag[(k+2)%4] << 4) ^ (flag[(k+2)%4] >> 5))) ^ (key[(sums>>11)&3] + sums)
flag[(k+1)%4] = (0x100000000 + flag[(k+1)%4]) & 0xffffffff

sums = (sums + 0x4E75314C) & 0xffffffff

flag[(k+3)%4] -= (flag[(k+1)%4] + ((flag[(k+1)%4] << 4) ^ (flag[(k+1)%4] >> 5))) ^ (key[sums&3] + sums)
flag[(k+3)%4] -= (flag[(k+1)%4] + ((flag[(k+1)%4] << 4) ^ (flag[(k+1)%4] >> 5))) ^ (key[sums&3] + sums)
flag[(k+3)%4] = (0x100000000 + flag[(k+3)%4]) & 0xffffffff

v48 = flag[(k+1)%4]
v48 ^= flag[(k+2)%4]
v49 = flag[(k+3)%4] ^ v48

v49 ^= v55[k]
v15 = (v56[v49&0xff] << 24) | (v56[(v49>>8)&0xff] << 16) | (v56[(v49>>16)&0xff] << 8) | v56[(v49>>24)&0xff]
v15 &= 0xffffffff

flag[k%4] ^= v15 ^ ((v15 >> 30) | (4 * v15)) ^ ((v15 >> 22) | (v15 << 10)) ^ ((v15 >> 14) | (v15 << 18)) ^ ((v15 >> 8) | (v15 << 24)) ^ ((v15 >> 30) | (4 * v15)) ^ ((v15 >> 9) | (v15 << 23))
flag[k%4] = (0x100000000 + flag[k%4]) & 0xffffffff

for k in flag:
print(k.to_bytes(4, byteorder='little').decode(), end='')


N1CTF2024-RE
https://blog.noxke.fun/2024/11/10/ctf_wp/N1CTF2024-RE/
作者
noxke
发布于
2024年11月10日
许可协议