这道题的前面一部分我分析不是很清楚,参考了其他大佬的博客才能理解
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| int __cdecl main(int argc, const char **argv, const char **envp) { __int64 v3; // rbx __int64 v4; // rax __int128 *v5; // rax __int64 v6; // r11 __int128 *v7; // r14 int v8; // edi __int128 *v9; // rsi char v10; // r10 int v11; // edx __int64 v12; // r8 unsigned __int64 v13; // rcx __int64 v14; // rcx unsigned __int64 v15; // rax unsigned __int64 i; // rax __int64 v17; // rax size_t v18; // rsi _BYTE *v19; // rbx _BYTE *v20; // r9 int v21; // er11 char *v22; // r8 __int64 v23; // rcx char v24; // al __int64 v25; // r9 __int64 v26; // rdx __int64 v27; // rax size_t Size; // [rsp+20h] [rbp-48h] BYREF __int128 v30; // [rsp+28h] [rbp-40h] BYREF int v31; // [rsp+38h] [rbp-30h] int v32; // [rsp+3Ch] [rbp-2Ch] int Code[4]; // [rsp+40h] [rbp-28h] BYREF int v34; // [rsp+50h] [rbp-18h]
*Code = 0i64; v34 = 0; sub_1400018C0(std::cin, argv, Code); v3 = -1i64; v4 = -1i64; do ++v4; while ( *(Code + v4) ); if ( v4 != 19 ) { sub_140001620(std::cout, "error\n"); _exit(Code); } v5 = operator new(5ui64); v6 = *&::Code; v7 = v5; v8 = 0; v9 = v5; do { v10 = *(v9 + Code - v5); v11 = 0; *v9 = v10; v12 = 0i64; v13 = -1i64; do ++v13; while ( *(v6 + v13) ); if ( v13 ) { do { if ( v10 == *(v6 + v12) ) break; ++v11; ++v12; } while ( v11 < v13 ); } v14 = -1i64; do ++v14; while ( *(v6 + v14) ); if ( v11 == v14 ) _exit(v6); v9 = (v9 + 1); } while ( v9 - v5 < 4 ); *(v5 + 4) = 0; do ++v3; while ( *(Code + v3) ); v15 = 0i64; v30 = *v7; while ( *(&v30 + v15) ) { if ( !*(&v30 + v15 + 1) ) { ++v15; break; } if ( !*(&v30 + v15 + 2) ) { v15 += 2i64; break; } if ( !*(&v30 + v15 + 3) ) { v15 += 3i64; break; } v15 += 4i64; if ( v15 >= 16 ) break; } for ( i = v15 + 1; i < 0x10; ++i ) *(&v30 + i) = 0; v17 = sub_140001AB0(Code, v3, &v30, &Size); v18 = Size; v19 = v17; v20 = operator new(Size); v21 = 1; *v20 = v19[2]; v22 = v20 + 1; v20[1] = *v19; v20[2] = v19[3]; v20[3] = v19[1]; v20[4] = v19[6]; v20[5] = v19[4]; v20[6] = v19[7]; v20[7] = v19[5]; v20[8] = v19[10]; v20[9] = v19[8]; v20[10] = v19[11]; v20[11] = v19[9]; v20[12] = v19[14]; v20[13] = v19[12]; v20[14] = v19[15]; v20[15] = v19[13]; v20[16] = v19[18]; v20[17] = v19[16]; v20[18] = v19[19]; v20[19] = v19[17]; v20[20] = v19[22]; v20[21] = v19[20]; v20[22] = v19[23]; for ( v20[23] = v19[21]; v21 < v18; ++v22 ) { v23 = 0i64; if ( v21 / 3 > 0 ) { v24 = *v22; do { v24 ^= v20[v23++]; *v22 = v24; } while ( v23 < v21 / 3 ); } ++v21; } *&v30 = 0xC0953A7C6B40BCCEui64; v25 = v20 - &v30; *(&v30 + 1) = 0x3502F79120209BEFi64; v26 = 0i64; v31 = 0xC8021823; v32 = 0xFA5656E7; do { if ( *(&v30 + v26) != *(&v30 + v26 + v25) ) _exit(v8 * v8); ++v8; ++v26; } while ( v26 < 24 ); v27 = sub_140001620(std::cout, "You win!"); std::ostream::operator<<(v27, sub_1400017F0); return 0; }
|
用 findcrypt 看了一下,sub_140001AB0 这个函数是 xxtea 加密,然后在加密之后,后面对加密后的 flag 乱了一下顺序,再每 3 个数据位一组,进行了一些异或操作
至于前面一部分的操作,大佬的博客是这样说的
- 判断输入的字符串的每个字符是否包含在 "qwertyuiopasdfghjklzxcvbnm1234567890" 中
- 取输入字符串的前 4 位字符,即 "flag",扩展为 16 位,作为 xxtea 加密的秘钥 key
其中的 flag 扩展为 16 位,就只要在右端补 0 就可以了
由最后的 if 条件可知,v30,v30+1,v31,v32 就是最后的结果,这里要注意一下小端序的问题,要反过来写
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
| import xxtea
result = 'CE BC 40 6B 7C 3A 95 C0 EF 9B 20 20 91 F7 02 35 23 18 02 C8 E7 56 56 FA'.split(" ") res = [int(i,16) for i in result]
for i in range(7,-1,-1): t = 0 for n in range(0,i): if t == 0: t = res[0] else: t ^= res[n] for j in range(3): res[i*3+j] ^= t
box = [1,3,0,2,5,7,4,6,9,11,8,10,13,15,12,14,17,19,16,18,21,23,20,22] m = []
for i in range(len(box)): m.append(res[box[i]]) print(m)
key = 'flag'+'\x00'*12
print(xxtea.decrypt(bytes(m),key,padding=False))
|
得到 flag:flag