[网鼎杯 2020 青龙组]singal
找到主函数
提取v4->&byte_403040数组
进入vm_operad函数
进入read函数
发现flag的长度为15
exp:
#include<stdio.h> int __cdecl vm_operad(int* a1, int len_114); int __cdecl vm_decode(int* a1, int len_114); int main() { char ida_chars[] = { 10, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 81, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 65, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 65, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 7, 0, 0, 0, 63, 0, 0, 0, 7, 0, 0, 0, 52, 0, 0, 0, 7, 0, 0, 0, 50, 0, 0, 0, 7, 0, 0, 0, 114, 0, 0, 0, 7, 0, 0, 0, 51, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 7, 0, 0, 0, 167, 255, 255, 255, 7, 0, 0, 0, 49, 0, 0, 0, 7, 0, 0, 0, 241, 255, 255, 255, 7, 0, 0, 0, 40, 0, 0, 0, 7, 0, 0, 0, 132, 255, 255, 255, 7, 0, 0, 0, 193, 255, 255, 255, 7, 0, 0, 0, 30, 0, 0, 0, 7, 0, 0, 0, 122, 0, 0, 0 }; vm_operad(ida_chars, 114);//从“char*”到“int* ”的类型不兼容,编译器强制转为int*类型 vm_decode(ida_chars, 114); return 0; } int __cdecl vm_operad(int* a1, int len_114) { int result; // eax char flag[200] = "111111111111111"; //flag长度为15 char v4; // [esp+DBh] [ebp-1Dh] int v5; // [esp+DCh] [ebp-1Ch] int v6; // [esp+E0h] [ebp-18h] int v7; // [esp+E4h] [ebp-14h] int v8; // [esp+E8h] [ebp-10h] int i; // [esp+ECh] [ebp-Ch] i = 0; v8 = 0; v7 = 0; v6 = 0; v5 = 0; while (1) { result = i; if (i >= len_114) return result; switch (a1[i]) { case 1: flag[v6 + 100] = v4; ++i; ++v6; ++v8; break; case 2: v4 = a1[i + 1] + flag[v8]; i += 2; break; case 3: v4 = flag[v8] - a1[i + 1]; i += 2; break; case 4: v4 = a1[i + 1] ^ flag[v8]; i += 2; break; case 5: v4 = a1[i + 1] * flag[v8]; i += 2; break; case 6: ++i; break; case 7: printf("%d,", a1[i + 1]);//输出符合条件的code ++v7; i += 2; break; case 8: flag[v5] = v4; ++i; ++v5; break; case 10: //read(flag); ++i; break; case 11: v4 = flag[v8] - 1; ++i; break; case 12: v4 = flag[v8] + 1; ++i; break; default: continue; } //printf("%d,", i);//输出下表 } } //逆向过程为从后面向前面走 int __cdecl vm_decode(int* a1, int len_114) { unsigned char flag[100] = { '\0'}; // [esp+13h] [ebp-E5h] BYREF int v4; // [esp+DBh] [ebp-1Dh] int v5; // [esp+DCh] [ebp-1Ch] int v6; // [esp+E0h] [ebp-18h] int v7; // [esp+E4h] [ebp-14h] int v8; // [esp+E8h] [ebp-10h] int i; // [esp+ECh] [ebp-Ch] v8 = 15; v7 = 15; v6 = 15; v5 = 15; unsigned int code[] = { 34,63,52,50,114,51,24,-89,49,-15,40,-124,-63,30,122, }; char index[] = { 1,3,4,6,7,9,10,12,13,15,16,17,18,19,20,22,23,25,26,28,29,30,31,32,33,35,36,38,39,41,42,44,45,46,47,48,49,51,52,54,55,57,58,60,61,63,64,66,67,69,70,72,73,75,76,78,79,81,82,83,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114, }; for(int k=75;k>=0;k--) { i = index[k]; switch (a1[i]) { case 1: --v8; --v6; v4 = code[v6]; break; case 2: flag[v8] = v4 - a1[i + 1]; break; case 3: flag[v8] = v4 + a1[i + 1]; break; case 4: flag[v8] = v4 ^ a1[i + 1]; break; case 5: flag[v8] = v4 / a1[i + 1]; break; case 6://可删除 break; case 7://可删除 --v7; break; case 8: v4 = flag[--v5]; break; case 10://可删除 break; case 11: flag[v8] = v4 + 1; break; case 12: flag[v8] = v4 - 1; break; default: continue; } } printf("\n%s", flag); return 0; }