* 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 );
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 );
foreach( QString part, parts )
foreach( const QString &part, parts )
{
QString p = part;
if( part.startsWith( "AREA=" ) )

View File

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

View File

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

View File

@ -111,7 +111,7 @@ void PrintColoredString( const char *msg, int highlite )
{
QString str( msg );
QStringList list = str.split( "\n", QString::SkipEmptyParts );
foreach( QString s, list )
foreach( const QString &s, list )
{
QString m = s;
QString m2 = s.trimmed();
@ -183,7 +183,7 @@ void Usage()
qDebug() << "";
qDebug() << " -all does all of the above";
qDebug() << "";
qDebug() << " -v increase verbosity";
qDebug() << " -v increase verbosity ( can be used more than once )";
qDebug() << "";
qDebug() << " -continue try to keep going as fas as possible on errors that should be fatal";
qDebug() << "";
@ -434,22 +434,22 @@ void CheckShared()
qDebug() << "checking" << path << "...";
QByteArray stuff = nand.GetData( path );
if( stuff.isEmpty() )
{
BadSharedItems << sharedM.Hash( i );
{
BadSharedItems << sharedM.Hash( i );
Fail( "One of the shared contents in this nand is missing" );
}
}
QByteArray realHash = GetSha1( stuff );
if( realHash != sharedM.Hash( i ) )
{
BadSharedItems << sharedM.Hash( i );
if( verbose )
{
qCritical() << "\texpected: " << sharedM.Hash( i ).toHex();
qCritical() << "\tactual: " << realHash.toHex();
}
{
BadSharedItems << sharedM.Hash( i );
if( verbose )
{
qCritical() << "\texpected: " << sharedM.Hash( i ).toHex();
qCritical() << "\tactual: " << realHash.toHex();
}
Fail( "The hash for at least 1 content is bad" );
}
}
}
}
@ -680,86 +680,81 @@ bool CheckTitleIntegrity( quint64 tid )
qDebug() << "error getting" << it << "data";
return false;
}
if( i )//tmd
{
t = Tmd( ba );
if( t.Tid() != tid )
{
qWarning() << "\tthe TMD contains the wrong TID";
return false;
}
if( calcRsa )
{
qint32 ch = check_cert_chain( ba );
switch( ch )
{
case ERROR_SIG_TYPE:
case ERROR_SUB_TYPE:
case ERROR_RSA_HASH:
case ERROR_RSA_TYPE_UNKNOWN:
case ERROR_RSA_TYPE_MISMATCH:
case ERROR_CERT_NOT_FOUND:
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
break;
case ERROR_RSA_FAKESIGNED:
qWarning().nospace() << "\t" << qPrintable( it ) << " fakesigned";
break;
default:
break;
}
}
}
else
{
Ticket ticket( ba, false );
if( ticket.Tid() != tid )
{
qWarning() << "\tthe ticket contains the wrong TID";
return false;
}
if( calcRsa )
{
int tikVersions = ba.size() / 0x2a4;
qint32 ch = ERROR_RSA_TYPE_UNKNOWN;
bool ok = false;
for( int rr = 0; rr < tikVersions && !ok; rr++ )
{
ch = check_cert_chain( ba.mid( rr * 0x2a4, 0x2a4 ) );
switch( ch )
{
default:
break;
case ERROR_RSA_FAKESIGNED:
case ERROR_SUCCESS:
ok = true;
break;
}
}
switch( ch )
{
case ERROR_SIG_TYPE:
case ERROR_SUB_TYPE:
case ERROR_RSA_HASH:
case ERROR_RSA_TYPE_UNKNOWN:
case ERROR_RSA_TYPE_MISMATCH:
case ERROR_CERT_NOT_FOUND:
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
break;
case ERROR_RSA_FAKESIGNED:
qWarning().nospace() << "\t" << qPrintable( it ) << " fakesigned";
break;
default:
break;
}
}
}
if( i )//tmd
{
t = Tmd( ba );
if( t.Tid() != tid )
{
qWarning() << "\tthe TMD contains the wrong TID";
return false;
}
if( calcRsa )
{
qint32 ch = check_cert_chain( ba );
switch( ch )
{
case ERROR_SIG_TYPE:
case ERROR_SUB_TYPE:
case ERROR_RSA_HASH:
case ERROR_RSA_TYPE_UNKNOWN:
case ERROR_RSA_TYPE_MISMATCH:
case ERROR_CERT_NOT_FOUND:
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
break;
case ERROR_RSA_FAKESIGNED:
qWarning().nospace() << "\t" << qPrintable( it ) << " fakesigned";
break;
default:
break;
}
}
}
else
{
Ticket ticket( ba, false );
if( ticket.Tid() != tid )
{
qWarning() << "\tthe ticket contains the wrong TID";
return false;
}
if( calcRsa )
{
int tikVersions = ba.size() / 0x2a4;
qint32 ch = ERROR_RSA_TYPE_UNKNOWN;
bool ok = false;
for( int rr = 0; rr < tikVersions && !ok; rr++ )
{
ch = check_cert_chain( ba.mid( rr * 0x2a4, 0x2a4 ) );
switch( ch )
{
default:
break;
case ERROR_RSA_FAKESIGNED:
case ERROR_SUCCESS:
ok = true;
break;
}
}
switch( ch )
{
case ERROR_SIG_TYPE:
case ERROR_SUB_TYPE:
case ERROR_RSA_HASH:
case ERROR_RSA_TYPE_UNKNOWN:
case ERROR_RSA_TYPE_MISMATCH:
case ERROR_CERT_NOT_FOUND:
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
break;
case ERROR_RSA_FAKESIGNED:
qWarning().nospace() << "\t" << qPrintable( it ) << " fakesigned";
break;
default:
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
@ -770,11 +765,11 @@ bool CheckTitleIntegrity( quint64 tid )
{
if( t.Type( i ) == 0x8001 )//shared
{
if( BadSharedItems.contains( t.Hash( i ) ) )
{
qWarning() << "\tthis title relies on a shared content that is borked (" << i << ")\n\t" << t.Hash( i ).toHex();
return false;
}
if( BadSharedItems.contains( t.Hash( i ) ) )
{
qWarning() << "\tthis title relies on a shared content that is borked (" << i << ")\n\t" << t.Hash( i ).toHex();
return false;
}
if( sharedM.GetAppFromHash( t.Hash( i ) ).isEmpty() )
{
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 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
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/" );
}
@ -1197,7 +1192,7 @@ void CheckSettingTxt()
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
QStringList parts = str.split( "\n", QString::SkipEmptyParts );
foreach( QString part, parts )
foreach( const QString &part, parts )
{
if( part.startsWith( "AREA=" ) )
{
@ -1320,7 +1315,7 @@ int main( int argc, char *argv[] )
qCritical() << "** nandBinCheck : Wii nand info tool **";
qCritical() << " from giantpune";
qCritical() << " built:" << __DATE__ << __TIME__;
args = QCoreApplication::arguments();
args = QCoreApplication::arguments();
if( args.contains( "-nocolor", Qt::CaseInsensitive ) )
color = false;

View File

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

View File

@ -9,9 +9,9 @@ NewNandBin::NewNandBin( QWidget *parent, QList<quint16> badBlocks ) : QDialog(pa
ui->setupUi(this);
foreach( quint16 block, badBlocks )
{
QString txt = QString( "%1" ).arg( block );
if( ui->listWidget_badBlocks->findItems( txt, Qt::MatchExactly ).isEmpty() )
ui->listWidget_badBlocks->addItem( txt );
QString txt = QString( "%1" ).arg( block );
if( ui->listWidget_badBlocks->findItems( txt, Qt::MatchExactly ).isEmpty() )
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 );
if( f.isEmpty() )
return;
return;
ui->lineEdit_keys->setText( f );
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 );
if( f.isEmpty() )
return;
return;
ui->lineEdit_boot->setText( f );
dir = QFileInfo( f ).canonicalPath();
}
@ -42,7 +42,7 @@ void NewNandBin::on_pushButton_dest_clicked()
{
QString f = QFileDialog::getSaveFileName( this, tr( "Output file" ), dir );
if( f.isEmpty() )
return;
return;
ui->lineEdit_dest->setText( f );
dir = QFileInfo( f ).canonicalPath();
}
@ -53,10 +53,10 @@ QList<quint16> NewNandBin::BadBlocks()
quint16 cnt = ui->listWidget_badBlocks->count();
for( quint16 i = 0; i < cnt; i++ )
{
bool ok = false;
quint16 num = ui->listWidget_badBlocks->item( i )->text().toInt( &ok );
if( ok )
ret << num;
bool ok = false;
quint16 num = ui->listWidget_badBlocks->item( i )->text().toInt( &ok );
if( ok )
ret << num;
}
return ret;
}
@ -66,7 +66,7 @@ void NewNandBin::on_pushButton_bb_add_clicked()
quint16 val = ui->spinBox->value();
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();
foreach( QListWidgetItem *item, items )
{
ui->listWidget_badBlocks->removeItemWidget( item );
delete item;
ui->listWidget_badBlocks->removeItemWidget( item );
delete item;
}
}
bool NewNandBin::CreateDefaultEntries()
{
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( "/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( "/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( "/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.WriteMetaData() )
{
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating directories in the new nand";
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create base folders in the new nand." ) );
return false;
}
//add cert.sys
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 ) ) )
{
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating cert in the new nand";
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create cert.sys in the new nand." ) );
return false;
}
//create uid.sys
switch( ui->comboBox_uid->currentIndex() )
{
case 0:
uidSys.clear();
break;
case 1://jap
{
UIDmap uid;
uid.CreateNew( 0x4a );
uidSys = uid.Data();
}
break;
case 2://usa
{
UIDmap uid;
uid.CreateNew( 0x45 );
uidSys = uid.Data();
}
break;
case 3://eur
{
UIDmap uid;
uid.CreateNew( 0x50 );
uidSys = uid.Data();
}
break;
case 4://kor
{
UIDmap uid;
uid.CreateNew( 0x4b );
uidSys = uid.Data();
}
break;
default:
break;
}
if( !uidSys.isEmpty() )
{
//hexdump( uidSys );
quint16 fd = nand.CreateEntry( "/sys/uid.sys", 0, 0, NAND_FILE, NAND_RW, NAND_RW, 0 );
if( !fd || !nand.SetData( fd, uidSys ) )
{
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating cert in the new nand";
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create uid.sys in the new nand." ) );
return false;
}
}
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( "/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( "/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( "/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.WriteMetaData() )
{
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating directories in the new nand";
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create base folders in the new nand." ) );
return false;
}
//add cert.sys
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 ) ) )
{
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating cert in the new nand";
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create cert.sys in the new nand." ) );
return false;
}
//create uid.sys
switch( ui->comboBox_uid->currentIndex() )
{
case 0:
uidSys.clear();
break;
case 1://jap
{
UIDmap uid;
uid.CreateNew( 0x4a );
uidSys = uid.Data();
}
break;
case 2://usa
{
UIDmap uid;
uid.CreateNew( 0x45 );
uidSys = uid.Data();
}
break;
case 3://eur
{
UIDmap uid;
uid.CreateNew( 0x50 );
uidSys = uid.Data();
}
break;
case 4://kor
{
UIDmap uid;
uid.CreateNew( 0x4b );
uidSys = uid.Data();
}
break;
default:
break;
}
if( !uidSys.isEmpty() )
{
//hexdump( uidSys );
quint16 fd = nand.CreateEntry( "/sys/uid.sys", 0, 0, NAND_FILE, NAND_RW, NAND_RW, 0 );
if( !fd || !nand.SetData( fd, uidSys ) )
{
qWarning() << "NewNandBin::on_buttonBox_accepted -> error creating cert in the new nand";
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't create uid.sys in the new nand." ) );
return false;
}
}
//commit changes to metadata
if( !nand.WriteMetaData() )
{
qWarning() << "NewNandBin::on_buttonBox_accepted -> error writing metadata";
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't write metadata in the new nand." ) );
return false;
}
return true;
//commit changes to metadata
if( !nand.WriteMetaData() )
{
qWarning() << "NewNandBin::on_buttonBox_accepted -> error writing metadata";
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't write metadata in the new nand." ) );
return false;
}
return true;
}
//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() )
{
QMessageBox::warning( this, tr( "Error" ), tr( "Required feilds are empty" ) );
return;
QMessageBox::warning( this, tr( "Error" ), tr( "Required feilds are empty" ) );
return;
}
if( keys.isEmpty() )
keys = ReadFile( ui->lineEdit_keys->text() );
if( boots.isEmpty() )
boots = ReadFile( ui->lineEdit_boot->text() );
if( keys.isEmpty() )
keys = ReadFile( ui->lineEdit_keys->text() );
if( boots.isEmpty() )
boots = ReadFile( ui->lineEdit_boot->text() );
if( keys.size() != 0x400 || boots.size() != 0x108000 )
{
QMessageBox::warning( this, tr( "Error" ), tr( "The keys or boot1/2 is not correct" ) );
keys.clear();
boots.clear();
return;
QMessageBox::warning( this, tr( "Error" ), tr( "The keys or boot1/2 is not correct" ) );
keys.clear();
boots.clear();
return;
}
if( !nand.CreateNew( ui->lineEdit_dest->text(), keys, boots, BadBlocks() ) )
{
qDebug() << "error creating nand.bin";
keys.clear();
boots.clear();
return;
qDebug() << "error creating nand.bin";
keys.clear();
boots.clear();
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();
}
@ -208,7 +208,7 @@ QString NewNandBin::GetNewNandPath( QWidget *parent, QList<quint16> badBlocks )
{
NewNandBin d( parent, badBlocks );
if( !d.exec() )
return QString();
return QString();
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 );
if( f.isEmpty() )
return;
return;
dir = QFileInfo( f ).canonicalPath();
QString str = QString( ReadFile( f ) );
if( str.isEmpty() )
{
qWarning() << "NewNandBin::on_pushButton_badBlockFile_clicked -> error reading file";
return;
qWarning() << "NewNandBin::on_pushButton_badBlockFile_clicked -> error reading file";
return;
}
ui->listWidget_badBlocks->clear();
str.replace( "\r\n", "\n" );
QStringList lines = str.split( "\n", QString::SkipEmptyParts );
foreach( QString line, lines )
foreach( const QString &line, lines )
{
if( line.size() > 5 )
continue;
bool ok = false;
if( line.size() > 5 )
continue;
bool ok = false;
if( ui->listWidget_badBlocks->findItems( line, Qt::MatchExactly ).size() )//this one is already in the list
continue;
if( ui->listWidget_badBlocks->findItems( line, Qt::MatchExactly ).size() )//this one is already in the list
continue;
quint16 bb = line.toInt( &ok );
if( !ok || bb < 8 || bb > 4079 )
continue;
quint16 bb = line.toInt( &ok );
if( !ok || bb < 8 || bb > 4079 )
continue;
ui->listWidget_badBlocks->addItem( line );
ui->listWidget_badBlocks->addItem( line );
}
}
//read info from existing nand.bin
void NewNandBin::on_pushButton_oldNand_clicked()
{
QString f = QFileDialog::getOpenFileName( this, tr( "Select Old nand.bin" ), dir );
if( f.isEmpty() )
return;
QString f = QFileDialog::getOpenFileName( this, tr( "Select Old nand.bin" ), dir );
if( f.isEmpty() )
return;
QFileInfo fi( f );
QFile file( fi.absoluteFilePath() );
if( !file.exists() || !file.open( QIODevice::ReadOnly ) )
{
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't open %1!" ).arg( fi.absoluteFilePath() ) );
return;
}
ui->listWidget_badBlocks->clear();
QFileInfo fi( f );
QFile file( fi.absoluteFilePath() );
if( !file.exists() || !file.open( QIODevice::ReadOnly ) )
{
QMessageBox::warning( this, tr( "Error" ), \
tr( "Can't open %1!" ).arg( fi.absoluteFilePath() ) );
return;
}
ui->listWidget_badBlocks->clear();
switch( fi.size() )
{
case 0x21000000:// w/ ecc, keys in different file
{
boots = file.read( 0x108000 );
//file.seek();
keys = ReadFile( fi.absoluteDir().absoluteFilePath( "keys.bin" ) );
switch( fi.size() )
{
case 0x21000000:// w/ ecc, keys in different file
{
boots = file.read( 0x108000 );
//file.seek();
keys = ReadFile( fi.absoluteDir().absoluteFilePath( "keys.bin" ) );
}
break;
case 0x21000400:// w/ ecc, keys at end of nand dump
{
boots = file.read( 0x108000 );
file.seek( 0x21000000 );
keys = file.read( 0x400 );
//keys = ReadFile( fi.absoluteDir().absoluteFilePath( "keys.bin" ) );
}
break;
case 0x21000400:// w/ ecc, keys at end of nand dump
{
boots = file.read( 0x108000 );
file.seek( 0x21000000 );
keys = file.read( 0x400 );
//keys = ReadFile( fi.absoluteDir().absoluteFilePath( "keys.bin" ) );
}
break;
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." ) );
file.close();
return;
break;
}
file.close();
}
break;
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." ) );
file.close();
return;
break;
}
file.close();
//create nandBin object to get the list of bad blocks
NandBin old( this );
if( !old.SetPath( fi.absoluteFilePath() ) || !old.InitNand() )
{
QMessageBox::warning( this, tr( "Error" ), \
tr( "Error reading %1." ).arg( fi.absoluteFilePath() ) );
keys.clear();
boots.clear();
return;
}
QList<quint16> clusters = old.GetFats();
QList<quint16> badBlacks;
if( !clusters.size() == 0x8000 )
{
QMessageBox::warning( this, tr( "Error" ), \
tr( "Expected 0x8000 clusters from the nand, but got %1 instead!" ).arg( clusters.size(), 0, 16 ), QMessageBox::Ok );
keys.clear();
boots.clear();
return;
}
for( quint16 i = 0; i < 0x8000; i += 8 )//first cluster of each block.
{
//qDebug() << hex << i << clusters.at( i );
if( clusters.at( i ) == 0xFFFD )
{
quint16 block = ( i / 8 );
badBlacks << block;
QString txt = QString( "%1" ).arg( block );
//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
ui->listWidget_badBlocks->addItem( txt );
}
}
uidSys = old.GetData( "/sys/uid.sys" );
if( !uidSys.isEmpty() )
{
uidSys = GetCleanUid( uidSys );
ui->comboBox_uid->setCurrentIndex( 5 );
//hexdump( uidSys );
}
ui->lineEdit_boot->setText( tr( "<From old nand>" ) );
ui->lineEdit_keys->setText( tr( "<From old nand>" ) );
//create nandBin object to get the list of bad blocks
NandBin old( this );
if( !old.SetPath( fi.absoluteFilePath() ) || !old.InitNand() )
{
QMessageBox::warning( this, tr( "Error" ), \
tr( "Error reading %1." ).arg( fi.absoluteFilePath() ) );
keys.clear();
boots.clear();
return;
}
QList<quint16> clusters = old.GetFats();
QList<quint16> badBlacks;
if( !clusters.size() == 0x8000 )
{
QMessageBox::warning( this, tr( "Error" ), \
tr( "Expected 0x8000 clusters from the nand, but got %1 instead!" ).arg( clusters.size(), 0, 16 ), QMessageBox::Ok );
keys.clear();
boots.clear();
return;
}
for( quint16 i = 0; i < 0x8000; i += 8 )//first cluster of each block.
{
//qDebug() << hex << i << clusters.at( i );
if( clusters.at( i ) == 0xFFFD )
{
quint16 block = ( i / 8 );
badBlacks << block;
QString txt = QString( "%1" ).arg( block );
//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
ui->listWidget_badBlocks->addItem( txt );
}
}
uidSys = old.GetData( "/sys/uid.sys" );
if( !uidSys.isEmpty() )
{
uidSys = GetCleanUid( uidSys );
ui->comboBox_uid->setCurrentIndex( 5 );
//hexdump( uidSys );
}
ui->lineEdit_boot->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
QByteArray NewNandBin::GetCleanUid( QByteArray old )
{
QBuffer buf( &old );
buf.open( QIODevice::ReadWrite );
QBuffer buf( &old );
buf.open( QIODevice::ReadWrite );
quint64 tid;
quint16 titles = 0;
quint32 cnt = old.size() / 12;
for( quint32 i = 0; i < cnt; i++ )
{
buf.seek( i * 12 );
buf.read( (char*)&tid, 8 );
tid = qFromBigEndian( tid );
quint32 upper = ( ( tid >> 32 ) & 0xffffffff );
quint32 lower = ( tid & 0xffffffff );
//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'
lower == 0x48415858 || //original HBC
tid == 0x100000000ull || //bannerbomb -> ATD ( or any other program that uses the SU tid )
( upper == 0x10000 && ( ( lower & 0xffffff00 ) == 0x555000 ) ) ) //a disc update partition
break;
quint64 tid;
quint16 titles = 0;
quint32 cnt = old.size() / 12;
for( quint32 i = 0; i < cnt; i++ )
{
buf.seek( i * 12 );
buf.read( (char*)&tid, 8 );
tid = qFromBigEndian( tid );
quint32 upper = ( ( tid >> 32 ) & 0xffffffff );
quint32 lower = ( tid & 0xffffffff );
//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'
lower == 0x48415858 || //original HBC
tid == 0x100000000ull || //bannerbomb -> ATD ( or any other program that uses the SU tid )
( upper == 0x10000 && ( ( lower & 0xffffff00 ) == 0x555000 ) ) ) //a disc update partition
break;
titles++;
}
buf.close();
return old.left( 12 * titles );
titles++;
}
buf.close();
return old.left( 12 * titles );
}