-
-
[原创] 第二题 南冥神功题解
-
发表于: 2021-5-11 21:46 4925
-
使用ida打开pzcrackme.exe, 跳转到主函数F5, 首先看到输入, 将其重命名为input;
之后进入循环:
主体逻辑是循环找到a0123456789abcd字符串中输入字符所在的位置keypos之后进入下面的逻辑, 分析见注释:
之后是验证:
所以就是要走迷宫把迷宫走成全是1的.
因为并没有分析它的一系列初始化函数, 怕哪里藏了坑然后静态的数据其实是骗你的, 所以接下来进行动态调试, 也为了绕过可能存在的反ida的调试措施(后来发现并没有) 所以使用frida进行动态调试.
根据分析结果写个frida agent脚本 (使用了typescript):
运行后输出如下:
起始在左上角, 可以自由向左右上下走, (从0开始算)在偶数行可以向右上或右下走, 在奇数行可以向左上或左下走, 可以手走一遍出结果, 为: convertInput("1234321234321101210050543450501210121234322321")
将其输出出来, 最后flag是GJ0V4LA4VKEVQZSVCNGJ00N
if
( strlen(
input
) <
=
0x30
)
{
inpc
=
input
[
0
];
if
(
input
[
0
] )
{
ipos
=
0
;
y
=
0
;
tx
=
0
;
length
=
dword_4B7020;
keyc
=
a0123456789abcd[
0
];
next
:
if
( length >
0
)
{
keypos
=
0
;
if
( keyc
=
=
inpc )
{
LABEL_11:
...(此处暂时省略)
}
else
{
while
( length !
=
+
+
keypos )
{
if
( a0123456789abcd[keypos]
=
=
inpc )
goto LABEL_11;
}
}
}
}
if
( strlen(
input
) <
=
0x30
)
{
inpc
=
input
[
0
];
if
(
input
[
0
] )
{
ipos
=
0
;
y
=
0
;
tx
=
0
;
length
=
dword_4B7020;
keyc
=
a0123456789abcd[
0
];
next
:
if
( length >
0
)
{
keypos
=
0
;
if
( keyc
=
=
inpc )
{
LABEL_11:
...(此处暂时省略)
}
else
{
while
( length !
=
+
+
keypos )
{
if
( a0123456789abcd[keypos]
=
=
inpc )
goto LABEL_11;
}
}
}
}
LABEL_11:
v7
=
(ipos
+
keypos
/
6
)
%
6
;
v8
=
keypos
+
ipos;
x
=
tx;
inp2
=
v7;
inp1
=
5
-
v8
%
6
;
/
/
将keypos
+
ipos 按
6
进制分解为inp1和inp2
for
( i
=
0
; ; i
=
1
)
{
switch ( inp1 )
/
/
然后走迷宫
{
case
1
:
+
+
x;
/
/
右
break
;
case
2
:
v17
=
(y
+
+
&
1
)
=
=
0
;
/
/
偶行 右下 奇行 下
x
+
=
v17;
break
;
case
3
:
v12
=
(y
+
+
&
1
) !
=
0
;
/
/
偶行 下 奇行 左下
x
-
=
v12;
break
;
case
4
:
-
-
x;
/
/
左
break
;
case
5
:
v19
=
(y
-
-
&
1
) !
=
0
;
/
/
偶行 上 奇行 左上
x
-
=
v19;
break
;
default:
/
/
偶行 右上 奇行 上
v18
=
(y
-
-
&
1
)
=
=
0
;
x
+
=
v18;
break
;
}
if
( x >
9
)
/
/
迷宫有
10
列
break
;
if
( y >
8
)
/
/
迷宫有
9
行
break
;
v13
=
&byte_4B7080[
10
*
y
+
x];
/
/
迷宫数据在byte_4B7080
if
(
*
v13 )
break
;
*
v13
=
1
;
/
/
只能走在数据为
0
的格子, 走过的位置设为
1
if
( i
=
=
1
)
{
+
+
ipos;
tx
=
x;
inpc
=
input
[ipos];
if
( inpc )
goto
next
;
goto fin;
}
inp1
=
inp2;
LABEL_11:
v7
=
(ipos
+
keypos
/
6
)
%
6
;
v8
=
keypos
+
ipos;
x
=
tx;
inp2
=
v7;
inp1
=
5
-
v8
%
6
;
/
/
将keypos
+
ipos 按
6
进制分解为inp1和inp2
for
( i
=
0
; ; i
=
1
)
{
switch ( inp1 )
/
/
然后走迷宫
{
case
1
:
+
+
x;
/
/
右
break
;
case
2
:
v17
=
(y
+
+
&
1
)
=
=
0
;
/
/
偶行 右下 奇行 下
x
+
=
v17;
break
;
case
3
:
v12
=
(y
+
+
&
1
) !
=
0
;
/
/
偶行 下 奇行 左下
x
-
=
v12;
break
;
case
4
:
-
-
x;
/
/
左
break
;
case
5
:
v19
=
(y
-
-
&
1
) !
=
0
;
/
/
偶行 上 奇行 左上
x
-
=
v19;
break
;
default:
/
/
偶行 右上 奇行 上
v18
=
(y
-
-
&
1
)
=
=
0
;
x
+
=
v18;
break
;
}
if
( x >
9
)
/
/
迷宫有
10
列
break
;
if
( y >
8
)
/
/
迷宫有
9
行
break
;
v13
=
&byte_4B7080[
10
*
y
+
x];
/
/
迷宫数据在byte_4B7080
if
(
*
v13 )
break
;
*
v13
=
1
;
/
/
只能走在数据为
0
的格子, 走过的位置设为
1
if
( i
=
=
1
)
{
+
+
ipos;
tx
=
x;
inpc
=
input
[ipos];
if
( inpc )
goto
next
;
goto fin;
}
inp1
=
inp2;
v14
=
byte_4B7080;
/
/
迷宫数据
v15
=
0
;
do
{
v16
=
v14
+
0xA
;
do
v15
+
=
*
v14
+
+
=
=
0
;
/
/
如果迷宫数据中任意位是
0
则v15会增加
while
( v16 !
=
v14 );
}
while
( &unk_4B70DA !
=
(_UNKNOWN
*
)v16 );
if
( !v15 )
/
/
当v15没有增加时 成功
{
sub_4ABF30(&dword_4B8860,
"Good job!"
,
9
);
sub_4AD980(&dword_4B8860);
return
0
;
}
v14
=
byte_4B7080;
/
/
迷宫数据
v15
=
0
;
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
看原图
赞赏
雪币:
留言: