diff options
Diffstat (limited to 'tools/fwpatcher/iriver.c')
-rw-r--r-- | tools/fwpatcher/iriver.c | 57 |
1 files changed, 47 insertions, 10 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 " |