Last active
May 28, 2018 12:02
-
-
Save spacemeowx2/6e88851f7547854bef86f3a6e27e98cc to your computer and use it in GitHub Desktop.
simple vm @ RCTF 2018
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 00 01 00 00 // X = 0x100 | |
LABEL: | |
0E // X++ | |
12 // A = [X] | |
0B // putchar(A) | |
0C 00 01 00 00 // loop | |
15 10 01 00 00 | |
0E // X++ | |
0A // getchar | |
0B | |
16 // [X] = A | |
0C 10 01 00 00 | |
function nand(a, b){ | |
return ~(a & b) | |
} | |
function xor(a, b) { | |
const z1 = nand(a, b) | |
const z2 = nand(z1, a) | |
const z3 = nand(z1, b) | |
return nand(z2, z3) | |
} | |
// 0x140: x | |
// 0x141: z1 | |
// 0x142: z3 | |
// 0x143: s[i] | |
// 0x144: xor(a, b) | |
// 0x145: LOOP_COUNT | |
03 40 01 00 00 // A = [0x140] | |
10 // X = A | |
11 F1 00 00 00 // A += 0xF1 | |
13 // A = [A] | |
04 43 01 00 00 // [0x143] = A | |
08 // A = nand(A, X) | |
04 41 01 00 00 // [0x141] = A (z1) | |
10 // X = A | |
03 40 01 00 00 // A = [0x140] (x, b) | |
08 // A = nand(A, X) | |
04 42 01 00 00 // [0x142] = A (z3) | |
03 41 01 00 00 // A = [0x141] (z1) | |
03 43 01 00 00 // A = [0x143] (s[i], a) | |
08 // A = nand(A, X) | |
10 // X = A | |
03 42 01 00 00 // A = [0x142] (z3) | |
08 // A = nand(A, X) | |
04 44 01 00 00 // [0x144] = A (result) | |
// xor over | |
66 // 0B | |
03 40 01 00 00 // A = [0x140] | |
11 F1 00 00 00 // A += 0xF1 | |
10 // X = A | |
03 44 01 00 00 // A = [0x144] (result) | |
16 // [X] = A | |
05 40 01 00 00 // X = [0x140] | |
0E // X++ | |
06 40 01 00 00 // [0x140] = X | |
0C 45 01 00 00 55 00 00 00 // LOOP [0x145] (32 times) | |
FF | |
// 0x146: CMP Counter | |
03 46 01 00 00 // A = [0x146] | |
11 05 00 00 00 // A += 0x05 | |
13 // A = [A] | |
10 // X = A | |
03 46 01 00 00 // A = [0x146] | |
11 11 01 00 00 // A += 0x111 | |
13 // A = [A] | |
17 // A = A - X | |
18 60 01 00 00 // JNE | |
0C 46 01 00 00 B6 00 00 00 // LOOP [0x146] (32 times) | |
01 76 01 00 00// JMP 176 | |
FF | |
15 50 01 00 00 // X = 0x150 wrong | |
// LOOP | |
0E // X++ | |
12 // A = [X] | |
0B // putchar(A) | |
0C 50 01 00 00 65 01 00 00 // loop [0x150] | |
00 00 00 00 00 // exit | |
15 56 01 00 00 // X = 0x155 right | |
// LOOP | |
0E // X++ | |
12 // A = [X] | |
0B // putchar(A) | |
0C 50 01 00 00 7B 01 00 00 // loop [0x150] | |
00 00 00 00 00 // exit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#ifdef _DEBUG | |
#define DEBUG(...) printf(__VA_ARGS__) | |
#else | |
#define DEBUG(...) | |
#endif | |
enum OP { | |
OP_END, | |
OP_JMP, | |
OP_MOVi, | |
OP_LOAD, | |
OP_STORE, | |
OP_LOAD_X, | |
OP_STORE_X, | |
OP_ADD, | |
OP_NAND, | |
OP_OR, | |
OP_INPUT, | |
OP_OUTPUT, | |
OP_LOOP, | |
OP_INC, | |
OP_INC_X, | |
OP_X2A, | |
OP_A2X, | |
OP_ADDi, | |
OP_MOV_FROM_X, | |
OP_MOV_FROM_A, | |
OP_MOVi_A, | |
OP_MOVi_X, | |
OP_SET_X_A, | |
OP_SUB, | |
OP_JNE, | |
OP_NOP = 0x66, | |
OP_DEBUG = -1 | |
}; | |
struct VM { | |
int size; | |
void* data; | |
int A; | |
int X; | |
}; | |
struct VM vm; | |
int run() | |
{ | |
#define READ_INT() ({int _t; _t = *(int*)(p + i); i += sizeof(int); _t;}) | |
char *p = (char *)vm.data; | |
int i = 0; | |
int src, dst, base, val; | |
while (233) | |
{ | |
// DEBUG("POS: %x OP: %x AX: %x %x\n", i, p[i], vm.A, vm.X); | |
switch (p[i++]) | |
{ | |
case OP_END: // 0 | |
return READ_INT(); | |
break; | |
case OP_JMP: // 1 | |
i = READ_INT(); | |
break; | |
case OP_MOVi: // 2 | |
dst = READ_INT(); | |
val = READ_INT(); | |
p[dst] = val; | |
break; | |
case OP_LOAD: // 3 | |
src = READ_INT(); | |
vm.A = p[src]; | |
break; | |
case OP_STORE: // 4 | |
dst = READ_INT(); | |
p[dst] = vm.A; | |
break; | |
case OP_LOAD_X: // 5 | |
src = READ_INT(); | |
vm.X = p[src]; | |
break; | |
case OP_STORE_X: // 6 | |
dst = READ_INT(); | |
p[dst] = vm.X; | |
break; | |
case OP_ADD: // 7 | |
vm.A += vm.X; | |
break; | |
case OP_NAND: // 8 | |
vm.A = ~(vm.A & vm.X); | |
break; | |
case OP_INPUT: // 0A | |
vm.A = getchar(); | |
break; | |
case OP_OUTPUT: // 0B | |
// DEBUG("Output: %x\n", vm.A); | |
putchar(vm.A); | |
break; | |
case OP_LOOP: // 0C | |
src = READ_INT(); | |
dst = READ_INT(); | |
// DEBUG("LOOP %d to %d\n", p[src], dst); | |
if (p[src]) { | |
i = dst; | |
p[src]--; | |
} | |
break; | |
case OP_INC_X: // 0E | |
vm.X++; | |
break; | |
case OP_X2A: // 0F | |
vm.A = vm.X; | |
break; | |
case OP_A2X: // 10 | |
vm.X = vm.A; | |
break; | |
case OP_ADDi: // 11 | |
val = READ_INT(); | |
vm.A += val; | |
break; | |
case OP_INC: | |
vm.A++; | |
break; | |
case OP_MOV_FROM_X: // 12 | |
vm.A = p[vm.X]; | |
break; | |
case OP_MOV_FROM_A: // 13 | |
vm.A = p[vm.A]; | |
break; | |
case OP_MOVi_A: // 14 | |
vm.A = READ_INT(); | |
break; | |
case OP_MOVi_X: // 15 | |
vm.X = READ_INT(); | |
break; | |
case OP_SET_X_A: // 16 | |
p[vm.X] = vm.A; | |
break; | |
case OP_SUB: // 17 | |
vm.A -= vm.X; | |
break; | |
case OP_JNE: // 18 | |
dst = READ_INT(); | |
if (vm.A != 0) | |
{ | |
i = dst; | |
} | |
break; | |
case OP_NOP: | |
break; | |
#ifdef _DEBUG | |
case OP_DEBUG: | |
puts("DEBUG"); | |
break; | |
#endif | |
} | |
if (i >= vm.size) | |
{ | |
break; | |
} | |
} | |
return 0; | |
} | |
#ifdef _DEBUG | |
void fuck() | |
{ | |
FILE* fp = fopen("fuck.bin", "wb"); | |
fwrite(vm.data, 1, vm.size, fp); | |
fclose(fp); | |
} | |
#endif | |
int main() | |
{ | |
FILE* file = fopen("p.bin", "rb"); | |
if (file == NULL) | |
{ | |
puts("err 0"); | |
return -1; | |
} | |
fseek(file, 0, SEEK_END); | |
vm.size = ftell(file); | |
fseek(file, 0, SEEK_SET); | |
if (vm.size <= 0) | |
{ | |
puts("err 1"); | |
return -1; | |
} | |
DEBUG("Size: %d\n", vm.size); | |
vm.data = malloc(vm.size); | |
if (vm.data == NULL) | |
{ | |
puts("err 3"); | |
return -1; | |
} | |
if (fread(vm.data, 1, vm.size, file) != vm.size) | |
{ | |
puts("err 4"); | |
return -1; | |
} | |
fclose(file); | |
DEBUG("Run\n"); | |
if (run() != 0) | |
{ | |
puts("err 5"); | |
return -1; | |
} | |
free(vm.data); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment