buu-reverse-[FlareOn5]Ultimate Minesweeper题解
关键代码
因为是基于.net库的游戏,使用dnSpy打开
在主函数找到关键的两个函数
// Token: 0x0600000C RID: 12
private void SquareRevealedCallback(uint column, uint row)
{
if (this.MineField.BombRevealed)
{
this.stopwatch.Stop();
Application.DoEvents();
Thread.Sleep(1000);
new FailurePopup().ShowDialog();
Application.Exit();
}
this.RevealedCells.Add(row * MainForm.VALLOC_NODE_LIMIT + column);
if (this.MineField.TotalUnrevealedEmptySquares == 0)
{
this.stopwatch.Stop();
Application.DoEvents();
Thread.Sleep(1000);
new SuccessPopup(this.GetKey(this.RevealedCells)).ShowDialog();
Application.Exit();
}
}
// Token: 0x0600000D RID: 13 RVA: 0x000023E4 File Offset: 0x000005E4
private string GetKey(List<uint> revealedCells)
{
revealedCells.Sort();
Random random = new Random(Convert.ToInt32(revealedCells[0] << 20 | revealedCells[1] << 10 | revealedCells[2]));
byte[] array = new byte[32];
byte[] array2 = new byte[]
{
245,
//太长了我截断,一下,一共32个字符
86
};
random.NextBytes(array);
uint num = 0U;
while ((ulong)num < (ulong)((long)array2.Length))
{
byte[] array3 = array2;
uint num2 = num;
array3[(int)num2] = (array3[(int)num2] ^ array[(int)num]);
num += 1U;
}
return Encoding.ASCII.GetString(array2);
}
前一个函数是,判断是否点对了,执行对应的成功或者失败的操作。
后面一个函数是得到flag的过程,但是没有定义array1的值,没法计算。
逆向过程
有两种思路可以得到答案
- 修改程序,想办法直接通关游戏得到flag
- 动调获得array1的值,然后自写注册机
显然方案一更便捷。
右键编辑方法,修改以下if内的判断条件变成if (this.MineField.BombRevealed && false)
把以下内容不执行
if (this.MineField.BombRevealed)
{
this.stopwatch.Stop();
Application.DoEvents();
Thread.Sleep(1000);
new FailurePopup().ShowDialog();
Application.Exit();
}
再保存一下(文件-保存模块)
然后执行保存的新的.exe文件,运行,随意点击找到答案位
后正确点击对应的答案位置,直接得到答案
最后得到答案Ch3aters_Alw4ys_W1n@flare-on.com
总结
关键是熟悉,游戏类套壳逆向, 这种题目一般加密过程不难,或者只需要简单修改通关就可以获得答案。这类题目会在不同的编译工具之间迁移,参考另一篇汇总各类语言的汇总博客:http://poilzero.sipc115.club/index.php/archives/72/
【buu】[FlareOn5]Ultimate Minesweeper .net逆向
【buu】[GKCTF2020]Check_1n .net逆向
【buu】[BJDCTF2020]BJD hamburger competition