Advertisement
Guest User

Update checksums in firmware binary

a guest
Jun 6th, 2016
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.88 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6.  
  7. #define FILE_HEADER_INFO "Full Info:\n"\
  8.     "\tMagic number:\t\t0x%08x\n" \
  9.     "\tHeader checksum:\t0x%08x\n" \
  10.     "\tHeader length:\t\t0x%08x\n" \
  11.     "\tFiles number:\t\t0x%08x\n" \
  12.     "\tLanguache:\t\t0x%08x\n" \
  13.     "\tDevice class:\t\t0x%08x\n"
  14.  
  15.  
  16. #define FILE_ITEM_HEADER_INFO "\tFile name:\t\t%s\n" \
  17.     "\tStart:\t\t\t0x%08x\n" \
  18.     "\tLength:\t\t\t0x%08x\n" \
  19.     "\tChecksum:\t\t0x%08x\n"
  20.  
  21.  
  22. typedef struct {
  23.   uint32_t magic_namber;
  24.   uint32_t header_checksum;
  25.   uint32_t total_length;
  26.   uint32_t file_number;
  27.   uint32_t languache;
  28.   uint32_t device_class;
  29. } file_header_t;
  30.  
  31. typedef struct {
  32.     char file_name[32];
  33.     uint32_t file_start;
  34.     uint32_t file_length;
  35.     uint32_t checksum;
  36. } file_item_header_t;
  37.  
  38. char *hexlify(char *str) {
  39.     int l,i;
  40.     char *t;
  41.     l = strlen(str)*2;
  42.     t = malloc(l);
  43.     if (t) {
  44.         for(i=0; i<l; i++) {
  45.             sprintf(t+2*i, "%02x", str[i]);
  46.         }
  47.         return t;
  48.     }
  49.     return NULL;
  50. }
  51.  
  52. char fromhex(char c) {
  53.     if (isxdigit(c)) {
  54.         if (isdigit(c)) {
  55.             c -= '0';
  56.         } else {
  57.             c = tolower(c);
  58.             c = c - 'a' + 10;
  59.         }
  60.     } else { c = 0; }
  61.     return c;
  62. }
  63.  
  64. char *unhexlify(char *hstr) {
  65.     int l, i;
  66.     char *t;
  67.     char c;
  68.     l = strlen(hstr)/2;
  69.     t = malloc(l);
  70.     if (t) {
  71.         for(i=0; i<l; i++) {
  72.             c = fromhex(hstr[2*i+1]) + 16 * fromhex(hstr[2*i]);
  73.             t[i] = c;
  74.         }
  75.     }
  76.     return t;
  77. }
  78.  
  79. char *get_key(char* short_key) {
  80.     int short_key_len = strlen(short_key);
  81.     char *key = calloc((16 * short_key_len + 1), sizeof(char));
  82.     int i, j;
  83.     char first;
  84.  
  85.     // The longer key just rotates the short_key left by 1 byte each time
  86.     for (i = 0; i < short_key_len; i++) {
  87.         strncat(key, short_key, short_key_len);
  88.  
  89.         first = short_key[0];
  90.         for (j = 0; j < short_key_len - 1; j++)
  91.             short_key[j] = short_key[j + 1];
  92.         short_key[short_key_len - 1] = first;
  93.     }
  94.  
  95.     return key;
  96. }
  97.  
  98.  
  99. void* decode(void *data, size_t data_length, const char *key) {
  100.     char c1, c2;
  101.     int pos = 0;
  102.  
  103.     // XOR decode the header
  104.     while (pos != data_length) {
  105.         c1 = ((char*)data)[pos];
  106.         c2 = key[pos];
  107.  
  108.         ((char*)data)[pos] = c1 ^ c2;
  109.         pos++;
  110.     }
  111.  
  112.     return data;
  113. }
  114.  
  115. int main(int argc, char const *argv[]) {
  116.     char *short_key = unhexlify("BACDBCFED6CADDD3BAB9A3ABBFCBB5BE");
  117.     //char *short_key = unhexlify("68656C6C6F20776F726C64");
  118.      int i, j, index,
  119.         write_to_file = 0,
  120.         file_header_length = sizeof(file_header_t),
  121.         file_item_header_length = sizeof(file_item_header_t);
  122.     char *data, *file_item,
  123.         *key = get_key(short_key);
  124.  
  125.     char answer;
  126.     uint32_t calced_checksum;
  127.     file_item_header_t *file_item_header = malloc(file_item_header_length);
  128.     file_header_t *file_header = calloc(1, sizeof(file_header_t));
  129.     FILE *file = fopen(argv[1], "r+");
  130.  
  131.     fread(file_header, sizeof(file_header_t), 1, file);
  132.  
  133.     file_header = (file_header_t*)decode(file_header, file_header_length, key);
  134.  
  135.     printf(FILE_HEADER_INFO, file_header->magic_namber, file_header->header_checksum,
  136.            file_header->total_length, file_header->file_number, file_header->languache,
  137.            file_header->device_class);
  138.  
  139.  
  140.     fseek(file, 0, SEEK_SET);
  141.  
  142.     data = malloc(file_header->total_length * sizeof(char));
  143.  
  144.     if (NULL == data) return -1;
  145.  
  146.     fread(data, sizeof(char), file_header->total_length, file);
  147.  
  148.     data = (char*)decode(data, file_header->total_length, key);
  149.  
  150.     // Header checksum is just a byte sum from the checksum to length
  151.     calced_checksum = 0;
  152.     for (i = 11; i < file_header->total_length; i++)
  153.         calced_checksum += (unsigned char)data[i];
  154.  
  155.     printf("\tCalced checksum:\t0x%08x\n\n", calced_checksum);
  156.  
  157.     index = 64;
  158.     for (i = 0; i < file_header->file_number; i++) {
  159.         printf("Information about file part #%i\n", i);
  160.         memcpy(file_item_header, (data + index), file_item_header_length);
  161.  
  162.         printf(FILE_ITEM_HEADER_INFO, file_item_header->file_name,
  163.                file_item_header->file_start, file_item_header->file_length,
  164.                file_item_header->checksum);
  165.  
  166.         file_item = malloc(file_item_header->file_length);
  167.         fseek(file, file_item_header->file_start, SEEK_SET);
  168.         fread(file_item, sizeof(char), file_item_header->file_length, file);
  169.  
  170.         calced_checksum = 0;
  171.         for (j = 0; j < file_item_header->file_length; j++)
  172.             calced_checksum += (unsigned char)file_item[j];
  173.         printf("\tCalced checksum:\t0x%08x\n\n", calced_checksum);
  174.  
  175.         if (calced_checksum != file_item_header->checksum) {
  176.             printf("Checksums of file item #%i and it's header checksum mismatch. Correct checksum in header? (y/n): ", i);
  177.             answer = getchar();
  178.             if ('y' == answer) {
  179.                 write_to_file = 1;
  180.                 printf("Replacing checksum in file item header (0x%08x) with 0x%08x\n", file_item_header->checksum, calced_checksum);
  181.                 file_item_header->checksum = calced_checksum;
  182.                 memcpy((data + index), file_item_header, file_item_header_length);
  183.                 printf("Done.\n");
  184.             }
  185.             else
  186.                 printf("Continue.\n");
  187.         }
  188.  
  189.         free(file_item);
  190.         index += file_item_header_length;
  191.     }
  192.  
  193.     if (write_to_file) {
  194.         printf("Save changes to file.\n");
  195.         fseek(file, 0, SEEK_SET);
  196.         data = (char*)decode(data, file_header->total_length, key);
  197.         fwrite(data, sizeof(char), file_header->total_length, file);
  198.     }
  199.  
  200.     free(data);
  201.     free(key);
  202.     free(short_key);
  203.     fclose(file);
  204.     printf("Everything done.\n");
  205.  
  206.     return 0;
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement