安恒月赛4 逆向两题

最后十分钟才刷新看到有第三题,已经来不及了,记一下前两题。

 

这两题都是简单的异或,但是就是纯看反汇编函数有点迷,好在问题不大。

第一题: 运行没有啥东西:

 

 程序也没加壳啥的,拖到ida就是一顿分析:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  size_t i; // [esp+28h] [ebp-80h]
  char input; // [esp+30h] [ebp-78h]
  char v6[8]; // [esp+A0h] [ebp-8h]

  _alloca(0x10u);
  __main();
  std::operator<<<std::char_traits<char>>(&std::cout, "input your key: ");
  std::operator>><char,std::char_traits<char>>(&std::cin, &input);
  for ( i = 0; i < strlen(&input); ++i )
    v6[i - 112] = (v6[i - 112] ^ 6) + 1;
  if ( !strcmp(&input, "akhb~chdaZrdaZudqduvdZvvv|") )
    std::operator<<<std::char_traits<char>>(&std::cout, "yes!you are right");
  else
    std::operator<<<std::char_traits<char>>(&std::cout, "try again");
  system("PAUSE");
  return 0;
}

中间的for循环是对输入的字符串的操作,至于为什么不是input直接进行操作而是用v6,我猜测是因为内存数据存储有关。

keygen:

chr1='akhb~chdaZrdaZudqduvdZvvv|'
flag=""
for i in range(len(chr1)):
    flag += chr((ord(chr1[i])-1)^6)
print(flag)

flag{daef_wef_reverse_sss}

 

第二题:运行貌似需要输入一个数,但是没啥反应,看一下代码:

 v54 = __readfsqword(0x28u);
  v16 = 38;
  v17 = 44;
  v18 = 33;
  v19 = 39;
  v20 = 59;
  v21 = 35;
  v22 = 34;
  v23 = 115;
  v24 = 117;
  v25 = 114;
  v26 = 113;
  v27 = 33;
  v28 = 36;
  v29 = 117;
  v30 = 118;
  v31 = 119;
  v32 = 35;
  v33 = 120;
  v34 = 38;
  v35 = 114;
  v36 = 117;
  v37 = 113;
  v38 = 38;
  v39 = 34;
  v40 = 113;
  v41 = 114;
  v42 = 117;
  v43 = 114;
  v44 = 36;
  v45 = 112;
  v46 = 115;
  v47 = 118;
  v48 = 121;
  v49 = 112;
  v50 = 35;
  v51 = 37;
  v52 = 121;
  v53 = 61;
  v3 = std::operator<<<std::char_traits<char>>(&std::cout, "Please input your magic number", a3);
  std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
  std::istream::operator>>(&std::cin, &input);
  if ( input <= 9 )
    return 0xFFFFFFFFLL;
  v15 = operator new[](input);                  // 分配一个大小是input
  for ( i = 0; i < input; ++i )
    std::operator>><char,std::char_traits<char>>(&std::cin, i + v15);// v15=0一直加到input
  v6 = std::operator<<<std::char_traits<char>>(&std::cout, "You have input sth.", v5);
  std::ostream::operator<<(v6, &std::endl<char,std::char_traits<char>>);
  v8 = std::operator<<<std::char_traits<char>>(&std::cout, "I will mix them with the enc_flag!", v7);
  std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
  for ( j = 0; j <= 37; ++j )
  {
    v10 = 0;
    for ( k = 0; k < input; ++k )
      v10 ^= *(k + v15);
    putchar(v10 ^ *(&v16 + j));
  }
  std::operator<<<std::char_traits<char>>(&std::cout, "\nMaybe you have found the `flag`\n", v9);
  return 0LL;
}

关键比较就是那个for循环,对输入的值每一个进行 xor v10,但是每次v10都会重新赋值再进行异或,一开始我想直接计算出v15,但是没有必要,应该就是一个混淆的,猜测一下最后的

  v53 = 61; 对应的就是  }   ,异或的就是64,所以:
chr2=[38, 44 ,33,39, 59 , 35 , 34, 115 , 117 , 114 , 113 , 33 , 36 , 117 , 118 , 119 , 35 , 120 , 38 , 114 , 117 , 113 , 38 , 34, 113, 114, 117, 114, 36, 112, 115, 118, 121, 112, 35, 37, 121, 61]

flag2=""

for i in range(38):
     flag2+=chr(chr2[i]^64)
print(flag2)

flag{cb3521ad567c8f251fb1252d03690ce9}

 

 

 

 

posted @ 2020-04-25 21:18  jentle  阅读(930)  评论(0编辑  收藏  举报