# Another Android Applaketion

下载附件发现是 apk 文件,拖入 jadx 打开,然后找到 MainActivity:

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
package com.lake.ctf;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

/* loaded from: classes.dex */
public class MainActivity extends AppCompatActivity {
long wow = 0;

public native long Init();

public native boolean Test(String str);

static {
System.loadLibrary("ohgreat2");
}

@Override // android.support.v7.app.AppCompatActivity, android.support.v4.app.FragmentActivity, android.support.v4.app.SupportActivity, android.app.Activity
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
this.wow = Init();
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(1);
final TextView textView = new TextView(this);
textView.setText("this UI follows swiss style");
final EditText editText = new EditText(this);
editText.setHint("Enter flag:");
Button button = new Button(this);
button.setText("Check flag");
button.setOnClickListener(new View.OnClickListener() { // from class: com.lake.ctf.MainActivity$$ExternalSyntheticLambda0
@Override // android.view.View.OnClickListener
public final void onClick(View view) {
this.f$0.m4lambda$onCreate$0$comlakectfMainActivity(editText, textView, view);
}
});
linearLayout.addView(editText);
linearLayout.addView(button);
linearLayout.addView(textView);
setContentView(linearLayout);
}

/* renamed from: lambda$onCreate$0$com-lake-ctf-MainActivity, reason: not valid java name */
/* synthetic */ void m4lambda$onCreate$0$comlakectfMainActivity(EditText editText, TextView textView, View view) {
String string = editText.getText().toString();
Log.i("LAKECTF", "flag: " + string);
if (string.length() != 55) {
textView.setText("flag is wrong...");
return;
}
boolean zTest = Test(string);
boolean zTest2 = Test(string);
boolean zTest3 = Test(string);
boolean zTest4 = Test(string);
boolean zTest5 = Test(string);
boolean zTest6 = Test(string);
boolean zTest7 = Test(string);
boolean zTest8 = Test(string);
boolean zTest9 = Test(string);
boolean zTest10 = Test(string);
boolean zTest11 = Test(string);
boolean zTest12 = Test(string);
boolean zTest13 = Test(string);
boolean zTest14 = Test(string);
boolean zTest15 = Test(string);
boolean zTest16 = Test(string);
boolean zTest17 = Test(string);
boolean zTest18 = Test(string);
boolean zTest19 = Test(string);
boolean zTest20 = Test(string);
boolean zTest21 = Test(string);
boolean zTest22 = Test(string);
boolean zTest23 = Test(string);
boolean zTest24 = Test(string);
boolean zTest25 = Test(string);
boolean zTest26 = Test(string);
boolean zTest27 = Test(string);
boolean zTest28 = Test(string);
boolean zTest29 = Test(string);
boolean zTest30 = Test(string);
boolean zTest31 = Test(string);
boolean zTest32 = Test(string);
boolean zTest33 = Test(string);
boolean zTest34 = Test(string);
boolean zTest35 = Test(string);
boolean zTest36 = Test(string);
boolean zTest37 = Test(string);
boolean zTest38 = Test(string);
boolean zTest39 = Test(string);
boolean zTest40 = Test(string);
boolean zTest41 = Test(string);
boolean zTest42 = Test(string);
boolean zTest43 = Test(string);
boolean zTest44 = Test(string);
boolean zTest45 = Test(string);
boolean zTest46 = Test(string);
boolean zTest47 = Test(string);
boolean zTest48 = Test(string);
boolean zTest49 = Test(string);
boolean zTest50 = Test(string);
boolean zTest51 = Test(string);
boolean zTest52 = Test(string);
boolean zTest53 = Test(string);
boolean zTest54 = Test(string);
boolean zTest55 = Test(string);
boolean zTest56 = Test(string);
boolean zTest57 = Test(string);
boolean zTest58 = Test(string);
boolean zTest59 = Test(string);
boolean zTest60 = Test(string);
boolean zTest61 = Test(string);
boolean zTest62 = Test(string);
boolean zTest63 = Test(string);
boolean zTest64 = Test(string);
boolean zTest65 = Test(string);
boolean zTest66 = Test(string);
boolean zTest67 = Test(string);
boolean zTest68 = Test(string);
boolean zTest69 = Test(string);
boolean zTest70 = Test(string);
boolean zTest71 = Test(string);
boolean zTest72 = Test(string);
boolean zTest73 = Test(string);
boolean zTest74 = Test(string);
boolean zTest75 = Test(string);
boolean zTest76 = Test(string);
boolean zTest77 = Test(string);
boolean zTest78 = Test(string);
boolean zTest79 = Test(string);
boolean zTest80 = Test(string);
if (zTest && zTest2 && zTest3 && zTest4 && zTest5 && zTest6 && zTest7 && zTest8 && zTest9 && zTest10 && zTest11 && zTest12 && zTest13 && zTest14 && zTest15 && zTest16 && zTest17 && zTest18 && zTest19 && zTest20 && zTest21 && zTest22 && zTest23 && zTest24 && zTest25 && zTest26 && zTest27 && zTest28 && zTest29 && zTest30 && zTest31 && zTest32 && zTest33 && zTest34 && zTest35 && zTest36 && zTest37 && zTest38 && zTest39 && zTest40 && zTest41 && zTest42 && zTest43 && zTest44 && zTest45 && zTest46 && zTest47 && zTest48 && zTest49 && zTest50 && zTest51 && zTest52 && zTest53 && zTest54 && zTest55 && zTest56 && zTest57 && zTest58 && zTest59 && zTest60 && zTest61 && zTest62 && zTest63 && zTest64 && zTest65 && zTest66 && zTest67 && zTest68 && zTest69 && zTest70 && zTest71 && zTest72 && zTest73 && zTest74 && zTest75 && zTest76 && zTest77 && zTest78 && zTest79 && zTest80) {
textView.setText("flag correct!");
} else {
textView.setText("flag is wrong...");
}
}
}

分析可知:

Flag 的长度固定为 55 个字符;

System.loadLibrary ("ohgreat2"); 说明核心逻辑在名为 libohgreat2.so 的 C/C++ 动态库中;

