diff --git a/build/tests/FakeRomHeader/Makefile b/build/tests/FakeRomHeader/Makefile index 892956ee..153cf8bc 100644 --- a/build/tests/FakeRomHeader/Makefile +++ b/build/tests/FakeRomHeader/Makefile @@ -21,7 +21,7 @@ include $(TWLSDK_ROOT)/build/buildtools/commondefs -TARGETS = FakeRomHeader$(SUFFIX).exe +TARGETS = $(PREFIX)$(SUFFIX).exe SOURCES_C = main.c keys.c @@ -62,6 +62,13 @@ endif endif endif +ifeq ($(FOR_RED),TRUE) +MACROS += -DFOR_RED +PREFIX = FakeRomHeader +else +PREFIX = RomVersionChanger +endif + LDIRT_CLEAN = $(OBJECTS) $(TARGETS) *.BAK $(REVISION_H) include $(TWLSDK_ROOT)/build/buildtools/twl/modulerules.x86 diff --git a/build/tests/FakeRomHeader/README.html b/build/tests/FakeRomHeader/README.html new file mode 100644 index 00000000..14b8777d --- /dev/null +++ b/build/tests/FakeRomHeader/README.html @@ -0,0 +1,532 @@ + + + + + + +ROMバージョンつけかえツール + + + +
+

ROMバージョンつけかえツール

+ + +
+

ROMバージョンつけかえツールとは?

+

本ツールは、TWL向けSRLのROMバージョンを変更するPCツールです。

+
+
+

非対応なROM形式

+
    +
  1. クローンブート対応タイトル
  2. +
+

クローンブート対応タイトルに対して本ツールを使用すると、 +出力SRLではクローンブートができなくなります。 +TWL Hybridタイトルの場合には、警告が出力されますので、 +クローンブート対応でないかを確認してください。

+
    +
  1. TAD形式
  2. +
+

本ツールは SRL 形式のみ対応しています。 +本ツールに TAD を入力すると、エラーとなります。 +あらかじめ TAD⇒SRL 変換をしてから、本ツールをご使用ください。

+
    +
  1. NTR専用ROM
  2. +
+

TWL向けROM (TWL Hybrid/TWL Limited) のみ入力可能です。

+
+
+

使用上の注意

+

本ツールは、再ビルドなしにROMバージョンをつけかえるという、 +一般開発者が行なうことができないROM設定を可能にするツールです。 +したがって、再配布しないようにしてください。 +もし部外に配布する必要が生じた場合には、開発技術部にご確認ください。

+
+
+

実行方法

+

WindowsXP付属のコマンドプロンプト、もしくはcygwinで以下の形式をタイプしてください。

+
+
    +
  • ./RomVersionChecker.exe [オプション] (入力SRLファイル名) (出力SRLファイル名) (ROMバージョン)
  • +
+
+

たとえば、input.srl のROMバージョンを "0F" にしたい場合、以下のようにタイプしてください。

+
+
    +
  • ./RomVersionChecker.exe input.srl output.srl 0F
  • +
+
+
+

注意

+

「ROMバージョン」に入力する値は 16進数 です。 10進数での入力には対応していません。

+

たとえば、ROMバージョンを "0C" に設定したい場合には、 +"12" ではなく、"0C" と入力してください。

+
+
+

オプション

+
    +
  • -h : 使用方法を表示します。
  • +
  • -f : 通常、出力SRLファイルがすでに存在する場合、上書き確認をしますが、 +この上書き確認をスキップし、強制的に上書きします。
  • +
+
+
+
+

エラー

+

プログラムにエラーがあった場合、エラーメッセージが出力されます。

+

また、通常は、プログラムの返り値は "0" ですが、 +エラーが発生した場合には、返り値は "1" となります。

+

返り値は、Windowsコマンドプロンプトの場合、 +%ERRORLEVEL%環境変数に格納されますので、 +バッチファイルなどの分岐に利用することができます。

+

cygwinの場合、返り値の格納先は、 +%ERRORLEVEL%環境変数ではなく、シェル変数 $? となります。

+
+
+

変更履歴

+ +

初版

+
+
+ + diff --git a/build/tests/FakeRomHeader/README.txt b/build/tests/FakeRomHeader/README.txt index 6a287402..22bae893 100644 --- a/build/tests/FakeRomHeader/README.txt +++ b/build/tests/FakeRomHeader/README.txt @@ -1,35 +1,103 @@ -ROMwb_Uc[ +============================================================================= +ROMo[W‚c[ +============================================================================= -What? +* ڎ -EPCpR}hCc[ -Eo - - : SRL - - o: SRL - - ҂̈Ⴂ: oSRLɂ͐Vȃwb_CRCƏ‚Ă - (‚܂A`FbNʂ) + * `ROMo[W‚c[Ƃ?`_ + * `ΉROM``_ + * `gp̒`_ + * `s@`_ + * `G[`_ + * `ύX`_ -rh@ - ӂ‚ make ƁǍ[UAvpɂȂ܂B - ςƂAȉ̃IvV‚ make ĂB +ROMo[W‚c[Ƃ? +============================================================================= - make KEY_SYSTEM=TRUE VXeAvp̌I - make KEY_SECURE=TRUE ZLAAvp̌I - make KEY_LAUNCHER=TRUE `Avp̌I +{c[́ATWLSRLROMo[WύXPCc[łB -s@ - ./fakeRomHeader [Option] input_file output_file +ΉROM` +============================================================================= - EIvV - -p: vbgtH[R[h0x01ɂ܂B - -s: LtOOffɂ܂B - -d: VEJpÍtO0ɂāAEJpÍtO1ɂ܂B +1. N[u[gΉ^Cg - EɂROMwb_肽Ƃ - -> oCiGfB^ȂǂROMwb_ɁA - {c[IvVȂŎsƁA - ROMwb_wb_CRCƏČvZÂ܂B +N[u[gΉ^Cgɑ΂Ė{c[gpƁA +oSRLł̓N[u[głȂȂ܂B +TWL Hybrid^Cg̏ꍇɂ́Axo͂܂̂ŁA +N[u[gΉłȂmFĂB + + +2. TAD` + +{c[ SRL `̂ݑΉĂ܂B +{c[ TAD ͂ƁAG[ƂȂ܂B +炩 TADSRL ϊĂA{c[gpB + + +3. NTRpROM + +TWLROM (TWL Hybrid/TWL Limited) ̂ݓ͉”\łB + + +gp̒ +============================================================================= + +{c[́AărhȂROMo[W‚ƂA +ʊJ҂sȂƂłȂROMݒ”\ɂc[łB +āAĔzzȂ悤ɂĂB +OɔzzKvꍇɂ́AJZpɂmFB + + +s@ +============================================================================= + +WindowsXPt̃R}hvvgAcygwinňȉ̌`^CvĂB + + * ./RomVersionChecker.exe@[IvV]@(SRLt@C)@(oSRLt@C)@(ROMo[W) + +Ƃ΁Ainput.srl ROMo[W "0F" ɂꍇAȉ̂悤Ƀ^CvĂB + + * ./RomVersionChecker.exe@input.srl@output.srl@0F + + +------------------------------------------------------------------------------ + +uROMo[Wvɓ͂l **16i** łB **10ił̓͂ɂ͑ΉĂ܂B** + +Ƃ΁AROMo[W "0C" ɐݒ肵ꍇɂ́A +"12" ł͂ȂA"0C" Ɠ͂ĂB + + +IvV +------------------------------------------------------------------------------ + +* -h : gp@\܂B +* -f : ʏAoSRLt@Cłɑ݂ꍇA㏑mF܂A + ̏㏑mFXLbvAIɏ㏑܂B + + +G[ +============================================================================= + +vOɃG[ꍇAG[bZ[Wo͂܂B + +܂Aʏ́AvO̕Ԃl "0" łA +G[ꍇɂ́AԂl "1" ƂȂ܂B + +ԂĺAWindowsR}hvvg̏ꍇA +%ERRORLEVEL%‹ϐɊi[܂̂ŁA +ob`t@CȂǂ̕ɗp邱Ƃł܂B + +cygwin̏ꍇAԂl̊i[́A +%ERRORLEVEL%‹ϐł͂ȂAVFϐ $? ƂȂ܂B + + +ύX +============================================================================= + +* ver.1.0 (2009/08/18) + + -ȏ diff --git a/build/tests/FakeRomHeader/main.c b/build/tests/FakeRomHeader/main.c index d09d497f..341f5e48 100644 --- a/build/tests/FakeRomHeader/main.c +++ b/build/tests/FakeRomHeader/main.c @@ -78,6 +78,7 @@ SContext; static BOOL iMain( SContext *pContext ); u16 CalcCRC16(u16 start, u8 *data, int size); BOOL SignRomHeader( ROM_Header *prh ); +BOOL DecryptSignRomHeader( ROM_Header *prh ); static void SetRomSpeedByIndex(ROM_Header * header, tRomSpeedType idx); /*---------------------------------------------------------------------------* @@ -101,11 +102,19 @@ BOOL DebugMode = FALSE; void usage() { printf( "-----------------------------------------------------------------------------\n" ); +#ifdef FOR_RED printf( "Usage: fakeRomHeader.exe input_file output_file\n" ); printf( " input_file : a ROM data file (generated by makerom.TWL).\n" ); printf( " output_file : a destination file.\n" ); +#else + printf( "Usage: fakeRomHeader.exe input_file output_file new_version\n" ); + printf( " input_file : a ROM data file (generated by makerom.TWL).\n" ); + printf( " output_file : a destination file.\n" ); + printf( " ROM_version : a new ROM version.\n" ); +#endif printf( "\nOption:\n" ); printf( "-h : print help only.\n" ); +#ifdef FOR_RED printf( "-p : write invalid platform code in a ROM Header.\n" ); printf( "-s : negate flag for the signature in a ROM Header.\n" ); printf( "-d : negate a new developer encrypt flag, and assert an old one.\n" ); @@ -113,7 +122,8 @@ void usage() printf( "-m : [Only NTR limited ROM] Rom speed type replace 1TROM from MROM.\n" ); printf( "-D : assert a disable flag of debugger alalysis.\n" ); printf( "-c : assert a check(inspection) card flag.\n" ); - printf( "-N : skip sign [using for NTR limited ROM]" ); +#endif + printf( "-N : skip appending signature [using for NTR limited ROM]" ); printf( "-f : force to overwrite a output_file.\n" ); printf( "-----------------------------------------------------------------------------\n" ); } @@ -130,14 +140,21 @@ int main(int argc, char *argv[]) BOOL bForceOverwrite = FALSE; printf( "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" ); - printf( " fakeRomHeader [%s-%s]\n", SDK_REVISION, IPL_REVISION ); +#ifdef FOR_RED + printf( " FakeRomHeader [%s-%s]\n", SDK_REVISION, IPL_REVISION ); +#else + printf( " RomVersionChanger [%s-%s]\n", SDK_REVISION, IPL_REVISION ); +#endif printf( "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" ); // context ̏ memset( &context, 0, sizeof(SContext) ); // IvV +#ifdef FOR_RED while( (opt = getopt(argc, argv, "hpsdmv:DcfN")) >= 0 ) +#endif + while( (opt = getopt(argc, argv, "hfN")) >= 0 ) { switch( opt ) { @@ -146,6 +163,7 @@ int main(int argc, char *argv[]) return 0; break; +#ifdef FOR_RED case 'p': context.bPlatform = TRUE; break; @@ -160,7 +178,7 @@ int main(int argc, char *argv[]) case 'v': context.bVerFlag = TRUE; - context.verNum = atoi(optarg); + context.verNum = strtol(optarg, NULL, 16); break; case 'm': @@ -174,7 +192,7 @@ int main(int argc, char *argv[]) case 'c': context.bCheckCard = TRUE; break; - +#endif case 'N': context.bNTR = TRUE; break; @@ -194,6 +212,7 @@ int main(int argc, char *argv[]) argv = argv + optind; // +#ifdef FOR_RED if( argc != 2 ) { usage(); @@ -205,6 +224,31 @@ int main(int argc, char *argv[]) pSrc = argv[0]; pDst = argv[1]; } +#else + if( argc != 3 ) // ʔłROMo[WƂĎ󂯎 + { + usage(); + printf( "error arguments\n" ); + exit(1); + } + else + { + pSrc = argv[0]; + pDst = argv[1]; + context.bVerFlag = TRUE; + context.verNum = strtol(argv[2], NULL, 16); + } +#endif + + // ROMo[W1oCgŎ܂邩`FbN + if( context.bVerFlag ) + { + if( (context.verNum < 0) || (255 < context.verNum) ) + { + printf("Error: ROM version (arg 3) must be within [0, 0xFF].\n"); + return -1; + } + } printf( "input_file: %s\n", pSrc ); printf( "output_file: %s\n", pDst ); @@ -266,7 +310,7 @@ FINALIZE: { unlink( pDst ); // o̓t@C폜 } - return 0; + return ((bResult)?0:1); } /*---------------------------------------------------------------------------* @@ -288,32 +332,79 @@ static BOOL iMain( SContext *pContext ) return FALSE; } +#ifndef FOR_RED + // ̌ + if( !(pContext->bNTR) ) + { + if( !DecryptSignRomHeader(&rh) ) + { + printf( "Decrypt Sign: Failed\n" ); + return FALSE; + } + printf( "Decrypt Sign: Succeeded\n" ); + } + else if( rh.s.platform_code == PLATFORM_CODE_NTR ) + { + printf( "\n*** Error: required -N option for NTR Limited application. ***\n" ); + return FALSE; + } + + // Hybrid̂Ƃx + if( rh.s.platform_code == PLATFORM_CODE_TWL_HYBLID) + { + printf("\n"); + printf("******************** Warning *******************\n"); + printf("* *\n"); + printf("* Platform is TWL/NTR Hybrid. *\n"); + printf("* *\n"); + printf("* Clone-boot application is not supported. *\n"); + printf("* *\n"); + printf("************************************************\n"); + printf("\n"); + } + + // NTR̂ƂÔߌx + if( rh.s.platform_code == PLATFORM_CODE_NTR ) + { + printf("\n"); + printf("******************** Warning *******************\n"); + printf("* *\n"); + printf("* Platform is NTR Limited. *\n"); + printf("* *\n"); + printf("* Clone-boot application is not supported. *\n"); + printf("* *\n"); + printf("************************************************\n"); + printf("\n"); + } +#endif //#ifndef FOR_RED + // ROMwb_ { if( pContext->bPlatform ) { - printf( "platform_code: 0x%02x -> 0x01\n", rh.s.platform_code ); + printf( "Platform Code: 0x%02x -> 0x01\n", rh.s.platform_code ); rh.s.platform_code = 0x01; } if( pContext->bSignFlag ) { - printf( "enable_signature: 0x%02x -> 0x00\n", rh.s.enable_signature ); + printf( "Enable Signature: 0x%02x -> 0x00\n", rh.s.enable_signature ); rh.s.enable_signature = 0x0; } if( pContext->bDevFlag ) { - printf( "old dev. encrypt: 0x%02x -> 0x01x\n", rh.s.developer_encrypt_old ); - printf( "new dev. encrypt: 0x%02x -> 0x00x\n", rh.s.exFlags.developer_encrypt ); + printf( "Old Dev. Encrypt: 0x%02x -> 0x01x\n", rh.s.developer_encrypt_old ); + printf( "Oew Dev. Encrypt: 0x%02x -> 0x00x\n", rh.s.exFlags.developer_encrypt ); rh.s.developer_encrypt_old = 0x1; rh.s.exFlags.developer_encrypt = 0x0; } if( pContext->bVerFlag ) { - printf( "ROM version: 0x%02x -> 0x%02x\n", rh.s.rom_version, pContext->verNum ); - rh.s.rom_version = pContext->verNum; + u8 old = rh.s.rom_version; + rh.s.rom_version = (u8)(pContext->verNum & 0xFF); + printf( "ROM version: 0x%02x -> 0x%02X\n", old, rh.s.rom_version ); } if( pContext->bMROM ) @@ -362,17 +453,20 @@ static BOOL iMain( SContext *pContext ) // wb_CRCvZ rh.s.header_crc16 = CalcCRC16( CRC16_INIT_VALUE, (u8*)&rh, CALC_CRC16_SIZE ); - // + // ď if( !(pContext->bMROM) && !(pContext->bNTR) ) // NTRpIvV̂Ƃ͏Ȃ { if( !SignRomHeader( &rh ) ) { + printf( "Encrypt Sign: Failed\n" ); + printf("\n*** Error: Failed to encrypt the sigunature. ***\n\n"); return FALSE; } + printf( "Encrypt Sign: Succeeded\n" ); } else { - printf( "skip sign\n" ); + printf( "Encrypt Sign: Skip\n" ); } // t@CRs @@ -483,7 +577,7 @@ BOOL SignRomHeader( ROM_Header *prh ) result = ACSign_Encrypto( signDst, g_devPrivKey_DER, &signSrc, sizeof(SignatureData) ); if( !result ) { - printf( "ACSign_Encrypto encryption failed.\n" ); + printf( "\n*** Error: failed to ACSign_Encrypto. ***\n\n" ); return FALSE; } @@ -496,7 +590,7 @@ BOOL SignRomHeader( ROM_Header *prh ) } if( !result || (memcmp( &signSrc, &(decryptBlock[pos+1]), sizeof(SignatureData) ) != 0) ) { - printf( "Verification a signature failed.\n" ); + printf( "\n*** Error: failed to verify the signature. ***\n\n" ); return FALSE; } @@ -506,6 +600,57 @@ BOOL SignRomHeader( ROM_Header *prh ) return TRUE; } // ECSrlResult RCSrl::signRomHeader(void) +// O +BOOL DecryptSignRomHeader( ROM_Header *prh ) +{ + u8 original[ RSA_KEY_LENGTH ]; // Õf[^i[ + s32 pos = 0; // ubN̐擪AhX + u8 digest[ DIGEST_SIZE_SHA1 ]; // ROMwb_̃_CWFXg + + // + // (1) Jŕ(ubN)[Jϐ(original)Ɋi[ + // (2) ubN]ȕ菜Ĉ(pDst)ɃRs[ + + // I +#ifdef KEY_USER + printf( "Decryption Key: USER\n" ); +#endif +#ifdef KEY_SYSTEM + printf( "Decryption Key: SYSTEM\n" ); +#endif +#ifdef KEY_SECURE + printf( "Decryption Key: SECURE\n" ); +#endif +#ifdef KEY_LAUNCHER + printf( "Decryption Key: LAUNCHER\n" ); +#endif + + // ̉ = Jŕ + if( !ACSign_Decrypto( original, g_devPubKey_DER, prh->signature, RSA_KEY_LENGTH ) ) + { + printf( "\n*** Error: failed to decrypt the signature. ***\n\n" ); + return FALSE; + } + // Of[^𕜍ubNQbg + for( pos=0; pos < (RSA_KEY_LENGTH-2); pos++ ) // {ubN̐擪0x00̓ɂďdl + { + // ÍubN` = 0x00, BlockType, Padding, 0x00, f[^ + if( original[pos] == 0x00 ) // f[^̒O0x00T[` + { + break; + } + } + // xt@C + // ROMwb_̃_CWFXgZo(擪ؖ̈̒O܂łΏ) + ACSign_DigestUnit( digest, prh, (u32)&(prh->certificate) - (u32)prh ); + if( memcmp( &(original[pos+1]), digest, DIGEST_SIZE_SHA1 ) != 0 ) + { + printf( "\n*** Error: failed to verify the signature. ***\n\n" ); + return FALSE; + } + return TRUE; +} + /*---------------------------------------------------------------------------* diff --git a/build/tests/FakeRomHeader/ビルド方法.txt b/build/tests/FakeRomHeader/ビルド方法.txt new file mode 100644 index 00000000..378135a5 --- /dev/null +++ b/build/tests/FakeRomHeader/ビルド方法.txt @@ -0,0 +1,22 @@ + +rh@ +============= + +1. @\ + + ӂ‚ make ƁAiZp̋@\łɂȂ܂B + (oCi RomVersionChanger.*.exe ƂȂ܂B) + @\ɂ́Aȉ̃IvV‚ make ĂB + + make FOR_RED=TRUE + + +2. ̕ύX + + ӂ‚ make ƁǍ[UAvpɂȂ܂B + ςƂAȉ̃IvV‚ make ĂB + + make KEY_SYSTEM=TRUE VXeAvp̌I + make KEY_SECURE=TRUE ZLAAvp̌I + make KEY_LAUNCHER=TRUE `Avp̌I +