Article Directory
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)
- 0x0A: Read the 15 characters entered by the console
- 0x4: Find the value of v5, the next position value of the file string ^ the first data of the console
- 0x10:continue
- 0x08: v5 is assigned to the first element of the v3 array
- 0x03: (the first element of the v3 array-the next position value of the file string) is assigned to v5
- 0x05: Find the value of V5, the next position value of the file string * the first data of the console
- 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
- 0x4: Find the value of v5, the next position value of the file string ^ the first data of the console
- 0x20:continue
- 0x08: v5 is assigned to the second element of the v3 array
- 0x05: Find the value of V5, the next position value of the file string * the second data of the console
- 0x03: (the second element of the v3 array-the next position value of the file string) is assigned to v5
- 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
……………………………………
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
- (0x22+5)^ 0x10
- (0x3f/3) ^ 0x20
- (0x34 + 1) + 2
- (0x32 ^ 4) - 1
- (0x72 + 0x21) / 3
- (0x33 + 1) + 1
- (0x18 + 0x20) ^ 9
- (0xa7 ^ 0x24) -0x51
- (0x31 + 1) - 1
- (0xf1 - 0x25) / 2
- (0x28 ^ 0x41) - 0x36
- (0x84 / 1) - 0x20
- (0xc1 - 0x25) / 3
- (0x1e + 0x20) ^ 9
- (0x7a - 1) - 0x41
flag{
757515121f3d478}