split_tad 移植版:出力srlファイルを指定できるようにAPIを変更。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlToolsRED@57 7061adef-622a-194b-ae81-725974e89856
This commit is contained in:
nishikawa_takeshi 2008-12-04 02:36:05 +00:00
parent b9f04422fb
commit b7922c0dcb
7 changed files with 64 additions and 18 deletions

View File

@ -23,19 +23,23 @@ const u8 commonKey[] =
// ------------------------------------------------------ // ------------------------------------------------------
// tadŠOµ<EFBFBD>ˆ<EFBFBD>{‘Ì(split_tad_dev.pl ̈Ú<CB86>A) // tad外し処理本体
// ------------------------------------------------------ // ------------------------------------------------------
// //
// tad ファイルから srl(0番目のコンテンツ)を抜き出す // tad ファイルから srl(0番目のコンテンツ)を抜き出す
// (split_tad_dev.pl の移植)
//
// @arg [in] 入力 tad ファイル名
// @arg [out] 出力 srl ファイル名
// //
// @ret 成功したとき0 失敗したら負の値 // @ret 成功したとき0 失敗したら負の値
// //
int splitTad( System::String ^filename ) int splitTad( System::String ^tadpath, System::String ^srlpath )
{ {
FILE *fp = NULL; FILE *fp = NULL;
const char *pchFilename = const char *pchFilename =
(const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( filename ).ToPointer(); (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( tadpath ).ToPointer();
if( fopen_s( &fp, pchFilename, "rb" ) != NULL ) if( fopen_s( &fp, pchFilename, "rb" ) != NULL )
{ {
@ -84,23 +88,31 @@ int splitTad( System::String ^filename )
cli::array<System::Byte> ^tmd = subStr( fp, tmdOffset, tmdSize ); cli::array<System::Byte> ^tmd = subStr( fp, tmdOffset, tmdSize );
cli::array<System::Byte> ^content = subStr( fp, contentOffset, contentSize ); cli::array<System::Byte> ^content = subStr( fp, contentOffset, contentSize );
//saveFile( "cert.bin", subStr( fp, certOffset, certSize ) ); //saveFile( "cert.bin", subStr( fp, certOffset, certSize ) );
//saveFile( "crl.bin", subStr( fp, crlOffset, crlSize ) ); //saveFile( "crl.bin", subStr( fp, crlOffset, crlSize ) );
//saveFile( "ticket.bin", ticket ); //saveFile( "ticket.bin", ticket );
//saveFile( "tmd.bin", tmd ); //saveFile( "tmd.bin", tmd );
//saveFile( "meta.bin", subStr( fp, metaOffset, metaSize ) ); //saveFile( "meta.bin", subStr( fp, metaOffset, metaSize ) );
cli::array<System::Byte> ^titleKey = readTitleKey( ticket ); cli::array<System::Byte> ^title_key = readTitleKey( ticket );
cli::array<rcContentsInfo^> ^rci = readContentsInfo( tmd ); cli::array<rcContentsInfo^> ^rci = readContentsInfo( tmd );
dumpBytes( titleKey ); dumpBytes( title_key );
// 通常は tad は srl (コンテンツ No.0) しか含まないが
// マルチコンテンツ を含む場合のために No.1 以降も別ファイルとして保存する
// srl 名が out.srl のとき out_1.bin out_2.bin ... として出力する
System::String ^srl_dir = System::IO::Path::GetDirectoryName( srlpath ); // 格納ディレクトリ名
System::String ^srl_prefix = System::IO::Path::GetFileNameWithoutExtension( srlpath ); // 拡張子よりも前のファイル名
System::String ^srl_ext = System::IO::Path::GetExtension( srlpath ); // 拡張子
int result = 0;
u32 offset = 0; u32 offset = 0;
for each( rcContentsInfo ^ci in rci ) for each( rcContentsInfo ^ci in rci )
{ {
u32 size = roundUp( (u32)ci->size, 16 ); u32 size = roundUp( (u32)ci->size, 16 );
cli::array<System::Byte> ^enc_content_x = subStr( content, offset, size ); cli::array<System::Byte> ^enc_content_x = subStr( content, offset, size );
cli::array<System::Byte> ^content_x_iv = resizeBytes( pack16( reverseEndian(ci->idx) ), 14 ); // ビッグエンディアンにしておく cli::array<System::Byte> ^content_x_iv = resizeBytes( pack16( reverseEndian(ci->idx) ), 14 ); // ビッグエンディアンにしておく
cli::array<System::Byte> ^dec_content_x = decCBC( titleKey, content_x_iv, enc_content_x ); cli::array<System::Byte> ^dec_content_x = decCBC( title_key, content_x_iv, enc_content_x );
cli::array<System::Byte> ^dec_content = subStr( dec_content_x, 0, ci->size ); cli::array<System::Byte> ^dec_content = subStr( dec_content_x, 0, ci->size );
System::Security::Cryptography::SHA1 ^sha1 = gcnew System::Security::Cryptography::SHA1Managed(); System::Security::Cryptography::SHA1 ^sha1 = gcnew System::Security::Cryptography::SHA1Managed();
cli::array<System::Byte> ^hash = sha1->ComputeHash( dec_content ); cli::array<System::Byte> ^hash = sha1->ComputeHash( dec_content );
@ -115,13 +127,24 @@ int splitTad( System::String ^filename )
else else
{ {
printf( "hash mismatch\n" ); printf( "hash mismatch\n" );
result = -1; // エラーとする 中断はせず最後まで作成
}
//saveFile( "content_" + ci->idx.ToString() + ".encrypted.bin", enc_content_x );
//saveFile( "content_" + ci->idx.ToString() + ".bin", dec_content );
if( ci->idx == 0 )
{
saveFile( srlpath, dec_content ); // コンテンツ No.0 が srl にあたる
}
else
{
System::String ^tmppath = srl_dir + "\\" + srl_prefix + "_" + ci->idx.ToString() + ".bin";
saveFile( tmppath, dec_content );
} }
saveFile( "content_" + ci->idx.ToString() + ".encrypted.bin", enc_content_x );
saveFile( "content_" + ci->idx.ToString() + ".bin", dec_content );
offset += roundUp( size, 64 ); offset += roundUp( size, 64 );
} }
fclose( fp ); fclose( fp );
return 0; return result;
} }
// ------------------------------------------------------ // ------------------------------------------------------
@ -149,7 +172,7 @@ cli::array<System::Byte>^ readTitleKey( cli::array<System::Byte> ^ticket )
} }
catch (System::Exception ^ e) catch (System::Exception ^ e)
{ {
System::Console::WriteLine("Error: {0}", e->Message); System::Console::WriteLine("Exception in readTitleKey(): {0}", e->Message);
} }
return plain; return plain;
} }

View File

@ -9,13 +9,20 @@
// APIs // APIs
// ------------------------------------------------------ // ------------------------------------------------------
//
// tad ファイルから srl(0番目のコンテンツ)を抜き出す // tad ファイルから srl(0番目のコンテンツ)を抜き出す
// (split_tad_dev.pl の移植) // (split_tad_dev.pl の移植)
int splitTad( System::String ^filename ); //
// @arg [in] 入力 tad ファイルのパス
// @arg [out] 出力 srl ファイルのパス
//
// @ret 成功したとき0 失敗したら負の値
//
int splitTad( System::String ^tadpath, System::String ^srlpath );
// ------------------------------------------------------ // ------------------------------------------------------
// 内部処理用の構造体(宣言だけできないのでヘッダに置く) // 内部処理用の構造体(プロトタイプ宣言できないのでヘッダに置く)
// ------------------------------------------------------ // ------------------------------------------------------
// コンテンツ情報の構造体 // コンテンツ情報の構造体
@ -30,11 +37,11 @@ private:
public: public:
rcContentsInfo() rcContentsInfo()
{ {
this->h_cid = gcnew System::UInt32; this->h_cid = gcnew System::UInt32; // 解放の必要なし
this->h_idx = gcnew System::UInt16; this->h_idx = gcnew System::UInt16;
this->h_type = gcnew System::UInt16; this->h_type = gcnew System::UInt16;
this->h_size = gcnew System::UInt32; this->h_size = gcnew System::UInt32;
this->h_hash = gcnew cli::array<System::Byte>(20); // 固定長 : 解放の必要なし this->h_hash = gcnew cli::array<System::Byte>(20); // 固定長
} }
public: public:
property System::UInt32 cid property System::UInt32 cid

View File

@ -10,8 +10,24 @@ using namespace System;
int main(array<System::String ^> ^args) int main(array<System::String ^> ^args)
{ {
splitTad( args[0] ); if( args->Length < 1 )
{
printf( "argument error\n" );
return -1;
}
System::String ^tad = args[0];
System::String ^srl = (args->Length >=2)?args[1]:"out.srl";
return 0; int result = splitTad( tad, srl );
if( result < 0 )
{
printf( "\nerror\n" );
}
else
{
printf( "\nsucceeded\n" );
}
return result;
} }

View File

@ -56,7 +56,7 @@ int saveFile( System::String ^filename, cli::array<System::Byte> ^bytes )
(const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( filename ).ToPointer(); (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( filename ).ToPointer();
// ファイルにROMヘッダをライト // ファイルにROMヘッダをライト
if( fopen_s( &fp, pchFilename, "wb" ) != NULL ) // 上書き・バイナリ if( fopen_s( &fp, pchFilename, "wb" ) != NULL ) // 同名ファイルを削除して新規にライト・バイナリ
{ {
return -1; return -1;
} }