Skip to content

Instantly share code, notes, and snippets.

@jimouris
Created March 21, 2021 19:03
Show Gist options
  • Select an option

  • Save jimouris/d7bf596aa82db5f9a8b77b83611b5cbe to your computer and use it in GitHub Desktop.

Select an option

Save jimouris/d7bf596aa82db5f9a8b77b83611b5cbe to your computer and use it in GitHub Desktop.
compUDer - bluehens CTF 2021
#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