From a3e62886044288f62480f65ab3d8c85a9d234df8 Mon Sep 17 00:00:00 2001 From: "giantpune@gmail.com" Date: Thu, 23 Dec 2010 16:17:46 +0000 Subject: [PATCH] * implement static function for creating wads from a list of bytearrays * minor optimizations - using "const &" to avoid creating a duplicate for function arguments in the library files * nandBin needs to be built with write support to create a new file git-svn-id: http://wiiqt.googlecode.com/svn/trunk@30 389f4c8b-5dfe-645f-db0e-df882bc27289 --- WiiQt/nandbin.cpp | 34 +++++++++++++++++++--------------- WiiQt/nandbin.h | 30 +++++++++++++++--------------- WiiQt/nanddump.cpp | 30 +++++++++++++++--------------- WiiQt/nanddump.h | 20 ++++++++++---------- WiiQt/nusdownloader.cpp | 11 +++++------ WiiQt/nusdownloader.h | 8 ++++---- WiiQt/sharedcontentmap.cpp | 4 ++-- WiiQt/sharedcontentmap.h | 4 ++-- WiiQt/tiktmd.cpp | 12 ++++++------ WiiQt/tiktmd.h | 8 ++++---- WiiQt/tools.cpp | 20 ++++++++------------ WiiQt/tools.h | 19 +++++-------------- WiiQt/uidmap.cpp | 2 +- WiiQt/uidmap.h | 2 +- WiiQt/wad.cpp | 23 +++++++++++++++-------- WiiQt/wad.h | 24 +++++++++++++++--------- nand_dump/mainwindow.cpp | 1 - nand_dump/mainwindow.ui | 3 +++ 18 files changed, 130 insertions(+), 125 deletions(-) diff --git a/WiiQt/nandbin.cpp b/WiiQt/nandbin.cpp index 88264b8..82a7858 100755 --- a/WiiQt/nandbin.cpp +++ b/WiiQt/nandbin.cpp @@ -47,8 +47,12 @@ bool NandBin::SetPath( const QString &path ) return ret; } -bool NandBin::CreateNew( const QString &path, QByteArray keys, QByteArray first8, QList badBlocks ) +bool NandBin::CreateNew( const QString &path, const QByteArray &keys, const QByteArray &first8, const QList &badBlocks ) { +#ifndef NAND_BIN_CAN_WRITE + qWarning() << __FILE__ << "was built without write support"; + return false; +#endif if( keys.size() != 0x400 || first8.size() != 0x108000 ) { qWarning() << "NandBin::CreateNew -> bad sizes" << hex << keys.size() << first8.size(); @@ -256,7 +260,7 @@ bool NandBin::AddChildren( QTreeWidgetItem *parent, quint16 entry ) return true; } -QString NandBin::FstName( fst_t fst ) +const QString NandBin::FstName( fst_t fst ) { QByteArray ba( (char*)fst.filename, 0xc ); QString ret = QString( ba ); @@ -294,7 +298,7 @@ bool NandBin::ExtractFST( quint16 entry, const QString &path, bool singleFile ) return true; } -bool NandBin::ExtractDir( fst_t fst, QString parent ) +bool NandBin::ExtractDir( fst_t fst, const QString &parent ) { //qDebug() << "NandBin::ExtractDir(" << parent << ")"; QByteArray ba( (char*)fst.filename, 0xc ); @@ -316,7 +320,7 @@ bool NandBin::ExtractDir( fst_t fst, QString parent ) return true; } -bool NandBin::ExtractFile( fst_t fst, QString parent ) +bool NandBin::ExtractFile( fst_t fst, const QString &parent ) { QByteArray ba( (char*)fst.filename, 0xc ); QString filename( ba ); @@ -336,7 +340,7 @@ bool NandBin::ExtractFile( fst_t fst, QString parent ) return true; } -bool NandBin::InitNand( QIcon dirs, QIcon files ) +bool NandBin::InitNand( const QIcon &dirs, const QIcon &files ) { fstInited = false; memset( (void*)&fsts, 0, sizeof( fst_t ) * 0x17ff ); @@ -525,7 +529,7 @@ bool NandBin::GetKey( int type ) return true; } -QByteArray NandBin::ReadKeyfile( QString path, quint8 type ) +const QByteArray NandBin::ReadKeyfile( const QString &path, quint8 type ) { QByteArray retval; QFile f( path ); @@ -688,7 +692,7 @@ quint16 NandBin::GetFAT( quint16 fat_entry ) return ret; } -QByteArray NandBin::GetPage( quint32 pageNo, bool withEcc ) +const QByteArray NandBin::GetPage( quint32 pageNo, bool withEcc ) { //qDebug() << "NandBin::GetPage( " << hex << pageNo << ", " << withEcc << " )"; quint32 n_pagelen[] = { 0x800, 0x840, 0x840 }; @@ -704,7 +708,7 @@ QByteArray NandBin::GetPage( quint32 pageNo, bool withEcc ) return page; } -QByteArray NandBin::GetCluster( quint16 cluster_entry, bool decrypt ) +const QByteArray NandBin::GetCluster( quint16 cluster_entry, bool decrypt ) { //qDebug() << "NandBin::GetCluster" << hex << cluster_entry; quint32 n_clusterlen[] = { 0x4000, 0x4200, 0x4200 }; @@ -746,7 +750,7 @@ QByteArray NandBin::GetCluster( quint16 cluster_entry, bool decrypt ) return ret; } -QByteArray NandBin::GetFile( quint16 entry ) +const QByteArray NandBin::GetFile( quint16 entry ) { fst_t fst = GetFST( entry ); if( !fst.filename[ 0 ] )//something is amiss, better quit now @@ -754,7 +758,7 @@ QByteArray NandBin::GetFile( quint16 entry ) return GetFile( fst ); } -QByteArray NandBin::GetFile( fst_t fst_ ) +const QByteArray NandBin::GetFile( fst_t fst_ ) { //qDebug() << "NandBin::GetFile" << QByteArray( (const char*)fst_.filename, 12 ); if( !fst_.size ) @@ -1014,7 +1018,7 @@ QTreeWidgetItem *NandBin::ItemFromEntry( const QString &i, QTreeWidgetItem *pare return NULL; } -bool NandBin::WriteCluster( quint32 pageNo, const QByteArray data, const QByteArray hmac ) +bool NandBin::WriteCluster( quint32 pageNo, const QByteArray &data, const QByteArray &hmac ) { if( data.size() != 0x4000 ) { @@ -1047,7 +1051,7 @@ bool NandBin::WriteCluster( quint32 pageNo, const QByteArray data, const QByteAr return true; } -bool NandBin::WriteDecryptedCluster( quint32 pageNo, const QByteArray data, fst_t fst, quint16 idx ) +bool NandBin::WriteDecryptedCluster( quint32 pageNo, const QByteArray &data, fst_t fst, quint16 idx ) { //qDebug() << "NandBin::WriteDecryptedCluster"; QByteArray hmac = spare.Get_hmac_data( data, fst.uid, (const unsigned char *)&fst.filename, fst.fst_pos, fst.x3, idx ); @@ -1060,7 +1064,7 @@ bool NandBin::WriteDecryptedCluster( quint32 pageNo, const QByteArray data, fst_ return WriteCluster( pageNo, encData, hmac ); } -bool NandBin::WritePage( quint32 pageNo, const QByteArray data ) +bool NandBin::WritePage( quint32 pageNo, const QByteArray &data ) { //return true; #ifndef NAND_BIN_CAN_WRITE @@ -1335,7 +1339,7 @@ bool NandBin::DeleteItem( QTreeWidgetItem *item ) return true; } -bool NandBin::SetData( const QString &path, const QByteArray data ) +bool NandBin::SetData( const QString &path, const QByteArray &data ) { QTreeWidgetItem *i = ItemFromPath( path ); if( !i ) @@ -1355,7 +1359,7 @@ bool NandBin::SetData( const QString &path, const QByteArray data ) return SetData( idx, data ); } -bool NandBin::SetData( quint16 idx, const QByteArray data ) +bool NandBin::SetData( quint16 idx, const QByteArray &data ) { fst_t fst = fsts[ idx ]; qDebug() << "NandBin::SetData" << FstName( fst ); diff --git a/WiiQt/nandbin.h b/WiiQt/nandbin.h index bb7c9ca..3e8a15f 100755 --- a/WiiQt/nandbin.h +++ b/WiiQt/nandbin.h @@ -46,7 +46,7 @@ public: //keys should be a 0x400 byte array containing a keys.bin from bootmii //first8 should be a bytearray containing 0x108000 bytes - the first 8 blocks of the nand with spare data //badBlocks is a list of blocks to be marked bad, in the range 8 - 4079 - bool CreateNew( const QString &path, QByteArray keys, QByteArray first8, QList badBlocks = QList() ); + bool CreateNew( const QString &path, const QByteArray &keys, const QByteArray &first8, const QList &badBlocks = QList() ); //sets the path of this object to path. returns false if it cannot open an already existing file //keys.bin should be in this same path if they are to be used @@ -55,7 +55,7 @@ public: //try to read the filesystem and create a tree from its contents //this takes care of the stuff like reading the keys, finding teh superblock, and creating the QTreeWidgetItem* tree //icons given here will be the ones used when asking for that tree - bool InitNand( QIcon dirs = QIcon(), QIcon files = QIcon() ); + bool InitNand( const QIcon &dirs = QIcon(), const QIcon &files = QIcon() ); //get a root item containing children that are actually entries in the nand dump //the root itself is just a container to hold them all and can be deleted once its children are taken @@ -83,7 +83,7 @@ public: void SetFixNamesForFAT( bool fix = true ); //returns the data that makes up the file of a given entry# - QByteArray GetFile( quint16 entry ); + const QByteArray GetFile( quint16 entry ); //get data for a given path @@ -113,7 +113,7 @@ public: const QList Boot2Infos(); quint8 Boot1Version(); - QByteArray GetPage( quint32 pageNo, bool withEcc = false ); + const QByteArray GetPage( quint32 pageNo, bool withEcc = false ); //create new entry //returns the index of the entry on success, or 0 on error @@ -123,10 +123,10 @@ public: bool Delete( const QString &path ); //sets the data for a given file ( overwrites existing data ) - bool SetData( quint16 idx, const QByteArray data ); + bool SetData( quint16 idx, const QByteArray &data ); //overloads the above function - bool SetData( const QString &path, const QByteArray data ); + bool SetData( const QString &path, const QByteArray &data ); //write the current changes to the metadata( if you dont do this, then none of the other stuff youve done wont be saved ) // but at the same time, you probably dont need to overuse this. ( no need to write metadata every time you make a single change ) @@ -170,17 +170,17 @@ private: int GetDumpType( quint64 fileSize ); bool GetKey( int type ); - QByteArray ReadKeyfile( QString path, quint8 type );//type 0 for nand key, type 1 for hmac + const QByteArray ReadKeyfile( const QString &path, quint8 type );//type 0 for nand key, type 1 for hmac qint32 FindSuperblock(); quint16 GetFAT( quint16 fat_entry ); fst_t GetFST( quint16 entry ); - QByteArray GetCluster( quint16 cluster_entry, bool decrypt = true ); - QByteArray GetFile( fst_t fst ); + const QByteArray GetCluster( quint16 cluster_entry, bool decrypt = true ); + const QByteArray GetFile( fst_t fst ); - QString FstName( fst_t fst ); + const QString FstName( fst_t fst ); bool ExtractFST( quint16 entry, const QString &path, bool singleFile = false ); - bool ExtractDir( fst_t fst, QString parent ); - bool ExtractFile( fst_t fst, QString parent ); + bool ExtractDir( fst_t fst, const QString &parent ); + bool ExtractFile( fst_t fst, const QString &parent ); QTreeWidgetItem *CreateItem( QTreeWidgetItem *parent, const QString &name, quint32 size, quint16 entry, quint32 uid, quint32 gid, quint32 x3, quint8 attr, quint8 wtf); @@ -194,9 +194,9 @@ private: //holds info about boot1 & 2 Blocks0to7 bootBlocks; - bool WriteCluster( quint32 pageNo, const QByteArray data, const QByteArray hmac ); - bool WriteDecryptedCluster( quint32 pageNo, const QByteArray data, fst_t fst, quint16 idx ); - bool WritePage( quint32 pageNo, const QByteArray data ); + bool WriteCluster( quint32 pageNo, const QByteArray &data, const QByteArray &hmac ); + bool WriteDecryptedCluster( quint32 pageNo, const QByteArray &data, fst_t fst, quint16 idx ); + bool WritePage( quint32 pageNo, const QByteArray &data ); quint16 CreateNode( const QString &name, quint32 uid, quint16 gid, quint8 attr, quint8 user_perm, quint8 group_perm, quint8 other_perm ); diff --git a/WiiQt/nanddump.cpp b/WiiQt/nanddump.cpp index c0d27df..73c2ce6 100644 --- a/WiiQt/nanddump.cpp +++ b/WiiQt/nanddump.cpp @@ -144,7 +144,7 @@ QByteArray NandDump::GetSettingTxt() return GetFile( "/title/00000001/00000002/data/setting.txt" ); } -bool NandDump::SetSettingTxt( const QByteArray ba ) +bool NandDump::SetSettingTxt( const QByteArray &ba ) { if( basePath.isEmpty() ) return false; @@ -163,7 +163,7 @@ const QByteArray NandDump::GetFile( const QString &path ) } //write some file to the nand -bool NandDump::SaveData( const QByteArray ba, const QString& path ) +bool NandDump::SaveData( const QByteArray &ba, const QString& path ) { if( basePath.isEmpty() || !path.startsWith( "/" ) ) return false; @@ -181,7 +181,7 @@ void NandDump::DeleteData( const QString & path ) QFile::remove( basePath + path ); } -bool NandDump::InstallTicket( const QByteArray ba, quint64 tid ) +bool NandDump::InstallTicket( const QByteArray &ba, quint64 tid ) { Ticket t( ba ); if( t.Tid() != tid ) @@ -208,7 +208,7 @@ bool NandDump::InstallTicket( const QByteArray ba, quint64 tid ) return SaveData( start, p ); } -bool NandDump::InstallTmd( const QByteArray ba, quint64 tid ) +bool NandDump::InstallTmd( const QByteArray &ba, quint64 tid ) { Tmd t( ba ); if( t.Tid() != tid ) @@ -225,7 +225,7 @@ bool NandDump::InstallTmd( const QByteArray ba, quint64 tid ) return SaveData( start, p ); } -bool NandDump::InstallSharedContent( const QByteArray ba, const QByteArray hash ) +bool NandDump::InstallSharedContent( const QByteArray &ba, const QByteArray &hash ) { QByteArray h = hash; if( h.isEmpty() ) @@ -245,7 +245,7 @@ bool NandDump::InstallSharedContent( const QByteArray ba, const QByteArray hash return true; } -bool NandDump::InstallPrivateContent( const QByteArray ba, quint64 tid, const QString &cid ) +bool NandDump::InstallPrivateContent( const QByteArray &ba, quint64 tid, const QString &cid ) { QString p = QString( "%1" ).arg( tid, 16, 16, QChar( '0' ) ); p.insert( 8 ,"/" ); @@ -322,7 +322,7 @@ bool NandDump::RecurseDeleteFolder( const QString &path ) return QDir().rmdir( path ); } -bool NandDump::InstallNusItem( NusJob job ) +bool NandDump::InstallNusItem( const NusJob &job ) { if( !job.tid || job.data.size() < 3 ) { @@ -345,13 +345,13 @@ bool NandDump::InstallNusItem( NusJob job ) if( !QFileInfo( path ).exists() && !QDir().mkpath( path ) ) return false; - QByteArray ba = job.data.takeFirst(); + QByteArray ba = job.data.at( 0 ); if( !InstallTmd( ba, job.tid ) ) return false; Tmd t( ba ); - ba = job.data.takeFirst(); + ba = job.data.at( 1 ); Ticket ti( ba ); if( !InstallTicket( ba, job.tid ) ) { @@ -372,14 +372,14 @@ bool NandDump::InstallNusItem( NusJob job ) QByteArray decData; if( job.decrypt ) { - decData = job.data.takeFirst(); + decData = job.data.at( i + 2 ); } else { //seems like a waste to keep setting the key, but for now im doing it this way //so multiple objects can be decrypting titles at the same time AesSetKey( ti.DecryptedKey() ); - QByteArray paddedEncrypted = PaddedByteArray( job.data.takeFirst(), 0x40 ); + QByteArray paddedEncrypted = PaddedByteArray( job.data.at( i + 2 ), 0x40 ); decData = AesDecrypt( i, paddedEncrypted ); decData.resize( t.Size( i ) ); QByteArray realHash = GetSha1( decData ); @@ -448,7 +448,7 @@ bool NandDump::InstallWad( Wad wad ) Tmd t( ba ); ba = wad.getTik(); - Ticket ti( ba ); + //Ticket ti( ba ); if( !InstallTicket( ba, wad.Tid() ) ) { AbortInstalling( wad.Tid() ); @@ -565,7 +565,7 @@ void NandDump::ReadReplacementStrings() } } -bool NandDump::SetReplaceString( const QString ch, const QString &replaceWith ) +bool NandDump::SetReplaceString( const QString &ch, const QString &replaceWith ) { qWarning() << "NandDump::SetReplaceString(" << ch << "," << replaceWith << ")"; QRegExp re( "[^/?*:;{}\\]+" ); @@ -749,7 +749,7 @@ SaveGame NandDump::GetSaveData( quint64 tid ) return ret; } -bool NandDump::InstallSave( SaveGame save ) +bool NandDump::InstallSave( const SaveGame &save ) { if( basePath.isEmpty() || !IsValidSave( save ) ) return false; @@ -791,7 +791,7 @@ bool NandDump::InstallSave( SaveGame save ) return true; } -bool NandDump::IsValidSave( SaveGame save ) +bool NandDump::IsValidSave( const SaveGame &save ) { if( !save.tid || save.entries.size() != save.isFile.size() ) return false; diff --git a/WiiQt/nanddump.h b/WiiQt/nanddump.h index efe5fd3..d88f77e 100644 --- a/WiiQt/nanddump.h +++ b/WiiQt/nanddump.h @@ -39,7 +39,7 @@ public: //giving an empty replacement string will remove that entry and all the actual character will be used in paths //! this function will recurse the "/title" folder and apply any change to any existing files if finds //! if that fails ( like you tried to tell it to use a ':' while writing to a FAT32 drive), it will try to recurse that folder again and undo the change - bool SetReplaceString( const QString ch, const QString &replaceWith = QString() ); + bool SetReplaceString( const QString &ch, const QString &replaceWith = QString() ); //get a list of the replacement strings used when writing save data // they are returned as ( character as it would be on the wii nand, string as it is on this nand dump ) @@ -53,7 +53,7 @@ public: //installs a title to the nand dump from an already existing NusJob //returns false if something went wrong - bool InstallNusItem( NusJob job ); + bool InstallNusItem( const NusJob &job ); //installs a title to the nand dump from a wad //returns false if something went wrong @@ -76,13 +76,13 @@ public: //overloads GetFile() with "/title/00000001/00000002/data/setting.txt" QByteArray GetSettingTxt(); - bool SetSettingTxt( const QByteArray ba ); + bool SetSettingTxt( const QByteArray &ba ); //reads a file from the nand and returns it as a qbytearray const QByteArray GetFile( const QString &path ); //tries to write the given bytearray to a file of the given path - bool SaveData( const QByteArray ba, const QString& path ); + bool SaveData( const QByteArray &ba, const QString& path ); //expects a file, not directory void DeleteData( const QString & path ); @@ -92,7 +92,7 @@ public: SaveGame GetSaveData( quint64 tid ); //installs a save to the nand - bool InstallSave( SaveGame save ); + bool InstallSave( const SaveGame &save ); //convert a name TO the format that will be writen to the nand // it would be wise to only give these functions the name of the exact file you want to convert instead of the path @@ -110,7 +110,7 @@ public: const QString FromNandPath( const QString &path ); //sanity check a save object - static bool IsValidSave( SaveGame save ); + static bool IsValidSave( const SaveGame &save ); @@ -132,10 +132,10 @@ private: bool cmDirty; bool FlushContentMap(); - bool InstallTicket( const QByteArray ba, quint64 tid ); - bool InstallTmd( const QByteArray ba, quint64 tid ); - bool InstallSharedContent( const QByteArray ba, const QByteArray hash = QByteArray() ); - bool InstallPrivateContent( const QByteArray ba, quint64 tid, const QString &cid ); + bool InstallTicket( const QByteArray &ba, quint64 tid ); + bool InstallTmd( const QByteArray &ba, quint64 tid ); + bool InstallSharedContent( const QByteArray &ba, const QByteArray &hash = QByteArray() ); + bool InstallPrivateContent( const QByteArray &ba, quint64 tid, const QString &cid ); void AbortInstalling( quint64 tid ); //go through and delete all the stuff in a given folder and then delete the folder itself diff --git a/WiiQt/nusdownloader.cpp b/WiiQt/nusdownloader.cpp index b1b48d2..5b31696 100644 --- a/WiiQt/nusdownloader.cpp +++ b/WiiQt/nusdownloader.cpp @@ -17,7 +17,7 @@ void NusDownloader::SetCachePath( const QString &cPath ) } //add a single job to the list -void NusDownloader::GetTitle( NusJob job ) +void NusDownloader::GetTitle( const NusJob &job ) { //qDebug() << "NusDownloader::GetTitle"; jobList.append( job ); @@ -32,7 +32,7 @@ void NusDownloader::GetTitle( NusJob job ) } //add a list of jobs to the list -void NusDownloader::GetTitles( QList jobs ) +void NusDownloader::GetTitles( const QList &jobs ) { //qDebug() << "NusDownloader::GetTitles"; jobList.append( jobs ); @@ -140,7 +140,7 @@ QByteArray NusDownloader::GetDataFromCache( downloadJob job ) } //load the tmd and try to get the ticket -void NusDownloader::ReadTmdAndGetTicket( QByteArray ba ) +void NusDownloader::ReadTmdAndGetTicket( const QByteArray &ba ) { //qDebug() << "NusDownloader::ReadTmdAndGetTicket" << hex << ba.size(); curTmd = Tmd( ba ); @@ -227,7 +227,7 @@ bool NusDownloader::SaveDataToCache( const QString &path, const QByteArray &stuf return true; } -downloadJob NusDownloader::CreateJob( QString name, quint16 index ) +downloadJob NusDownloader::CreateJob( const QString &name, quint16 index ) { downloadJob r; r.tid = QString( "%1" ).arg( currentJob.tid, 16, 16, QChar( '0' ) ); @@ -984,7 +984,7 @@ QMap< quint64, quint16 > NusDownloader::List41e() QMap< quint64, quint16 > NusDownloader::List42e() { QMap< quint64, quint16 > titles = List41e(); - titles.insert( 0x100000001ull, 0x4 );//make people really ask for the boot2 update if they want it + //titles.insert( 0x100000001ull, 0x4 );//make people really ask for the boot2 update if they want it titles.insert( 0x100000009ull, 0x30a ); // IOS9 titles.insert( 0x10000000cull, 0x10d ); // IOS12 titles.insert( 0x10000000dull, 0x111 ); // IOS13 @@ -1107,7 +1107,6 @@ QMap< quint64, quint16 > NusDownloader::List31u() { QMap< quint64, quint16 > titles = List30u(); //( from rockband2 ) - //titles.insert( 0x100000001ull, 2 );//boot2 titles.insert( 0x100000002ull, 257 );//sys menu titles.insert( 0x10000000eull, 262 );//14v262 - should actually be 14v257 but that version isnt available on NUS titles.insert( 0x10000001eull, 1040 );//30v1040 diff --git a/WiiQt/nusdownloader.h b/WiiQt/nusdownloader.h index 013e62a..66870b9 100644 --- a/WiiQt/nusdownloader.h +++ b/WiiQt/nusdownloader.h @@ -50,8 +50,8 @@ public: void SetCachePath( const QString &cPath = QString() ); //get a title from NUS. if version is 0, get the latest one - void GetTitle( NusJob job ); - void GetTitles( QList jobs ); + void GetTitle( const NusJob &job ); + void GetTitles( const QList &jobs ); void Get( quint64 tid, bool decrypt, quint16 version = TITLE_LATEST_VERSION ); //TODO! this function is far from complete @@ -108,7 +108,7 @@ public: private: //helper function to create a job - downloadJob CreateJob( QString name, quint16 index ); + downloadJob CreateJob( const QString &name, quint16 index ); //path on the PC to try and get files from and save to to avoid downloading deplicates from NUS QString cachePath; @@ -121,7 +121,7 @@ private: bool SaveDataToCache( const QString &path, const QByteArray &stuff ); //check the tmd and try to ticket - void ReadTmdAndGetTicket( QByteArray ba ); + void ReadTmdAndGetTicket( const QByteArray &ba ); bool DecryptCheckHashAndAppendData( const QByteArray &encData, quint16 idx ); diff --git a/WiiQt/sharedcontentmap.cpp b/WiiQt/sharedcontentmap.cpp index 92cbff4..9bb8a63 100644 --- a/WiiQt/sharedcontentmap.cpp +++ b/WiiQt/sharedcontentmap.cpp @@ -1,7 +1,7 @@ #include "sharedcontentmap.h" #include "tools.h" -SharedContentMap::SharedContentMap( QByteArray old ) +SharedContentMap::SharedContentMap( const QByteArray &old ) { data = old; if( data.size() ) @@ -79,7 +79,7 @@ bool SharedContentMap::Check( const QString &path ) return true; } -QString SharedContentMap::GetAppFromHash( QByteArray hash ) +QString SharedContentMap::GetAppFromHash( const QByteArray &hash ) { quint32 cnt = data.size() / 28; for( quint32 i = 0; i < cnt; i++ ) diff --git a/WiiQt/sharedcontentmap.h b/WiiQt/sharedcontentmap.h index b026338..6a82466 100644 --- a/WiiQt/sharedcontentmap.h +++ b/WiiQt/sharedcontentmap.h @@ -7,7 +7,7 @@ class SharedContentMap { public: - SharedContentMap( QByteArray old = QByteArray() ); + SharedContentMap( const QByteArray &old = QByteArray() ); //checks that the content map is sane //size should be correct, contents should be in numerical order @@ -16,7 +16,7 @@ public: //gets a string containing the 8 letter app that matches the given hash. //returns an empty string if the hash is not found in the map - QString GetAppFromHash( QByteArray hash ); + QString GetAppFromHash( const QByteArray &hash ); //gets the first available u32 that is not already in the map and returns it as a string QString GetNextEmptyCid(); diff --git a/WiiQt/tiktmd.cpp b/WiiQt/tiktmd.cpp index 306feba..791282a 100644 --- a/WiiQt/tiktmd.cpp +++ b/WiiQt/tiktmd.cpp @@ -4,7 +4,7 @@ #include -Tmd::Tmd( QByteArray stuff ) +Tmd::Tmd( const QByteArray &stuff ) { data = stuff; p_tmd = NULL; @@ -102,7 +102,7 @@ QByteArray Tmd::Hash( quint16 i ) return QByteArray( (const char*)&p_tmd->contents[ i ].hash, 20 ); } -bool Tmd::SetHash( quint16 cid, const QByteArray hash ) +bool Tmd::SetHash( quint16 cid, const QByteArray &hash ) { if( !p_tmd || cid >= qFromBigEndian( p_tmd->num_contents ) || hash.size() != 20 ) return false; @@ -234,7 +234,7 @@ bool Tmd::FakeSign() return ret; } -Ticket::Ticket( QByteArray stuff ) +Ticket::Ticket( const QByteArray &stuff ) { data = stuff; p_tik = NULL; @@ -451,7 +451,7 @@ static int get_sub_len( const quint8 *sub ) return -ERROR_SUB_TYPE; } -static int check_rsa( QByteArray h, const quint8 *sig, const quint8 *key, const quint32 n ) +static int check_rsa( const QByteArray &h, const quint8 *sig, const quint8 *key, const quint32 n ) { quint8 correct[ 0x200 ], x[ 0x200 ]; static const quint8 ber[ 16 ] = { 0x00,0x30,0x21,0x30,0x09,0x06,0x05,0x2b, @@ -476,7 +476,7 @@ static int check_rsa( QByteArray h, const quint8 *sig, const quint8 *key, const return ERROR_RSA_HASH; } -static int check_hash( QByteArray h, const quint8 *sig, const quint8 *key ) +static int check_hash( const QByteArray &h, const quint8 *sig, const quint8 *key ) { quint32 type; type = BE32( sig ) - 0x10000; @@ -528,7 +528,7 @@ static const quint8* find_cert_in_chain( const quint8 *sub, const quint8 *cert, return NULL; } -int check_cert_chain( const QByteArray data ) +int check_cert_chain( const QByteArray &data ) { int cert_err; const quint8* key; diff --git a/WiiQt/tiktmd.h b/WiiQt/tiktmd.h index ee0d6ee..5defe12 100644 --- a/WiiQt/tiktmd.h +++ b/WiiQt/tiktmd.h @@ -139,7 +139,7 @@ typedef struct _cert_ecdsa { class Ticket { public: - Ticket( QByteArray stuff = QByteArray() ); + Ticket( const QByteArray &stuff = QByteArray() ); //expose the tik data to the rest of the code so it cas read directly from the p_tmd instead of having to add a function to access all the data //the pointer should be good until "data" is changed @@ -173,7 +173,7 @@ private: class Tmd { public: - Tmd( QByteArray stuff = QByteArray() ); + Tmd( const QByteArray &stuff = QByteArray() ); //expose the tmd data to the rest of the code so it cas read directly from the p_tmd instead of having to add a function to access all the data //the pointer should be good until "data" is changed @@ -205,7 +205,7 @@ public: bool SetVersion( quint16 v ); bool SetType( quint16 i, quint16 type ); bool SetSize( quint16 i, quint32 size ); - bool SetHash( quint16 i, const QByteArray hash ); + bool SetHash( quint16 i, const QByteArray &hash ); bool SetIOS( quint64 ios ); bool SetAhb( bool remove = true ); bool SetDiskAccess( bool allow = true ); @@ -249,6 +249,6 @@ enum //checks the signatures in a tmd/ticket //returns 1 of the above enums -int check_cert_chain( const QByteArray data ); +int check_cert_chain( const QByteArray &data ); #endif // TIKTMD_H diff --git a/WiiQt/tools.cpp b/WiiQt/tools.cpp index 5947c93..2fad569 100644 --- a/WiiQt/tools.cpp +++ b/WiiQt/tools.cpp @@ -3,10 +3,6 @@ #include "aes.h" #include "sha1.h" -//QString currentDir; -//QString cachePath = "./NUS_cache"; -//QString nandPath = "./dump"; - char ascii( char s ) { if ( s < 0x20 ) return '.'; if ( s > 0x7E ) return '.'; @@ -92,20 +88,20 @@ QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo ) return orig + padding; } -QByteArray AesDecrypt( quint16 index, const QByteArray source ) +QByteArray AesDecrypt( quint16 index, const QByteArray &source ) { //qDebug() << "AesDecrypt" << hex << index << source.size(); quint8 iv[ 16 ]; quint16 beidx = qFromBigEndian( index ); - memset( iv, 0, 16 ); - memcpy( iv, &beidx, 2 ); + memset( &iv, 0, 16 ); + memcpy( &iv, &beidx, 2 ); QByteArray ret( source.size(), '\0' ); - aes_decrypt( 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; } -QByteArray AesEncrypt( quint16 index, const QByteArray source ) +QByteArray AesEncrypt( quint16 index, const QByteArray &source ) { static quint8 iv[ 16 ]; @@ -117,13 +113,13 @@ QByteArray AesEncrypt( quint16 index, const QByteArray source ) return ret; } -void AesSetKey( const QByteArray key ) +void AesSetKey( const QByteArray &key ) { // qDebug() << "AesSetKey()" << key.toHex(); aes_set_key( (const quint8*)key.data() ); } -QByteArray GetSha1( QByteArray stuff ) +QByteArray GetSha1( const QByteArray &stuff ) { SHA1Context sha; SHA1Reset( &sha ); @@ -157,7 +153,7 @@ QByteArray ReadFile( const QString &path ) return ret; } -bool WriteFile( const QString &path, const QByteArray ba ) +bool WriteFile( const QString &path, const QByteArray &ba ) { QFile file( path ); if( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) diff --git a/WiiQt/tools.h b/WiiQt/tools.h index 4a41408..8e2b25f 100644 --- a/WiiQt/tools.h +++ b/WiiQt/tools.h @@ -16,11 +16,11 @@ void hexdump12( const void *d, int len ); void hexdump12( const QByteArray &d, int from = 0, int len = -1 ); //simplified functions for crypto shit -void AesSetKey( const QByteArray key ); -QByteArray AesDecrypt( quint16 index, const QByteArray source ); -QByteArray AesEncrypt( quint16 index, const QByteArray source ); +void AesSetKey( const QByteArray &key ); +QByteArray AesDecrypt( quint16 index, const QByteArray &source ); +QByteArray AesEncrypt( quint16 index, const QByteArray &source ); -QByteArray GetSha1( QByteArray stuff ); +QByteArray GetSha1( const QByteArray &stuff ); //get a padded version of the given buffer QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo ); @@ -29,16 +29,7 @@ QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo ); QByteArray ReadFile( const QString &path ); //save a file to disc -bool WriteFile( const QString &path, const QByteArray ba ); - -//keep track of the last folder browsed to when looking for files -//extern QString currentDir; - -//folder used to cache stuff downloaded from NUS so duplicate titles dont need to be downloaded -//extern QString cachePath; - -//folder to use as the base path for the nand -//extern QString nandPath; +bool WriteFile( const QString &path, const QByteArray &ba ); #define CERTS_DAT_SIZE 2560 extern const quint8 certs_dat[ CERTS_DAT_SIZE ]; diff --git a/WiiQt/uidmap.cpp b/WiiQt/uidmap.cpp index 6990707..0ef48d4 100644 --- a/WiiQt/uidmap.cpp +++ b/WiiQt/uidmap.cpp @@ -1,7 +1,7 @@ #include "uidmap.h" #include "tools.h" -UIDmap::UIDmap( const QByteArray old ) +UIDmap::UIDmap( const QByteArray &old ) { data = old; if( data.isEmpty() ) diff --git a/WiiQt/uidmap.h b/WiiQt/uidmap.h index a688279..8147409 100644 --- a/WiiQt/uidmap.h +++ b/WiiQt/uidmap.h @@ -8,7 +8,7 @@ class UIDmap { public: - UIDmap( const QByteArray old = QByteArray() ); + UIDmap( const QByteArray &old = QByteArray() ); ~UIDmap(); //makes sure there are the default entries in the map and that the entries are sane diff --git a/WiiQt/wad.cpp b/WiiQt/wad.cpp index e20195b..c576a06 100644 --- a/WiiQt/wad.cpp +++ b/WiiQt/wad.cpp @@ -4,7 +4,7 @@ static QByteArray globalCert; -Wad::Wad( const QByteArray stuff ) +Wad::Wad( const QByteArray &stuff ) { ok = false; if( stuff.size() < 0x80 )//less than this and there is definitely nothing there @@ -132,7 +132,7 @@ Wad::Wad( const QByteArray stuff ) ok = true; } -Wad::Wad( QList< QByteArray > stuff, bool encrypted ) +Wad::Wad( const QList< QByteArray > &stuff, bool encrypted ) { if( stuff.size() < 3 ) { @@ -173,7 +173,7 @@ Wad::Wad( QList< QByteArray > stuff, bool encrypted ) } -void Wad::SetCert( const QByteArray stuff ) +void Wad::SetCert( const QByteArray &stuff ) { certData = stuff; } @@ -238,14 +238,14 @@ quint32 Wad::content_count() return partsEnc.size(); } -void Wad::Err( QString str ) +void Wad::Err( const QString &str ) { ok = false; errStr = str; qWarning() << "Wad::Error" << str; } -const QByteArray Wad::Data( quint32 magicWord, const QByteArray footer ) +const QByteArray Wad::Data( quint32 magicWord, const QByteArray &footer ) { //qDebug() << "Wad::Data" << hex << magicWord << footer.size(); if( !partsEnc.size() || tmdData.isEmpty() || tikData.isEmpty() || ( certData.isEmpty() && globalCert.isEmpty() ) ) @@ -337,7 +337,7 @@ const QByteArray Wad::Data( quint32 magicWord, const QByteArray footer ) return ret; } -QString Wad::WadName( QString path ) +QString Wad::WadName( const QString &path ) { if( !tmdData.size() ) { @@ -348,7 +348,7 @@ QString Wad::WadName( QString path ) return WadName( t.Tid(), t.Version(), path ); } -QString Wad::WadName( quint64 tid, quint16 version, QString path ) +QString Wad::WadName( quint64 tid, quint16 version, const QString &path ) { quint32 type = (quint32)( ( tid >> 32 ) & 0xffffffff ); quint32 base = (quint32)( tid & 0xffffffff ); @@ -635,7 +635,7 @@ bool Wad::SetDiskAccess( bool allow ) return true; } -bool Wad::ReplaceContent( quint16 idx, const QByteArray ba ) +bool Wad::ReplaceContent( quint16 idx, const QByteArray &ba ) { if( idx >= partsEnc.size() || !tmdData.size() || !tikData.size() ) { @@ -675,3 +675,10 @@ bool Wad::ReplaceContent( quint16 idx, const QByteArray ba ) return true; } +QByteArray FromPartList( const QList< QByteArray > &stuff, bool isEncrypted = true ) +{ + Wad wad( stuff, isEncrypted ); + if( !wad.IsOk() ) + return QByteArray(); + return wad.Data(); +} diff --git a/WiiQt/wad.h b/WiiQt/wad.h index 847c9c1..3087e41 100644 --- a/WiiQt/wad.h +++ b/WiiQt/wad.h @@ -6,18 +6,18 @@ class Wad { public: //create a wad instance from a bytearray containing a wad - Wad( const QByteArray stuff = QByteArray() ); + Wad( const QByteArray &stuff = QByteArray() ); //create a wad object from a list of byteArrays. //the first one should be the tmd, the second one the ticket, and the rest are the contents, in order //it will use the global cert unless one is given with SetCert - Wad( QList< QByteArray > stuff, bool isEncrypted = true ); + Wad( const QList< QByteArray > &stuff, bool isEncrypted = true ); //check if this wad is valid bool IsOk(){ return ok; } //set the cert for this wad - void SetCert( const QByteArray stuff ); + void SetCert( const QByteArray &stuff ); //returns the tid of the tmd of this wad( which may be different than the one in the ticket if somebody did something stupid ) quint64 Tid(); @@ -36,7 +36,7 @@ public: //replace a content of this wad, update the size & hash in the tmd and sign it //ba should be decrypted - bool ReplaceContent( quint16 idx, const QByteArray ba ); + bool ReplaceContent( quint16 idx, const QByteArray &ba ); //add a new content to this wad and fakesign //if the data is encrypted, set that arguement to true @@ -50,15 +50,21 @@ public: static void SetGlobalCert( const QByteArray &stuff ); //pack a wad from the given directory + //returns a bytearray containing a wad reading for writing to a file + //or an empty bytearray on error + //! dir should be a directory containing a tmd ( "*.tmd" or "tmd.*" ), a ticket ( "*.tik" or "cetk" ), + //! all the contents ( .app :where cid is the correct cid from the tmd, not the "0, 1, 2, 3..." bullshit some broken wad-unpackers create ) + //! if any of the .apps do not match in size or hash what is in the TMD, then the TMD will be updated and fakesigned + //! a cert ( "*.cert" ) is also supported, but not required static QByteArray FromDirectory( QDir dir ); //get a assembled wad from the list of parts //the first one should be the tmd, the second one the ticket, and the rest are the contents, in order //it will use the global cert - static QByteArray FromPartList( QList< QByteArray > stuff, bool isEncrypted = true ); + static QByteArray FromPartList( const QList< QByteArray > &stuff, bool isEncrypted = true ); //get all the parts of this wad put together in a wad ready for writing to disc or whatever - const QByteArray Data( quint32 magicWord = 0x49730000, const QByteArray footer = QByteArray() ); + const QByteArray Data( quint32 magicWord = 0x49730000, const QByteArray &footer = QByteArray() ); //get the tmd for the wad const QByteArray getTmd(); @@ -78,10 +84,10 @@ public: //get a name for a wad as it would be seen in a wii disc update partition //if a path is given, it will check that path for existing wads with the name and append a number to the end "(1)" to avoid duplicate files //returns an empty string if it cant guess the title based on TID - static QString WadName( quint64 tid, quint16 version, QString path = QString() ); + static QString WadName( quint64 tid, quint16 version, const QString &path = QString() ); //get this Wad's name as it would appear on a disc update partition - QString WadName( QString path = QString() ); + QString WadName( const QString &path = QString() ); private: bool ok; @@ -93,7 +99,7 @@ private: QByteArray tikData; QByteArray certData; - void Err( QString str ); + void Err( const QString &str ); }; #endif // WAD_H diff --git a/nand_dump/mainwindow.cpp b/nand_dump/mainwindow.cpp index 42b5e4e..bf66e9d 100644 --- a/nand_dump/mainwindow.cpp +++ b/nand_dump/mainwindow.cpp @@ -343,7 +343,6 @@ void MainWindow::on_actionImportWad_triggered() ShowMessage( tr( "Wad data not ok" ) );; return; } - bool ok = nand.InstallWad( wad ); if( ok ) ShowMessage( tr( "Installed %1 title to nand" ).arg( wad.WadName() ) ); diff --git a/nand_dump/mainwindow.ui b/nand_dump/mainwindow.ui index 04cc557..5860e12 100644 --- a/nand_dump/mainwindow.ui +++ b/nand_dump/mainwindow.ui @@ -245,6 +245,9 @@ Import Wad + + Ctrl+I +