this.wow = Init (); 在应用启动时调用了一个 Init 函数;

有一个奇怪的 80 次调用:

1
2
3
4
boolean zTest = Test(string);
boolean zTest2 = Test(string);
// ... 一直到 zTest80
if (zTest && zTest2 && ... && zTest80) { Success }

你输入了同一个字符串 string,但程序调用了 80 次 Test (string),并且要求每一次都必须返回 true。 因此找到 libohgreat2.so 文件,拖入 ida 中,找到 Java_com_lake_ctf_MainActivity_Test 函数:

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
__int64 __fastcall Java_com_lake_ctf_MainActivity_Test(__int64 a1, __int64 a2, int a3)
{
char *v5; // rax
char *v6; // rax
__int64 v7; // r15
int v8; // eax
int v9; // r8d
int v10; // r9d
_OWORD v12[16]; // [rsp+0h] [rbp-228h] BYREF
_OWORD v13[16]; // [rsp+100h] [rbp-128h] BYREF
unsigned __int64 v14; // [rsp+200h] [rbp-28h]

v14 = __readfsqword(0x28u);
memset(v13, 0, sizeof(v13));
v5 = (char *)__strcat_chk(v13, "com/lake/ctf/Check", 256);
strcat(v5, aaa);
memset(v12, 0, sizeof(v12));
v6 = (char *)__strcat_chk(v12, "Check", 256);
strcat(v6, bbb);
v7 = (*(__int64 (__fastcall **)(__int64, _OWORD *))(*(_QWORD *)a1 + 48LL))(a1, v13);
v8 = (*(__int64 (__fastcall **)(__int64, __int64, _OWORD *, const char *))(*(_QWORD *)a1 + 904LL))(
a1,
v7,
v12,
"(Ljava/lang/String;)Z");
return _JNIEnv::CallStaticBooleanMethod(a1, v7, v8, a3, v9, v10, v12[0]);
}

分析可知

  • Init 函数:把两个全局变量 aaa 和 bbb 设置为了两个很长的十六进制字符串。
  • Test 函数:把这俩字符串拼接到类名和方法名后面,然后通过反射去调用 Java 方法。

然后再 jadx 可以看见许多 check 函数

56

因此导出所有 Java 代码

57

然后通过 z3-solver 写脚本即可求解:

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


SOURCE_DIR = r"D:\1\com.lake.ctf"
def solve():
print(f"[*] 正在扫描文件夹: {SOURCE_DIR} ...")

methods = {}


class_pattern = re.compile(r'Check([a-f0-9]{64})')


method_pattern = re.compile(
r'static boolean Check([a-f0-9]{64})\(String \w+\)\s*\{'
r'\s*if \((.*?)\)\s*\{'
r'\s*nop\("([a-f0-9]{64})", "([a-f0-9]{64})"',
re.DOTALL | re.MULTILINE
)

file_count = 0
for root, dirs, files in os.walk(SOURCE_DIR):
for file in files:
if file.endswith(".java") and file.startswith("Check"):
file_count += 1
path = os.path.join(root, file)

