* 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
This commit is contained in:
giantpune@gmail.com 2010-12-23 16:17:46 +00:00
parent 0f506a205d
commit dfcd1bed60
18 changed files with 130 additions and 125 deletions

View File

@ -47,8 +47,12 @@ bool NandBin::SetPath( const QString &path )
return ret;
}
bool NandBin::CreateNew( const QString &path, QByteArray keys, QByteArray first8, QList<quint16> badBlocks )
bool NandBin::CreateNew( const QString &path, const QByteArray &keys, const QByteArray &first8, const QList<quint16> &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 );

View File

@ -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<quint16> badBlocks = QList<quint16>() );
bool CreateNew( const QString &path, const QByteArray &keys, const QByteArray &first8, const QList<quint16> &badBlocks = QList<quint16>() );
//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<Boot2Info> 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 );

View File

@ -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;

View File

@ -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

View File

@ -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<NusJob> jobs )
void NusDownloader::GetTitles( const QList<NusJob> &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

View File

@ -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<NusJob> jobs );
void GetTitle( const NusJob &job );
void GetTitles( const QList<NusJob> &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 );

View File

@ -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++ )

View File

@ -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();

View File

@ -4,7 +4,7 @@
#include <iostream>
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;

View File

@ -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

View File

@ -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 ) )

View File

@ -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 ];

View File

@ -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() )

View File

@ -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

View File

@ -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();
}

View File

@ -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 ( <cid>.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

View File

@ -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() ) );

View File

@ -245,6 +245,9 @@
<property name="text">
<string>Import Wad</string>
</property>
<property name="shortcut">
<string>Ctrl+I</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>