mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-08 11:51:48 +00:00
gamecard: support ID set dumping.
This commit is contained in:
parent
9cc1d64694
commit
4929330e32
5 changed files with 74 additions and 3 deletions
|
@ -480,6 +480,9 @@ end:
|
|||
|
||||
utilsSetLongRunningProcessState(false);
|
||||
|
||||
FsGameCardIdSet id_set = {0};
|
||||
if (gamecardGetIdSet(&id_set)) LOG_DATA(&id_set, sizeof(FsGameCardIdSet), "Gamecard ID set:");
|
||||
|
||||
consolePrint("press any button to continue");
|
||||
utilsWaitForButtonPress(0);
|
||||
|
||||
|
|
|
@ -32,18 +32,50 @@ extern "C" {
|
|||
|
||||
/// Located at offset 0x7000 in the gamecard image.
|
||||
typedef struct {
|
||||
u8 signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over the rest of the data.
|
||||
u32 magic; ///< "CERT".
|
||||
u8 signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over the rest of the data.
|
||||
u32 magic; ///< "CERT".
|
||||
u32 version;
|
||||
u8 kek_index;
|
||||
u8 reserved[0x7];
|
||||
u8 device_id[0x10];
|
||||
u8 iv[0x10];
|
||||
u8 data[0xD0]; ///< Encrypted using the IV from this struct and an unknown key.
|
||||
u8 data[0xD0]; ///< Encrypted using the IV from this struct and an unknown key.
|
||||
} FsGameCardCertificate;
|
||||
|
||||
NXDT_ASSERT(FsGameCardCertificate, 0x200);
|
||||
|
||||
typedef struct {
|
||||
u8 maker_code; ///< Usually 0xC2 (Macronix).
|
||||
u8 memory_capacity; ///< Matches GameCardRomSize.
|
||||
u8 reserved; ///< Usually 0x0A / 0x09.
|
||||
u8 memory_type; ///< Usually 0x21.
|
||||
} FsCardId1;
|
||||
|
||||
NXDT_ASSERT(FsCardId1, 0x4);
|
||||
|
||||
typedef struct {
|
||||
u8 card_security_number; ///< Usually 0x02.
|
||||
u8 card_type; ///< Usually 0x00.
|
||||
u8 reserved[0x2]; ///< Usually filled with zeroes.
|
||||
} FsCardId2;
|
||||
|
||||
NXDT_ASSERT(FsCardId2, 0x4);
|
||||
|
||||
typedef struct {
|
||||
u8 reserved[0x4]; ///< Usually filled with zeroes.
|
||||
} FsCardId3;
|
||||
|
||||
NXDT_ASSERT(FsCardId3, 0x4);
|
||||
|
||||
/// Returned by fsDeviceOperatorGetGameCardIdSet.
|
||||
typedef struct {
|
||||
FsCardId1 id1;
|
||||
FsCardId2 id2;
|
||||
FsCardId3 id3;
|
||||
} FsGameCardIdSet;
|
||||
|
||||
NXDT_ASSERT(FsGameCardIdSet, 0xC);
|
||||
|
||||
/// IFileSystemProxy.
|
||||
Result fsOpenGameCardStorage(FsStorage *out, const FsGameCardHandle *handle, u32 partition);
|
||||
Result fsOpenGameCardDetectionEventNotifier(FsEventNotifier *out);
|
||||
|
@ -51,6 +83,7 @@ Result fsOpenGameCardDetectionEventNotifier(FsEventNotifier *out);
|
|||
/// IDeviceOperator.
|
||||
Result fsDeviceOperatorUpdatePartitionInfo(FsDeviceOperator *d, const FsGameCardHandle *handle, u32 *out_title_version, u64 *out_title_id);
|
||||
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator *d, const FsGameCardHandle *handle, FsGameCardCertificate *out);
|
||||
Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator *d, FsGameCardIdSet *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -236,6 +236,10 @@ bool gamecardReadStorage(void *out, u64 read_size, u64 offset);
|
|||
/// This area can't be read using gamecardReadStorage().
|
||||
bool gamecardGetKeyArea(GameCardKeyArea *out);
|
||||
|
||||
/// Fills the provided FsGameCardIdSet pointer.
|
||||
/// This area can't be read using gamecardReadStorage().
|
||||
bool gamecardGetIdSet(FsGameCardIdSet *out);
|
||||
|
||||
/// Fills the provided GameCardHeader pointer.
|
||||
/// This area can also be read using gamecardReadStorage(), starting at offset 0.
|
||||
bool gamecardGetHeader(GameCardHeader *out);
|
||||
|
|
|
@ -78,3 +78,17 @@ Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator *d, const F
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator *d, FsGameCardIdSet *out)
|
||||
{
|
||||
struct {
|
||||
u64 buf_size;
|
||||
} in = { sizeof(FsGameCardIdSet) };
|
||||
|
||||
Result rc = serviceDispatchIn(&d->s, 208, in,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||
.buffers = { { out, sizeof(FsGameCardIdSet) } }
|
||||
);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -347,6 +347,23 @@ bool gamecardGetKeyArea(GameCardKeyArea *out)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool gamecardGetIdSet(FsGameCardIdSet *out)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
SCOPED_LOCK(&g_gameCardMutex)
|
||||
{
|
||||
if (!g_gameCardInterfaceInit || g_gameCardStatus != GameCardStatus_InsertedAndInfoLoaded || !out) break;
|
||||
|
||||
Result rc = fsDeviceOperatorGetGameCardIdSet(&g_deviceOperator, out);
|
||||
if (R_FAILED(rc)) LOG_MSG("fsDeviceOperatorGetGameCardIdSet failed! (0x%08X)", rc);
|
||||
|
||||
ret = R_SUCCEEDED(rc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool gamecardGetHeader(GameCardHeader *out)
|
||||
{
|
||||
bool ret = false;
|
||||
|
|
Loading…
Reference in a new issue