1.思路

先看下前面大佬答题的时间,

有点变态的,不到一个小时就弄完了!说明可能有点希望 0.0 !!!!!

2.正文

刚开始那道题目的时候!

先运行下看下情况!

发现是个窗体程序

直接拖到IDA里面!

找到GetDlgItemTextA

然后由它的找到单击事件

咋一看,懵了!怎么没有判断序列号成功的地方!

刚开始怀疑类似于第二题,初始化一个全局或者静态的类对象,将验证算法藏在析构函数里面!奈何太菜没有找到!

然后又怀疑是不是栈溢出,但是输入的时候给定了最大长度!而且string的缓冲区也符合最大。

然后一点点想法,一点点否定。

最后将程序拖入study_pe的时候 ,

发现这么一个东西。。。TLS表!

这东西注册回调函数的时候,一般先于入口点运行!

算了一下偏移值!

base+0x122FC

因为程序有重定向

所以在IDA中我把base值设成0x1340000(实际情况,由你来定)

0x1340000 +0x122FC=0x13522FC

由它找到回调函数

一路跟下来找到主要调用的地方,

实际上每次调用GetDlgItemTextA之后,紧接着就会 调用这个函数(ps:藏的可真深啊!)

实际情况这样

看着很难看!

简单的定义了一个结构,让结果好看点

这里有一些地方没定义就是,是为了让ida识别的好看点,没有什么lowbyte的恶心人(ps:可能我是强迫症吧,嘻嘻)

从上图中逻辑中可以看出主要有两个检测点!

check1

check2

实际情况中,我过了一个答案就出来了!

初始化一个3x3的表。

1

2

3

4 1 3

7 2 5

8 6 0

因为结果需返回1,所以可知最后的表结构

1

2

3

1 2 3

4 5 6

7 8 0

不用想也知道上图中move,改变了表。

而且对传入的序列号进行了判断输入w -> 0 , d -> 1 , s -> 2 a -> 3

经常 玩游戏的可能一下就反应过来了,这是方向键!

可能我太菜了,一下没有反应过来,哈哈!

进去move看一看。

看着很乱,但是用心分析很快也能分析出来

这是我粗略整理了一下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

char __cdecl move(int s1, int s2)

{

    if(!s2)

        return 0;

    int j=0,i=0;

    for(j=0;j<3;j++){

        for(i=0;i<3;i++){

            if(table[j][i]==s2){

                switch ( s1 )

                {

                case 0:

                    if ( j )

                    {

                        if ( table1[j - 1][i] )

                        {

                            result = 0;

                        }

                        else

                        {

                            table1[j - 1][i] = table1[j][i];

                            table1[j][i] = 0;

                            result = 1;

                        }

                    }

                    else

                    {

                        result = 0;

                    }

                    return result;

                case 1:

                    if ( i == 2 )

                    {

                        result = 0;

                    }

                    else if ( table1[j][i+1] )

                    {

                        result = 0;

                    }

                    else

                    {

                        table1[j][i+1] = table1[j][i];

                        table1[j][i] = 0;

                        result = 1;

                    }

                    return result;

                    //break;

                case 2:

                    if ( j == 2 )

                    {

                        result = 0;

                    }

                    else if ( table1[j + 1][i] )

                    {

                        result = 0;

                    }

                    else

                    {

                        table1[j + 1][i] = table1[j][i];

                        table1[j][i] = 0;

                        result = 1;

                    }

                    return result;

                case 3:

                    if ( i )

                    {

                        if ( table1[j][i-1] )

                        {

                            result = 0;

                        }

                        else

                        {

                            table1[j][i-1] = table1[j][i];

                            table1[j][i] = 0;

                            result = 1;

                        }

                    }

                    else

                    {

                        result = 0;

                    }

                    return result;

                default:

                    ;

                }

            }

        }

        

    }

}  

由此可以看出!对传入的参数在0 1 2 3中进行了判断,有w a s d 我们就就可以初步的推断是对表中的元素进行了移动。

结果正是如此,由上面化简的代码可知,实际上移动后的位置会被置为0,而后面判断的元素,每个都是初始化的内容!

所以可知移动的地方只能为0。

最后的表结构为

1

2

3

1 2 3

4 5 6

7 8 0

因此我们就可以大胆的猜测这是一个拼图游戏。

1

2

3

4 1 3          1 2 3

7 2 5   -- ->  4 5 6

8 6 0          7 8 0

下面就是写算法求解了

可能我太菜了,于是乎上网随便搜了一个。。。。。。。。。。。

3.结果

1

2

3

4

5

6

7

8

6 d

8 d

7 s

4 s

1 a

2 w

5 a

6 w

最后的序列号就为:d6d8s7s4a1w2a5w6

4.总结

前面的大佬太强了,估计一下就看出算法了,学逆向一年左右了还是经验太少!还需学习啊,幸好有看雪这么好的论坛在(舔狗,哈哈 ^.^),看雪万岁!!

有空自己实现下拼图算法再发出来!先发网上的.......

