Advertisement
badeip

Portable Network Graphics, PNG analyzer

Dec 6th, 2011
401
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.39 KB | None | 0 0
  1. // by petter wahlman, http://www.twitter.com/badeip
  2. // display and verify the crc of PNG chunk data
  3. // hex.h - available here: http://pastebin.com/yj3xsZLW
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <string.h>
  9. #include <sys/mman.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <arpa/inet.h>
  13.  
  14. #include "hex.h"
  15.  
  16. unsigned long crc_table[256];
  17.  
  18. int crc_table_computed = 0;
  19.  
  20. void make_crc_table(void)
  21. {
  22.     unsigned long c;
  23.     int n, k;
  24.  
  25.     for (n = 0; n < 256; n++) {
  26.         c = (unsigned long) n;
  27.         for (k = 0; k < 8; k++) {
  28.             if (c & 1)
  29.                 c = 0xedb88320L ^ (c >> 1);
  30.             else
  31.                 c = c >> 1;
  32.         }
  33.         crc_table[n] = c;
  34.     }
  35.     crc_table_computed = 1;
  36. }
  37.  
  38. unsigned long update_crc(unsigned long crc, unsigned char *buf, int len)
  39. {
  40.     unsigned long c = crc;
  41.     int n;
  42.  
  43.     if (!crc_table_computed)
  44.         make_crc_table();
  45.     for (n = 0; n < len; n++) {
  46.         c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
  47.     }
  48.     return c;
  49. }
  50.  
  51. unsigned long crc(unsigned char *buf, int len)
  52. {
  53.     return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
  54. }
  55.  
  56. int print_sections(char *mem, size_t size)
  57. {
  58.     char *ptr = mem;
  59.     int i;
  60.  
  61.     i = 0;
  62.  
  63.     if ((*(unsigned int *)ptr != 0x474e5089) ||
  64.         (*(unsigned int *)(ptr + sizeof(int)) != 0x0a1a0a0d)) {
  65.         fprintf(stderr, "error, not a valid png-image\n");
  66.         return 1;
  67.     }
  68.  
  69.     i += 8;
  70.  
  71.     do {
  72.         unsigned int section_len;
  73.         unsigned int org_crc, calc_crc;
  74.  
  75.         printf("file size:      0x%08zx\n", size);
  76.  
  77.         section_len = ntohl(*(unsigned int *)&ptr[i]);
  78.         printf("section offset: 0x%08x\n", i);
  79.  
  80.         printf("section length: 0x%08x\n", section_len);
  81.         i += 4;
  82.  
  83.         printf("section name:   %c%c%c%c\n",
  84.             isalpha(*(ptr + i + 0)) ? *(ptr + i + 0) : '?',
  85.             isalpha(*(ptr + i + 1)) ? *(ptr + i + 1) : '?',
  86.             isalpha(*(ptr + i + 2)) ? *(ptr + i + 2) : '?',
  87.             isalpha(*(ptr + i + 3)) ? *(ptr + i + 3) : '?');
  88.         i += 4;
  89.  
  90.         calc_crc = ntohl(crc((unsigned char *)&mem[i - 4], section_len + 4));
  91.         printf("calculated crc: 0x%08x\n", calc_crc);
  92.  
  93.         org_crc = *(unsigned int *)&ptr[i + section_len];
  94.         printf("crc:            0x%08x\n", org_crc);
  95.  
  96.         if (org_crc != calc_crc) {
  97.             fprintf(stderr, "error, incorrect CRC\n");
  98.             return 1;
  99.         }
  100.  
  101.         printf("data:\n");
  102.         print_hex(mem + i, section_len, 0);
  103.         i += section_len;
  104.  
  105.         i += 4; // skip past crc (printed above)
  106.  
  107.         printf("\n");
  108.     } while(i < size);
  109.  
  110.     return 0;
  111. }
  112.  
  113. int main(int argc, char **argv)
  114. {
  115.     int fd;
  116.     char *map;
  117.     char *png;
  118.     struct stat st;
  119.     int i;
  120.  
  121.     map = NULL;
  122.     if (argc < 2) {
  123.         argc = 2;
  124.         argv[1] = "challenge.png";
  125.     }
  126.     for (i = 1; i < argc; i++) {
  127.         png = argv[i];
  128.         printf("filename:       %s\n", png);
  129.         fd = open(png, O_RDONLY);
  130.         if (-1 == fd) {
  131.             perror(png);
  132.             return 1;
  133.         }
  134.  
  135.         fstat(fd, &st);
  136.  
  137.         map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  138.         close(fd);
  139.         print_sections(map, st.st_size);
  140.     }
  141.     if (isatty(fileno(stdin)))
  142.         munmap(map, st.st_size);
  143.  
  144.     return 0;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement