攻防世界:reverse_re3 IDA数据处理 代码分析

一级难度...我做了,不对,看wp看了好久的题目。

还是先看看有没有壳以及多少位

64位的,elf文件,我运行过,好像是没有结果,毕竟这是一道地图题目。

那就找string和main函数,很容易的就发现了,在main函数里面的有一个函数点开就能看到

所以,就直接看代码吧。

首先这个,main函数有两个函数,第一个

这里面,其实第5行和第7行,我用去寻找了什么意思,说是 “栈保护金丝雀值(Stack Canary),用于检测缓冲区溢出攻击”,毕竟第7行这个return 确实是在校验什么,因为任何一个数^他自己都为0,如果这个数有变化就不会正常返回0了。那么没有迷惑选项,可以看到,这里面就是定义了一个恶心的,好长的变量,我就直接叫AB0了,定义他为0.其实也可以xref(交叉引用)一下(选中直接按“x”)

看到最后一行,赋值为0.

然后就是main函数还有一个do while循环,这个循环要正常返回和V4有关,我们就直接打开V4就好。

__int64 sub_564F0B5ED940()
{
  int v0; // eax
  int v2; // [rsp+8h] [rbp-218h]
  int v3; // [rsp+Ch] [rbp-214h]
  char v4[520]; // [rsp+10h] [rbp-210h] BYREF
  unsigned __int64 v5; // [rsp+218h] [rbp-8h]

  v5 = __readfsqword(0x28u);                    // 输入值
  v3 = 0;                                       // 索引,不会清零
  memset(v4, 0, 0x200uLL);                      // 给V4赋值为0
  _isoc99_scanf(&unk_564F0B5EE278, v4, v4);
  while ( 1 )
  {
    do
    {
      v2 = 0;
      sub_564F0B5ED86C();
      v0 = v4[v3];
      if ( v0 == 'd' )
      {
        v2 = sub_564F0B5EDE23();
      }
      else if ( v0 > 'd' )
      {
        if ( v0 == 's' )
        {
          v2 = sub_564F0B5EDC5A();
        }
        else if ( v0 == 'w' )
        {
          v2 = sub_564F0B5EDA92();
        }
      }
      else
      {
        if ( v0 == 27 )
          return 0xFFFFFFFFLL;                  // 十进制的-1
        if ( v0 == 'a' )
          v2 = sub_564F0B5EDFEC();
      }
      ++v3;
    }
    while ( v2 != 1 );
    if ( dword_564F0B7EFAB0 == 2 )
      break;
    ++dword_564F0B7EFAB0;
  }
  puts("success! the flag is flag{md5(your input)}");
  return 1LL;
}

我看到代码是挺无语的,又点开看了几个函数...没有看的欲望了。真的是,还是太年轻,太浮躁了。

首先V5好像没啥作用,会不会就是前面那个金丝雀值,然后因为一些运算没了。让V4初始化全零,再scanf,那么可以确定V4是我们用户要输入的值,这里面有两个循环,一个while一个do while。再看这个V3一直在用,而且不在循环不会被清零,V4[V3]看着就是起到索引的作用的。再看看末尾,出现了熟悉的AB0,所以就可以看出来,这个最外层的while循环会循环3次,直到AB0等于2跳出去。还有就是,如果你把那些做判断的数字换成字符,机会发现里面包含了,a w s d和Esc,这不就是方向键吗,这个时候可以合理想想会不会是地图题目。这些分析的差不多,我们就可以看do while 循环里面的内容了。这里面的V2没啥作用,比较像引用函数?我觉得这个数字有没有无所谓。我们打开这个86C结尾的函数看看吧。

其实看到这里,如果你能分析出这个玩意到底在干嘛,那么这道题目基本就出来了。首先,这里面的V3就是前面说的金丝雀值,对函数逻辑没啥用,干扰的就不看。最明显的会看到,有 i联合的组合技。两个循环,像不像15X15的地图,以及后面的 i X15+j 就差在旁边表备注“我是地图啦”。但是这个地图怪怪的,他有一个判断,判断这个点是不是等于3,如果是,那么就赋值给AB4和AB8( i 和 j 循环一个一个位置寻找3)。还有就是AB0也在里面,我们之前知道,AB0和最外层循环有关,那么对于这个内循环的函数来说,这个AB0是不会被清零的,就是说每次循环的这个AB0的值是不一样的,我们还可以知道这个dword_564F0B7EF020是一个有675字节的数组,225*3=675,这个是不是有三个地图啊,结合AB0的0,1,2的取值,我们再查看这个数组