看雪CTF.TSRC 2018 团队赛-第六题 追凶者也--拼图游戏相关推荐

  1. 看雪ctf 流浪者 WP

    看雪ctf 第一题 流浪者 wp   打开程序,提示要验证password,载入OD,按照签到题的思路,改了一个跳转,出现了提示框pass,但是没有flag,应该不是这种思路(我是一个刚入手的萌新,可 ...

  2. 看雪CTF 2016_第八题分析

    用exeinfo查看发现是x64程序,所以用平常的OD调试器是调试不到的,需要用x64的调试器 我这里是用x64dbug 这个调试器来进行调试分析 经过一步一步调试,发现程序调用RtlMoveMemo ...

  3. 看雪CTF 2016_第四题分析

    结合前辈们的分析,自己再作一个分析,算是当做学习笔记吧! OD 下GetDlgItemTextA 这个断点 0040148C |. 83F8 1E cmp eax,0x1E 检测注册码长度是否为30位 ...

  4. 2018第九届蓝桥杯C/C++ B国赛 —— 第六题:矩阵求和

    矩阵求和 经过重重笔试面试的考验,小明成功进入 Macrohard 公司工作. 今天小明的任务是填满这么一张表: 表有 n 行 n 列,行和列的编号都从1算起. 其中第 i 行第 j 个元素的值是 g ...

  5. 第七届 蓝桥杯 省赛 第六题 方格填数(next_permutation)

    填入0~9的数字.要求:连续的两个数字不能相邻. (左右.上下.对角都算相邻) 一共有多少种可能填写的方案? 请填写表示方案数目的整数- 分析:从左到右从上到下标为0-9,将a[10]中的数字依次填入 ...

  6. 5月10日12点,看雪.深信服2021 KCTF春季赛正式开赛!

    5月10日12点,看雪.深信服2021 KCTF春季赛正式开赛!想要在这盛大赛事大展身手的你们,一定要抓住这次机会! 在这里你会收获到相关的实战经验,与志同道合的网络安全人才交流.切磋的机会,同时还有 ...

  7. 段钢:自从那个冬夜看雪,一晃已是十六年

    本文来源微信公众号:安在,版权归原作者所有. 最近,一则消息引爆了朋友圈,看雪学院获得了永州创投的500万元天使轮投资,作为安全圈内最资深的安全论坛之一,16年来看雪学院滋养了大量安全技术爱好者,被誉 ...

  8. 看雪CTF2020 KCTF 秋季赛 签到题

    前言 佛系参加看雪CTF2020 最终只水了一个签到题 是个win64的逆向 解题过程 先运行看看 是个输入flag 然后进行判断对不对的小程序 扔进IDA F5看伪码 顺手按着习惯改了改变量名 需要 ...

  9. TrustAsia(亚洲诚信)助力看雪2018安全开发者峰会

    2018年7月21日,看雪2018安全开发者峰会在北京国家会议中心圆满落下帷幕.拥有18年悠久历史的老牌安全技术社区--看雪学院联手国内最大开发者社区CSDN,汇聚业内顶尖的安全开发者和技术专家,倾力 ...

  10. 2018哈理工院个人赛、校团队赛总结

    ​ 院个人赛拿了亚军,校团队赛185支队伍拿了第五名.还算满意,今天打算总结总结- ​ 哈理工院个人赛12月2号举行,10道题4个小时.题目比较简单- ​ 两道水题 跳转到小乐乐玩木桶 和 跳转到小乐 ...

最新文章

  1. MySQL 5.5.35 单机多实例配置详解
  2. 期末复习、化学反应工程科目(第三章)
  3. 元素分类--块级元素(特点:独占一行, 宽高边距可改)
  4. Object Tracking using OpenCV (C++/Python)(使用OpenCV进行目标跟踪)
  5. 2017年机器之心北京开会_2017年成为机器人的感觉
  6. java 日历纪实,日历表--案例 (转载)
  7. 雅虎14条性能优化原则
  8. Unity用GUI绘制Debug/print窗口/控制台-打包后测试
  9. Android MVP架构实现
  10. 鸡兔同笼c语言代码while,鸡兔同笼(C语言代码)
  11. Monaco Editor教程(十七):代码信息指示器CodeLens配置详解
  12. python 复选框_每日一练:Python复选框的运用
  13. pycharm: Error: Cannot run program……
  14. 3D建模和渲染吃什么硬件?新手避坑指南
  15. 理解事务四大特性(Transaction)——原子性、一致性、隔离性和持久性(ACID)
  16. 扩散模型加持下,机器人模型DALL-E-Bot可以轻松完成自主重新排列任务
  17. HCSA-08 威胁防护介绍、ARP防护、网络攻击防护、病毒过滤、入侵防御、边界流量过滤
  18. 使用burp进行网站爆破
  19. SMA、EMA与双均线策略
  20. Linux基础——之一命令

热门文章

  1. 扩展天气图标skycons.js, 将10个扩展到20个
  2. 加ing形式的单词有哪些_初中英语中哪些单词后接动词要加ing形式
  3. LeetCode452用最少的箭射爆气球
  4. 计算机主机电源灯不亮,电脑主机开不了机、电源灯不亮解决方法与技巧
  5. 面试通过了,也给了Offer,不去有什么后果?
  6. Cesium加载OpenStreetMap
  7. 2021-2027全球与中国乳胶机械稳定性测试仪市场现状及未来发展趋势
  8. 解决苹果电脑OS X 10.8.5 安装双系统,遇到的各种坑
  9. ioi 赛制_《Produce48》现坑爹赛制 网友称这波操作令人窒息
  10. go mod invalid pseudo-version