[buuctf.reverse] 098_[SUCTF2019]hardcpp

手工搞一下扁平化的题

ida可以看到,这是一个明显的扁平化的题,它通过一个变量在一堆while循环里跳,代码被分散在这些while中间。

不过可以明显的看到处理逻辑

                              v35 = v38 ^ v41[v36 - 1];
                              v34[0] = main::$_0::operator()(v44, (unsigned int)v35);// return a2
                              v33[0] = main::$_1::operator()(v42, (unsigned int)*(&s + v38 + v36 - 1));// return a2
                              v11 = main::$_1::operator() const(char)::{lambda(int)#1}::operator()(v33, 7LL);// a1%a2
                              v35 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()(// char a1+a2
                                      v34,
                                      (unsigned int)v11);
                              v32[0] = main::$_2::operator()(v45, (unsigned int)v35);// return a2
                              v31[0] = main::$_2::operator()(v45, (unsigned int)*(&s + v38 + v36 - 1));// return a2
                              v12 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v31, 18LL);// a1^a2
                              v30[0] = main::$_3::operator()(v43, (unsigned int)v12);// return a2
                              v13 = main::$_3::operator() const(char)::{lambda(char)#1}::operator()(v30, 3LL);// a1*a2
                              v29[0] = main::$_0::operator()(v44, (unsigned int)v13);// return a2
                              v14 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()(v29, 2LL);// a1+a2
                              v15 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(// a1^a2
                                      v32,
                                      (unsigned int)v14);
                              v16 = 1299792285;
                              v35 = v15;
                              v52 = enc[v36 - 1] != v15;
                              if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
                                v16 = -424557443;
                              v28 = v16;
                            }
                            if ( v28 != -1957245689 )
                              break;
                            v28 = 1587023630;

先把每个子函数的功能搞明白。点进去看其实很简单,无非就是直接返回或者是两个字符作+^*%这样的操作

这里边明显v36是循环的指针,找到++v36,然后顺着这个v28一直可以走完循环并可以走到win

      if ( v28 != 24093646 )
        break;
      ++v36;
      v28 = 1587023630;
    }

这里还有一个干扰项,很显然不管x是几,(x-1)*x一定是偶数然后&1 == 0一定成立,所以这时候一定走下边的路径

        v20 = -350248402;
        if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
          v20 = -226137905;
        v28 = v20;

根据处理逻辑也就确定它的对比方式,flag由20位组成前面加一字符(这个没整明白应该是多少)

#flag[i+1] + flag[i]%7 == enc[i]^(((flag[i]^18)*3)+2)

第一个是啥不重要,暴力即可

data = open('hardCpp', 'rb').read()

enc = data[0x2060: 0x2060+0x15]
print(' '.join([hex(i)[2:] for i in enc]))

#flag[i+1] + flag[i]%7 == enc[i]^(((flag[i]^18)*3)+2)
flag = [0]*21
for i in range(0x20, 0x7f):
    flag[0] = i 
    for j in range(20):
        flag[j+1] = ( (enc[j] ^(((flag[j]^18)*3)+2)) - flag[j]%7 )& 0xff
    print(bytes(flag))

#b'#flag{mY-CurR1ed_Fns}'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值