All pastes #968507 Raw Edit

iPatcher 2.0 5A225c

public c v1 · immutable
·published 2008-04-03 02:11 UTC
rendered paste body
#include<stdio.h>#include<stdlib.h>#include<getopt.h>#include<stdarg.h>#include<errno.h>#include <unistd.h>#include<sys/types.h>#include<sys/stat.h>//Thanks to Solar Designer for the CRC routineschar *LOCKDOWND_PATH="/usr/libexec/lockdownd";typedef struct a_patch_ {    unsigned long offset;    unsigned char orig_byte;    unsigned char new_byte;} a_patch;typedef struct os_fixes_ {    char *file_id;    char major;    char minor;    char sub;    unsigned long orig_crc;    unsigned long new_crc;    a_patch *patches;} os_fixes;a_patch lockdownd_120_5a225c[] ={    {0x0000C40F, 0x0A, 0xEA},    {0x0000667B, 0x0A, 0xEA},    {0x00007C1B, 0x1A, 0xEA},    {0x00008860, 0xA0, 0x1C},    {0x00008861, 0x28, 0x29},    {0x00008864, 0x01, 0x00},    {0x000088C4, 0x3C, 0xB8},    {0x0000893C, 0xC4, 0x40},    {0x0000893D, 0x27, 0x28},    {0x00008A30, 0xFC, 0x4C},    {0x00008A31, 0x26, 0x27},    {0x00008A88, 0xB4, 0xF4},    {0x00008B0C, 0x30, 0x70},    {0x00008C2C, 0xD4, 0x50},    {0x00008C2D, 0x34, 0x35},    {0x00008CA8, 0x94, 0xD4},    {0x00008D04, 0x01, 0x00},    {0x00008D1B, 0xDA, 0xEA},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_114_patches[] ={    {0x000083AF, 0x0A, 0xEA},    {0x0000AFA3, 0x0A, 0xEA},    {0x0000C4CF, 0x1A, 0xEA},    {0x0000CDB4, 0x80, 0x04},    {0x0000CDB5, 0x28, 0x29},    {0x0000CDC0, 0x01, 0x00},    {0x0000CE08, 0x2C, 0xB0},    {0x0000CE58, 0xDC, 0x60},    {0x0000CE59, 0x27, 0x28},    {0x0000CF24, 0x3C, 0x94},    {0x0000CF7C, 0xF4, 0x3C},    {0x0000CF7D, 0x26, 0x27},    {0x0000D000, 0x70, 0xB8},    {0x0000D1A8, 0x8C, 0x10},    {0x0000D1A9, 0x24, 0x25},    {0x0000D224, 0x4C, 0x94},    {0x0000D274, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_113_patches[] ={    {0x000083AF, 0x0A, 0xEA},    {0x0000AFA3, 0x0A, 0xEA},    {0x0000C4CF, 0x1A, 0xEA},    {0x0000CDB4, 0x80, 0x04},    {0x0000CDB5, 0x28, 0x29},    {0x0000CDC0, 0x01, 0x00},    {0x0000CE08, 0x2C, 0xB0},    {0x0000CE58, 0xDC, 0x60},    {0x0000CE59, 0x27, 0x28},    {0x0000CF24, 0x3C, 0x94},    {0x0000CF7C, 0xF4, 0x3C},    {0x0000CF7D, 0x26, 0x27},    {0x0000D000, 0x70, 0xB8},    {0x0000D1A8, 0x8C, 0x10},    {0x0000D1A9, 0x24, 0x25},    {0x0000D224, 0x4C, 0x94},    {0x0000D274, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_112_patches[] ={    {0x00004B3B, 0x1A, 0xEA},    {0x000079FC, 0xD7, 0x00},    {0x000079FD, 0xFF, 0x00},    {0x000079FE, 0xFF, 0xA0},    {0x000079FF, 0x1A, 0xE1},    {0x00007E0B, 0x0A, 0xEA},    {0x0000AC73, 0x0A, 0xEA},    {0x0000BC40, 0x01, 0x00},    {0x0000C5CC, 0x01, 0x00},    {0x0000C5D4, 0x88, 0xEC},    {0x0000C614, 0x48, 0xAC},    {0x0000C640, 0x1C, 0x80},    {0x0000C6F0, 0x90, 0xD0},    {0x0000C74C, 0x44, 0x74},    {0x0000C7DC, 0xB4, 0xE4},    {0x0000C8AC, 0xB0, 0x14},    {0x0000C8AD, 0x33, 0x34},    {0x0000C904, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_111_patches[] ={    {0x0000482F, 0x1A, 0xEA},    {0x0000AF5C, 0x01, 0x00},    {0x0000B814, 0x24, 0x54},    {0x0000B818, 0x01, 0x00},    {0x0000B838, 0x00, 0x30},    {0x0000B858, 0xE0, 0x10},    {0x0000B859, 0x14, 0x15},    {0x0000B884, 0xB4, 0xE4},    {0x0000B958, 0x00, 0x10},    {0x0000B970, 0xEC, 0xF8},    {0x0000B9E0, 0x58, 0x88},    {0x0000BA58, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_102_patches[] ={    {0x00009184, 0x01, 0x00},    {0x000094F0, 0x01, 0x00},    {0x000094F4, 0x3C, 0x68},    {0x000095C4, 0x84, 0x98},    {0x00009604, 0x01, 0x00},    {0x00009624, 0x2C, 0x38},    {0x0000962C, 0x28, 0x30},    {0x000096A4, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_101_patches[] ={    {0x00009158, 0x01, 0x00},    {0x000094C4, 0x01, 0x00},    {0x000094C8, 0x3C, 0x68},    {0x00009598, 0x84, 0x98},    {0x000095D8, 0x01, 0x00},    {0x000095F8, 0x2C, 0x38},    {0x00009600, 0x28, 0x30},    {0x00009678, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_100_patches[] ={    {0x00008CF8, 0x01, 0x00},    {0x000090A4, 0x01, 0x00},    {0x000090A8, 0x3C, 0x68},    {0x00009178, 0x84, 0x98},    {0x000091B8, 0x01, 0x00},    {0x000091D8, 0x2C, 0x38},    {0x000091E0, 0x28, 0x30},    {0x00009258, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_100_ipd2ipe[] ={    {0x00008CF8, 0x01, 0x00},    {0x000090A7, 0xE3, 0x03},    {0x000090AB, 0xE5, 0x05},    {0x000090B3, 0xEA, 0x0A},    {0x00009178, 0x84, 0x98},    {0x000091B8, 0x01, 0x00},    {0x000091D8, 0x2C, 0x38},    {0x000091E0, 0x28, 0x30},    {0x00009258, 0x01, 0x00},    {0x00009263, 0xEA, 0x0A},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_101_ipd2ipe[] ={    {0x00009158, 0x01, 0x00},    {0x000094C7, 0xE3, 0x03},    {0x000094CB, 0xE5, 0x05},    {0x000094D3, 0xEA, 0x0A},    {0x00009598, 0x84, 0x98},    {0x000095D8, 0x01, 0x00},    {0x000095F8, 0x2C, 0x38},    {0x00009600, 0x28, 0x30},    {0x00009678, 0x01, 0x00},    {0x00009683, 0xEA, 0x0A},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_102_hack0[] ={    {0x00009184, 0x01, 0x00},    {0x000094F0, 0x01, 0x00},    {0x000094F4, 0x3C, 0x68},    {0x000095C4, 0x84, 0x98},    {0x00009604, 0x01, 0x00},    {0x00009624, 0x2C, 0x38},    {0x0000962C, 0x28, 0x30},    {0x000096A4, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_111_hack0[] ={    {0x0000482F, 0x1A, 0xEA},    {0x0000AF5C, 0x01, 0x00},    {0x0000B810, 0x00, 0x04},    {0x0000B812, 0xA0, 0x00},    {0x0000B813, 0xE1, 0x1A},    {0x0000B838, 0x00, 0x30},    {0x0000B858, 0xE0, 0x10},    {0x0000B859, 0x14, 0x15},    {0x0000B884, 0xB4, 0xE4},    {0x0000B958, 0x00, 0x10},    {0x0000B970, 0xEC, 0xF8},    {0x0000B9E0, 0x58, 0x88},    {0x0000BA58, 0x01, 0x00},    {0x0007A284, 0x32, 0x31},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_111_hack1[] ={    {0x0000482F, 0x1A, 0xEA},    {0x0000AF5C, 0x01, 0x00},    {0x0000B810, 0x00, 0x04},    {0x0000B812, 0xA0, 0x00},    {0x0000B813, 0xE1, 0x1A},    {0x0000B838, 0x00, 0x30},    {0x0000B858, 0xE0, 0x10},    {0x0000B859, 0x14, 0x15},    {0x0000B884, 0xB4, 0xE4},    {0x0000B958, 0x00, 0x10},    {0x0000B970, 0xEC, 0xF8},    {0x0000B9E0, 0x58, 0x88},    {0x0000BA58, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_111_hack2[] ={    {0x0000482F, 0x1A, 0xEA},    {0x0000AF5C, 0x01, 0x00},    {0x0000B814, 0x24, 0x54},    {0x0000B818, 0x01, 0x00},    {0x0000B838, 0x00, 0x30},    {0x0000B858, 0xE0, 0x10},    {0x0000B859, 0x14, 0x15},    {0x0000B884, 0xB4, 0xE4},    {0x0000B958, 0x00, 0x10},    {0x0000B970, 0xEC, 0xF8},    {0x0000B9E0, 0x58, 0x88},    {0x0000BA58, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_112_hack0[] ={    {0x00004B3B, 0x1A, 0xEA},    {0x000079FC, 0xD7, 0x00},    {0x000079FD, 0xFF, 0x00},    {0x000079FE, 0xFF, 0xA0},    {0x000079FF, 0x1A, 0xE1},    {0x00007E0B, 0x0A, 0xEA},    {0x0000AC73, 0x0A, 0xEA},    {0x0000BC40, 0x01, 0x00},    {0x0000C5C1, 0x40, 0x00},    {0x0000C5C2, 0xA0, 0x54},    {0x0000C5C8, 0x00, 0x04},    {0x0000C5CA, 0xA0, 0x00},    {0x0000C5CB, 0xE1, 0x1A},    {0x0000C614, 0x48, 0xAC},    {0x0000C640, 0x1C, 0x80},    {0x0000C6F0, 0x90, 0xD0},    {0x0000C74C, 0x44, 0x74},    {0x0000C7DC, 0xB4, 0xE4},    {0x0000C8AC, 0xB0, 0x14},    {0x0000C8AD, 0x33, 0x34},    {0x0000C904, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};a_patch lockdownd_112_ipe_old[] ={    {0x000079FC, 0xD7, 0x00},    {0x000079FD, 0xFF, 0x00},    {0x000079FE, 0xFF, 0xA0},    {0x000079FF, 0x1A, 0xE1},    {0x00007E0B, 0x0A, 0xEA},    {0x0000AC73, 0x0A, 0xEA},    {0x0000BC40, 0x01, 0x00},    {0x0000C5C8, 0x00, 0x04},    {0x0000C5CA, 0xA0, 0x00},    {0x0000C5CB, 0xE1, 0x1A},    {0x0000C614, 0x48, 0xAC},    {0x0000C640, 0x1C, 0x80},    {0x0000C6F0, 0x90, 0xD0},    {0x0000C74C, 0x44, 0x74},    {0x0000C7DC, 0xB4, 0xE4},    {0x0000C8AC, 0xB0, 0x14},    {0x0000C8AD, 0x33, 0x34},    {0x0000C904, 0x01, 0x00},    {0xFFFFFFFF, 0x00, 0x00}};os_fixes lockdownd_fixes[] ={    {        "lockdownd-5a225c",        1,2,0,        0x343402BE,        0x40A55184,        lockdownd_120_5a225c    },    {        "lockdownd",        1,1,4,        0x76177C04,        0xD500E7A2,        lockdownd_114_patches    },    {        "lockdownd",        1,1,3,        0x53CBC7DB,        0xF0DC5C7D,        lockdownd_113_patches    },    {        "lockdownd",        1,1,2,        0x44FCC4E8,        0x11EE32DF,        lockdownd_112_patches    },    {        "lockdownd",        1,1,1,        0x749267AE,        0xF7A0E782,        lockdownd_111_patches    },    {        "lockdownd",        1,0,2,        0x2D908293,        0xB0525bb7,        lockdownd_102_patches    },    {        "lockdownd",        1,0,1,        0xBEEA7BE6,        0x0126C5B6,        lockdownd_101_patches    },    {        "lockdownd",        1,0,0,        0x1F3EF62D,        0x09031ECF,        lockdownd_100_patches    },    /* To convert other patches to this one */    {        "lockdownd-iphonedev",        1,0,0,        0x56A03DDC,        0x09031ECF,        lockdownd_100_ipd2ipe    },    {        "lockdownd-iphonedev",        1,0,1,        0xF8E3714B,        0x0126C5B6,        lockdownd_101_ipd2ipe    },    {        "lockdownd-hack0",        1,0,2,        0x2D908293,        0xB0525BB7,        lockdownd_102_hack0    },    {        "lockdownd-hack0",        1,1,1,        0x06F3F00F,        0xF7A0E782,        lockdownd_111_hack0    },    {        "lockdownd-hack1",        1,1,1,        0x7A813EC5,        0xF7A0E782,        lockdownd_111_hack1    },    {        "lockdownd-hack2",        1,1,1,        0x749267AE,        0xF7A0E782,        lockdownd_111_hack1    },    {        "lockdownd-hack0",        1,1,2,        0x6BBCCA70,        0x11EE32DF,        lockdownd_112_hack0    },        {        "lockdownd-outdated-ipe",        1,1,2,        0x4CA880A2,        0x11EE32DF,        lockdownd_112_ipe_old    }};typedef unsigned long CRC32_t;#define POLY 0xEDB88320#define ALL1 0xFFFFFFFFstatic CRC32_t *table = NULL;unsigned long REPORTING_LEVEL = 0xFFFFFFFF;void CRC32_Init(CRC32_t *value);void CRC32_Update(CRC32_t *value, void *data, unsigned int size);void CRC32_Final(unsigned char *out, CRC32_t value);int file_exists(char *path);unsigned long get_file_crc(char *path);int handle_patching(char *path, os_fixes *records, int num_records);void inform(int level, char *fmt, ...);int generate_patches(char *orig_path, char *new_path);int do_patches(char *path, a_patch *patches);void usage(char *path){    printf("iPatcher 1.1.x 2008-04-03 237325be65eb7b7663a4485529743805161b42da\n");    printf("Usage: %s [options]\n",path);    printf("Options:\n");    printf("\t-a\t\tautomatically perform all patches\n");    printf("\t-l [file]\tpatch lockdownd at the path\n");    printf("\t-v [level]\tset verbosity to level\n");    printf("\t-m\t\tgenerate patch data (must use -o and -n)\n");    printf("\t-n [file]\tfile after patching (new file)\n");    printf("\t-o [file]\tfile before patching (original file)\n");    printf("\t-h\t\tprint this help\n");}int main(int argc, char *argv[]){  int ch;  int do_something=0;  int do_lockdownd = 0;  int do_makepatch = 0;  char *new_path = NULL;  char *orig_path = NULL;  char *lockdownd_path = LOCKDOWND_PATH;  int ret_check;    if ( argc < 2 )    {      usage(argv[0]);      return(0);    }    while ((ch = getopt(argc, argv, "ah?v:l:mn:o:")) != -1)    {            switch (ch) {            case 'v':                REPORTING_LEVEL = strtoul(optarg, NULL, 0);                break;            case 'l':                do_lockdownd = 1;                do_something = 1;                lockdownd_path = optarg;                              break;            case 'a':                do_lockdownd = 1;                do_something = 1;                break;            case 'm':                do_makepatch = 1;                do_something = 1;                break;            case 'n':                new_path = optarg;                break;            case 'o':                orig_path = optarg;                break;            case 'h':            case '?':            default:                    usage(argv[0]);                    return(0);            }    }    if ( do_something == 0 )    {        usage(argv[0]);        return(0);    }    argc -= optind;    argv += optind;    if ( do_makepatch == 1 )    {        if ( new_path == NULL || orig_path == NULL )        {            inform(1, "[e] must supply an original and new file\n");            return(0);        }        if ( !file_exists(new_path))        {            inform(1, "[e] file %s doesn't exist\n", new_path);            return(0);        }        if ( !file_exists(orig_path))        {            inform(1, "[e] file %s doesn't exist\n", orig_path);            return(0);        }        inform(1, "[i] generating patches\n");        ret_check = generate_patches(orig_path, new_path);        if ( ret_check == 1 )        {            inform(1, "[i] patch generation succeeded\n");        }        else        {            inform(1, "[i] patch generation failed\n");        }        return(0);    }    if ( do_lockdownd )    {        inform(1, "[i] Performing the lockdownd patch\n");        if(!file_exists(lockdownd_path))        {            inform(2, "[e] no lockdownd at %s\n", lockdownd_path);            inform(1, "[i] Lockdownd patch failed\n");            return(0);        }        ret_check = handle_patching(lockdownd_path, lockdownd_fixes,                                    sizeof(lockdownd_fixes) / sizeof(os_fixes));        if ( ret_check == 1 )        {            inform(1, "[i] Lockdownd patch succeeded\n");        }        else        {            inform(1, "[i] Lockdownd patch failed\n");        }            }    return(0);}int file_exists(char *path){  int retcheck;  struct stat finfo;    retcheck = stat(path, &finfo);  if ( retcheck == -1 )    return(0);  return(1);  }void inform(int level, char *fmt, ...){  if ( level <= REPORTING_LEVEL) {      va_list ap;      va_start(ap, fmt);      vprintf(fmt, ap);      va_end(ap);      if ( errno != 0 && level > 1)        perror("last system error");  }}int generate_patches(char *orig_path, char *new_path){  FILE *o_file;  FILE *n_file;  unsigned char o_byte;  unsigned char n_byte;  unsigned long offset;  unsigned long o_crc;  unsigned long n_crc;    o_file = fopen(orig_path, "rb");    if ( o_file == NULL )    {        inform(2, "[e] generate_patches->fopen(orig) failed on %s\n",                orig_path);        return(0);    }    n_file = fopen(new_path, "rb");    if ( n_file == NULL )    {        inform(2, "[e] generate_patches->fopen(new) failed on %s\n", new_path);        return(0);    }    printf("a_patch new_patches[] =\n{\n");    while( (!feof(o_file)) && (!feof(n_file)) )    {        o_byte = fgetc(o_file);        n_byte = fgetc(n_file);        if ( o_byte != n_byte )        {            offset = ftell(o_file) - 1;            if ( offset == -1 )            {                inform(2,"[e] generate_patches->ftell failed\n");                return(0);            }            printf("    {0x%8.8X, 0x%2.2X, 0x%2.2X},\n", (unsigned int)offset,                    o_byte, n_byte);        }    }    printf("    {0xFFFFFFFF, 0x00, 0x00}\n};\n");    fclose(o_file);    fclose(n_file);    o_crc = get_file_crc(orig_path);    n_crc = get_file_crc(new_path);    printf("original crc: 0x%8.8X\n", (unsigned int)o_crc);    printf("new crc: 0x%8.8X\n", (unsigned int)n_crc);    return(1);}int handle_patching(char *path, os_fixes *records, int num_records){  unsigned long orig_crc;  unsigned long new_crc;  a_patch *patches;  os_fixes *a_fix;  int cnt;  int ret_val;      a_fix = records;    for(cnt = 0; cnt < num_records; cnt++)    {      patches = a_fix->patches;      orig_crc = get_file_crc(path);      if ( orig_crc == a_fix->new_crc )      {          inform(2, "[i] found patched %d.%d.%d %s, no need to patch\n",                 a_fix->major, a_fix->minor, a_fix->sub,a_fix->file_id);          return(1);      }      if ( orig_crc == a_fix->orig_crc )      {          inform(2, "[i] found unpatched %d.%d.%d %s, patching\n", a_fix->major,                  a_fix->minor, a_fix->sub,a_fix->file_id);          break;      }      a_fix++;    }    if ( cnt >= num_records )    {        inform(2, "[e] could not match file to a known signature\n");        return(0);    }    ret_val = do_patches(path, patches);    if ( ret_val == 0 )    {        inform(2, "[e] couldn't perform the patch\n");        return(0);    }    new_crc =  get_file_crc(path);    if ( new_crc != a_fix->new_crc )    {        inform(2, "[e] documented crc: %8.8X actual crc: %8.8X\n",               a_fix->new_crc, new_crc);        return(0);    }    inform(2, "[i] patch succeeded\n");    return(1);}int do_patches(char *path, a_patch *patches){  FILE *patch_file;  a_patch *current_patch;  unsigned char current_byte;  int ret_val;      ret_val = chmod(path, 0777);    if ( ret_val == -1 )    {        inform(2, "[e] couldn't set write permissions on file, continuing\n");    }    patch_file = fopen(path, "r+b");    if( patch_file == NULL )    {        inform(2,"[e] do_patches->fopen failure on %s\n", path);        return(0);    }    current_patch = patches;    while(current_patch->offset != 0xFFFFFFFF)    {        ret_val = fseek(patch_file, current_patch->offset, SEEK_SET);        if(ret_val != 0)        {            inform(2,"[e] do_patches->fseek failure\n");            fclose(patch_file);            return(0);        }        current_byte = fgetc(patch_file);        if(current_byte != current_patch->orig_byte)        {            inform(2,"[e] do_patches: original byte does not match\n");            fclose(patch_file);            return(0);        }        ret_val = fseek(patch_file, current_patch->offset, SEEK_SET);        if(ret_val != 0)        {            inform(2,"[e] do_patches->fseek failure\n");            fclose(patch_file);            return(0);        }        ret_val = fwrite(&current_patch->new_byte, 1, 1, patch_file);        if (ret_val != 1 )        {            inform(2,"[e] do_patches->fputc failure\n");            fclose(patch_file);            return(0);        }        current_patch++;    }    ret_val = fclose(patch_file);    if ( ret_val != 0 )    {        inform(2,"[e] do_patches->fclose failed\n");    }    ret_val = chmod(path, 0555);    if ( ret_val == -1 )    {        inform(2, "[e] couldn't set file permissions to original\n");    }    return(1);}unsigned long get_file_crc(char *path){  unsigned char inbuff[1024];  FILE *in_file;  CRC32_t crc32;  unsigned long ret_val;  int ret_check;      in_file = fopen(path, "rb");    if ( in_file == NULL )    {      inform(2, "[e] get_file_crc->fopen failed on %s\n", path);      return(0);    }    CRC32_Init(&crc32);    while(!feof(in_file))    {      fread(inbuff, sizeof(unsigned char), sizeof(inbuff), in_file);      CRC32_Update(&crc32, inbuff, sizeof(inbuff));    }    ret_check = fclose(in_file);    if ( ret_check != 0 )    {        inform(2, "[e] get_file_crc->fclose failed\n");    }    CRC32_Final((unsigned char *)&ret_val, crc32);    return(ret_val);}void CRC32_Init(CRC32_t *value){  unsigned int index, bit;  CRC32_t entry;  *value = ALL1;  if (table) return;/* mem_alloc() doesn't return on failure.  If replacing this with plain * malloc(3), error checking would need to be added. */  table = malloc(sizeof(*table) * 0x100);  if ( table == NULL )  {    inform(1,"[e] CRC32_Init->malloc failed\n");    exit(-1);  }  for (index = 0; index < 0x100; index++) {    entry = index;    for (bit = 0; bit < 8; bit++)    if (entry & 1) {      entry >>= 1;      entry ^= POLY;    } else      entry >>= 1;    table[index] = entry;  }}void CRC32_Update(CRC32_t *value, void *data, unsigned int size){  unsigned char *ptr;  unsigned int count;  CRC32_t result;  result = *value;  ptr = data;  count = size;  if (count)  do {    result = (result >> 8) ^ table[(result ^ *ptr++) & 0xFF];  } while (--count);  *value = result;}void CRC32_Final(unsigned char *out, CRC32_t value){  value = ~value;  out[0] = value;  out[1] = value >> 8;  out[2] = value >> 16;  out[3] = value >> 24;}