Easy Crackme
都说逆向挺难的,但是这题挺容易的,反正我不会,大家来挑战一下吧~~:)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 int __cdecl main(int argc, const char **argv, const char **envp) { __int64 v3; // rdi char v5; // [rsp+0h] [rbp-38h] char v6; // [rsp+1h] [rbp-37h] char v7; // [rsp+2h] [rbp-36h] char v8; // [rsp+3h] [rbp-35h] char v9; // [rsp+4h] [rbp-34h] char v10; // [rsp+5h] [rbp-33h] unsigned __int8 v11; // [rsp+10h] [rbp-28h] _BYTE v12[7]; // [rsp+11h] [rbp-27h] v5 = -85; v6 = -35; v7 = 51; v8 = 84; v9 = 53; v10 = -17; printf((unsigned __int64)"Input your password:"); _isoc99_scanf((unsigned __int64)"%s"); if ( strlen((const char *)&v11) == 26 ) { v3 = 0LL; if ( (v11 ^ 0xAB) == list1 ) { while ( (v12[v3] ^ (unsigned __int8)*(&v5 + ((signed int)v3 + 1) % 6)) == byte_6B41D1[v3] ) { if ( ++v3 == 25 ) { printf((unsigned __int64)"Congratulations!"); return 0; } } } } printf((unsigned __int64)"Password Wrong!! Please try again."); return 0; }
代码的思路很简单,
第一位flag先异或0xAB,之后的flag在while循环中
就是把v5-v10作为密码表,然后异或假码,然后验证
byte_6B41D1 的值为 9E 67 12 4E 9D 98 AB 00 06 46 8A F4 B4 06 0B 43 DC D9 A4 6C 31 74 9C D2 A0
但是(unsigned __int8)*(&v5 + ((signed int)v3 + 1) % 6) 其实取出的数据是v5-v10的int8数据
所以我们需要对v5-v10的二进制取后八位
比如 -85 = 1111111111111111111111111111111111111111111111111111111110101011
然后取后面8位,即 10101011 所以v5 = 171
转化完之后,我们开始用python编写代码
1 2 3 4 5 print 'first is '+chr(0xFB^0xAB) s = "\x9E\x67\x12\x4E\x9D\x98\xAB\x00\x06\x46\x8A\xF4\xB4\x06\x0B\x43\xDC\xD9\xA4\x6C\x31\x74\x9C\xD2\xA0" key_box = [171,221,51,84,53,239] for i in range(0,25): print chr(key_box[(i+1) % 6]^ord(s[i]))
PCTF{r3v3Rse_i5_v3ry_eAsy}