*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

This commit is contained in:
giantpune 2011-01-29 08:44:22 +00:00
parent 506aa591e5
commit c96add47e3
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,37 +10,49 @@ 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";
return QByteArray(); return QByteArray();
} }
quint32 r[ 32 ]; quint32 r[ 32 ];
quint32 count=0; quint32 count=0;
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,10 +85,10 @@ 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;
r[0] = r[26] >> 31; r[0] = r[26] >> 31;
r[26]= qFromBigEndian(*(quint32 *)(r[4] + r[24] + inDiff)); r[26]= qFromBigEndian(*(quint32 *)(r[4] + r[24] + inDiff));
@ -74,16 +96,16 @@ 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;
r[0] = r[23] | 0x8000; r[0] = r[23] | 0x8000;
*(quint16 *)(r[31] + outDiff2) = (quint16)qFromBigEndian((quint16)r[0]); *(quint16 *)(r[31] + outDiff2) = (quint16)qFromBigEndian((quint16)r[0]);
@ -97,31 +119,31 @@ 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];
t = r[21]; t = r[21];
if( r[21] > 0x20 ) if( r[21] > 0x20 )
goto loc_813321AC; goto loc_813321AC;
r[21] = (~(r[12] - 0x20))+1; r[21] = (~(r[12] - 0x20))+1;
r[6] = r[26] >> r[21]; r[6] = r[26] >> r[21];
if( t == 0x20 ) if( t == 0x20 )
goto loc_8133219C; goto loc_8133219C;
r[26] = r[26] << r[12]; r[26] = r[26] << r[12];
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;
@ -141,30 +163,30 @@ loc_813321D0:
r[0] = r[12] & 0x8000; r[0] = r[12] & 0x8000;
r[12]= (r[12] & 0x1FFF) << 1; r[12]= (r[12] & 0x1FFF) << 1;
if( r[0] == 0 ) if( r[0] == 0 )
goto loc_813321F8; goto loc_813321F8;
*(quint16 *)(r[9]+r[12] + outDiff2 ) = (quint16)qFromBigEndian((quint16)r[6]);//????? *(quint16 *)(r[9]+r[12] + outDiff2 ) = (quint16)qFromBigEndian((quint16)r[6]);//?????
r[6] = (r[12] & 0x3FFF)>>1;//extrwi %r6, %r12, 14,17 r[6] = (r[12] & 0x3FFF)>>1;//extrwi %r6, %r12, 14,17
if( r[27] != 0 ) if( r[27] != 0 )
goto loc_813321D0; goto 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;
r[0] = r[30] >> 31; r[0] = r[30] >> 31;
r[30]= qFromBigEndian(*(quint32 *)(r[4] + r[28] + inDiff)); r[30]= qFromBigEndian(*(quint32 *)(r[4] + r[28] + inDiff));
@ -172,16 +194,16 @@ 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;
r[0] = r[23] | 0x8000; r[0] = r[23] | 0x8000;
*(quint16 *)(r[31] + outDiff2) = (quint16)qFromBigEndian((quint16)r[0]); *(quint16 *)(r[31] + outDiff2) = (quint16)qFromBigEndian((quint16)r[0]);
@ -195,31 +217,31 @@ 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];
t = r[21]; t = r[21];
if( r[21] > 0x20 ) if( r[21] > 0x20 )
goto loc_81332294; goto loc_81332294;
r[21] = (~(r[12] - 0x20))+1; r[21] = (~(r[12] - 0x20))+1;
r[7] = r[30] >> r[21]; r[7] = r[30] >> r[21];
if( t == 0x20 ) if( t == 0x20 )
goto loc_81332284; goto loc_81332284;
r[30] = r[30] << r[12]; r[30] = r[30] << r[12];
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;
@ -239,36 +261,36 @@ loc_813322B8:
r[0] = r[12] & 0x8000; r[0] = r[12] & 0x8000;
r[12]= (r[12] & 0x1FFF) << 1; r[12]= (r[12] & 0x1FFF) << 1;
if( r[0] == 0 ) if( r[0] == 0 )
goto loc_813322E0; goto loc_813322E0;
*(quint16 *)(r[11]+r[12] + outDiff2 ) = (quint16)qFromBigEndian((quint16)r[7]);//???? *(quint16 *)(r[11]+r[12] + outDiff2 ) = (quint16)qFromBigEndian((quint16)r[7]);//????
r[7] = (r[12] & 0x3FFF)>>1;// extrwi %r7, %r12, 14,17 r[7] = (r[12] & 0x3FFF)>>1;// extrwi %r7, %r12, 14,17
if( r[27] != 0 ) if( r[27] != 0 )
goto loc_813322B8; goto 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;
if( r[25] != 0x1F ) if( r[25] != 0x1F )
goto loc_81332318; goto loc_81332318;
r[31] = r[26] >> 31; r[31] = r[26] >> 31;
r[26] = qFromBigEndian(*(quint32 *)(r[4] + r[24] + inDiff)); r[26] = qFromBigEndian(*(quint32 *)(r[4] + r[24] + inDiff));
@ -276,50 +298,50 @@ 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 )
goto loc_81332334; goto loc_81332334;
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;
*(quint8 *)(r[3] + outDiff) = r[12]; *(quint8 *)(r[3] + outDiff) = r[12];
r[3] = r[3] + 1; r[3] = r[3] + 1;
r[5] = r[5] - 1; r[5] = r[5] - 1;
if( r[5] != 0 ) if( r[5] != 0 )
goto loc_813322F0; goto loc_813322F0;
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;
if( r[29] != 0x1F ) if( r[29] != 0x1F )
goto loc_81332384; goto loc_81332384;
r[31] = r[30] >> 31; r[31] = r[30] >> 31;
r[30] = qFromBigEndian(*(quint32 *)(r[4] + r[28] + inDiff)); r[30] = qFromBigEndian(*(quint32 *)(r[4] + r[28] + inDiff));
@ -327,27 +349,27 @@ 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 )
goto loc_813323A0; goto loc_813323A0;
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;
@ -355,11 +377,11 @@ loc_813323A8:
r[31] = r[12] >> 3; r[31] = r[12] >> 3;
if( r[31] == 0 ) if( r[31] == 0 )
goto loc_81332414; goto loc_81332414;
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];
@ -389,17 +411,17 @@ loc_813323C0:
r[3] = r[3] + 8; r[3] = r[3] + 8;
if( --count ) if( --count )
goto loc_813323C0; goto loc_813323C0;
r[12] = r[12] & 7; r[12] = r[12] & 7;
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;
@ -407,14 +429,14 @@ loc_81332418:
r[3] = r[3] + 1; r[3] = r[3] + 1;
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];

File diff suppressed because it is too large Load Diff

View File

@ -39,10 +39,10 @@ int GetColor()
{ {
WORD wColor = 0; WORD wColor = 0;
HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE ); HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
CONSOLE_SCREEN_BUFFER_INFO csbi; CONSOLE_SCREEN_BUFFER_INFO csbi;
//We use csbi for the wAttributes word. //We use csbi for the wAttributes word.
if( GetConsoleScreenBufferInfo( hStdOut, &csbi ) ) if( GetConsoleScreenBufferInfo( hStdOut, &csbi ) )
{ {
wColor = csbi.wAttributes; wColor = csbi.wAttributes;
} }
@ -69,19 +69,19 @@ struct bin_str
static struct bin_str color_indicator[] = static struct bin_str color_indicator[] =
{ {
{ LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */
{ LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */
{ 0, NULL }, /* ec: End color (replaces lc+no+rc) */ { 0, NULL }, /* ec: End color (replaces lc+no+rc) */
{ LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */
{ 0, NULL }, /* no: Normal */ { 0, NULL }, /* no: Normal */
{ 0, NULL }, /* fi: File: default */ { 0, NULL }, /* fi: File: default */
{ LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */ { LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */
{ LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */ { LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */
{ LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */ { LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */
{ LEN_STR_PAIR ("01;35") }, /* so: Socket: bright magenta */ { LEN_STR_PAIR ("01;35") }, /* so: Socket: bright magenta */
{ LEN_STR_PAIR ("01;33") }, /* bd: Block device: bright yellow */ { LEN_STR_PAIR ("01;33") }, /* bd: Block device: bright yellow */
{ LEN_STR_PAIR ("01;33") }, /* cd: Char device: bright yellow */ { LEN_STR_PAIR ("01;33") }, /* cd: Char device: bright yellow */
{ 0, NULL }, /* mi: Missing file: undefined */ { 0, NULL }, /* mi: Missing file: undefined */
{ 0, NULL }, /* or: Orphaned symlink: undefined */ { 0, NULL }, /* or: Orphaned symlink: undefined */
{ LEN_STR_PAIR ("01;32") }, /* ex: Executable: bright green */ { LEN_STR_PAIR ("01;32") }, /* ex: Executable: bright green */
{ LEN_STR_PAIR ("01;35") }, /* do: Door: bright magenta */ { LEN_STR_PAIR ("01;35") }, /* do: Door: bright magenta */
{ LEN_STR_PAIR ("37;41") }, /* su: setuid: white on red */ { LEN_STR_PAIR ("37;41") }, /* su: setuid: white on red */
@ -90,7 +90,7 @@ static struct bin_str color_indicator[] =
{ LEN_STR_PAIR ("34;42") }, /* ow: other-writable: blue on green */ { LEN_STR_PAIR ("34;42") }, /* ow: other-writable: blue on green */
{ LEN_STR_PAIR ("30;42") }, /* tw: ow w/ sticky: black on green */ { LEN_STR_PAIR ("30;42") }, /* tw: ow w/ sticky: black on green */
{ LEN_STR_PAIR ("30;41") }, /* ca: black on red */ { LEN_STR_PAIR ("30;41") }, /* ca: black on red */
{ 0, NULL }, /* mh: disabled by default */ { 0, NULL }, /* mh: disabled by default */
{ LEN_STR_PAIR ("\033[K") }, /* cl: clear to end of line */ { LEN_STR_PAIR ("\033[K") }, /* cl: clear to end of line */
}; };
@ -107,31 +107,31 @@ void PrintColoredString( const char *msg, int highlite )
} }
else else
{ {
QString str( msg ); QString str( msg );
QStringList list = str.split( "\n", QString::SkipEmptyParts ); QStringList list = str.split( "\n", QString::SkipEmptyParts );
foreach( QString s, list ) foreach( QString s, list )
{ {
QString m = s; QString m = s;
QString m2 = s.trimmed(); QString m2 = s.trimmed();
m.resize( m.indexOf( m2 ) ); m.resize( m.indexOf( m2 ) );
printf( "%s", m.toLatin1().data() ); //print all leading whitespace printf( "%s", m.toLatin1().data() ); //print all leading whitespace
#ifdef Q_WS_WIN #ifdef Q_WS_WIN
SetConsoleTextAttribute( hConsole, highlite ); SetConsoleTextAttribute( hConsole, highlite );
#else #else
put_indicator( &color_indicator[ C_LEFT ] ); put_indicator( &color_indicator[ C_LEFT ] );
put_indicator( &color_indicator[ highlite ] ); //change color put_indicator( &color_indicator[ highlite ] ); //change color
put_indicator( &color_indicator[ C_RIGHT ] ); put_indicator( &color_indicator[ C_RIGHT ] );
#endif #endif
printf( "%s", m2.toLatin1().data() ); //print text printf( "%s", m2.toLatin1().data() ); //print text
#ifdef Q_WS_WIN #ifdef Q_WS_WIN
SetConsoleTextAttribute( hConsole, origColor ); SetConsoleTextAttribute( hConsole, origColor );
#else #else
put_indicator( &color_indicator[ C_LEFT ] ); put_indicator( &color_indicator[ C_LEFT ] );
put_indicator( &color_indicator[ C_NORM ] ); //reset color put_indicator( &color_indicator[ C_NORM ] ); //reset color
put_indicator( &color_indicator[ C_RIGHT ] ); put_indicator( &color_indicator[ C_RIGHT ] );
#endif #endif
printf( "\n" ); printf( "\n" );
} }
} }
fflush( stdout ); fflush( stdout );
} }
@ -144,14 +144,14 @@ void DebugHandler( QtMsgType type, const char *msg )
case QtDebugMsg: case QtDebugMsg:
printf( "%s\n", msg ); printf( "%s\n", msg );
break; break;
case QtWarningMsg: case QtWarningMsg:
PrintColoredString( msg, C_STICKY ); PrintColoredString( msg, C_STICKY );
break; break;
case QtCriticalMsg: case QtCriticalMsg:
PrintColoredString( msg, C_CAP ); PrintColoredString( msg, C_CAP );
break; break;
case QtFatalMsg: case QtFatalMsg:
fprintf( stderr, "Fatal Error: %s\n", msg ); fprintf( stderr, "Fatal Error: %s\n", msg );
abort(); abort();
break; break;
} }
@ -165,14 +165,14 @@ void Usage()
qDebug() << ""; qDebug() << "";
qDebug() << " -fs verify the filesystem is in tact"; qDebug() << " -fs verify the filesystem is in tact";
qDebug() << " verifies presence of uid & content.map & checks the hashes in the content.map"; qDebug() << " verifies presence of uid & content.map & checks the hashes in the content.map";
qDebug() << " check sha1 hashes for title private contents"; qDebug() << " check sha1 hashes for title private contents";
qDebug() << " check all titles with a ticket titles for required IOS, proper uid & gid"; qDebug() << " check all titles with a ticket titles for required IOS, proper uid & gid";
qDebug() << ""; qDebug() << "";
qDebug() << " -settingtxt check setting.txt itself and against system menu resources. this must be combined with \"-fs\""; qDebug() << " -settingtxt check setting.txt itself and against system menu resources. this must be combined with \"-fs\"";
qDebug() << ""; qDebug() << "";
qDebug() << " -uid Look any titles in the uid.sys, check signatures and whatnot. this must be combined with \"-fs\""; qDebug() << " -uid Look any titles in the uid.sys, check signatures and whatnot. this must be combined with \"-fs\"";
qDebug() << ""; qDebug() << "";
qDebug() << " -rsa Calculate and compare RSA signatures. this must be combined with \"-fs\""; qDebug() << " -rsa Calculate and compare RSA signatures. this must be combined with \"-fs\"";
qDebug() << ""; qDebug() << "";
qDebug() << " -clInfo shows free, used, and lost ( marked used, but dont belong to any file ) clusters"; qDebug() << " -clInfo shows free, used, and lost ( marked used, but dont belong to any file ) clusters";
qDebug() << ""; qDebug() << "";
@ -183,24 +183,24 @@ void Usage()
qDebug() << ""; qDebug() << "";
qDebug() << " -v increase verbosity"; qDebug() << " -v increase verbosity";
qDebug() << ""; qDebug() << "";
qDebug() << " -continue try to keep going as fas as possible on errors that should be fatal"; qDebug() << " -continue try to keep going as fas as possible on errors that should be fatal";
qDebug() << ""; qDebug() << "";
qDebug() << " -nocolor don\'t use terminal color trickery"; qDebug() << " -nocolor don\'t use terminal color trickery";
qDebug() << ""; qDebug() << "";
qDebug() << " -about info about this program"; qDebug() << " -about info about this program";
exit( 1 ); exit( 1 );
} }
void About() void About()
{ {
qCritical() << " (c) giantpune 2010, 2011"; qCritical() << " (c) giantpune 2010, 2011";
qCritical() << " http://code.google.com/p/wiiqt/"; qCritical() << " http://code.google.com/p/wiiqt/";
qCritical() << " built:" << __DATE__ << __TIME__; qCritical() << " built:" << __DATE__ << __TIME__;
qWarning() << "This software is licensed under GPLv2. It comes with no guarentee that it will work,"; qWarning() << "This software is licensed under GPLv2. It comes with no guarentee that it will work,";
qWarning() << "or that it will work well."; qWarning() << "or that it will work well.";
qDebug() << ""; qDebug() << "";
qDebug() << "This program is designed to gather information about a nand dump for a Nintendo Wii"; qDebug() << "This program is designed to gather information about a nand dump for a Nintendo Wii";
exit( 1 ); exit( 1 );
} }
void Fail( const QString& str ) void Fail( const QString& str )
@ -241,7 +241,7 @@ void ShowBootInfo( quint8 boot1, QList<Boot2Info> boot2stuff )
qDebug() << "Boot1 D (fixed)"; qDebug() << "Boot1 D (fixed)";
break; break;
default: default:
qWarning() << "unrecognized boot1 version"; qWarning() << "unrecognized boot1 version";
break; break;
} }
quint16 cnt = boot2stuff.size(); quint16 cnt = boot2stuff.size();
@ -345,8 +345,8 @@ QTreeWidgetItem *ItemFromPath( const QString &path )
item = FindItem( lookingFor, item ); item = FindItem( lookingFor, item );
if( !item ) if( !item )
{ {
//if( verbose ) //if( verbose )
// qWarning() << "ItemFromPath ->item not found" << path; // qWarning() << "ItemFromPath ->item not found" << path;
return NULL; return NULL;
} }
slash = nextSlash + 1; slash = nextSlash + 1;
@ -390,27 +390,27 @@ QList< quint64 > InstalledTitles()
for( quint16 j = 0; j < subfc2; j++ ) for( quint16 j = 0; j < subfc2; j++ )
{ {
QTreeWidgetItem *tikI = subF->child( j ); QTreeWidgetItem *tikI = subF->child( j );
QString name = tikI->text( 0 ); QString name = tikI->text( 0 );
if( !name.endsWith( ".tik" ) ) if( !name.endsWith( ".tik" ) )
{ {
continue; continue;
} }
name.resize( 8 ); name.resize( 8 );
quint32 lower = name.toUInt( &ok, 16 ); quint32 lower = name.toUInt( &ok, 16 );
if( !ok ) if( !ok )
{ {
continue; continue;
} }
//now see if there is a tmd //now see if there is a tmd
QTreeWidgetItem *tmdI = ItemFromPath( "/title/" + subF->text( 0 ) + "/" + name + "/content/title.tmd" ); QTreeWidgetItem *tmdI = ItemFromPath( "/title/" + subF->text( 0 ) + "/" + name + "/content/title.tmd" );
if( !tmdI ) if( !tmdI )
{ {
continue; continue;
} }
quint64 tid = ( ( (quint64)upper << 32) | lower ); quint64 tid = ( ( (quint64)upper << 32) | lower );
ret << tid; ret << tid;
} }
} }
@ -461,9 +461,9 @@ void BuildGoodIosList()
if( ba.isEmpty() ) if( ba.isEmpty() )
continue; continue;
Tmd t( ba ); //skip stubbzzzzz Tmd t( ba ); //skip stubbzzzzz
if( !( t.Version() % 0x100 ) && //version is a nice pretty round number if( !( t.Version() % 0x100 ) && //version is a nice pretty round number
t.Count() == 3 && //3 contents, 1 private and 2 shared t.Count() == 3 && //3 contents, 1 private and 2 shared
t.Type( 0 ) == 1 && t.Type( 0 ) == 1 &&
t.Type( 1 ) == 0x8001 && t.Type( 1 ) == 0x8001 &&
t.Type( 2 ) == 0x8001 ) t.Type( 2 ) == 0x8001 )
@ -473,7 +473,7 @@ void BuildGoodIosList()
if( !CheckTitleIntegrity( tid ) ) if( !CheckTitleIntegrity( tid ) )
continue; continue;
validIoses << tid; //seems good enough. add it to the list validIoses << tid; //seems good enough. add it to the list
} }
} }
@ -530,110 +530,110 @@ void PrintName( const QByteArray &app )
bool CheckArm003( const QByteArray &stuff ) bool CheckArm003( const QByteArray &stuff )
{ {
qint32 esTag = MAX( stuff.indexOf( "$IOSVersion: ES" ), stuff.indexOf( "$IOSVersion: ES" ) ); qint32 esTag = MAX( stuff.indexOf( "$IOSVersion: ES" ), stuff.indexOf( "$IOSVersion: ES" ) );
if( esTag < 0 ) if( esTag < 0 )
{ {
qWarning() << "\tFailed to find the ES module in the kernel"; qWarning() << "\tFailed to find the ES module in the kernel";
return false; return false;
} }
if( stuff.contains( QByteArray::fromHex( "e2511cb1d7fbbef8d7f97db5a1d81694" ) ) //1337 buffer #1 if( stuff.contains( QByteArray::fromHex( "e2511cb1d7fbbef8d7f97db5a1d81694" ) ) //1337 buffer #1
|| stuff.contains( QByteArray::fromHex( "3f5b8cc9ea855a0afa7347d23e8d664e" ) ) //1337 buffer #2 || stuff.contains( QByteArray::fromHex( "3f5b8cc9ea855a0afa7347d23e8d664e" ) ) //1337 buffer #2
|| stuff.contains( QByteArray::fromHex( "b570b08868851c01310c22c0005218ab681b2b00d10248bff001f852680b2b45" ) ) )//blablabla, CMP R3, #0x45 || stuff.contains( QByteArray::fromHex( "b570b08868851c01310c22c0005218ab681b2b00d10248bff001f852680b2b45" ) ) )//blablabla, CMP R3, #0x45
{ {
if( verbose > 1 ) if( verbose > 1 )
qWarning() << "\tSystem menu IOS supports the Korean-key check"; qWarning() << "\tSystem menu IOS supports the Korean-key check";
return true; return true;
} }
if( verbose > 1 ) if( verbose > 1 )
qDebug() << "\tSystem menu IOS does not appear to support the Korean-key check"; qDebug() << "\tSystem menu IOS does not appear to support the Korean-key check";
return false; return false;
} }
void Check003() void Check003()
{ {
qDebug() << "Checking for 003 error ..."; qDebug() << "Checking for 003 error ...";
if( sysMenuExe.isEmpty() ) if( sysMenuExe.isEmpty() )
{ {
qWarning() << "can\'t check 003 error for empty data"; qWarning() << "can\'t check 003 error for empty data";
return; return;
} }
bool brick = true; bool brick = true;
//check the PPC half //check the PPC half
if( !sysMenuExe.contains( QByteArray::fromHex( "3880004538A0000038C00000" ) ) ) //li %r4, 0x45 if( !sysMenuExe.contains( QByteArray::fromHex( "3880004538A0000038C00000" ) ) ) //li %r4, 0x45
{ //li %r5, 0 { //li %r5, 0
brick = false; //li %r6, 0 brick = false; //li %r6, 0
if( verbose > 1 ) if( verbose > 1 )
qDebug() << "\tThe system menu doesn\'t appear to perform the Korean-key check"; qDebug() << "\tThe system menu doesn\'t appear to perform the Korean-key check";
} }
else if( verbose > 1 ) else if( verbose > 1 )
qWarning() << "\tThe system menu performs the Korean-key check"; qWarning() << "\tThe system menu performs the Korean-key check";
//check the ARM half //check the ARM half
QString iosStr = TidTxt( sysMenuIos ); QString iosStr = TidTxt( sysMenuIos );
iosStr.insert( 8, "/" ); iosStr.insert( 8, "/" );
iosStr.prepend( "/title/" ); iosStr.prepend( "/title/" );
iosStr += "/content/"; iosStr += "/content/";
QByteArray tmdD = nand.GetData( iosStr + "title.tmd" ); QByteArray tmdD = nand.GetData( iosStr + "title.tmd" );
if( tmdD.isEmpty() ) if( tmdD.isEmpty() )
{ {
qWarning() << "\tcan\'t read systemmenu-ios's TMD"; qWarning() << "\tcan\'t read systemmenu-ios's TMD";
return; return;
} }
Tmd t( tmdD ); Tmd t( tmdD );
QByteArray iosKernel; QByteArray iosKernel;
QString kernelPath; QString kernelPath;
quint16 cnt = t.Count(); quint16 cnt = t.Count();
if( t.BootIndex() >= cnt ) //in case there is some really fucked up TMD if( t.BootIndex() >= cnt ) //in case there is some really fucked up TMD
{ {
Fail( "\tThe system menu ios bootindex is fucked up pretty bad" ); Fail( "\tThe system menu ios bootindex is fucked up pretty bad" );
return; return;
} }
if( t.Type( t.BootIndex() ) == 0x8001 ) if( t.Type( t.BootIndex() ) == 0x8001 )
{ {
QString appname = sharedM.GetAppFromHash( t.Hash( t.BootIndex() ) ); QString appname = sharedM.GetAppFromHash( t.Hash( t.BootIndex() ) );
if( appname.isEmpty() ) if( appname.isEmpty() )
{ {
Fail( "\tError reading the system menu ios" ); Fail( "\tError reading the system menu ios" );
return; return;
} }
kernelPath = "/shared1/" + appname + ".app"; kernelPath = "/shared1/" + appname + ".app";
} }
else else
{ {
kernelPath = iosStr + t.Cid( t.BootIndex() ) + ".app"; kernelPath = iosStr + t.Cid( t.BootIndex() ) + ".app";
} }
iosKernel = nand.GetData( kernelPath ); iosKernel = nand.GetData( kernelPath );
if( iosKernel.isEmpty() ) if( iosKernel.isEmpty() )
{ {
Fail( "\tError reading the system menu ios data" ); Fail( "\tError reading the system menu ios data" );
return; return;
} }
if( !CheckArm003( iosKernel ) ) if( !CheckArm003( iosKernel ) )
brick = false; brick = false;
//look for korean keys in keys.bin //look for korean keys in keys.bin
QByteArray keys = nand.Keys(); QByteArray keys = nand.Keys();
if( keys.size() != 0x400 ) if( keys.size() != 0x400 )
{ {
Fail( "\tError getting nand keys" ); Fail( "\tError getting nand keys" );
return; return;
} }
quint8 k_key[ 16 ] = KOREAN_KEY; quint8 k_key[ 16 ] = KOREAN_KEY;
if( !keys.contains( QByteArray( (const char*)&k_key, 16 ) ) ) if( !keys.contains( QByteArray( (const char*)&k_key, 16 ) ) )
{ {
brick = false; brick = false;
if( verbose > 1 ) if( verbose > 1 )
qDebug() << "\tThe korean key is not present in this wii"; qDebug() << "\tThe korean key is not present in this wii";
} }
else if( verbose > 1 ) else if( verbose > 1 )
qWarning() << "\tThis wii contains the korean key"; qWarning() << "\tThis wii contains the korean key";
if( brick ) if( brick )
Fail( "\tThis wii will likely show the 003 error" ); Fail( "\tThis wii will likely show the 003 error" );
} }
bool CheckTitleIntegrity( quint64 tid ) bool CheckTitleIntegrity( quint64 tid )
@ -668,27 +668,27 @@ bool CheckTitleIntegrity( quint64 tid )
qDebug() << "error getting" << it << "data"; qDebug() << "error getting" << it << "data";
return false; return false;
} }
if( calcRsa ) if( calcRsa )
{ {
qint32 ch = check_cert_chain( ba ); qint32 ch = check_cert_chain( ba );
switch( ch ) switch( ch )
{ {
case ERROR_SIG_TYPE: case ERROR_SIG_TYPE:
case ERROR_SUB_TYPE: case ERROR_SUB_TYPE:
case ERROR_RSA_HASH: case ERROR_RSA_HASH:
case ERROR_RSA_TYPE_UNKNOWN: case ERROR_RSA_TYPE_UNKNOWN:
case ERROR_RSA_TYPE_MISMATCH: case ERROR_RSA_TYPE_MISMATCH:
case ERROR_CERT_NOT_FOUND: case ERROR_CERT_NOT_FOUND:
qWarning().nospace() << "\t" << qPrintable( it ) << " RSA signature isn't even close ( " << ch << " )"; qWarning().nospace() << "\t" << qPrintable( it ) << " RSA signature isn't even close ( " << ch << " )";
//return false; //maye in the future this will be true, but for now, this doesnt mean it wont boot //return false; //maye in the future this will be true, but for now, this doesnt mean it wont boot
break; break;
case ERROR_RSA_FAKESIGNED: case ERROR_RSA_FAKESIGNED:
qWarning().nospace() << "\t" << qPrintable( it ) << " fakesigned"; qWarning().nospace() << "\t" << qPrintable( it ) << " fakesigned";
break; break;
default: default:
break; break;
} }
} }
if( i ) if( i )
{ {
t = Tmd( ba ); t = Tmd( ba );
@ -721,7 +721,7 @@ bool CheckTitleIntegrity( quint64 tid )
{ {
qWarning() << "\tone of the shared contents is missing"; qWarning() << "\tone of the shared contents is missing";
return false; return false;
} }
} }
else//private else//private
{ {
@ -746,22 +746,22 @@ bool CheckTitleIntegrity( quint64 tid )
//if we are going to check the setting.txt stuff, we need to get the system menu resource file to compare ( check for opera bricks ) //if we are going to check the setting.txt stuff, we need to get the system menu resource file to compare ( check for opera bricks )
//so far, i think this file is always boot index 1, type 1 //so far, i think this file is always boot index 1, type 1
if( tid == 0x100000002ull ) if( tid == 0x100000002ull )
{ {
if( t.Index( i ) == 1 && if( t.Index( i ) == 1 &&
( args.contains( "-settingtxt", Qt::CaseInsensitive ) || args.contains( "-all", Qt::CaseInsensitive ) ) ) ( args.contains( "-settingtxt", Qt::CaseInsensitive ) || args.contains( "-all", Qt::CaseInsensitive ) ) )
{ {
sysMenuResource = ba; sysMenuResource = ba;
} }
else if( t.Index( i ) == t.BootIndex() ) else if( t.Index( i ) == t.BootIndex() )
sysMenuExe = ba; sysMenuExe = ba;
} }
//print a description of this title //print a description of this title
if( verbose > 1 && t.Index( i ) == 0 ) if( verbose > 1 && t.Index( i ) == 0 )
{ {
PrintName( ba ); PrintName( ba );
} }
} }
} }
@ -782,11 +782,11 @@ bool CheckTitleIntegrity( quint64 tid )
qWarning() << "\tthe IOS for this title is not bootable\n\t" << TidTxt( ios ).insert( 8, "-" ); qWarning() << "\tthe IOS for this title is not bootable\n\t" << TidTxt( ios ).insert( 8, "-" );
return false; return false;
} }
if( tid == 0x100000002ull ) if( tid == 0x100000002ull )
sysMenuIos = ios; sysMenuIos = ios;
if( verbose > 1 && ( upper != 1 || tid == 0x100000002ull ) ) if( verbose > 1 && ( upper != 1 || tid == 0x100000002ull ) )
qDebug() << "\trequires IOS" << ((quint32)( ios & 0xffffffff )); qDebug() << "\trequires IOS" << ((quint32)( ios & 0xffffffff ));
quint32 uid = uidM.GetUid( tid, false ); quint32 uid = uidM.GetUid( tid, false );
if( !uid ) if( !uid )
{ {
@ -808,7 +808,7 @@ bool CheckTitleIntegrity( quint64 tid )
if( dataI->text( 3 ) != uidS || !dataI->text( 4 ).startsWith( gidS ) )//dont necessarily fail for this. the title will still be bootable without its data if( dataI->text( 3 ) != uidS || !dataI->text( 4 ).startsWith( gidS ) )//dont necessarily fail for this. the title will still be bootable without its data
qWarning() << "\tincorrect uid/gid for data folder"; qWarning() << "\tincorrect uid/gid for data folder";
RecurseCheckGidUid( dataI, uidS, gidS, "data/" ); RecurseCheckGidUid( dataI, uidS, gidS, "data/" );
} }
dataP.resize( 25 ); dataP.resize( 25 );
dataP += "content"; dataP += "content";
@ -835,7 +835,7 @@ void ListDeletedTitles()
return; return;
} }
qDebug() << "Comparing uid.sys against the filesystem..."; qDebug() << "Comparing uid.sys against the filesystem...";
//hexdump12( uidSys ); //hexdump12( uidSys );
QBuffer buf( &uidSys ); QBuffer buf( &uidSys );
buf.open( QIODevice::ReadWrite ); buf.open( QIODevice::ReadWrite );
@ -851,9 +851,9 @@ void ListDeletedTitles()
tid = qFromBigEndian( tid ); tid = qFromBigEndian( tid );
quint32 upper = ( ( tid >> 32 ) & 0xffffffff ); quint32 upper = ( ( tid >> 32 ) & 0xffffffff );
quint32 lower = ( tid & 0xffffffff ); quint32 lower = ( tid & 0xffffffff );
if( ( upper == 0x10001 && ( ( lower >> 24 ) & 0xff ) != 0x48 ) || //a channel, not starting with 'H' if( ( upper == 0x10001 && ( ( lower >> 24 ) & 0xff ) != 0x48 ) || //a channel, not starting with 'H'
lower == 0x48415858 || //original HBC lower == 0x48415858 || //original HBC
tid == 0x100000000ull || //bannerbomb -> ATD ( or any other program that uses the SU tid ) tid == 0x100000000ull || //bannerbomb -> ATD ( or any other program that uses the SU tid )
( upper == 0x10000 && ( ( lower & 0xffffff00 ) == 0x555000 ) ) ) //a disc update partition ( upper == 0x10000 && ( ( lower & 0xffffff00 ) == 0x555000 ) ) ) //a disc update partition
break; break;
if( ( verbose || upper != 0x10000 ) && !tids.contains( tid ) ) if( ( verbose || upper != 0x10000 ) && !tids.contains( tid ) )
@ -892,7 +892,7 @@ void ListDeletedTitles()
qWarning() << "\tError reading TMD for" << qPrintable( TidTxt( tid ).insert( 8, "-" ) + ( upper != 1 ? " (" + AsciiTxt( lower ) + ")" : "" ) ); qWarning() << "\tError reading TMD for" << qPrintable( TidTxt( tid ).insert( 8, "-" ) + ( upper != 1 ? " (" + AsciiTxt( lower ) + ")" : "" ) );
deleted = true; deleted = true;
} }
else if( calcRsa ) else if( calcRsa )
{ {
qint32 ch = check_cert_chain( ba ); qint32 ch = check_cert_chain( ba );
switch( ch ) switch( ch )
@ -933,7 +933,7 @@ void ListDeletedTitles()
qWarning() << "\tError reading ticket for" << qPrintable( TidTxt( tid ).insert( 8, "-" ) + ( upper != 1 ? " (" + AsciiTxt( lower ) + ")" : "" ) ); qWarning() << "\tError reading ticket for" << qPrintable( TidTxt( tid ).insert( 8, "-" ) + ( upper != 1 ? " (" + AsciiTxt( lower ) + ")" : "" ) );
deleted = true; deleted = true;
} }
else if( calcRsa ) else if( calcRsa )
{ {
qint32 ch = check_cert_chain( ba ); qint32 ch = check_cert_chain( ba );
switch( ch ) switch( ch )
@ -964,8 +964,8 @@ void ListDeletedTitles()
void CheckLostClusters() void CheckLostClusters()
{ {
QList<quint16> u = nand.GetFatsForEntry( 0 );//all clusters actually used for a file QList<quint16> u = nand.GetFatsForEntry( 0 );//all clusters actually used for a file
if( verbose ) if( verbose )
qDebug() << "total used clusters" << hex << u.size() << "of 0x8000"; qDebug() << "total used clusters" << hex << u.size() << "of 0x8000";
quint16 lost = 0; quint16 lost = 0;
QList<quint16> ffs; QList<quint16> ffs;
QList<quint16> frs; QList<quint16> frs;
@ -1006,7 +1006,7 @@ void CheckEcc()
for( quint16 i = 0; i < 0x8000; i++ ) for( quint16 i = 0; i < 0x8000; i++ )
{ {
if( fats.at( i ) == 0xfffd || fats.at( i ) == 0xfffe ) if( fats.at( i ) == 0xfffd || fats.at( i ) == 0xfffe )
continue; continue;
for( quint8 j = 0; j < 8; j++, checked += 8 ) for( quint8 j = 0; j < 8; j++, checked += 8 )
{ {
@ -1026,16 +1026,16 @@ void CheckEcc()
{ {
quint16 p = clustersCpy.takeFirst(); quint16 p = clustersCpy.takeFirst();
if( fats.at( p ) < 0xfff0 ) if( fats.at( p ) < 0xfff0 )
badClustersNotSpecial++; badClustersNotSpecial++;
quint16 block = p/8; quint16 block = p/8;
if( !blocks.contains( block ) ) if( !blocks.contains( block ) )
blocks << block; blocks << block;
} }
qDebug() << bad.size() << "out of" << checked << "pages had incorrect ecc.\nthey were spread through" qDebug() << bad.size() << "out of" << checked << "pages had incorrect ecc.\nthey were spread through"
<< clusters.size() << "clusters in" << blocks.size() << "blocks:\n" << blocks; << clusters.size() << "clusters in" << blocks.size() << "blocks:\n" << blocks;
qDebug() << badClustersNotSpecial << "of those clusters are non-special (they belong to the fs)"; qDebug() << badClustersNotSpecial << "of those clusters are non-special (they belong to the fs)";
} }
@ -1258,17 +1258,17 @@ int main( int argc, char *argv[] )
origColor = GetColor(); origColor = GetColor();
hConsole = GetStdHandle( STD_OUTPUT_HANDLE ); hConsole = GetStdHandle( STD_OUTPUT_HANDLE );
#endif #endif
qInstallMsgHandler( DebugHandler ); qInstallMsgHandler( DebugHandler );
qCritical() << "** nandBinCheck : Wii nand info tool **"; qCritical() << "** nandBinCheck : Wii nand info tool **";
qCritical() << " from giantpune"; qCritical() << " from giantpune";
qCritical() << " built:" << __DATE__ << __TIME__; qCritical() << " built:" << __DATE__ << __TIME__;
args = QCoreApplication::arguments(); args = QCoreApplication::arguments();
if( args.contains( "-nocolor", Qt::CaseInsensitive ) ) if( args.contains( "-nocolor", Qt::CaseInsensitive ) )
color = false; color = false;
if( args.contains( "-about", Qt::CaseInsensitive ) ) if( args.contains( "-about", Qt::CaseInsensitive ) )
About(); About();
if( args.size() < 3 ) if( args.size() < 3 )
Usage(); Usage();
@ -1281,13 +1281,13 @@ int main( int argc, char *argv[] )
root = NULL; root = NULL;
verbose = args.count( "-v" ); verbose = args.count( "-v" );
if( args.contains( "-continue", Qt::CaseInsensitive ) ) if( args.contains( "-continue", Qt::CaseInsensitive ) )
tryToKeepGoing = true; tryToKeepGoing = true;
if( args.contains( "-rsa", Qt::CaseInsensitive ) || args.contains( "-all", Qt::CaseInsensitive ) ) if( args.contains( "-rsa", Qt::CaseInsensitive ) || args.contains( "-all", Qt::CaseInsensitive ) )
calcRsa = true; calcRsa = true;
//these only serve to show info. no action is taken //these only serve to show info. no action is taken
if( args.contains( "-boot", Qt::CaseInsensitive ) || args.contains( "-all", Qt::CaseInsensitive ) ) if( args.contains( "-boot", Qt::CaseInsensitive ) || args.contains( "-all", Qt::CaseInsensitive ) )
@ -1321,7 +1321,7 @@ int main( int argc, char *argv[] )
//if( !CheckTitleIntegrity( tid ) && tid == 0x100000002ull ) //well, this SHOULD be the case. but nintendo doesnt care so much about //if( !CheckTitleIntegrity( tid ) && tid == 0x100000002ull ) //well, this SHOULD be the case. but nintendo doesnt care so much about
//Fail( "The System menu isnt valid" ); //checking signatures & hashes as the rest of us. //Fail( "The System menu isnt valid" ); //checking signatures & hashes as the rest of us.
} }
Check003(); Check003();
if( args.contains( "-settingtxt", Qt::CaseInsensitive ) || args.contains( "-all", Qt::CaseInsensitive ) ) if( args.contains( "-settingtxt", Qt::CaseInsensitive ) || args.contains( "-all", Qt::CaseInsensitive ) )
{ {
CheckSettingTxt(); CheckSettingTxt();