Minesweeper
萧禾财 Lv4

先查壳

image-20221027220919349

发现是用C#写的,用dnspy打开

开始逆

image-20221027221239788

program类是函数的入口

image-20221027221335884

发现直接跳转到MainForm类中去了

观察mainform的主要逻辑

image-20221027221526057

SquareRevealedCallback观看命名是一个回调函数

通过动调发现这个回调函数会对我们点击雷区有反应

image-20221027222008699

当我们踩到雷时弹出失败的弹窗,就是这里调用的失败弹窗,合理猜测下面那个就是成功的弹窗。

比较简单的方法,我们可以注释掉这段if判断,就会不会调用失败弹窗,直到我们测出所有雷,跳出成功弹窗,先按下不表。

接着看 mainform 中调用这个函数AllocateMemory

image-20221027222549666

两层循环 30*30 应该是个产生雷阵的函数,题中提到 一共有897雷,只有3处没雷,那三处就是关键

易知,有雷的地方 flag=true

当满足if判断时 flag = false 这个就是我们要找的地方

image-20221027223152889

VALLOC_NODE_LIMIT = 30是个常数

r,c 对应雷阵的行和列

image-20221027223315097

这边要匹配的三个数也是常数,则三处没雷区是个定值

求解

我先试试最简单的方法,直接失败的判断注释掉

image-20221027223659920

右键编辑方法,注释完后保存

此时可以发现不会有失败的界面了

image-20221027223944435

image-20221027224316305

可以找出这三个无雷区,但是flag是乱码,说明有检测手段,或者,那段判断中有运算影响flag,但不重要,因为三个无雷区是定值,不会变,我们打开原来没有改过的程序,精准找出这三个点,就可得flag

image-20221027224341650

另外,我们试试用脚本找

1
2
3
4
5
6
7
8
9
#include<stdio.h>
void main()
{
int i,j;
for(i=0;i<=30;i++)
for(j=0;j<=30;j++)
if(~((i+1)*30+(j+1))==0xFFFFFC80||~((i+1)*30+(j+1))==0xFFFFFD81||~((i+1)*30+(j+1))==0xFFFFFEF2)
printf("%d %d \n",i+1,j+1);
}

image-20221027224520632

同样可以找到三个无雷区位置

参考文献

*Microsoft Word - FlareOn5_Challenge2_Solution.docx (fireeye.com)

[BUUCTF–FlareOn5]Ultimate Minesweeper - Hk_Mayfly - 博客园 (cnblogs.com)

  • 本文标题:Minesweeper
  • 本文作者:萧禾财
  • 创建时间:2022-10-27 22:06:31
  • 本文链接:https://ipartmentxhc.github.io/2022/10/27/Minesweeper/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!