Pastebin is 300% more awesome when you are logged in. Sign Up, it's FREE!
Guest

Untitled

By: a guest on Nov 26th, 2010  |  syntax: C  |  size: 5.58 KB  |  hits: 87  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <errno.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. #include <inttypes.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <time.h>
  12.  
  13. /* taken from original code by Rafaël Carré ? */
  14. #if 1 /* ANSI colors */
  15.  
  16. #       define color(a) printf("%s",a)
  17. char OFF[]              = { 0x1b, 0x5b, 0x31, 0x3b, '0', '0', 0x6d, '\0' };
  18.  
  19. char GREY[]     = { 0x1b, 0x5b, 0x31, 0x3b, '3', '0', 0x6d, '\0' };
  20. char RED[]              = { 0x1b, 0x5b, 0x31, 0x3b, '3', '1', 0x6d, '\0' };
  21. char GREEN[]    = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' };
  22. char YELLOW[]   = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' };
  23. char BLUE[]     = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
  24.  
  25. #else
  26.         /* disable colors */
  27. #       define color(a)
  28. #endif
  29.  
  30. #define bug(...) do { fprintf(stderr,"ERROR: "__VA_ARGS__); exit(1); } while(0)
  31. #define bugp(a) do { perror("ERROR: "a); exit(1); } while(0)
  32.  
  33. #define get32le(a) ((uint32_t) \
  34.     ( buf[a+3] << 24 | buf[a+2] << 16 | buf[a+1] << 8 | buf[a] ))
  35. #define get16le(a) ((uint16_t)( buf[a+1] << 8 | buf[a] ))
  36.  
  37. #define assert(a) do { if(!(a)) { fprintf(stderr,"Assertion \"%s\" failed in %s() line %d!\n\nPlease send us your firmware!\n",#a,__func__,__LINE__); exit(1); } } while(0)
  38.  
  39. #define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round))
  40.  
  41. /* globals */
  42.  
  43. size_t sz;      /* file size */
  44. uint8_t *buf; /* file content */
  45. #define PREFIX_SIZE     128
  46. char out_prefix[PREFIX_SIZE]; /* output prefix */
  47.  
  48. /* definitions */
  49. struct sb_instruction_header_t
  50. {
  51.     uint32_t inst;
  52. } __attribute__((packed));
  53.  
  54. #define SB_INST_OP(inst)    (((inst) >> 8) & 0xff)
  55. #define SB_INST_UNK(inst)   ((inst) & 0xff)
  56.  
  57. #define SB_INST_FINISH  0x0
  58. #define SB_INST_LOAD    0x2
  59. #define SB_INST_FILL    0x3
  60. #define SB_INST_CALL    0x5
  61.  
  62. struct sb_instruction_load_t
  63. {
  64.     struct sb_instruction_header_t hdr;
  65.     uint32_t addr;
  66.     uint32_t len;
  67.     uint32_t crc;
  68. } __attribute__((packed));
  69.  
  70. struct sb_instruction_fill_t
  71. {
  72.     struct sb_instruction_header_t hdr;
  73.     uint32_t addr;
  74.     uint32_t len;
  75.     uint32_t pattern;
  76. } __attribute__((packed));
  77.  
  78. struct sb_instruction_call_t
  79. {
  80.     struct sb_instruction_header_t hdr;
  81.     uint32_t addr;
  82.     uint32_t arg;
  83. } __attribute__((packed));
  84.  
  85. static void *xmalloc(size_t s) /* malloc helper */
  86. {
  87.         void * r = malloc(s);
  88.         if(!r) bugp("malloc");
  89.         return r;
  90. }
  91.  
  92. static void check(unsigned long filesize)
  93. {
  94. }
  95.  
  96. static void extract(unsigned long filesize)
  97. {
  98.     size_t pos = 0;
  99.     while(pos < filesize)
  100.     {
  101.         struct sb_instruction_header_t *hdr = (struct sb_instruction_header_t *)&buf[pos];
  102.         if(SB_INST_OP(hdr->inst) == SB_INST_LOAD)
  103.         {
  104.             struct sb_instruction_load_t *load = (struct sb_instruction_load_t *)&buf[pos];
  105.             color(RED);
  106.             printf("LOAD");
  107.             color(OFF);printf(" | ");
  108.             color(BLUE);
  109.             printf("addr=%#08x", load->addr);
  110.             color(OFF);printf(" | ");
  111.             color(GREEN);
  112.             printf("len=%#08x", load->len);
  113.             color(OFF);printf(" | ");
  114.             color(YELLOW);
  115.             printf("crc=%#08x\n", load->crc);
  116.             color(OFF);
  117.  
  118.             pos += load->len + sizeof(struct sb_instruction_load_t);
  119.             // unsure about rounding
  120.             pos = ROUND_UP(pos, 16);
  121.         }
  122.         else if(SB_INST_OP(hdr->inst) == SB_INST_FILL)
  123.         {
  124.             struct sb_instruction_fill_t *fill = (struct sb_instruction_fill_t *)&buf[pos];
  125.             color(RED);
  126.             printf("FILL");
  127.             color(OFF);printf(" | ");
  128.             color(BLUE);
  129.             printf("addr=%#08x", fill->addr);
  130.             color(OFF);printf(" | ");
  131.             color(GREEN);
  132.             printf("len=%#08x", fill->len);
  133.             color(OFF);printf(" | ");
  134.             color(YELLOW);
  135.             printf("pattern=%#08x\n", fill->pattern);
  136.             color(OFF);
  137.  
  138.             pos += sizeof(struct sb_instruction_fill_t);
  139.             // fixme: useless as pos is a multiple of 16 and fill struct is 4-bytes wide ?
  140.             pos = ROUND_UP(pos, 16);
  141.         }
  142.         else if(SB_INST_OP(hdr->inst) == SB_INST_CALL)
  143.         {
  144.             struct sb_instruction_call_t *call = (struct sb_instruction_call_t *)&buf[pos];
  145.             color(RED);
  146.             printf("CALL");
  147.             color(OFF);printf(" | ");
  148.             color(BLUE);
  149.             printf("addr=%#08x", call->addr);
  150.             color(OFF);printf(" | ");
  151.             color(GREEN);
  152.             printf("arg=%#08x\n", call->arg);
  153.             color(OFF);
  154.  
  155.             pos += sizeof(struct sb_instruction_call_t);
  156.             // fixme: useless as pos is a multiple of 16 and call struct is 4-bytes wide ?
  157.             pos = ROUND_UP(pos, 16);
  158.         }
  159.         else
  160.             bug("Unknown instruction %#08x at address %#08lx\n", hdr->inst, (unsigned long)pos);
  161.     }
  162. }
  163.  
  164. int main(int argc, char **argv)
  165. {
  166.     int fd;
  167.         struct stat st;
  168.         if(argc != 2 && argc != 3)
  169.                 bug("Usage: %s <firmware> [<out prefix>]\n",*argv);
  170.     if(argc == 3)
  171.         snprintf(out_prefix, PREFIX_SIZE, "%s", argv[2]);
  172.     else
  173.         strcpy(out_prefix, "");
  174.  
  175.         if( (fd = open(argv[1],O_RDONLY)) == -1 )
  176.                 bugp("opening firmware failed");
  177.  
  178.         if(fstat(fd,&st) == -1)
  179.                 bugp("firmware stat() failed");
  180.         sz = st.st_size;
  181.  
  182.         buf=xmalloc(sz);
  183.         if(read(fd,buf,sz)!=(ssize_t)sz) /* load the whole file into memory */
  184.                 bugp("reading firmware");
  185.  
  186.         close(fd);
  187.  
  188.         check(st.st_size);      /* verify header and checksums */
  189.         extract(st.st_size);    /* split in blocks */
  190.        
  191.         color(OFF);
  192.  
  193.         free(buf);
  194.         return 0;
  195. }