Snert-2018春季淘汰赛Reverse WriteUp

Author Avatar
kabeor 3月 18, 2018

RE100

这题越看越熟悉,原来做过,i春秋的那篇wp就是我写的hhh

链接 第三届上海市大学生网络安全大赛crackme

RE500

查壳

无壳
mark

IDA反编译

运行发现,随意输入会弹出fail,此题应该是算法题,于是拖入IDA,shift+F12搜索字符串fail
mark
只有一个,于是跟进去
mark
发现这里就是主要算法部分了

算法分析

这个程序的伪代码竟然是标准的C++

我们可以明显注意到名称空间Sudu
mark

黄标可以看出有三个函数,分别是

Sudu::Sudu
Sudu::set_data
Sudu::check

根据他们的位置判断,这些就是主要函数了

Sudu::Sudu方法

进入后看到,这里是用来初始化的,把所有字符初始化为零
mark

Sudu::set_data方法

mark
这里明显是创建一个9x9的表,然后把this中的数字按顺序填进去
this就是外面的_data_start__
mark
里面数字具体如下(太长了,只截取一部分)
mark
按序填入后如下

0 0 7 5 0 0 0 6 0
0 2 0 0 1 0 0 0 7
9 0 0 0 3 0 4 0 0
2 0 1 0 0 0 0 0 0
0 3 0 1 0 0 0 0 5
0 0 0 0 0 0 7 1 0
4 0 0 0 0 8 2 0 0
0 0 5 9 0 0 0 8 0
0 8 0 0 0 1 0 0 3

Sudu::check方法

最后来看check这个方法,这个方法是判断决定输出是否成功的,返回1则success,内部如下
mark
又是三个方法分别为

Sudu::check_block    //块
Sudu::check_col //列
Sudu::check_row //行

根据单词意思就很好理解了,它们以&&连接,所以必须同时为1才行

check_block方法

mark
先初始化v2,再对每个3x3的块做遍历,判断是否每个块里的数字各不相同

check_col方法

mark
检查每列数字是否相同

check_row方法

mark
同样的,检测每行数字是否相同

还有一个坑

我们没有注意到,在if中有个set_sudu函数,进去看看
mark

很长,但我们只需要看主要的if,这里有个Sudu::number方法,再进去
mark
这里
a1是我们要输入的字符串
this=v10/9
a3=v10%9
a4=v8-48
a5=v5

判断表中的值是否为0,把原来给的值全设为0

结果

数独太难,直接放网站解
http://shudu.gwalker.cn/
mark

flag{340089102508406930016207058060875349709064820854392006093650071170023604602740590}

From https://kabeor.github.io/Snert-2018春季淘汰赛Reverse WriteUp/ bye

This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接:https://kabeor.github.io/Snert-2018春季淘汰赛Reverse WriteUp/