bugku-游戏过关

pwnable.tw的calc和pwnable.kr的memcpy难度提升得让我突然像是到了一片知识的孤岛上,举目所望是无尽的未知。才发现自己的汇编基础实在薄弱,另外只通过0day安全分析学了windows的堆管理,对linux的堆管理实在是所知甚少,鉴于此,在补足基础的时候,打算做一下bugku上的逆向维持一下基本的做题感觉。

bugku逆向的前三题都是用IDA打开就看到答案了,所以从游戏过关这一题开始。

用IDA打开,搜索main,没看到,搜索_main查到主函数。

一进主函数就看到

  sub_45A7BE((int)&unk_50B110, v21);
  sub_45A7BE((int)&unk_50B158, v3);
  sub_45A7BE((int)&unk_50B1A0, v4);
  sub_45A7BE((int)&unk_50B1E8, v5);
  sub_45A7BE((int)&unk_50B230, v6);
  sub_45A7BE((int)&unk_50B278, v7);
  sub_45A7BE((int)&unk_50B2C0, v8);
  sub_45A7BE((int)&unk_50B308, v9);
  sub_45A7BE((int)&unk_50AFD0, v10);
  sub_45A7BE((int)"|              by 0x61                                 |\n", v11);
  sub_45A7BE((int)"|                                                      |\n", v12);
  sub_45A7BE((int)"|------------------------------------------------------|\n", v13);
  sub_45A7BE(
    (int)"Play a game\n"
         "The n is the serial number of the lamp,and m is the state of the lamp\n"
         "If m of the Nth lamp is 1,it's on ,if not it's off\n"
         "At first all the lights were closed\n",
    v14);

这样一篇看不懂的代码,sub_45A7BE竟然还Decompliation failure,直接打开程序知道了是一个把黑灯全转化成亮灯的游戏。

顺着main函数查看

    while ( 1 )
    {
      sub_45A7BE((int)"input n,n(1-8)\n", v22);
      sub_459418();
      sub_45A7BE((int)"n=", v19);
      sub_4596D4("%d", &v24);
      sub_45A7BE((int)"\n", v20);
      if ( v24 >= 0 && v24 <= 8 )
        break;
      sub_45A7BE((int)"sorry,n error,try again\n", v22);
    }
    if ( v24 )
    {
      sub_4576D6(v24 - 1);
    }
    else
    {
      for ( i = 0; i < 8; ++i )
      {
        if ( (unsigned int)i >= 9 )
          j____report_rangecheckfailure(a1, a2, a3);
        byte_532E28[i] = 0;
      }
    }

通过sub_4596D4知道了v24就是我们输入的值,else就是重置游戏,通过byte_532E28[i]=0知道0是关灯的状态,那main函数最后的if语句就是判断游戏胜利的条件了。

    if ( byte_532E28[0] == 1
      && byte_532E28[1] == 1
      && byte_532E28[2] == 1
      && byte_532E28[3] == 1
      && byte_532E28[4] == 1
      && byte_532E28[5] == 1
      && byte_532E28[6] == 1
      && byte_532E28[7] == 1 )
    {
      sub_457AB4();
    }

跟进sub_457AB4,看到一百多个从v3-v116的参数,后面跟着一个函数

  for ( i = 0; i < 56; ++i )
  {
    *(&v3 + i) ^= *(&v60 + i);
    *(&v3 + i) ^= 0x13u;
  }
  return sub_45A7BE((int)"%s\n", (unsigned int)&v3);

明白了这114个参数分成两组进行异或运算,最后再和0x13异或。

把一百多个参数直接复制到nodepad++里面,然后按着alt选择前面几列删除,把分号替换成逗号,在这114行数字前加上a=[,末尾加上],就变成了一个python列表了

for i in range(0,56):
	print(chr((a[i]^a[i+57])^19))

加上一个循环,成功输出flag

 

其实这道题并没有怎么顺着分析。。点开main函数顶部的unk_50B110,碰巧在数据段内发现flag

.rdata:0050B0F0 aDoneTheFlagIs  db 'done!!! the flag is ',0
.rdata:0050B0F0                                         ; DATA XREF: sub_45E940+28↑o
.rdata:0050B105                 db    0
.rdata:0050B106                 db    0
.rdata:0050B107                 db    0
.rdata:0050B108                 db    0
.rdata:0050B109                 db    0
.rdata:0050B10A                 db    0
.rdata:0050B10B                 db    0
.rdata:0050B10C aS              db '%s',0Ah,0           ; DATA XREF: sub_45E940+288↑o
.rdata:0050B110 unk_50B110      db  20h                 ; DATA XREF: _main_0+1E↑o

然后右键选择Xrefs graph to就发现了sub_45E940调用了这个字段,搜索到这个函数后一路倒着进入了main函数,就明白了flag怎么得到了。

你可能感兴趣的:(bugku-游戏过关)