mirror of
https://github.com/martravi/wiiqt.git
synced 2024-11-22 17:19:18 +01:00
* 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:
parent
0f506a205d
commit
dfcd1bed60
@ -47,8 +47,12 @@ bool NandBin::SetPath( const QString &path )
|
|||||||
return ret;
|
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 )
|
if( keys.size() != 0x400 || first8.size() != 0x108000 )
|
||||||
{
|
{
|
||||||
qWarning() << "NandBin::CreateNew -> bad sizes" << hex << keys.size() << first8.size();
|
qWarning() << "NandBin::CreateNew -> bad sizes" << hex << keys.size() << first8.size();
|
||||||
@ -256,7 +260,7 @@ bool NandBin::AddChildren( QTreeWidgetItem *parent, quint16 entry )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NandBin::FstName( fst_t fst )
|
const QString NandBin::FstName( fst_t fst )
|
||||||
{
|
{
|
||||||
QByteArray ba( (char*)fst.filename, 0xc );
|
QByteArray ba( (char*)fst.filename, 0xc );
|
||||||
QString ret = QString( ba );
|
QString ret = QString( ba );
|
||||||
@ -294,7 +298,7 @@ bool NandBin::ExtractFST( quint16 entry, const QString &path, bool singleFile )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandBin::ExtractDir( fst_t fst, QString parent )
|
bool NandBin::ExtractDir( fst_t fst, const QString &parent )
|
||||||
{
|
{
|
||||||
//qDebug() << "NandBin::ExtractDir(" << parent << ")";
|
//qDebug() << "NandBin::ExtractDir(" << parent << ")";
|
||||||
QByteArray ba( (char*)fst.filename, 0xc );
|
QByteArray ba( (char*)fst.filename, 0xc );
|
||||||
@ -316,7 +320,7 @@ bool NandBin::ExtractDir( fst_t fst, QString parent )
|
|||||||
return true;
|
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 );
|
QByteArray ba( (char*)fst.filename, 0xc );
|
||||||
QString filename( ba );
|
QString filename( ba );
|
||||||
@ -336,7 +340,7 @@ bool NandBin::ExtractFile( fst_t fst, QString parent )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandBin::InitNand( QIcon dirs, QIcon files )
|
bool NandBin::InitNand( const QIcon &dirs, const QIcon &files )
|
||||||
{
|
{
|
||||||
fstInited = false;
|
fstInited = false;
|
||||||
memset( (void*)&fsts, 0, sizeof( fst_t ) * 0x17ff );
|
memset( (void*)&fsts, 0, sizeof( fst_t ) * 0x17ff );
|
||||||
@ -525,7 +529,7 @@ bool NandBin::GetKey( int type )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray NandBin::ReadKeyfile( QString path, quint8 type )
|
const QByteArray NandBin::ReadKeyfile( const QString &path, quint8 type )
|
||||||
{
|
{
|
||||||
QByteArray retval;
|
QByteArray retval;
|
||||||
QFile f( path );
|
QFile f( path );
|
||||||
@ -688,7 +692,7 @@ quint16 NandBin::GetFAT( quint16 fat_entry )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray NandBin::GetPage( quint32 pageNo, bool withEcc )
|
const QByteArray NandBin::GetPage( quint32 pageNo, bool withEcc )
|
||||||
{
|
{
|
||||||
//qDebug() << "NandBin::GetPage( " << hex << pageNo << ", " << withEcc << " )";
|
//qDebug() << "NandBin::GetPage( " << hex << pageNo << ", " << withEcc << " )";
|
||||||
quint32 n_pagelen[] = { 0x800, 0x840, 0x840 };
|
quint32 n_pagelen[] = { 0x800, 0x840, 0x840 };
|
||||||
@ -704,7 +708,7 @@ QByteArray NandBin::GetPage( quint32 pageNo, bool withEcc )
|
|||||||
return page;
|
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;
|
//qDebug() << "NandBin::GetCluster" << hex << cluster_entry;
|
||||||
quint32 n_clusterlen[] = { 0x4000, 0x4200, 0x4200 };
|
quint32 n_clusterlen[] = { 0x4000, 0x4200, 0x4200 };
|
||||||
@ -746,7 +750,7 @@ QByteArray NandBin::GetCluster( quint16 cluster_entry, bool decrypt )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray NandBin::GetFile( quint16 entry )
|
const QByteArray NandBin::GetFile( quint16 entry )
|
||||||
{
|
{
|
||||||
fst_t fst = GetFST( entry );
|
fst_t fst = GetFST( entry );
|
||||||
if( !fst.filename[ 0 ] )//something is amiss, better quit now
|
if( !fst.filename[ 0 ] )//something is amiss, better quit now
|
||||||
@ -754,7 +758,7 @@ QByteArray NandBin::GetFile( quint16 entry )
|
|||||||
return GetFile( fst );
|
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 );
|
//qDebug() << "NandBin::GetFile" << QByteArray( (const char*)fst_.filename, 12 );
|
||||||
if( !fst_.size )
|
if( !fst_.size )
|
||||||
@ -1014,7 +1018,7 @@ QTreeWidgetItem *NandBin::ItemFromEntry( const QString &i, QTreeWidgetItem *pare
|
|||||||
return NULL;
|
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 )
|
if( data.size() != 0x4000 )
|
||||||
{
|
{
|
||||||
@ -1047,7 +1051,7 @@ bool NandBin::WriteCluster( quint32 pageNo, const QByteArray data, const QByteAr
|
|||||||
return true;
|
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";
|
//qDebug() << "NandBin::WriteDecryptedCluster";
|
||||||
QByteArray hmac = spare.Get_hmac_data( data, fst.uid, (const unsigned char *)&fst.filename, fst.fst_pos, fst.x3, idx );
|
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 );
|
return WriteCluster( pageNo, encData, hmac );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandBin::WritePage( quint32 pageNo, const QByteArray data )
|
bool NandBin::WritePage( quint32 pageNo, const QByteArray &data )
|
||||||
{
|
{
|
||||||
//return true;
|
//return true;
|
||||||
#ifndef NAND_BIN_CAN_WRITE
|
#ifndef NAND_BIN_CAN_WRITE
|
||||||
@ -1335,7 +1339,7 @@ bool NandBin::DeleteItem( QTreeWidgetItem *item )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandBin::SetData( const QString &path, const QByteArray data )
|
bool NandBin::SetData( const QString &path, const QByteArray &data )
|
||||||
{
|
{
|
||||||
QTreeWidgetItem *i = ItemFromPath( path );
|
QTreeWidgetItem *i = ItemFromPath( path );
|
||||||
if( !i )
|
if( !i )
|
||||||
@ -1355,7 +1359,7 @@ bool NandBin::SetData( const QString &path, const QByteArray data )
|
|||||||
return SetData( idx, 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 ];
|
fst_t fst = fsts[ idx ];
|
||||||
qDebug() << "NandBin::SetData" << FstName( fst );
|
qDebug() << "NandBin::SetData" << FstName( fst );
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
//keys should be a 0x400 byte array containing a keys.bin from bootmii
|
//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
|
//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
|
//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
|
//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
|
//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
|
//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
|
//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
|
//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
|
//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
|
//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 );
|
void SetFixNamesForFAT( bool fix = true );
|
||||||
|
|
||||||
//returns the data that makes up the file of a given entry#
|
//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
|
//get data for a given path
|
||||||
@ -113,7 +113,7 @@ public:
|
|||||||
const QList<Boot2Info> Boot2Infos();
|
const QList<Boot2Info> Boot2Infos();
|
||||||
quint8 Boot1Version();
|
quint8 Boot1Version();
|
||||||
|
|
||||||
QByteArray GetPage( quint32 pageNo, bool withEcc = false );
|
const QByteArray GetPage( quint32 pageNo, bool withEcc = false );
|
||||||
|
|
||||||
//create new entry
|
//create new entry
|
||||||
//returns the index of the entry on success, or 0 on error
|
//returns the index of the entry on success, or 0 on error
|
||||||
@ -123,10 +123,10 @@ public:
|
|||||||
bool Delete( const QString &path );
|
bool Delete( const QString &path );
|
||||||
|
|
||||||
//sets the data for a given file ( overwrites existing data )
|
//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
|
//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 )
|
//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 )
|
// 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 );
|
int GetDumpType( quint64 fileSize );
|
||||||
bool GetKey( int type );
|
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();
|
qint32 FindSuperblock();
|
||||||
quint16 GetFAT( quint16 fat_entry );
|
quint16 GetFAT( quint16 fat_entry );
|
||||||
fst_t GetFST( quint16 entry );
|
fst_t GetFST( quint16 entry );
|
||||||
QByteArray GetCluster( quint16 cluster_entry, bool decrypt = true );
|
const QByteArray GetCluster( quint16 cluster_entry, bool decrypt = true );
|
||||||
QByteArray GetFile( fst_t fst );
|
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 ExtractFST( quint16 entry, const QString &path, bool singleFile = false );
|
||||||
bool ExtractDir( fst_t fst, QString parent );
|
bool ExtractDir( fst_t fst, const QString &parent );
|
||||||
bool ExtractFile( fst_t fst, 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);
|
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
|
//holds info about boot1 & 2
|
||||||
Blocks0to7 bootBlocks;
|
Blocks0to7 bootBlocks;
|
||||||
|
|
||||||
bool WriteCluster( quint32 pageNo, const QByteArray data, const QByteArray hmac );
|
bool WriteCluster( quint32 pageNo, const QByteArray &data, const QByteArray &hmac );
|
||||||
bool WriteDecryptedCluster( quint32 pageNo, const QByteArray data, fst_t fst, quint16 idx );
|
bool WriteDecryptedCluster( quint32 pageNo, const QByteArray &data, fst_t fst, quint16 idx );
|
||||||
bool WritePage( quint32 pageNo, const QByteArray data );
|
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 );
|
quint16 CreateNode( const QString &name, quint32 uid, quint16 gid, quint8 attr, quint8 user_perm, quint8 group_perm, quint8 other_perm );
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ QByteArray NandDump::GetSettingTxt()
|
|||||||
return GetFile( "/title/00000001/00000002/data/setting.txt" );
|
return GetFile( "/title/00000001/00000002/data/setting.txt" );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandDump::SetSettingTxt( const QByteArray ba )
|
bool NandDump::SetSettingTxt( const QByteArray &ba )
|
||||||
{
|
{
|
||||||
if( basePath.isEmpty() )
|
if( basePath.isEmpty() )
|
||||||
return false;
|
return false;
|
||||||
@ -163,7 +163,7 @@ const QByteArray NandDump::GetFile( const QString &path )
|
|||||||
}
|
}
|
||||||
|
|
||||||
//write some file to the nand
|
//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( "/" ) )
|
if( basePath.isEmpty() || !path.startsWith( "/" ) )
|
||||||
return false;
|
return false;
|
||||||
@ -181,7 +181,7 @@ void NandDump::DeleteData( const QString & path )
|
|||||||
QFile::remove( basePath + path );
|
QFile::remove( basePath + path );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandDump::InstallTicket( const QByteArray ba, quint64 tid )
|
bool NandDump::InstallTicket( const QByteArray &ba, quint64 tid )
|
||||||
{
|
{
|
||||||
Ticket t( ba );
|
Ticket t( ba );
|
||||||
if( t.Tid() != tid )
|
if( t.Tid() != tid )
|
||||||
@ -208,7 +208,7 @@ bool NandDump::InstallTicket( const QByteArray ba, quint64 tid )
|
|||||||
return SaveData( start, p );
|
return SaveData( start, p );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandDump::InstallTmd( const QByteArray ba, quint64 tid )
|
bool NandDump::InstallTmd( const QByteArray &ba, quint64 tid )
|
||||||
{
|
{
|
||||||
Tmd t( ba );
|
Tmd t( ba );
|
||||||
if( t.Tid() != tid )
|
if( t.Tid() != tid )
|
||||||
@ -225,7 +225,7 @@ bool NandDump::InstallTmd( const QByteArray ba, quint64 tid )
|
|||||||
return SaveData( start, p );
|
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;
|
QByteArray h = hash;
|
||||||
if( h.isEmpty() )
|
if( h.isEmpty() )
|
||||||
@ -245,7 +245,7 @@ bool NandDump::InstallSharedContent( const QByteArray ba, const QByteArray hash
|
|||||||
return true;
|
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' ) );
|
QString p = QString( "%1" ).arg( tid, 16, 16, QChar( '0' ) );
|
||||||
p.insert( 8 ,"/" );
|
p.insert( 8 ,"/" );
|
||||||
@ -322,7 +322,7 @@ bool NandDump::RecurseDeleteFolder( const QString &path )
|
|||||||
return QDir().rmdir( path );
|
return QDir().rmdir( path );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandDump::InstallNusItem( NusJob job )
|
bool NandDump::InstallNusItem( const NusJob &job )
|
||||||
{
|
{
|
||||||
if( !job.tid || job.data.size() < 3 )
|
if( !job.tid || job.data.size() < 3 )
|
||||||
{
|
{
|
||||||
@ -345,13 +345,13 @@ bool NandDump::InstallNusItem( NusJob job )
|
|||||||
if( !QFileInfo( path ).exists() && !QDir().mkpath( path ) )
|
if( !QFileInfo( path ).exists() && !QDir().mkpath( path ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QByteArray ba = job.data.takeFirst();
|
QByteArray ba = job.data.at( 0 );
|
||||||
if( !InstallTmd( ba, job.tid ) )
|
if( !InstallTmd( ba, job.tid ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Tmd t( ba );
|
Tmd t( ba );
|
||||||
|
|
||||||
ba = job.data.takeFirst();
|
ba = job.data.at( 1 );
|
||||||
Ticket ti( ba );
|
Ticket ti( ba );
|
||||||
if( !InstallTicket( ba, job.tid ) )
|
if( !InstallTicket( ba, job.tid ) )
|
||||||
{
|
{
|
||||||
@ -372,14 +372,14 @@ bool NandDump::InstallNusItem( NusJob job )
|
|||||||
QByteArray decData;
|
QByteArray decData;
|
||||||
if( job.decrypt )
|
if( job.decrypt )
|
||||||
{
|
{
|
||||||
decData = job.data.takeFirst();
|
decData = job.data.at( i + 2 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//seems like a waste to keep setting the key, but for now im doing it this way
|
//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
|
//so multiple objects can be decrypting titles at the same time
|
||||||
AesSetKey( ti.DecryptedKey() );
|
AesSetKey( ti.DecryptedKey() );
|
||||||
QByteArray paddedEncrypted = PaddedByteArray( job.data.takeFirst(), 0x40 );
|
QByteArray paddedEncrypted = PaddedByteArray( job.data.at( i + 2 ), 0x40 );
|
||||||
decData = AesDecrypt( i, paddedEncrypted );
|
decData = AesDecrypt( i, paddedEncrypted );
|
||||||
decData.resize( t.Size( i ) );
|
decData.resize( t.Size( i ) );
|
||||||
QByteArray realHash = GetSha1( decData );
|
QByteArray realHash = GetSha1( decData );
|
||||||
@ -448,7 +448,7 @@ bool NandDump::InstallWad( Wad wad )
|
|||||||
Tmd t( ba );
|
Tmd t( ba );
|
||||||
|
|
||||||
ba = wad.getTik();
|
ba = wad.getTik();
|
||||||
Ticket ti( ba );
|
//Ticket ti( ba );
|
||||||
if( !InstallTicket( ba, wad.Tid() ) )
|
if( !InstallTicket( ba, wad.Tid() ) )
|
||||||
{
|
{
|
||||||
AbortInstalling( 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 << ")";
|
qWarning() << "NandDump::SetReplaceString(" << ch << "," << replaceWith << ")";
|
||||||
QRegExp re( "[^/?*:;{}\\]+" );
|
QRegExp re( "[^/?*:;{}\\]+" );
|
||||||
@ -749,7 +749,7 @@ SaveGame NandDump::GetSaveData( quint64 tid )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandDump::InstallSave( SaveGame save )
|
bool NandDump::InstallSave( const SaveGame &save )
|
||||||
{
|
{
|
||||||
if( basePath.isEmpty() || !IsValidSave( save ) )
|
if( basePath.isEmpty() || !IsValidSave( save ) )
|
||||||
return false;
|
return false;
|
||||||
@ -791,7 +791,7 @@ bool NandDump::InstallSave( SaveGame save )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NandDump::IsValidSave( SaveGame save )
|
bool NandDump::IsValidSave( const SaveGame &save )
|
||||||
{
|
{
|
||||||
if( !save.tid || save.entries.size() != save.isFile.size() )
|
if( !save.tid || save.entries.size() != save.isFile.size() )
|
||||||
return false;
|
return false;
|
||||||
|
@ -39,7 +39,7 @@ public:
|
|||||||
//giving an empty replacement string will remove that entry and all the actual character will be used in paths
|
//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
|
//! 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
|
//! 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
|
//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 )
|
// 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
|
//installs a title to the nand dump from an already existing NusJob
|
||||||
//returns false if something went wrong
|
//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
|
//installs a title to the nand dump from a wad
|
||||||
//returns false if something went wrong
|
//returns false if something went wrong
|
||||||
@ -76,13 +76,13 @@ public:
|
|||||||
|
|
||||||
//overloads GetFile() with "/title/00000001/00000002/data/setting.txt"
|
//overloads GetFile() with "/title/00000001/00000002/data/setting.txt"
|
||||||
QByteArray GetSettingTxt();
|
QByteArray GetSettingTxt();
|
||||||
bool SetSettingTxt( const QByteArray ba );
|
bool SetSettingTxt( const QByteArray &ba );
|
||||||
|
|
||||||
//reads a file from the nand and returns it as a qbytearray
|
//reads a file from the nand and returns it as a qbytearray
|
||||||
const QByteArray GetFile( const QString &path );
|
const QByteArray GetFile( const QString &path );
|
||||||
|
|
||||||
//tries to write the given bytearray to a file of the given 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
|
//expects a file, not directory
|
||||||
void DeleteData( const QString & path );
|
void DeleteData( const QString & path );
|
||||||
@ -92,7 +92,7 @@ public:
|
|||||||
SaveGame GetSaveData( quint64 tid );
|
SaveGame GetSaveData( quint64 tid );
|
||||||
|
|
||||||
//installs a save to the nand
|
//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
|
//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
|
// 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 );
|
const QString FromNandPath( const QString &path );
|
||||||
|
|
||||||
//sanity check a save object
|
//sanity check a save object
|
||||||
static bool IsValidSave( SaveGame save );
|
static bool IsValidSave( const SaveGame &save );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -132,10 +132,10 @@ private:
|
|||||||
bool cmDirty;
|
bool cmDirty;
|
||||||
bool FlushContentMap();
|
bool FlushContentMap();
|
||||||
|
|
||||||
bool InstallTicket( const QByteArray ba, quint64 tid );
|
bool InstallTicket( const QByteArray &ba, quint64 tid );
|
||||||
bool InstallTmd( const QByteArray ba, quint64 tid );
|
bool InstallTmd( const QByteArray &ba, quint64 tid );
|
||||||
bool InstallSharedContent( const QByteArray ba, const QByteArray hash = QByteArray() );
|
bool InstallSharedContent( const QByteArray &ba, const QByteArray &hash = QByteArray() );
|
||||||
bool InstallPrivateContent( const QByteArray ba, quint64 tid, const QString &cid );
|
bool InstallPrivateContent( const QByteArray &ba, quint64 tid, const QString &cid );
|
||||||
void AbortInstalling( quint64 tid );
|
void AbortInstalling( quint64 tid );
|
||||||
|
|
||||||
//go through and delete all the stuff in a given folder and then delete the folder itself
|
//go through and delete all the stuff in a given folder and then delete the folder itself
|
||||||
|
@ -17,7 +17,7 @@ void NusDownloader::SetCachePath( const QString &cPath )
|
|||||||
}
|
}
|
||||||
|
|
||||||
//add a single job to the list
|
//add a single job to the list
|
||||||
void NusDownloader::GetTitle( NusJob job )
|
void NusDownloader::GetTitle( const NusJob &job )
|
||||||
{
|
{
|
||||||
//qDebug() << "NusDownloader::GetTitle";
|
//qDebug() << "NusDownloader::GetTitle";
|
||||||
jobList.append( job );
|
jobList.append( job );
|
||||||
@ -32,7 +32,7 @@ void NusDownloader::GetTitle( NusJob job )
|
|||||||
}
|
}
|
||||||
|
|
||||||
//add a list of jobs to the list
|
//add a list of jobs to the list
|
||||||
void NusDownloader::GetTitles( QList<NusJob> jobs )
|
void NusDownloader::GetTitles( const QList<NusJob> &jobs )
|
||||||
{
|
{
|
||||||
//qDebug() << "NusDownloader::GetTitles";
|
//qDebug() << "NusDownloader::GetTitles";
|
||||||
jobList.append( jobs );
|
jobList.append( jobs );
|
||||||
@ -140,7 +140,7 @@ QByteArray NusDownloader::GetDataFromCache( downloadJob job )
|
|||||||
}
|
}
|
||||||
|
|
||||||
//load the tmd and try to get the ticket
|
//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();
|
//qDebug() << "NusDownloader::ReadTmdAndGetTicket" << hex << ba.size();
|
||||||
curTmd = Tmd( ba );
|
curTmd = Tmd( ba );
|
||||||
@ -227,7 +227,7 @@ bool NusDownloader::SaveDataToCache( const QString &path, const QByteArray &stuf
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadJob NusDownloader::CreateJob( QString name, quint16 index )
|
downloadJob NusDownloader::CreateJob( const QString &name, quint16 index )
|
||||||
{
|
{
|
||||||
downloadJob r;
|
downloadJob r;
|
||||||
r.tid = QString( "%1" ).arg( currentJob.tid, 16, 16, QChar( '0' ) );
|
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 > NusDownloader::List42e()
|
||||||
{
|
{
|
||||||
QMap< quint64, quint16 > titles = List41e();
|
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( 0x100000009ull, 0x30a ); // IOS9
|
||||||
titles.insert( 0x10000000cull, 0x10d ); // IOS12
|
titles.insert( 0x10000000cull, 0x10d ); // IOS12
|
||||||
titles.insert( 0x10000000dull, 0x111 ); // IOS13
|
titles.insert( 0x10000000dull, 0x111 ); // IOS13
|
||||||
@ -1107,7 +1107,6 @@ QMap< quint64, quint16 > NusDownloader::List31u()
|
|||||||
{
|
{
|
||||||
QMap< quint64, quint16 > titles = List30u();
|
QMap< quint64, quint16 > titles = List30u();
|
||||||
//( from rockband2 )
|
//( from rockband2 )
|
||||||
//titles.insert( 0x100000001ull, 2 );//boot2
|
|
||||||
titles.insert( 0x100000002ull, 257 );//sys menu
|
titles.insert( 0x100000002ull, 257 );//sys menu
|
||||||
titles.insert( 0x10000000eull, 262 );//14v262 - should actually be 14v257 but that version isnt available on NUS
|
titles.insert( 0x10000000eull, 262 );//14v262 - should actually be 14v257 but that version isnt available on NUS
|
||||||
titles.insert( 0x10000001eull, 1040 );//30v1040
|
titles.insert( 0x10000001eull, 1040 );//30v1040
|
||||||
|
@ -50,8 +50,8 @@ public:
|
|||||||
void SetCachePath( const QString &cPath = QString() );
|
void SetCachePath( const QString &cPath = QString() );
|
||||||
|
|
||||||
//get a title from NUS. if version is 0, get the latest one
|
//get a title from NUS. if version is 0, get the latest one
|
||||||
void GetTitle( NusJob job );
|
void GetTitle( const NusJob &job );
|
||||||
void GetTitles( QList<NusJob> jobs );
|
void GetTitles( const QList<NusJob> &jobs );
|
||||||
void Get( quint64 tid, bool decrypt, quint16 version = TITLE_LATEST_VERSION );
|
void Get( quint64 tid, bool decrypt, quint16 version = TITLE_LATEST_VERSION );
|
||||||
|
|
||||||
//TODO! this function is far from complete
|
//TODO! this function is far from complete
|
||||||
@ -108,7 +108,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
//helper function to create a job
|
//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
|
//path on the PC to try and get files from and save to to avoid downloading deplicates from NUS
|
||||||
QString cachePath;
|
QString cachePath;
|
||||||
@ -121,7 +121,7 @@ private:
|
|||||||
bool SaveDataToCache( const QString &path, const QByteArray &stuff );
|
bool SaveDataToCache( const QString &path, const QByteArray &stuff );
|
||||||
|
|
||||||
//check the tmd and try to ticket
|
//check the tmd and try to ticket
|
||||||
void ReadTmdAndGetTicket( QByteArray ba );
|
void ReadTmdAndGetTicket( const QByteArray &ba );
|
||||||
|
|
||||||
bool DecryptCheckHashAndAppendData( const QByteArray &encData, quint16 idx );
|
bool DecryptCheckHashAndAppendData( const QByteArray &encData, quint16 idx );
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "sharedcontentmap.h"
|
#include "sharedcontentmap.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
SharedContentMap::SharedContentMap( QByteArray old )
|
SharedContentMap::SharedContentMap( const QByteArray &old )
|
||||||
{
|
{
|
||||||
data = old;
|
data = old;
|
||||||
if( data.size() )
|
if( data.size() )
|
||||||
@ -79,7 +79,7 @@ bool SharedContentMap::Check( const QString &path )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SharedContentMap::GetAppFromHash( QByteArray hash )
|
QString SharedContentMap::GetAppFromHash( const QByteArray &hash )
|
||||||
{
|
{
|
||||||
quint32 cnt = data.size() / 28;
|
quint32 cnt = data.size() / 28;
|
||||||
for( quint32 i = 0; i < cnt; i++ )
|
for( quint32 i = 0; i < cnt; i++ )
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
class SharedContentMap
|
class SharedContentMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SharedContentMap( QByteArray old = QByteArray() );
|
SharedContentMap( const QByteArray &old = QByteArray() );
|
||||||
|
|
||||||
//checks that the content map is sane
|
//checks that the content map is sane
|
||||||
//size should be correct, contents should be in numerical order
|
//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.
|
//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
|
//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
|
//gets the first available u32 that is not already in the map and returns it as a string
|
||||||
QString GetNextEmptyCid();
|
QString GetNextEmptyCid();
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
Tmd::Tmd( QByteArray stuff )
|
Tmd::Tmd( const QByteArray &stuff )
|
||||||
{
|
{
|
||||||
data = stuff;
|
data = stuff;
|
||||||
p_tmd = NULL;
|
p_tmd = NULL;
|
||||||
@ -102,7 +102,7 @@ QByteArray Tmd::Hash( quint16 i )
|
|||||||
return QByteArray( (const char*)&p_tmd->contents[ i ].hash, 20 );
|
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 )
|
if( !p_tmd || cid >= qFromBigEndian( p_tmd->num_contents ) || hash.size() != 20 )
|
||||||
return false;
|
return false;
|
||||||
@ -234,7 +234,7 @@ bool Tmd::FakeSign()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ticket::Ticket( QByteArray stuff )
|
Ticket::Ticket( const QByteArray &stuff )
|
||||||
{
|
{
|
||||||
data = stuff;
|
data = stuff;
|
||||||
p_tik = NULL;
|
p_tik = NULL;
|
||||||
@ -451,7 +451,7 @@ static int get_sub_len( const quint8 *sub )
|
|||||||
return -ERROR_SUB_TYPE;
|
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 ];
|
quint8 correct[ 0x200 ], x[ 0x200 ];
|
||||||
static const quint8 ber[ 16 ] = { 0x00,0x30,0x21,0x30,0x09,0x06,0x05,0x2b,
|
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;
|
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;
|
quint32 type;
|
||||||
type = BE32( sig ) - 0x10000;
|
type = BE32( sig ) - 0x10000;
|
||||||
@ -528,7 +528,7 @@ static const quint8* find_cert_in_chain( const quint8 *sub, const quint8 *cert,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int check_cert_chain( const QByteArray data )
|
int check_cert_chain( const QByteArray &data )
|
||||||
{
|
{
|
||||||
int cert_err;
|
int cert_err;
|
||||||
const quint8* key;
|
const quint8* key;
|
||||||
|
@ -139,7 +139,7 @@ typedef struct _cert_ecdsa {
|
|||||||
class Ticket
|
class Ticket
|
||||||
{
|
{
|
||||||
public:
|
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
|
//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
|
//the pointer should be good until "data" is changed
|
||||||
@ -173,7 +173,7 @@ private:
|
|||||||
class Tmd
|
class Tmd
|
||||||
{
|
{
|
||||||
public:
|
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
|
//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
|
//the pointer should be good until "data" is changed
|
||||||
@ -205,7 +205,7 @@ public:
|
|||||||
bool SetVersion( quint16 v );
|
bool SetVersion( quint16 v );
|
||||||
bool SetType( quint16 i, quint16 type );
|
bool SetType( quint16 i, quint16 type );
|
||||||
bool SetSize( quint16 i, quint32 size );
|
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 SetIOS( quint64 ios );
|
||||||
bool SetAhb( bool remove = true );
|
bool SetAhb( bool remove = true );
|
||||||
bool SetDiskAccess( bool allow = true );
|
bool SetDiskAccess( bool allow = true );
|
||||||
@ -249,6 +249,6 @@ enum
|
|||||||
|
|
||||||
//checks the signatures in a tmd/ticket
|
//checks the signatures in a tmd/ticket
|
||||||
//returns 1 of the above enums
|
//returns 1 of the above enums
|
||||||
int check_cert_chain( const QByteArray data );
|
int check_cert_chain( const QByteArray &data );
|
||||||
|
|
||||||
#endif // TIKTMD_H
|
#endif // TIKTMD_H
|
||||||
|
@ -3,10 +3,6 @@
|
|||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
|
|
||||||
//QString currentDir;
|
|
||||||
//QString cachePath = "./NUS_cache";
|
|
||||||
//QString nandPath = "./dump";
|
|
||||||
|
|
||||||
char ascii( char s ) {
|
char ascii( char s ) {
|
||||||
if ( s < 0x20 ) return '.';
|
if ( s < 0x20 ) return '.';
|
||||||
if ( s > 0x7E ) return '.';
|
if ( s > 0x7E ) return '.';
|
||||||
@ -92,20 +88,20 @@ QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo )
|
|||||||
return orig + padding;
|
return orig + padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray AesDecrypt( quint16 index, const QByteArray source )
|
QByteArray AesDecrypt( quint16 index, const QByteArray &source )
|
||||||
{
|
{
|
||||||
//qDebug() << "AesDecrypt" << hex << index << source.size();
|
//qDebug() << "AesDecrypt" << hex << index << source.size();
|
||||||
quint8 iv[ 16 ];
|
quint8 iv[ 16 ];
|
||||||
|
|
||||||
quint16 beidx = qFromBigEndian( index );
|
quint16 beidx = qFromBigEndian( index );
|
||||||
memset( iv, 0, 16 );
|
memset( &iv, 0, 16 );
|
||||||
memcpy( iv, &beidx, 2 );
|
memcpy( &iv, &beidx, 2 );
|
||||||
QByteArray ret( source.size(), '\0' );
|
QByteArray ret( source.size(), '\0' );
|
||||||
aes_decrypt( iv, (const quint8*)source.data(), (quint8*)ret.data(), source.size() );
|
aes_decrypt( (quint8*)&iv, (const quint8*)source.data(), (quint8*)ret.data(), source.size() );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray AesEncrypt( quint16 index, const QByteArray source )
|
QByteArray AesEncrypt( quint16 index, const QByteArray &source )
|
||||||
{
|
{
|
||||||
static quint8 iv[ 16 ];
|
static quint8 iv[ 16 ];
|
||||||
|
|
||||||
@ -117,13 +113,13 @@ QByteArray AesEncrypt( quint16 index, const QByteArray source )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AesSetKey( const QByteArray key )
|
void AesSetKey( const QByteArray &key )
|
||||||
{
|
{
|
||||||
// qDebug() << "AesSetKey()" << key.toHex();
|
// qDebug() << "AesSetKey()" << key.toHex();
|
||||||
aes_set_key( (const quint8*)key.data() );
|
aes_set_key( (const quint8*)key.data() );
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray GetSha1( QByteArray stuff )
|
QByteArray GetSha1( const QByteArray &stuff )
|
||||||
{
|
{
|
||||||
SHA1Context sha;
|
SHA1Context sha;
|
||||||
SHA1Reset( &sha );
|
SHA1Reset( &sha );
|
||||||
@ -157,7 +153,7 @@ QByteArray ReadFile( const QString &path )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteFile( const QString &path, const QByteArray ba )
|
bool WriteFile( const QString &path, const QByteArray &ba )
|
||||||
{
|
{
|
||||||
QFile file( path );
|
QFile file( path );
|
||||||
if( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
|
if( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
|
||||||
|
@ -16,11 +16,11 @@ void hexdump12( const void *d, int len );
|
|||||||
void hexdump12( const QByteArray &d, int from = 0, int len = -1 );
|
void hexdump12( const QByteArray &d, int from = 0, int len = -1 );
|
||||||
|
|
||||||
//simplified functions for crypto shit
|
//simplified functions for crypto shit
|
||||||
void AesSetKey( const QByteArray key );
|
void AesSetKey( const QByteArray &key );
|
||||||
QByteArray AesDecrypt( quint16 index, const QByteArray source );
|
QByteArray AesDecrypt( quint16 index, const QByteArray &source );
|
||||||
QByteArray AesEncrypt( 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
|
//get a padded version of the given buffer
|
||||||
QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo );
|
QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo );
|
||||||
@ -29,16 +29,7 @@ QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo );
|
|||||||
QByteArray ReadFile( const QString &path );
|
QByteArray ReadFile( const QString &path );
|
||||||
|
|
||||||
//save a file to disc
|
//save a file to disc
|
||||||
bool WriteFile( const QString &path, const QByteArray ba );
|
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;
|
|
||||||
|
|
||||||
#define CERTS_DAT_SIZE 2560
|
#define CERTS_DAT_SIZE 2560
|
||||||
extern const quint8 certs_dat[ CERTS_DAT_SIZE ];
|
extern const quint8 certs_dat[ CERTS_DAT_SIZE ];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "uidmap.h"
|
#include "uidmap.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
UIDmap::UIDmap( const QByteArray old )
|
UIDmap::UIDmap( const QByteArray &old )
|
||||||
{
|
{
|
||||||
data = old;
|
data = old;
|
||||||
if( data.isEmpty() )
|
if( data.isEmpty() )
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
class UIDmap
|
class UIDmap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UIDmap( const QByteArray old = QByteArray() );
|
UIDmap( const QByteArray &old = QByteArray() );
|
||||||
~UIDmap();
|
~UIDmap();
|
||||||
|
|
||||||
//makes sure there are the default entries in the map and that the entries are sane
|
//makes sure there are the default entries in the map and that the entries are sane
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
static QByteArray globalCert;
|
static QByteArray globalCert;
|
||||||
|
|
||||||
Wad::Wad( const QByteArray stuff )
|
Wad::Wad( const QByteArray &stuff )
|
||||||
{
|
{
|
||||||
ok = false;
|
ok = false;
|
||||||
if( stuff.size() < 0x80 )//less than this and there is definitely nothing there
|
if( stuff.size() < 0x80 )//less than this and there is definitely nothing there
|
||||||
@ -132,7 +132,7 @@ Wad::Wad( const QByteArray stuff )
|
|||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Wad::Wad( QList< QByteArray > stuff, bool encrypted )
|
Wad::Wad( const QList< QByteArray > &stuff, bool encrypted )
|
||||||
{
|
{
|
||||||
if( stuff.size() < 3 )
|
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;
|
certData = stuff;
|
||||||
}
|
}
|
||||||
@ -238,14 +238,14 @@ quint32 Wad::content_count()
|
|||||||
return partsEnc.size();
|
return partsEnc.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wad::Err( QString str )
|
void Wad::Err( const QString &str )
|
||||||
{
|
{
|
||||||
ok = false;
|
ok = false;
|
||||||
errStr = str;
|
errStr = str;
|
||||||
qWarning() << "Wad::Error" << 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();
|
//qDebug() << "Wad::Data" << hex << magicWord << footer.size();
|
||||||
if( !partsEnc.size() || tmdData.isEmpty() || tikData.isEmpty() || ( certData.isEmpty() && globalCert.isEmpty() ) )
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Wad::WadName( QString path )
|
QString Wad::WadName( const QString &path )
|
||||||
{
|
{
|
||||||
if( !tmdData.size() )
|
if( !tmdData.size() )
|
||||||
{
|
{
|
||||||
@ -348,7 +348,7 @@ QString Wad::WadName( QString path )
|
|||||||
return WadName( t.Tid(), t.Version(), 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 type = (quint32)( ( tid >> 32 ) & 0xffffffff );
|
||||||
quint32 base = (quint32)( tid & 0xffffffff );
|
quint32 base = (quint32)( tid & 0xffffffff );
|
||||||
@ -635,7 +635,7 @@ bool Wad::SetDiskAccess( bool allow )
|
|||||||
return true;
|
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() )
|
if( idx >= partsEnc.size() || !tmdData.size() || !tikData.size() )
|
||||||
{
|
{
|
||||||
@ -675,3 +675,10 @@ bool Wad::ReplaceContent( quint16 idx, const QByteArray ba )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray FromPartList( const QList< QByteArray > &stuff, bool isEncrypted = true )
|
||||||
|
{
|
||||||
|
Wad wad( stuff, isEncrypted );
|
||||||
|
if( !wad.IsOk() )
|
||||||
|
return QByteArray();
|
||||||
|
return wad.Data();
|
||||||
|
}
|
||||||
|
24
WiiQt/wad.h
24
WiiQt/wad.h
@ -6,18 +6,18 @@ class Wad
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//create a wad instance from a bytearray containing a wad
|
//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.
|
//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
|
//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
|
//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
|
//check if this wad is valid
|
||||||
bool IsOk(){ return ok; }
|
bool IsOk(){ return ok; }
|
||||||
|
|
||||||
//set the cert for this wad
|
//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 )
|
//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();
|
quint64 Tid();
|
||||||
@ -36,7 +36,7 @@ public:
|
|||||||
|
|
||||||
//replace a content of this wad, update the size & hash in the tmd and sign it
|
//replace a content of this wad, update the size & hash in the tmd and sign it
|
||||||
//ba should be decrypted
|
//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
|
//add a new content to this wad and fakesign
|
||||||
//if the data is encrypted, set that arguement to true
|
//if the data is encrypted, set that arguement to true
|
||||||
@ -50,15 +50,21 @@ public:
|
|||||||
static void SetGlobalCert( const QByteArray &stuff );
|
static void SetGlobalCert( const QByteArray &stuff );
|
||||||
|
|
||||||
//pack a wad from the given directory
|
//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 );
|
static QByteArray FromDirectory( QDir dir );
|
||||||
|
|
||||||
//get a assembled wad from the list of parts
|
//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
|
//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
|
//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
|
//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
|
//get the tmd for the wad
|
||||||
const QByteArray getTmd();
|
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
|
//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
|
//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
|
//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
|
//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:
|
private:
|
||||||
bool ok;
|
bool ok;
|
||||||
@ -93,7 +99,7 @@ private:
|
|||||||
QByteArray tikData;
|
QByteArray tikData;
|
||||||
QByteArray certData;
|
QByteArray certData;
|
||||||
|
|
||||||
void Err( QString str );
|
void Err( const QString &str );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WAD_H
|
#endif // WAD_H
|
||||||
|
@ -343,7 +343,6 @@ void MainWindow::on_actionImportWad_triggered()
|
|||||||
ShowMessage( tr( "Wad data not ok" ) );;
|
ShowMessage( tr( "Wad data not ok" ) );;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = nand.InstallWad( wad );
|
bool ok = nand.InstallWad( wad );
|
||||||
if( ok )
|
if( ok )
|
||||||
ShowMessage( tr( "Installed %1 title to nand" ).arg( wad.WadName() ) );
|
ShowMessage( tr( "Installed %1 title to nand" ).arg( wad.WadName() ) );
|
||||||
|
@ -245,6 +245,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Import Wad</string>
|
<string>Import Wad</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+I</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user