第七届蓝帽杯半决赛 逆向

无壳,直接用ida看加密函数

__int64 __fastcall sub_4051A0(_DWORD *a1)
{
  _DWORD *v1; // r10
  char *v2; // rbp
  _DWORD *v3; // rdi
  char *v4; // r8
  char *v5; // r9
  char *v6; // rcx
  _DWORD *v7; // rax
  __int64 v8; // rsi
  __int64 v9; // rdx
  __int64 result; // rax
  char v11[400]; // [rsp+0h] [rbp-348h] BYREF
  char v12[400]; // [rsp+190h] [rbp-1B8h] BYREF
  char v13; // [rsp+320h] [rbp-28h] BYREF
  unsigned __int64 v14; // [rsp+328h] [rbp-20h]
​
  v1 = a1;
  v2 = v12;
  v14 = __readfsqword(0x28u);
  qmemcpy(v11, &unk_574020, sizeof(v11));
  qmemcpy(v12, &unk_5741C0, sizeof(v12));
  v3 = a1 + 10;
  while ( 2 )
  {
    v4 = v11;
    v5 = v2;
    do
    {
      v6 = v4;
      v7 = v1;
      LODWORD(v8) = 0;
      do
      {
        v9 = (*v6 * *v7++);
        v6 += 40;
        v8 = (v9 + v8);
      }
      while ( v7 != v3 );
      if ( *v5 != v8 )
      {
        result = 0LL;
        goto LABEL_10;
      }
      v4 += 4;
      v5 += 4;
    }
    while ( v4 != &v11[40] );
    v2 += 40;
    v1 += 10;
    v3 = v7 + 10;
    if ( v2 != &v13 )
      continue;
    break;
  }
  result = 1LL;
LABEL_10:
  if ( __readfsqword(0x28u) != v14 )
    sub_52D790(v3, v8, v9, v6, v4, v5);
  return result;
}

这是主要的判断函数,当result返回1的时候就成功,这里我们用IDA python把&unk_574020和&unk_5741C0中的数据提取出来

import idaapi
​
addr = 0x5741C0#需要数据的起始位置
size = 100#需要截取数据的范围
arr = []
for i in range(size):
    dword_val = idaapi.get_dword(addr + 4*i)
    arr.append(hex(dword_val))
print(arr)

这里加密比较的函数逻辑是,每十个flag一组,乘以&unk_574020每隔十位取一个数据累加起来等于&unk_5741C0对应的数据,这里相当于是十元一次方程,需要用z3解,之前没用过,只能现学了。。。

from z3 import *
s = Solver()
X = [BitVec(('x%s' % i), 8) for i in range(0x64)]
data1 = [
    0xfe, 0xb, 0x1d, 0xf6, 0x83, 0xff, 0xe0, 0xb8, 0xdd, 0xb0,
    0xc5, 0xde, 0xf6, 0x14, 0x9f, 0xdd, 0xd9, 0x7, 0x2d, 0x6b,
    0x19, 0xca, 0x73, 0xfd, 0x87, 0x72, 0x24, 0x4, 0x49, 0x7e,
    0xa9, 0xce, 0x91, 0xbe, 0x41, 0x18, 0x60, 0x3f, 0x2b, 0x63,
    0x1c, 0xd2, 0x90, 0xe9, 0x8e, 0xba, 0x1e, 0xf3, 0x41, 0xad,
    0x2c, 0x3, 0x69, 0xda, 0x10, 0xfd, 0xfd, 0xe7, 0x6, 0x36,
    0xd6, 0x2, 0x59, 0x18, 0xcc, 0x50, 0x87, 0xaf, 0xfb, 0x18,
    0x44, 0x7f, 0xad, 0xf8, 0x2c, 0x67, 0x1d, 0x22, 0x84, 0xac,
    0xe, 0x23, 0xdc, 0xe6, 0xbb, 0xd2, 0xb8, 0x4a, 0xbc, 0xde,
    0x50, 0x9c, 0x1c, 0x1e, 0x86, 0x3a, 0x2d, 0xdd, 0xc3, 0x3
]
data2 = [0x1c633, 0x1df94, 0x20ebf, 0x2ba40, 0x1e884, 0x260d1, 0x1f9b1, 0x1ea1a, 0x1eeaa, 0x1dfb2,
         0x1c1d0, 0x1eef2, 0x216e1, 0x2be00, 0x1fb5e, 0x25d74, 0x1f000, 0x202d6, 0x20002, 0x1ddfe,
         0x1c017, 0x1f08c, 0x227f6, 0x2c7ba, 0x201ae, 0x27fbf, 0x20e21, 0x1ff5c, 0x1fd62, 0x1e948,
         0x1be6e, 0x1f4d7, 0x22c8d, 0x2c353, 0x1f8db, 0x26e1d, 0x1ff61, 0x1ea0f, 0x1f0d6, 0x1eda8,
         0x1ad7d, 0x18218, 0x1ccd4, 0x239b6, 0x1ac4c, 0x20d7c, 0x1d967, 0x1a4f4, 0x1cad8, 0x196ae,
         0x1831b, 0x17e45, 0x1d0cf, 0x23edf, 0x181ae, 0x21760, 0x1d3b4, 0x175d6, 0x17d3a, 0x1994f,
         0x1189d, 0x14ccf, 0x1568e, 0x17eeb, 0x1327e, 0x16a45, 0x12921, 0x11ff0, 0x13643, 0x11729,
         0x15191, 0x17d17, 0x17262, 0x1a863, 0x17010, 0x17b10, 0x14f9c, 0x143e8, 0x15e9b, 0x1242c,
         0xf68c, 0x1192a, 0x150ad, 0x1b1a0, 0x14c60, 0x182ab, 0x13f4b, 0x141a6, 0x15aa3, 0x135c9,
         0x1d86f, 0x1e8fa, 0x2158d, 0x2bdac, 0x20e4f, 0x27ee6, 0x213b9, 0x20e86, 0x211ff, 0x1e1ef]
result = [0]*0x64
flag = ''
for m in range(0, 10):
    for n in range(0, 10):
        result[m] += X[n] * data1[10*n+m]
        result[m+10] += X[n+10] * data1[10*n+m]
        result[m+20] += X[n+20] * data1[10*n+m]
        result[m+30] += X[n+30] * data1[10*n+m]
        result[m+40] += X[n+40] * data1[10*n+m]
        result[m+50] += X[n+50] * data1[10*n+m]
        result[m+60] += X[n+60] * data1[10*n+m]
        result[m+70] += X[n+70] * data1[10*n+m]
        result[m+80] += X[n+80] * data1[10*n+m]
        result[m+90] += X[n+90] * data1[10*n+m]
​
for o in range(0, 10):
    s.add(result[o] == data2[o])
    s.add(result[o+10] == data2[o+10])
    s.add(result[o+20] == data2[o+20])
    s.add(result[o+30] == data2[o+30])
    s.add(result[o+40] == data2[o+40])
    s.add(result[o+50] == data2[o+50])
    s.add(result[o+60] == data2[o+60])
    s.add(result[o+70] == data2[o+70])
    s.add(result[o+80] == data2[o+80])
    s.add(result[o+90] == data2[o+90])
​
s.check()
m = s.model()
for i in range(0, 100):
    flag += chr(int("%s" % (m[X[i]])))
​
print(flag)

这里exp还可以简化,但是是比赛的时候写的就没多想,将就看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值