Skip to content

Commit

Permalink
Some updates
Browse files Browse the repository at this point in the history
* fs_ext: rename `sel_t1_key` field in `FsCardId2` struct to `card_security_number`.
* fs_ext: add `FsCardId2CardSecurityNumber` enum.

* gamecard: add `GameCardUid` struct.
* gamecard: add `GameCardUidMakerCode` enum.
* gamecard: add `GameCardUidCardType` enum.
* gamecard: update `GameCardSpecificData` struct to reflect the other changes.

* lz4: update to v1.10.0.

* npdm: update `NpdmMetaFlags` struct.

* nso: rename `entry_point` field in `NsoModStart` struct to `version`.
* nso: add `NsoNnSdkVersion` struct.
* nso: update code to make it retrieve nnSdk version info from input NSOs whenever possible.

* GameCardImageDumpTask: fix gamecard image dumping with prepended key areas.
  • Loading branch information
DarkMatterCore committed Aug 6, 2024
1 parent d64c4de commit 414780a
Show file tree
Hide file tree
Showing 9 changed files with 614 additions and 316 deletions.
4 changes: 2 additions & 2 deletions code_templates/nxdt_rw_poc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2810,13 +2810,13 @@ static bool saveGameCardUid(void *userdata)
goto end;
}

crc = crc32Calculate(gc_security_information.specific_data.card_uid, sizeof(gc_security_information.specific_data.card_uid));
crc = crc32Calculate(&(gc_security_information.specific_data.card_uid), sizeof(gc_security_information.specific_data.card_uid));
snprintf(path, MAX_ELEMENTS(path), " (Card UID) (%08X).bin", crc);

filename = generateOutputGameCardFileName("Gamecard", path, true);
if (!filename) goto end;

if (!saveFileData(filename, gc_security_information.specific_data.card_uid, sizeof(gc_security_information.specific_data.card_uid))) goto end;
if (!saveFileData(filename, &(gc_security_information.specific_data.card_uid), sizeof(gc_security_information.specific_data.card_uid))) goto end;

consolePrint("successfully saved gamecard uid as \"%s\"\n", filename);
success = true;
Expand Down
15 changes: 12 additions & 3 deletions include/core/fs_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ typedef struct {

NXDT_ASSERT(FsCardId1, 0x4);

typedef enum {
FsCardId2CardSecurityNumber_Number0 = 0,
FsCardId2CardSecurityNumber_Number1 = 1,
FsCardId2CardSecurityNumber_Number2 = 2,
FsCardId2CardSecurityNumber_Number3 = 3,
FsCardId2CardSecurityNumber_Number4 = 4,
FsCardId2CardSecurityNumber_Count = 5 ///< Total values supported by this enum.
} FsCardId2CardSecurityNumber;

typedef enum {
FsCardId2CardType_Rom = 0,
FsCardId2CardType_WritableDevT1 = 1,
Expand All @@ -93,9 +102,9 @@ typedef enum {
} FsCardId2CardType;

typedef struct {
u8 sel_t1_key; ///< Matches sel_t1_key value from GameCardHeader (usually 0x02).
u8 card_type; ///< FsCardId2CardType.
u8 reserved[0x2]; ///< Usually filled with zeroes.
u8 card_security_number; ///< FsCardId2CardSecurityNumber.
u8 card_type; ///< FsCardId2CardType.
u8 reserved[0x2]; ///< Usually filled with zeroes.
} FsCardId2;

NXDT_ASSERT(FsCardId2, 0x4);
Expand Down
36 changes: 32 additions & 4 deletions include/core/gamecard.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,44 @@ typedef struct {

NXDT_ASSERT(GameCardKeyArea, 0x1000);

typedef enum {
GameCardUidMakerCode_MegaChips = 0,
GameCardUidMakerCode_Lapis = 1,
GameCardUidMakerCode_Unknown = 2,
GameCardUidMakerCode_Count = 3 ///< Total values supported by this enum.
} GameCardUidMakerCode;

typedef enum {
GameCardUidCardType_Rom = 0,
GameCardUidCardType_WritableDev = 0xFE,
GameCardUidCardType_WritableProd = 0xFF,
GameCardUidCardType_Count = 3 ///< Total values supported by this enum.
} GameCardUidCardType;

typedef struct {
u8 maker_code; ///< GameCardUidMakerCode.
u8 version;
u8 card_type; ///< GameCardUidCardType.
u8 unique_data[0x9];
u32 random;
u8 platform_flag;
u8 reserved[0xB];
FsCardId1 card_id_1; ///< Are we sure about this?
u8 mac[0x20];
} GameCardUid;

NXDT_ASSERT(GameCardUid, 0x40);

/// Plaintext area. Dumped from FS program memory.
/// Overall structure may change with each new LAFW version.
typedef struct {
u32 asic_security_mode; ///< Determines how the Lotus ASIC initialised the gamecard security mode. Usually 0xFFFFFFF9.
u32 asic_status; ///< Bitmask of the internal gamecard interface status. Usually 0x20000000.
u32 asic_security_mode; ///< Determines how the Lotus ASIC initialised the gamecard security mode. Usually 0xFFFFFFF9.
u32 asic_status; ///< Bitmask of the internal gamecard interface status. Usually 0x20000000.
FsCardId1 card_id1;
FsCardId2 card_id2;
u8 card_uid[0x40];
GameCardUid card_uid;
u8 reserved[0x190];
u8 asic_session_hash[0x20]; ///< Changes with each gamecard (re)insertion.
u8 mac[0x20]; ///< Changes with each gamecard (re)insertion.
} GameCardSpecificData;

NXDT_ASSERT(GameCardSpecificData, 0x200);
Expand Down
180 changes: 111 additions & 69 deletions include/core/lz4.h

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion include/core/npdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ typedef struct {
u8 process_address_space : 3; ///< NpdmProcessAddressSpace.
u8 optimize_memory_allocation : 1;
u8 disable_device_address_space_merge : 1;
u8 reserved : 2;
u8 enable_alias_region_extra_size : 1;
u8 reserved : 1;
} NpdmMetaFlags;

NXDT_ASSERT(NpdmMetaFlags, 0x1);
Expand Down
32 changes: 18 additions & 14 deletions include/core/nso.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,17 @@ typedef struct {
NXDT_ASSERT(NsoSectionInfo, 0x8);

/// This is the start of every NSO.
/// This is always followed by a NsoModuleName block.
/// This can be optionally followed by the NSO module name.
/// If available, the 'module_name_size' member is greater than 1, and the 'module_name_offset' member will usually be set to 0x100 (the size of this header).
typedef struct {
u32 magic; ///< "NSO0".
u32 version; ///< Always set to 0.
u8 reserved_1[0x4];
u32 flags; ///< NsoFlags.
NsoSegmentInfo text_segment_info;
u32 module_name_offset; ///< NsoModuleName block offset.
u32 module_name_offset; ///< NSO module name offset.
NsoSegmentInfo rodata_segment_info;
u32 module_name_size; ///< NsoModuleName block size.
u32 module_name_size; ///< NSO module name size.
NsoSegmentInfo data_segment_info;
u32 bss_size;
u8 module_id[0x20]; ///< Also known as build ID.
Expand All @@ -87,19 +88,10 @@ typedef struct {

NXDT_ASSERT(NsoHeader, 0x100);

/// Usually placed right after NsoHeader, but its actual offset may vary.
/// If the 'module_name_size' member from NsoHeader is greater than 1 and the 'name_length' element from NsoModuleName is greater than 0, 'name' will hold the module name.
typedef struct {
u8 name_length;
char name[];
} NsoModuleName;

NXDT_ASSERT(NsoModuleName, 0x1);

/// Placed at the very start of the decompressed .text segment.
typedef struct {
u32 entry_point;
u32 mod_offset; ///< NsoModHeader block offset (relative to the start of this header). Almost always set to 0x8 (the size of this struct).
u32 version; ///< Usually set to 0 or a branch instruction (0x14000002). Set to 1 or 0x14000003 if a NsoNnSdkVersion block is available.
s32 mod_offset; ///< NsoModHeader block offset (relative to the start of this header). Almost always set to 0x8 (the size of this struct).
} NsoModStart;

NXDT_ASSERT(NsoModStart, 0x8);
Expand All @@ -121,6 +113,16 @@ typedef struct {

NXDT_ASSERT(NsoModHeader, 0x1C);

/// Only available in 17.0.0+ binaries. Holds the nnSdk version used to build this NRO.
/// This is usually placed right after the NsoModHeader block.
typedef struct {
u32 major;
u32 minor;
u32 micro;
} NsoNnSdkVersion;

NXDT_ASSERT(NsoNnSdkVersion, 0xC);

/// Placed at the start of the decompressed .rodata segment + 0x4.
/// If the 'name_length' element is greater than 0, 'name' will hold the module name.
typedef struct {
Expand All @@ -136,6 +138,7 @@ typedef struct {
char *nso_filename; ///< Pointer to the NSO filename in the Program NCA FS section #0.
NsoHeader nso_header; ///< NSO header.
char *module_name; ///< Pointer to a dynamically allocated buffer that holds the NSO module name, if available. Otherwise, this is set to NULL.
NsoNnSdkVersion *nnsdk_version; ///< Pointer to a dynamically allocated buffer that holds the nnSdk version info, if available. Otherwise, this is set to NULL.
char *module_info_name; ///< Pointer to a dynamically allocated buffer that holds the .rodata module info module name, if available. Otherwise, this is set to NULL.
char *rodata_api_info_section; ///< Pointer to a dynamically allocated buffer that holds the .rodata API info section data, if available. Otherwise, this is set to NULL.
///< Middleware and GuidelineApi entries are retrieved from this section.
Expand All @@ -155,6 +158,7 @@ NX_INLINE void nsoFreeContext(NsoContext *nso_ctx)
{
if (!nso_ctx) return;
if (nso_ctx->module_name) free(nso_ctx->module_name);
if (nso_ctx->nnsdk_version) free(nso_ctx->nnsdk_version);
if (nso_ctx->module_info_name) free(nso_ctx->module_info_name);
if (nso_ctx->rodata_api_info_section) free(nso_ctx->rodata_api_info_section);
if (nso_ctx->rodata_dynstr_section) free(nso_ctx->rodata_dynstr_section);
Expand Down
Loading

0 comments on commit 414780a

Please sign in to comment.