-
-
[原创] 南冥神功 writeup
-
发表于: 2021-5-11 20:03 4610
-
先拖到IDA里分析,当看到字符S后边跟了一堆01的时候就猜到是迷宫了,结合main函数里边的逻辑基本就可以判断是走迷宫了。这里我把main函数加了一些注释可以很清晰看出来迷宫的规则,迷宫是一个9*10的二维数组,S(0x53)是起点,0是路,1是墙。走过的路会被置为1,然后再最后程序会判断数组内所有的值,只要所有的值都为1就成功了。代码逻辑如下:
迷宫如下:
根据这个迷宫的行走规则可以规划出如下路线:
最终flag的每一位可以走两步,计算的公式如下所示:
最终写出了如下计算flag的程序:
最终编译运行即可得到flag
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char pinput;
/
/
al
int
index_input;
/
/
esi
int
index_key;
/
/
ecx
int
check2;
/
/
edx
int
v8;
/
/
eax
unsigned
int
pos_x;
/
/
ecx
int
check1;
/
/
eax
signed
int
v11;
/
/
edx
int
v12;
/
/
eax
char
*
pmaze;
/
/
eax
char (
*
v14)[
10
];
/
/
eax
int
v15;
/
/
edx
char (
*
v16)[
10
];
/
/
ecx
int
v17;
/
/
eax
int
v18;
/
/
eax
int
v19;
/
/
eax
int
v20;
/
/
[esp
+
1Ch
] [ebp
-
60h
]
unsigned
int
pos_y;
/
/
[esp
+
20h
] [ebp
-
5Ch
]
unsigned
int
v22;
/
/
[esp
+
24h
] [ebp
-
58h
]
char pkey;
/
/
[esp
+
2Bh
] [ebp
-
51h
]
int
keylength;
/
/
[esp
+
2Ch
] [ebp
-
50h
]
char
input
[
76
];
/
/
[esp
+
30h
] [ebp
-
4Ch
]
sub_40AD70();
sub_4AF840((
int
)&dword_4B8860,
"Input your code: "
);
sub_4B0AB0((
int
)&dword_4B8680,
input
);
if
( strlen(
input
) <
=
48
)
{
pinput
=
input
[
0
];
if
(
input
[
0
] )
{
index_input
=
0
;
pos_y
=
0
;
v22
=
0
;
keylength
=
keylen;
pkey
=
key[
0
];
LABEL_4:
if
( keylength >
0
)
{
index_key
=
0
;
if
( pkey
=
=
pinput )
{
LABEL_11:
check2
=
(index_input
+
index_key
/
6
)
%
6
;
v8
=
index_key
+
index_input;
pos_x
=
v22;
v20
=
check2;
check1
=
5
-
v8
%
6
;
v11
=
0
;
while
(
1
)
{
switch ( check1 )
{
case
1
:
/
/
向右走
+
+
pos_x;
break
;
case
2
:
/
/
偶数行向右下走,奇数行向下走
v17
=
(pos_y
+
+
&
1
)
=
=
0
;
pos_x
+
=
v17;
break
;
case
3
:
/
/
奇数行向左下走,偶数行向下走
v12
=
(pos_y
+
+
&
1
) !
=
0
;
pos_x
-
=
v12;
break
;
case
4
:
/
/
向左走
-
-
pos_x;
break
;
case
5
:
/
/
奇数行向左上走,偶数行向上走
v19
=
(pos_y
-
-
&
1
) !
=
0
;
pos_x
-
=
v19;
break
;
default:
/
/
偶数行向右上走,奇数行向上走
v18
=
(pos_y
-
-
&
1
)
=
=
0
;
pos_x
+
=
v18;
break
;
}
if
( pos_x >
9
)
break
;
if
( pos_y >
8
)
break
;
pmaze
=
&maze[pos_y][pos_x];
if
(
*
pmaze )
/
/
判断是否撞墙,
0
是路,
1
是墙
break
;
*
pmaze
=
1
;
if
( v11
=
=
1
)
{
+
+
index_input;
v22
=
pos_x;
pinput
=
input
[index_input];
if
( pinput )
goto LABEL_4;
goto LABEL_19;
}
v11
=
1
;
check1
=
v20;
}
}
else
{
while
( keylength !
=
+
+
index_key )
{
if
( key[index_key]
=
=
pinput )
goto LABEL_11;
}
}
}
}
else
{
LABEL_19:
/
/
遍历迷宫数组,判断所有位置的值是否都为
1
v14
=
maze;
v15
=
0
;
do
{
v16
=
v14
+
1
;
do
{
v15
+
=
*
(_BYTE
*
)v14 <
1u
;
v14
=
(char (
*
)[
10
])((char
*
)v14
+
1
);
}
while
( v16 !
=
v14 );
}
while
( &End !
=
(_UNKNOWN
*
)v16 );
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
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char pinput;
/
/
al
int
index_input;
/
/
esi
int
index_key;
/
/
ecx
int
check2;
/
/
edx
int
v8;
/
/
eax
unsigned
int
pos_x;
/
/
ecx
int
check1;
/
/
eax
signed
int
v11;
/
/
edx
int
v12;
/
/
eax
char
*
pmaze;
/
/
eax
char (
*
v14)[
10
];
/
/
eax
int
v15;
/
/
edx
char (
*
v16)[
10
];
/
/
ecx
int
v17;
/
/
eax
int
v18;
/
/
eax
int
v19;
/
/
eax
int
v20;
/
/
[esp
+
1Ch
] [ebp
-
60h
]
unsigned
int
pos_y;
/
/
[esp
+
20h
] [ebp
-
5Ch
]
unsigned
int
v22;
/
/
[esp
+
24h
] [ebp
-
58h
]
char pkey;
/
/
[esp
+
2Bh
] [ebp
-
51h
]
int
keylength;
/
/
[esp
+
2Ch
] [ebp
-
50h
]
char
input
[
76
];
/
/
[esp
+
30h
] [ebp
-
4Ch
]
sub_40AD70();
sub_4AF840((
int
)&dword_4B8860,
"Input your code: "
);
sub_4B0AB0((
int
)&dword_4B8680,
input
);
if
( strlen(
input
) <
=
48
)
{
pinput
=
input
[
0
];
if
(
input
[
0
] )
{
index_input
=
0
;
pos_y
=
0
;
v22
=
0
;
keylength
=
keylen;
pkey
=
key[
0
];
LABEL_4:
if
( keylength >
0
)
{
index_key
=
0
;
if
( pkey
=
=
pinput )
{
LABEL_11:
check2
=
(index_input
+
index_key
/
6
)
%
6
;
v8
=
index_key
+
index_input;
pos_x
=
v22;
v20
=
check2;
check1
=
5
-
v8
%
6
;
v11
=
0
;
while
(
1
)
{
switch ( check1 )
{
case
1
:
/
/
向右走
+
+
pos_x;
break
;
case
2
:
/
/
偶数行向右下走,奇数行向下走
v17
=
(pos_y
+
+
&
1
)
=
=
0
;
pos_x
+
=
v17;
break
;
case
3
:
/
/
奇数行向左下走,偶数行向下走
v12
=
(pos_y
+
+
&
1
) !
=
0
;
pos_x
-
=
v12;
break
;
case
4
:
/
/
向左走
-
-
pos_x;
break
;
case
5
:
/
/
奇数行向左上走,偶数行向上走
v19
=
(pos_y
-
-
&
1
) !
=
0
;
pos_x
-
=
v19;
break
;
default:
/
/
偶数行向右上走,奇数行向上走
v18
=
(pos_y
-
-
&
1
)
=
=
0
;
pos_x
+
=
v18;
break
;
}
if
( pos_x >
9
)
break
;
if
( pos_y >
8
)
break
;
pmaze
=
&maze[pos_y][pos_x];
if
(
*
pmaze )
/
/
判断是否撞墙,
0
是路,
1
是墙
break
;
*
pmaze
=
1
;
if
( v11
=
=
1
)
{
+
+
index_input;
v22
=
pos_x;
pinput
=
input
[index_input];
if
( pinput )
goto LABEL_4;
goto LABEL_19;
}
v11
=
1
;
check1
=
v20;
}
}
else
{
while
( keylength !
=
+
+
index_key )
{
if
( key[index_key]
=
=
pinput )
goto LABEL_11;
}
}
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [原创] 南冥神功 writeup 4611
- [原创] 签到题writeup 2095
- [建议] 关于过去CTF比赛的赛题。 12567
- [原创] 半加器解题过程 3157
- [建议] 论坛上传图片功能后缀名检查不区分大小写 7131
看原图
赞赏
雪币:
留言: