From 5adc0644788a4530c4f864631e7d6ec858fd6ebc Mon Sep 17 00:00:00 2001 From: mizu Date: Thu, 12 May 2011 03:00:34 +0000 Subject: [PATCH] git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@253 385bec56-5757-e545-9c3a-d8741f4650f1 --- trunk/CardSaveData/ToSD/Imp/source/main.cpp | 482 ++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 trunk/CardSaveData/ToSD/Imp/source/main.cpp diff --git a/trunk/CardSaveData/ToSD/Imp/source/main.cpp b/trunk/CardSaveData/ToSD/Imp/source/main.cpp new file mode 100644 index 0000000..625573f --- /dev/null +++ b/trunk/CardSaveData/ToSD/Imp/source/main.cpp @@ -0,0 +1,482 @@ +/*---------------------------------------------------------------------------* + Project: Horizon + File: main.cpp + + Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Rev$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "demo.h" +#include "../../body/ver.h" +#include "../common/sleep.h" +#include "../common/common.h" +#include "../common/shfnt.h" +#include "../common/test_data.h" + +#define INF_FILE "sdmc:/cts_inf.txt" + +#define KEY_LENGTH 2048 +#define LIST_FILE "sdmc:/cts_list.txt" +#define SIGN_FILE "sdmc:/cts_sign.dat" + + +extern "C" { + extern u8* PUBLIC_KEY_BEGIN[]; + extern u8* PUBLIC_KEY_END[]; + + const void* PUBLIC_KEY = PUBLIC_KEY_BEGIN; +} + +demo::RenderSystemDrawing s_RenderSystem; +nn::fnd::ExpHeap appHeap; +uptr heapForGx; +void ErrorStop(char *s); +void ErrorPOff(char *s); + +const size_t ROMFS_BUFFER_SIZE = 64*1024;//ROMマウント用 +const size_t READ_BUFFER_SIZE = 64*1024; + +#define SDK_SER_LEN nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN + +namespace +{ + u8* readBuf; + u8* romfsBuf; + +} +nn::Result result; + + +bool ImportFile(nn::fs::MediaType mediaType, wchar_t* filename) +{ + //nn::Result result; + + nn::fs::FileOutputStream* stream; + result = nn::am::BeginImportProgram(&stream, mediaType); + if (result.IsSuccess()) + { + //NN_LOG("Importing: %ls...", filename); + nn::fs::FileInputStream in(filename); + + while(s32 read = in.Read(readBuf, READ_BUFFER_SIZE)) + { + stream->Write(readBuf, read); + } + result = nn::am::EndImportProgram(stream); + } + return result.IsSuccess(); +} + +#define LIST_MAX 4000 +#define LIST_LENGTH (LIST_MAX * (nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN+1)) +u8 s_list[LIST_MAX][nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN+1];//シリアルリスト +u8 sign[256];//署名 +u8 serialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN+1]; + +//本体シリアル取得 +int GettedSerLen; +bool GetSerial(){ + nn::cfg::CTR::init::Initialize(); + nn::cfg::CTR::system::Initialize(); + result = nn::cfg::CTR::system::GetSerialNo(serialNo); + nn::cfg::CTR::system::Finalize(); + nn::cfg::CTR::init::Finalize(); + serialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN] = 0; + GettedSerLen = strlen((char*)serialNo); + return result.IsSuccess(); +} + + + +//#define setColor(r,g,b,a) s_RenderSystem.SetColor(r,g,b,a) +void setColor(f32 r,f32 g,f32 b,f32 a){ shf_SetColor(r,g,b,a);} +//#define setText(x,y,s) s_RenderSystem.DrawText(x,y,s) +void drawText(u16 x,u16 y,char *s){ shf_DrawText_0( x,y,s);} +//上はASCIIのみ対応したTextWriterへのラッパ +//日本語表示の場合、WideTextWriterを使う(要sft_側の関数追加) + + +nn::hid::PadReader *hpr; +//入力待ち +nn::hid::PadStatus padStatus; +u32 WaitKey(u32 mask) +{ + + while(1){ + hpr->ReadLatest(&padStatus); + if(padStatus.trigger & mask)return padStatus.trigger; + CheckSysBreak(); + } +} + +//終了 +void endfunc() +{ + appHeap.Free(reinterpret_cast(readBuf)); + appHeap.Free(reinterpret_cast(romfsBuf)); + nn::hid::Finalize(); + SharedFontFinalize(); + nngxWaitVSync(NN_GX_DISPLAY_BOTH);//SDK2.0以降では不要? + s_RenderSystem.Finalize(); +} + +//署名検証 +bool VeriRsa(u8* src,size_t sz,u8* sig) +{ + nn::crypto::RsaKey key; + //nn::crypto::Initialize(); + nn::ps::CTR::Initialize(); + result = key.InitializePublicKey(PUBLIC_KEY_BEGIN,KEY_LENGTH); + if (result.IsSuccess()) + { + result = nn::ps::CTR::VerifyRsaSha256(src,sz,sig,key); + } + //nn::crypto::Finalize(); + nn::ps::CTR::Finalize(); + return result.IsSuccess(); +} + +//エラー +void ErrorCommon(char *s,char *ss) +{ + char str[128]; + nn::am::FinalizeForLocalImporter(); + nn::fs::Unmount("sdmc:"); + nn::fs::Unmount("rom:"); + NN_LOG(s); + NN_LOG(" result = %d\n",result.GetDescription()); + shf_SetScale(0.7,0.7); + setColor(1.0, 0.0, 0.0,1.0); + strcpy(str,"Error: "); + strcat(str,s); + drawText(10,100,str); + drawText(10,140,ss); +} + + +void ErrorStop(char *s) +{ + ErrorCommon(s,"Push Home Button & end"); + s_RenderSystem.SwapBuffers(); + WaitKey(0); +} + +void ErrorPoff(char *s) +{ + ErrorCommon(s,"Push Power Button & Power Off"); + drawText(10,160,"Home Button is invalid"); + s_RenderSystem.SwapBuffers(); + WaitKey(0); +} + + +//改行後の位置を返す、0=見つからなかった +int CrLf(int n,int max) +{ + u8 d; + while(n < max) + { + d = readBuf[n]; + if (d==0x0a)return n+1;//LF + if (d==0x0d)//CR + { + if (n == max-1)return 0;//終端 + n++; + if (readBuf[n]==0x0a)return n+1;//CR+LF + ErrorStop("list broken");//CRのみは異常、署名時にファイル壊れてた? + } + n++; + } + return 0; +} + +nn::fs::FileInputStream fi; +//ファイルリード +s32 FileRead(char* fname) +{ + s32 size; + result = fi.TryInitialize(fname); + if (result.IsFailure()){//open error + //NN_LOG("desc= %d\n",result.GetDescription()); + return 0; + } + result = fi.TryRead(&size,readBuf,READ_BUFFER_SIZE); + fi.Finalize(); + if (result.IsFailure()){ + //NN_LOG("desc= %d\n",result.GetDescription()); + return 0; + } + return size; +} + + +char ver[16]; +char seri[32]; +void nnMain( void ) +{ + //nn::Result result; + bool flg_applove=false; + bool flg_test=false; + extern bool prohibitHome;// HOME ボタン禁止 + + nn::os::Initialize(); + nn::fs::Initialize(); + + //DEA-SUPにて推奨のフリーズ暫定対策:無線デーモンを停止 (2011.3.1 現在) + //ただし、スリープに入ると再開 + //無線は使わないので本体横スイッチ切っとくのが確実 + nn::ndm::Initialize(); + nn::ndm::SuspendScheduler(); + + //中断処理の準備 + InitSysBreak((uptr)endfunc); + // グラフィックスライブラリの初期化は、以降で行わなければならない + // 他、アプリケーションの初期化処理 + + nn::hid::Initialize(); + nn::hid::PadReader padReader; + hpr = &padReader; + + //result = nn::ns::CTR::InitializeForShell(); + //if (result.IsSuccess()) + result = nn::am::InitializeForLocalImporter(); + + nn::applet::DisableSleep();//スリープ非対応 .. 無線対策 + + // ヒープの確保 + appHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(), nn::os::ALLOCATE_OPTION_LINEAR); + + const u32 s_GxHeapSize = 0x800000; + // RenderSystem の準備 + heapForGx = reinterpret_cast(appHeap.Allocate(s_GxHeapSize)); + s_RenderSystem.Initialize(heapForGx, s_GxHeapSize); + SharedFontInit(); + + // 共有フォントの種類を取得 + //nn::pl::SharedFontType sftype = nn::pl::GetSharedFontType(); + + // スリープ要求に対する返答を有効にする + // また、蓋の状態チェックを行い蓋が閉じられているならスリープ要求が発生する +// nn::applet::EnableSleep(true); + + s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0); + s_RenderSystem.Clear(); +// s_RenderSystem.SetFontSize(12); + shf_SetScale(0.8,0.6); + setColor(1.0,1.0,1.0,1.0); + drawText(20,20,"CTR Card Savedata to SD Setup"); + s_RenderSystem.SwapBuffers(); + + shf_SetScale(0.5,0.5); + sprintf(ver,"version %.2f",VERSION); + drawText(250,40,ver); + + shf_SetScale(0.7,0.7); + if (result.IsFailure())ErrorStop("Initialize");//初期化に失敗 + if (READ_BUFFER_SIZE < LIST_LENGTH)ErrorStop("buffer size");//バッファサイズのチェック + + //ファイルバッファ + //SDKで4倍数サイズ、4アライン推奨 + if (READ_BUFFER_SIZE > appHeap.GetTotalFreeSize())ErrorStop("memory alloc"); + readBuf = reinterpret_cast(appHeap.Allocate(READ_BUFFER_SIZE,32)); + if (ROMFS_BUFFER_SIZE > appHeap.GetTotalFreeSize())ErrorStop("memory alloc"); + romfsBuf = reinterpret_cast(appHeap.Allocate(ROMFS_BUFFER_SIZE,32)); + + if (nn::os::CTR::GetRunningTargetHardware() != nn::os::TARGET_HARDWARE_PRODUCT) + {//デバッガ + flg_test=true; + flg_applove=true; + }else{//実機ならシリアルチェック + int i,j,n; + s32 fsize; + if( GetSerial() == false)ErrorStop("Get Serial");//本体シリの取得に失敗 + + result = nn::fs::MountSdmc();//ダイレクトでマウント..マスタリング時にワーニング + if (result.IsFailure())ErrorStop("Mount SD"); + fsize = FileRead(INF_FILE);//設定ファイルがあるか + if((fsize < 1024) && (fsize > 0))//サイズチェック,増えても1Kは超えない + {//不具合調査時に状況にあわせて現場で作成&変更を想定したオプション + //通常は不要なので無しでも動くようしとく + n = 0; + while(n < fsize) + { + if (readBuf[n] == '-'){ + if (n == fsize-1)break;//終端 + n++; + switch (readBuf[n]){ + case 'p':// -p .. 本体シリアル表示 + strcpy(seri,"s/n: "); + strcat(seri,(char *)serialNo); + shf_SetScale(0.5,0.5); + drawText(10,40,(char*)seri); + shf_SetScale(0.7,0.7); + break; + case 't':// -t .. テストメニュー有効 + flg_test = true; + break; + } + } + n++; + } + } + + //シリアル表示(オプション)後にチェック + //デバッガ=15,実機=11 + if (GettedSerLen < 11)ErrorStop("invalid Serial"); + + fsize = FileRead(SIGN_FILE);//署名リード + if(fsize != 256)ErrorStop("sign file");//鍵のbit長は2046固定 + memcpy(sign,readBuf,256);//readBuf -> sign + fsize = FileRead(LIST_FILE);//リストリード + if((fsize > LIST_LENGTH ) || (fsize == 0))ErrorStop("list file"); + + nn::fs::Unmount("sdmc:"); //検証後はSDから読まないでメモリバッファ上のデータを使う: 差替え対策 + if (VeriRsa(readBuf,fsize,sign) == false)ErrorStop("sign verify"); + + //署名検証OK + int list_ct = 0; + n=0; + while(n < fsize)//リスト作成 + { + if (readBuf[n] == '#')//コメント行を無視、ワイド文字非対応 + { + i = CrLf(n,fsize);//コメントの次行 + if (i == 0)break;//ファイル終わりまで改行が見つからない + }else + { + //改行さがし + if ((fsize-n) > (SDK_SER_LEN+2)) + {//シリアルは改行つける + i = CrLf(n,n+SDK_SER_LEN+2); + if (i == 0)ErrorStop("list broken");//改行が見つからない + }else{ + i = CrLf(n,fsize); + if (i ==0)i = fsize;//改行以外でファイル終 + } + if ((i-n) > GettedSerLen)//シリアルをリスト化 + { + j = 0; + while(n=LIST_MAX)ErrorStop("List too Long"); + } + } + if ((fsize-i) < GettedSerLen)break;//ファイル終 + n=i;//ポインタを改行の次へ + } + + //文字数チェック + //開発初期のファームアップで空ID本体が発生してたので念の為 + //2011.5現在、製品で報告はない + if (GettedSerLen < 11)ErrorStop("invalid Serial"); + + //本体シリアルがリストにあるかチェック + n =0; + while(n