-
-
[原创]KCTF2021 第二题 南冥神功 writeup
-
发表于: 2021-5-11 15:58 4373
-
拖进IDA中,直接看到main中所有逻辑,good
可以看出是个走迷宫的题:在9*10的迷宫内,1为墙,0为路,'S'是起点,一共有6(0-5)种前进方式,走过的路会变成墙。
成功条件是走过所有的路。
先把路径跑出来,果断dfs
跑出路径,输出操作方式opt: 1 2 3 4 3 2 1 2 3 4 3 2 1 1 0 1 2 1 0 0 5 0 5 4 3 4 5 0 5 0 1 2 1 0 1 2 1 2 3 4 3 2 2 3 2 1
每个输入字符可以生成两个操作方式v10
和v20
,且无后继影响,暴力解
Flag: GJ0V4LA4VKEVQZSVCNGJ00N
sub_40AD70();
sub_4AF840((
int
)&dword_4B8860,
"Input your code: "
);
sub_4B0AB0((
int
)&dword_4B8680, v25);
if
( strlen(v25) <
=
48
)
{
v3
=
v25[
0
];
if
( v25[
0
] )
{
v4
=
0
;
v21
=
0
;
v22
=
0
;
v24
=
dword_4B7020;
v23
=
byte_4B7040[
0
];
LABEL_4:
if
( v24 >
0
)
{
v5
=
0
;
if
( v23
=
=
v3 )
{
LABEL_11:
v7
=
(v4
+
v5
/
6
)
%
6
;
v8
=
v5
+
v4;
v9
=
v22;
v20
=
v7;
v10
=
5
-
v8
%
6
;
for
( i
=
0
; ; i
=
1
)
{
switch ( v10 )
/
/
地图上的操作,走到下一个位置
{
case
1
:
+
+
v9;
break
;
case
2
:
v17
=
(v21
+
+
&
1
)
=
=
0
;
v9
+
=
v17;
break
;
case
3
:
v12
=
(v21
+
+
&
1
) !
=
0
;
v9
-
=
v12;
break
;
case
4
:
-
-
v9;
break
;
case
5
:
v19
=
(v21
-
-
&
1
) !
=
0
;
v9
-
=
v19;
break
;
default:
v18
=
(v21
-
-
&
1
)
=
=
0
;
v9
+
=
v18;
break
;
}
if
( v9 >
9
)
break
;
if
( v21 >
8
)
break
;
v13
=
&aS_1[
10
*
v21
+
v9];
if
(
*
v13 )
break
;
*
v13
=
1
;
/
/
根据行列取地图位置,为
0
设置为
1
if
( i
=
=
1
)
{
+
+
v4;
v22
=
v9;
v3
=
v25[v4];
if
( v3 )
goto LABEL_4;
goto LABEL_19;
}
v10
=
v20;
}
}
else
{
while
( v24 !
=
+
+
v5 )
{
if
( byte_4B7040[v5]
=
=
v3 )
goto LABEL_11;
}
}
}
}
else
{
LABEL_19:
/
/
v15 统计地图上
0
的个数
v14
=
aS_1;
v15
=
0
;
do
{
v16
=
v14
+
10
;
do
v15
+
=
*
v14
+
+
=
=
0
;
while
( v16 !
=
v14 );
}
while
( &unk_4B70DA !
=
(_UNKNOWN
*
)v16 );
/
/
地图上不可有
0
if
( !v15 )
{
sub_4ABF30(&dword_4B8860,
"Good job!"
,
9
);
sub_4AD980(&dword_4B8860);
return
0
;
}
}
}
sub_4ABF30(&dword_4B8860,
"Try again..."
,
12
);
sub_4AD980(&dword_4B8860);
return
0
;
}
sub_40AD70();
sub_4AF840((
int
)&dword_4B8860,
"Input your code: "
);
sub_4B0AB0((
int
)&dword_4B8680, v25);
if
( strlen(v25) <
=
48
)
{
v3
=
v25[
0
];
if
( v25[
0
] )
{
v4
=
0
;
v21
=
0
;
v22
=
0
;
v24
=
dword_4B7020;
v23
=
byte_4B7040[
0
];
LABEL_4:
if
( v24 >
0
)
{
v5
=
0
;
if
( v23
=
=
v3 )
{
LABEL_11:
v7
=
(v4
+
v5
/
6
)
%
6
;
v8
=
v5
+
v4;
v9
=
v22;
v20
=
v7;
v10
=
5
-
v8
%
6
;
for
( i
=
0
; ; i
=
1
)
{
switch ( v10 )
/
/
地图上的操作,走到下一个位置
{
case
1
:
+
+
v9;
break
;
case
2
:
v17
=
(v21
+
+
&
1
)
=
=
0
;
v9
+
=
v17;
break
;
case
3
:
v12
=
(v21
+
+
&
1
) !
=
0
;
v9
-
=
v12;
break
;
case
4
:
-
-
v9;
break
;
case
5
:
v19
=
(v21
-
-
&
1
) !
=
0
;
v9
-
=
v19;
break
;
default:
v18
=
(v21
-
-
&
1
)
=
=
0
;
v9
+
=
v18;
break
;
}
if
( v9 >
9
)
break
;
if
( v21 >
8
)
break
;
v13
=
&aS_1[
10
*
v21
+
v9];
if
(
*
v13 )
break
;
*
v13
=
1
;
/
/
根据行列取地图位置,为
0
设置为
1
if
( i
=
=
1
)
{
+
+
v4;
v22
=
v9;
v3
=
v25[v4];
if
( v3 )
goto LABEL_4;
goto LABEL_19;
}
v10
=
v20;
}
}
else
{
while
( v24 !
=
+
+
v5 )
{
if
( byte_4B7040[v5]
=
=
v3 )
goto LABEL_11;
}
}
}
}
else
{
LABEL_19:
/
/
v15 统计地图上
0
的个数
v14
=
aS_1;
v15
=
0
;
do
{
v16
=
v14
+
10
;
do
v15
+
=
*
v14
+
+
=
=
0
;
while
( v16 !
=
v14 );
}
while
( &unk_4B70DA !
=
(_UNKNOWN
*
)v16 );
/
/
地图上不可有
0
if
( !v15 )
{
sub_4ABF30(&dword_4B8860,
"Good job!"
,
9
);
sub_4AD980(&dword_4B8860);
return
0
;
}
}
}
sub_4ABF30(&dword_4B8860,
"Try again..."
,
12
);
sub_4AD980(&dword_4B8860);
return
0
;
}
"S010010011"
,
"1100100100"
,
"0010111110"
,
"0110100100"
,
"0010010011"
,
"1101110101"
,
"0011110101"
,
"0110010101"
,
"0001001100"
"S010010011"
,
"1100100100"
,
"0010111110"
,
"0110100100"
,
"0010010011"
,
"1101110101"
,
"0011110101"
,
"0110010101"
,
"0001001100"
#include <iostream>
#include <stdio.h>
#include <string>
#include <stack>
#include <vector>
using namespace std;
string mp[]
=
{
"S010010011"
,
"1100100100"
,
"0010111110"
,
"0110100100"
,
"0010010011"
,
"1101110101"
,
"0011110101"
,
"0110010101"
,
"0001001100"
};
int
sum
=
0
;
stack<
int
> st;
void
print
()
{
stack<
int
> s;
while
(!st.empty())
{
s.push(st.top());
st.pop();
}
cout <<
"opt: "
;
while
(!s.empty())
{
cout << s.top() <<
" "
;
st.push(s.top());
s.pop();
}
cout << endl;
}
bool
opt(
int
o,
int
&x,
int
&y)
{
if
(o >
5
)
{
printf(
"error o"
);
return
false;
}
switch (o)
{
case
1
:
+
+
x;
break
;
case
2
:
x
+
=
(y
+
+
&
1
)
=
=
0
;
break
;
case
3
:
x
-
=
(y
+
+
&
1
) !
=
0
;
break
;
case
4
:
-
-
x;
break
;
case
5
:
x
-
=
(y
-
-
&
1
) !
=
0
;
break
;
default:
x
+
=
(y
-
-
&
1
)
=
=
0
;
break
;
}
if
(x >
9
|| x <
0
|| y <
0
|| y >
=
9
)
{
return
false;
}
return
mp[y][x]
=
=
'0'
;
}
bool
dfs(
int
x,
int
y)
{
if
(
sum
=
=
0
)
{
print
();
return
true;
}
for
(
int
i
=
0
; i <
6
; i
+
+
)
{
int
xt
=
x;
int
yt
=
y;
if
(opt(i, x, y))
{
st.push(i);
sum
-
-
;
mp[y][x]
=
'1'
;
if
(dfs(x, y))
return
true;
mp[y][x]
=
'0'
;
sum
+
+
;
st.pop();
}
x
=
xt;
y
=
yt;
}
return
false;
}
int
main()
{
for
(
int
i
=
0
; i <
9
; i
+
+
)
{
for
(char c : mp[i])
if
(c
=
=
'0'
)
sum
+
+
;
}
dfs(
0
,
0
);
for
(
int
i
=
0
; i <
9
; i
+
+
)
{
for
(char c : mp[i])
printf(
"%c"
,c);
printf(
"\n"
);
}
return
0
;
}
#include <iostream>
#include <stdio.h>
#include <string>
#include <stack>
#include <vector>
using namespace std;
string mp[]
=
{
"S010010011"
,
"1100100100"
,
"0010111110"
,
"0110100100"
,
"0010010011"
,
"1101110101"
,
"0011110101"
,
"0110010101"
,
"0001001100"
};
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-5-11 16:30
被Wblank编辑
,原因:
赞赏
他的文章
看原图
赞赏
雪币:
留言: