攻防世界 Reverse reverse-for-the-holy-grail-350

reverse-for-the-holy-grail-350
Windows系统打不开,放进ida发现Linux系统下文件,查看main函数反汇编

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // ebx
  int v4; // ebx
  __int64 v5; // rbx
  void *v7[2]; // [rsp+0h] [rbp-70h] BYREF
  _BYTE v8[16]; // [rsp+10h] [rbp-60h] BYREF
  void *v9[2]; // [rsp+20h] [rbp-50h] BYREF
  _BYTE v10[16]; // [rsp+30h] [rbp-40h] BYREF
  void *v11[2]; // [rsp+40h] [rbp-30h] BYREF
  char v12[24]; // [rsp+50h] [rbp-20h] BYREF

  v11[0] = v12;
  v11[1] = 0LL;
  v12[0] = 0;
  std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is your name?", 21LL);
  std::endl<char,std::char_traits<char>>(&std::cout);
  std::operator>><char>(&std::cin, v11);
  std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is your quest?", 22LL);
  std::endl<char,std::char_traits<char>>(&std::cout);
  std::istream::ignore((std::istream *)&std::cin);
  std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, v11);
  std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What...  is the secret password?", 32LL);
  std::endl<char,std::char_traits<char>>(&std::cout);
  std::operator>><char>(&std::cin, &userIn[abi:cxx11]);
  v7[0] = v8;
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::_M_construct<char *>(
    v7,
    userIn[abi:cxx11],
    qword_601AE8 + userIn[abi:cxx11]);
  v3 = validChars((__int64 *)v7);  //输入v3
  if ( v7[0] != v8 )  
    operator delete(v7[0]);
  if ( v3 < 0 )
    goto LABEL_8;
  v9[0] = v10;
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::_M_construct<char *>(
    v9,
    userIn[abi:cxx11],
    qword_601AE8 + userIn[abi:cxx11]);
  v4 = stringMod((__int64 *)v9);  //主要这里的关键函数stringMod
  if ( v9[0] != v10 )  //与上面的v7[0] != v8 相对应
    operator delete(v9[0]);
  if ( v4 < 0 )
  {
LABEL_8:
    std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Auuuuuuuugh", 11LL);
    std::endl<char,std::char_traits<char>>(&std::cout);
  }
  else
  {
    std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Go on. Off you go. tuctf{", 25LL);
    v5 = std::__ostream_insert<char,std::char_traits<char>>(&std::cout, userIn[abi:cxx11], qword_601AE8);
    std::__ostream_insert<char,std::char_traits<char>>(v5, "}", 1LL);
    std::endl<char,std::char_traits<char>>(v5);
  }  //最后输出的格式可以得到是Go on. Off you go. tuctf{}
  if ( v11[0] != v12 )
    operator delete(v11[0]);
  return 0;
}

其中的stringMod函数非常关键

__int64 __fastcall stringMod(__int64 *a1)
{
  __int64 v1; // r9
  __int64 v2; // r10
  __int64 v3; // rcx
  int v4; // er8
  int *v5; // rdi
  int *v6; // rsi
  int v7; // ecx
  int v8; // er9
  int v9; // er10
  unsigned int v10; // eax
  int v11; // esi
  int v12; // esi
  int v14[18]; // [rsp+0h] [rbp-60h] BYREF
  __int64 v15; // [rsp+48h] [rbp-18h] BYREF

  memset(v14, 0, sizeof(v14));
  v1 = a1[1];
  if ( v1 )
  {
    v2 = *a1;
    v3 = 0LL;
    v4 = 0;
    do
    {
      v12 = *(char *)(v2 + v3);
      v14[v3] = v12;
      if ( 3 * ((unsigned int)v3 / 3) == (_DWORD)v3 && v12 != firstchar[(unsigned int)v3 / 3] )
        v4 = -1;  //前半段判断是否是3的倍数,如果是,那么V12的值就为firstchar[i/3](firstchar=[])
      ++v3;
    }
    while ( v3 != v1 );
  }
  else
  {
    v4 = 0;
  }
  v5 = v14;
  v6 = v14;
  v7 = 666;  //注意这边V7赋值为666
  do
  {
    *v6 = v7 ^ *(unsigned __int8 *)v6;
    v7 += v7 % 5;
    ++v6;    //必须要运行的循环处理
  }
  while ( &v15 != (__int64 *)v6 );
  v8 = 1;
  v9 = 0;
  v10 = 1;
  v11 = 0;
  do
  {
    if ( v11 == 2 )
    {
      if ( *v5 != thirdchar[v9] )
        v4 = -1;
      if ( v10 % *v5 != masterArray[v9] )  //要对应下面else语句里面的 v10 *= *v5
        v4 = -1;
      ++v9;
      v10 = 1;
      v11 = 0;
    }
    else
    {
      v10 *= *v5;
      if ( ++v11 == 3 )
        v11 = 0;
    }
    ++v8;
    ++v5;
  }
  while ( v8 != 19 );  //循环范围是18
  return (unsigned int)(v7 * v4);
}

写代码

firstchar=[0x41,0x69,0x6E,0x45,0x6F,0x61]
thirdchar=[0x2EF,0x2c4,0x2dc,0x2c7,0x2de,0x2fc]
masterarray=[0x1d7,0xc,0x244,0x25e,0x93,0x6c]
c=[]
v7=666
flag=[0 for i in range(18)]
for i in range(18):
    c.append(v7)
    v7+=v7%5    //用作加密
t=0
for i in range(0,18,3):
    flag[i]=firstchar[t]
    t+=1        //第一组数据不需要进行加密
t=0
for i in range(2,18,3):
    flag[i]=thirdchar[t]^c[i]
    t+=1        //第三组数据
t=0
for i in range(1,18,3):
    for j in range(128):
        if masterarray[t]==(j^c[i])*(flag[i-1]^c[i-1])%(flag[i+1]^c[i+1]):
            flag[i]=j   //第三组数据要进行判断,v10*v5%v5==masterarray根据前面的对thirdchar处理写代码
            t+=1
            break
for i in range(18):
    print(chr(flag[i]),end='')

运行得到

AfricanOrEuropean?

最后提交时记得加上tuctf{}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值