[网鼎杯 2020 青龙组]singal

第一次真正接触VM 熟悉了三天 大概知道应该咋做了 但是在不使用“黑科技“(Angr)的情况下不管怎样做都挺繁琐 考虑过把swtich里的处理逻辑改成生成flag的逻辑

发现难度也还是挺大 因为涉及了两三个索引需要一起变 还涉及判断逻辑 因此决定先正向输出所有的处理逻辑

#include <stdio.h>
#include <string.h>

int main(){
  int result;
  char flag[200];
  char v4;
  int index_2;
  int index_3;
  int index_4;
  int index_1;
  int op_eip;

  op_eip = 0;
  index_1 = 0;
  index_4 = 0;
  index_3 = 0;
  index_2 = 0;

  int op_code[]={4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1};
  
  while ( 1 )
  {
    result = op_eip;
    if ( op_eip >= 83 )
      return result;
    switch ( op_code[op_eip] )
    {
      case 1:   
        printf("flag[index_3++ + 100] = v4; ++index_1;\n\n");
        ++op_eip;
        ++index_3;
        ++index_1;
        break;
      case 2:
        printf("v4 = op_code[op_eip + 1] + flag[index_1];\n");
        op_eip += 2;
        break;
      case 3:
        printf("v4 = flag[index_1] - op_code[op_eip + 1];\n");
        op_eip += 2;
        break;
      case 4:
        printf("v4 = op_code[op_eip + 1] ^ flag[index_1];\n");
        op_eip += 2;
        break;
      case 5:
        printf("v4 = op_code[op_eip + 1] * flag[index_1];\n");
        op_eip += 2;
        break;
      case 6:
        printf("++op_eip;\n");
        break;
      case 8:
        printf("flag[index_2++] = v4; \n");
        ++op_eip;
        ++index_2;
        break;
      case 11:
        printf("v4 = flag[index_1] - 1; \n");
        ++op_eip;
        break;
      case 12:
        printf("v4 = flag[index_1] + 1; \n");
        ++op_eip;
        break;
      default:
        continue;
    }
  }
    return 0;
}

得到如下:

int op_code[]={
4, 16, 8, 3, 5, 1,
4, 32, 8, 5, 3, 1,
3, 2, 8, 11, 1,
12, 8, 4, 4, 1,
5, 3, 8, 3, 33, 1,
11, 8, 11, 1,
4, 9,8, 3, 32, 1,
2, 81, 8, 4, 36, 1,
12, 8, 11, 1,
5, 2, 8, 2, 37, 1,
2, 54, 8, 4, 65, 1,
2, 32, 8, 5, 1, 1,
5, 3, 8, 2, 37, 1,
4, 9, 8, 3, 32, 1,
2, 65, 8, 12, 1};

int check[] ={34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122};

v4 = op_code[op_eip + 1] ^ flag[index_1];
flag[index_2++] = v4;
v4 = flag[index_1] - op_code[op_eip + 1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] ^ flag[index_1];
flag[index_2++] = v4;
v4 = op_code[op_eip + 1] * flag[index_1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = flag[index_1] - op_code[op_eip + 1];
flag[index_2++] = v4;
v4 = flag[index_1] - 1;
flag[index_3++ + 100] = v4; ++index_1;

v4 = flag[index_1] + 1;
flag[index_2++] = v4;
v4 = op_code[op_eip + 1] ^ flag[index_1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] * flag[index_1];
flag[index_2++] = v4;
v4 = flag[index_1] - op_code[op_eip + 1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = flag[index_1] - 1;
flag[index_2++] = v4;
v4 = flag[index_1] - 1;
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] ^ flag[index_1];
flag[index_2++] = v4;
v4 = flag[index_1] - op_code[op_eip + 1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] + flag[index_1];
flag[index_2++] = v4;
v4 = op_code[op_eip + 1] ^ flag[index_1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = flag[index_1] + 1;
flag[index_2++] = v4;
v4 = flag[index_1] - 1;
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] * flag[index_1];
flag[index_2++] = v4;
v4 = op_code[op_eip + 1] + flag[index_1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] + flag[index_1];
flag[index_2++] = v4;
v4 = op_code[op_eip + 1] ^ flag[index_1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] + flag[index_1];
flag[index_2++] = v4;
v4 = op_code[op_eip + 1] * flag[index_1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] * flag[index_1];
flag[index_2++] = v4;
v4 = op_code[op_eip + 1] + flag[index_1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] ^ flag[index_1];
flag[index_2++] = v4;
v4 = flag[index_1] - op_code[op_eip + 1];
flag[index_3++ + 100] = v4; ++index_1;

v4 = op_code[op_eip + 1] + flag[index_1];
flag[index_2++] = v4;
v4 = flag[index_1] + 1;
flag[index_3++ + 100] = v4; ++index_1;

发现其中有一定的规律性 每一层的逻辑都很简单 手动逆向15次得到如下表达式

flag[0]=(check[0]+5)^16;
flag[1]=(check[1]/3)^32;
flag[2]=(check[2]+1)+2;
flag[3]=(check[3]^4)-1;
flag[4]=(check[4]+33)/3;
flag[5]=(check[5]+1)+1;
flag[6]=(check[6]+32)^9;
flag[7]=(check[7]^36)-81;
flag[8]=(check[8]+1)-1;
flag[9]=(check[9]-37)/2;
flag[10]=(check[10]^65)-54;
flag[11]=(check[11]/1)-32;
flag[12]=(check[12]-37)/3;
flag[13]=(check[13]+32)^9;
flag[14]=(check[14]-1)-65;
#include <stdio.h>

int main(){
char flag[20]={0};
int check[] ={34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122};

flag[0]=(check[0]+5)^16;
flag[1]=(check[1]/3)^32;
flag[2]=(check[2]+1)+2;
flag[3]=(check[3]^4)-1;
flag[4]=(check[4]+33)/3;
flag[5]=(check[5]+1)+1;
flag[6]=(check[6]+32)^9;
flag[7]=(check[7]^36)-81;
flag[8]=(check[8]+1)-1;
flag[9]=(check[9]-37)/2;
flag[10]=(check[10]^65)-54;
flag[11]=(check[11]/1)-32;
flag[12]=(check[12]-37)/3;
flag[13]=(check[13]+32)^9;
flag[14]=(check[14]-1)-65;

for(int i=0;i<15;i++){
    printf("%c",flag[i]);
}
    return 0;
}
上一篇:调试Bug的神兵利器:通过WinDbg条件断点收集Log [转载]


下一篇:powerdesigner 逆向工程 mysql失败解决方案