try:
with open(path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()

class_match = class_pattern.search(file)
if not class_match:
continue
current_class_hash = class_match.group(1)

if current_class_hash not in methods:
methods[current_class_hash] = {}


for m in method_pattern.findall(content):
m_hash, cond, next_cls, next_mtd = m

methods[current_class_hash][m_hash] = (cond, next_cls, next_mtd)
except Exception as e:
print(f"[-] 读取文件 {file} 出错: {e}")

print(f"[*] 扫描完成,共处理 {file_count} 个文件。")
print(f"[*] 加载了 {len(methods)} 个类的信息。")


curr_class = "86e50149658661312a9e0b35558d84f6c6d3da797f552a9657fe0558ca40cdef"
curr_method = "031b4af5197ec30a926f48cf40e11a7dbc470048a21e4003b7a3c07c5dab1baa"

constraints = []

print("[*] 正在追踪 80 层调用链...")
for i in range(80):
if curr_class not in methods:
print(f"[-] 错误:找不到类 Hash {curr_class[:8]}... (链条在第 {i + 1} 步断裂)")
break
if curr_method not in methods[curr_class]:
print(f"[-] 错误:在类 {curr_class[:8]}... 中找不到方法 {curr_method[:8]}...")
break


cond, next_cls, next_mtd = methods[curr_class][curr_method]


constraints.append(cond)


curr_class = next_cls
curr_method = next_mtd

print(f"[*] 成功收集到 {len(constraints)} 个方程约束。正在使用 Z3 求解...")


solver = Solver()


flag_chars = [Int(f'x_{i}') for i in range(55)]


for i in range(55):
solver.add(flag_chars[i] >= 32, flag_chars[i] <= 126)

for raw_cond in constraints:

py_expr = re.sub(r'str\.charAt\((\d+)\)', r'x_\1', raw_cond)


if "==" in py_expr:
left, right = py_expr.split('==')


env = {f'x_{i}': flag_chars[i] for i in range(55)}

try:

solver.add(eval(left, {}, env) == int(right))
except Exception as e:
print(f"[-] 解析方程失败: {raw_cond} -> {e}")


if solver.check() == sat:
model = solver.model()
flag_str = ""

for i in range(55):
val = model[flag_chars[i]]
if val is not None:
flag_str += chr(val.as_long())
else:
flag_str += "?" # 如果某一位没有被约束
print("\n" + "=" * 50)
print(f"🎉 恭喜!Flag 是:\n{flag_str}")
print("=" * 50 + "\n")
else:
print("[-] 无解 (Unsatisfiable)。可能文件导出不完整或逻辑解析有误。")


if __name__ == "__main__":
solve()

运行得到 EPFL {Wh1_3v3n_b0th3r_w1th_J4v4_1n_th3_f1rst_Pl4c3?????}

# drum machine

通过 ida 分析 main 函数,可以知道:

  • 读取用户输入字符串。

  • 调用 decomposeInput 将字符串转换为 vector<Step>。

  • 初始化 DrumMachine 对象(加载巨大的转移表)。

  • 调用 DrumMachine::playBeat 执行状态机。

  • 检查 DrumMachine::getState () == 181。如果成立,打印 "Congratulations"。

同时 main 函数还定义了字符到状态机输入的转换规则:

  • 遍历输入字符串的每一个字符。

  • 对每个字符的 8 个比特位(0-7)进行检查。

  • 如果第 j 位是 1,则生成一个数值为 j 的 Hit。

  • 关键特性:对于同一个字符,生成的 Hit 序列是严格递增的(从小到大遍历比特位)。一旦 Hit 数值变小,意味着开始处理下一个字符。

因此可以知道这是一个典型的 DFA (确定性有限自动机) 实现。 转移表硬编码在 DrumMachine 的构造函数中

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
void __fastcall DrumMachine::DrumMachine(DrumMachine *this, __int64 a2)
{
_DWORD *v2; // rdi
std::vector<Step>::vector(this, a2);
v2 = (_DWORD *)((char *)this + 24);
memset(v2, 0, 0x1700u);
*v2 = 1;
*((_DWORD *)this + 15) = 1;
*((_DWORD *)this + 16) = 2;
*((_DWORD *)this + 25) = 2;
*((_DWORD *)this + 26) = 4;
*((_DWORD *)this + 27) = 5;
*((_DWORD *)this + 28) = 3;
*((_DWORD *)this + 30) = 6;
*((_DWORD *)this + 31) = 3;
*((_DWORD *)this + 32) = 3;
*((_DWORD *)this + 34) = 4;
*((_DWORD *)this + 37) = 6;
*((_DWORD *)this + 43) = 4;
*((_DWORD *)this + 44) = 5;
*((_DWORD *)this + 46) = 5;
*((_DWORD *)this + 47) = 6;
*((_DWORD *)this + 53) = 5;
*((_DWORD *)this + 56) = 7;
*((_DWORD *)this + 65) = 10;
*((_DWORD *)this + 66) = 10;
*((_DWORD *)this + 67) = 7;
*((_DWORD *)this + 68) = 8;
*((_DWORD *)this + 70) = 4;
*((_DWORD *)this + 71) = 11;
*((_DWORD *)this + 72) = 9;
*((_DWORD *)this + 77) = 11;
*((_DWORD *)this + 81) = 10;
*((_DWORD *)this + 90) = 6;
*((_DWORD *)this + 91) = 12;
*((_DWORD *)this + 92) = 11;
*((_DWORD *)this + 94) = 12;
*((_DWORD *)this + 101) = 11;
*((_DWORD *)this + 103) = 13;
*((_DWORD *)this + 112) = 16;
*((_DWORD *)this + 113) = 14;
*((_DWORD *)this + 122) = 15;
*((_DWORD *)this + 131) = 16;
*((_DWORD *)this + 140) = 17;
*((_DWORD *)this + 142) = 19;
*((_DWORD *)this + 143) = 19;
*((_DWORD *)this + 144) = 18;
*((_DWORD *)this + 149) = 13;
*((_DWORD *)this + 153) = 21;
*((_DWORD *)this + 154) = 21;
*((_DWORD *)this + 155) = 19;
*((_DWORD *)this + 164) = 20;
*((_DWORD *)this + 166) = 21;
*((_DWORD *)this + 173) = 22;
*((_DWORD *)this + 175) = 21;
*((_DWORD *)this + 176) = 21;
*((_DWORD *)this + 177) = 17;
*((_DWORD *)this + 178) = 21;
*((_DWORD *)this + 179) = 22;
*((_DWORD *)this + 188) = 23;
*((_DWORD *)this + 190) = 25;
*((_DWORD *)this + 191) = 24;
*((_DWORD *)this + 197) = 25;
*((_DWORD *)this + 200) = 25;
*((_DWORD *)this + 209) = 26;
*((_DWORD *)this + 218) = 28;
*((_DWORD *)this + 219) = 27;
*((_DWORD *)this + 228) = 28;
*((_DWORD *)this + 230) = 29;
*((_DWORD *)this + 237) = 28;
*((_DWORD *)this + 239) = 30;
*((_DWORD *)this + 248) = 26;
*((_DWORD *)this + 249) = 30;
*((_DWORD *)this + 250) = 26;
*((_DWORD *)this + 251) = 31;
*((_DWORD *)this + 260) = 32;
*((_DWORD *)this + 262) = 33;
*((_DWORD *)this + 269) = 32;
*((_DWORD *)this + 271) = 35;
*((_DWORD *)this + 272) = 34;
*((_DWORD *)this + 281) = 36;
*((_DWORD *)this + 282) = 37;
*((_DWORD *)this + 283) = 35;
*((_DWORD *)this + 292) = 36;
*((_DWORD *)this + 294) = 37;
*((_DWORD *)this + 301) = 36;
*((_DWORD *)this + 303) = 38;
*((_DWORD *)this + 312) = 39;
*((_DWORD *)this + 321) = 40;
*((_DWORD *)this + 330) = 41;
*((_DWORD *)this + 339) = 41;
*((_DWORD *)this + 340) = 42;
*((_DWORD *)this + 342) = 43;
*((_DWORD *)this + 349) = 45;
*((_DWORD *)this + 351) = 45;
*((_DWORD *)this + 352) = 43;
*((_DWORD *)this + 353) = 46;
*((_DWORD *)this + 354) = 43;
*((_DWORD *)this + 355) = 44;
*((_DWORD *)this + 364) = 45;
*((_DWORD *)this + 366) = 47;
*((_DWORD *)this + 367) = 41;
*((_DWORD *)this + 368) = 46;
*((_DWORD *)this + 373) = 41;
*((_DWORD *)this + 377) = 47;
*((_DWORD *)this + 386) = 49;
*((_DWORD *)this + 387) = 48;
*((_DWORD *)this + 396) = 49;
*((_DWORD *)this + 398) = 50;
*((_DWORD *)this + 405) = 52;
*((_DWORD *)this + 407) = 51;
*((_DWORD *)this + 416) = 52;
*((_DWORD *)this + 425) = 53;
*((_DWORD *)this + 434) = 55;
*((_DWORD *)this + 435) = 54;
*((_DWORD *)this + 444) = 55;
*((_DWORD *)this + 446) = 58;
*((_DWORD *)this + 447) = 56;
*((_DWORD *)this + 453) = 57;
*((_DWORD *)this + 456) = 57;
*((_DWORD *)this + 465) = 58;
*((_DWORD *)this + 474) = 60;
*((_DWORD *)this + 475) = 59;
*((_DWORD *)this + 484) = 60;
*((_DWORD *)this + 486) = 61;
*((_DWORD *)this + 493) = 60;
*((_DWORD *)this + 495) = 62;
*((_DWORD *)this + 504) = 63;
*((_DWORD *)this + 513) = 66;
*((_DWORD *)this + 514) = 66;
*((_DWORD *)this + 515) = 64;
*((_DWORD *)this + 524) = 65;
*((_DWORD *)this + 526) = 66;
*((_DWORD *)this + 533) = 68;
*((_DWORD *)this + 535) = 67;
*((_DWORD *)this + 544) = 68;
*((_DWORD *)this + 553) = 69;
*((_DWORD *)this + 562) = 70;
*((_DWORD *)this + 571) = 66;
*((_DWORD *)this + 572) = 71;
*((_DWORD *)this + 574) = 73;
*((_DWORD *)this + 575) = 74;
*((_DWORD *)this + 576) = 72;
*((_DWORD *)this + 581) = 67;
*((_DWORD *)this + 585) = 74;
*((_DWORD *)this + 586) = 73;
*((_DWORD *)this + 595) = 74;
*((_DWORD *)this + 604) = 75;
*((_DWORD *)this + 606) = 76;
*((_DWORD *)this + 613) = 75;
*((_DWORD *)this + 615) = 77;
*((_DWORD *)this + 624) = 78;
*((_DWORD *)this + 633) = 79;
*((_DWORD *)this + 642) = 82;
*((_DWORD *)this + 643) = 80;
*((_DWORD *)this + 652) = 81;
*((_DWORD *)this + 654) = 82;
*((_DWORD *)this + 661) = 81;
*((_DWORD *)this + 663) = 83;
*((_DWORD *)this + 672) = 84;
*((_DWORD *)this + 681) = 85;
*((_DWORD *)this + 690) = 86;
*((_DWORD *)this + 699) = 88;
*((_DWORD *)this + 700) = 87;
*((_DWORD *)this + 702) = 89;
*((_DWORD *)this + 703) = 87;
*((_DWORD *)this + 704) = 88;
*((_DWORD *)this + 709) = 83;
*((_DWORD *)this + 713) = 91;
*((_DWORD *)this + 714) = 89;
*((_DWORD *)this + 723) = 90;
*((_DWORD *)this + 732) = 91;
*((_DWORD *)this + 734) = 94;
*((_DWORD *)this + 735) = 87;
*((_DWORD *)this + 736) = 87;
*((_DWORD *)this + 737) = 92;
*((_DWORD *)this + 741) = 93;
*((_DWORD *)this + 746) = 88;
*((_DWORD *)this + 747) = 93;
*((_DWORD *)this + 756) = 94;
*((_DWORD *)this + 758) = 95;
*((_DWORD *)this + 765) = 97;
*((_DWORD *)this + 767) = 97;
*((_DWORD *)this + 768) = 96;
*((_DWORD *)this + 777) = 99;
*((_DWORD *)this + 778) = 99;
*((_DWORD *)this + 779) = 97;
*((_DWORD *)this + 788) = 98;
*((_DWORD *)this + 790) = 99;
*((_DWORD *)this + 797) = 100;
*((_DWORD *)this + 799) = 100;
*((_DWORD *)this + 808) = 101;
*((_DWORD *)this + 817) = 102;
*((_DWORD *)this + 826) = 103;
*((_DWORD *)this + 835) = 99;
*((_DWORD *)this + 836) = 104;
*((_DWORD *)this + 838) = 106;
*((_DWORD *)this + 839) = 105;
*((_DWORD *)this + 845) = 100;
*((_DWORD *)this + 848) = 108;
*((_DWORD *)this + 849) = 108;
*((_DWORD *)this + 850) = 101;
*((_DWORD *)this + 851) = 106;
*((_DWORD *)this + 860) = 107;
*((_DWORD *)this + 862) = 108;
*((_DWORD *)this + 869) = 107;
*((_DWORD *)this + 871) = 109;
*((_DWORD *)this + 880) = 109;
*((_DWORD *)this + 881) = 109;
*((_DWORD *)this + 882) = 110;
*((_DWORD *)this + 891) = 111;
*((_DWORD *)this + 894) = 107;
*((_DWORD *)this + 895) = 111;
*((_DWORD *)this + 896) = 112;
*((_DWORD *)this + 900) = 114;
*((_DWORD *)this + 901) = 114;
*((_DWORD *)this + 905) = 108;
*((_DWORD *)this + 906) = 113;
*((_DWORD *)this + 915) = 114;
*((_DWORD *)this + 918) = 116;
*((_DWORD *)this + 919) = 114;
*((_DWORD *)this + 920) = 115;
*((_DWORD *)this + 924) = 110;
*((_DWORD *)this + 925) = 110;
*((_DWORD *)this + 929) = 115;
*((_DWORD *)this + 930) = 116;
*((_DWORD *)this + 939) = 117;
*((_DWORD *)this + 948) = 118;
*((_DWORD *)this + 950) = 119;
*((_DWORD *)this + 957) = 120;
*((_DWORD *)this + 959) = 120;
*((_DWORD *)this + 968) = 121;
*((_DWORD *)this + 977) = 122;
*((_DWORD *)this + 986) = 123;
*((_DWORD *)this + 995) = 125;
*((_DWORD *)this + 996) = 124;
*((_DWORD *)this + 998) = 125;
*((_DWORD *)this + 1005) = 124;
*((_DWORD *)this + 1007) = 126;
*((_DWORD *)this + 1016) = 127;
*((_DWORD *)this + 1025) = 128;
*((_DWORD *)this + 1034) = 130;
*((_DWORD *)this + 1035) = 129;
*((_DWORD *)this + 1044) = 130;
*((_DWORD *)this + 1046) = 133;
*((_DWORD *)this + 1047) = 131;
*((_DWORD *)this + 1053) = 126;
*((_DWORD *)this + 1056) = 132;
*((_DWORD *)this + 1065) = 128;
*((_DWORD *)this + 1066) = 132;
*((_DWORD *)this + 1067) = 133;
*((_DWORD *)this + 1076) = 134;
*((_DWORD *)this + 1078) = 135;
*((_DWORD *)this + 1085) = 136;
*((_DWORD *)this + 1087) = 136;
*((_DWORD *)this + 1096) = 137;
*((_DWORD *)this + 1105) = 138;
*((_DWORD *)this + 1114) = 139;
*((_DWORD *)this + 1123) = 142;
*((_DWORD *)this + 1124) = 140;
*((_DWORD *)this + 1126) = 142;
*((_DWORD *)this + 1127) = 143;
*((_DWORD *)this + 1128) = 141;
*((_DWORD *)this + 1133) = 140;
*((_DWORD *)this + 1137) = 144;
*((_DWORD *)this + 1138) = 142;
*((_DWORD *)this + 1147) = 143;
*((_DWORD *)this + 1156) = 144;
*((_DWORD *)this + 1158) = 147;
*((_DWORD *)this + 1159) = 144;
*((_DWORD *)this + 1160) = 146;
*((_DWORD *)this + 1161) = 145;
*((_DWORD *)this + 1165) = 146;
*((_DWORD *)this + 1170) = 141;
*((_DWORD *)this + 1171) = 146;
*((_DWORD *)this + 1180) = 147;
*((_DWORD *)this + 1182) = 148;
*((_DWORD *)this + 1189) = 147;
*((_DWORD *)this + 1191) = 148;
*((_DWORD *)this + 1192) = 149;
*((_DWORD *)this + 1201) = 151;
*((_DWORD *)this + 1202) = 151;
*((_DWORD *)this + 1203) = 150;
*((_DWORD *)this + 1212) = 151;
*((_DWORD *)this + 1214) = 152;
*((_DWORD *)this + 1221) = 154;
*((_DWORD *)this + 1223) = 153;
*((_DWORD *)this + 1232) = 154;
*((_DWORD *)this + 1241) = 155;
*((_DWORD *)this + 1250) = 156;
*((_DWORD *)this + 1259) = 156;
*((_DWORD *)this + 1260) = 157;
*((_DWORD *)this + 1262) = 157;
*((_DWORD *)this + 1263) = 158;
*((_DWORD *)this + 1269) = 160;
*((_DWORD *)this + 1272) = 159;
*((_DWORD *)this + 1281) = 159;
*((_DWORD *)this + 1282) = 155;
*((_DWORD *)this + 1283) = 160;
*((_DWORD *)this + 1292) = 161;
*((_DWORD *)this + 1294) = 164;
*((_DWORD *)this + 1295) = 164;
*((_DWORD *)this + 1296) = 162;
*((_DWORD *)this + 1301) = 161;
*((_DWORD *)this + 1305) = 163;
*((_DWORD *)this + 1314) = 159;
*((_DWORD *)this + 1315) = 164;
*((_DWORD *)this + 1324) = 165;
*((_DWORD *)this + 1326) = 167;
*((_DWORD *)this + 1327) = 161;
*((_DWORD *)this + 1328) = 166;
*((_DWORD *)this + 1333) = 168;
*((_DWORD *)this + 1337) = 169;
*((_DWORD *)this + 1338) = 167;
*((_DWORD *)this + 1347) = 168;
*((_DWORD *)this + 1350) = 169;
*((_DWORD *)this + 1356) = 171;
*((_DWORD *)this + 1357) = 170;
*((_DWORD *)this + 1359) = 170;
*((_DWORD *)this + 1368) = 171;
*((_DWORD *)this + 1377) = 167;
*((_DWORD *)this + 1378) = 173;
*((_DWORD *)this + 1379) = 172;
*((_DWORD *)this + 1388) = 173;
*((_DWORD *)this + 1390) = 174;
*((_DWORD *)this + 1397) = 169;
*((_DWORD *)this + 1399) = 170;
*((_DWORD *)this + 1400) = 174;
*((_DWORD *)this + 1401) = 177;
*((_DWORD *)this + 1402) = 177;
*((_DWORD *)this + 1403) = 175;
*((_DWORD *)this + 1406) = 176;
*((_DWORD *)this + 1412) = 175;
*((_DWORD *)this + 1413) = 177;
*((_DWORD *)this + 1415) = 176;
*((_DWORD *)this + 1416) = 177;
*((_DWORD *)this + 1425) = 178;
*((_DWORD *)this + 1434) = 179;
*((_DWORD *)this + 1443) = 180;
*((_DWORD *)this + 1452) = 181;
*((_DWORD *)this + 1461) = 184;
*((_DWORD *)this + 1478) = 0;
*((_DWORD *)this + 1479) = 23;
*((_DWORD *)this + 1480) = 21;
*((_DWORD *)this + 1481) = 32;
*((_DWORD *)this + 1482) = 19;
*((_DWORD *)this + 1483) = 17;
*((_DWORD *)this + 1484) = 31;
*((_DWORD *)this + 1485) = 38;
*((_DWORD *)this + 1486) = 0;
*(_QWORD *)((char *)this + 5948) = 0;
*(_QWORD *)((char *)this + 5956) = 0;
*(_QWORD *)((char *)this + 5964) = 0;
*(_QWORD *)((char *)this + 5972) = 0;
}

通过观察状态机的逻辑,我们发现这是一个 Flag 校验机。这意味着正确的输入会让状态机按部就班地晋级:State 0→State 1→State 2⋯→State 181 因此这是一条单向链表

所以给出 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
import re

code_raw = """
std::vector<Step>::vector(this, a2);
v2 = (_DWORD *)((char *)this + 24);
memset(v2, 0, 0x1700u);
*v2 = 1;
*((_DWORD *)this + 15) = 1;
*((_DWORD *)this + 16) = 2;
*((_DWORD *)this + 25) = 2;
*((_DWORD *)this + 26) = 4;
*((_DWORD *)this + 27) = 5;
*((_DWORD *)this + 28) = 3;
*((_DWORD *)this + 30) = 6;
*((_DWORD *)this + 31) = 3;
*((_DWORD *)this + 32) = 3;
*((_DWORD *)this + 34) = 4;
*((_DWORD *)this + 37) = 6;
*((_DWORD *)this + 43) = 4;
*((_DWORD *)this + 44) = 5;
*((_DWORD *)this + 46) = 5;
*((_DWORD *)this + 47) = 6;
*((_DWORD *)this + 53) = 5;
*((_DWORD *)this + 56) = 7;
*((_DWORD *)this + 65) = 10;
*((_DWORD *)this + 66) = 10;
*((_DWORD *)this + 67) = 7;
*((_DWORD *)this + 68) = 8;
*((_DWORD *)this + 70) = 4;
*((_DWORD *)this + 71) = 11;
*((_DWORD *)this + 72) = 9;
*((_DWORD *)this + 77) = 11;
*((_DWORD *)this + 81) = 10;
*((_DWORD *)this + 90) = 6;
*((_DWORD *)this + 91) = 12;
*((_DWORD *)this + 92) = 11;
*((_DWORD *)this + 94) = 12;
*((_DWORD *)this + 101) = 11;
*((_DWORD *)this + 103) = 13;
*((_DWORD *)this + 112) = 16;
*((_DWORD *)this + 113) = 14;
*((_DWORD *)this + 122) = 15;
*((_DWORD *)this + 131) = 16;
*((_DWORD *)this + 140) = 17;
*((_DWORD *)this + 142) = 19;
*((_DWORD *)this + 143) = 19;
*((_DWORD *)this + 144) = 18;
*((_DWORD *)this + 149) = 13;
*((_DWORD *)this + 153) = 21;
*((_DWORD *)this + 154) = 21;
*((_DWORD *)this + 155) = 19;
*((_DWORD *)this + 164) = 20;
*((_DWORD *)this + 166) = 21;
*((_DWORD *)this + 173) = 22;
*((_DWORD *)this + 175) = 21;
*((_DWORD *)this + 176) = 21;
*((_DWORD *)this + 177) = 17;
*((_DWORD *)this + 178) = 21;
*((_DWORD *)this + 179) = 22;
*((_DWORD *)this + 188) = 23;
*((_DWORD *)this + 190) = 25;
*((_DWORD *)this + 191) = 24;
*((_DWORD *)this + 197) = 25;
*((_DWORD *)this + 200) = 25;
*((_DWORD *)this + 209) = 26;
*((_DWORD *)this + 218) = 28;
*((_DWORD *)this + 219) = 27;
*((_DWORD *)this + 228) = 28;
*((_DWORD *)this + 230) = 29;
*((_DWORD *)this + 237) = 28;
*((_DWORD *)this + 239) = 30;
*((_DWORD *)this + 248) = 26;
*((_DWORD *)this + 249) = 30;
*((_DWORD *)this + 250) = 26;
*((_DWORD *)this + 251) = 31;
*((_DWORD *)this + 260) = 32;
*((_DWORD *)this + 262) = 33;
*((_DWORD *)this + 269) = 32;
*((_DWORD *)this + 271) = 35;
*((_DWORD *)this + 272) = 34;
*((_DWORD *)this + 281) = 36;
*((_DWORD *)this + 282) = 37;
*((_DWORD *)this + 283) = 35;
*((_DWORD *)this + 292) = 36;
*((_DWORD *)this + 294) = 37;
*((_DWORD *)this + 301) = 36;
*((_DWORD *)this + 303) = 38;
*((_DWORD *)this + 312) = 39;
*((_DWORD *)this + 321) = 40;
*((_DWORD *)this + 330) = 41;
*((_DWORD *)this + 339) = 41;
*((_DWORD *)this + 340) = 42;
*((_DWORD *)this + 342) = 43;
*((_DWORD *)this + 349) = 45;
*((_DWORD *)this + 351) = 45;
*((_DWORD *)this + 352) = 43;
*((_DWORD *)this + 353) = 46;
*((_DWORD *)this + 354) = 43;
*((_DWORD *)this + 355) = 44;
*((_DWORD *)this + 364) = 45;
*((_DWORD *)this + 366) = 47;
*((_DWORD *)this + 367) = 41;
*((_DWORD *)this + 368) = 46;
*((_DWORD *)this + 373) = 41;
*((_DWORD *)this + 377) = 47;
*((_DWORD *)this + 386) = 49;
*((_DWORD *)this + 387) = 48;
*((_DWORD *)this + 396) = 49;
*((_DWORD *)this + 398) = 50;
*((_DWORD *)this + 405) = 52;
*((_DWORD *)this + 407) = 51;
*((_DWORD *)this + 416) = 52;
*((_DWORD *)this + 425) = 53;
*((_DWORD *)this + 434) = 55;
*((_DWORD *)this + 435) = 54;
*((_DWORD *)this + 444) = 55;
*((_DWORD *)this + 446) = 58;
*((_DWORD *)this + 447) = 56;
*((_DWORD *)this + 453) = 57;
*((_DWORD *)this + 456) = 57;
*((_DWORD *)this + 465) = 58;
*((_DWORD *)this + 474) = 60;
*((_DWORD *)this + 475) = 59;
*((_DWORD *)this + 484) = 60;
*((_DWORD *)this + 486) = 61;
*((_DWORD *)this + 493) = 60;
*((_DWORD *)this + 495) = 62;
*((_DWORD *)this + 504) = 63;
*((_DWORD *)this + 513) = 66;
*((_DWORD *)this + 514) = 66;
*((_DWORD *)this + 515) = 64;
*((_DWORD *)this + 524) = 65;
*((_DWORD *)this + 526) = 66;
*((_DWORD *)this + 533) = 68;
*((_DWORD *)this + 535) = 67;
*((_DWORD *)this + 544) = 68;
*((_DWORD *)this + 553) = 69;
*((_DWORD *)this + 562) = 70;
*((_DWORD *)this + 571) = 66;
*((_DWORD *)this + 572) = 71;
*((_DWORD *)this + 574) = 73;
*((_DWORD *)this + 575) = 74;
*((_DWORD *)this + 576) = 72;
*((_DWORD *)this + 581) = 67;
*((_DWORD *)this + 585) = 74;
*((_DWORD *)this + 586) = 73;
*((_DWORD *)this + 595) = 74;
*((_DWORD *)this + 604) = 75;
*((_DWORD *)this + 606) = 76;
*((_DWORD *)this + 613) = 75;
*((_DWORD *)this + 615) = 77;
*((_DWORD *)this + 624) = 78;
*((_DWORD *)this + 633) = 79;
*((_DWORD *)this + 642) = 82;
*((_DWORD *)this + 643) = 80;
*((_DWORD *)this + 652) = 81;
*((_DWORD *)this + 654) = 82;
*((_DWORD *)this + 661) = 81;
*((_DWORD *)this + 663) = 83;
*((_DWORD *)this + 672) = 84;
*((_DWORD *)this + 681) = 85;
*((_DWORD *)this + 690) = 86;
*((_DWORD *)this + 699) = 88;
*((_DWORD *)this + 700) = 87;
*((_DWORD *)this + 702) = 89;
*((_DWORD *)this + 703) = 87;
*((_DWORD *)this + 704) = 88;
*((_DWORD *)this + 709) = 83;
*((_DWORD *)this + 713) = 91;
*((_DWORD *)this + 714) = 89;
*((_DWORD *)this + 723) = 90;
*((_DWORD *)this + 732) = 91;
*((_DWORD *)this + 734) = 94;
*((_DWORD *)this + 735) = 87;
*((_DWORD *)this + 736) = 87;
*((_DWORD *)this + 737) = 92;
*((_DWORD *)this + 741) = 93;
*((_DWORD *)this + 746) = 88;
*((_DWORD *)this + 747) = 93;
*((_DWORD *)this + 756) = 94;
*((_DWORD *)this + 758) = 95;
*((_DWORD *)this + 765) = 97;
*((_DWORD *)this + 767) = 97;
*((_DWORD *)this + 768) = 96;
*((_DWORD *)this + 777) = 99;
*((_DWORD *)this + 778) = 99;
*((_DWORD *)this + 779) = 97;
*((_DWORD *)this + 788) = 98;
*((_DWORD *)this + 790) = 99;
*((_DWORD *)this + 797) = 100;
*((_DWORD *)this + 799) = 100;
*((_DWORD *)this + 808) = 101;
*((_DWORD *)this + 817) = 102;
*((_DWORD *)this + 826) = 103;
*((_DWORD *)this + 835) = 99;
*((_DWORD *)this + 836) = 104;
*((_DWORD *)this + 838) = 106;
*((_DWORD *)this + 839) = 105;
*((_DWORD *)this + 845) = 100;
*((_DWORD *)this + 848) = 108;
*((_DWORD *)this + 849) = 108;
*((_DWORD *)this + 850) = 101;
*((_DWORD *)this + 851) = 106;
*((_DWORD *)this + 860) = 107;
*((_DWORD *)this + 862) = 108;
*((_DWORD *)this + 869) = 107;
*((_DWORD *)this + 871) = 109;
*((_DWORD *)this + 880) = 109;
*((_DWORD *)this + 881) = 109;
*((_DWORD *)this + 882) = 110;
*((_DWORD *)this + 891) = 111;
*((_DWORD *)this + 894) = 107;
*((_DWORD *)this + 895) = 111;
*((_DWORD *)this + 896) = 112;
*((_DWORD *)this + 900) = 114;
*((_DWORD *)this + 901) = 114;
*((_DWORD *)this + 905) = 108;
*((_DWORD *)this + 906) = 113;
*((_DWORD *)this + 915) = 114;
*((_DWORD *)this + 918) = 116;
*((_DWORD *)this + 919) = 114;
*((_DWORD *)this + 920) = 115;
*((_DWORD *)this + 924) = 110;
*((_DWORD *)this + 925) = 110;
*((_DWORD *)this + 929) = 115;
*((_DWORD *)this + 930) = 116;
*((_DWORD *)this + 939) = 117;
*((_DWORD *)this + 948) = 118;
*((_DWORD *)this + 950) = 119;
*((_DWORD *)this + 957) = 120;
*((_DWORD *)this + 959) = 120;
*((_DWORD *)this + 968) = 121;
*((_DWORD *)this + 977) = 122;
*((_DWORD *)this + 986) = 123;
*((_DWORD *)this + 995) = 125;
*((_DWORD *)this + 996) = 124;
*((_DWORD *)this + 998) = 125;
*((_DWORD *)this + 1005) = 124;
*((_DWORD *)this + 1007) = 126;
*((_DWORD *)this + 1016) = 127;
*((_DWORD *)this + 1025) = 128;
*((_DWORD *)this + 1034) = 130;
*((_DWORD *)this + 1035) = 129;
*((_DWORD *)this + 1044) = 130;
*((_DWORD *)this + 1046) = 133;
*((_DWORD *)this + 1047) = 131;
*((_DWORD *)this + 1053) = 126;
*((_DWORD *)this + 1056) = 132;
*((_DWORD *)this + 1065) = 128;
*((_DWORD *)this + 1066) = 132;
*((_DWORD *)this + 1067) = 133;
*((_DWORD *)this + 1076) = 134;
*((_DWORD *)this + 1078) = 135;
*((_DWORD *)this + 1085) = 136;
*((_DWORD *)this + 1087) = 136;
*((_DWORD *)this + 1096) = 137;
*((_DWORD *)this + 1105) = 138;
*((_DWORD *)this + 1114) = 139;
*((_DWORD *)this + 1123) = 142;
*((_DWORD *)this + 1124) = 140;
*((_DWORD *)this + 1126) = 142;
*((_DWORD *)this + 1127) = 143;
*((_DWORD *)this + 1128) = 141;
*((_DWORD *)this + 1133) = 140;
*((_DWORD *)this + 1137) = 144;
*((_DWORD *)this + 1138) = 142;
*((_DWORD *)this + 1147) = 143;
*((_DWORD *)this + 1156) = 144;
*((_DWORD *)this + 1158) = 147;
*((_DWORD *)this + 1159) = 144;
*((_DWORD *)this + 1160) = 146;
*((_DWORD *)this + 1161) = 145;
*((_DWORD *)this + 1165) = 146;
*((_DWORD *)this + 1170) = 141;
*((_DWORD *)this + 1171) = 146;
*((_DWORD *)this + 1180) = 147;
*((_DWORD *)this + 1182) = 148;
*((_DWORD *)this + 1189) = 147;
*((_DWORD *)this + 1191) = 148;
*((_DWORD *)this + 1192) = 149;
*((_DWORD *)this + 1201) = 151;
*((_DWORD *)this + 1202) = 151;
*((_DWORD *)this + 1203) = 150;
*((_DWORD *)this + 1212) = 151;
*((_DWORD *)this + 1214) = 152;
*((_DWORD *)this + 1221) = 154;
*((_DWORD *)this + 1223) = 153;
*((_DWORD *)this + 1232) = 154;
*((_DWORD *)this + 1241) = 155;
*((_DWORD *)this + 1250) = 156;
*((_DWORD *)this + 1259) = 156;
*((_DWORD *)this + 1260) = 157;
*((_DWORD *)this + 1262) = 157;
*((_DWORD *)this + 1263) = 158;
*((_DWORD *)this + 1269) = 160;
*((_DWORD *)this + 1272) = 159;
*((_DWORD *)this + 1281) = 159;
*((_DWORD *)this + 1282) = 155;
*((_DWORD *)this + 1283) = 160;
*((_DWORD *)this + 1292) = 161;
*((_DWORD *)this + 1294) = 164;
*((_DWORD *)this + 1295) = 164;
*((_DWORD *)this + 1296) = 162;
*((_DWORD *)this + 1301) = 161;
*((_DWORD *)this + 1305) = 163;
*((_DWORD *)this + 1314) = 159;
*((_DWORD *)this + 1315) = 164;
*((_DWORD *)this + 1324) = 165;
*((_DWORD *)this + 1326) = 167;
*((_DWORD *)this + 1327) = 161;
*((_DWORD *)this + 1328) = 166;
*((_DWORD *)this + 1333) = 168;
*((_DWORD *)this + 1337) = 169;
*((_DWORD *)this + 1338) = 167;
*((_DWORD *)this + 1347) = 168;
*((_DWORD *)this + 1350) = 169;
*((_DWORD *)this + 1356) = 171;
*((_DWORD *)this + 1357) = 170;
*((_DWORD *)this + 1359) = 170;
*((_DWORD *)this + 1368) = 171;
*((_DWORD *)this + 1377) = 167;
*((_DWORD *)this + 1378) = 173;
*((_DWORD *)this + 1379) = 172;
*((_DWORD *)this + 1388) = 173;
*((_DWORD *)this + 1390) = 174;
*((_DWORD *)this + 1397) = 169;
*((_DWORD *)this + 1399) = 170;
*((_DWORD *)this + 1400) = 174;
*((_DWORD *)this + 1401) = 177;
*((_DWORD *)this + 1402) = 177;
*((_DWORD *)this + 1403) = 175;
*((_DWORD *)this + 1406) = 176;
*((_DWORD *)this + 1412) = 175;
*((_DWORD *)this + 1413) = 177;
*((_DWORD *)this + 1415) = 176;
*((_DWORD *)this + 1416) = 177;
*((_DWORD *)this + 1425) = 178;
*((_DWORD *)this + 1434) = 179;
*((_DWORD *)this + 1443) = 180;
*((_DWORD *)this + 1452) = 181;
*((_DWORD *)this + 1461) = 184;
*((_DWORD *)this + 1478) = 0;
*((_DWORD *)this + 1479) = 23;
*((_DWORD *)this + 1480) = 21;
*((_DWORD *)this + 1481) = 32;
*((_DWORD *)this + 1482) = 19;
*((_DWORD *)this + 1483) = 17;
*((_DWORD *)this + 1484) = 31;
*((_DWORD *)this + 1485) = 38;
*((_DWORD *)this + 1486) = 0;
*(_QWORD *)((char *)this + 5948) = 0;
*(_QWORD *)((char *)this + 5956) = 0;
*(_QWORD *)((char *)this + 5964) = 0;
*(_QWORD *)((char *)this + 5972) = 0;
"""


def solve_linear_chain():
print("[*] Parsing code...")


graph = {}


pattern = re.compile(r'\+\s*(\d+)\)\s*=\s*(\d+);')
matches = pattern.findall(code_raw)


for offset_str, value_str in matches:
offset = int(offset_str)
value = int(value_str)


if offset >= 1478: continue
rel_offset = offset - 6
if rel_offset < 0: continue

state = rel_offset // 8
hit = rel_offset % 8

if state not in graph: graph[state] = {}
graph[state][hit] = value


if 0 not in graph: graph[0] = {}
graph[0][0] = 1

print(f"[*] Graph parsed with {len(graph)} source states.")
print("[*] Tracing the linear chain (0 -> 1 -> ... -> 181)...")


path = []

for current_state in range(181):
found_hit = -1

if current_state in graph:

for hit, next_state in graph[current_state].items():
if next_state == current_state + 1:
found_hit = hit
break

if found_hit != -1:
path.append(found_hit)
else:
print(f"[-] Broken chain at State {current_state}! Could not find transition to {current_state + 1}")
break

print(f"[*] Chain complete. Length: {len(path)}")


flag = ""
val = 0
last_hit = -1

for hit in path:

if hit <= last_hit:
flag += chr(val)
val = 0
last_hit = -1

val |= (1 << hit)
last_hit = hit

flag += chr(val)

print("\n" + "=" * 40)
print(f"FLAG: {flag}")
print("=" * 40)


if __name__ == "__main__":
solve_linear_chain()

更新于 阅读次数