* use const reference in foreach() also

This commit is contained in:
giantpune 2011-05-17 21:18:45 +00:00
parent 3ee828284a
commit d0ca7c0f15
6 changed files with 353 additions and 358 deletions

View File

@ -13,7 +13,7 @@ SettingTxtDialog::SettingTxtDialog( QWidget *parent, const QByteArray &old, qint
QString str( copy ); QString str( copy );
str.replace( "\r\n", "\n" );//maybe not needed to do this in 2 steps, but there may be some reason the file only uses "\n", so do it this way to be safe str.replace( "\r\n", "\n" );//maybe not needed to do this in 2 steps, but there may be some reason the file only uses "\n", so do it this way to be safe
QStringList parts = str.split( "\n", QString::SkipEmptyParts ); QStringList parts = str.split( "\n", QString::SkipEmptyParts );
foreach( QString part, parts ) foreach( const QString &part, parts )
{ {
QString p = part; QString p = part;
if( part.startsWith( "AREA=" ) ) if( part.startsWith( "AREA=" ) )

View File

@ -35,7 +35,7 @@ void hexdump( const void *d, int len ) {
fprintf( stderr, " " ); fprintf( stderr, " " );
for ( i = 0; i < 16; i++ ) for ( i = 0; i < 16; i++ )
if ( ( i + off) >= len ) fprintf( stderr," "); if ( ( i + off) >= len ) fprintf( stderr," ");
else fprintf( stderr,"%c", ascii( data[ off + i ])); else fprintf( stderr,"%c", ascii( data[ off + i ]));
fprintf( stderr,"\n"); fprintf( stderr,"\n");
} }
fflush( stderr ); fflush( stderr );
@ -70,7 +70,7 @@ void hexdump12( const void *d, int len ) {
fprintf( stderr, " " ); fprintf( stderr, " " );
for ( i = 0; i < 12; i++ ) for ( i = 0; i < 12; i++ )
if ( ( i + off) >= len ) fprintf( stderr," "); if ( ( i + off) >= len ) fprintf( stderr," ");
else fprintf( stderr,"%c", ascii( data[ off + i ])); else fprintf( stderr,"%c", ascii( data[ off + i ]));
fprintf( stderr,"\n"); fprintf( stderr,"\n");
} }
fflush( stderr ); fflush( stderr );
@ -83,34 +83,34 @@ void hexdump12( const QByteArray &d, int from, int len )
QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo ) QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo )
{ {
//qDebug() << "need to pad from" << hex << orig.size() << "to nearest" << padTo; //qDebug() << "need to pad from" << hex << orig.size() << "to nearest" << padTo;
QByteArray padding( RU( orig.size(), padTo ) - orig.size(), '\0' ); QByteArray padding( RU( orig.size(), padTo ) - orig.size(), '\0' );
return orig + padding; return orig + padding;
} }
QByteArray AesDecrypt( quint16 index, const QByteArray &source ) QByteArray AesDecrypt( quint16 index, const QByteArray &source )
{ {
//qDebug() << "AesDecrypt" << hex << index << source.size(); //qDebug() << "AesDecrypt" << hex << index << source.size();
quint8 iv[ 16 ]; quint8 iv[ 16 ];
quint16 beidx = qFromBigEndian( index ); quint16 beidx = qFromBigEndian( index );
memset( &iv, 0, 16 ); memset( &iv, 0, 16 );
memcpy( &iv, &beidx, 2 ); memcpy( &iv, &beidx, 2 );
QByteArray ret( source.size(), '\0' ); QByteArray ret( source.size(), '\0' );
aes_decrypt( (quint8*)&iv, (const quint8*)source.data(), (quint8*)ret.data(), source.size() ); aes_decrypt( (quint8*)&iv, (const quint8*)source.data(), (quint8*)ret.data(), source.size() );
return ret; return ret;
} }
QByteArray AesEncrypt( quint16 index, const QByteArray &source ) QByteArray AesEncrypt( quint16 index, const QByteArray &source )
{ {
static quint8 iv[ 16 ]; static quint8 iv[ 16 ];
quint16 beidx = qFromBigEndian( index ); quint16 beidx = qFromBigEndian( index );
memset( iv, 0, 16 ); memset( iv, 0, 16 );
memcpy( iv, &beidx, 2 ); memcpy( iv, &beidx, 2 );
QByteArray ret( source.size(), '\0' ); QByteArray ret( source.size(), '\0' );
aes_encrypt( iv, (const quint8*)source.data(), (quint8*)ret.data(), source.size() ); aes_encrypt( iv, (const quint8*)source.data(), (quint8*)ret.data(), source.size() );
return ret; return ret;
} }
void AesSetKey( const QByteArray &key ) void AesSetKey( const QByteArray &key )
@ -121,12 +121,12 @@ void AesSetKey( const QByteArray &key )
QByteArray GetSha1( const QByteArray &stuff ) QByteArray GetSha1( const QByteArray &stuff )
{ {
return QCryptographicHash::hash( stuff, QCryptographicHash::Sha1 ); return QCryptographicHash::hash( stuff, QCryptographicHash::Sha1 );
} }
QByteArray GetMd5( const QByteArray &stuff ) QByteArray GetMd5( const QByteArray &stuff )
{ {
return QCryptographicHash::hash( stuff, QCryptographicHash::Md5 ); return QCryptographicHash::hash( stuff, QCryptographicHash::Md5 );
} }
QByteArray ReadFile( const QString &path ) QByteArray ReadFile( const QString &path )
@ -229,10 +229,10 @@ const QByteArray DataFromSave( const SaveGame &save, const QString &name )
quint32 SaveItemSize( const SaveGame &save ) quint32 SaveItemSize( const SaveGame &save )
{ {
quint32 ret = 0; quint32 ret = 0;
foreach( QByteArray ba, save.data ) foreach( const QByteArray &ba, save.data )
ret += ba.size(); ret += ba.size();
return ret; return ret;
} }
quint8 AttrFromSave( const SaveGame &save, const QString &name ) quint8 AttrFromSave( const SaveGame &save, const QString &name )

View File

@ -896,7 +896,7 @@ void U8::CreateEntryList()
if( child.IsOK() ) if( child.IsOK() )
{ {
nestedU8s.insert( path, child ); nestedU8s.insert( path, child );
foreach( QString chPath, child.Entries() ) foreach( const QString &chPath, child.Entries() )
{ {
QString newPath = path + "/" + chPath; QString newPath = path + "/" + chPath;
paths << newPath; paths << newPath;

View File

@ -111,7 +111,7 @@ void PrintColoredString( const char *msg, int highlite )
{ {
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( const QString &s, list )
{ {
QString m = s; QString m = s;
QString m2 = s.trimmed(); QString m2 = s.trimmed();
@ -183,7 +183,7 @@ void Usage()
qDebug() << ""; qDebug() << "";
qDebug() << " -all does all of the above"; qDebug() << " -all does all of the above";
qDebug() << ""; qDebug() << "";
qDebug() << " -v increase verbosity"; qDebug() << " -v increase verbosity ( can be used more than once )";
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() << "";
@ -434,22 +434,22 @@ void CheckShared()
qDebug() << "checking" << path << "..."; qDebug() << "checking" << path << "...";
QByteArray stuff = nand.GetData( path ); QByteArray stuff = nand.GetData( path );
if( stuff.isEmpty() ) if( stuff.isEmpty() )
{ {
BadSharedItems << sharedM.Hash( i ); BadSharedItems << sharedM.Hash( i );
Fail( "One of the shared contents in this nand is missing" ); Fail( "One of the shared contents in this nand is missing" );
} }
QByteArray realHash = GetSha1( stuff ); QByteArray realHash = GetSha1( stuff );
if( realHash != sharedM.Hash( i ) ) if( realHash != sharedM.Hash( i ) )
{ {
BadSharedItems << sharedM.Hash( i ); BadSharedItems << sharedM.Hash( i );
if( verbose ) if( verbose )
{ {
qCritical() << "\texpected: " << sharedM.Hash( i ).toHex(); qCritical() << "\texpected: " << sharedM.Hash( i ).toHex();
qCritical() << "\tactual: " << realHash.toHex(); qCritical() << "\tactual: " << realHash.toHex();
} }
Fail( "The hash for at least 1 content is bad" ); Fail( "The hash for at least 1 content is bad" );
} }
} }
} }
@ -680,86 +680,81 @@ bool CheckTitleIntegrity( quint64 tid )
qDebug() << "error getting" << it << "data"; qDebug() << "error getting" << it << "data";
return false; return false;
} }
if( i )//tmd if( i )//tmd
{ {
t = Tmd( ba ); t = Tmd( ba );
if( t.Tid() != tid ) if( t.Tid() != tid )
{ {
qWarning() << "\tthe TMD contains the wrong TID"; qWarning() << "\tthe TMD contains the wrong TID";
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;
} }
} }
} }
else else
{ {
Ticket ticket( ba, false ); Ticket ticket( ba, false );
if( ticket.Tid() != tid ) if( ticket.Tid() != tid )
{ {
qWarning() << "\tthe ticket contains the wrong TID"; qWarning() << "\tthe ticket contains the wrong TID";
return false; return false;
} }
if( calcRsa ) if( calcRsa )
{ {
int tikVersions = ba.size() / 0x2a4; int tikVersions = ba.size() / 0x2a4;
qint32 ch = ERROR_RSA_TYPE_UNKNOWN; qint32 ch = ERROR_RSA_TYPE_UNKNOWN;
bool ok = false; bool ok = false;
for( int rr = 0; rr < tikVersions && !ok; rr++ ) for( int rr = 0; rr < tikVersions && !ok; rr++ )
{ {
ch = check_cert_chain( ba.mid( rr * 0x2a4, 0x2a4 ) ); ch = check_cert_chain( ba.mid( rr * 0x2a4, 0x2a4 ) );
switch( ch ) switch( ch )
{ {
default: default:
break; break;
case ERROR_RSA_FAKESIGNED: case ERROR_RSA_FAKESIGNED:
case ERROR_SUCCESS: case ERROR_SUCCESS:
ok = true; ok = true;
break; break;
} }
} }
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( upper == 0x10005 || upper == 0x10007 ) //dont try to verify all the contents of DLC, it will just find a bunch of missing contents and bitch about them if( upper == 0x10005 || upper == 0x10007 ) //dont try to verify all the contents of DLC, it will just find a bunch of missing contents and bitch about them
@ -770,11 +765,11 @@ bool CheckTitleIntegrity( quint64 tid )
{ {
if( t.Type( i ) == 0x8001 )//shared if( t.Type( i ) == 0x8001 )//shared
{ {
if( BadSharedItems.contains( t.Hash( i ) ) ) if( BadSharedItems.contains( t.Hash( i ) ) )
{ {
qWarning() << "\tthis title relies on a shared content that is borked (" << i << ")\n\t" << t.Hash( i ).toHex(); qWarning() << "\tthis title relies on a shared content that is borked (" << i << ")\n\t" << t.Hash( i ).toHex();
return false; return false;
} }
if( sharedM.GetAppFromHash( t.Hash( i ) ).isEmpty() ) if( sharedM.GetAppFromHash( t.Hash( i ) ).isEmpty() )
{ {
qWarning() << "\tone of the shared contents is missing"; qWarning() << "\tone of the shared contents is missing";
@ -864,7 +859,7 @@ bool CheckTitleIntegrity( quint64 tid )
QString uidS = QString( "%1" ).arg( uid, 8, 16, QChar( '0' ) ); QString uidS = QString( "%1" ).arg( uid, 8, 16, QChar( '0' ) );
QString gidS = QString( "%1" ).arg( gid, 4, 16, QChar( '0' ) ); QString gidS = QString( "%1" ).arg( gid, 4, 16, QChar( '0' ) );
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().nospace() << "\tincorrect uid/gid for data folder-- expected: " << uidS << "/" << gidS << " got: " << dataI->text( 3 ) << "/" << dataI->text( 4 ).left( 4 ); qWarning().nospace() << "\tincorrect uid/gid for data folder-- expected: " << uidS << "/" << gidS << " got: " << dataI->text( 3 ) << "/" << dataI->text( 4 ).left( 4 );
RecurseCheckGidUid( dataI, uidS, gidS, "data/" ); RecurseCheckGidUid( dataI, uidS, gidS, "data/" );
} }
@ -1197,7 +1192,7 @@ void CheckSettingTxt()
QString str( settingTxt ); QString str( settingTxt );
str.replace( "\r\n", "\n" );//maybe not needed to do this in 2 steps, but there may be some reason the file only uses "\n", so do it this way to be safe str.replace( "\r\n", "\n" );//maybe not needed to do this in 2 steps, but there may be some reason the file only uses "\n", so do it this way to be safe
QStringList parts = str.split( "\n", QString::SkipEmptyParts ); QStringList parts = str.split( "\n", QString::SkipEmptyParts );
foreach( QString part, parts ) foreach( const QString &part, parts )
{ {
if( part.startsWith( "AREA=" ) ) if( part.startsWith( "AREA=" ) )
{ {
@ -1320,7 +1315,7 @@ int main( int argc, char *argv[] )
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;

View File

@ -329,7 +329,7 @@ void MainWindow::on_actionImportWad_triggered()
if( fns.isEmpty() ) if( fns.isEmpty() )
return; return;
foreach( QString fn, fns ) foreach( const QString &fn, fns )
{ {
QByteArray data = ReadFile( fn ); QByteArray data = ReadFile( fn );
if( data.isEmpty() ) if( data.isEmpty() )

View File

@ -9,9 +9,9 @@ NewNandBin::NewNandBin( QWidget *parent, QList<quint16> badBlocks ) : QDialog(pa
ui->setupUi(this); ui->setupUi(this);
foreach( quint16 block, badBlocks ) foreach( quint16 block, badBlocks )
{ {
QString txt = QString( "%1" ).arg( block ); QString txt = QString( "%1" ).arg( block );
if( ui->listWidget_badBlocks->findItems( txt, Qt::MatchExactly ).isEmpty() ) if( ui->listWidget_badBlocks->findItems( txt, Qt::MatchExactly ).isEmpty() )
ui->listWidget_badBlocks->addItem( txt ); ui->listWidget_badBlocks->addItem( txt );
} }
} }
@ -24,7 +24,7 @@ void NewNandBin::on_pushButton_keys_clicked()
{ {
QString f = QFileDialog::getOpenFileName( this, tr( "Select Keys.bin" ), dir ); QString f = QFileDialog::getOpenFileName( this, tr( "Select Keys.bin" ), dir );
if( f.isEmpty() ) if( f.isEmpty() )
return; return;
ui->lineEdit_keys->setText( f ); ui->lineEdit_keys->setText( f );
dir = QFileInfo( f ).canonicalPath(); dir = QFileInfo( f ).canonicalPath();
} }
@ -33,7 +33,7 @@ void NewNandBin::on_pushButton_boot_clicked()
{ {
QString f = QFileDialog::getOpenFileName( this, tr( "Select Boot 1 & 2" ), dir ); QString f = QFileDialog::getOpenFileName( this, tr( "Select Boot 1 & 2" ), dir );
if( f.isEmpty() ) if( f.isEmpty() )
return; return;
ui->lineEdit_boot->setText( f ); ui->lineEdit_boot->setText( f );
dir = QFileInfo( f ).canonicalPath(); dir = QFileInfo( f ).canonicalPath();
} }
@ -42,7 +42,7 @@ void NewNandBin::on_pushButton_dest_clicked()
{ {
QString f = QFileDialog::getSaveFileName( this, tr( "Output file" ), dir ); QString f = QFileDialog::getSaveFileName( this, tr( "Output file" ), dir );
if( f.isEmpty() ) if( f.isEmpty() )
return; return;
ui->lineEdit_dest->setText( f ); ui->lineEdit_dest->setText( f );
dir = QFileInfo( f ).canonicalPath(); dir = QFileInfo( f ).canonicalPath();
} }
@ -53,10 +53,10 @@ QList<quint16> NewNandBin::BadBlocks()
quint16 cnt = ui->listWidget_badBlocks->count(); quint16 cnt = ui->listWidget_badBlocks->count();
for( quint16 i = 0; i < cnt; i++ ) for( quint16 i = 0; i < cnt; i++ )
{ {
bool ok = false; bool ok = false;
quint16 num = ui->listWidget_badBlocks->item( i )->text().toInt( &ok ); quint16 num = ui->listWidget_badBlocks->item( i )->text().toInt( &ok );
if( ok ) if( ok )
ret << num; ret << num;
} }
return ret; return ret;
} }
@ -66,7 +66,7 @@ void NewNandBin::on_pushButton_bb_add_clicked()
quint16 val = ui->spinBox->value(); quint16 val = ui->spinBox->value();
if( !BadBlocks().contains( val ) ) if( !BadBlocks().contains( val ) )
{ {
ui->listWidget_badBlocks->addItem( QString( "%1" ).arg( val ) ); ui->listWidget_badBlocks->addItem( QString( "%1" ).arg( val ) );
} }
} }
@ -75,96 +75,96 @@ void NewNandBin::on_pushButton_bb_rm_clicked()
QList<QListWidgetItem *> items = ui->listWidget_badBlocks->selectedItems(); QList<QListWidgetItem *> items = ui->listWidget_badBlocks->selectedItems();
foreach( QListWidgetItem *item, items ) foreach( QListWidgetItem *item, items )
{ {
ui->listWidget_badBlocks->removeItemWidget( item ); ui->listWidget_badBlocks->removeItemWidget( item );
delete item; delete item;
} }
} }
bool NewNandBin::CreateDefaultEntries() bool NewNandBin::CreateDefaultEntries()
{ {
if( !nand.CreateEntry( "/sys", 0, 0, NAND_DIR, NAND_RW, NAND_RW, 0 ) if( !nand.CreateEntry( "/sys", 0, 0, NAND_DIR, NAND_RW, NAND_RW, 0 )
|| !nand.CreateEntry( "/ticket", 0, 0, NAND_DIR, NAND_RW, NAND_RW, 0 ) || !nand.CreateEntry( "/ticket", 0, 0, NAND_DIR, NAND_RW, NAND_RW, 0 )
|| !nand.CreateEntry( "/title", 0, 0, NAND_DIR, NAND_RW, NAND_RW, NAND_READ ) || !nand.CreateEntry( "/title", 0, 0, NAND_DIR, NAND_RW, NAND_RW, NAND_READ )
|| !nand.CreateEntry( "/shared1", 0, 0, NAND_DIR, NAND_RW, NAND_RW, 0 ) || !nand.CreateEntry( "/shared1", 0, 0, NAND_DIR, NAND_RW, NAND_RW, 0 )
|| !nand.CreateEntry( "/shared2", 0, 0, NAND_DIR, NAND_RW, NAND_RW, NAND_RW ) || !nand.CreateEntry( "/shared2", 0, 0, NAND_DIR, NAND_RW, NAND_RW, NAND_RW )
|| !nand.CreateEntry( "/import", 0, 0, NAND_DIR, NAND_RW, NAND_RW, 0 ) || !nand.CreateEntry( "/import", 0, 0, NAND_DIR, NAND_RW, NAND_RW, 0 )
|| !nand.CreateEntry( "/meta", 0x1000, 1, NAND_DIR, NAND_RW, NAND_RW, NAND_RW ) || !nand.CreateEntry( "/meta", 0x1000, 1, NAND_DIR, NAND_RW, NAND_RW, NAND_RW )
|| !nand.CreateEntry( "/tmp", 0, 0, NAND_DIR, NAND_RW, NAND_RW, NAND_RW ) || !nand.CreateEntry( "/tmp", 0, 0, NAND_DIR, NAND_RW, NAND_RW, NAND_RW )
|| !nand.WriteMetaData() ) || !nand.WriteMetaData() )
{ {
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating directories in the new nand"; qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating directories in the new nand";
QMessageBox::warning( this, tr( "Error" ), \ QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create base folders in the new nand." ) ); tr( "Can't create base folders in the new nand." ) );
return false; return false;
} }
//add cert.sys //add cert.sys
quint16 handle = nand.CreateEntry( "/sys/cert.sys", 0, 0, NAND_FILE, NAND_RW, NAND_RW, NAND_READ ); quint16 handle = nand.CreateEntry( "/sys/cert.sys", 0, 0, NAND_FILE, NAND_RW, NAND_RW, NAND_READ );
if( !handle || !nand.SetData( handle, QByteArray( (const char*)&certs_dat, CERTS_DAT_SIZE ) ) ) if( !handle || !nand.SetData( handle, QByteArray( (const char*)&certs_dat, CERTS_DAT_SIZE ) ) )
{ {
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating cert in the new nand"; qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating cert in the new nand";
QMessageBox::warning( this, tr( "Error" ), \ QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create cert.sys in the new nand." ) ); tr( "Can't create cert.sys in the new nand." ) );
return false; return false;
} }
//create uid.sys //create uid.sys
switch( ui->comboBox_uid->currentIndex() ) switch( ui->comboBox_uid->currentIndex() )
{ {
case 0: case 0:
uidSys.clear(); uidSys.clear();
break; break;
case 1://jap case 1://jap
{ {
UIDmap uid; UIDmap uid;
uid.CreateNew( 0x4a ); uid.CreateNew( 0x4a );
uidSys = uid.Data(); uidSys = uid.Data();
} }
break; break;
case 2://usa case 2://usa
{ {
UIDmap uid; UIDmap uid;
uid.CreateNew( 0x45 ); uid.CreateNew( 0x45 );
uidSys = uid.Data(); uidSys = uid.Data();
} }
break; break;
case 3://eur case 3://eur
{ {
UIDmap uid; UIDmap uid;
uid.CreateNew( 0x50 ); uid.CreateNew( 0x50 );
uidSys = uid.Data(); uidSys = uid.Data();
} }
break; break;
case 4://kor case 4://kor
{ {
UIDmap uid; UIDmap uid;
uid.CreateNew( 0x4b ); uid.CreateNew( 0x4b );
uidSys = uid.Data(); uidSys = uid.Data();
} }
break; break;
default: default:
break; break;
} }
if( !uidSys.isEmpty() ) if( !uidSys.isEmpty() )
{ {
//hexdump( uidSys ); //hexdump( uidSys );
quint16 fd = nand.CreateEntry( "/sys/uid.sys", 0, 0, NAND_FILE, NAND_RW, NAND_RW, 0 ); quint16 fd = nand.CreateEntry( "/sys/uid.sys", 0, 0, NAND_FILE, NAND_RW, NAND_RW, 0 );
if( !fd || !nand.SetData( fd, uidSys ) ) if( !fd || !nand.SetData( fd, uidSys ) )
{ {
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating cert in the new nand"; qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating cert in the new nand";
QMessageBox::warning( this, tr( "Error" ), \ QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create uid.sys in the new nand." ) ); tr( "Can't create uid.sys in the new nand." ) );
return false; return false;
} }
} }
//commit changes to metadata //commit changes to metadata
if( !nand.WriteMetaData() ) if( !nand.WriteMetaData() )
{ {
qWarning() << "NewNandBin::on_buttonBox_accepted -> error writing metadata"; qWarning() << "NewNandBin::on_buttonBox_accepted -> error writing metadata";
QMessageBox::warning( this, tr( "Error" ), \ QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't write metadata in the new nand." ) ); tr( "Can't write metadata in the new nand." ) );
return false; return false;
} }
return true; return true;
} }
//ok clicked //ok clicked
@ -172,34 +172,34 @@ void NewNandBin::on_buttonBox_accepted()
{ {
if( ui->lineEdit_keys->text().isEmpty() || ui->lineEdit_boot->text().isEmpty() || ui->lineEdit_dest->text().isEmpty() ) if( ui->lineEdit_keys->text().isEmpty() || ui->lineEdit_boot->text().isEmpty() || ui->lineEdit_dest->text().isEmpty() )
{ {
QMessageBox::warning( this, tr( "Error" ), tr( "Required feilds are empty" ) ); QMessageBox::warning( this, tr( "Error" ), tr( "Required feilds are empty" ) );
return; return;
} }
if( keys.isEmpty() ) if( keys.isEmpty() )
keys = ReadFile( ui->lineEdit_keys->text() ); keys = ReadFile( ui->lineEdit_keys->text() );
if( boots.isEmpty() ) if( boots.isEmpty() )
boots = ReadFile( ui->lineEdit_boot->text() ); boots = ReadFile( ui->lineEdit_boot->text() );
if( keys.size() != 0x400 || boots.size() != 0x108000 ) if( keys.size() != 0x400 || boots.size() != 0x108000 )
{ {
QMessageBox::warning( this, tr( "Error" ), tr( "The keys or boot1/2 is not correct" ) ); QMessageBox::warning( this, tr( "Error" ), tr( "The keys or boot1/2 is not correct" ) );
keys.clear(); keys.clear();
boots.clear(); boots.clear();
return; return;
} }
if( !nand.CreateNew( ui->lineEdit_dest->text(), keys, boots, BadBlocks() ) ) if( !nand.CreateNew( ui->lineEdit_dest->text(), keys, boots, BadBlocks() ) )
{ {
qDebug() << "error creating nand.bin"; qDebug() << "error creating nand.bin";
keys.clear(); keys.clear();
boots.clear(); boots.clear();
return; return;
}
//qDebug() << "created nand, trying to add default entries";
if( !CreateDefaultEntries() )
{
keys.clear();
boots.clear();
return;
} }
//qDebug() << "created nand, trying to add default entries";
if( !CreateDefaultEntries() )
{
keys.clear();
boots.clear();
return;
}
ret = ui->lineEdit_dest->text(); ret = ui->lineEdit_dest->text();
} }
@ -208,7 +208,7 @@ QString NewNandBin::GetNewNandPath( QWidget *parent, QList<quint16> badBlocks )
{ {
NewNandBin d( parent, badBlocks ); NewNandBin d( parent, badBlocks );
if( !d.exec() ) if( !d.exec() )
return QString(); return QString();
return d.ret; return d.ret;
} }
@ -217,149 +217,149 @@ void NewNandBin::on_pushButton_badBlockFile_clicked()
{ {
QString f = QFileDialog::getOpenFileName( this, tr( "Select File with Bad Block List" ), dir ); QString f = QFileDialog::getOpenFileName( this, tr( "Select File with Bad Block List" ), dir );
if( f.isEmpty() ) if( f.isEmpty() )
return; return;
dir = QFileInfo( f ).canonicalPath(); dir = QFileInfo( f ).canonicalPath();
QString str = QString( ReadFile( f ) ); QString str = QString( ReadFile( f ) );
if( str.isEmpty() ) if( str.isEmpty() )
{ {
qWarning() << "NewNandBin::on_pushButton_badBlockFile_clicked -> error reading file"; qWarning() << "NewNandBin::on_pushButton_badBlockFile_clicked -> error reading file";
return; return;
} }
ui->listWidget_badBlocks->clear(); ui->listWidget_badBlocks->clear();
str.replace( "\r\n", "\n" ); str.replace( "\r\n", "\n" );
QStringList lines = str.split( "\n", QString::SkipEmptyParts ); QStringList lines = str.split( "\n", QString::SkipEmptyParts );
foreach( QString line, lines ) foreach( const QString &line, lines )
{ {
if( line.size() > 5 ) if( line.size() > 5 )
continue; continue;
bool ok = false; bool ok = false;
if( ui->listWidget_badBlocks->findItems( line, Qt::MatchExactly ).size() )//this one is already in the list if( ui->listWidget_badBlocks->findItems( line, Qt::MatchExactly ).size() )//this one is already in the list
continue; continue;
quint16 bb = line.toInt( &ok ); quint16 bb = line.toInt( &ok );
if( !ok || bb < 8 || bb > 4079 ) if( !ok || bb < 8 || bb > 4079 )
continue; continue;
ui->listWidget_badBlocks->addItem( line ); ui->listWidget_badBlocks->addItem( line );
} }
} }
//read info from existing nand.bin //read info from existing nand.bin
void NewNandBin::on_pushButton_oldNand_clicked() void NewNandBin::on_pushButton_oldNand_clicked()
{ {
QString f = QFileDialog::getOpenFileName( this, tr( "Select Old nand.bin" ), dir ); QString f = QFileDialog::getOpenFileName( this, tr( "Select Old nand.bin" ), dir );
if( f.isEmpty() ) if( f.isEmpty() )
return; return;
QFileInfo fi( f ); QFileInfo fi( f );
QFile file( fi.absoluteFilePath() ); QFile file( fi.absoluteFilePath() );
if( !file.exists() || !file.open( QIODevice::ReadOnly ) ) if( !file.exists() || !file.open( QIODevice::ReadOnly ) )
{ {
QMessageBox::warning( this, tr( "Error" ), \ QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't open %1!" ).arg( fi.absoluteFilePath() ) ); tr( "Can't open %1!" ).arg( fi.absoluteFilePath() ) );
return; return;
} }
ui->listWidget_badBlocks->clear(); ui->listWidget_badBlocks->clear();
switch( fi.size() ) switch( fi.size() )
{ {
case 0x21000000:// w/ ecc, keys in different file case 0x21000000:// w/ ecc, keys in different file
{ {
boots = file.read( 0x108000 ); boots = file.read( 0x108000 );
//file.seek(); //file.seek();
keys = ReadFile( fi.absoluteDir().absoluteFilePath( "keys.bin" ) ); keys = ReadFile( fi.absoluteDir().absoluteFilePath( "keys.bin" ) );
} }
break; break;
case 0x21000400:// w/ ecc, keys at end of nand dump case 0x21000400:// w/ ecc, keys at end of nand dump
{ {
boots = file.read( 0x108000 ); boots = file.read( 0x108000 );
file.seek( 0x21000000 ); file.seek( 0x21000000 );
keys = file.read( 0x400 ); keys = file.read( 0x400 );
//keys = ReadFile( fi.absoluteDir().absoluteFilePath( "keys.bin" ) ); //keys = ReadFile( fi.absoluteDir().absoluteFilePath( "keys.bin" ) );
} }
break; break;
default://unsupported for this default://unsupported for this
QMessageBox::warning( this, tr( "Error" ), tr( "I need a nand dump with ecc to create a new nand from.<br>Accepted sizes are 0x21000000 and 0x21000400." ) ); QMessageBox::warning( this, tr( "Error" ), tr( "I need a nand dump with ecc to create a new nand from.<br>Accepted sizes are 0x21000000 and 0x21000400." ) );
file.close(); file.close();
return; return;
break; break;
} }
file.close(); file.close();
//create nandBin object to get the list of bad blocks //create nandBin object to get the list of bad blocks
NandBin old( this ); NandBin old( this );
if( !old.SetPath( fi.absoluteFilePath() ) || !old.InitNand() ) if( !old.SetPath( fi.absoluteFilePath() ) || !old.InitNand() )
{ {
QMessageBox::warning( this, tr( "Error" ), \ QMessageBox::warning( this, tr( "Error" ), \
tr( "Error reading %1." ).arg( fi.absoluteFilePath() ) ); tr( "Error reading %1." ).arg( fi.absoluteFilePath() ) );
keys.clear(); keys.clear();
boots.clear(); boots.clear();
return; return;
} }
QList<quint16> clusters = old.GetFats(); QList<quint16> clusters = old.GetFats();
QList<quint16> badBlacks; QList<quint16> badBlacks;
if( !clusters.size() == 0x8000 ) if( !clusters.size() == 0x8000 )
{ {
QMessageBox::warning( this, tr( "Error" ), \ QMessageBox::warning( this, tr( "Error" ), \
tr( "Expected 0x8000 clusters from the nand, but got %1 instead!" ).arg( clusters.size(), 0, 16 ), QMessageBox::Ok ); tr( "Expected 0x8000 clusters from the nand, but got %1 instead!" ).arg( clusters.size(), 0, 16 ), QMessageBox::Ok );
keys.clear(); keys.clear();
boots.clear(); boots.clear();
return; return;
} }
for( quint16 i = 0; i < 0x8000; i += 8 )//first cluster of each block. for( quint16 i = 0; i < 0x8000; i += 8 )//first cluster of each block.
{ {
//qDebug() << hex << i << clusters.at( i ); //qDebug() << hex << i << clusters.at( i );
if( clusters.at( i ) == 0xFFFD ) if( clusters.at( i ) == 0xFFFD )
{ {
quint16 block = ( i / 8 ); quint16 block = ( i / 8 );
badBlacks << block; badBlacks << block;
QString txt = QString( "%1" ).arg( block ); QString txt = QString( "%1" ).arg( block );
//qDebug() << "bad cluster" << hex << i << block << txt; //qDebug() << "bad cluster" << hex << i << block << txt;
//if( ui->listWidget_badBlocks->findItems( txt, Qt::MatchExactly ).isEmpty() )//just in case, but this should always be true //if( ui->listWidget_badBlocks->findItems( txt, Qt::MatchExactly ).isEmpty() )//just in case, but this should always be true
ui->listWidget_badBlocks->addItem( txt ); ui->listWidget_badBlocks->addItem( txt );
} }
} }
uidSys = old.GetData( "/sys/uid.sys" ); uidSys = old.GetData( "/sys/uid.sys" );
if( !uidSys.isEmpty() ) if( !uidSys.isEmpty() )
{ {
uidSys = GetCleanUid( uidSys ); uidSys = GetCleanUid( uidSys );
ui->comboBox_uid->setCurrentIndex( 5 ); ui->comboBox_uid->setCurrentIndex( 5 );
//hexdump( uidSys ); //hexdump( uidSys );
} }
ui->lineEdit_boot->setText( tr( "<From old nand>" ) ); ui->lineEdit_boot->setText( tr( "<From old nand>" ) );
ui->lineEdit_keys->setText( tr( "<From old nand>" ) ); ui->lineEdit_keys->setText( tr( "<From old nand>" ) );
} }
//remove all entries of a uid.sys from after the user has started doing stuff //remove all entries of a uid.sys from after the user has started doing stuff
QByteArray NewNandBin::GetCleanUid( QByteArray old ) QByteArray NewNandBin::GetCleanUid( QByteArray old )
{ {
QBuffer buf( &old ); QBuffer buf( &old );
buf.open( QIODevice::ReadWrite ); buf.open( QIODevice::ReadWrite );
quint64 tid; quint64 tid;
quint16 titles = 0; quint16 titles = 0;
quint32 cnt = old.size() / 12; quint32 cnt = old.size() / 12;
for( quint32 i = 0; i < cnt; i++ ) for( quint32 i = 0; i < cnt; i++ )
{ {
buf.seek( i * 12 ); buf.seek( i * 12 );
buf.read( (char*)&tid, 8 ); buf.read( (char*)&tid, 8 );
tid = qFromBigEndian( tid ); tid = qFromBigEndian( tid );
quint32 upper = ( ( tid >> 32 ) & 0xffffffff ); quint32 upper = ( ( tid >> 32 ) & 0xffffffff );
quint32 lower = ( tid & 0xffffffff ); quint32 lower = ( tid & 0xffffffff );
//qDebug() << QString( "%1" ).arg( tid, 16, 16, QChar( '0' ) ) << hex << upper << lower << ( ( lower >> 24 ) & 0xff ) << ( lower & 0xffff00 ); //qDebug() << QString( "%1" ).arg( tid, 16, 16, QChar( '0' ) ) << hex << upper << lower << ( ( lower >> 24 ) & 0xff ) << ( lower & 0xffff00 );
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;
titles++; titles++;
} }
buf.close(); buf.close();
return old.left( 12 * titles ); return old.left( 12 * titles );
} }