-
-
[原创]KCTF2020 第二题 异常信号 WriteUp
-
发表于: 2020-11-20 02:05 4397
-
肝了个一血出来哈哈哈
直接运行,然后x32dbg附加,注意开启sharpod的anti anti attach,然后ollydumpex,点search image,选择module、binary(virtual),dump下来,用ida打开,定位到sub_2F12B0函数
遇到30xxxx的地址,从x32dbg里查看到底是啥内容
解密脚本:
list中的值要满足的条件是:从[0,89]中选择12个互不相同的数,使它们任意两个数之差都不相同,这里我问了4位ACM金牌爷,2个多小时后有人把结果弄出来了
程序执行的思路就是,读入至多360个字符,只能0-9、A-F,把每4个输入组合成一个类似0x1234这样的short,如果与v31一样,则把下标加入v39队列,如果与v35一样,则继续,如果都不一样,则结束程序。如果v39的元素小于12则结束程序。之后会判断v39里面的数(也就是满足v31的输入的下标)是否两两之差唯一,是的话就输出Correct。
生成v31和v35的算法是可以本地写代码跑出来的,只要输入的满足“下标不在list里的输入等于v35,否则等于v31”的就是flag
补充金牌爷算法:
注意,这段代码能跑出多组解,但是其余解不满足程序的要求,会输出“穿越虫洞要讲究顺序”,因此上面那组解应该是唯一满足题目限制的解
int
sub_2F12B0()
{
int
v0;
/
/
esi
char v1;
/
/
al
char
*
v2;
/
/
ecx
unsigned __int8
*
v3;
/
/
ecx
unsigned __int8 v4;
/
/
al
signed
int
v5;
/
/
eax
signed
int
v6;
/
/
ecx
signed
int
length;
/
/
ebx
unsigned __int8 v8;
/
/
al
char v9;
/
/
al
signed
int
v10;
/
/
edx
int
v11;
/
/
esi
char v12;
/
/
cl
char v13;
/
/
al
char v14;
/
/
cl
signed
int
v15;
/
/
eax
__int16 v16;
/
/
ax
signed
int
half_len;
/
/
ebx
int
v18;
/
/
edi
int
v19;
/
/
ecx
signed
int
v20;
/
/
esi
signed
int
v21;
/
/
esi
int
v22;
/
/
eax
int
v23;
/
/
eax
__int16 v24;
/
/
ax
int
v25;
/
/
esi
int
v26;
/
/
eax
int
v27;
/
/
ecx
int
v28;
/
/
edx
int
v29;
/
/
eax
__int16 v31;
/
/
[esp
+
Ch] [ebp
-
514h
]
int
v32;
/
/
[esp
+
10h
] [ebp
-
510h
]
int
v33;
/
/
[esp
+
14h
] [ebp
-
50Ch
]
unsigned __int16 v34;
/
/
[esp
+
18h
] [ebp
-
508h
]
__int16 v35;
/
/
[esp
+
18h
] [ebp
-
508h
]
int
v36;
/
/
[esp
+
1Ch
] [ebp
-
504h
]
int
v37;
/
/
[esp
+
20h
] [ebp
-
500h
]
unsigned __int8
input
;
/
/
[esp
+
23h
] [ebp
-
4FDh
]
int
v39[
100
];
/
/
[esp
+
24h
] [ebp
-
4FCh
]
char flag[
400
];
/
/
[esp
+
1B4h
] [ebp
-
36Ch
]
char table[
256
];
/
/
[esp
+
344h
] [ebp
-
1DCh
]
__int16 dest[
50
];
/
/
[esp
+
444h
] [ebp
-
DCh]
char v43[
100
];
/
/
[esp
+
4A8h
] [ebp
-
78h
]
char v44;
/
/
[esp
+
50Ch
] [ebp
-
14h
]
int
v45;
/
/
[esp
+
50Dh
] [ebp
-
13h
]
int
v46;
/
/
[esp
+
511h
] [ebp
-
Fh]
int
v47;
/
/
[esp
+
515h
] [ebp
-
Bh]
__int16 v48;
/
/
[esp
+
519h
] [ebp
-
7h
]
v0
=
*
(_DWORD
*
)&unk_314474;
memset(
*
(_DWORD
*
)&unk_314474,
0
,
256
);
v1
=
*
(_BYTE
*
)&unk_3138B0;
if
(
*
(_BYTE
*
)&unk_3138B0 )
{
v2
=
(_BYTE
*
)&unk_3138B0;
do
{
*
(
+
+
v2
-
1
)
=
v1 ^
0xE4
;
v1
=
*
v2;
}
while
(
*
v2 );
}
sub_2F5D70(v0,
0x3138B0
, strlen((const char
*
)&unk_3138B0)
+
1
);
/
/
Correct
v45
=
0x9091948A
;
v46
=
0x9681B7C4
;
v3
=
(unsigned __int8
*
)&v44;
v47
=
0xDE88858D
;
v4
=
0xADu
;
v48
=
0xEE
;
do
{
*
(
+
+
v3
-
1
)
=
v4 ^
0xE4
;
v4
=
*
v3;
}
while
(
*
v3 );
/
/
Input
Serial:\n
v36
=
*
*
(_DWORD
*
*
)(
*
(_DWORD
*
)(
*
(_DWORD
*
)&unk_314478
+
0x3C
)
+
*
(_DWORD
*
)&unk_314478
+
0x28
);
printf(&v44);
memset(v39,
0
,
400
);
memset(dest,
0
,
200
);
memset(flag,
255
,
400
);
memset(table,
255
,
256
);
v5
=
0
;
do
{
table[v5
+
'0'
]
=
v5;
+
+
v5;
}
while
( v5 <
=
9
);
v6
=
0
;
do
{
table[v6
+
'A'
]
=
v6
+
10
;
+
+
v6;
}
while
( v6 <
=
5
);
input
=
0
;
length
=
0
;
scanf(
0x310CDC
, &
input
,
1
);
/
/
%
c
v8
=
input
;
if
(
input
!
=
10
)
{
while
( length <
360
)
{
v9
=
table[v8];
if
( v9
=
=
-
1
)
{
LABEL_52:
printf(
0x310C6C
);
printf(
0x310C80
);
/
/
一个礼貌的开场白还是要的
return
0
;
}
flag[length
+
+
]
=
v9;
scanf(
0x310CDC
, &
input
,
1
);
/
/
%
c
v8
=
input
;
if
(
input
=
=
'\n'
)
goto LABEL_14;
}
LABEL_32:
printf(
0x310C6C
);
printf(
0x310C70
);
/
/
\f换页
return
0
;
}
LABEL_14:
v10
=
0
;
if
( length >
0
)
{
v11
=
*
(_DWORD
*
)&unk_31446C;
while
( v11 )
{
v12
=
flag[v10];
if
( v12
=
=
-
1
)
goto LABEL_52;
v13
=
flag[v10
+
1
];
if
( v13
=
=
-
1
)
goto LABEL_52;
v14
=
v13
+
16
*
v12;
v15
=
v10 >>
1
;
v10
+
=
2
;
*
((_BYTE
*
)dest
+
v15)
=
v14;
/
/
4
个输入构成一个int16
if
( v10 >
=
length )
goto LABEL_20;
}
goto LABEL_32;
}
LABEL_20:
v16
=
0
;
half_len
=
length >>
2
;
v18
=
0
;
v33
=
0
;
if
( half_len <
=
0
)
goto LABEL_57;
v19
=
0
;
v32
=
0
;
do
{
v34
=
-
v16;
sub_2F6305(v19);
v20
=
0x65
;
do
{
v31
=
sub_2F62E4();
-
-
v20;
}
while
( v20 );
sub_2F6305(v34);
v21
=
0x65
;
do
{
v35
=
sub_2F62E4();
-
-
v21;
}
while
( v21 );
v22
=
(
*
(
int
(__stdcall
*
*
)(_DWORD))&unk_30B144)(
0
);
/
/
GetActiveWindow(
0
)
if
( v22 )
{
v23
=
(
*
(
int
(__stdcall
*
*
)(
int
))&unk_30B148)(v22);
/
/
GetWindowLongA(v22,GWL_STYLE)
if
( v23
=
=
0x17CF0000
|| v23
=
=
0x16CF0000
|| v23
=
=
0x97CF0000
)
goto LABEL_51;
}
v24
=
dest[v32];
/
/
v32是满足条件v31的输入的index
if
( v31
=
=
v24 )
{
v39[v18
+
+
]
=
v32;
/
/
将满足条件的index入队
}
else
if
( v35 !
=
v24 )
{
goto LABEL_52;
}
v16
=
v33
+
+
+
1
;
v19
=
(unsigned __int16)v33;
v32
=
(unsigned __int16)v33;
}
while
( (unsigned __int16)v33 < half_len );
if
( v18 <
12
)
{
LABEL_57:
printf(
0x310C6C
);
printf(
0x310C9C
);
/
/
行星太少了
return
0
;
}
if
( v39[
1
]
-
v39[
0
] >
*
(&v37
+
v18)
-
*
(&v36
+
v18) )
{
printf(
0x310C6C
);
printf(
0x310CA8
);
/
/
穿越虫洞还得讲个顺序
return
0
;
}
memset(v43,
0
,
100
);
v25
=
0
;
if
( v18
-
1
<
=
0
)
{
LABEL_49:
if
( !
*
(_DWORD
*
)&unk_314470 )
return
0
;
printf(
*
(_DWORD
*
)&unk_314474);
/
/
Correct
return
0
;
}
v26
=
v36;
while
(
1
)
{
if
( !v26 )
{
printf(
0x310C6C
);
printf(
0x310C80
);
/
/
一个礼貌的开场白还是要的
LABEL_47:
v26
=
v36;
goto LABEL_48;
}
v27
=
v25
+
1
;
if
( v25
+
1
< v18 )
break
;
LABEL_48:
if
(
+
+
v25 >
=
v18
-
1
)
goto LABEL_49;
}
v28
=
v39[v25];
while
(
1
)
{
v29
=
v39[v27]
-
v28;
/
/
v29每次必须不一样
if
( v43[v29] )
/
/
队列中的indexes,两两的差必须唯一
break
;
+
+
v27;
v43[v29]
=
1
;
if
( v27 >
=
v18 )
goto LABEL_47;
}
LABEL_51:
printf(
0x310C6C
);
printf(
0x310CC0
);
/
/
有人说这题根本无解,你信吗
return
0
;
}
int
sub_2F12B0()
{
int
v0;
/
/
esi
char v1;
/
/
al
char
*
v2;
/
/
ecx
unsigned __int8
*
v3;
/
/
ecx
unsigned __int8 v4;
/
/
al
signed
int
v5;
/
/
eax
signed
int
v6;
/
/
ecx
signed
int
length;
/
/
ebx
unsigned __int8 v8;
/
/
al
char v9;
/
/
al
signed
int
v10;
/
/
edx
int
v11;
/
/
esi
char v12;
/
/
cl
char v13;
/
/
al
char v14;
/
/
cl
signed
int
v15;
/
/
eax
__int16 v16;
/
/
ax
signed
int
half_len;
/
/
ebx
int
v18;
/
/
edi
int
v19;
/
/
ecx
signed
int
v20;
/
/
esi
signed
int
v21;
/
/
esi
int
v22;
/
/
eax
int
v23;
/
/
eax
__int16 v24;
/
/
ax
int
v25;
/
/
esi
int
v26;
/
/
eax
int
v27;
/
/
ecx
int
v28;
/
/
edx
int
v29;
/
/
eax
__int16 v31;
/
/
[esp
+
Ch] [ebp
-
514h
]
int
v32;
/
/
[esp
+
10h
] [ebp
-
510h
]
int
v33;
/
/
[esp
+
14h
] [ebp
-
50Ch
]
unsigned __int16 v34;
/
/
[esp
+
18h
] [ebp
-
508h
]
__int16 v35;
/
/
[esp
+
18h
] [ebp
-
508h
]
int
v36;
/
/
[esp
+
1Ch
] [ebp
-
504h
]
int
v37;
/
/
[esp
+
20h
] [ebp
-
500h
]
unsigned __int8
input
;
/
/
[esp
+
23h
] [ebp
-
4FDh
]
int
v39[
100
];
/
/
[esp
+
24h
] [ebp
-
4FCh
]
char flag[
400
];
/
/
[esp
+
1B4h
] [ebp
-
36Ch
]
char table[
256
];
/
/
[esp
+
344h
] [ebp
-
1DCh
]
__int16 dest[
50
];
/
/
[esp
+
444h
] [ebp
-
DCh]
char v43[
100
];
/
/
[esp
+
4A8h
] [ebp
-
78h
]
char v44;
/
/
[esp
+
50Ch
] [ebp
-
14h
]
int
v45;
/
/
[esp
+
50Dh
] [ebp
-
13h
]
int
v46;
/
/
[esp
+
511h
] [ebp
-
Fh]
int
v47;
/
/
[esp
+
515h
] [ebp
-
Bh]
__int16 v48;
/
/
[esp
+
519h
] [ebp
-
7h
]
v0
=
*
(_DWORD
*
)&unk_314474;
memset(
*
(_DWORD
*
)&unk_314474,
0
,
256
);
v1
=
*
(_BYTE
*
)&unk_3138B0;
if
(
*
(_BYTE
*
)&unk_3138B0 )
{
v2
=
(_BYTE
*
)&unk_3138B0;
do
{
*
(
+
+
v2
-
1
)
=
v1 ^
0xE4
;
v1
=
*
v2;
}
while
(
*
v2 );
}
sub_2F5D70(v0,
0x3138B0
, strlen((const char
*
)&unk_3138B0)
+
1
);
/
/
Correct
v45
=
0x9091948A
;
v46
=
0x9681B7C4
;
v3
=
(unsigned __int8
*
)&v44;
v47
=
0xDE88858D
;
v4
=
0xADu
;
v48
=
0xEE
;
do
{
*
(
+
+
v3
-
1
)
=
v4 ^
0xE4
;
v4
=
*
v3;
}
while
(
*
v3 );
/
/
Input
Serial:\n
v36
=
*
*
(_DWORD
*
*
)(
*
(_DWORD
*
)(
*
(_DWORD
*
)&unk_314478
+
0x3C
)
+
*
(_DWORD
*
)&unk_314478
+
0x28
);
printf(&v44);
memset(v39,
0
,
400
);
memset(dest,
0
,
200
);
memset(flag,
255
,
400
);
memset(table,
255
,
256
);
v5
=
0
;
do
{
table[v5
+
'0'
]
=
v5;
+
+
v5;
}
while
( v5 <
=
9
);
v6
=
0
;
do
{
table[v6
+
'A'
]
=
v6
+
10
;
+
+
v6;
}
while
( v6 <
=
5
);
input
=
0
;
length
=
0
;
scanf(
0x310CDC
, &
input
,
1
);
/
/
%
c
v8
=
input
;
if
(
input
!
=
10
)
{
while
( length <
360
)
{
v9
=
table[v8];
if
( v9
=
=
-
1
)
{
LABEL_52:
printf(
0x310C6C
);
printf(
0x310C80
);
/
/
一个礼貌的开场白还是要的
return
0
;
}
flag[length
+
+
]
=
v9;
scanf(
0x310CDC
, &
input
,
1
);
/
/
%
c
v8
=
input
;
if
(
input
=
=
'\n'
)
goto LABEL_14;
}
LABEL_32:
printf(
0x310C6C
);
printf(
0x310C70
);
/
/
\f换页
return
0
;
}
LABEL_14:
v10
=
0
;
if
( length >
0
)
{
v11
=
*
(_DWORD
*
)&unk_31446C;
while
( v11 )
{
v12
=
flag[v10];
if
( v12
=
=
-
1
)
goto LABEL_52;
v13
=
flag[v10
+
1
];
if
( v13
=
=
-
1
)
goto LABEL_52;
v14
=
v13
+
16
*
v12;
v15
=
v10 >>
1
;
v10
+
=
2
;
*
((_BYTE
*
)dest
+
v15)
=
v14;
/
/
4
个输入构成一个int16
if
( v10 >
=
length )
goto LABEL_20;
}
goto LABEL_32;
}
LABEL_20:
v16
=
0
;
half_len
=
length >>
2
;
v18
=
0
;
v33
=
0
;
if
( half_len <
=
0
)
goto LABEL_57;
v19
=
0
;
v32
=
0
;
do
{
v34
=
-
v16;
sub_2F6305(v19);
v20
=
0x65
;
do
{
v31
=
sub_2F62E4();
-
-
v20;
}
while
( v20 );
sub_2F6305(v34);
v21
=
0x65
;
do
{
v35
=
sub_2F62E4();
-
-
v21;
}
while
( v21 );
v22
=
(
*
(
int
(__stdcall
*
*
)(_DWORD))&unk_30B144)(
0
);
/
/
GetActiveWindow(
0
)
if
( v22 )
{
v23
=
(
*
(
int
(__stdcall
*
*
)(
int
))&unk_30B148)(v22);
/
/
GetWindowLongA(v22,GWL_STYLE)
if
( v23
=
=
0x17CF0000
|| v23
=
=
0x16CF0000
|| v23
=
=
0x97CF0000
)
goto LABEL_51;
}
v24
=
dest[v32];
/
/
v32是满足条件v31的输入的index
if
( v31
=
=
v24 )
{
v39[v18
+
+
]
=
v32;
/
/
将满足条件的index入队
}
else
if
( v35 !
=
v24 )
{
goto LABEL_52;
}
v16
=
v33
+
+
+
1
;
v19
=
(unsigned __int16)v33;
v32
=
(unsigned __int16)v33;
}
while
( (unsigned __int16)v33 < half_len );
if
( v18 <
12
)
{
LABEL_57:
printf(
0x310C6C
);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2020-11-20 20:24
被古月浪子编辑
,原因: 补充求解算法
赞赏
他的文章
看原图
赞赏
雪币:
留言: