2.
int __usercall sub_415280@(int xmm0_4_0@ , int a1, int a2) { int v3; // edx FILE *v4; // eax int v5; // edx int v6; // ecx char *v7; // eax int v8; // edx int v9; // ecx int v10; // ST04_4 int v11; // ST08_4 char v13; // [esp+0h] [ebp-134h] char Buf; // [esp+D0h] [ebp-64h] size_t i; // [esp+100h] [ebp-34h] FILE *File; // [esp+10Ch] [ebp-28h] char v17; // [esp+118h] [ebp-1Ch] int v18; // [esp+130h] [ebp-4h] int savedregs; // [esp+134h] [ebp+0h] sub_411208((int)&unk_41C008); printf("Input Your Flag:\n", v13); sub_41137F("%19s", (unsigned int)&v17); // v12大小为24 if ( a1 != 2 ) { printf("Input error!\n", v13); exit(1); } printf("%s\n", *(_DWORD *)(a2 + 4)); // 在执行文件时,执行的第一个参数 for ( i = 0; i < j_strlen(*(const char **)(a2 + 4)); ++i )// 遍历执行文件时输入的字符串 *(_BYTE *)(*(_DWORD *)(a2 + 4) + i) += i; // 每一位 str[i] += i if ( !j_strcmp(Str1, *(const char **)(a2 + 4)) )// 和“fmcj2y~{”比较 { v4 = fopen(*(const char **)(a2 + 4), "r"); // 下面两句文件操作,应该是获取输入的 File = (FILE *)sub_411212(v6, v5, &v13 == &v13, (int)v4, xmm0_4_0); if ( File ) { v7 = fgets(&Buf, 40, File); sub_411212(v9, v8, &v13 == &v13, (int)v7, xmm0_4_0); if ( j_strlen(&Buf) != 32 || j_strlen(&Buf) % 2 == 1 )// 输入长度应该是32 exit(1); sub_4113B1(xmm0_4_0, &Buf, (int)&unk_41A4E0); if ( sub_4113B6(xmm0_4_0, (int)&unk_41A4E0) ) printf("flag{%s}", (unsigned int)&Buf); else printf("Input Error!\n", v13); } else { printf("Input Error!\n", v13); } } else { printf("Input Error!\n", v13); } sub_411235(&savedregs, dword_4154C4, 0, v3); return sub_411212((unsigned int)&savedregs ^ v18, v11, 1, v10, xmm0_4_0); }
str1 = 'fmcj2y~{' str2 = '' for i in range(len(str1)): str2 += chr(ord(str1[i]) - i) print (str2
3.代码分析
3.1 sub_4113B1函数
int __usercall sub_414E50@(int a1@ , char *Str, int a3) { unsigned int v3; // eax int v4; // edx int v5; // ecx char v7; // [esp+0h] [ebp-E4h] int v8; // [esp+D0h] [ebp-14h] signed int i; // [esp+DCh] [ebp-8h] sub_411208((int)&unk_41C008); dword_41A078[8] = 0xA7; dword_41A078[9] = 0xDE; dword_41A078[10] = 0xDA; dword_41A078[11] = 0x46; dword_41A078[12] = 0xAB; dword_41A078[13] = 0x2E; dword_41A078[14] = 0xFF; dword_41A078[15] = 0xDB; for ( i = 0; ; i += 2 ) // 0开始,2跳 { v3 = j_strlen(Str); // v3为Buf长度32 if ( i >= v3 ) break; if ( Str[i] >= 48 && Str[i] <= 57 ) // '0'~'9' { *(_DWORD *)(a3 + 4 * (i / 2)) = Str[i] - 48;// 字符转换为整型 } else { if ( Str[i] < 97 || Str[i] > 102 ) // 非'a'~'f',说明组成的字符是'0'~'9'||'a'~'f',十六进制啊 { printf("Input Error!\n", v7); exit(0); } *(_DWORD *)(a3 + 4 * (i / 2)) = Str[i] - 87;// 十六进制啊!'a'~'f'就是10~15 } *(_DWORD *)(a3 + 4 * (i / 2)) *= 16; // 最后还要乘16 if ( Str[i + 1] >= 48 && Str[i + 1] <= 57 ) // i=1,3,5...如果为数字 { v8 = Str[i + 1] - 48; // v8=字符转数字 } else { if ( Str[i + 1] < 97 || Str[i + 1] > 102 ) { printf("Input Error!\n", v7); exit(0); } v8 = Str[i + 1] - 87; // i=1,3,5...如果是'a'~'f'字符转数字,10~15 } *(_DWORD *)(a3 + 4 * (i / 2)) += v8; // a3[i]+=v8 } return sub_411212(v5, v4, 1, v3, a1); }
3.2 sub_4113B6函数
int __usercall sub_411D90@(int a1@ , int a2) { int v2; // edx int v3; // ecx int v4; // eax signed int i; // [esp+D0h] [ebp-8h] sub_411208((int)&unk_41C008); for ( i = 0; i < 16; ++i ) { v3 = a2; // v3赋值为之前得到的整数 v2 = *(_DWORD *)(a2 + 4 * i) + 1; // v2=v2[i]+1 if ( v2 != dword_41A078[i] ) { v4 = 0; return sub_411212(v3, v2, 1, v4, a1); } } v4 = 1; return sub_411212(v3, v2, 1, v4, a1); }
if ( sub_4113B6(xmm0_4_0, (int)&unk_41A4E0) ) printf("flag{%s}", (unsigned int)&Buf);
4.get flag!
0x02
下载链接:https://www.lanzous.com/i7atzwd
原题:
http://www.pianshen.com/article/898554458
5acb06231724c8c369bae711166dbe85
0x04
2019中国杭州网络安全技能大赛 预选赛原题,不过没解完。
https://xhyeax.github.io/2019/04/07/2019-hzwas-wp/
0x05 总结
湖湘杯又被吐槽了...Reverse基本都是签到题,菜鸡做着还是舒服。