最后十分钟才刷新看到有第三题,已经来不及了,记一下前两题。
这两题都是简单的异或,但是就是纯看反汇编函数有点迷,好在问题不大。
第一题: 运行没有啥东西:
程序也没加壳啥的,拖到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, " Maybe you have found the `flag` ", 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}