逆向攻防世界CTF系列52-Newbie_calculations

32位,无壳

aaa

我们得到的信息是,32位初始值赋为1,然后很多函数重复,这是一个生成flag的题型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
_DWORD *__cdecl sub_A31100(_DWORD *a1, int a2){
v4 = *a1;//1
v5 = a2;//1000000000
v3 = -1;
v8 = 0;
v7 = a2 * v4;//1000000000
while ( a2 ){//1000000000
v6 = v7 * v4;
sub_A31000(&v8, *a1);//0,1
++v7;
--a2;
v5 = v6 - 1;
}
while ( v3 ){
++v7;
++*a1;
--v3;
--v5;
}
++*a1;
*a1 = v8;
return a1;
}

a2是1000000000,也就是说要循环1000000000次,难怪跑不完

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
_DWORD *__cdecl sub_A31000(_DWORD *a1, int a2){// 0, 1
v4 = -1;
v3 = -1 - a2 + 1; // -1
v6 = 1231;
v5 = a2 + 1231;//1232
while ( v3 ){// -1
++v6;
--*a1;
--v3;
--v5;
}
while ( v4 ){
--v5;
++*a1;
--v4;
}
++*a1;
return a1;
}

注意这里不要陷入思维定势,while()循环只要条件不为0就能运行,因此是负数也能运行

因此while(v3)会一直执行下去,因为一直–,while(v4)也会一直执行,v5这个变量好像完全没有用删掉。

然后最重要的一点来了,就是如果一直–的话,变量是有范围的,负数为它的补码表示,会有溢出现象产生,也就是说超过了这个范围负数就又会变成正数

例:

在此循环中,

1
2
3
4
5
int v5=-1, a=0
while(v5){
a--;
v5--;
}

a的二进制表示为:0x00000000, v5 的二进制表示为:0xFFFFFFFE,故当v5的值减到0时,即整个循环会运行0xFFFFFFFE次,故a的值要减去0xFFFFFFFE值,

比如:-1是FFFFFFFF,就是100000000 - 1。所以如果while(-1)就循环100000000 - 1次,这里while(-a2),就循环100000000 - a2次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
_DWORD *__cdecl sub_A31000(_DWORD *a1, int a2){// 0, 1
v4 = -1;
v3 = -1 - a2 + 1; // -1
v6 = 1231;
while ( v3 ){// -1
++v6;
--*a1;//循环100000000 - 1,也就是a1 = a1 - (100000000 - 1)
--v3;
}
while ( v4 ){
++*a1;// a1=a1 - (100000000 - a2)+(100000000 - 1) + 1 = a1 + a2 -1
--v4;
}
++*a1;// a1 + a2 -1 + 1 = a1 + a2
return a1;
}

只关注a1变化,这里实现了加法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
_DWORD *__cdecl sub_A31220(_DWORD *a1, int a2){
v4 = -1;
v3 = -1 - a2 + 1;
while ( v3 ){ // 循环100000000 - a2次
++*a1; // a1 = a1 + 100000000 - a2
--v3;
}
while ( v4 ){
++*a1;// a1 = a1 + 100000000 - a2 + 100000000 - 1
--v4;
}
++*a1; // a1 = a1 + 200000000 - a2 = a1 - a2
return a1;
}

因此在sub_A31100中是乘法

1
2
3
4
5
6
7
8
9
_DWORD *__cdecl sub_A31100(_DWORD *a1, int a2){
v8 = 0;
while ( a2 ){
sub_A31000(&v8, *a1);// 相加,1000000000次,就是乘法,a2*a1
--a2;
}
*a1 = v8;
return a1;
}

相减

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
_DWORD *__cdecl sub_A31000(_DWORD *a1, int a2){
v4 = -1;
v3 = -1 - a2 + 1;
v6 = 1231;
v5 = a2 + 1231;
while ( v3 ){
++v6;
--*a1;
--v3;
--v5;
}
while ( v4 ){
--v5;
++*a1;
--v4;
}
++*a1;
return a1;
}

C++代码抄过去写一遍就行

当然这里有一个小技巧,因为源代码中数组只有12位,剩下的被拆分了,右键

image-20241210110941740

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
#include <iostream>
#include <stdio.h>

using namespace std;
int sub_401100(int a, int b)
{
return a * b;
}
int sub_401000(int a, int b)
{
return a + b;
}
int sub_401220(int a, int b)
{
return a - b;
}

int __cdecl main()
{
int v3; // eax
int v4; // eax
int v5; // eax
int v6; // eax
int v7; // eax
int v8; // eax
int v9; // eax
int v10; // eax
int v11; // eax
int v12; // eax
int v13; // eax
int v14; // eax
int v15; // eax
int v16; // eax
int v17; // eax
int v18; // eax
int v19; // eax
int v20; // eax
int v21; // eax
int v22; // eax
int v23; // eax
int v24; // eax
int v25; // eax
int v26; // eax
int v27; // eax
int v28; // eax
int v29; // eax
int v30; // eax
int v31; // eax
int v32; // eax
int v33; // eax
int v34; // eax
int v35; // eax
int v36; // eax
int v37; // eax
int v38; // eax
int v39; // eax
int v40; // eax
int v41; // eax
int v42; // eax
int v43; // eax
int v44; // eax
int v45; // eax
int v46; // eax
int v47; // eax
int v48; // eax
int v49; // eax
int v50; // eax
int v51; // eax
int v52; // eax
int v53; // eax
int v54; // eax
int v55; // eax
int v56; // eax
int v57; // eax
int v58; // eax
int v59; // eax
int v60; // eax
int v61; // eax
int v62; // eax
int v63; // eax
int v64; // eax
int v65; // eax
int v66; // eax
int v67; // eax
int v68; // eax
int v69; // eax
int v70; // eax
int v71; // eax
int v72; // eax
int v73; // eax
int v74; // eax
int v75; // eax
int v76; // eax
int v77; // eax
int v78; // eax
int v79; // eax
int v80; // eax
int v81; // eax
int v82; // eax
int v83; // eax
int v84; // eax
int v85; // eax
int v86; // eax
int v87; // eax
int v88; // eax
int v89; // eax
int v90; // eax
int v91; // eax
int v92; // eax
int v93; // eax
int v94; // eax
int v95; // eax
int v96; // eax
int v97; // eax
int v98; // eax
int v99; // eax
int v100; // eax
int v101; // eax
int v102; // eax
int v103; // eax
int v104; // eax
int v105; // eax
int v106; // eax
int v107; // eax
int v108; // eax
int v109; // ST1C_4
int v110; // eax
int v111; // eax
int v112; // ST20_4
int v113; // eax
int v114; // eax
int v115; // ST20_4
int v116; // eax
signed int i; // [esp+4h] [ebp-90h]
signed int j; // [esp+8h] [ebp-8Ch]
int v120[32]; // [esp+Ch] [ebp-88h]
int v121; // [esp+8Ch] [ebp-8h]
for ( i = 0; i < 32; ++i ) v120[i] = 1;
v121 = 0;
puts("Your flag is:");
v3 = sub_401100(v120[0], 1000000000);
v4 = sub_401220(v3, 999999950);
v120[0] = sub_401100(v4, 2);

v5 = sub_401000(v120[1], 5000000);
v6 = sub_401220(v5, 6666666);
v7 = sub_401000(v6, 1666666);
v8 = sub_401000(v7, 45);
v9 = sub_401100(v8, 2);
v120[1] = sub_401000(v9, 5);
v10 = sub_401100(v120[2], 1000000000);
v11 = sub_401220(v10, 999999950);
v12 = sub_401100(v11, 2);
sub_401000(v12, 2);
v120[2] = sub_401000(v12, 2);
v13 = sub_401000(v120[3], 55);
v14 = sub_401220(v13, 3);
v15 = sub_401000(v14, 4);
sub_401220(v15, 1);
v120[3] = sub_401220(v15, 1);
v16 = sub_401100(v120[4], 100000000);
v17 = sub_401220(v16, 99999950);
v18 = sub_401100(v17, 2);
sub_401000(v18, 2);
v120[4] = sub_401000(v18, 2);
v19 = sub_401220(v120[5], 1);
v20 = sub_401100(v19, 1000000000);
v21 = sub_401000(v20, 55);
sub_401220(v21, 3);
v120[5] = sub_401220(v21, 3);
v22 = sub_401100(v120[6], 1000000);
v23 = sub_401220(v22, 999975);
v120[6] = sub_401100(v23, 4);
v24 = sub_401000(v120[7], 55);
v25 = sub_401220(v24, 33);
v26 = sub_401000(v25, 44);
sub_401220(v26, 11);
v120[7] = sub_401220(v26, 11);
v27 = sub_401100(v120[8], 10);
v28 = sub_401220(v27, 5);
v29 = sub_401100(v28, 8);
v120[8] = sub_401000(v29, 9);
v30 = sub_401000(v120[9], 0);
v31 = sub_401220(v30, 0);
v32 = sub_401000(v31, 11);
v33 = sub_401220(v32, 11);
sub_401000(v33, 53);
v120[9] = sub_401000(v33, 53);
v34 = sub_401000(v120[10], 49);
v35 = sub_401220(v34, 2);
v36 = sub_401000(v35, 4);
sub_401220(v36, 2);
v120[10] = sub_401220(v36, 2);
v37 = sub_401100(v120[11], 1000000);
v38 = sub_401220(v37, 999999);
v39 = sub_401100(v38, 4);
sub_401000(v39, 50);
v120[11] = sub_401000(v39, 50);
v40 = sub_401000(v120[12], 1);
v41 = sub_401000(v40, 1);
v42 = sub_401000(v41, 1);
v43 = sub_401000(v42, 1);
v44 = sub_401000(v43, 1);
v45 = sub_401000(v44, 1);
v46 = sub_401000(v45, 10);
sub_401000(v46, 32);
v120[12] = sub_401000(v46, 32);
v47 = sub_401100(v120[13], 10);
v48 = sub_401220(v47, 5);
v49 = sub_401100(v48, 8);
v50 = sub_401000(v49, 9);
sub_401000(v50, 48);
v120[13] = sub_401000(v50, 48);
v51 = sub_401220(v120[14], 1);
v52 = sub_401100(v51, -294967296);
v53 = sub_401000(v52, 55);
sub_401220(v53, 3);
v120[14] = sub_401220(v53, 3);
v54 = sub_401000(v120[15], 1);
v55 = sub_401000(v54, 2);
v56 = sub_401000(v55, 3);
v57 = sub_401000(v56, 4);
v58 = sub_401000(v57, 5);
v59 = sub_401000(v58, 6);
v60 = sub_401000(v59, 7);
sub_401000(v60, 20);
v120[15] = sub_401000(v60, 20);
v61 = sub_401100(v120[16], 10);
v62 = sub_401220(v61, 5);
v63 = sub_401100(v62, 8);
v64 = sub_401000(v63, 9);
v120[16] = sub_401000(v64, 48);
v65 = sub_401000(v120[17], 7);
v66 = sub_401000(v65, 6);
v67 = sub_401000(v66, 5);
v68 = sub_401000(v67, 4);
v69 = sub_401000(v68, 3);
v70 = sub_401000(v69, 2);
v71 = sub_401000(v70, 1);
sub_401000(v71, 20);
v120[17] = sub_401000(v71, 20);
v72 = sub_401000(v120[18], 7);
v73 = sub_401000(v72, 2);
v74 = sub_401000(v73, 4);
v75 = sub_401000(v74, 3);
v76 = sub_401000(v75, 6);
v77 = sub_401000(v76, 5);
v78 = sub_401000(v77, 1);
sub_401000(v78, 20);
v120[18] = sub_401000(v78, 20);
v79 = sub_401100(v120[19], 1000000);
v80 = sub_401220(v79, 999999);
v81 = sub_401100(v80, 4);
v82 = sub_401000(v81, 50);
sub_401220(v82, 1);
v120[19] = sub_401220(v82, 1);
v83 = sub_401220(v120[20], 1);
v84 = sub_401100(v83, -294967296);
v85 = sub_401000(v84, 49);
sub_401220(v85, 1);
v120[20] = sub_401220(v85, 1);
v86 = sub_401220(v120[21], 1);
v87 = sub_401100(v86, 1000000000);
v88 = sub_401000(v87, 54);
v89 = sub_401220(v88, 1);
v90 = sub_401000(v89, 1000000000);
sub_401220(v90, 1000000000);
v120[21] = sub_401220(v90, 1000000000);
v91 = sub_401000(v120[22], 49);
v92 = sub_401220(v91, 1);
v93 = sub_401000(v92, 2);
sub_401220(v93, 1);
v120[22] = sub_401220(v93, 1);
v94 = sub_401100(v120[23], 10);
v95 = sub_401220(v94, 5);
v96 = sub_401100(v95, 8);
v97 = sub_401000(v96, 9);
sub_401000(v97, 48);
v120[23] = sub_401000(v97, 48);
v98 = sub_401000(v120[24], 1);
v99 = sub_401000(v98, 3);
v100 = sub_401000(v99, 3);
v101 = sub_401000(v100, 3);
v102 = sub_401000(v101, 6);
v103 = sub_401000(v102, 6);
v104 = sub_401000(v103, 6);
sub_401000(v104, 20);
v120[24] = sub_401000(v104, 20);
v105 = sub_401000(v120[25], 55);
v106 = sub_401220(v105, 33);
v107 = sub_401000(v106, 44);
v108 = sub_401220(v107, 11);
v120[25] = sub_401000(v108, 42);
v120[26] = sub_401000(v120[26], v120[25]);
v120[27] = sub_401000(v120[27], v120[12]);
v109 = v120[27];
v110 = sub_401220(v120[28], 1);
v111 = sub_401000(v110, v109);
v120[28] = sub_401220(v111, 1);
v112 = v120[23];
v113 = sub_401220(v120[29], 1);
v114 = sub_401100(v113, 1000000);
v120[29] = sub_401000(v114, v112);
v115 = v120[27];
v116 = sub_401000(v120[30], 1);
v120[30] = sub_401100(v116, v115);
v120[31] = sub_401000(v120[31], v120[30]);
printf("CTF{");
for (j = 0; j < 32; ++j)
printf("%c", v120[j]);
printf("}\n");
return 0;
}

image-20241210111418097