mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
SimpleAddressが壊れている場合修正するように
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@551 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
parent
0ee21cb674
commit
e1feb8c47d
@ -139,6 +139,7 @@ typedef enum RestoreState
|
||||
REBOOTING, // 再起動を行う
|
||||
ERASE, // 削除処理を行う
|
||||
RESTORE_CAL, // cfgの一部をcal値で上書きする
|
||||
REPAIR_SIMPLE_ADDRESS_ID, // 本ツールで過去に破壊されたSimpleAddress.idを修正する
|
||||
TIME_ADJUST, // 時計あわせを行う
|
||||
DOWNLOAD_TWL, // TWLアプリ本体をダウンロードする
|
||||
WAIT_SD_EJECT, // SDカードぬき待ち
|
||||
@ -1428,9 +1429,16 @@ void ControlState(common::HardwareStateManager& manager, ::std::vector<std::stri
|
||||
if (IsImportThreadFinished())
|
||||
{
|
||||
FinalizeImportThread();
|
||||
s_RestoreState = TIME_ADJUST;
|
||||
s_RestoreState = REPAIR_SIMPLE_ADDRESS_ID;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REPAIR_SIMPLE_ADDRESS_ID:
|
||||
{
|
||||
RepairSimpleAddress();
|
||||
s_RestoreState = TIME_ADJUST;
|
||||
}
|
||||
break;
|
||||
|
||||
// 時計あわせ
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include <nn/drivers/mcu/CTR/driverMcuRegisterMap.h>
|
||||
#include <nn/ndm.h>
|
||||
#include <nn/crypto/crypto_AesCmac.h>
|
||||
#include <nn/cx.h>
|
||||
|
||||
#include "FileName.h"
|
||||
#include "Importer.h"
|
||||
@ -50,6 +51,7 @@
|
||||
#include "FileChecker.h"
|
||||
#include "VersionDetect.h"
|
||||
#include "SaveDataMover.h"
|
||||
#include "RegionIdModifier.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
@ -1941,6 +1943,88 @@ bool IsImportSucceeded()
|
||||
return s_IsImportSucceeded;
|
||||
}
|
||||
|
||||
void ReadRegionFile(const wchar_t* path, void** decode, size_t* size)
|
||||
{
|
||||
if(path == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char filePath[256];
|
||||
std::wcstombs(filePath, path, sizeof(filePath));
|
||||
|
||||
char prefix[] = "rom:/regionData/";
|
||||
|
||||
char fullPath[256];
|
||||
std::memset(fullPath, 0, sizeof(fullPath));
|
||||
strlcpy(fullPath, prefix, sizeof(fullPath));
|
||||
strlcat(fullPath, filePath, 256 - strlen(fullPath));
|
||||
NN_LOG("regionData: %s\n", fullPath);
|
||||
|
||||
nn::fs::FileInputStream file;
|
||||
file.Initialize(fullPath);
|
||||
|
||||
s64 fileSize = file.GetSize();
|
||||
common::HeapManager heap(fileSize, AES_BLOCK_SIZE);
|
||||
void* buf = heap.GetAddr();
|
||||
|
||||
file.Read(buf, fileSize);
|
||||
|
||||
*size = nn::cx::GetUncompressedSize(buf);
|
||||
nn::cx::UncompressLZ(buf, *decode);
|
||||
}
|
||||
|
||||
void RepairSimpleAddress()
|
||||
{
|
||||
nn::cfg::CTR::SimpleAddress sa;
|
||||
nn::cfg::CTR::GetSimpleAddress(&sa);
|
||||
|
||||
RegionIdModifier rim(sa.id >> 16, s_SDVersionData.nup.majorVersion, nn::cfg::CTR::GetRegion(), sa.regionName[0]);
|
||||
if(rim.IsValid())
|
||||
{
|
||||
// 壊れていなければ何もしない
|
||||
return;
|
||||
}
|
||||
|
||||
COMMON_LOGGER("Repair SimpleAddress.\n");
|
||||
|
||||
size_t size;
|
||||
PathList filePath[3];
|
||||
u8 modifiedId;
|
||||
|
||||
common::HeapManager heap(common::FILE_COPY_HEAP_SIZE / 8 , AES_BLOCK_SIZE);
|
||||
void* buf = heap.GetAddr();
|
||||
|
||||
size_t fileNum = rim.GetFilePathNum();
|
||||
|
||||
std::memset(filePath, 0, sizeof(filePath));
|
||||
std::memcpy(filePath, rim.GetFilePath(), sizeof(PathList) * fileNum);
|
||||
|
||||
for (u8 i = 0; i < fileNum; i++)
|
||||
{
|
||||
ReadRegionFile(filePath[fileNum - i - 1].path, &buf, &size);
|
||||
if (rim.GetValidRegionId(buf, size, &modifiedId))
|
||||
{
|
||||
NN_LOG("CurrentRegionId = %02x\n", (sa.id >> 16) & 0x00ff);
|
||||
NN_LOG("ValidRegionId = %02x\n", modifiedId);
|
||||
using namespace nn::cfg::CTR;
|
||||
using namespace nn::cfg::CTR::detail;
|
||||
|
||||
nn::cfg::CTR::system::Initialize();
|
||||
|
||||
SimpleAddressIdCfgData simpleAddressId;
|
||||
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::system::GetConfig(&simpleAddressId, sizeof(SimpleAddressIdCfgData), GET_CFG_KEY(NN_CFG_SIMPLE_ADDRESS, NN_CFG_SIMPLE_ADDRESS_ID)));
|
||||
|
||||
simpleAddressId.id = (simpleAddressId.id & 0xff00ffff) | (modifiedId << CFG_SIMPLE_ADDRESS_ID_REGION_SHIFT);
|
||||
|
||||
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::system::SetConfig(GET_CFG_KEY(NN_CFG_SIMPLE_ADDRESS, NN_CFG_SIMPLE_ADDRESS_ID), &simpleAddressId, sizeof(SimpleAddressIdCfgData)));
|
||||
|
||||
NN_UTIL_PANIC_IF_FAILED(nn::cfg::CTR::system::FlushConfig());
|
||||
nn::cfg::CTR::system::Finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nn::Result ImportData()
|
||||
{
|
||||
static nn::Result result = nn::ResultSuccess();
|
||||
|
||||
@ -160,6 +160,8 @@ bool ImportIvsData();
|
||||
// 書き込みが成功したかどうか
|
||||
bool IsImportSucceeded();
|
||||
|
||||
void RepairSimpleAddress();
|
||||
|
||||
}
|
||||
|
||||
#endif /* IMPORTER_H_ */
|
||||
|
||||
@ -30,6 +30,7 @@ SOURCES[] =
|
||||
Ntpclient.cpp
|
||||
TitleDownloader.cpp
|
||||
Shop.cpp
|
||||
RegionIdModifier.cpp
|
||||
../common/Util.cpp
|
||||
../common/DrawSystemState.cpp
|
||||
../common/FileTransfer.cpp
|
||||
|
||||
@ -0,0 +1,152 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: RegionIdModifier.cpp
|
||||
|
||||
Copyright (C)2011 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 "RegionIdModifier.h"
|
||||
#include <cwchar>
|
||||
#include <cstring>
|
||||
|
||||
struct CountryData
|
||||
{
|
||||
u32 id; // 上記定数にあるように、国IDと地域IDを組み合わせたID
|
||||
u16 regionName[16][64]; // NULL終端込み
|
||||
u8 order[16]; // 言語ごとの地域名並び順(「未設定」が0になるので、最初の地域は1)
|
||||
u16 latitude; // リストの値を 65536/360 倍して格納して下さい
|
||||
u16 longitude; // リストの値を 65536/360 倍して格納して下さい
|
||||
};
|
||||
|
||||
const size_t NUP_VERSION_TO_REGIONNUM[] =
|
||||
{
|
||||
1, // ローンチ(0)
|
||||
1, // 0thNUP(1)
|
||||
2, // 1stNUP(2)
|
||||
2, // 1.05NUP(3)
|
||||
2, // 1.1NUP(4)
|
||||
3, // 2ndNUP(5)
|
||||
3, // 2.1NUP(6)
|
||||
};
|
||||
|
||||
const wchar_t* DIR_PATH[] =
|
||||
{
|
||||
L"0/JP/",
|
||||
L"0/US/",
|
||||
L"0/EU/",
|
||||
L"2/JP/",
|
||||
L"2/US/",
|
||||
L"2/EU/",
|
||||
L"5/JP/",
|
||||
L"5/US/",
|
||||
L"5/EU/"
|
||||
};
|
||||
|
||||
RegionIdModifier::RegionIdModifier(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName)
|
||||
{
|
||||
m_Id = id;
|
||||
m_NupVersion = nupVersion;
|
||||
m_RegionCode = regionCode;
|
||||
if (regionName != NULL)
|
||||
{
|
||||
std::wcsncpy(m_RegionName, regionName, sizeof(m_RegionName) / sizeof(wchar_t));
|
||||
}
|
||||
}
|
||||
|
||||
bool RegionIdModifier::IsValid()
|
||||
{
|
||||
return (m_Id & 0x000f) != 0x01;
|
||||
}
|
||||
|
||||
const PathList* RegionIdModifier::GetDirectoryPath()
|
||||
{
|
||||
// 範囲外のリージョン
|
||||
if (2 < m_RegionCode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (u8 i = 0; i < 3; i++)
|
||||
{
|
||||
std::wcsncpy(m_DirectoryPathBuf[i].path, DIR_PATH[m_RegionCode + i * 3], 32);
|
||||
}
|
||||
|
||||
return m_DirectoryPathBuf;
|
||||
}
|
||||
|
||||
size_t RegionIdModifier::GetDirectoryPathNum()
|
||||
{
|
||||
// 範囲外のリージョン
|
||||
if (2 < m_RegionCode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const size_t countryNum = sizeof(NUP_VERSION_TO_REGIONNUM) / sizeof(NUP_VERSION_TO_REGIONNUM[0]);
|
||||
if (m_NupVersion > countryNum - 1)
|
||||
{
|
||||
return NUP_VERSION_TO_REGIONNUM[countryNum - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NUP_VERSION_TO_REGIONNUM[m_NupVersion];
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t* RegionIdModifier::GetFileName()
|
||||
{
|
||||
std::swprintf(m_FileNameBuf, sizeof(m_FileNameBuf), L"%d_LZ.bin", m_Id >> 8);
|
||||
return m_FileNameBuf;
|
||||
}
|
||||
|
||||
const PathList* RegionIdModifier::GetFilePath()
|
||||
{
|
||||
std::memset(m_FilePathBuf, 0, sizeof(m_FilePathBuf));
|
||||
GetDirectoryPath();
|
||||
for (u8 i = 0; i < GetDirectoryPathNum(); i++)
|
||||
{
|
||||
size_t writeSize = std::wcslen(m_DirectoryPathBuf[i].path);
|
||||
std::wcsncpy(m_FilePathBuf[i].path, m_DirectoryPathBuf[i].path, writeSize);
|
||||
std::wcsncat(m_FilePathBuf[i].path, GetFileName(), 32 - writeSize);
|
||||
}
|
||||
|
||||
return m_FilePathBuf;
|
||||
}
|
||||
|
||||
size_t RegionIdModifier::GetFilePathNum()
|
||||
{
|
||||
return GetDirectoryPathNum();
|
||||
}
|
||||
|
||||
bool RegionIdModifier::GetValidRegionId(void* buf, size_t size, u8* id)
|
||||
{
|
||||
if (buf == NULL || size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 numRegion; // その国に含まれる地域の数
|
||||
numRegion = *reinterpret_cast<u32*>(buf);
|
||||
|
||||
CountryData* pCountry;
|
||||
pCountry = reinterpret_cast<CountryData*>(&reinterpret_cast<u32*>(buf)[1]);
|
||||
|
||||
for (u32 i = 0; i < numRegion + 1; i++)
|
||||
{
|
||||
if (std::wcscmp(m_RegionName, reinterpret_cast<wchar_t*>(pCountry->regionName[0])) == 0)
|
||||
{
|
||||
*id = (pCountry->id >> 16) & 0x00ff;
|
||||
return true;
|
||||
}
|
||||
pCountry++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: Horizon
|
||||
File: RegionIdModifier.h
|
||||
|
||||
Copyright (C)2011 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:$
|
||||
*---------------------------------------------------------------------------*/
|
||||
#ifndef _REGION_ID_MODIFIER_H_
|
||||
#define _REGION_ID_MODIFIER_H_
|
||||
|
||||
#include <nn.h>
|
||||
|
||||
struct PathList
|
||||
{
|
||||
wchar_t path[32];
|
||||
};
|
||||
|
||||
//! @brief データ移行ツールで破壊した地域idを修正するためのクラスです
|
||||
class RegionIdModifier
|
||||
{
|
||||
public:
|
||||
//! @brief パラメータを与えて初期化します。
|
||||
//! @param[in] id SimpleAddressの上位16ビット
|
||||
//! @param[in] nupVersion NUPバージョン
|
||||
//! @param[in] regionCode リージョン
|
||||
//! @param[in] regionName 地域名
|
||||
RegionIdModifier(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName);
|
||||
~RegionIdModifier() {};
|
||||
|
||||
//! @brief 正しいIDかどうか
|
||||
bool IsValid();
|
||||
|
||||
//! @brief バージョン、リージョンに応じたディレクトリパスの配列を取得します
|
||||
//! @return パス名。バージョン・リージョンが正しくない場合はNULL
|
||||
const PathList* GetDirectoryPath();
|
||||
|
||||
//! @brief バージョン、リージョンに応じたディレクトリパス数を取得します
|
||||
size_t GetDirectoryPathNum();
|
||||
|
||||
//! @brief 国idに応じたファイル名を取得します
|
||||
const wchar_t* GetFileName();
|
||||
|
||||
//! @brief バージョン、リージョン、国idに応じたファイルパスの配列を取得します
|
||||
const PathList* GetFilePath();
|
||||
|
||||
//! @brief バージョン、リージョン、国idに応じたファイルパス数を取得します
|
||||
size_t GetFilePathNum();
|
||||
|
||||
//! @brief 与えられたバッファから正しい地域idを取得します
|
||||
//! @param[in] buf 展開済みの地域データの入ったバッファ
|
||||
//! @param[in] size バッファサイズ
|
||||
//! @param[out] id 正しいid
|
||||
//! @return 正しいidが見つかったかどうか
|
||||
bool GetValidRegionId(void* buf , size_t size, u8* id);
|
||||
|
||||
private:
|
||||
//! @brief SimpleAddressの上位16ビット
|
||||
// 上位8ビットが国id,下位8ビットが地域
|
||||
u16 m_Id;
|
||||
|
||||
//! @brief NUPバージョン番号
|
||||
u8 m_NupVersion;
|
||||
//! @brief リージョンコード
|
||||
u8 m_RegionCode;
|
||||
//! @brief 地域名
|
||||
wchar_t m_RegionName[64];
|
||||
|
||||
//! @brief ファイル名を保存するバッファ
|
||||
wchar_t m_FileNameBuf[32];
|
||||
//! @brief ディレクトリパスを保存するバッファ
|
||||
PathList m_DirectoryPathBuf[3];
|
||||
//! @brief ファイルパスを保存するバッファ
|
||||
PathList m_FilePathBuf[3];
|
||||
};
|
||||
|
||||
#endif // _REGION_ID_MODIFIER_H_
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user