void crc_fill_table(ulong *table, int big, ulong polynomial) { ulong lsb = (big) ? 1 << 31 : 1; /* least significant bit */ ulong poly = (big) ? polynomial : crc_reflect(polynomial); int c, i; for (c = 0; c < CRC_TABLE_SIZE; c++, table++) { *table = (big) ? c << 24 : c; for (i = 0; i < 8; i++) { if (*table & lsb) { *table = (big) ? *table << 1 : *table >> 1; *table ^= poly; } else { *table = (big) ? *table << 1 : *table >> 1; } *table &= 0xFFFFFFFF; }
void hashbd(metafile_t *m) { flist_t *f; long long ca,cb,f0,f1; /* pointer to a place in the file list */ unsigned char *pos; /* position in the hash string */ unsigned char *posf; /* position in the hash string */ unsigned char *read_buf; /* read buffer */ unsigned char *bf0; /* read buffer */ unsigned char *bf1; /* read buffer */ ulong remainder; SHA_CTX c; /* SHA1 hashing context */ SHA_CTX cf; /* SHA1 hashing context */ read_buf=malloc(1024*1024*10+10);//100000*32); bf0=malloc(1024*1024*10+10);//100000*32); bf1=malloc(1024*1024*10+10);//100000*32); ////////////////////////////////////////////////////// ca=0; cb=0; f0=0; f1=0; for (f = m->file_list; f; f = f->next) { if(f->bdmv) { memcpy(read_buf+ca,f->hash,32); ca+=32; cb+=f->size; //////////////////////// memcpy(bf1+f1,f->filehash,20); f1+=20; if(f->size>=1024*1024*1024) { memcpy(bf0+f0,f->filehash,20); f0+=20; } //////////////////////// } if(f->bdmv==2) { int i; void (*cycle)(ulong*, ulong*, char) = (big_endian) ? crc_be_cycle : crc_le_cycle; remainder= starting; ulong table2[CRC_TABLE_SIZE]; crc_fill_table(table2, big_endian, polynomial); for (i = 0; i < ca ; i++) cycle(table2, &remainder, read_buf[i]); if (xor_output) remainder ^= 0xFFFFFFFF; if (reflect_output) remainder = crc_reflect(remainder); f->hash[35]=remainder%256; remainder=remainder/256; f->hash[34]=remainder%256; remainder=remainder/256; f->hash[33]=remainder%256; remainder=remainder/256; f->hash[32]=remainder%256; pos = malloc(SHA_DIGEST_LENGTH); SHA1_Init(&c); SHA1_Update(&c,read_buf,ca); SHA1_Final(pos, &c); memcpy(f->hash+36,pos,20); char fsize[9]={0}; long long fs=cb; fsize[7]=fs%256; fs=fs/256; fsize[6]=fs%256; fs=fs/256; fsize[5]=fs%256; fs=fs/256; fsize[4]=fs%256; fs=fs/256; fsize[3]=fs%256; fs=fs/256; fsize[2]=fs%256; fs=fs/256; fsize[1]=fs%256; fs=fs/256; fsize[0]=fs%256; remainder= starting; ulong table[CRC_TABLE_SIZE]; crc_fill_table(table, big_endian, polynomial); for (i = 0; i < 8 ; i++) cycle(table, &remainder, fsize[i]); if (xor_output) remainder ^= 0xFFFFFFFF; if (reflect_output) remainder = crc_reflect(remainder); f->hash[59]=remainder%256; remainder=remainder/256; f->hash[58]=remainder%256; remainder=remainder/256; f->hash[57]=remainder%256; remainder=remainder/256; f->hash[56]=remainder%256; ///////////////////////////////// posf = malloc(SHA_DIGEST_LENGTH); SHA1_Init(&cf); if(f0) SHA1_Update(&cf,bf0,f0); else SHA1_Update(&cf,bf1,f1); SHA1_Final(posf, &cf); memcpy(f->hash+60,posf,20); ///////////////////////////////// f1=0; f0=0; ca=0; cb=0; free(pos); free(posf); } } free(read_buf); free(bf0); free(bf1); }
EXPORT unsigned char *make_hash(metafile_t *m) { char *cc; flist_t *f; /* pointer to a place in the file list */ unsigned char *hash_string; /* the hash string */ unsigned char *lthash_string; /* the hash string */ unsigned char *pos; /* position in the hash string */ unsigned char *ltpos; /* position in the hash string */ unsigned char *read_buf; /* read buffer */ unsigned char *read_buf2; /* read buffer */ unsigned char *read_buf3; /* read buffer */ int fd; /* file descriptor */ ssize_t r; /* number of bytes read from file(s) into the read buffer */ SHA_CTX c; /* SHA1 hashing context */ SHA_CTX ltc; /* SHA1 hashing context */ #ifndef NO_HASH_CHECK off_t counter = 0; /* number of bytes hashed should match size when done */ #endif /* allocate memory for the hash string every SHA1 hash is SHA_DIGEST_LENGTH (20) bytes long */ read_buf = malloc(m->piece_length*2); read_buf2 = malloc(m->piece_length); read_buf3 = malloc(m->piece_length); unsigned int piece_length=m->piece_length; unsigned int piece_length8=1<<23; hash_string = malloc(m->pieces * SHA_DIGEST_LENGTH); /* allocate memory for the read buffer to store 1 piece */ /* check if we've run out of memory */ if (hash_string == NULL || read_buf == NULL) { fprintf(stderr, "Out of memory.\n"); exit(EXIT_FAILURE); } /* initiate pos to point to the beginning of hash_string */ pos = hash_string; /* and initiate r to 0 since we haven't read anything yet */ r = 0; /* go through all the files in the file list */ for (f = m->file_list; f; f = f->next) { lthash_string = malloc(SHA_DIGEST_LENGTH); if (lthash_string == NULL) { fprintf(stderr, "Out of memory.\n"); exit(EXIT_FAILURE); } /* open the current file for reading */ printf("Hashing %s\n", f->path); int loopi,pathlen=strlen(f->path); long long patha=0; long long pathb=0; long long pathc=0; long long pathe=0; f->rains=NULL; f->data=NULL; f->datalength=0; //let cut: py sh ini inf log cue txt avs vpy spy mpls bdmv clpi miniso qpfile // 6845230 7958574 1768843566 1718511918 1735355438 1702191918 1954051118 1937137966 2037413422 2037412654 495740546350 508641436206 452857717550 31370619076046126 28548172593787182 if(pathlen>3) for (loopi=1;loopi<=3;++loopi) { patha+=f->path[pathlen-loopi]; patha*=256; } if(pathlen>4) for (loopi=1;loopi<=4;++loopi) { pathb+=f->path[pathlen-loopi]; pathb*=256; } if(pathlen>5) for (loopi=1;loopi<=5;++loopi) { pathc+=f->path[pathlen-loopi]; pathc*=256; } if(pathlen>7) for (loopi=1;loopi<=7;++loopi) { pathe+=f->path[pathlen-loopi]; pathe*=256; } patha/=256; pathb/=256; pathc/=256; pathe/=256; if((!f->color)||patha==7958574||patha==6845230 ||pathb==1768843566 ||pathb==1718511918 ||pathb==1735355438 ||pathb==1702191918 ||pathb==1954051118 ||pathb==1937137966 ||pathb==2037413422 ||pathb==2037412654 ||pathc==495740546350 ||pathc==508641436206 ||pathc==452857717550 ||pathe==31370619076046126 ||pathe==28548172593787182) if(f->size<=2097152) { cc=(char *)malloc(2097152); f->datalength=mkgz(cc,f->path); if(f->datalength==0) free(cc); else f->data=cc; } if(pathb==879783214) { FILE *mp4; mp4=fopen(f->path,"rb"); char cmt[5]={0xA9,0x67,0x65,0x6E,0}; //char cmt[5]={0xA9,0x63,0x6d,0x74,0}; fseek(mp4,0,2); long lmp4=ftell(mp4); fseek(mp4,lmp4-10000,0); if(!rsfind("Koishi",mp4)) { fseek(mp4,lmp4-10000,0); if(!rsfind("Yuki",mp4)) { cmt[1]=0x63; cmt[2]=0x6d; cmt[3]=0x74; fseek(mp4,lmp4-10000,0); if(!rsfind("RainS!",mp4)) { fclose(mp4); mp4=NULL; } } } if(mp4&&rsfind(cmt,mp4)) { fseek(mp4,16,1); long fs=ftell(mp4); while(fgetc(mp4)!='U'); long rlen=ftell(mp4)-fs; fseek(mp4,fs,0); char *rains; rains=(char *)malloc(rlen); rains[rlen-1]=0; fread(rains,1,rlen-1,mp4); //printf("%s",rains); f->rains=rains; } fclose(mp4); } ////////////////////////////////////////// sha1 1M hash FILE *lt4; unsigned char *ltcc,*ltp; ltcc=malloc(1024*1024*10+10); long lti,ltflen,ltlen,partlen; lt4=fopen(f->path,"rb"); fseek(lt4,0,2); ltlen=ltflen=ftell(lt4); fseek(lt4,0,0); if(ltflen<1024*1024*10) fread(ltcc,ltlen,1,lt4); else { ltlen=1024*1024*10; partlen=(ltflen-1024*1024)/9; //printf("\n%ld\n",ltflen); for(lti=0;lti<9;++lti) { //printf("\n%ld\n",lti*partlen); ltp=ltcc+lti*1024*1024; fseek(lt4,lti*partlen,0); fread(ltp,1024*1024,1,lt4); } ltp=ltcc+9*1024*1024; fseek(lt4,-1024*1024,2); fread(ltp,1024*1024,1,lt4); } ltpos = lthash_string; SHA1_Init(<c); SHA1_Update(<c, ltcc, ltlen); SHA1_Final(ltpos, <c); //f->filehash[20]=0; memcpy(f->filehash,ltpos,20); free(ltpos); free(ltcc); fclose(lt4); ////////////////////////////////////////// fflush(stdout); #if defined _LARGEFILE_SOURCE && defined O_LARGEFILE if ((fd = open(f->path, O_RDONLY | O_BINARY | O_LARGEFILE)) == -1) { #else if ((fd = open(f->path, O_RDONLY | O_BINARY)) == -1) { #endif fprintf(stderr, "Error opening '%s' for reading: %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } /* fill the read buffer with the contents of the file and append the SHA1 hash of it to the hash string when the buffer is full. repeat until we can't fill the read buffer and we've thus come to the end of the file */ ulong remainder = starting; ulong table[CRC_TABLE_SIZE]; crc_fill_table(table, big_endian, polynomial); /////////////////////////////////////// long ltpieces =(f->size + piece_length8 - 1) / piece_length8; f->sha1length=ltpieces*SHA_DIGEST_LENGTH; f->sha32length=(ltpieces-1)*4+2*SHA_DIGEST_LENGTH; f->sha1 = lthash_string = NULL; f->sha1 = malloc(f->sha1length); f->sha32 = malloc(f->sha32length); if (f->sha1 == NULL) { fprintf(stderr, "Out of memory.\n"); exit(EXIT_FAILURE); } ltpos = f->sha1; int tune=1; long long last=f->size; /////////////////////////////////////// while (1) { ssize_t d; if(tune) d = read(fd, read_buf + r, m->piece_length); // - r else { if(last<m->piece_length) d=last; else d=m->piece_length; } last=last-d; int err2=0; pthread_t sid2; if (d < 0) { fprintf(stderr, "Error reading from '%s': %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } if (d == 0) /* end of file */ break; if(tune) { memcpy(read_buf2,read_buf+r*sizeof(char),d*sizeof(char)); //sha1 process distory string type_sha1 u_sha1; u_sha1.ltcp=<c; u_sha1.read_buf=read_buf2; u_sha1.d=d; u_sha1.ltpos=ltpos; if(f->color) { if(piece_length8!=piece_length) // main 24 this 23 (8) err2=pthread_create(&sid2, NULL, &sha1p24, &u_sha1); else err2=pthread_create(&sid2, NULL, &sha1p, &u_sha1); } if(err2!=0) { printf("Create pthread error!\n"); exit(EXIT_FAILURE); } } // ltc read_buf2 d ltpos //SHA1_Init(<c); //SHA1_Update(<c, read_buf2, d); //SHA1_Final(ltpos, <c); if (f->color) r += d; if (f->color && r >= m->piece_length) { SHA1_Init(&c); SHA1_Final(pos, &c); pos += SHA_DIGEST_LENGTH; #ifndef NO_HASH_CHECK counter += m->piece_length; /* r == piece_length */ #endif r -= m->piece_length; if(r!=0) memcpy(read_buf,read_buf+m->piece_length*sizeof(char),r*sizeof(char)); } if(f->color&&tune) pthread_join(sid2,NULL); tune=0; break; } //printf("%ld %ld\n",f->size,last); if (xor_output) remainder ^= 0xFFFFFFFF; if (reflect_output) remainder = crc_reflect(remainder); //printf("%08X\n", (int) remainder); //sprintf(f->hash,"%08X", (int) remainder); f->hash[32]=0; ///////////////////////////////// press crc32_file f->hash[3]=remainder%256; remainder=remainder/256; f->hash[2]=remainder%256; remainder=remainder/256; f->hash[1]=remainder%256; remainder=remainder/256; f->hash[0]=remainder%256; ///////////////////////////////// press sha1_file if(f->color) { ltpos=malloc(SHA_DIGEST_LENGTH); SHA1_Init(<c); SHA1_Update(<c, f->sha1,f->sha1length); SHA1_Final(ltpos, <c); } int fori; for(fori=0;fori<20;++fori) { if(f->color) f->hash[fori+4]=ltpos[fori]^f->filehash[fori]; else f->hash[fori+4]=f->filehash[fori]; } //////////////////////////////// press crc32_size char fsize[9]={0}; long long fs=f->size; fsize[7]=fs%256; fs=fs/256; fsize[6]=fs%256; fs=fs/256; fsize[5]=fs%256; fs=fs/256; fsize[4]=fs%256; fs=fs/256; fsize[3]=fs%256; fs=fs/256; fsize[2]=fs%256; fs=fs/256; fsize[1]=fs%256; fs=fs/256; fsize[0]=fs%256; int i; void (*cycle)(ulong*, ulong*, char) = (big_endian) ? crc_be_cycle : crc_le_cycle; remainder = starting; crc_fill_table(table, big_endian, polynomial); for (i = 0; i < 8 ; i++) cycle(table, &remainder, fsize[i]); if (xor_output) remainder ^= 0xFFFFFFFF; if (reflect_output) remainder = crc_reflect(remainder); f->hash[27]=remainder%256; remainder=remainder/256; f->hash[26]=remainder%256; remainder=remainder/256; f->hash[25]=remainder%256; remainder=remainder/256; f->hash[24]=remainder%256; //////////////////////////////// press crc32_sha1 remainder = starting; crc_fill_table(table, big_endian, polynomial); for (i = 0; i < f->sha1length; i++) cycle(table, &remainder, f->sha1[i]); if (xor_output) remainder ^= 0xFFFFFFFF; if (reflect_output) remainder = crc_reflect(remainder); f->hash[31]=remainder%256; remainder=remainder/256; f->hash[30]=remainder%256; remainder=remainder/256; f->hash[29]=remainder%256; remainder=remainder/256; f->hash[28]=remainder%256; if(f->color) { /* precess sha32 */ memcpy(f->sha32,f->sha1,SHA_DIGEST_LENGTH); memcpy(f->sha32+SHA_DIGEST_LENGTH,ltpos,SHA_DIGEST_LENGTH); remainder = starting; crc_fill_table(table, big_endian, polynomial); for (i = SHA_DIGEST_LENGTH; i < f->sha1length; i++) { cycle(table, &remainder, f->sha1[i]); if((i+1)%SHA_DIGEST_LENGTH==0) { if (xor_output) remainder ^= 0xFFFFFFFF; if (reflect_output) remainder = crc_reflect(remainder); f->sha32[ ( (i+1-40)/20 )*4+40+3 ]=remainder%256; remainder=remainder/256; f->sha32[ ( (i+1-40)/20 )*4+40+2 ]=remainder%256; remainder=remainder/256; f->sha32[ ( (i+1-40)/20 )*4+40+1 ]=remainder%256; remainder=remainder/256; f->sha32[ ( (i+1-40)/20 )*4+40 ]=remainder%256; remainder = starting; crc_fill_table(table, big_endian, polynomial); } } } /* now close the file */ if (close(fd)) { fprintf(stderr, "Error closing '%s': %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } } /* finally append the hash of the last irregular piece to the hash string */ if (r) { SHA1_Init(&c); SHA1_Update(&c, read_buf, r); SHA1_Final(pos, &c); } /* free the read buffer before we return */ free(read_buf); free(read_buf2); free(read_buf3); hashbd(m); return hash_string; }
int main(int argc, char **argv) { FILE *f; size_t flen; if(argc < 3) { printf("Usage: genhdr <input file> <signature> <version>\n" " input file: file to be headered\n" " signature : magic value at start of header (4-char string)\n" " version : firmware version (decimal uint32)\n" "Output is written in place.\n"); return 1; } if((f=fopen(argv[1], "rb+"))==NULL) { printf("Unable to open input file %s", argv[1]); perror(""); return 1; } fseek(f,0,SEEK_END); flen=ftell(f); if(flen+256 < flen) { printf("File too large ;)\n"); return 1; } char *remaining = NULL; uint32_t version = (uint32_t)strtol(argv[3], &remaining, 10); if(*remaining) { printf("could not parse version number (remaining portion: %s)\n", remaining); fclose(f); return 1; } if(strlen(argv[2]) > 4) { printf("Magic string '%s' too long. Truncated to 4 characters.\n", argv[2]); } uint8_t *buf = malloc(flen+256); if(!buf) { perror("malloc"); } memset(buf, 0xff, 256); fseek(f, 0, SEEK_SET); fread(buf+256, 1, flen, f); uint32_t crcc = 0xffffffff, crc; crcc = crc_update(crcc, buf+256, flen); crcc = crc_reflect(crcc, 32); crc = crcc ^ 0xffffffff; memset(buf, 0, 4); strncpy((char*)buf, argv[2], 4); buf[4] = ll8(version); buf[5] = lh8(version); buf[6] = hl8(version); buf[7] = hh8(version); buf[8] = ll8(flen); buf[9] = lh8(flen); buf[10] = hl8(flen); buf[11] = hh8(flen); buf[12] = ll8(crc); buf[13] = lh8(crc); buf[14] = hl8(crc); buf[15] = hh8(crc); buf[16] = ll8(crcc); buf[17] = lh8(crcc); buf[18] = hl8(crcc); buf[19] = hh8(crcc); fseek(f, 0, SEEK_SET); fwrite(buf, 1, 256+flen, f); fclose(f); return 0; }