diff options
-rw-r--r-- | tools/fwpatcher/iriver.c | 57 | ||||
-rw-r--r-- | tools/iriver.c | 71 |
2 files changed, 103 insertions, 25 deletions
diff --git a/tools/fwpatcher/iriver.c b/tools/fwpatcher/iriver.c index 0843d9c383..a55b7cb9b9 100644 --- a/tools/fwpatcher/iriver.c +++ b/tools/fwpatcher/iriver.c @@ -101,7 +101,8 @@ int iriver_decode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify, FILE * outfile = NULL; int i = -1; unsigned char headerdata[512]; - unsigned long dwLength1, dwLength2, dwLength3, fp = 0; + unsigned int dwLength1, dwLength2, dwLength3, fp = 0; + unsigned int minsize, maxsize, sizes[2]; unsigned char blockdata[16+16]; unsigned char out[16]; unsigned char newmunge; @@ -138,10 +139,7 @@ int iriver_decode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify, dwLength3 = headerdata[8] | (headerdata[9]<<8) | (headerdata[10]<<16) | (headerdata[11]<<24); - if( dwLength1 < firmware_minsize[ i ] || - dwLength1 > firmware_maxsize[ i ] || - dwLength2 < firmware_minsize[ i ] || - dwLength2 > dwLength1 || + if( dwLength2 > dwLength1 || dwLength3 > dwLength1 || dwLength2>>9 != dwLength3 || dwLength2+dwLength3+512 != dwLength1 ) @@ -151,6 +149,10 @@ int iriver_decode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify, goto error; }; + minsize = firmware_minsize[i]; + maxsize = firmware_maxsize[i]; + sizes[0] = sizes[1] = 0; + pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) ); if( modify ) @@ -177,6 +179,12 @@ int iriver_decode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify, ck += out[i]; } + if (fp <= 32) + sizes[fp / 16 - 1] = (out[0] << 24) | + (out[1] << 16) | + (out[2] << 8) | + (out[3] << 0); + if( fp > ESTF_SIZE || stripmode != STRIP_HEADER_CHECKSUM_ESTF ) { fwrite( out+4, 1, 12, outfile ); @@ -204,6 +212,16 @@ int iriver_decode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify, s+=16; }; + if( sizes[0] < minsize || + sizes[1] < minsize || + sizes[0] > maxsize || + sizes[1] > maxsize ) + { + fprintf( stderr, "This doesn't look like a valid encrypted " + "iHP firmware - reason: ESTFBINR 'length' data\n" ); + goto error; + }; + if( fp != dwLength2 ) { fprintf( stderr, "This doesn't look like a valid encrypted " @@ -269,7 +287,8 @@ int iriver_encode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify ) FILE * outfile = NULL; int i = -1; unsigned char headerdata[512]; - unsigned long dwLength1, dwLength2, dwLength3, fp = 0; + unsigned int dwLength1, dwLength2, dwLength3, fp = 0; + unsigned int minsize, maxsize, sizes[2]; unsigned char blockdata[16+16]; unsigned char out[16]; unsigned char newmunge; @@ -313,10 +332,7 @@ int iriver_encode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify ) dwLength3 = headerdata[8] | (headerdata[9]<<8) | (headerdata[10]<<16) | (headerdata[11]<<24); - if( dwLength1 < firmware_minsize[i] || - dwLength1 > firmware_maxsize[i] || - dwLength2 < firmware_minsize[i] || - dwLength2 > dwLength1 || + if( dwLength2 > dwLength1 || dwLength3 > dwLength1 || dwLength2+dwLength3+512 != dwLength1 ) { @@ -325,6 +341,10 @@ int iriver_encode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify ) goto error; }; + minsize = firmware_minsize[i]; + maxsize = firmware_maxsize[i]; + sizes[0] = sizes[1] = 0; + pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) ); fwrite( headerdata, 512, 1, outfile ); @@ -335,6 +355,13 @@ int iriver_encode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify ) ( lenread = fread( blockdata+16, 1, 16, infile ) ) == 16 ) { fp += 16; + + if (fp <= 32) + sizes[fp / 16 - 1] = (blockdata[28] << 24) | + (blockdata[29] << 16) | + (blockdata[30] << 8) | + (blockdata[31] << 0); + for( i=0; i<16; ++i ) { newmunge = blockdata[16+((12+i)&0xf)] ^ blockdata[i]; @@ -355,6 +382,16 @@ int iriver_encode(TCHAR *infile_name, TCHAR *outfile_name, unsigned int modify ) s+=16; }; + if( sizes[0] < minsize || + sizes[1] < minsize || + sizes[0] > maxsize || + sizes[1] > maxsize ) + { + fprintf( stderr, "This doesn't look like a valid decoded iHP" + " firmware - reason: ESTFBINR 'length' data\n" ); + goto error; + }; + if( fp != dwLength2 ) { fprintf( stderr, "This doesn't look like a valid decoded " diff --git a/tools/iriver.c b/tools/iriver.c index b9ccd2378f..53e8fbe7a7 100644 --- a/tools/iriver.c +++ b/tools/iriver.c @@ -103,7 +103,8 @@ int iriver_decode(const char *infile_name, const char *outfile_name, BOOL modify FILE * outfile = NULL; int i = -1; unsigned char headerdata[512]; - unsigned long dwLength1, dwLength2, dwLength3, fp = 0; + unsigned int dwLength1, dwLength2, dwLength3, fp = 0; + unsigned int minsize, maxsize, sizes[2]; unsigned char blockdata[16+16]; unsigned char out[16]; unsigned char newmunge; @@ -143,10 +144,7 @@ int iriver_decode(const char *infile_name, const char *outfile_name, BOOL modify dwLength3 = headerdata[8] | (headerdata[9]<<8) | (headerdata[10]<<16) | (headerdata[11]<<24); - if( dwLength1 < firmware_minsize[ i ] || - dwLength1 > firmware_maxsize[ i ] || - dwLength2 < firmware_minsize[ i ] || - dwLength2 > dwLength1 || + if( dwLength2 > dwLength1 || dwLength3 > dwLength1 || dwLength2>>9 != dwLength3 || dwLength2+dwLength3+512 != dwLength1 ) @@ -158,6 +156,10 @@ int iriver_decode(const char *infile_name, const char *outfile_name, BOOL modify return -3; }; + minsize = firmware_minsize[i]; + maxsize = firmware_maxsize[i]; + sizes[0] = sizes[1] = 0; + pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) ); if( modify ) @@ -184,6 +186,12 @@ int iriver_decode(const char *infile_name, const char *outfile_name, BOOL modify ck += out[i]; } + if (fp <= 32) + sizes[fp / 16 - 1] = (out[0] << 24) | + (out[1] << 16) | + (out[2] << 8) | + (out[3] << 0); + if( fp > ESTF_SIZE || stripmode != STRIP_HEADER_CHECKSUM_ESTF ) { fwrite( out+4, 1, 12, outfile ); @@ -211,13 +219,25 @@ int iriver_decode(const char *infile_name, const char *outfile_name, BOOL modify s+=16; }; + if( sizes[0] < minsize || + sizes[1] < minsize || + sizes[0] > maxsize || + sizes[1] > maxsize ) + { + fprintf( stderr, "This doesn't look like a valid encrypted " + "iHP firmware - reason: ESTFBINR 'length' data\n" ); + fclose(infile); + fclose(outfile); + return -4; + }; + if( fp != dwLength2 ) { fprintf( stderr, "This doesn't look like a valid encrypted " "iHP firmware - reason: 'length2' mismatch\n" ); fclose(infile); fclose(outfile); - return -4; + return -5; }; fp = 0; @@ -234,7 +254,7 @@ int iriver_decode(const char *infile_name, const char *outfile_name, BOOL modify "iHP firmware - reason: Checksum mismatch!" ); fclose(infile); fclose(outfile); - return -5; + return -6; }; ppChecksums += lenread; }; @@ -245,7 +265,7 @@ int iriver_decode(const char *infile_name, const char *outfile_name, BOOL modify "iHP firmware - reason: 'length3' mismatch\n" ); fclose(infile); fclose(outfile); - return -6; + return -7; }; @@ -276,7 +296,8 @@ int iriver_encode(const char *infile_name, const char *outfile_name, BOOL modify FILE * outfile = NULL; int i = -1; unsigned char headerdata[512]; - unsigned long dwLength1, dwLength2, dwLength3, fp = 0; + unsigned int dwLength1, dwLength2, dwLength3, fp = 0; + unsigned int minsize, maxsize, sizes[2]; unsigned char blockdata[16+16]; unsigned char out[16]; unsigned char newmunge; @@ -321,10 +342,7 @@ int iriver_encode(const char *infile_name, const char *outfile_name, BOOL modify dwLength3 = headerdata[8] | (headerdata[9]<<8) | (headerdata[10]<<16) | (headerdata[11]<<24); - if( dwLength1 < firmware_minsize[i] || - dwLength1 > firmware_maxsize[i] || - dwLength2 < firmware_minsize[i] || - dwLength2 > dwLength1 || + if( dwLength2 > dwLength1 || dwLength3 > dwLength1 || dwLength2+dwLength3+512 != dwLength1 ) { @@ -335,6 +353,10 @@ int iriver_encode(const char *infile_name, const char *outfile_name, BOOL modify return -3; }; + minsize = firmware_minsize[i]; + maxsize = firmware_maxsize[i]; + sizes[0] = sizes[1] = 0; + pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) ); fwrite( headerdata, 512, 1, outfile ); @@ -345,6 +367,13 @@ int iriver_encode(const char *infile_name, const char *outfile_name, BOOL modify ( lenread = fread( blockdata+16, 1, 16, infile ) ) == 16 ) { fp += 16; + + if (fp <= 32) + sizes[fp / 16 - 1] = (blockdata[28] << 24) | + (blockdata[29] << 16) | + (blockdata[30] << 8) | + (blockdata[31] << 0); + for( i=0; i<16; ++i ) { newmunge = blockdata[16+((12+i)&0xf)] ^ blockdata[i]; @@ -365,13 +394,25 @@ int iriver_encode(const char *infile_name, const char *outfile_name, BOOL modify s+=16; }; + if( sizes[0] < minsize || + sizes[1] < minsize || + sizes[0] > maxsize || + sizes[1] > maxsize ) + { + fprintf( stderr, "This doesn't look like a valid decoded iHP" + " firmware - reason: ESTFBINR 'length' data\n" ); + fclose(infile); + fclose(outfile); + return -4; + }; + if( fp != dwLength2 ) { fprintf( stderr, "This doesn't look like a valid decoded " "iHP firmware - reason: 'length1' mismatch\n" ); fclose(infile); fclose(outfile); - return -4; + return -5; }; /* write out remainder w/out applying descrambler */ @@ -392,7 +433,7 @@ int iriver_encode(const char *infile_name, const char *outfile_name, BOOL modify "iHP firmware - reason: 'length2' mismatch\n" ); fclose(infile); fclose(outfile); - return -5; + return -6; }; fprintf( stderr, "File encoded successfully and checksum table built!\n" ); |