mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-12-22 16:42:11 +00:00
*FormattedStringToBuffer: relax input validation
Affects both utilsAppendFormattedStringToBuffer() and logWriteFormattedStringToBuffer(). Fixes logging issues within both the exception handler and memory debugging code. Other changes include: * bfttf: rename BfttfFontType_Total -> BfttfFontType_Count. * config: rename "append_authoringtool_data" -> "generate_authoringtool_data". * fs_ext: update FsGameCardCertificate struct * gamecard: fix gamecardReadLotusAsicFirmwareBlob() not returning false if FS .data segment memory couldn't be retrieved; update GameCardInfo struct to reflect a recently discovered area that's not zeroed out. * mem: expand MemoryProgramSegmentType enum; define extra macros for PID buffer size and memory page type checks; force empty memory page attribute and R/X permission checks while looking for the last FS .text segment; make memory page filtering code more readable. * npdm: rename KernelCapability enums; rename entry_value -> bitmask in all KernelCapability descriptor structs. * tik: force byte-for-byte memory lookup while dumping volatile tickets. * libs: update libusbhsfs to latest commit. * codebase: add missing comments to some enums; add missing "None" and "Count" elements to some enums. "Count" entries from enums with bitmasks will only reflect the number of available bitmask values. Enums with hex values remain unchanged. * PoC builds: use EXIT_SUCCESS and EXIT_FAILURE as return values. * nxdt_rw_poc: move "end" jump label within main() to avoid a crash if utilsInitializeResources() fails; reflect changes in config.c.
This commit is contained in:
parent
51b17f35fe
commit
8f75b6b923
34 changed files with 387 additions and 289 deletions
|
@ -257,8 +257,8 @@ static void setNspEnableVideoCaptureOption(u32 idx);
|
|||
static u32 getNspDisableHdcpOption(void);
|
||||
static void setNspDisableHdcpOption(u32 idx);
|
||||
|
||||
static u32 getNspAppendAuthoringToolDataOption(void);
|
||||
static void setNspAppendAuthoringToolDataOption(u32 idx);
|
||||
static u32 getNspGenerateAuthoringToolDataOption(void);
|
||||
static void setNspGenerateAuthoringToolDataOption(u32 idx);
|
||||
|
||||
static u32 getTicketRemoveConsoleDataOption(void);
|
||||
static void setTicketRemoveConsoleDataOption(u32 idx);
|
||||
|
@ -589,13 +589,13 @@ static MenuElement *g_nspMenuElements[] = {
|
|||
.userdata = NULL
|
||||
},
|
||||
&(MenuElement){
|
||||
.str = "nsp: append authoringtool data",
|
||||
.str = "nsp: generate authoringtool data",
|
||||
.child_menu = NULL,
|
||||
.task_func = NULL,
|
||||
.element_options = &(MenuElementOption){
|
||||
.selected = 1,
|
||||
.getter_func = &getNspAppendAuthoringToolDataOption,
|
||||
.setter_func = &setNspAppendAuthoringToolDataOption,
|
||||
.getter_func = &getNspGenerateAuthoringToolDataOption,
|
||||
.setter_func = &setNspGenerateAuthoringToolDataOption,
|
||||
.options = g_noYesStrings
|
||||
},
|
||||
.userdata = NULL
|
||||
|
@ -876,11 +876,11 @@ static char path[FS_MAX_PATH] = {0};
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
if (!utilsInitializeResources(argc, (const char**)argv))
|
||||
{
|
||||
ret = -1;
|
||||
ret = EXIT_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -1356,7 +1356,6 @@ int main(int argc, char *argv[])
|
|||
if (btn_held & (HidNpadButton_StickLDown | HidNpadButton_StickRDown | HidNpadButton_StickLUp | HidNpadButton_StickRUp | HidNpadButton_ZL | HidNpadButton_ZR)) svcSleepThread(40000000); // 40 ms
|
||||
}
|
||||
|
||||
end:
|
||||
freeNcaFsSectionsList();
|
||||
|
||||
freeNcaList();
|
||||
|
@ -1367,6 +1366,7 @@ end:
|
|||
|
||||
titleFreeUserApplicationData(&user_app_data);
|
||||
|
||||
end:
|
||||
utilsCloseResources();
|
||||
|
||||
consoleExit(NULL);
|
||||
|
@ -4716,7 +4716,7 @@ static void nspThreadFunc(void *arg)
|
|||
bool patch_screenshot = (bool)getNspEnableScreenshotsOption();
|
||||
bool patch_video_capture = (bool)getNspEnableVideoCaptureOption();
|
||||
bool patch_hdcp = (bool)getNspDisableHdcpOption();
|
||||
bool append_authoringtool_data = (bool)getNspAppendAuthoringToolDataOption();
|
||||
bool generate_authoringtool_data = (bool)getNspGenerateAuthoringToolDataOption();
|
||||
bool success = false;
|
||||
|
||||
u64 free_space = 0;
|
||||
|
@ -4783,7 +4783,7 @@ static void nspThreadFunc(void *arg)
|
|||
}
|
||||
|
||||
// determine if we should initialize programinfo ctx
|
||||
if (append_authoringtool_data)
|
||||
if (generate_authoringtool_data)
|
||||
{
|
||||
program_count = titleGetContentCountByType(title_info, NcmContentType_Program);
|
||||
if (program_count && !(program_info_ctx = calloc(program_count, sizeof(ProgramInfoContext))))
|
||||
|
@ -4794,7 +4794,7 @@ static void nspThreadFunc(void *arg)
|
|||
}
|
||||
|
||||
// determine if we should initialize nacp ctx
|
||||
if (patch_sua || patch_screenshot || patch_video_capture || patch_hdcp || append_authoringtool_data)
|
||||
if (patch_sua || patch_screenshot || patch_video_capture || patch_hdcp || generate_authoringtool_data)
|
||||
{
|
||||
control_count = titleGetContentCountByType(title_info, NcmContentType_Control);
|
||||
if (control_count && !(nacp_ctx = calloc(control_count, sizeof(NacpContext))))
|
||||
|
@ -4805,7 +4805,7 @@ static void nspThreadFunc(void *arg)
|
|||
}
|
||||
|
||||
// determine if we should initialize legalinfo ctx
|
||||
if (append_authoringtool_data)
|
||||
if (generate_authoringtool_data)
|
||||
{
|
||||
legal_info_count = titleGetContentCountByType(title_info, NcmContentType_LegalInformation);
|
||||
if (legal_info_count && !(legal_info_ctx = calloc(legal_info_count, sizeof(LegalInfoContext))))
|
||||
|
@ -4923,7 +4923,7 @@ static void nspThreadFunc(void *arg)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (append_authoringtool_data && !nacpGenerateAuthoringToolXml(cur_nacp_ctx, title_info->version.value, cnmtGetRequiredTitleVersion(&cnmt_ctx)))
|
||||
if (generate_authoringtool_data && !nacpGenerateAuthoringToolXml(cur_nacp_ctx, title_info->version.value, cnmtGetRequiredTitleVersion(&cnmt_ctx)))
|
||||
{
|
||||
consolePrint("nacp xml failed (%s)\n", cur_nca_ctx->content_id_str);
|
||||
goto end;
|
||||
|
@ -4972,7 +4972,7 @@ static void nspThreadFunc(void *arg)
|
|||
|
||||
// generate cnmt xml right away even though we don't yet have all the data we need
|
||||
// This is because we need its size to calculate the full nsp size
|
||||
if (append_authoringtool_data && !cnmtGenerateAuthoringToolXml(&cnmt_ctx, nca_ctx, title_info->content_count))
|
||||
if (generate_authoringtool_data && !cnmtGenerateAuthoringToolXml(&cnmt_ctx, nca_ctx, title_info->content_count))
|
||||
{
|
||||
consolePrint("cnmt xml #1 failed\n");
|
||||
goto end;
|
||||
|
@ -5019,7 +5019,7 @@ static void nspThreadFunc(void *arg)
|
|||
}
|
||||
|
||||
// add cnmt xml info
|
||||
if (append_authoringtool_data)
|
||||
if (generate_authoringtool_data)
|
||||
{
|
||||
sprintf(entry_name, "%s.cnmt.xml", meta_nca_ctx->content_id_str);
|
||||
if (!pfsAddEntryInformationToFileContext(&pfs_file_ctx, entry_name, cnmt_ctx.authoring_tool_xml_size, &(meta_nca_ctx->content_type_ctx_data_idx)))
|
||||
|
@ -5030,7 +5030,7 @@ static void nspThreadFunc(void *arg)
|
|||
}
|
||||
|
||||
// add content type ctx data info
|
||||
u32 limit = append_authoringtool_data ? (title_info->content_count - 1) : 0;
|
||||
u32 limit = generate_authoringtool_data ? (title_info->content_count - 1) : 0;
|
||||
for(u32 i = 0; i < limit; i++)
|
||||
{
|
||||
bool ret = false;
|
||||
|
@ -5275,7 +5275,7 @@ static void nspThreadFunc(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (append_authoringtool_data)
|
||||
if (generate_authoringtool_data)
|
||||
{
|
||||
// regenerate cnmt xml
|
||||
if (!cnmtGenerateAuthoringToolXml(&cnmt_ctx, nca_ctx, title_info->content_count))
|
||||
|
@ -5643,14 +5643,14 @@ static void setNspDisableHdcpOption(u32 idx)
|
|||
configSetBoolean("nsp/disable_hdcp", (bool)idx);
|
||||
}
|
||||
|
||||
static u32 getNspAppendAuthoringToolDataOption(void)
|
||||
static u32 getNspGenerateAuthoringToolDataOption(void)
|
||||
{
|
||||
return (u32)configGetBoolean("nsp/append_authoringtool_data");
|
||||
return (u32)configGetBoolean("nsp/generate_authoringtool_data");
|
||||
}
|
||||
|
||||
static void setNspAppendAuthoringToolDataOption(u32 idx)
|
||||
static void setNspGenerateAuthoringToolDataOption(u32 idx)
|
||||
{
|
||||
configSetBoolean("nsp/append_authoringtool_data", (bool)idx);
|
||||
configSetBoolean("nsp/generate_authoringtool_data", (bool)idx);
|
||||
}
|
||||
|
||||
static u32 getTicketRemoveConsoleDataOption(void)
|
||||
|
|
|
@ -262,11 +262,11 @@ static void dumpFsSection(TitleInfo *info, NcaFsSectionContext *nca_fs_ctx)
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
if (!utilsInitializeResources(argc, (const char**)argv))
|
||||
{
|
||||
ret = -1;
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,11 +81,11 @@ static void writeFile(void *buf, size_t buf_size, const char *path)
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
if (!utilsInitializeResources(argc, (const char**)argv))
|
||||
{
|
||||
ret = -1;
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ typedef enum {
|
|||
BfttfFontType_ChineseSimplified = 3, ///< Simplified Chinese.
|
||||
BfttfFontType_ExtChineseSimplified = 4, ///< Extended Simplified Chinese.
|
||||
BfttfFontType_ChineseTraditional = 5, ///< Traditional Chinese.
|
||||
BfttfFontType_Total = 6 ///< Total fonts supported by this enum.
|
||||
BfttfFontType_Count = 6 ///< Total fonts supported by this enum.
|
||||
} BfttfFontType;
|
||||
|
||||
/// Loosely based on PlFontData.
|
||||
|
|
|
@ -70,7 +70,8 @@ NXDT_ASSERT(BucketTreeOffsetNode, BKTR_NODE_SIZE);
|
|||
/// IndirectStorage-related elements.
|
||||
typedef enum {
|
||||
BucketTreeIndirectStorageIndex_Original = 0,
|
||||
BucketTreeIndirectStorageIndex_Patch = 1
|
||||
BucketTreeIndirectStorageIndex_Patch = 1,
|
||||
BucketTreeIndirectStorageIndex_Count = 2 ///< Total values supported by this enum.
|
||||
} BucketTreeIndirectStorageIndex;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
@ -86,7 +87,8 @@ NXDT_ASSERT(BucketTreeIndirectStorageEntry, BKTR_INDIRECT_ENTRY_SIZE);
|
|||
/// AesCtrExStorage-related elements.
|
||||
typedef enum {
|
||||
BucketTreeAesCtrExStorageEncryption_Enabled = 0,
|
||||
BucketTreeAesCtrExStorageEncryption_Disabled = 1
|
||||
BucketTreeAesCtrExStorageEncryption_Disabled = 1,
|
||||
BucketTreeAesCtrExStorageEncryption_Count = 2 ///< Total values supported by this enum.
|
||||
} BucketTreeAesCtrExStorageEncryption;
|
||||
|
||||
typedef struct {
|
||||
|
@ -100,10 +102,11 @@ NXDT_ASSERT(BucketTreeAesCtrExStorageEntry, BKTR_AES_CTR_EX_ENTRY_SIZE);
|
|||
|
||||
/// CompressedStorage-related elements.
|
||||
typedef enum {
|
||||
BucketTreeCompressedStorageCompressionType_None = 0,
|
||||
BucketTreeCompressedStorageCompressionType_Zero = 1,
|
||||
BucketTreeCompressedStorageCompressionType_2 = 2,
|
||||
BucketTreeCompressedStorageCompressionType_LZ4 = 3
|
||||
BucketTreeCompressedStorageCompressionType_None = 0,
|
||||
BucketTreeCompressedStorageCompressionType_Zero = 1,
|
||||
BucketTreeCompressedStorageCompressionType_2 = 2,
|
||||
BucketTreeCompressedStorageCompressionType_LZ4 = 3,
|
||||
BucketTreeCompressedStorageCompressionType_Count = 4 ///< Total values supported by this enum.
|
||||
} BucketTreeCompressedStorageCompressionType;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -46,7 +46,8 @@ NXDT_ASSERT(CertSig##sigtype##PubKey##pubkeytype, certsize);
|
|||
typedef enum {
|
||||
CertPubKeyType_Rsa4096 = 0,
|
||||
CertPubKeyType_Rsa2048 = 1,
|
||||
CertPubKeyType_Ecc480 = 2
|
||||
CertPubKeyType_Ecc480 = 2,
|
||||
CertPubKeyType_Count = 3 ///< Total values supported by this enum.
|
||||
} CertPubKeyType;
|
||||
|
||||
/// Placed after the certificate signature block.
|
||||
|
@ -121,7 +122,8 @@ typedef enum {
|
|||
CertType_SigEcc480_PubKeyEcc480 = 9,
|
||||
CertType_SigHmac160_PubKeyRsa4096 = 10,
|
||||
CertType_SigHmac160_PubKeyRsa2048 = 11,
|
||||
CertType_SigHmac160_PubKeyEcc480 = 12
|
||||
CertType_SigHmac160_PubKeyEcc480 = 12,
|
||||
CertType_Count = 13 ///< Total values supported by this enum.
|
||||
} CertType;
|
||||
|
||||
/// Used to store certificate type, size and raw data.
|
||||
|
|
|
@ -34,6 +34,7 @@ extern "C" {
|
|||
|
||||
/// Equivalent to NcmContentMetaAttribute.
|
||||
typedef enum {
|
||||
ContentMetaAttribute_None = 0,
|
||||
ContentMetaAttribute_IncludesExFatDriver = BIT(0),
|
||||
ContentMetaAttribute_Rebootless = BIT(1),
|
||||
ContentMetaAttribute_Compacted = BIT(2), ///< One or more NCAs use SparseInfo data.
|
||||
|
@ -41,6 +42,7 @@ typedef enum {
|
|||
} ContentMetaAttribute;
|
||||
|
||||
typedef enum {
|
||||
ContentMetaInstallState_None = 0,
|
||||
ContentMetaInstallState_Committed = BIT(0),
|
||||
ContentMetaInstallState_Count = 1 ///< Total values supported by this enum.
|
||||
} ContentMetaInstallState;
|
||||
|
@ -98,6 +100,7 @@ typedef struct {
|
|||
NXDT_ASSERT(ContentMetaPatchMetaExtendedHeader, 0x18);
|
||||
|
||||
typedef enum {
|
||||
ContentMetaContentAccessibility_None = 0,
|
||||
ContentMetaContentAccessibility_Individual = BIT(0),
|
||||
ContentMetaContentAccessibility_Count = 1 ///< Total values supported by this enum.
|
||||
} ContentMetaContentAccessibility;
|
||||
|
@ -149,7 +152,8 @@ typedef enum {
|
|||
ContentMetaFirmwareVariationVersion_Invalid = 0,
|
||||
ContentMetaFirmwareVariationVersion_V1 = 1,
|
||||
ContentMetaFirmwareVariationVersion_V2 = 2,
|
||||
ContentMetaFirmwareVariationVersion_Unknown = 3
|
||||
ContentMetaFirmwareVariationVersion_Unknown = 3,
|
||||
ContentMetaFirmwareVariationVersion_Count = 4 ///< Total values supported by this enum.
|
||||
} ContentMetaFirmwareVariationVersion;
|
||||
|
||||
/// Header for the extended data region in the SystemUpdate title, pointed to by the extended header.
|
||||
|
@ -240,7 +244,8 @@ NXDT_ASSERT(ContentMetaPatchDeltaHeader, 0x28);
|
|||
typedef enum {
|
||||
ContentMetaUpdateType_ApplyAsDelta = 0,
|
||||
ContentMetaUpdateType_Overwrite = 1,
|
||||
ContentMetaUpdateType_Create = 2
|
||||
ContentMetaUpdateType_Create = 2,
|
||||
ContentMetaUpdateType_Count = 3 ///< Total values supported by this enum.
|
||||
} ContentMetaUpdateType;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
|
|
@ -33,14 +33,14 @@ extern "C" {
|
|||
typedef enum {
|
||||
ConfigOutputStorage_SdCard = 0,
|
||||
ConfigOutputStorage_UsbHost = 1,
|
||||
ConfigOutputStorage_Count = 2
|
||||
ConfigOutputStorage_Count = 2 ///< Total values supported by this enum.
|
||||
} ConfigOutputStorage;
|
||||
|
||||
typedef enum {
|
||||
ConfigChecksumLookupMethod_None = 0,
|
||||
ConfigChecksumLookupMethod_NSWDB = 1,
|
||||
ConfigChecksumLookupMethod_NoIntro = 2,
|
||||
ConfigChecksumLookupMethod_Count = 3
|
||||
ConfigChecksumLookupMethod_Count = 3 ///< Total values supported by this enum.
|
||||
} ConfigChecksumLookupMethod;
|
||||
|
||||
/// Initializes the configuration interface.
|
||||
|
|
|
@ -32,14 +32,15 @@ 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 t1_card_device_id[0x10];
|
||||
u8 iv[0x10];
|
||||
u8 data[0xD0]; ///< Encrypted using the IV from this struct and an unknown key.
|
||||
u8 hw_key[0x10]; ///< Encrypted.
|
||||
u8 data[0xC0]; ///< Encrypted.
|
||||
} FsGameCardCertificate;
|
||||
|
||||
NXDT_ASSERT(FsGameCardCertificate, 0x200);
|
||||
|
|
|
@ -40,20 +40,6 @@ extern "C" {
|
|||
|
||||
#define GAMECARD_CERTIFICATE_OFFSET 0x7000
|
||||
|
||||
/// 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.
|
||||
FsCardId1 card_id1;
|
||||
FsCardId2 card_id2;
|
||||
u8 card_uid[0x40];
|
||||
u8 reserved[0x190];
|
||||
u8 asic_session_hash[0x20]; ///< Changes with each gamecard (re)insertion.
|
||||
} GameCardSpecificData;
|
||||
|
||||
NXDT_ASSERT(GameCardSpecificData, 0x200);
|
||||
|
||||
/// Encrypted using AES-128-ECB with the common titlekek generator key (stored in the .rodata segment from the Lotus firmware).
|
||||
typedef struct {
|
||||
union {
|
||||
|
@ -78,18 +64,6 @@ typedef struct {
|
|||
|
||||
NXDT_ASSERT(GameCardInitialData, 0x200);
|
||||
|
||||
/// Plaintext area. Dumped from FS program memory.
|
||||
/// This struct is returned by Lotus command "ChangeToSecureMode" (0xF). This means it is only available *after* the gamecard secure area has been mounted.
|
||||
/// A copy of the gamecard header without the RSA-2048 signature and a plaintext GameCardInfo precedes this struct in FS program memory.
|
||||
typedef struct {
|
||||
GameCardSpecificData specific_data;
|
||||
FsGameCardCertificate certificate;
|
||||
u8 reserved[0x200];
|
||||
GameCardInitialData initial_data;
|
||||
} GameCardSecurityInformation;
|
||||
|
||||
NXDT_ASSERT(GameCardSecurityInformation, 0x800);
|
||||
|
||||
/// Encrypted using AES-128-CTR with the key and IV/counter from the `GameCardTitleKeyAreaEncryption` section. Assumed to be all zeroes in retail gamecards.
|
||||
typedef struct {
|
||||
u8 titlekey[0x10]; ///< Decrypted titlekey from the `GameCardInitialData` section.
|
||||
|
@ -117,9 +91,36 @@ typedef struct {
|
|||
|
||||
NXDT_ASSERT(GameCardKeyArea, 0x1000);
|
||||
|
||||
/// 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.
|
||||
FsCardId1 card_id1;
|
||||
FsCardId2 card_id2;
|
||||
u8 card_uid[0x40];
|
||||
u8 reserved[0x190];
|
||||
u8 asic_session_hash[0x20]; ///< Changes with each gamecard (re)insertion.
|
||||
} GameCardSpecificData;
|
||||
|
||||
NXDT_ASSERT(GameCardSpecificData, 0x200);
|
||||
|
||||
/// Plaintext area. Dumped from FS program memory.
|
||||
/// This struct is returned by Lotus command "ChangeToSecureMode" (0xF). This means it is only available *after* the gamecard secure area has been mounted.
|
||||
/// A copy of the gamecard header without the RSA-2048 signature and a plaintext GameCardInfo precedes this struct in FS program memory.
|
||||
typedef struct {
|
||||
GameCardSpecificData specific_data;
|
||||
FsGameCardCertificate certificate;
|
||||
u8 reserved[0x200];
|
||||
GameCardInitialData initial_data;
|
||||
} GameCardSecurityInformation;
|
||||
|
||||
NXDT_ASSERT(GameCardSecurityInformation, 0x800);
|
||||
|
||||
typedef enum {
|
||||
GameCardKekIndex_Version0 = 0,
|
||||
GameCardKekIndex_VersionForDev = 1
|
||||
GameCardKekIndex_VersionForDev = 1,
|
||||
GameCardKekIndex_Count = 2 ///< Total values supported by this enum.
|
||||
} GameCardKekIndex;
|
||||
|
||||
typedef struct {
|
||||
|
@ -139,17 +140,20 @@ typedef enum {
|
|||
} GameCardRomSize;
|
||||
|
||||
typedef enum {
|
||||
GameCardFlags_None = 0,
|
||||
GameCardFlags_AutoBoot = BIT(0),
|
||||
GameCardFlags_HistoryErase = BIT(1),
|
||||
GameCardFlags_RepairTool = BIT(2),
|
||||
GameCardFlags_DifferentRegionCupToTerraDevice = BIT(3),
|
||||
GameCardFlags_DifferentRegionCupToGlobalDevice = BIT(4),
|
||||
GameCardFlags_HasCa10Certificate = BIT(7)
|
||||
GameCardFlags_HasCa10Certificate = BIT(7),
|
||||
GameCardFlags_Count = 6 ///< Total values supported by this enum.
|
||||
} GameCardFlags;
|
||||
|
||||
typedef enum {
|
||||
GameCardSelSec_ForT1 = 1,
|
||||
GameCardSelSec_ForT2 = 2
|
||||
GameCardSelSec_ForT2 = 2,
|
||||
GameCardSelSec_Count = 2 ///< Total values supported by this enum.
|
||||
} GameCardSelSec;
|
||||
|
||||
typedef enum {
|
||||
|
@ -159,7 +163,7 @@ typedef enum {
|
|||
GameCardFwVersion_Since900NUP = 3, ///< upp_version >= 603979776 (9.0.0-0.0) in GameCardInfo. Seems to be unused.
|
||||
GameCardFwVersion_Since1100NUP = 4, ///< upp_version >= 738197504 (11.0.0-0.0) in GameCardInfo.
|
||||
GameCardFwVersion_Since1200NUP = 5, ///< upp_version >= 805306368 (12.0.0-0.0) in GameCardInfo.
|
||||
GameCardFwVersion_Count = 6
|
||||
GameCardFwVersion_Count = 6 ///< Total values supported by this enum.
|
||||
} GameCardFwVersion;
|
||||
|
||||
typedef enum {
|
||||
|
@ -170,7 +174,7 @@ typedef enum {
|
|||
typedef enum {
|
||||
GameCardCompatibilityType_Normal = 0,
|
||||
GameCardCompatibilityType_Terra = 1,
|
||||
GameCardCompatibilityType_Count = 2
|
||||
GameCardCompatibilityType_Count = 2 ///< Total values supported by this enum.
|
||||
} GameCardCompatibilityType;
|
||||
|
||||
/// Encrypted using AES-128-CBC with the XCI header key (found in FS program memory under HOS 9.0.0+) and the IV from `GameCardHeader`.
|
||||
|
@ -187,7 +191,8 @@ typedef struct {
|
|||
u8 reserved_1[0x3];
|
||||
u64 upp_hash; ///< Checksum for the update partition. The exact way it's calculated is currently unknown.
|
||||
u64 upp_id; ///< Must match GAMECARD_UPDATE_TID.
|
||||
u8 reserved_2[0x38];
|
||||
u8 reserved_2[0x28];
|
||||
u8 unknown[0x10]; ///< Unknown purpose. It's not zeroed out in recent (2021+?) gamecards.
|
||||
} GameCardInfo;
|
||||
|
||||
NXDT_ASSERT(GameCardInfo, 0x70);
|
||||
|
@ -227,7 +232,8 @@ typedef enum {
|
|||
GameCardStatus_LotusAsicFirmwareUpdateRequired = 3, ///< A gamecard has been inserted, but a LAFW update is needed before being able to read the secure storage area.
|
||||
///< Operations on the normal storage area are still possible, though.
|
||||
GameCardStatus_InsertedAndInfoNotLoaded = 4, ///< A gamecard has been inserted, but an unexpected error unrelated to both "nogc" patch and LAFW version occurred.
|
||||
GameCardStatus_InsertedAndInfoLoaded = 5 ///< A gamecard has been inserted and all required information could be successfully retrieved from it.
|
||||
GameCardStatus_InsertedAndInfoLoaded = 5, ///< A gamecard has been inserted and all required information could be successfully retrieved from it.
|
||||
GameCardStatus_Count = 6 ///< Total values supported by this enum.
|
||||
} GameCardStatus;
|
||||
|
||||
typedef enum {
|
||||
|
@ -242,7 +248,7 @@ typedef enum {
|
|||
LotusAsicDeviceType_Dev = 1,
|
||||
LotusAsicDeviceType_Prod = 2,
|
||||
LotusAsicDeviceType_Prod2Dev = 3,
|
||||
LotusAsicDeviceType_Count = 4 ///< Not a real value.
|
||||
LotusAsicDeviceType_Count = 4 ///< Total values supported by this enum.
|
||||
} LotusAsicDeviceType;
|
||||
|
||||
/// Plaintext Lotus ASIC firmware (LAFW) blob. Dumped from FS program memory.
|
||||
|
|
|
@ -30,9 +30,12 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef enum {
|
||||
MemoryProgramSegmentType_None = 0,
|
||||
MemoryProgramSegmentType_Text = BIT(0),
|
||||
MemoryProgramSegmentType_Rodata = BIT(1),
|
||||
MemoryProgramSegmentType_Data = BIT(2)
|
||||
MemoryProgramSegmentType_Data = BIT(2),
|
||||
MemoryProgramSegmentType_All = (MemoryProgramSegmentType_Data | MemoryProgramSegmentType_Rodata | MemoryProgramSegmentType_Text),
|
||||
MemoryProgramSegmentType_Limit = (MemoryProgramSegmentType_All + 1) ///< Placed here for convenience.
|
||||
} MemoryProgramSegmentType;
|
||||
|
||||
typedef struct {
|
||||
|
@ -43,7 +46,7 @@ typedef struct {
|
|||
} MemoryLocation;
|
||||
|
||||
/// Retrieves memory segment (.text, .rodata, .data) data from a running program.
|
||||
/// These are memory pages with read permission (Perm_R) enabled and type MemType_CodeStatic or MemType_CodeMutable.
|
||||
/// These are memory pages with read permission (Perm_R) enabled, with type MemType_CodeStatic or MemType_CodeMutable and no MemoryAttribute flag set.
|
||||
bool memRetrieveProgramMemorySegment(MemoryLocation *location);
|
||||
|
||||
/// Retrieves full memory data from a running program.
|
||||
|
|
|
@ -64,6 +64,7 @@ typedef enum {
|
|||
} NacpAddOnContentRegistrationType;
|
||||
|
||||
typedef enum {
|
||||
NacpAttribute_None = 0,
|
||||
NacpAttribute_Demo = BIT(0),
|
||||
NacpAttribute_RetailInteractiveDisplay = BIT(1),
|
||||
NacpAttribute_DownloadPlay = BIT(2), ///< Removed.
|
||||
|
@ -96,23 +97,24 @@ typedef enum {
|
|||
} NacpLanguage;
|
||||
|
||||
typedef enum {
|
||||
NacpSupportedLanguage_AmericanEnglish = BIT(0),
|
||||
NacpSupportedLanguage_BritishEnglish = BIT(1),
|
||||
NacpSupportedLanguage_Japanese = BIT(2),
|
||||
NacpSupportedLanguage_French = BIT(3),
|
||||
NacpSupportedLanguage_German = BIT(4),
|
||||
NacpSupportedLanguage_LatinAmericanSpanish = BIT(5),
|
||||
NacpSupportedLanguage_Spanish = BIT(6),
|
||||
NacpSupportedLanguage_Italian = BIT(7),
|
||||
NacpSupportedLanguage_Dutch = BIT(8),
|
||||
NacpSupportedLanguage_CanadianFrench = BIT(9),
|
||||
NacpSupportedLanguage_Portuguese = BIT(10),
|
||||
NacpSupportedLanguage_Russian = BIT(11),
|
||||
NacpSupportedLanguage_Korean = BIT(12),
|
||||
NacpSupportedLanguage_TraditionalChinese = BIT(13),
|
||||
NacpSupportedLanguage_SimplifiedChinese = BIT(14),
|
||||
NacpSupportedLanguage_BrazilianPortuguese = BIT(15),
|
||||
NacpSupportedLanguage_Count = 16, ///< Total values supported by this enum. Should always match NacpLanguage_Count.
|
||||
NacpSupportedLanguage_None = 0,
|
||||
NacpSupportedLanguage_AmericanEnglish = BIT(NacpLanguage_AmericanEnglish),
|
||||
NacpSupportedLanguage_BritishEnglish = BIT(NacpLanguage_BritishEnglish),
|
||||
NacpSupportedLanguage_Japanese = BIT(NacpLanguage_Japanese),
|
||||
NacpSupportedLanguage_French = BIT(NacpLanguage_French),
|
||||
NacpSupportedLanguage_German = BIT(NacpLanguage_German),
|
||||
NacpSupportedLanguage_LatinAmericanSpanish = BIT(NacpLanguage_LatinAmericanSpanish),
|
||||
NacpSupportedLanguage_Spanish = BIT(NacpLanguage_Spanish),
|
||||
NacpSupportedLanguage_Italian = BIT(NacpLanguage_Italian),
|
||||
NacpSupportedLanguage_Dutch = BIT(NacpLanguage_Dutch),
|
||||
NacpSupportedLanguage_CanadianFrench = BIT(NacpLanguage_CanadianFrench),
|
||||
NacpSupportedLanguage_Portuguese = BIT(NacpLanguage_Portuguese),
|
||||
NacpSupportedLanguage_Russian = BIT(NacpLanguage_Russian),
|
||||
NacpSupportedLanguage_Korean = BIT(NacpLanguage_Korean),
|
||||
NacpSupportedLanguage_TraditionalChinese = BIT(NacpLanguage_TraditionalChinese),
|
||||
NacpSupportedLanguage_SimplifiedChinese = BIT(NacpLanguage_SimplifiedChinese),
|
||||
NacpSupportedLanguage_BrazilianPortuguese = BIT(NacpLanguage_BrazilianPortuguese),
|
||||
NacpSupportedLanguage_Count = NacpLanguage_Count, ///< Total values supported by this enum.
|
||||
|
||||
///< Old.
|
||||
NacpSupportedLanguage_Taiwanese = NacpSupportedLanguage_TraditionalChinese,
|
||||
|
@ -120,6 +122,7 @@ typedef enum {
|
|||
} NacpSupportedLanguage;
|
||||
|
||||
typedef enum {
|
||||
NacpParentalControl_None = 0,
|
||||
NacpParentalControl_FreeCommunication = BIT(0),
|
||||
NacpParentalControl_Count = 1 ///< Total values supported by this enum.
|
||||
} NacpParentalControl;
|
||||
|
@ -249,6 +252,7 @@ typedef enum {
|
|||
} NacpHdcp;
|
||||
|
||||
typedef enum {
|
||||
NacpStartupUserAccountOption_None = 0,
|
||||
NacpStartupUserAccountOption_IsOptional = BIT(0),
|
||||
NacpStartupUserAccountOption_Count = 1 ///< Total values supported by this enum.
|
||||
} NacpStartupUserAccountOption;
|
||||
|
@ -260,6 +264,7 @@ typedef enum {
|
|||
} NacpRuntimeUpgrade;
|
||||
|
||||
typedef enum {
|
||||
NacpSupportingLimitedApplicationLicenses_None = 0,
|
||||
NacpSupportingLimitedApplicationLicenses_Demo = BIT(0),
|
||||
NacpSupportingLimitedApplicationLicenses_Count = 1 ///< Total values supported by this enum.
|
||||
} NacpSupportingLimitedApplicationLicenses;
|
||||
|
@ -272,16 +277,19 @@ typedef enum {
|
|||
} NacpPlayLogQueryCapability;
|
||||
|
||||
typedef enum {
|
||||
NacpRepair_None = 0,
|
||||
NacpRepair_SuppressGameCardAccess = BIT(0),
|
||||
NacpRepair_Count = 1 ///< Total values supported by this enum.
|
||||
} NacpRepair;
|
||||
|
||||
typedef enum {
|
||||
NacpRequiredNetworkServiceLicenseOnLaunch_None = 0,
|
||||
NacpRequiredNetworkServiceLicenseOnLaunch_Common = BIT(0),
|
||||
NacpRequiredNetworkServiceLicenseOnLaunch_Count = 1 ///< Total values supported by this enum.
|
||||
} NacpRequiredNetworkServiceLicenseOnLaunch;
|
||||
|
||||
typedef enum {
|
||||
NacpJitConfigurationFlag_None = 0,
|
||||
NacpJitConfigurationFlag_Enabled = BITL(0),
|
||||
NacpJitConfigurationFlag_Count = 1 ///< Total values supported by this enum.
|
||||
} NacpJitConfigurationFlag;
|
||||
|
@ -295,7 +303,8 @@ NXDT_ASSERT(NacpJitConfiguration, 0x10);
|
|||
|
||||
typedef enum {
|
||||
NacpRequiredAddOnContentsSetDescriptorFlag_None = 0,
|
||||
NacpRequiredAddOnContentsSetDescriptorFlag_Continue = 1
|
||||
NacpRequiredAddOnContentsSetDescriptorFlag_Continue = 1,
|
||||
NacpRequiredAddOnContentsSetDescriptorFlag_Count = 2 ///< Total values supported by this enum.
|
||||
} NacpRequiredAddOnContentsSetDescriptorFlag;
|
||||
|
||||
typedef struct {
|
||||
|
@ -312,6 +321,7 @@ typedef struct {
|
|||
NXDT_ASSERT(NacpRequiredAddOnContentsSetBinaryDescriptor, 0x40);
|
||||
|
||||
typedef enum {
|
||||
NacpPlayReportPermission_None = 0,
|
||||
NacpPlayReportPermission_TargetMarketing = BIT(0),
|
||||
NacpPlayReportPermission_Count = 1 ///< Total values supported by this enum.
|
||||
} NacpPlayReportPermission;
|
||||
|
|
|
@ -62,7 +62,8 @@ extern "C" {
|
|||
|
||||
typedef enum {
|
||||
NcaDistributionType_Download = 0,
|
||||
NcaDistributionType_GameCard = 1
|
||||
NcaDistributionType_GameCard = 1,
|
||||
NcaDistributionType_Count = 2 ///< Total values supported by this enum.
|
||||
} NcaDistributionType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -71,7 +72,8 @@ typedef enum {
|
|||
NcaContentType_Control = 2,
|
||||
NcaContentType_Manual = 3,
|
||||
NcaContentType_Data = 4,
|
||||
NcaContentType_PublicData = 5
|
||||
NcaContentType_PublicData = 5,
|
||||
NcaContentType_Count = 6 ///< Total values supported by this enum.
|
||||
} NcaContentType;
|
||||
|
||||
/// 'NcaKeyGeneration_Current' will always point to the last known key generation value.
|
||||
|
@ -101,7 +103,7 @@ typedef enum {
|
|||
NcaKeyAreaEncryptionKeyIndex_Application = 0,
|
||||
NcaKeyAreaEncryptionKeyIndex_Ocean = 1,
|
||||
NcaKeyAreaEncryptionKeyIndex_System = 2,
|
||||
NcaKeyAreaEncryptionKeyIndex_Count = 3
|
||||
NcaKeyAreaEncryptionKeyIndex_Count = 3 ///< Total values supported by this enum.
|
||||
} NcaKeyAreaEncryptionKeyIndex;
|
||||
|
||||
/// 'NcaSignatureKeyGeneration_Current' will always point to the last known key generation value.
|
||||
|
@ -172,7 +174,8 @@ NXDT_ASSERT(NcaHeader, 0x400);
|
|||
|
||||
typedef enum {
|
||||
NcaFsType_RomFs = 0,
|
||||
NcaFsType_PartitionFs = 1
|
||||
NcaFsType_PartitionFs = 1,
|
||||
NcaFsType_Count = 2 ///< Total values supported by this enum.
|
||||
} NcaFsType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -182,7 +185,8 @@ typedef enum {
|
|||
NcaHashType_HierarchicalIntegrity = 3, ///< Used by NcaFsType_RomFs.
|
||||
NcaHashType_AutoSha3 = 4,
|
||||
NcaHashType_HierarchicalSha3256 = 5, ///< Used by NcaFsType_PartitionFs.
|
||||
NcaHashType_HierarchicalIntegritySha3 = 6 ///< Used by NcaFsType_RomFs.
|
||||
NcaHashType_HierarchicalIntegritySha3 = 6, ///< Used by NcaFsType_RomFs.
|
||||
NcaHashType_Count = 7 ///< Total values supported by this enum.
|
||||
} NcaHashType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -192,13 +196,15 @@ typedef enum {
|
|||
NcaEncryptionType_AesCtr = 3,
|
||||
NcaEncryptionType_AesCtrEx = 4,
|
||||
NcaEncryptionType_AesCtrSkipLayerHash = 5,
|
||||
NcaEncryptionType_AesCtrExSkipLayerHash = 6
|
||||
NcaEncryptionType_AesCtrExSkipLayerHash = 6,
|
||||
NcaEncryptionType_Count = 7 ///< Total values supported by this enum.
|
||||
} NcaEncryptionType;
|
||||
|
||||
typedef enum {
|
||||
NcaMetaDataHashType_None = 0,
|
||||
NcaMetaDataHashType_HierarchicalIntegrity = 1,
|
||||
NcaMetaDataHashType_HierarchicalIntegritySha3 = 2
|
||||
NcaMetaDataHashType_HierarchicalIntegritySha3 = 2,
|
||||
NcaMetaDataHashType_Count = 3 ///< Total values supported by this enum.
|
||||
} NcaMetaDataHashType;
|
||||
|
||||
typedef struct {
|
||||
|
@ -408,9 +414,10 @@ typedef struct {
|
|||
} NcaFsSectionContext;
|
||||
|
||||
typedef enum {
|
||||
NcaVersion_Nca0 = 0,
|
||||
NcaVersion_Nca2 = 2,
|
||||
NcaVersion_Nca3 = 3
|
||||
NcaVersion_Nca0 = 0,
|
||||
NcaVersion_Nca2 = 1,
|
||||
NcaVersion_Nca3 = 2,
|
||||
NcaVersion_Count = 3 ///< Total values supported by this enum.
|
||||
} NcaVersion;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -31,11 +31,12 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef enum {
|
||||
NcaStorageBaseStorageType_Invalid = 0, /* Placeholder. */
|
||||
NcaStorageBaseStorageType_Invalid = 0, ///< Placeholder.
|
||||
NcaStorageBaseStorageType_Regular = 1,
|
||||
NcaStorageBaseStorageType_Sparse = 2,
|
||||
NcaStorageBaseStorageType_Indirect = 3,
|
||||
NcaStorageBaseStorageType_Compressed = 4
|
||||
NcaStorageBaseStorageType_Compressed = 4,
|
||||
NcaStorageBaseStorageType_Count = 5 ///< Total values supported by this enum.
|
||||
} NcaStorageBaseStorageType;
|
||||
|
||||
/// Used to perform multi-layered reads within a single NCA FS section.
|
||||
|
|
|
@ -52,7 +52,8 @@ typedef enum {
|
|||
NpdmProcessAddressSpace_AddressSpace32Bit = 0,
|
||||
NpdmProcessAddressSpace_AddressSpace64BitOld = 1,
|
||||
NpdmProcessAddressSpace_AddressSpace32BitNoReserved = 2,
|
||||
NpdmProcessAddressSpace_AddressSpace64Bit = 3
|
||||
NpdmProcessAddressSpace_AddressSpace64Bit = 3,
|
||||
NpdmProcessAddressSpace_Count = 4 ///< Total values supported by this enum.
|
||||
} NpdmProcessAddressSpace;
|
||||
|
||||
typedef struct {
|
||||
|
@ -95,6 +96,7 @@ typedef enum {
|
|||
NpdmMemoryRegion_Applet = 1,
|
||||
NpdmMemoryRegion_SecureSystem = 2,
|
||||
NpdmMemoryRegion_NonSecureSystem = 3,
|
||||
NpdmMemoryRegion_Count = 4, ///< Total values supported by this enum.
|
||||
|
||||
/// Old.
|
||||
NpdmMemoryRegion_NonSecure = NpdmMemoryRegion_Application,
|
||||
|
@ -153,6 +155,7 @@ typedef struct {
|
|||
NXDT_ASSERT(NpdmAciHeader, 0x40);
|
||||
|
||||
typedef enum {
|
||||
NpdmFsAccessControlFlags_None = 0,
|
||||
NpdmFsAccessControlFlags_ApplicationInfo = BITL(0),
|
||||
NpdmFsAccessControlFlags_BootModeControl = BITL(1),
|
||||
NpdmFsAccessControlFlags_Calibration = BITL(2),
|
||||
|
@ -193,7 +196,8 @@ typedef enum {
|
|||
NpdmFsAccessControlFlags_DeviceTreeBlob = BITL(37),
|
||||
NpdmFsAccessControlFlags_NotifyErrorContextServiceReady = BITL(38),
|
||||
NpdmFsAccessControlFlags_Debug = BITL(62),
|
||||
NpdmFsAccessControlFlags_FullPermission = BITL(63)
|
||||
NpdmFsAccessControlFlags_FullPermission = BITL(63),
|
||||
NpdmFsAccessControlFlags_Count = 64 ///< Total values supported by this enum.
|
||||
} NpdmFsAccessControlFlags;
|
||||
|
||||
/// FsAccessControl descriptor. Part of the ACID section body.
|
||||
|
@ -246,9 +250,11 @@ typedef struct {
|
|||
NXDT_ASSERT(NpdmFsAccessControlDataContentOwnerBlock, 0x4);
|
||||
|
||||
typedef enum {
|
||||
NpdmAccessibility_None = 0,
|
||||
NpdmAccessibility_Read = BIT(0),
|
||||
NpdmAccessibility_Write = BIT(1),
|
||||
NpdmAccessibility_ReadWrite = NpdmAccessibility_Read | NpdmAccessibility_Write
|
||||
NpdmAccessibility_ReadWrite = (NpdmAccessibility_Read | NpdmAccessibility_Write),
|
||||
NpdmAccessibility_Count = 3 ///< Total values supported by this enum.
|
||||
} NpdmAccessibility;
|
||||
|
||||
/// Placed after NpdmFsAccessControlData / NpdmFsAccessControlDataContentOwnerBlock if the 'save_data_owner_info_size' member from NpdmFsAccessControlData is greater than zero.
|
||||
|
@ -273,35 +279,35 @@ typedef struct {
|
|||
NXDT_ASSERT(NpdmSrvAccessControlDescriptorEntry, 0x1);
|
||||
|
||||
typedef enum {
|
||||
NpdmKernelCapabilityEntryNumber_ThreadInfo = 3,
|
||||
NpdmKernelCapabilityEntryNumber_EnableSystemCalls = 4,
|
||||
NpdmKernelCapabilityEntryNumber_MemoryMap = 6,
|
||||
NpdmKernelCapabilityEntryNumber_IoMemoryMap = 7,
|
||||
NpdmKernelCapabilityEntryNumber_MemoryRegionMap = 10,
|
||||
NpdmKernelCapabilityEntryNumber_EnableInterrupts = 11,
|
||||
NpdmKernelCapabilityEntryNumber_MiscParams = 13,
|
||||
NpdmKernelCapabilityEntryNumber_KernelVersion = 14,
|
||||
NpdmKernelCapabilityEntryNumber_HandleTableSize = 15,
|
||||
NpdmKernelCapabilityEntryNumber_MiscFlags = 16
|
||||
} NpdmKernelCapabilityEntryNumber;
|
||||
NpdmKernelCapabilityEntryBitmaskSize_ThreadInfo = 3,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_EnableSystemCalls = 4,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_MemoryMap = 6,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_IoMemoryMap = 7,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_MemoryRegionMap = 10,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_EnableInterrupts = 11,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_MiscParams = 13,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_KernelVersion = 14,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_HandleTableSize = 15,
|
||||
NpdmKernelCapabilityEntryBitmaskSize_MiscFlags = 16
|
||||
} NpdmKernelCapabilityEntryBitmaskSize;
|
||||
|
||||
typedef enum {
|
||||
NpdmKernelCapabilityEntryValue_ThreadInfo = BIT(NpdmKernelCapabilityEntryNumber_ThreadInfo) - 1,
|
||||
NpdmKernelCapabilityEntryValue_EnableSystemCalls = BIT(NpdmKernelCapabilityEntryNumber_EnableSystemCalls) - 1,
|
||||
NpdmKernelCapabilityEntryValue_MemoryMap = BIT(NpdmKernelCapabilityEntryNumber_MemoryMap) - 1,
|
||||
NpdmKernelCapabilityEntryValue_IoMemoryMap = BIT(NpdmKernelCapabilityEntryNumber_IoMemoryMap) - 1,
|
||||
NpdmKernelCapabilityEntryValue_MemoryRegionMap = BIT(NpdmKernelCapabilityEntryNumber_MemoryRegionMap) - 1,
|
||||
NpdmKernelCapabilityEntryValue_EnableInterrupts = BIT(NpdmKernelCapabilityEntryNumber_EnableInterrupts) - 1,
|
||||
NpdmKernelCapabilityEntryValue_MiscParams = BIT(NpdmKernelCapabilityEntryNumber_MiscParams) - 1,
|
||||
NpdmKernelCapabilityEntryValue_KernelVersion = BIT(NpdmKernelCapabilityEntryNumber_KernelVersion) - 1,
|
||||
NpdmKernelCapabilityEntryValue_HandleTableSize = BIT(NpdmKernelCapabilityEntryNumber_HandleTableSize) - 1,
|
||||
NpdmKernelCapabilityEntryValue_MiscFlags = BIT(NpdmKernelCapabilityEntryNumber_MiscFlags) - 1
|
||||
} NpdmKernelCapabilityEntryValue;
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_ThreadInfo = BIT(NpdmKernelCapabilityEntryBitmaskSize_ThreadInfo) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_EnableSystemCalls = BIT(NpdmKernelCapabilityEntryBitmaskSize_EnableSystemCalls) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_MemoryMap = BIT(NpdmKernelCapabilityEntryBitmaskSize_MemoryMap) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_IoMemoryMap = BIT(NpdmKernelCapabilityEntryBitmaskSize_IoMemoryMap) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_MemoryRegionMap = BIT(NpdmKernelCapabilityEntryBitmaskSize_MemoryRegionMap) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_EnableInterrupts = BIT(NpdmKernelCapabilityEntryBitmaskSize_EnableInterrupts) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_MiscParams = BIT(NpdmKernelCapabilityEntryBitmaskSize_MiscParams) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_KernelVersion = BIT(NpdmKernelCapabilityEntryBitmaskSize_KernelVersion) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_HandleTableSize = BIT(NpdmKernelCapabilityEntryBitmaskSize_HandleTableSize) - 1,
|
||||
NpdmKernelCapabilityEntryBitmaskPattern_MiscFlags = BIT(NpdmKernelCapabilityEntryBitmaskSize_MiscFlags) - 1
|
||||
} NpdmKernelCapabilityEntryBitmaskPattern;
|
||||
|
||||
/// ThreadInfo entry for the KernelCapability descriptor.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_ThreadInfo; ///< Always set to NpdmKernelCapabilityEntryValue_ThreadInfo.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_ThreadInfo; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_ThreadInfo.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 lowest_priority : 6;
|
||||
u32 highest_priority : 6;
|
||||
u32 min_core_number : 8;
|
||||
|
@ -312,6 +318,8 @@ NXDT_ASSERT(NpdmThreadInfo, 0x4);
|
|||
|
||||
/// System call table.
|
||||
typedef enum {
|
||||
NpdmSystemCallId_None = 0,
|
||||
|
||||
///< System calls for index 0.
|
||||
NpdmSystemCallId_Reserved1 = BIT(0), ///< SVC 0x00.
|
||||
NpdmSystemCallId_SetHeapSize = BIT(1), ///< SVC 0x01.
|
||||
|
@ -525,39 +533,41 @@ typedef enum {
|
|||
|
||||
/// EnableSystemCalls entry for the KernelCapability descriptor.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_EnableSystemCalls; ///< Always set to NpdmKernelCapabilityEntryValue_EnableSystemCalls.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 system_call_ids : 24; ///< NpdmSystemCallId.
|
||||
u32 index : 3; ///< System calls index.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_EnableSystemCalls; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_EnableSystemCalls.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 system_call_ids : 24; ///< NpdmSystemCallId.
|
||||
u32 index : 3; ///< System calls index.
|
||||
} NpdmEnableSystemCalls;
|
||||
|
||||
NXDT_ASSERT(NpdmEnableSystemCalls, 0x4);
|
||||
|
||||
typedef enum {
|
||||
NpdmPermissionType_RW = 0,
|
||||
NpdmPermissionType_RO = 1
|
||||
NpdmPermissionType_RW = 0,
|
||||
NpdmPermissionType_RO = 1,
|
||||
NpdmPermissionType_Count = 2 ///< Total values supported by this enum.
|
||||
} NpdmPermissionType;
|
||||
|
||||
typedef enum {
|
||||
NpdmMappingType_Io = 0,
|
||||
NpdmMappingType_Static = 1
|
||||
NpdmMappingType_Static = 1,
|
||||
NpdmMappingType_Count = 2 ///< Total values supported by this enum.
|
||||
} NpdmMappingType;
|
||||
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_MemoryMap; ///< Always set to NpdmKernelCapabilityEntryValue_MemoryMap.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 begin_address : 24; ///< begin_address << 12.
|
||||
u32 permission_type : 1; ///< NpdmPermissionType.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_MemoryMap; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_MemoryMap.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 begin_address : 24; ///< begin_address << 12.
|
||||
u32 permission_type : 1; ///< NpdmPermissionType.
|
||||
} NpdmMemoryMapType1;
|
||||
|
||||
NXDT_ASSERT(NpdmMemoryMapType1, 0x4);
|
||||
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_MemoryMap; ///< Always set to NpdmKernelCapabilityEntryValue_MemoryMap.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 size : 20; ///< size << 12.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_MemoryMap; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_MemoryMap.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 size : 20; ///< size << 12.
|
||||
u32 reserved : 4;
|
||||
u32 mapping_type : 1; ///< NpdmMappingType.
|
||||
u32 mapping_type : 1; ///< NpdmMappingType.
|
||||
} NpdmMemoryMapType2;
|
||||
|
||||
NXDT_ASSERT(NpdmMemoryMapType2, 0x4);
|
||||
|
@ -575,9 +585,9 @@ NXDT_ASSERT(NpdmMemoryMap, 0x4);
|
|||
|
||||
/// IoMemoryMap entry for the KernelCapability descriptor.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_IoMemoryMap; ///< Always set to NpdmKernelCapabilityEntryValue_IoMemoryMap.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 begin_address : 24; ///< begin_address << 12.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_IoMemoryMap; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_IoMemoryMap.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 begin_address : 24; ///< begin_address << 12.
|
||||
} NpdmIoMemoryMap;
|
||||
|
||||
NXDT_ASSERT(NpdmIoMemoryMap, 0x4);
|
||||
|
@ -586,29 +596,30 @@ typedef enum {
|
|||
NpdmRegionType_NoMapping = 0,
|
||||
NpdmRegionType_KernelTraceBuffer = 1,
|
||||
NpdmRegionType_OnMemoryBootImage = 2,
|
||||
NpdmRegionType_DTB = 3
|
||||
NpdmRegionType_DTB = 3,
|
||||
NpdmRegionType_Count = 4 ///< Total values supported by this enum.
|
||||
} NpdmRegionType;
|
||||
|
||||
/// MemoryRegionMap entry for the KernelCapability descriptor.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_MemoryRegionMap; ///< Always set to NpdmKernelCapabilityEntryValue_MemoryRegionMap.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 region_type_0 : 6; ///< NpdmRegionType.
|
||||
u32 permission_type_0 : 1; ///< NpdmPermissionType.
|
||||
u32 region_type_1 : 6; ///< NpdmRegionType.
|
||||
u32 permission_type_1 : 1; ///< NpdmPermissionType.
|
||||
u32 region_type_2 : 6; ///< NpdmRegionType.
|
||||
u32 permission_type_2 : 1; ///< NpdmPermissionType.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_MemoryRegionMap; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_MemoryRegionMap.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 region_type_0 : 6; ///< NpdmRegionType.
|
||||
u32 permission_type_0 : 1; ///< NpdmPermissionType.
|
||||
u32 region_type_1 : 6; ///< NpdmRegionType.
|
||||
u32 permission_type_1 : 1; ///< NpdmPermissionType.
|
||||
u32 region_type_2 : 6; ///< NpdmRegionType.
|
||||
u32 permission_type_2 : 1; ///< NpdmPermissionType.
|
||||
} NpdmMemoryRegionMap;
|
||||
|
||||
NXDT_ASSERT(NpdmMemoryRegionMap, 0x4);
|
||||
|
||||
/// EnableInterrupts entry for the KernelCapability descriptor.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_EnableInterrupts; ///< Always set to NpdmKernelCapabilityEntryValue_EnableInterrupts.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 interrupt_number_0 : 10; ///< 0x3FF means empty.
|
||||
u32 interrupt_number_1 : 10; ///< 0x3FF means empty.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_EnableInterrupts; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_EnableInterrupts.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 interrupt_number_0 : 10; ///< 0x3FF means empty.
|
||||
u32 interrupt_number_1 : 10; ///< 0x3FF means empty.
|
||||
} NpdmEnableInterrupts;
|
||||
|
||||
NXDT_ASSERT(NpdmEnableInterrupts, 0x4);
|
||||
|
@ -616,15 +627,16 @@ NXDT_ASSERT(NpdmEnableInterrupts, 0x4);
|
|||
typedef enum {
|
||||
NpdmProgramType_System = 0,
|
||||
NpdmProgramType_Application = 1,
|
||||
NpdmProgramType_Applet = 2
|
||||
NpdmProgramType_Applet = 2,
|
||||
NpdmProgramType_Count = 3 ///< Total values supported by this enum.
|
||||
} NpdmProgramType;
|
||||
|
||||
/// MiscParams entry for the KernelCapability descriptor.
|
||||
/// Defaults to 0 if this entry doesn't exist.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_MiscParams; ///< Always set to NpdmKernelCapabilityEntryValue_MiscParams.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 program_type : 3; ///< NpdmProgramType.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_MiscParams; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_MiscParams.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 program_type : 3; ///< NpdmProgramType.
|
||||
u32 reserved : 15;
|
||||
} NpdmMiscParams;
|
||||
|
||||
|
@ -633,18 +645,18 @@ NXDT_ASSERT(NpdmMiscParams, 0x4);
|
|||
/// KernelVersion entry for the KernelCapability descriptor.
|
||||
/// This is derived from/equivalent to SDK version.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_KernelVersion; ///< Always set to NpdmKernelCapabilityEntryValue_KernelVersion.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 minor_version : 4; ///< SDK minor version.
|
||||
u32 major_version : 13; ///< SDK major version + 4.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_KernelVersion; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_KernelVersion.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 minor_version : 4; ///< SDK minor version.
|
||||
u32 major_version : 13; ///< SDK major version + 4.
|
||||
} NpdmKernelVersion;
|
||||
|
||||
NXDT_ASSERT(NpdmKernelVersion, 0x4);
|
||||
|
||||
/// HandleTableSize entry for the KernelCapability descriptor.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_HandleTableSize; ///< Always set to NpdmKernelCapabilityEntryValue_HandleTableSize.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_HandleTableSize; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_HandleTableSize.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 handle_table_size : 10;
|
||||
u32 reserved : 6;
|
||||
} NpdmHandleTableSize;
|
||||
|
@ -653,8 +665,8 @@ NXDT_ASSERT(NpdmHandleTableSize, 0x4);
|
|||
|
||||
/// MiscFlags entry for the KernelCapability descriptor.
|
||||
typedef struct {
|
||||
u32 entry_value : NpdmKernelCapabilityEntryNumber_MiscFlags; ///< Always set to NpdmKernelCapabilityEntryValue_MiscFlags.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 bitmask : NpdmKernelCapabilityEntryBitmaskSize_MiscFlags; ///< Always set to NpdmKernelCapabilityEntryBitmaskPattern_MiscFlags.
|
||||
u32 padding : 1; ///< Always set to zero.
|
||||
u32 enable_debug : 1;
|
||||
u32 force_debug : 1;
|
||||
u32 reserved : 13;
|
||||
|
@ -707,7 +719,8 @@ NX_INLINE bool npdmIsValidContext(NpdmContext *npdm_ctx)
|
|||
((npdm_ctx->aci_header->kernel_capability_size && npdm_ctx->aci_kc_descriptor) || (!npdm_ctx->aci_header->kernel_capability_size && !npdm_ctx->aci_kc_descriptor)));
|
||||
}
|
||||
|
||||
NX_INLINE u32 npdmGetKernelCapabilityDescriptorEntryValue(NpdmKernelCapabilityDescriptorEntry *entry)
|
||||
/// Returns a value that can be loooked up in the NpdmKernelCapabilityEntryBitmaskPattern enum.
|
||||
NX_INLINE u32 npdmGetKernelCapabilityDescriptorEntryBitmaskPattern(NpdmKernelCapabilityDescriptorEntry *entry)
|
||||
{
|
||||
return (entry ? (((entry->value + 1) & ~entry->value) - 1) : 0);
|
||||
}
|
||||
|
|
|
@ -34,12 +34,14 @@ extern "C" {
|
|||
#define NSO_MOD_MAGIC 0x4D4F4430 /* "MOD0". */
|
||||
|
||||
typedef enum {
|
||||
NsoFlags_None = 0,
|
||||
NsoFlags_TextCompress = BIT(0), ///< Determines if .text segment is LZ4-compressed.
|
||||
NsoFlags_RoCompress = BIT(1), ///< Determines if .rodata segment is LZ4-compressed.
|
||||
NsoFlags_DataCompress = BIT(2), ///< Determines if .data segment is LZ4-compressed.
|
||||
NsoFlags_TextHash = BIT(3), ///< Determines if .text segment hash must be checked during load.
|
||||
NsoFlags_RoHash = BIT(4), ///< Determines if .rodata segment hash must be checked during load.
|
||||
NsoFlags_DataHash = BIT(5) ///< Determines if .data segment hash must be checked during load.
|
||||
NsoFlags_DataHash = BIT(5), ///< Determines if .data segment hash must be checked during load.
|
||||
NsoFlags_Count = 6 ///< Total values supported by this enum.
|
||||
} NsoFlags;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -49,7 +49,8 @@ typedef enum {
|
|||
UtilsCustomFirmwareType_Unknown = 0,
|
||||
UtilsCustomFirmwareType_Atmosphere = 1,
|
||||
UtilsCustomFirmwareType_SXOS = 2,
|
||||
UtilsCustomFirmwareType_ReiNX = 3
|
||||
UtilsCustomFirmwareType_ReiNX = 3,
|
||||
UtilsCustomFirmwareType_Count = 4 ///< Total values supported by this enum.
|
||||
} UtilsCustomFirmwareType;
|
||||
|
||||
/// Used to handle parsed data from a GitHub release JSON.
|
||||
|
|
|
@ -134,7 +134,8 @@ typedef struct {
|
|||
typedef enum {
|
||||
RomFileSystemPathIllegalCharReplaceType_None = 0,
|
||||
RomFileSystemPathIllegalCharReplaceType_IllegalFsChars = 1,
|
||||
RomFileSystemPathIllegalCharReplaceType_KeepAsciiCharsOnly = 2
|
||||
RomFileSystemPathIllegalCharReplaceType_KeepAsciiCharsOnly = 2,
|
||||
RomFileSystemPathIllegalCharReplaceType_Count = 3 ///< Total values supported by this enum.
|
||||
} RomFileSystemPathIllegalCharReplaceType;
|
||||
|
||||
/// Initializes a RomFS or Patch RomFS context.
|
||||
|
|
|
@ -34,7 +34,7 @@ typedef enum {
|
|||
SmcKeyType_NormalOnly = 1,
|
||||
SmcKeyType_RecoveryOnly = 2,
|
||||
SmcKeyType_NormalAndRecovery = 3,
|
||||
SmcKeyType_Count = 4
|
||||
SmcKeyType_Count = 4 ///< Total values supported by this enum.
|
||||
} SmcKeyType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -45,7 +45,7 @@ typedef enum {
|
|||
SmcSealKey_ReencryptDeviceUniqueData = 4,
|
||||
SmcSealKey_ImportSslKey = 5,
|
||||
SmcSealKey_ImportEsClientCertKey = 6,
|
||||
SmcSealKey_Count = 7
|
||||
SmcSealKey_Count = 7 ///< Total values supported by this enum.
|
||||
} SmcSealKey;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -43,7 +43,8 @@ NXDT_ASSERT(TikSig##sigtype, tiksize);
|
|||
|
||||
typedef enum {
|
||||
TikTitleKeyType_Common = 0,
|
||||
TikTitleKeyType_Personalized = 1
|
||||
TikTitleKeyType_Personalized = 1,
|
||||
TikTitleKeyType_Count = 2 ///< Total values supported by this enum.
|
||||
} TikTitleKeyType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -52,16 +53,19 @@ typedef enum {
|
|||
TikLicenseType_Trial = 2,
|
||||
TikLicenseType_Rental = 3,
|
||||
TikLicenseType_Subscription = 4,
|
||||
TikLicenseType_Service = 5
|
||||
TikLicenseType_Service = 5,
|
||||
TikLicenseType_Count = 6 ///< Total values supported by this enum.
|
||||
} TikLicenseType;
|
||||
|
||||
typedef enum {
|
||||
TikPropertyMask_None = 0,
|
||||
TikPropertyMask_PreInstallation = BIT(0),
|
||||
TikPropertyMask_SharedTitle = BIT(1),
|
||||
TikPropertyMask_AllContents = BIT(2),
|
||||
TikPropertyMask_DeviceLinkIndepedent = BIT(3),
|
||||
TikPropertyMask_Volatile = BIT(4), ///< Used to determine if the ticket copy inside ticket.bin should be encrypted or not.
|
||||
TikPropertyMask_ELicenseRequired = BIT(5) ///< Used to determine if the console should connect to the Internet to perform elicense verification.
|
||||
TikPropertyMask_ELicenseRequired = BIT(5), ///< Used to determine if the console should connect to the Internet to perform elicense verification.
|
||||
TikPropertyMask_Count = 6 ///< Total values supported by this enum.
|
||||
} TikPropertyMask;
|
||||
|
||||
/// Placed after the ticket signature block.
|
||||
|
@ -92,12 +96,14 @@ NXDT_ASSERT(TikCommonBlock, 0x180);
|
|||
/// Each ESV2 section record is followed by a 'record_count' number of ESV1 records, each one of 'record_size' size.
|
||||
|
||||
typedef enum {
|
||||
TikSectionType_None = 0,
|
||||
TikSectionType_Permanent = 1,
|
||||
TikSectionType_Subscription = 2,
|
||||
TikSectionType_Content = 3,
|
||||
TikSectionType_ContentConsumption = 4,
|
||||
TikSectionType_AccessTitle = 5,
|
||||
TikSectionType_LimitedResource = 6
|
||||
TikSectionType_LimitedResource = 6,
|
||||
TikSectionType_Count = 7 ///< Total values supported by this enum.
|
||||
} TikSectionType;
|
||||
|
||||
typedef struct {
|
||||
|
@ -159,7 +165,8 @@ typedef enum {
|
|||
TikType_SigRsa4096 = 1,
|
||||
TikType_SigRsa2048 = 2,
|
||||
TikType_SigEcc480 = 3,
|
||||
TikType_SigHmac160 = 4
|
||||
TikType_SigHmac160 = 4,
|
||||
TikType_Count = 5 ///< Total values supported by this enum.
|
||||
} TikType;
|
||||
|
||||
/// Used to store ticket type, size and raw data, as well as titlekey data.
|
||||
|
|
|
@ -77,13 +77,14 @@ typedef enum {
|
|||
///< Gamecards: "{Name1} [{Id1}][v{Version1}] + ... + {NameN} [{IdN}][v{VersionN}]".
|
||||
TitleNamingConvention_IdAndVersionOnly = 1, ///< Individual titles: "{Id}_v{Version}_{Type}".
|
||||
///< Gamecards: "{TitleId1}_v{TitleVersion1}_{TitleType1} + ... + {TitleIdN}_v{TitleVersionN}_{TitleTypeN}".
|
||||
TitleNamingConvention_Count = 2
|
||||
TitleNamingConvention_Count = 2 ///< Total values supported by this enum.
|
||||
} TitleNamingConvention;
|
||||
|
||||
typedef enum {
|
||||
TitleFileNameIllegalCharReplaceType_None = 0,
|
||||
TitleFileNameIllegalCharReplaceType_IllegalFsChars = 1,
|
||||
TitleFileNameIllegalCharReplaceType_KeepAsciiCharsOnly = 2
|
||||
TitleFileNameIllegalCharReplaceType_KeepAsciiCharsOnly = 2,
|
||||
TitleFileNameIllegalCharReplaceType_Count = 3 ///< Total values supported by this enum.
|
||||
} TitleFileNameIllegalCharReplaceType;
|
||||
|
||||
/// Initializes the title interface.
|
||||
|
|
|
@ -38,7 +38,8 @@ typedef enum {
|
|||
UsbHostSpeed_None = 0,
|
||||
UsbHostSpeed_FullSpeed = 1, ///< USB 1.x.
|
||||
UsbHostSpeed_HighSpeed = 2, ///< USB 2.0.
|
||||
UsbHostSpeed_SuperSpeed = 3 ///< USB 3.0.
|
||||
UsbHostSpeed_SuperSpeed = 3, ///< USB 3.0.
|
||||
UsbHostSpeed_Count = 4 ///< Total values supported by this enum.
|
||||
} UsbHostSpeed;
|
||||
|
||||
/// Initializes the USB interface, input and output endpoints and allocates an internal transfer buffer.
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 55f5a140770b10899e3c5e3a08243471fe8e9ba7
|
||||
Subproject commit a11eb0d7083fba72aade29d3f9b35070d5510c3d
|
|
@ -18,7 +18,7 @@
|
|||
"enable_screenshots": false,
|
||||
"enable_video_capture": false,
|
||||
"disable_hdcp": false,
|
||||
"append_authoringtool_data": false,
|
||||
"generate_authoringtool_data": false,
|
||||
"lookup_checksum": true
|
||||
},
|
||||
"ticket": {
|
||||
|
|
|
@ -208,7 +208,7 @@ void bfttfExit(void)
|
|||
|
||||
bool bfttfGetFontByType(BfttfFontData *font_data, u8 font_type)
|
||||
{
|
||||
if (!font_data || font_type >= BfttfFontType_Total)
|
||||
if (!font_data || font_type >= BfttfFontType_Count)
|
||||
{
|
||||
LOG_MSG_ERROR("Invalid parameters!");
|
||||
return false;
|
||||
|
|
|
@ -240,7 +240,7 @@ static bool configValidateJsonNspObject(const struct json_object *obj)
|
|||
{
|
||||
bool ret = false, set_download_distribution_found = false, remove_console_data_found = false, remove_titlekey_crypto_found = false;
|
||||
bool disable_linked_account_requirement_found = false, enable_screenshots_found = false, enable_video_capture_found = false, disable_hdcp_found = false;
|
||||
bool append_authoringtool_data_found = false, lookup_checksum_found = false;
|
||||
bool generate_authoringtool_data_found = false, lookup_checksum_found = false;
|
||||
|
||||
if (!jsonValidateObject(obj)) goto end;
|
||||
|
||||
|
@ -254,12 +254,12 @@ static bool configValidateJsonNspObject(const struct json_object *obj)
|
|||
CONFIG_VALIDATE_FIELD(Boolean, enable_video_capture);
|
||||
CONFIG_VALIDATE_FIELD(Boolean, disable_hdcp);
|
||||
CONFIG_VALIDATE_FIELD(Boolean, lookup_checksum);
|
||||
CONFIG_VALIDATE_FIELD(Boolean, append_authoringtool_data);
|
||||
CONFIG_VALIDATE_FIELD(Boolean, generate_authoringtool_data);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = (set_download_distribution_found && remove_console_data_found && remove_titlekey_crypto_found && disable_linked_account_requirement_found && \
|
||||
enable_screenshots_found && enable_video_capture_found && disable_hdcp_found && append_authoringtool_data_found && lookup_checksum_found);
|
||||
enable_screenshots_found && enable_video_capture_found && disable_hdcp_found && generate_authoringtool_data_found && lookup_checksum_found);
|
||||
|
||||
end:
|
||||
return ret;
|
||||
|
|
|
@ -582,19 +582,14 @@ static bool gamecardReadLotusAsicFirmwareBlob(void)
|
|||
/* Temporarily set the segment mask to .data. */
|
||||
g_fsProgramMemory.mask = MemoryProgramSegmentType_Data;
|
||||
|
||||
/* Retrieve full FS program memory dump. */
|
||||
ret = memRetrieveProgramMemorySegment(&g_fsProgramMemory);
|
||||
|
||||
/* Clear segment mask. */
|
||||
g_fsProgramMemory.mask = 0;
|
||||
|
||||
if (!ret)
|
||||
/* Retrieve FS .data segment memory dump. */
|
||||
if (!memRetrieveProgramMemorySegment(&g_fsProgramMemory))
|
||||
{
|
||||
LOG_MSG_ERROR("Failed to retrieve FS .data segment dump!");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Look for the LAFW ReadFw blob in the FS .data memory dump. */
|
||||
/* Look for the LAFW ReadFw blob in the FS .data segment memory dump. */
|
||||
for(u64 offset = 0; offset < g_fsProgramMemory.data_size; offset++)
|
||||
{
|
||||
if ((g_fsProgramMemory.data_size - offset) < sizeof(LotusAsicFirmwareBlob)) break;
|
||||
|
@ -635,6 +630,8 @@ static bool gamecardReadLotusAsicFirmwareBlob(void)
|
|||
end:
|
||||
memFreeMemoryLocation(&g_fsProgramMemory);
|
||||
|
||||
g_fsProgramMemory.mask = MemoryProgramSegmentType_None;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -953,6 +950,7 @@ static bool gamecardReadSecurityInformation(GameCardSecurityInformation *out)
|
|||
if (memcmp(g_fsProgramMemory.data + offset, &(g_gameCardHeader.package_id), sizeof(g_gameCardHeader.package_id)) != 0) continue;
|
||||
|
||||
sha256CalculateHash(tmp_hash, g_fsProgramMemory.data + offset, sizeof(GameCardInitialData));
|
||||
|
||||
if (!memcmp(tmp_hash, g_gameCardHeader.initial_data_hash, SHA256_HASH_SIZE))
|
||||
{
|
||||
/* Jackpot. */
|
||||
|
|
|
@ -23,8 +23,14 @@
|
|||
#include "nxdt_utils.h"
|
||||
#include "mem.h"
|
||||
|
||||
#define MEMLOG_DEBUG(fmt, ...) LOG_MSG_BUF_DEBUG(&g_memLogBuf, &g_memLogBufSize, fmt, ##__VA_ARGS__)
|
||||
#define MEMLOG_ERROR(fmt, ...) LOG_MSG_BUF_ERROR(&g_memLogBuf, &g_memLogBufSize, fmt, ##__VA_ARGS__)
|
||||
#define MEMLOG_DEBUG(fmt, ...) LOG_MSG_BUF_DEBUG(&g_memLogBuf, &g_memLogBufSize, fmt, ##__VA_ARGS__)
|
||||
#define MEMLOG_ERROR(fmt, ...) LOG_MSG_BUF_ERROR(&g_memLogBuf, &g_memLogBufSize, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define MEM_PID_BUF_SIZE 300
|
||||
|
||||
#define MEM_INVALID_SEGMENT_PAGE_TYPE(x) ((x) != MemType_CodeStatic && (x) != MemType_CodeMutable)
|
||||
|
||||
#define MEM_INVALID_FS_PAGE_TYPE(x) ((x) == MemType_Unmapped || (x) == MemType_Io || (x) == MemType_ThreadLocal || (x) == MemType_Reserved)
|
||||
|
||||
/* Global variables. */
|
||||
|
||||
|
@ -43,7 +49,7 @@ static bool memRetrieveDebugHandleFromProgramById(Handle *out, u64 program_id);
|
|||
|
||||
bool memRetrieveProgramMemorySegment(MemoryLocation *location)
|
||||
{
|
||||
if (!location || !location->program_id || !location->mask || location->mask >= BIT(3))
|
||||
if (!location || !location->program_id || !location->mask || location->mask >= MemoryProgramSegmentType_Limit)
|
||||
{
|
||||
LOG_MSG_ERROR("Invalid parameters!");
|
||||
return false;
|
||||
|
@ -76,7 +82,7 @@ static bool memRetrieveProgramMemory(MemoryLocation *location, bool is_segment)
|
|||
|
||||
u32 page_info = 0;
|
||||
u64 addr = 0, last_text_addr = 0;
|
||||
u8 segment = 1, mem_type = 0;
|
||||
u8 segment = MemoryProgramSegmentType_Text, mem_type = 0;
|
||||
u8 *tmp = NULL;
|
||||
|
||||
bool success = true;
|
||||
|
@ -98,8 +104,9 @@ static bool memRetrieveProgramMemory(MemoryLocation *location, bool is_segment)
|
|||
#if LOG_LEVEL < LOG_LEVEL_NONE
|
||||
/* LOG_*() macros will be useless if the target program is the FS sysmodule. */
|
||||
/* This is because any FS I/O operation *will* lock up the console while FS itself is being debugged. */
|
||||
/* So we'll just temporarily log data to a char array using LOG_MSG_BUF_*() macros, then write it all out after calling svcCloseHandle(). */
|
||||
/* So we'll just log data to a temporary buffer using LOG_MSG_BUF_*() macros, then write it all out to the logfile after calling svcCloseHandle(). */
|
||||
/* However, we must prevent other threads from logging data as well in order to avoid a lock up, so we'll temporarily lock the logfile mutex. */
|
||||
/* We don't need to take care of manually (re)allocating memory for our buffer -- the log handler ABI takes care of that for us. */
|
||||
logControlMutex(true);
|
||||
#endif
|
||||
|
||||
|
@ -112,11 +119,12 @@ static bool memRetrieveProgramMemory(MemoryLocation *location, bool is_segment)
|
|||
|
||||
if (is_segment && location->program_id == FS_SYSMODULE_TID)
|
||||
{
|
||||
/* Only look for the FS .text segment address if we haven't previously retrieved it. */
|
||||
/* Locate the "real" FS .text segment, since Atmosphère emuMMC has two. */
|
||||
/* We'll only look for it if we haven't previously retrieved it, though. */
|
||||
if (!g_fsTextSegmentAddr)
|
||||
{
|
||||
/* Locate the "real" FS .text segment, since Atmosphère emuMMC has two. */
|
||||
do {
|
||||
/* Query memory page info. */
|
||||
rc = svcQueryDebugProcessMemory(&mem_info, &page_info, debug_handle, addr);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
|
@ -125,27 +133,39 @@ static bool memRetrieveProgramMemory(MemoryLocation *location, bool is_segment)
|
|||
goto end;
|
||||
}
|
||||
|
||||
mem_type = (u8)(mem_info.type & MemState_Type);
|
||||
addr = (mem_info.addr + mem_info.size);
|
||||
|
||||
/* Filter out unwanted memory pages. */
|
||||
if (MEM_INVALID_SEGMENT_PAGE_TYPE(mem_type) || mem_info.attr || (mem_info.perm & Perm_Rx) != Perm_Rx) continue;
|
||||
|
||||
#if LOG_LEVEL == LOG_LEVEL_DEBUG
|
||||
MEMLOG_DEBUG("svcQueryDebugProcessMemory info (#1) (program %016lX, page 0x%X, debug handle 0x%X, address 0x%lX):\r\n" \
|
||||
"- addr: 0x%lX\r\n- size: 0x%lX\r\n- type: 0x%X\r\n- attr: 0x%X\r\n- perm: 0x%X\r\n- ipc_refcount: 0x%X\r\n- device_refcount: 0x%X", \
|
||||
location->program_id, page_info, debug_handle, addr, \
|
||||
mem_info.addr, mem_info.size, mem_info.type, mem_info.attr, mem_info.perm, mem_info.ipc_refcount, mem_info.device_refcount);
|
||||
MEMLOG_DEBUG("svcQueryDebugProcessMemory info (FS .text segment lookup) (program %016lX, page 0x%X, debug handle 0x%X):\r\n" \
|
||||
"- addr: 0x%lX\r\n" \
|
||||
"- size: 0x%lX\r\n" \
|
||||
"- type: 0x%X\r\n" \
|
||||
"- attr: 0x%X\r\n" \
|
||||
"- perm: 0x%X\r\n" \
|
||||
"- ipc_refcount: 0x%X\r\n" \
|
||||
"- device_refcount: 0x%X", \
|
||||
location->program_id, page_info, debug_handle, mem_info.addr, mem_info.size, mem_info.type, mem_info.attr, mem_info.perm, \
|
||||
mem_info.ipc_refcount, mem_info.device_refcount);
|
||||
#endif
|
||||
|
||||
mem_type = (u8)(mem_info.type & 0xFF);
|
||||
if ((mem_info.perm & Perm_X) && (mem_type == MemType_CodeStatic || mem_type == MemType_CodeMutable)) last_text_addr = mem_info.addr;
|
||||
|
||||
addr = (mem_info.addr + mem_info.size);
|
||||
/* Update .text segment address. */
|
||||
last_text_addr = mem_info.addr;
|
||||
} while(addr != 0);
|
||||
|
||||
g_fsTextSegmentAddr = last_text_addr;
|
||||
MEMLOG_DEBUG("FS .text segment address: 0x%lX.", g_fsTextSegmentAddr);
|
||||
}
|
||||
|
||||
/* Update variable so we can start reading data right from this address in the next steps. */
|
||||
addr = g_fsTextSegmentAddr;
|
||||
}
|
||||
|
||||
do {
|
||||
/* Query memory page info. */
|
||||
rc = svcQueryDebugProcessMemory(&mem_info, &page_info, debug_handle, addr);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
|
@ -154,45 +174,51 @@ static bool memRetrieveProgramMemory(MemoryLocation *location, bool is_segment)
|
|||
break;
|
||||
}
|
||||
|
||||
mem_type = (u8)(mem_info.type & MemState_Type);
|
||||
addr = (mem_info.addr + mem_info.size);
|
||||
|
||||
/* Filter out unwanted memory pages. */
|
||||
if (mem_info.attr || !(mem_info.perm & Perm_R) || \
|
||||
(is_segment && (MEM_INVALID_SEGMENT_PAGE_TYPE(mem_type) || !(((segment <<= 1) >> 1) & location->mask))) || \
|
||||
(!is_segment && location->program_id == FS_SYSMODULE_TID && MEM_INVALID_FS_PAGE_TYPE(mem_type))) continue;
|
||||
|
||||
#if LOG_LEVEL == LOG_LEVEL_DEBUG
|
||||
MEMLOG_DEBUG("svcQueryDebugProcessMemory info (#2) (program %016lX, page 0x%X, debug handle 0x%X, address 0x%lX):\r\n" \
|
||||
"- addr: 0x%lX\r\n- size: 0x%lX\r\n- type: 0x%X\r\n- attr: 0x%X\r\n- perm: 0x%X\r\n- ipc_refcount: 0x%X\r\n- device_refcount: 0x%X", \
|
||||
location->program_id, page_info, debug_handle, addr, \
|
||||
mem_info.addr, mem_info.size, mem_info.type, mem_info.attr, mem_info.perm, mem_info.ipc_refcount, mem_info.device_refcount);
|
||||
MEMLOG_DEBUG("svcQueryDebugProcessMemory info (program %016lX, page 0x%X, debug handle 0x%X):\r\n" \
|
||||
"- addr: 0x%lX\r\n" \
|
||||
"- size: 0x%lX\r\n" \
|
||||
"- type: 0x%X\r\n" \
|
||||
"- attr: 0x%X\r\n" \
|
||||
"- perm: 0x%X\r\n" \
|
||||
"- ipc_refcount: 0x%X\r\n" \
|
||||
"- device_refcount: 0x%X", \
|
||||
location->program_id, page_info, debug_handle, mem_info.addr, mem_info.size, mem_info.type, mem_info.attr, mem_info.perm, \
|
||||
mem_info.ipc_refcount, mem_info.device_refcount);
|
||||
#endif
|
||||
|
||||
mem_type = (u8)(mem_info.type & 0xFF);
|
||||
|
||||
/* Code to allow for bitmasking segments. */
|
||||
if ((mem_info.perm & Perm_R) && ((!is_segment && !mem_info.attr && (location->program_id != FS_SYSMODULE_TID || (location->program_id == FS_SYSMODULE_TID && mem_type != MemType_Unmapped && \
|
||||
mem_type != MemType_Io && mem_type != MemType_ThreadLocal && mem_type != MemType_Reserved))) || (is_segment && (mem_type == MemType_CodeStatic || mem_type == MemType_CodeMutable) && \
|
||||
(((segment <<= 1) >> 1) & location->mask))))
|
||||
/* Reallocate data buffer. */
|
||||
tmp = realloc(location->data, location->data_size + mem_info.size);
|
||||
if (!tmp)
|
||||
{
|
||||
/* Reallocate data buffer. */
|
||||
tmp = realloc(location->data, location->data_size + mem_info.size);
|
||||
if (!tmp)
|
||||
{
|
||||
MEMLOG_ERROR("Failed to resize segment data buffer to 0x%lX bytes for program %016lX!", location->data_size + mem_info.size, location->program_id);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
location->data = tmp;
|
||||
tmp = NULL;
|
||||
|
||||
rc = svcReadDebugProcessMemory(location->data + location->data_size, debug_handle, mem_info.addr, mem_info.size);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
MEMLOG_ERROR("svcReadDebugProcessMemory failed for program %016lX! (0x%X).", location->program_id, rc);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
location->data_size += mem_info.size;
|
||||
MEMLOG_ERROR("Failed to resize segment data buffer to 0x%lX bytes for program %016lX!", location->data_size + mem_info.size, location->program_id);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
addr = (mem_info.addr + mem_info.size);
|
||||
} while(addr != 0 && segment < BIT(3));
|
||||
location->data = tmp;
|
||||
tmp = NULL;
|
||||
|
||||
/* Read memory page. */
|
||||
rc = svcReadDebugProcessMemory(location->data + location->data_size, debug_handle, mem_info.addr, mem_info.size);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
MEMLOG_ERROR("svcReadDebugProcessMemory failed for program %016lX! (0x%X).", location->program_id, rc);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increase data buffer size. */
|
||||
location->data_size += mem_info.size;
|
||||
} while(addr != 0 && segment < MemoryProgramSegmentType_Limit);
|
||||
|
||||
end:
|
||||
/* Close debug handle. */
|
||||
|
@ -243,6 +269,8 @@ static bool memRetrieveDebugHandleFromProgramById(Handle *out, u64 program_id)
|
|||
u32 i = 0, num_processes = 0;
|
||||
u64 *pids = NULL;
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (program_id > BOOT_SYSMODULE_TID && program_id != SPL_SYSMODULE_TID)
|
||||
{
|
||||
/* If not a kernel process, get process ID from pm:dmnt. */
|
||||
|
@ -250,7 +278,7 @@ static bool memRetrieveDebugHandleFromProgramById(Handle *out, u64 program_id)
|
|||
if (R_FAILED(rc))
|
||||
{
|
||||
MEMLOG_ERROR("pmdmntGetProcessId failed for program %016lX! (0x%X).", program_id, rc);
|
||||
return false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
MEMLOG_DEBUG("Process ID (%016lX): 0x%lX.", program_id, pid);
|
||||
|
@ -260,27 +288,26 @@ static bool memRetrieveDebugHandleFromProgramById(Handle *out, u64 program_id)
|
|||
if (R_FAILED(rc))
|
||||
{
|
||||
MEMLOG_ERROR("svcDebugActiveProcess failed for program %016lX! (0x%X).", program_id, rc);
|
||||
return false;
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
/* Otherwise, query svc for the process list. */
|
||||
pids = calloc(300, sizeof(u64));
|
||||
pids = calloc(MEM_PID_BUF_SIZE, sizeof(u64));
|
||||
if (!pids)
|
||||
{
|
||||
MEMLOG_ERROR("Failed to allocate memory for PID list!");
|
||||
return false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
MEMLOG_DEBUG("svcDebugActiveProcess returned %u process IDs.", num_processes);
|
||||
|
||||
rc = svcGetProcessList((s32*)&num_processes, pids, 300);
|
||||
rc = svcGetProcessList((s32*)&num_processes, pids, MEM_PID_BUF_SIZE);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
MEMLOG_ERROR("svcGetProcessList failed! (0x%X).", rc);
|
||||
free(pids);
|
||||
return false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
MEMLOG_DEBUG("svcGetProcessList returned %u process IDs.", num_processes);
|
||||
|
||||
/* Perform a lookup using the retrieved process list. */
|
||||
for(i = 0; i < num_processes; i++)
|
||||
{
|
||||
|
@ -295,7 +322,7 @@ static bool memRetrieveDebugHandleFromProgramById(Handle *out, u64 program_id)
|
|||
MEMLOG_DEBUG("Debug handle (process 0x%lX): 0x%X.", pids[i], debug_handle);
|
||||
|
||||
/* Get debug event using the debug handle. */
|
||||
/* This will let us know the program ID from the current process ID. */
|
||||
/* This will let us know the program ID for the current process ID. */
|
||||
rc = svcGetDebugEvent((u8*)&d, debug_handle);
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
|
@ -310,19 +337,23 @@ static bool memRetrieveDebugHandleFromProgramById(Handle *out, u64 program_id)
|
|||
debug_handle = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
free(pids);
|
||||
|
||||
if (i == num_processes)
|
||||
{
|
||||
MEMLOG_ERROR("Unable to find program %016lX in kernel process list! (0x%X).", program_id, rc);
|
||||
return false;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
MEMLOG_DEBUG("Debug handle (%016lX): 0x%X.", program_id, debug_handle);
|
||||
MEMLOG_DEBUG("Output debug handle for program ID %016lX: 0x%X.", program_id, debug_handle);
|
||||
|
||||
/* Set output debug handle. */
|
||||
*out = debug_handle;
|
||||
|
||||
return true;
|
||||
/* Update output flag. */
|
||||
success = true;
|
||||
|
||||
end:
|
||||
if (pids) free(pids);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -856,7 +856,7 @@ static bool ncaInitializeFsSectionContext(NcaContext *nca_ctx, u32 section_idx)
|
|||
}
|
||||
}
|
||||
|
||||
if (fs_ctx->hash_type == NcaHashType_Auto || fs_ctx->hash_type == NcaHashType_AutoSha3 || fs_ctx->hash_type > NcaHashType_HierarchicalIntegritySha3)
|
||||
if (fs_ctx->hash_type == NcaHashType_Auto || fs_ctx->hash_type == NcaHashType_AutoSha3 || fs_ctx->hash_type >= NcaHashType_Count)
|
||||
{
|
||||
LOG_MSG_ERROR("Invalid hash type for FS section #%u in \"%s\" (0x%02X). Skipping FS section.", section_idx, nca_ctx->content_id_str, fs_ctx->hash_type);
|
||||
goto end;
|
||||
|
@ -880,7 +880,7 @@ static bool ncaInitializeFsSectionContext(NcaContext *nca_ctx, u32 section_idx)
|
|||
}
|
||||
}
|
||||
|
||||
if (fs_ctx->encryption_type == NcaEncryptionType_Auto || fs_ctx->encryption_type > NcaEncryptionType_AesCtrExSkipLayerHash)
|
||||
if (fs_ctx->encryption_type == NcaEncryptionType_Auto || fs_ctx->encryption_type >= NcaEncryptionType_Count)
|
||||
{
|
||||
LOG_MSG_ERROR("Invalid encryption type for FS section #%u in \"%s\" (0x%02X). Skipping FS section.", section_idx, nca_ctx->content_id_str, fs_ctx->encryption_type);
|
||||
goto end;
|
||||
|
@ -1017,7 +1017,7 @@ static bool ncaInitializeFsSectionContext(NcaContext *nca_ctx, u32 section_idx)
|
|||
|
||||
/* Initialize crypto data. */
|
||||
if ((!nca_ctx->rights_id_available || (nca_ctx->rights_id_available && nca_ctx->titlekey_retrieved)) && fs_ctx->encryption_type > NcaEncryptionType_None && \
|
||||
fs_ctx->encryption_type <= NcaEncryptionType_AesCtrExSkipLayerHash)
|
||||
fs_ctx->encryption_type < NcaEncryptionType_Count)
|
||||
{
|
||||
/* Initialize the partial AES counter for this section. */
|
||||
aes128CtrInitializePartialCtr(fs_ctx->ctr, fs_ctx->header.aes_ctr_upper_iv.value, fs_ctx->section_offset);
|
||||
|
@ -1137,7 +1137,7 @@ static bool ncaFsSectionValidateHashDataBoundaries(NcaFsSectionContext *ctx)
|
|||
static bool _ncaReadFsSection(NcaFsSectionContext *ctx, void *out, u64 read_size, u64 offset)
|
||||
{
|
||||
if (!g_ncaCryptoBuffer || !ctx || !ctx->enabled || !ctx->nca_ctx || ctx->section_idx >= NCA_FS_HEADER_COUNT || ctx->section_offset < sizeof(NcaHeader) || \
|
||||
ctx->section_type >= NcaFsSectionType_Invalid || ctx->encryption_type == NcaEncryptionType_Auto || ctx->encryption_type > NcaEncryptionType_AesCtrExSkipLayerHash || \
|
||||
ctx->section_type >= NcaFsSectionType_Invalid || ctx->encryption_type == NcaEncryptionType_Auto || ctx->encryption_type >= NcaEncryptionType_Count || \
|
||||
!out || !read_size || (offset + read_size) > ctx->section_size)
|
||||
{
|
||||
LOG_MSG_ERROR("Invalid NCA FS section header parameters!");
|
||||
|
@ -1685,7 +1685,7 @@ static void *ncaGenerateEncryptedFsSectionBlock(NcaFsSectionContext *ctx, const
|
|||
bool success = false;
|
||||
|
||||
if (!g_ncaCryptoBuffer || !ctx || !ctx->enabled || ctx->has_sparse_layer || ctx->has_compression_layer || !ctx->nca_ctx || ctx->section_idx >= NCA_FS_HEADER_COUNT || \
|
||||
ctx->section_offset < sizeof(NcaHeader) || ctx->hash_type <= NcaHashType_None || ctx->hash_type == NcaHashType_AutoSha3 || ctx->hash_type > NcaHashType_HierarchicalIntegritySha3 || \
|
||||
ctx->section_offset < sizeof(NcaHeader) || ctx->hash_type <= NcaHashType_None || ctx->hash_type == NcaHashType_AutoSha3 || ctx->hash_type >= NcaHashType_Count || \
|
||||
ctx->encryption_type == NcaEncryptionType_Auto || ctx->encryption_type == NcaEncryptionType_AesCtrEx || ctx->encryption_type >= NcaEncryptionType_AesCtrExSkipLayerHash || \
|
||||
ctx->section_type >= NcaFsSectionType_Invalid || !data || !data_size || (data_offset + data_size) > ctx->section_size || !out_block_size || !out_block_offset)
|
||||
{
|
||||
|
|
|
@ -72,7 +72,7 @@ __attribute__((format(printf, 5, 6))) void logWriteFormattedStringToLogFile(u8 l
|
|||
|
||||
__attribute__((format(printf, 7, 8))) void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, u8 level, const char *file_name, int line, const char *func_name, const char *fmt, ...)
|
||||
{
|
||||
if (!dst || !dst_size || (!*dst && *dst_size) || (*dst && !*dst_size) || level < LOG_LEVEL || !file_name || !*file_name || !func_name || !*func_name || !fmt || !*fmt) return;
|
||||
if (!dst || !dst_size || level < LOG_LEVEL || !file_name || !*file_name || !func_name || !*func_name || !fmt || !*fmt) return;
|
||||
|
||||
va_list args;
|
||||
|
||||
|
@ -85,7 +85,8 @@ __attribute__((format(printf, 7, 8))) void logWriteFormattedStringToBuffer(char
|
|||
struct tm ts = {0};
|
||||
struct timespec now = {0};
|
||||
|
||||
if (dst_str_len >= dst_cur_size) return;
|
||||
/* Sanity check. */
|
||||
if (dst_cur_size && dst_str_len >= dst_cur_size) return;
|
||||
|
||||
va_start(args, fmt);
|
||||
|
||||
|
@ -106,7 +107,7 @@ __attribute__((format(printf, 7, 8))) void logWriteFormattedStringToBuffer(char
|
|||
|
||||
log_str_len = (size_t)(str1_len + str2_len + 3);
|
||||
|
||||
if (!dst_cur_size || log_str_len > (dst_cur_size - dst_str_len))
|
||||
if (!dst_ptr || !dst_cur_size || log_str_len > (dst_cur_size - dst_str_len))
|
||||
{
|
||||
/* Update buffer size. */
|
||||
dst_cur_size = (dst_str_len + log_str_len);
|
||||
|
|
|
@ -501,7 +501,7 @@ void utilsJoinThread(Thread *thread)
|
|||
|
||||
__attribute__((format(printf, 3, 4))) bool utilsAppendFormattedStringToBuffer(char **dst, size_t *dst_size, const char *fmt, ...)
|
||||
{
|
||||
if (!dst || !dst_size || (!*dst && *dst_size) || (*dst && !*dst_size) || !fmt || !*fmt)
|
||||
if (!dst || !dst_size || !fmt || !*fmt)
|
||||
{
|
||||
LOG_MSG_ERROR("Invalid parameters!");
|
||||
return false;
|
||||
|
@ -517,6 +517,7 @@ __attribute__((format(printf, 3, 4))) bool utilsAppendFormattedStringToBuffer(ch
|
|||
|
||||
bool success = false;
|
||||
|
||||
/* Sanity check. */
|
||||
if (dst_cur_size && dst_str_len >= dst_cur_size)
|
||||
{
|
||||
LOG_MSG_ERROR("String length is equal to or greater than the provided buffer size! (0x%lX >= 0x%lX).", dst_str_len, dst_cur_size);
|
||||
|
@ -535,7 +536,7 @@ __attribute__((format(printf, 3, 4))) bool utilsAppendFormattedStringToBuffer(ch
|
|||
|
||||
formatted_str_len_cast = (size_t)(formatted_str_len + 1);
|
||||
|
||||
if (!dst_cur_size || formatted_str_len_cast > (dst_cur_size - dst_str_len))
|
||||
if (!dst_ptr || !dst_cur_size || formatted_str_len_cast > (dst_cur_size - dst_str_len))
|
||||
{
|
||||
/* Update buffer size. */
|
||||
dst_cur_size = (dst_str_len + formatted_str_len_cast);
|
||||
|
@ -561,6 +562,8 @@ __attribute__((format(printf, 3, 4))) bool utilsAppendFormattedStringToBuffer(ch
|
|||
|
||||
/* Generate formatted string. */
|
||||
vsprintf(dst_ptr + dst_str_len, fmt, args);
|
||||
|
||||
/* Update output flag. */
|
||||
success = true;
|
||||
|
||||
end:
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
#define TIK_LIST_STORAGE_PATH "/ticket_list.bin"
|
||||
#define TIK_DB_STORAGE_PATH "/ticket.bin"
|
||||
|
||||
#define ES_CTRKEY_ENTRY_ALIGNMENT 0x8
|
||||
|
||||
/* Type definitions. */
|
||||
|
||||
/// Used to parse ticket_list.bin entries.
|
||||
|
@ -52,7 +50,7 @@ NXDT_ASSERT(TikListEntry, 0x20);
|
|||
|
||||
/// 9.x+ CTR key entry in ES .data segment. Used to store CTR key/IV data for encrypted volatile tickets in ticket.bin and/or encrypted entries in ticket_list.bin.
|
||||
/// This is always stored in pairs. The first entry holds the key/IV for the encrypted volatile ticket, while the second entry holds the key/IV for the encrypted entry in ticket_list.bin.
|
||||
/// First index in this list is always 0, and it's aligned to ES_CTRKEY_ENTRY_ALIGNMENT.
|
||||
/// First index in this list is always 0.
|
||||
typedef struct {
|
||||
u32 idx; ///< Entry index.
|
||||
u8 key[AES_128_KEY_SIZE]; ///< AES-128-CTR key.
|
||||
|
@ -637,7 +635,7 @@ static bool tikRetrieveTicketEntryFromTicketBin(save_ctx_t *save_ctx, u8 *buf, u
|
|||
}
|
||||
|
||||
/* Retrieve the CTR key/IV from ES program memory in order to decrypt this ticket. */
|
||||
for(u64 i = 0; i < g_esMemoryLocation.data_size; i += ES_CTRKEY_ENTRY_ALIGNMENT)
|
||||
for(u64 i = 0; i < g_esMemoryLocation.data_size; i++)
|
||||
{
|
||||
if ((g_esMemoryLocation.data_size - i) < (sizeof(TikEsCtrKeyEntry9x) * 2)) break;
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ typedef enum {
|
|||
UsbCommandType_SendFileProperties = 1,
|
||||
UsbCommandType_CancelFileTransfer = 2,
|
||||
UsbCommandType_SendNspHeader = 3,
|
||||
UsbCommandType_EndSession = 4
|
||||
UsbCommandType_EndSession = 4,
|
||||
UsbCommandType_Count = 5 ///< Total values supported by this enum.
|
||||
} UsbCommandType;
|
||||
|
||||
typedef struct {
|
||||
|
@ -108,7 +109,9 @@ typedef enum {
|
|||
UsbStatusType_UnsupportedCommand = 5,
|
||||
UsbStatusType_UnsupportedAbiVersion = 6,
|
||||
UsbStatusType_MalformedCommand = 7,
|
||||
UsbStatusType_HostIoError = 8
|
||||
UsbStatusType_HostIoError = 8,
|
||||
|
||||
UsbStatusType_Count = 9 ///< Total values supported by this enum.
|
||||
} UsbStatusType;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace nxdt::utils {
|
|||
if (R_FAILED(rc)) LOG_MSG_ERROR("svcQueryMemory failed! (0x%X).", rc);
|
||||
}
|
||||
|
||||
#if LOG_LEVEL <= LOG_LEVEL_ERROR
|
||||
#if LOG_LEVEL < LOG_LEVEL_NONE
|
||||
static bool UnwindStack(u64 *out_stack_trace, u32 *out_stack_trace_size, size_t max_stack_trace_size, u64 cur_fp)
|
||||
{
|
||||
if (!out_stack_trace || !out_stack_trace_size || !max_stack_trace_size || !cur_fp)
|
||||
|
@ -90,7 +90,7 @@ namespace nxdt::utils {
|
|||
|
||||
return (*out_stack_trace_size > 0);
|
||||
}
|
||||
#endif /* LOG_LEVEL <= LOG_LEVEL_ERROR */
|
||||
#endif /* LOG_LEVEL < LOG_LEVEL_NONE */
|
||||
|
||||
static void NORETURN AbortProgramExecution(std::string str)
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ extern "C" {
|
|||
break;
|
||||
}
|
||||
|
||||
#if LOG_LEVEL <= LOG_LEVEL_ERROR
|
||||
#if LOG_LEVEL < LOG_LEVEL_NONE
|
||||
char *exception_str = NULL;
|
||||
size_t exception_str_size = 0;
|
||||
|
||||
|
@ -220,7 +220,7 @@ extern "C" {
|
|||
|
||||
/* Free exception info string. */
|
||||
if (exception_str) free(exception_str);
|
||||
#endif /* LOG_LEVEL <= LOG_LEVEL_ERROR */
|
||||
#endif /* LOG_LEVEL < LOG_LEVEL_NONE */
|
||||
|
||||
/* Abort program execution. */
|
||||
crash_str = (g_borealisInitialized ? i18n::getStr("generic/exception_triggered"_i18n, error_desc_str, ctx->error_desc) : \
|
||||
|
|
Loading…
Reference in a new issue