Very simple bytecode.

   1 #include <stdint.h>
   2 #include <stdio.h>
   3 #include <stdlib.h>
   4 #include <string.h>
   5 #include <vector>
   6 #include <string>
   7 
   8 const char * filename;
   9 
  10 bool trap = false;
  11 
  12 void fread_or_die(void * a, size_t b, size_t c, FILE * d)
  13 {
  14     size_t got = fread(a, b, c, d);
  15     if(feof(d)) {/*puts("feof"); puts(filename);*/ trap = true;}
  16     if(ferror(d)) {/*puts("ferror");*/ trap = true;}
  17     if(got != c) {trap = true;}
  18 }
  19 
  20 struct filedata
  21 {
  22     char name[0xD];
  23     uint32_t len;
  24     uint32_t start;
  25 };
  26 
  27 struct extdata
  28 {
  29     char ext[0x4];
  30     uint32_t count;
  31     uint32_t start;
  32     std::vector<filedata> files;
  33 };
  34 
  35 std::vector<extdata> extensions;
  36 
  37 int main(int argc, char ** argv)
  38 {
  39     if(argc < 2) return 0;
  40     
  41     for(int argument = 1; argument < argc; argument++)
  42     {
  43         trap = false;
  44         filename = argv[argument];
  45         auto f = fopen(filename, "rb");
  46         
  47         unsigned char trash[512];
  48         
  49         fseek(f, 0x18, SEEK_SET);
  50         
  51         uint32_t num_offsets;
  52         fread_or_die(&num_offsets, 4, 1, f);
  53         
  54         fseek(f, 0x458 + 4*num_offsets, SEEK_SET);
  55         
  56         while(!feof(f) and !ferror(f) and !trap)
  57         {
  58             uint16_t command;
  59             uint16_t length;
  60             fread_or_die(&command, 2, 1, f);
  61             if(trap) break;
  62             fread_or_die(&length, 2, 1, f);
  63             if(trap) break;
  64             
  65             //printf("%04X (%04X) : \n", command, length);
  66             
  67             uint32_t start = ftell(f);
  68             
  69             while(ftell(f) - start < length)
  70             {
  71                 uint8_t comma_type;
  72                 fread_or_die(&comma_type, 1, 1, f);
  73                 if(trap) break;
  74                 #define GENERIC(M, N) \
  75                     case (M): \
  76                     /*printf("%02X : ", command);*/ \
  77                     fread_or_die(trash, 1, (N), f); /*for(int i = 0; i < (N); i++) printf("%02X ", trash[i]); puts(""); */ \
  78                     break;
  79                 #define GOODSTRING(M, N) \
  80                     case (M): \
  81                     /*if(!visited[(M)]) printf("%02X : ", command);*/ \
  82                     fread_or_die(trash, 1, (N), f); \
  83                     for(;;) { int c = fgetc(f); if(c == 0) break; if(command == 0x07DA) putc(c, stdout); } /*if(!visited[(M)])*/ if(command == 0x07DA) puts(""); \
  84                     /*visited[(M)] = true;*/ \
  85                     break;
  86                 #define CONSUME(M) \
  87                     case (M): \
  88                     /*if(!visited[(M)]) printf("%02X : ", command);*/ \
  89                     while(ftell(f) - start != length) fgetc(f); \
  90                     break;
  91                 switch(comma_type)
  92                 {
  93                 GENERIC(0x01, 4)
  94                 GENERIC(0x02, 4)
  95                 GOODSTRING(0x03, 0)
  96                 CONSUME(0x04)
  97                 default:
  98                     printf("Unknown stack comma %02X at %08X in %s\n", comma_type, ftell(f)-1, filename);
  99                     exit(0);
 100                 }
 101             }
 102             if(ftell(f) - start != length)
 103             {
 104                 printf("sync error at %X08\n", ftell(f));
 105                 exit(0);
 106             }
 107         }
 108     }
 109 }

mscenario (last edited 2017-08-27 21:07:20 by weh)