Guest User

Synacor Challenge

a guest
May 1st, 2022
312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.90 KB | None | 0 0
  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <errors.h>
  4. #include <string.h>
  5.  
  6. #define STACK_SIZE 65536
  7. #define REGISTERS 8
  8. #define ADDRESS_SPACE_SIZE 32768 // Equal to 2^15
  9. #define MODM & 32767
  10.  
  11. int DEBUG = 0;
  12. int VDEBUG = 0;
  13.  
  14. #define debug_log if (DEBUG)
  15. #define vdebug_log if (VDEBUG)
  16.  
  17. int stack[STACK_SIZE];
  18. int stack_ptr = 0;
  19. int registers[REGISTERS];
  20. unsigned long *mem_ptr;
  21. unsigned long *mem_start;
  22.  
  23. int main(int argc, char* argv[]);
  24. unsigned long read(FILE *file_pointer);
  25. int process_opcodes();
  26. unsigned long convert_value();
  27.  
  28. unsigned long convert_value() {
  29.   unsigned long reg_val = *mem_ptr;
  30.   mem_ptr++;
  31.   unsigned long value = 0;
  32.   if (reg_val < ADDRESS_SPACE_SIZE) {
  33.     value = reg_val;
  34.     if (VDEBUG)
  35.       printf("Value Entered: %ld\n", value);
  36.   }
  37.   else {
  38.     value = registers[reg_val MODM];
  39.     vdebug_log printf("Accessing register %ld, value %ld\n", reg_val MODM, value);
  40.   }
  41.   return value % ADDRESS_SPACE_SIZE;
  42. }
  43.  
  44.  
  45. int process_opcodes() {
  46.   long opcode = *mem_ptr;
  47.   mem_ptr++;
  48.   vdebug_log printf("Opcode: %ld \t\t\t", opcode);
  49.  
  50.   switch(opcode) {
  51.  
  52.   case 0:
  53.     debug_log printf("Memory Address: %lld\n", (mem_ptr - mem_start));
  54.     return -1;
  55.     break;
  56.  
  57.   case 1: {
  58.     unsigned long set_reg = *mem_ptr MODM;
  59.     mem_ptr++;
  60.     unsigned long value = convert_value();
  61.     debug_log printf("SET %ld, %ld\n", set_reg, value);
  62.     registers[set_reg] = value;
  63.     break;
  64.   }
  65.  
  66.   case 2: {
  67.     unsigned long value = convert_value();
  68.     stack_ptr++;
  69.     if (stack_ptr ==  STACK_SIZE) {
  70.       printf("Stack Overflow \n");
  71.       stack_ptr--;
  72.       return -1;
  73.       break;
  74.     }
  75.     debug_log printf("PUSH %lu\n", value);
  76.     stack[stack_ptr] = value;
  77.     break;
  78.   }
  79.  
  80.   case 3: {
  81.     unsigned long reg = *mem_ptr % ADDRESS_SPACE_SIZE;
  82.     mem_ptr++;
  83.     if (stack_ptr == 0) {
  84.       printf("Stack Underflow. \n");
  85.       return -1;
  86.       break;
  87.     }
  88.     registers[reg] = stack[stack_ptr];
  89.     stack[stack_ptr] = 0;
  90.     stack_ptr--;
  91.     debug_log printf("POP %lu\n", reg);
  92.     break;
  93.     }
  94.    
  95.   case 4: {
  96.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  97.     mem_ptr++;
  98.     unsigned long b = convert_value();
  99.     unsigned long c = convert_value();
  100.  
  101.     registers[a] = (b == c);
  102.     debug_log printf("EQ %ld, %ld, %ld\n", a, b, c);
  103.     vdebug_log printf("New value of %ld register: %d\n", a, registers[a]);
  104.     break;
  105.   }
  106.   case 5: {
  107.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  108.     mem_ptr++;
  109.     unsigned long b = convert_value();
  110.     unsigned long c = convert_value();
  111.  
  112.     registers[a] = (b > c);
  113.     debug_log printf("GT %ld, %ld, %ld\n", a, b, c);
  114.     vdebug_log printf("New value of %ld register: %d", a, registers[a]);
  115.     break;
  116.   }
  117.    
  118.   case 6: {
  119.     unsigned long offset = *mem_ptr;
  120.     mem_ptr++;
  121.    
  122.     debug_log printf("JMP %ld\n", (offset * 2));
  123.    
  124.     mem_ptr = mem_start + offset;
  125.     break;
  126.   }
  127.  
  128.   case 7: {
  129.     unsigned long value = convert_value();
  130.     unsigned long offset = *mem_ptr;
  131.     mem_ptr++;
  132.  
  133.     debug_log printf("JT %ld, %ld\n", value, (offset * 2));
  134.  
  135.     if (!value)
  136.       break;
  137.    
  138.     mem_ptr = mem_start + offset;
  139.     break;
  140.   }
  141.   case 8: {
  142.     unsigned long value = convert_value();
  143.     unsigned long offset = *mem_ptr;
  144.     mem_ptr++;
  145.    
  146.     debug_log printf("JF %ld, %ld\n", value, (offset * 2));
  147.    
  148.     if (value)
  149.       break;
  150.    
  151.     mem_ptr = mem_start + offset;
  152.     break;
  153.   }
  154.  
  155.   case 9: {
  156.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  157.     mem_ptr++;
  158.     unsigned long b = convert_value();
  159.     unsigned long c = convert_value();
  160.  
  161.     registers[a] = (b + c) MODM;
  162.     debug_log printf("ADD %ld, %ld, %ld\n", a, b, c);
  163.     vdebug_log printf("New value of %ld register: %d", a, registers[a]);
  164.     break;
  165.   }
  166.  
  167.   case 10: {
  168.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  169.     mem_ptr++;
  170.     unsigned long b = convert_value();
  171.     unsigned long c = convert_value();
  172.    
  173.     registers[a] = (b * c) MODM;
  174.     debug_log printf("MUL %ld, %ld, %ld\n", a, b, c);
  175.     vdebug_log printf("New value of %ld register: %d", a, registers[a]);
  176.     break;
  177.   }
  178.  
  179.  
  180.   case 11: {
  181.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  182.     mem_ptr++;
  183.     unsigned long b = convert_value();
  184.     unsigned long c = convert_value();
  185.    
  186.     registers[a] = (b % c);
  187.     debug_log printf("MOD %ld, %ld, %ld\n", a, b, c);
  188.     vdebug_log printf("New value of %ld register: %d", a, registers[a]);
  189.     break;
  190.   }
  191.  
  192.   case 12: {
  193.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  194.     mem_ptr++;
  195.     unsigned long b = convert_value();
  196.     unsigned long c = convert_value();
  197.    
  198.     registers[a] = (b & c) MODM;
  199.     debug_log printf("AND %ld, %ld, %ld\n", a, b, c);
  200.     vdebug_log printf("New value of %ld register: %d", a, registers[a]);
  201.     break;
  202.   }
  203.    
  204.   case 13: {
  205.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  206.     mem_ptr++;
  207.     unsigned long b = convert_value();
  208.     unsigned long c = convert_value();
  209.    
  210.     registers[a] = (b | c) MODM;
  211.     debug_log printf("OR %ld, %ld, %ld\n", a, b, c);
  212.     vdebug_log printf("New value of %ld register: %d", a, registers[a]);
  213.     break;
  214.   }
  215.    
  216.   case 14: {
  217.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  218.     mem_ptr++;
  219.     unsigned long b = convert_value();
  220.    
  221.     registers[a] = (~b) MODM;
  222.     debug_log printf("NOT %ld, %ld\n", a, b);
  223.     vdebug_log printf("New value of %ld register: %d", a, registers[a]);
  224.     break;
  225.   }
  226.  
  227.  
  228.   case 15: {
  229.     unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
  230.     mem_ptr++;
  231.     unsigned long b = convert_value();
  232.  
  233.     registers[a] = *(mem_start + b);
  234.     debug_log printf("RMEM %lu, %lu\n", a, b);
  235.     break;
  236.   }
  237.  
  238.    case 16: {
  239.     unsigned long a = convert_value();
  240.     unsigned long b = convert_value();
  241.  
  242.     *(mem_start + a) = b;
  243.     debug_log printf("WMEM %lu, %lu\n", a, b);
  244.     break;
  245.   }
  246.    
  247.   case 17: {
  248.     unsigned long call_mov = convert_value();
  249.     stack_ptr++;
  250.     if (stack_ptr ==  STACK_SIZE) {
  251.       printf("Stack Overflow \n");
  252.       stack_ptr--;
  253.       return -1;
  254.       break;
  255.     }
  256.     debug_log printf("CALL %ld\n", call_mov);
  257.     vdebug_log printf("Stack: ");
  258.  
  259.     stack[stack_ptr] = mem_ptr - mem_start;
  260.     for (int i = 0; i <= stack_ptr; i++)
  261.       vdebug_log printf("%d, ", stack[i]);
  262.     mem_ptr = call_mov + mem_start;
  263.     break;  
  264.   }
  265.  
  266.   case 18: {
  267.     if (stack_ptr == 0) {
  268.       printf("Stack Underflow. \n");
  269.       return -1;
  270.       break;
  271.     }
  272.     int stack_top = stack[stack_ptr];
  273.     stack[stack_ptr] = 0;
  274.     stack_ptr--;
  275.     mem_ptr = stack_top + mem_start;
  276.     debug_log printf("RET \n");
  277.     break;
  278.   }
  279.  
  280.   case 19:
  281.     char data = (char)(*mem_ptr);
  282.     mem_ptr++;
  283.     printf("%c", data);
  284.     break;
  285.  
  286.   case 20: {
  287.     unsigned long reg = (*mem_ptr) MODM;
  288.     mem_ptr++;
  289.     registers[reg] = getchar();
  290.     debug_log printf("IN %lu", reg);
  291.     while(getchar() != '\n');
  292.   }
  293.    
  294.   case 21:
  295.     break;
  296.  
  297.   default:
  298.     debug_log printf("Unrecognised Opcode: %ld\n", opcode);
  299.     debug_log printf("Memory Address: %lld\n", (mem_ptr - mem_start));
  300.     return -1;
  301.     break;
  302.   }
  303.   return 0;
  304. }
  305.  
  306.  
  307. unsigned long read(FILE *file_pointer) {
  308.   unsigned long low = fgetc(file_pointer);
  309.   unsigned long high = fgetc(file_pointer);
  310.  
  311.   vdebug_log printf("read value: %lu   \t\t\t", (low + (high << 4)));
  312.   vdebug_log printf("Memory address: %lu\n", ftell(file_pointer));
  313.  
  314.  
  315.   return (low + (high << 8));
  316. }
  317.  
  318. int main(int argc, char* argv[]) {
  319.  
  320.  
  321.   for (int i = 0; i < REGISTERS; i++) {
  322.     registers[i] = 0;
  323.     vdebug_log printf("Zeroed register %d\n", i);
  324.   }
  325.  
  326.   if (argc < 2) {
  327.     printf("usage: %s binary.exe [-v/-vv]", argv[0]);
  328.     return 1;
  329.   }
  330.  
  331.   char *file_name = *(argv + 1);
  332.  
  333.   // Open file to read
  334.   FILE *file_pointer;
  335.   errno_t error = fopen_s(&file_pointer, file_name, "rb");
  336.   if (error != 0) {
  337.     printf("%s could not be opened", file_name);
  338.     printf("Error: %d", error);
  339.     return 1;
  340.   }
  341.  
  342.   if (argc >= 3) {
  343.     if (strcmp(*(argv + 2), "-vv") == 0) {
  344.       printf("Turning on verbose debug mode\n");
  345.       VDEBUG = 1;
  346.     } else if (strcmp(*(argv + 2), "-v") == 0) {
  347.       printf("Turning on debugging mode\n");
  348.       DEBUG = 1;
  349.     } else {
  350.       printf("Usage: %s binary.exe [-v/-vv]", *argv);
  351.       return 1;
  352.     }
  353.   }
  354.  
  355.   // Get size of binary
  356.   fseek(file_pointer, 0, SEEK_END);
  357.   long size = ftell(file_pointer);
  358.   FILE *file_start = file_pointer;
  359.   fseek(file_pointer, 0, SEEK_SET);
  360.   printf("File size: %ld\n", size);
  361.  
  362.   // read binary into memory
  363.   int address_space = size/2;
  364.   unsigned long *memory = malloc(size* 2);
  365.   printf("Allocated %ld bytes into memory", size * 2);
  366.   mem_ptr = memory;
  367.   mem_start = memory;
  368.  
  369.   for (int i = 0; i < address_space; i++) {
  370.     unsigned long temp = read(file_pointer);
  371.     *memory = temp;
  372.     memory++;
  373.   }
  374.  
  375.   // size = 1000;
  376.  
  377.   while (process_opcodes() != -1) {
  378.    
  379.   }
  380.  
  381. }
  382.  
  383.  
Advertisement
Add Comment
Please, Sign In to add comment