BUUCTF_Re_[ACTF新生赛2020]rome
main函数:
int func() { int result; // eax int v1[4]; // [esp+14h] [ebp-44h] unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREF unsigned __int8 v3; // [esp+25h] [ebp-33h] unsigned __int8 v4; // [esp+26h] [ebp-32h] unsigned __int8 v5; // [esp+27h] [ebp-31h] unsigned __int8 v6; // [esp+28h] [ebp-30h] int v7; // [esp+29h] [ebp-2Fh] int v8; // [esp+2Dh] [ebp-2Bh] int v9; // [esp+31h] [ebp-27h] int v10; // [esp+35h] [ebp-23h] unsigned __int8 v11; // [esp+39h] [ebp-1Fh] char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREF strcpy(v12, "Qsw3sj_lz4_Ujw@l"); printf("Please input:"); scanf("%s", &v2); result = v2; if ( v2 == 'A' ) { result = v3; if ( v3 == 'C' ) { result = v4; if ( v4 == 'T' ) { result = v5; if ( v5 == 'F' ) { result = v6; if ( v6 == '{' ) { result = v11; if ( v11 == '}' ) { v1[0] = v7; v1[1] = v8; v1[2] = v9; v1[3] = v10; *&v12[17] = 0; while ( *&v12[17] <= 15 ) { if ( *(v1 + *&v12[17]) > 64 && *(v1 + *&v12[17]) <= 90 ) *(v1 + *&v12[17]) = (*(v1 + *&v12[17]) - 51) % 26 + 65; if ( *(v1 + *&v12[17]) > 96 && *(v1 + *&v12[17]) <= 122 ) *(v1 + *&v12[17]) = (*(v1 + *&v12[17]) - 79) % 26 + 97; ++*&v12[17]; } *&v12[17] = 0; while ( *&v12[17] <= 15 ) { result = v12[*&v12[17]]; if ( *(v1 + *&v12[17]) != result ) return result; ++*&v12[17]; } result = printf("You are correct!"); } } } } } } return result; }
核心在中间两个while函数加密:
第一个while分析可以知道是对flag花括号里的字符进行大小写判断并加密
第二个while就是判断加密后的flag是否和前面的v12相等,如果相等就printf
这里加一个别人ida分析出来的main函数代码,和我的完全不一样,所以我就纠结了好久:
int func() { int result; // eax int v1; // [esp+14h] [ebp-44h] int v2; // [esp+18h] [ebp-40h] int v3; // [esp+1Ch] [ebp-3Ch] int v4; // [esp+20h] [ebp-38h] unsigned __int8 v5; // [esp+24h] [ebp-34h] unsigned __int8 v6; // [esp+25h] [ebp-33h] unsigned __int8 v7; // [esp+26h] [ebp-32h] unsigned __int8 v8; // [esp+27h] [ebp-31h] unsigned __int8 v9; // [esp+28h] [ebp-30h] int v10; // [esp+29h] [ebp-2Fh] int v11; // [esp+2Dh] [ebp-2Bh] int v12; // [esp+31h] [ebp-27h] int v13; // [esp+35h] [ebp-23h] unsigned __int8 v14; // [esp+39h] [ebp-1Fh] char v15; // [esp+3Bh] [ebp-1Dh] char v16; // [esp+3Ch] [ebp-1Ch] char v17; // [esp+3Dh] [ebp-1Bh] char v18; // [esp+3Eh] [ebp-1Ah] char v19; // [esp+3Fh] [ebp-19h] char v20; // [esp+40h] [ebp-18h] char v21; // [esp+41h] [ebp-17h] char v22; // [esp+42h] [ebp-16h] char v23; // [esp+43h] [ebp-15h] char v24; // [esp+44h] [ebp-14h] char v25; // [esp+45h] [ebp-13h] char v26; // [esp+46h] [ebp-12h] char v27; // [esp+47h] [ebp-11h] char v28; // [esp+48h] [ebp-10h] char v29; // [esp+49h] [ebp-Fh] char v30; // [esp+4Ah] [ebp-Eh] char v31; // [esp+4Bh] [ebp-Dh] int i; // [esp+4Ch] [ebp-Ch] v15 = 'Q'; v16 = 's'; v17 = 'w'; v18 = '3'; v19 = 's'; v20 = 'j'; v21 = '_'; v22 = 'l'; v23 = 'z'; v24 = '4'; v25 = '_'; v26 = 'U'; v27 = 'j'; v28 = 'w'; v29 = '@'; v30 = 'l'; v31 = 0; printf("Please input:"); scanf("%s", &v5); result = v5; if ( v5 == 'A' ) { result = v6; if ( v6 == 'C' ) { result = v7; if ( v7 == 'T' ) { result = v8; if ( v8 == 'F' ) { result = v9; if ( v9 == '{' ) { result = v14; if ( v14 == '}' ) { v1 = v10; v2 = v11; v3 = v12; v4 = v13; for ( i = 0; i <= 15; ++i ) { if ( *((_BYTE *)&v1 + i) > 64 && *((_BYTE *)&v1 + i) <= 90 )//如果是大写字母 *((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 51) % 26 + 65; if ( *((_BYTE *)&v1 + i) > 96 && *((_BYTE *)&v1 + i) <= 122 )//如果是小写字母 *((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 79) % 26 + 97; } for ( i = 0; i <= 15; ++i ) { result = (unsigned __int8)*(&v15 + i); if ( *((_BYTE *)&v1 + i) != (_BYTE)result ) return result; } result = printf("You are correct!"); } } } } } } return result; }
发现第一个循环开始前定义的单独变量,我的定义的就是一个数组,我一直想不明白数组怎么加减,
脚本逻辑就是在可见字符里遍历找到某个字符加密后和v12的值相等:
flag='' v12='Qsw3sj_lz4_Ujw@l' for i in range(16): for k in range(32,127): z=k if k>64 and k<=90: k=(k-51)%26+65 if k>96 and k<=122: k=(k-79)%26+97 if chr(k)==v12[i]: flag+=chr(z) print(flag)
得到flag:
flag{Cae3ar_th4_Gre@t}