-
-
Save jimouris/d7bf596aa82db5f9a8b77b83611b5cbe to your computer and use it in GitHub Desktop.
compUDer - bluehens CTF 2021
This file contains hidden or 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> | |
| #include <stdint.h> | |
| #include <stdbool.h> | |
| enum OPCODE { | |
| ADD = 0, SUB, MULT, AND, OR, LW, SW, HALT, NUM_OPCODES | |
| }; | |
| enum REGS { | |
| R0 = 0, R1, R2, R3, R4, R5, NUM_REGS, | |
| MEMORY_SZ = 64 | |
| }; | |
| void is_reg_valid(uint32_t reg) { | |
| if (reg < 0 || reg >= NUM_REGS) { | |
| printf("Not a valid register.\n"); | |
| exit(-1); | |
| } | |
| } | |
| void print_register_contents(uint32_t* reg_array) { | |
| printf("Registers:\n"); | |
| for (size_t i = 0; i < NUM_REGS; i++) { | |
| printf("%ld : %d\n", i, reg_array[i]); | |
| } | |
| printf("\n"); | |
| } | |
| void print_memory(uint32_t* memory) { | |
| printf("Memory:\n"); | |
| for (size_t i = 0; i < MEMORY_SZ + 2; i++) { | |
| printf("%d ", memory[i]); | |
| if (i == MEMORY_SZ/2) printf("\n"); | |
| } | |
| printf("\n"); | |
| } | |
| uint32_t fib_mem(uint32_t* memo, uint32_t n) { | |
| if (memo[n] == 0) { | |
| if (n <= 1) memo[n] = n; | |
| else memo[n] = fib_mem(memo, n-1) + fib_mem(memo, n-2); | |
| } | |
| return memo[n]; | |
| } | |
| int main(int argc, char **argv) { | |
| uint32_t reg_array[NUM_REGS] = { 0 }; | |
| uint32_t memory[MEMORY_SZ + 4] = { 0 }; | |
| reg_array[NUM_REGS - 1] = 1; | |
| fib_mem(memory, MEMORY_SZ/2); | |
| // print_memory(memory); | |
| printf("VM $ "); | |
| fflush(stdout); | |
| bool halt = 0; | |
| while (! halt) { | |
| size_t opcode, dst, src1, src2; | |
| scanf("%ld", &opcode); | |
| if (opcode < 0 || opcode >= NUM_OPCODES) { | |
| // printf("No such opcode exist.\n"); | |
| return -1; | |
| } | |
| scanf("%ld", &dst); | |
| is_reg_valid(dst); | |
| scanf("%ld", &src1); | |
| is_reg_valid(src1); | |
| scanf("%ld", &src2); | |
| is_reg_valid(src2); | |
| switch (opcode) { | |
| case ADD: | |
| // printf("ADD\n"); | |
| reg_array[dst] = reg_array[src1] + reg_array[src2]; | |
| break; | |
| case SUB: | |
| // printf("SUB\n"); | |
| reg_array[dst] = reg_array[src1] - reg_array[src2]; | |
| break; | |
| case MULT: | |
| // printf("MULT\n"); | |
| reg_array[dst] = reg_array[src1] * reg_array[src2]; | |
| break; | |
| case AND: | |
| // printf("AND\n"); | |
| reg_array[dst] = reg_array[src1] & reg_array[src2]; | |
| break; | |
| case OR: | |
| // printf("OR\n"); | |
| reg_array[dst] = reg_array[src1] | reg_array[src2]; | |
| break; | |
| case LW: | |
| // printf("LW\n"); | |
| if (dst < 0 || dst >= MEMORY_SZ + 4) { | |
| // printf("Out of bounds\n"); | |
| return -1; | |
| } | |
| reg_array[dst] = memory[(size_t) reg_array[src1]]; | |
| break; | |
| case SW: | |
| // printf("SW\n"); | |
| if (dst < 0 || dst >= MEMORY_SZ + 4) { | |
| // printf("Out of bounds\n"); | |
| return -1; | |
| } | |
| memory[(size_t) reg_array[dst]] = reg_array[src1]; | |
| break; | |
| case HALT: | |
| // printf("HALT\n"); | |
| halt = 1; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| // print_register_contents(reg_array); | |
| // print_memory(memory); | |
| } | |
| for (size_t i = 0; i < MEMORY_SZ/2 + 1; i++) { | |
| if (memory[i] != memory[MEMORY_SZ/2 + 1 + i]) { | |
| printf("Incorrect.\n"); | |
| return -1; | |
| } | |
| } | |
| char c; | |
| FILE* fp = fopen("flag.txt", "r"); | |
| if (fp == NULL) return EXIT_FAILURE; | |
| while ((c = getc(fp)) != EOF) { | |
| putchar(c); | |
| } | |
| fclose(fp); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment