2020-Wangding Cup (Qinglong Group) signal

vm_operad

int __cdecl vm_operad(int *a1, int a2)
{
    
    
  int result; // eax@2
  char v3[100]; // [sp+13h] [bp-E5h]@4
  char v4[100]; // [sp+77h] [bp-81h]@5
  char v5; // [sp+DBh] [bp-1Dh]@5
  int v6; // [sp+DCh] [bp-1Ch]@1
  int v7; // [sp+E0h] [bp-18h]@1
  int v8; // [sp+E4h] [bp-14h]@1
  int v9; // [sp+E8h] [bp-10h]@1
  int v10; // [sp+ECh] [bp-Ch]@1

  v10 = 0;
  v9 = 0;
  v8 = 0;
  v7 = 0;
  v6 = 0;
  while ( 1 )
  {
    
    
    result = v10;
    if ( v10 >= a2 )
      return result;
    switch ( a1[v10] )
    {
    
    
      case 10:
        read(v3);
        ++v10;
        break;
      case 1:
        v4[v7] = v5;
        ++v10;
        ++v7;
        ++v9;
        break;
      case 2:
        v5 = a1[v10 + 1] + v3[v9];
        v10 += 2;
        break;
      case 3:
        v5 = v3[v9] - LOBYTE(a1[v10 + 1]);
        v10 += 2;
        break;
      case 4:
        v5 = a1[v10 + 1] ^ v3[v9];
        v10 += 2;
        break;
      case 5:
        v5 = a1[v10 + 1] * v3[v9];
        v10 += 2;
        break;
      case 6:
        ++v10;
        break;
      case 7:
        if ( v4[v8] != a1[v10 + 1] )
        {
    
    
          printf("what a shame...");
          exit(0);
        }
        ++v8;
        v10 += 2;
        break;
      case 11:
        v5 = v3[v9] - 1;
        ++v10;
        break;
      case 12:
        v5 = v3[v9] + 1;
        ++v10;
        break;
      case 8:
        v3[v6] = v5;
        ++v10;
        ++v6;
        break;
      default:
        continue;
    }
  }
}

Function function

Use the process data (and encrypted data) saved in the file string and the console data to verify the flag (the data saved in the file string not only plays the role of the process but also the encryption)

read

size_t __cdecl read(char *a1)
{
    
    
  size_t result; // eax@1

  printf("string:");
  scanf("%s", a1);
  result = strlen(a1);
  if ( result != 15 )
  {
    
    
    puts("WRONG!\n");
    exit(0);
  }
  return result;
}

Function function

This read function is used to read the commands entered in the console, I think it is the flag

0A 00 00 00 04 00 00 00  10 00 00 00 08 00 00 00
03 00 00 00 05 00 00 00  01 00 00 00 04 00 00 00
20 00 00 00 08 00 00 00  05 00 00 00 03 00 00 00
01 00 00 00 03 00 00 00  02 00 00 00 08 00 00 00
0B 00 00 00 01 00 00 00  0C 00 00 00 08 00 00 00
04 00 00 00 04 00 00 00  01 00 00 00 05 00 00 00
03 00 00 00 08 00 00 00  03 00 00 00 21 00 00 00
01 00 00 00 0B 00 00 00  08 00 00 00 0B 00 00 00
01 00 00 00 04 00 00 00  09 00 00 00 08 00 00 00
03 00 00 00 20 00 00 00  01 00 00 00 02 00 00 00
51 00 00 00 08 00 00 00  04 00 00 00 24 00 00 00
01 00 00 00 0C 00 00 00  08 00 00 00 0B 00 00 00
01 00 00 00 05 00 00 00  02 00 00 00 08 00 00 00
02 00 00 00 25 00 00 00  01 00 00 00 02 00 00 00
36 00 00 00 08 00 00 00  04 00 00 00 41 00 00 00
01 00 00 00 02 00 00 00  20 00 00 00 08 00 00 00
05 00 00 00 01 00 00 00  01 00 00 00 05 00 00 00
03 00 00 00 08 00 00 00  02 00 00 00 25 00 00 00
01 00 00 00 04 00 00 00  09 00 00 00 08 00 00 00
03 00 00 00 20 00 00 00  01 00 00 00 02 00 00 00
41 00 00 00 08 00 00 00  0C 00 00 00 01 00 00 00
07 00 00 00 22 00 00 00  07 00 00 00 3F 00 00 00
07 00 00 00 34 00 00 00  07 00 00 00 32 00 00 00
07 00 00 00 72 00 00 00  07 00 00 00 33 00 00 00
07 00 00 00 18 00 00 00  07 00 00 00 A7 FF FF FF
07 00 00 00 31 00 00 00  07 00 00 00 F1 FF FF FF
07 00 00 00 28 00 00 00  07 00 00 00 84 FF FF FF
07 00 00 00 C1 FF FF FF  07 00 00 00 1E 00 00 00
07 00 00 00 7A 00 00 00

Process code

  case 10:
        read(v3);
        ++v10;
        break;
      case 1:
        v4[v7] = v5;
        ++v10;
        ++v7;
        ++v9;
        break;
      case 2:
        v5 = a1[v10 + 1] + v3[v9];
        v10 += 2;
        break;
      case 3:
        v5 = v3[v9] - LOBYTE(a1[v10 + 1]);
        v10 += 2;
        break;
      case 4:
        v5 = a1[v10 + 1] ^ v3[v9];
        v10 += 2;
        break;
      case 5:
        v5 = a1[v10 + 1] * v3[v9];
        v10 += 2;
        break;
      case 6:
        ++v10;
        break;
      case 7:
        if ( v4[v8] != a1[v10 + 1] )
        {
    
    
          printf("what a shame...");
          exit(0);
        }
        ++v8;
        v10 += 2;
        break;
      case 11:
        v5 = v3[v9] - 1;
        ++v10;
        break;
      case 12:
        v5 = v3[v9] + 1;
        ++v10;
        break;
      case 8:
        v3[v6] = v5;
        ++v10;
        ++v6;
        break;
      default:
        continue;

Introduce what each number has to do (but the process does not follow this way)

  1. 0x0A: Read the 15 characters entered by the console
  2. 0x4: Find the value of v5, the next position value of the file string ^ the first data of the console
  3. 0x10:continue
  4. 0x08: v5 is assigned to the first element of the v3 array
  5. 0x03: (the first element of the v3 array-the next position value of the file string) is assigned to v5
  6. 0x05: Find the value of V5, the next position value of the file string * the first data of the console
  7. 0x01: v5 is assigned to the first element of the v4 array, and then v9 is incremented, which means that the second data of the console needs to be used next
  8. 0x4: Find the value of v5, the next position value of the file string ^ the first data of the console
  9. 0x20:continue
  10. 0x08: v5 is assigned to the second element of the v3 array
  11. 0x05: Find the value of V5, the next position value of the file string * the second data of the console
  12. 0x03: (the second element of the v3 array-the next position value of the file string) is assigned to v5
  13. 0x01: v5 is assigned to the second element of the v4 array, and then v9 is incremented, which means that the third data of the console needs to be used next
    ……………………………………
    Insert picture description here

Insert picture description here
Insert picture description here

note:

When the file string is encountered 2 ,3,4,5,7, the next value does not control the flow (the flow is skipped directly!) , but is used as the calculation data . . So just say the flow of execution is not written above the

Validation data (reverse focus)

07 00 00 00 22 00 00 00  07 00 00 00 3F 00 00 00
07 00 00 00 34 00 00 00  07 00 00 00 32 00 00 00
07 00 00 00 72 00 00 00  07 00 00 00 33 00 00 00
07 00 00 00 18 00 00 00  07 00 00 00 A7 FF FF FF
07 00 00 00 31 00 00 00  07 00 00 00 F1 FF FF FF
07 00 00 00 28 00 00 00  07 00 00 00 84 FF FF FF
07 00 00 00 C1 FF FF FF  07 00 00 00 1E 00 00 00
07 00 00 00 7A 00 00 00

Here are all used to verify: the
order is 22h 3fh 34h 32h 72h 33h 18h ffffffa7h 31h fffff1h 28h ffff84h 1eh 7ah
therefore in accordance with standard string, and then each character to do it again against the operation, and then we got lost in the console something, then immediately it ended. . .

Reverse Thinking

  1. (0x22+5)^ 0x10
  2. (0x3f/3) ^ 0x20
  3. (0x34 + 1) + 2
  4. (0x32 ^ 4) - 1
  5. (0x72 + 0x21) / 3
  6. (0x33 + 1) + 1
  7. (0x18 + 0x20) ^ 9
  8. (0xa7 ^ 0x24) -0x51
  9. (0x31 + 1) - 1
  10. (0xf1 - 0x25) / 2
  11. (0x28 ^ 0x41) - 0x36
  12. (0x84 / 1) - 0x20
  13. (0xc1 - 0x25) / 3
  14. (0x1e + 0x20) ^ 9
  15. (0x7a - 1) - 0x41
flag{
    
    757515121f3d478}

Guess you like

Origin blog.csdn.net/CSNN2019/article/details/115314613