*ash class: slightly better error handling & memory management. should help fix/avoid some issues with buffer overflowing using the hardcoded buffer size from crediar's original code

git-svn-id: http://wiiqt.googlecode.com/svn/trunk@71 389f4c8b-5dfe-645f-db0e-df882bc27289
This commit is contained in:
giantpune 2011-01-29 08:44:22 +00:00
parent bd7b56f644
commit e48e9d67e0
3 changed files with 873 additions and 851 deletions

View File

@ -1,4 +1,8 @@
#include "ash.h" #include "ash.h"
//this is large enough for all the system menu ash0 files, and thats all i need it for
#define BUFFER_SIZE 0x600000
bool IsAshCompressed( const QByteArray ba ) bool IsAshCompressed( const QByteArray ba )
{ {
return ba.startsWith( "ASH" ); return ba.startsWith( "ASH" );
@ -6,6 +10,7 @@ bool IsAshCompressed( const QByteArray ba )
QByteArray DecryptAsh( const QByteArray ba ) QByteArray DecryptAsh( const QByteArray ba )
{ {
//qDebug() << "DecryptAsh()";
if( !IsAshCompressed( ba ) ) if( !IsAshCompressed( ba ) )
{ {
qWarning() << "DecryptAsh -> wrong magic"; qWarning() << "DecryptAsh -> wrong magic";
@ -16,27 +21,38 @@ QByteArray DecryptAsh( const QByteArray ba )
quint32 t; quint32 t;
quint64 memAddr = (quint64)( ba.data() );//in quint64 memAddr = (quint64)( ba.data() );//in
r[4] = 0x80000000; r[4] = 0x8000000;
qint64 inDiff = memAddr - r[ 4 ];//difference in r[ 4 ] and the real address. hack to support higher memory addresses than crediar's version qint64 inDiff = memAddr - r[ 4 ];//difference in r[ 4 ] and the real address. hack to support higher memory addresses than crediar's version
r[5] = 0x415348; r[5] = 0x415348;
r[6] = 0x415348; r[6] = 0x415348;
//Rvl_decode_ash: //Rvl_decode_ash:
r[5] = qFromBigEndian(*(quint32 *)( r[4] + inDiff + 4 ) ); r[5] = qFromBigEndian(*(quint32 *)( r[4] + inDiff + 4 ) );
r[5] = r[5] & 0x00FFFFFF; r[5] = r[5] & 0x00FFFFFF;
quint32 size = r[5]; quint32 size = r[5];
//qDebug() << "Decompressed size:" << hex << size; //qDebug() << "Decompressed size:" << hex << size;
if( size > BUFFER_SIZE )
{
qWarning() << "DecryptAsh(): this file was built with a buffer to small to deal with this archive. Build it with a bigger one and try again."
<< hex << size << ">" << BUFFER_SIZE;
return QByteArray();
}
char crap2[ size ]; QByteArray crap2( size, '\0' );
quint64 memAddr2 = (quint64)( crap2 );//outbuf if( (quint32)crap2.size() != size )
r[3] = 0x90000000; {
qWarning() << "DecryptAsh(): out of memory 1";
return QByteArray();
}
//char crap2[ size ];
quint64 memAddr2 = (quint64)( crap2.data() );//outbuf
r[3] = 0x9000000;
qint64 outDiff = memAddr2 - r[ 3 ];//difference in r[ 3 ] and the real address qint64 outDiff = memAddr2 - r[ 3 ];//difference in r[ 3 ] and the real address
quint32 o = r[ 3 ]; quint32 o = r[ 3 ];
memset( (void*)( r[ 3 ] + outDiff ), 0, size );
r[24] = 0x10; r[24] = 0x10;
r[28] = qFromBigEndian(*(quint32 *)(r[4]+8 + inDiff)); r[28] = qFromBigEndian(*(quint32 *)(r[4]+8 + inDiff));
@ -48,12 +64,18 @@ QByteArray DecryptAsh( const QByteArray ba )
//r[8] = 0x8108<<16; //r[8] = 0x8108<<16;
//HACK, pointer to RAM //HACK, pointer to RAM
char crap3[ 0x100000 ]; QByteArray crap3( BUFFER_SIZE, '\0' );
quint64 memAddr3 = (quint64)( crap3 );//outbuf if( crap3.size() != BUFFER_SIZE )
{
qWarning() << "DecryptAsh(): out of memory 1";
return QByteArray();
}
//char crap3[ 0x100000 ];
quint64 memAddr3 = (quint64)( crap3.data() );//outbuf
r[8] = 0x84000000; r[8] = 0x84000000;
qint64 outDiff2 = memAddr3 - r[ 8 ];//difference in r[ 3 ] and the real address qint64 outDiff2 = memAddr3 - r[ 8 ];//difference in r[ 3 ] and the real address
memset( (void*)( r[8] + outDiff2 ), 0, 0x100000 ); memset( (void*)( r[8] + outDiff2 ), 0, 0x100000 );
r[8] = r[8]; r[8] = r[8];
r[9] = r[8] + 0x07FE; r[9] = r[8] + 0x07FE;
r[10] = r[9] + 0x07FE; r[10] = r[9] + 0x07FE;
@ -63,7 +85,7 @@ QByteArray DecryptAsh( const QByteArray ba )
r[22] = 0x200; r[22] = 0x200;
r[27] = 0; r[27] = 0;
loc_81332124: loc_81332124:
if( r[25] != 0x1F ) if( r[25] != 0x1F )
goto loc_81332140; goto loc_81332140;
@ -74,13 +96,13 @@ loc_81332124:
r[24]= r[24] + 4; r[24]= r[24] + 4;
goto loc_8133214C; goto loc_8133214C;
loc_81332140: loc_81332140:
r[0] = r[26] >> 31; r[0] = r[26] >> 31;
r[25]= r[25] + 1; r[25]= r[25] + 1;
r[26]= r[26] << 1; r[26]= r[26] << 1;
loc_8133214C: loc_8133214C:
if( r[0] == 0 ) if( r[0] == 0 )
goto loc_81332174; goto loc_81332174;
@ -97,7 +119,7 @@ loc_8133214C:
goto loc_81332124; goto loc_81332124;
loc_81332174: loc_81332174:
r[12] = 9; r[12] = 9;
r[21] = r[25] + r[12]; r[21] = r[25] + r[12];
@ -114,14 +136,14 @@ loc_81332174:
r[25] = r[25] + r[12]; r[25] = r[25] + r[12];
goto loc_813321D0; goto loc_813321D0;
loc_8133219C: loc_8133219C:
r[26]= qFromBigEndian(*(quint32 *)(r[4] + r[24] + inDiff)); r[26]= qFromBigEndian(*(quint32 *)(r[4] + r[24] + inDiff));
r[25]= 0; r[25]= 0;
r[24]= r[24] + 4; r[24]= r[24] + 4;
goto loc_813321D0; goto loc_813321D0;
loc_813321AC: loc_813321AC:
r[0] = (~(r[12] - 0x20))+1; r[0] = (~(r[12] - 0x20))+1;
r[6] = r[26] >> r[0]; r[6] = r[26] >> r[0];
@ -133,7 +155,7 @@ loc_813321AC:
r[25] = r[21] - 0x20; r[25] = r[21] - 0x20;
r[26] = r[26] << r[25]; r[26] = r[26] << r[25];
loc_813321D0: loc_813321D0:
r[12]= (quint16)qFromBigEndian((quint16)(*(quint16 *)(( r[31] + outDiff2 ) - 2))); r[12]= (quint16)qFromBigEndian((quint16)(*(quint16 *)(( r[31] + outDiff2 ) - 2)));
r[31] -= 2; r[31] -= 2;
@ -150,18 +172,18 @@ loc_813321D0:
goto loc_81332204; goto loc_81332204;
loc_813321F8: loc_813321F8:
*(quint16 *)(r[8]+r[12] + outDiff2) = (quint16)qFromBigEndian((quint16)r[6]); *(quint16 *)(r[8]+r[12] + outDiff2) = (quint16)qFromBigEndian((quint16)r[6]);
r[23] = r[22]; r[23] = r[22];
goto loc_81332124; goto loc_81332124;
loc_81332204: loc_81332204:
r[23] = 0x800; r[23] = 0x800;
r[22] = 0x800; r[22] = 0x800;
loc_8133220C: loc_8133220C:
if( r[29] != 0x1F ) if( r[29] != 0x1F )
goto loc_81332228; goto loc_81332228;
@ -172,13 +194,13 @@ loc_8133220C:
r[28]= r[28] + 4; r[28]= r[28] + 4;
goto loc_81332234; goto loc_81332234;
loc_81332228: loc_81332228:
r[0] = r[30] >> 31; r[0] = r[30] >> 31;
r[29]= r[29] + 1; r[29]= r[29] + 1;
r[30]= r[30] << 1; r[30]= r[30] << 1;
loc_81332234: loc_81332234:
if( r[0] == 0 ) if( r[0] == 0 )
goto loc_8133225C; goto loc_8133225C;
@ -195,7 +217,7 @@ loc_81332234:
goto loc_8133220C; goto loc_8133220C;
loc_8133225C: loc_8133225C:
r[12] = 0xB; r[12] = 0xB;
r[21] = r[29] + r[12]; r[21] = r[29] + r[12];
@ -212,14 +234,14 @@ loc_8133225C:
r[29] = r[29] + r[12]; r[29] = r[29] + r[12];
goto loc_813322B8; goto loc_813322B8;
loc_81332284: loc_81332284:
r[30]= qFromBigEndian(*(quint32 *)(r[4] + r[28] + inDiff)); r[30]= qFromBigEndian(*(quint32 *)(r[4] + r[28] + inDiff));
r[29]= 0; r[29]= 0;
r[28]= r[28] + 4; r[28]= r[28] + 4;
goto loc_813322B8; goto loc_813322B8;
loc_81332294: loc_81332294:
r[0] = (~(r[12] - 0x20))+1; r[0] = (~(r[12] - 0x20))+1;
r[7] = r[30] >> r[0]; r[7] = r[30] >> r[0];
@ -231,7 +253,7 @@ loc_81332294:
r[29]= r[21] - 0x20; r[29]= r[21] - 0x20;
r[30]= r[30] << r[29]; r[30]= r[30] << r[29];
loc_813322B8: loc_813322B8:
r[12]= (quint16)qFromBigEndian((quint16)(*(quint16 *)((r[31] + outDiff2 ) - 2))); r[12]= (quint16)qFromBigEndian((quint16)(*(quint16 *)((r[31] + outDiff2 ) - 2)));
r[31] -= 2; r[31] -= 2;
@ -248,21 +270,21 @@ loc_813322B8:
goto loc_813322EC; goto loc_813322EC;
loc_813322E0: loc_813322E0:
*(quint16 *)(r[10]+r[12] + outDiff2 ) = (quint16)qFromBigEndian((quint16)r[7]); *(quint16 *)(r[10]+r[12] + outDiff2 ) = (quint16)qFromBigEndian((quint16)r[7]);
r[23] = r[22]; r[23] = r[22];
goto loc_8133220C; goto loc_8133220C;
loc_813322EC: loc_813322EC:
r[0] = r[5]; r[0] = r[5];
loc_813322F0: loc_813322F0:
r[12]= r[6]; r[12]= r[6];
loc_813322F4: loc_813322F4:
if( r[12] < 0x200 ) if( r[12] < 0x200 )
goto loc_8133233C; goto loc_8133233C;
@ -276,13 +298,13 @@ loc_813322F4:
r[25] = 0; r[25] = 0;
goto loc_81332324; goto loc_81332324;
loc_81332318: loc_81332318:
r[31] = r[26] >> 31; r[31] = r[26] >> 31;
r[25] = r[25] + 1; r[25] = r[25] + 1;
r[26] = r[26] << 1; r[26] = r[26] << 1;
loc_81332324: loc_81332324:
r[27] = r[12] << 1; r[27] = r[12] << 1;
if( r[31] != 0 ) if( r[31] != 0 )
@ -291,12 +313,12 @@ loc_81332324:
r[12] = (quint16)qFromBigEndian((quint16)(*(quint16 *)(r[8] + r[27] + outDiff2 ))); r[12] = (quint16)qFromBigEndian((quint16)(*(quint16 *)(r[8] + r[27] + outDiff2 )));
goto loc_813322F4; goto loc_813322F4;
loc_81332334: loc_81332334:
r[12] = (quint16)qFromBigEndian((quint16)(*(quint16 *)(r[9] + r[27] + outDiff2 ))); r[12] = (quint16)qFromBigEndian((quint16)(*(quint16 *)(r[9] + r[27] + outDiff2 )));
goto loc_813322F4; goto loc_813322F4;
loc_8133233C: loc_8133233C:
if( r[12] >= 0x100 ) if( r[12] >= 0x100 )
goto loc_8133235C; goto loc_8133235C;
@ -309,11 +331,11 @@ loc_8133233C:
goto loc_81332434; goto loc_81332434;
loc_8133235C: loc_8133235C:
r[23] = r[7]; r[23] = r[7];
loc_81332360: loc_81332360:
if( r[23] < 0x800 ) if( r[23] < 0x800 )
goto loc_813323A8; goto loc_813323A8;
@ -327,13 +349,13 @@ loc_81332360:
r[29] = 0; r[29] = 0;
goto loc_81332390; goto loc_81332390;
loc_81332384: loc_81332384:
r[31] = r[30] >> 31; r[31] = r[30] >> 31;
r[29] = r[29] + 1; r[29] = r[29] + 1;
r[30] = r[30] << 1; r[30] = r[30] << 1;
loc_81332390: loc_81332390:
r[27] = r[23] << 1; r[27] = r[23] << 1;
if( r[31] != 0 ) if( r[31] != 0 )
@ -342,12 +364,12 @@ loc_81332390:
r[23] = (quint16)qFromBigEndian((quint16)(*(quint16 *)(r[10] + r[27] + outDiff2 ))); r[23] = (quint16)qFromBigEndian((quint16)(*(quint16 *)(r[10] + r[27] + outDiff2 )));
goto loc_81332360; goto loc_81332360;
loc_813323A0: loc_813323A0:
r[23] = (quint16)qFromBigEndian((quint16)(*(quint16 *)(r[11] + r[27] + outDiff2 ))); r[23] = (quint16)qFromBigEndian((quint16)(*(quint16 *)(r[11] + r[27] + outDiff2 )));
goto loc_81332360; goto loc_81332360;
loc_813323A8: loc_813323A8:
r[12] = r[12] - 0xFD; r[12] = r[12] - 0xFD;
r[23] = ~r[23] + r[3] + 1; r[23] = ~r[23] + r[3] + 1;
@ -359,7 +381,7 @@ loc_813323A8:
count = r[31]; count = r[31];
loc_813323C0: loc_813323C0:
r[31] = *(quint8 *)(( r[23] + outDiff ) - 1); r[31] = *(quint8 *)(( r[23] + outDiff ) - 1);
*(quint8 *)(r[3] + outDiff) = r[31]; *(quint8 *)(r[3] + outDiff) = r[31];
@ -395,11 +417,11 @@ loc_813323C0:
if( r[12] == 0 ) if( r[12] == 0 )
goto loc_8133242C; goto loc_8133242C;
loc_81332414: loc_81332414:
count = r[12]; count = r[12];
loc_81332418: loc_81332418:
r[31] = *(quint8 *)(( r[23] + outDiff ) - 1); r[31] = *(quint8 *)(( r[23] + outDiff ) - 1);
r[23] = r[23] + 1; r[23] = r[23] + 1;
@ -409,12 +431,12 @@ loc_81332418:
if( --count ) if( --count )
goto loc_81332418; goto loc_81332418;
loc_8133242C: loc_8133242C:
if( r[5] != 0 ) if( r[5] != 0 )
goto loc_813322F0; goto loc_813322F0;
loc_81332434: loc_81332434:
r[3] = r[0]; r[3] = r[0];