这就是地图了,这里面5 dup(1):有5个1的意思,我们可以shift+e提取数据。前面的dd是4个字节的意思,那么,这也就是说,一个数据是4个字节,这点我倒是没注意,你可以看看这个数组的大小其实就是DWORD[675],那么提取数据就有坑了,我就是被坑了。

第一和第二个是有无空格的16进制表示,就比如 “77889966” 和“77 88 99 66”的区别。第三个是转化成字符串的形式,但是这个是有范围的,不能用字符串表示就就有很多个“/x”。第四个和第五个,你注意了,这是char,他是一个字节一个字节表示的,你一个数据的内存是4字节,这么搞就错了。你只要知道我一个数据是多大,相应的就不会有问题,第六个是,自己改变的,可能是字符或数字,这个就比较智能一点,所以我们选这个的话,他就会以4字节一个数据表示

我们数据前5个是1,第二幅图就是用char来表示了,所以就会有问题。我一开始也是写脚本提取数据的,但是就是会发现数据有问题,结果就是这个数据的字节数搞错了。这边我可以提供两个办法提取数据。

1.直接写脚本,很简单的

# “get_wide_byte(地址)"  1字节
# "get_wide_word(地址)"  2字节
# "get_wide_dword(地址)" 4字节
# "get_qwordn(地址)”     8字节
# “get_bytes(地址,字节数)"size个字节
# ,根据后缀可以分别知道提取了多少字节,依次是1,2,4,8,size字节

addr=0x000564F0B7EF020
arr=[]
for i in range(0,675):
    arr.append(get_wide_byte(addr+i))
print(arr)

看清楚数据的字节数就没问题了,一般这种可以直接提取成数组的数据,方便我后面处理

2.直接用IDA里的,再用python脚本,改变一下数据格式

def main():
    # 初始化存储675个地图元素的列表
    ous = [''] * 675

    # 读取675个输入值并提取每个值的首字符
    for i in range(675):
        ins = input().strip()  # 读取一行输入并去除空白字符
        if ins:  # 确保输入不为空
            ous[i] = ins[0]  # 只取第一个字符

    for i in range(675):
        if i !=674:
            print(ous[i], end=',')
        else:
            print(ous[i])


if __name__ == "__main__":
    main()

前面可以看到,用IDA里面的,数据之间有空格换行,这段代码主要是strip()这个函数,可以

读取一行输入并去除空白字符,简直就是量身定做,呃(⊙﹏⊙),好像有换行也无所谓,直接是python数组的,但是这道题目要寻找3的位置,也不好说,就是我这么搞就是为了可以直观的看到地图,如果只是跑代码,直接在IDA里面复制数据也不用多处理什么。

得到数据,我们就可以搞地图出来啦,可以脚本可以手动,都很快也很简单

[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 1, 1, 1, 1, 1, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0,
 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,


 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 1, 1, 0, 3, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0,
 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,


 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]

或许看的不明白吧,但是你可以ctrl+F,全局搜索,有高亮显示,就很明显了。我们寻找还没有分析后面的代码,但是如果看图就可以知道大概了,首先每一个图里面有一个3,0很没有规律,而且太多了,估计是墙。我们直接找1,第一幅图最明显,3经过1的路径会看到4,这个4会不会就是出口?再看后面两副,基本上就是了,那我们基本就知道这道题目的意思。

我这边就选一个,这些名字特别长的,但是我们直接这就是数组和我们的AB0和 i 大哥和 j 大哥,他们就是3的地址,每经过一个1的地址,就会把这个1变成3,前面的3变成1,就这么跑下去,直到3的位置变成4了,那就结束循环了(结束内循环,毕竟是有两个图的)。最后就是获得路径了,可以直接看出来,也可以直接跑代码。如果要跑代码可以看我的《攻防时间:maze》这里面讲了。

ddsssddddsssdssdddddsssddddsssaassssdddsddssddwddssssssdddssssdddssMD5加密

aeea66fcac7fa80ed8f79f38ad5bb953

flag{aeea66fcac7fa80ed8f79f38ad5bb953}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值