安恆月賽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}

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM