diff --git a/build/tools/MasterEditor/split_tad_console/split_tad_console.ncb b/build/tools/MasterEditor/split_tad_console/split_tad_console.ncb index 6c46eaa..c498982 100644 Binary files a/build/tools/MasterEditor/split_tad_console/split_tad_console.ncb and b/build/tools/MasterEditor/split_tad_console/split_tad_console.ncb differ diff --git a/build/tools/MasterEditor/split_tad_console/split_tad_console.suo b/build/tools/MasterEditor/split_tad_console/split_tad_console.suo index 3b0c12b..83ecf12 100644 Binary files a/build/tools/MasterEditor/split_tad_console/split_tad_console.suo and b/build/tools/MasterEditor/split_tad_console/split_tad_console.suo differ diff --git a/build/tools/MasterEditor/split_tad_console/split_tad_console/Debug/BuildLog.htm b/build/tools/MasterEditor/split_tad_console/split_tad_console/Debug/BuildLog.htm index 78a81bd..1fb79a8 100644 Binary files a/build/tools/MasterEditor/split_tad_console/split_tad_console/Debug/BuildLog.htm and b/build/tools/MasterEditor/split_tad_console/split_tad_console/Debug/BuildLog.htm differ diff --git a/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad.cpp b/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad.cpp deleted file mode 100644 index 9f00e7a..0000000 --- a/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include "stdafx.h" -#include "twl/types.h" -#include -#include -#include "split_tad.h" -#include "split_tad_util.h" - - -// ------------------------------------------------------ -// 宣言と定数 -// ------------------------------------------------------ - -// internal functions -cli::array^ readTitleKey( cli::array ^ticket ); -cli::array^ decCBC( cli::array ^ Key, cli::array ^ IV, cli::array ^cipherText ); -cli::array ^readContentsInfo( cli::array ^tmd ); - -// tad外し用の鍵 -const u8 commonKey[] = -{ - 0xA1,0x60,0x4A,0x6A,0x71,0x23,0xB5,0x29,0xAE,0x8B,0xEC,0x32,0xC8,0x16,0xFC,0xAA -}; - - -// ------------------------------------------------------ -// tad外し処理本体 -// ------------------------------------------------------ - -// -// tad ファイルから srl(0番目のコンテンツ)を抜き出す -// (split_tad_dev.pl の移植) -// -// @arg [in] 入力 tad ファイル名 -// @arg [out] 出力 srl ファイル名 -// -// @ret 成功したとき0 失敗したら負の値 -// -int splitTad( System::String ^tadpath, System::String ^srlpath ) -{ - FILE *fp = NULL; - const char *pchFilename = - (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( tadpath ).ToPointer(); - - if( fopen_s( &fp, pchFilename, "rb" ) != NULL ) - { - return -1; - } - - cli::array ^mbuf = subStr( fp, 0, 32 ); - - u32 hdrSize = reverseEndian( unpack32(mbuf, 0) ); // 基本的にビッグエンディアン - u16 tadType = reverseEndian( unpack16(mbuf, 4) ); - u16 tadVersion = reverseEndian( unpack16(mbuf, 6) ); - u32 certSize = reverseEndian( unpack32(mbuf, 8) ); - u32 crlSize = reverseEndian( unpack32(mbuf, 12) ); - u32 ticketSize = reverseEndian( unpack32(mbuf, 16) ); - u32 tmdSize = reverseEndian( unpack32(mbuf, 20) ); - u32 contentSize = reverseEndian( unpack32(mbuf, 24) ); - u32 metaSize = reverseEndian( unpack32(mbuf, 28) ); - - printf( "hdrSize %d\n", hdrSize ); - printf( "tadType %c%c\n", tadType>>8, tadType&0xFF ); - printf( "tadVersion %d\n", tadVersion ); - printf( "certSize %d\n", certSize ); - printf( "crlSize %d\n", crlSize ); - printf( "ticketSize %d\n", ticketSize ); - printf( "tmdSize %d\n", tmdSize ); - printf( "contentSize %d\n", contentSize ); - printf( "metaSize %d\n", metaSize ); - - u32 certOffset = roundUp( hdrSize, 64); - u32 crlOffset = roundUp( certOffset + certSize, 64); - u32 ticketOffset = roundUp( crlOffset + crlSize, 64); - u32 tmdOffset = roundUp( ticketOffset + ticketSize, 64); - u32 contentOffset = roundUp( tmdOffset + tmdSize, 64); - u32 metaOffset = roundUp( contentOffset + contentSize, 64); - u32 fileSize = roundUp( metaOffset + metaSize, 64); - - fseek( fp, 0, SEEK_END ); - u32 orgFileSize = ftell( fp ); - if( fileSize != orgFileSize ) - { - printf( "file size is not expected size(=%d)", fileSize ); - fclose( fp ); - return -1; - } - cli::array ^ticket = subStr( fp, ticketOffset, ticketSize ); - cli::array ^tmd = subStr( fp, tmdOffset, tmdSize ); - cli::array ^content = subStr( fp, contentOffset, contentSize ); - - //saveFile( "cert.bin", subStr( fp, certOffset, certSize ) ); - //saveFile( "crl.bin", subStr( fp, crlOffset, crlSize ) ); - //saveFile( "ticket.bin", ticket ); - //saveFile( "tmd.bin", tmd ); - //saveFile( "meta.bin", subStr( fp, metaOffset, metaSize ) ); - - cli::array ^title_key = readTitleKey( ticket ); - cli::array ^rci = readContentsInfo( tmd ); - 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; - for each( rcContentsInfo ^ci in rci ) - { - u32 size = roundUp( (u32)ci->size, 16 ); - cli::array ^enc_content_x = subStr( content, offset, size ); - cli::array ^content_x_iv = resizeBytes( pack16( reverseEndian(ci->idx) ), 14 ); // ビッグエンディアンにしておく - cli::array ^dec_content_x = decCBC( title_key, content_x_iv, enc_content_x ); - cli::array ^dec_content = subStr( dec_content_x, 0, ci->size ); - System::Security::Cryptography::SHA1 ^sha1 = gcnew System::Security::Cryptography::SHA1Managed(); - cli::array ^hash = sha1->ComputeHash( dec_content ); - - dumpBytes( hash ); - pin_ptr calc = &hash[0]; // 計算で求めたハッシュ - pin_ptr extr = &ci->hash[0]; // 抽出したハッシュ - if( memcmp( calc, extr, 20 ) == 0 ) - { - printf( "hash OK\n" ); - } - else - { - 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 ); - } - offset += roundUp( size, 64 ); - } - fclose( fp ); - return result; -} - -// ------------------------------------------------------ -// internal functions -// ------------------------------------------------------ - -// -// title_key の復号 -// -// @ret title_key のバイト列 -// -cli::array^ readTitleKey( cli::array ^ticket ) -{ - cli::array ^encTitleKey = subStr( ticket, 0x1BF, 16 ); - cli::array ^IV = resizeBytes( subStr( ticket, 0x1DC, 8 ), 8 ); // 16バイトに拡張してケツの8バイトを0で埋める - - cli::array ^comKey = gcnew cli::array(16); - pin_ptr pComKey = &comKey[0]; - memcpy( pComKey, commonKey, 16 ); - - cli::array ^plain; - try - { - plain = decCBC( comKey, IV, encTitleKey ); - } - catch (System::Exception ^ e) - { - System::Console::WriteLine("Exception in readTitleKey(): {0}", e->Message); - } - return plain; -} - -// -// tmd から各コンテンツファイルの情報を抜き出す -// -// @ret 各コンテンツファイルの情報をまとめた Array -// -cli::array ^readContentsInfo( cli::array ^tmd ) -{ - u16 nContent = reverseEndian( unpack16(tmd, 0x1DE) ); - cli::array ^ci = gcnew cli::array( nContent ); - - u16 i; - for( i=0; i < nContent; i++ ) - { - u32 offset = 0x1E4 + 36*i; - ci[i] = gcnew rcContentsInfo; - ci[i]->cid = reverseEndian( unpack32(tmd, offset) ); - ci[i]->idx = reverseEndian( unpack16(tmd, offset + 4) ); - ci[i]->type = reverseEndian( unpack16(tmd, offset + 6) ); - ci[i]->size = reverseEndian( unpack32(tmd, offset + 12) ); - ci[i]->hash = subStr( tmd, offset + 16, 20 ); - } - return ci; -} - -// -// AES復号 : System::Security::Cryptography::RijndaelManaged のヘルプのサンプルをコピペ -// -// @ret 復号後のデータ -// -cli::array^ decCBC( cli::array ^ Key, cli::array ^ IV, cli::array ^cipherText ) -{ - // Check arguments. - if (!cipherText || cipherText->Length <= 0) - throw gcnew System::ArgumentNullException("cipherText"); - if (!Key || Key->Length <= 0) - throw gcnew System::ArgumentNullException("Key"); - if (!IV || IV->Length <= 0) - throw gcnew System::ArgumentNullException("Key"); - - // TDeclare the streams used - // to decrypt to an in memory - // array of bytes. - System::IO::MemoryStream ^msDecrypt; - System::Security::Cryptography::CryptoStream ^csDecrypt; - - // Declare the RijndaelManaged object - // used to decrypt the data. - System::Security::Cryptography::RijndaelManaged ^aesAlg; - - // Declare the string used to hold - // the decrypted text. - cli::array ^plain = gcnew cli::array(cipherText->Length); - - try - { - // Create a RijndaelManaged object - // with the specified key and IV. - aesAlg = gcnew System::Security::Cryptography::RijndaelManaged(); - aesAlg->Mode = System::Security::Cryptography::CipherMode::CBC; // CBCモード - aesAlg->Key = Key; - aesAlg->IV = IV; - aesAlg->Padding = System::Security::Cryptography::PaddingMode::Zeros; - - // Create a decrytor to perform the stream transform. - System::Security::Cryptography::ICryptoTransform ^ decryptor - = aesAlg->CreateDecryptor(aesAlg->Key, aesAlg->IV); - - // Create the streams used for decryption. - msDecrypt = gcnew System::IO::MemoryStream(cipherText); - csDecrypt = gcnew System::Security::Cryptography::CryptoStream - (msDecrypt, decryptor, System::Security::Cryptography::CryptoStreamMode::Read); - csDecrypt->Read( plain, 0, cipherText->Length ); - //srDecrypt = gcnew System::IO::StreamReader(csDecrypt); - - //// Read the decrypted bytes from the decrypting stream - //// and place them in a string. - //plaintext = srDecrypt->ReadToEnd(); - } - finally - { - // Clean things up. - - // Close the streams. - if (csDecrypt) - csDecrypt->Close(); - if (msDecrypt) - msDecrypt->Close(); - - // Clear the RijndaelManaged object. - if (aesAlg) - aesAlg->Clear(); - } - return plain; -} - -// end of file diff --git a/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad.h b/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad.h deleted file mode 100644 index b08bdb0..0000000 --- a/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include "twl/types.h" -#include -#include - - -// ------------------------------------------------------ -// APIs -// ------------------------------------------------------ - -// -// tad ファイルから srl(0番目のコンテンツ)を抜き出す -// (split_tad_dev.pl の移植) -// -// @arg [in] 入力 tad ファイルのパス -// @arg [out] 出力 srl ファイルのパス -// -// @ret 成功したとき0 失敗したら負の値 -// -int splitTad( System::String ^tadpath, System::String ^srlpath ); - - -// ------------------------------------------------------ -// 内部処理用の構造体(プロトタイプ宣言できないのでヘッダに置く) -// ------------------------------------------------------ - -// コンテンツ情報の構造体 -ref class rcContentsInfo -{ -private: - System::UInt32 ^h_cid; - System::UInt16 ^h_idx; - System::UInt16 ^h_type; - System::UInt32 ^h_size; - cli::array ^h_hash; -public: - rcContentsInfo() - { - this->h_cid = gcnew System::UInt32; // 解放の必要なし - this->h_idx = gcnew System::UInt16; - this->h_type = gcnew System::UInt16; - this->h_size = gcnew System::UInt32; - this->h_hash = gcnew cli::array(20); // 固定長 - } -public: - property System::UInt32 cid - { - void set( System::UInt32 v ){ *this->h_cid = v; }; - System::UInt32 get(void){ return *this->h_cid; } - } - property System::UInt16 idx - { - void set( System::UInt16 v ){ *this->h_idx = v; }; - System::UInt16 get(void){ return *this->h_idx; } - } - property System::UInt16 type - { - void set( System::UInt16 v ){ *this->h_type = v; }; - System::UInt16 get(void){ return *this->h_type; } - } - property System::UInt32 size - { - void set( System::UInt32 v ){ *this->h_size = v; }; - System::UInt32 get(void){ return *this->h_size; } - } - property cli::array ^hash - { - void set( cli::array ^h ) - { - cli::array::Copy( h, this->h_hash, 20 ); - } - cli::array ^get(void) - { - cli::array ^cp = gcnew cli::array(20); // コピーを返す - cli::array::Copy( this->h_hash, cp, 20 ); - return cp; - } - } -}; diff --git a/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad_console.vcproj b/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad_console.vcproj index bd0b7de..d190888 100644 --- a/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad_console.vcproj +++ b/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad_console.vcproj @@ -42,7 +42,7 @@ -#include -#include "split_tad_util.h" - - -// ファイルから部分バイト列を抜き出す -cli::array^ subStr( FILE *fp, const int offset, const int size ) -{ - if( size <= 0 ) - { - return nullptr; - } - cli::array ^mbuf = gcnew cli::array(size); // メモリ解放の必要なし - pin_ptr buf = &mbuf[0]; // fread が unmanaged 配列を引数にするので変換 - - (void)fseek( fp, offset, SEEK_SET ); - if( fread( buf, 1, size, fp ) != size ) - { - return nullptr; - } - return mbuf; // managed のほうを返す -} - -// バイト列から部分バイト列を抜き出す -cli::array^ subStr( cli::array ^bytes, const int offset, const int size ) -{ - cli::array ^sub = gcnew cli::array(size); - - cli::array::Copy( bytes, offset, sub, 0, size ); - return sub; -} - -// ファイルを作成してバイト列を格納する -int saveFp( FILE *fp, cli::array ^bytes ) -{ - if( bytes == nullptr ) - { - return 0; // 空のファイルをつくりたいということなので正常終了とみなす - } - pin_ptr tmp = &bytes[0]; // array型はふつうの配列ではないのでバイト配列に変換 - int size = bytes->Length; - - if( fwrite( tmp, 1, size, fp ) != size ) - { - return -1; - } - return 0; -} - -int saveFile( System::String ^filename, cli::array ^bytes ) -{ - FILE *fp = NULL; - const char *pchFilename = - (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( filename ).ToPointer(); - - // ファイルにROMヘッダをライト - if( fopen_s( &fp, pchFilename, "wb" ) != NULL ) // 同名ファイルを削除して新規にライト・バイナリ - { - return -1; - } - fseek( fp, 0, SEEK_SET ); - int r = saveFp( fp, bytes ); - fclose( fp ); - - return r; -} - -// エンディアンを逆転させる(tadはビッグエンディアンなのであったほうが便利) -u32 reverseEndian( const u32 v ) -{ - u32 ret = (v<<24) | ((v<<8) & 0x00FF0000) | ((v>>8) & 0x0000FF00) | (v>>24); - return ret; -} - -u16 reverseEndian( const u16 v ) -{ - u16 ret = (v<<8) | (v>>8); - return ret; -} - -// 多バイト値をバイト列に変換(リトルエンディアン) *** perlのpackを意識 *** -cli::array ^pack32( u32 v ) -{ - cli::array ^bytes = gcnew cli::array(4); - bytes[0] = v & 0xFF; - bytes[1] = (v >> 8) & 0xFF; - bytes[2] = (v >> 16) & 0xFF; - bytes[3] = (v >> 24) & 0xFF; - return bytes; -} - -cli::array ^pack16( u16 v ) -{ - cli::array ^bytes = gcnew cli::array(2); - bytes[0] = v & 0xFF; - bytes[1] = v >>8; - return bytes; -} - -// バイト列の部分バイト列から多バイト値として解釈(リトルエンディアン) *** perlのunpackを意識 *** -u32 unpack32( cli::array ^bytes, const int index ) -{ - pin_ptr tmp = &bytes[0]; - u32 v = (u32)*((u32*)(tmp+index)); - return v; -} - -u16 unpack16( cli::array ^bytes, const int index ) -{ - pin_ptr tmp = &bytes[0]; - u16 v = (u16)*((u16*)(tmp+index)); - return v; -} - -// 丸める -u32 roundUp( const u32 v, const u32 align ) -{ - u32 r = ((v + align - 1) / align) * align; - return r; -} - -u16 roundUp( const u16 v, const u16 align ) -{ - u16 r = ((v + align - 1) / align) * align; - return r; -} - -// バイト列の長さを拡張して末尾を0で埋める -// (0x12345678 => 0x1234567800000000) -cli::array ^resizeBytes( cli::array ^org, const int difSize ) -{ - cli::array ^r = gcnew cli::array( org->Length + difSize ); - cli::array::Copy( org, 0, r, 0, org->Length ); - return r; -} - -// バイト列を16進で表示 -void dumpBytes( cli::array ^bytes ) -{ - for each( System::Byte b in bytes ) - { - printf( "%02x", b ); - } - printf( "\n" ); -} - -// end of file diff --git a/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad_util.h b/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad_util.h deleted file mode 100644 index 1c31f5a..0000000 --- a/build/tools/MasterEditor/split_tad_console/split_tad_console/split_tad_util.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include "twl/types.h" -#include -#include - - -// ------------------------------------------------------ -// APIs -// ------------------------------------------------------ - -// -// ファイルから部分バイト列を抜き出す -// -// @ret 抜き出したバイト列 -// -cli::array^ subStr( FILE *fp, const int offset, const int size ); - -// -// バイト列から部分バイト列を抜き出す -// -// @ret 抜き出したバイト列 -// -cli::array^ subStr( cli::array ^bytes, const int offset, const int size ); - -// -// ファイルを作成してバイト列を格納する -// -// @ret 成功したら0 失敗したら負の値 -// -int saveFp( FILE *fp, cli::array ^bytes ); -int saveFile( System::String ^filename, cli::array ^bytes ); - -// -// エンディアンを逆転させる(tadはビッグエンディアンなのであったほうが便利) -// -// @ret エンディアン逆転後の値 -// -u32 reverseEndian( const u32 v ); -u16 reverseEndian( const u16 v ); - -// -// 多バイト値をバイト列に変換(リトルエンディアン) *** perlのpackを意識 *** -// -// @ret 変換後のバイト列 -// -cli::array ^pack32( u32 v ); -cli::array ^pack16( u16 v ); - -// -// バイト列の部分バイト列から多バイト値として解釈(リトルエンディアン) *** perlのunpackを意識 *** -// -// @arg [in] バイト列 -// @arg [in] 何バイト目からを多バイト値とみなすか -// -// @ret 解釈した後の多バイト値 -// -u32 unpack32( cli::array ^bytes, const int index ); -u16 unpack16( cli::array ^bytes, const int index ); - -// -// 丸める -// -u32 roundUp( const u32 v, const u32 align ); -u16 roundUp( const u16 v, const u16 align ); - -// -// バイト列の長さを拡張して末尾を0で埋める -// (0x12345678 => 0x1234567800000000) -// -// @arg [in] 拡張前のバイト列 -// @arg [in] 何バイト拡張するか(拡張分だけを指定 例えば4バイトを5バイトにする場合には1を指定) -// -// @ret 拡張後のバイト列(新たなバイト列を内部で生成) -// -cli::array ^resizeBytes( cli::array ^org, const int difSize ); - -// バイト列を16進で表示 -void dumpBytes( cli::array ^bytes ); -