mirror of
https://github.com/martravi/wiiqt.git
synced 2024-11-24 18:16:56 +01:00
* use const reference in foreach() also
This commit is contained in:
parent
3ee828284a
commit
d0ca7c0f15
@ -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=" ) )
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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() )
|
||||
|
@ -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 );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user