summaryrefslogtreecommitdiffstats
path: root/tools/fwpatcher
diff options
context:
space:
mode:
Diffstat (limited to 'tools/fwpatcher')
-rw-r--r--tools/fwpatcher/iriver.c57
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 "