diff --git a/code_templates/xml_generator.c b/code_templates/xml_generator.c index 3b6fd6b..61a261e 100644 --- a/code_templates/xml_generator.c +++ b/code_templates/xml_generator.c @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) while(true) { consoleClear(); - printf("select an user application to generate a cnmt xml for.\npress b to exit.\n\n"); + printf("select an user application to generate xmls for.\npress b to exit.\n\n"); printf("title: %u / %u\n", selected_idx + 1, app_count); printf("selected title: %016lX - %s\n\n", app_metadata[selected_idx]->title_id, app_metadata[selected_idx]->lang_entry.name); diff --git a/legacy/nca.c b/legacy/nca.c index 4e8d546..0f405a1 100644 --- a/legacy/nca.c +++ b/legacy/nca.c @@ -931,332 +931,3 @@ bool patchCnmtNca(u8 *ncaBuf, u64 ncaBufSize, cnmt_xml_program_info *xml_program return true; } - -bool generateProgramInfoXml(NcmContentStorage *ncmStorage, const NcmContentId *ncaId, nca_header_t *dec_nca_header, u8 *decrypted_nca_keys, bool useCustomAcidRsaPubKey, char **outBuf, u64 *outBufSize) -{ - if (!ncmStorage || !ncaId || !dec_nca_header || !decrypted_nca_keys || !outBuf || !outBufSize) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid parameters to generate \"programinfo.xml\"!", __func__); - return false; - } - - if (dec_nca_header->fs_headers[0].partition_type != NCA_FS_HEADER_PARTITION_PFS0 || dec_nca_header->fs_headers[0].fs_type != NCA_FS_HEADER_FSTYPE_PFS0) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: Program NCA section #0 doesn't hold a PFS0 partition!", __func__); - return false; - } - - if (!dec_nca_header->fs_headers[0].pfs0_superblock.pfs0_size) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid size for PFS0 partition in Program NCA section #0!", __func__); - return false; - } - - if (dec_nca_header->fs_headers[0].crypt_type != NCA_FS_HEADER_CRYPT_CTR) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid AES crypt type for Program NCA section #0! (0x%02X)", __func__, dec_nca_header->fs_headers[0].crypt_type); - return false; - } - - u32 i; - - bool proceed = true, success = false; - - u64 section_offset; - u64 nca_pfs0_offset; - - pfs0_header nca_pfs0_header; - pfs0_file_entry *nca_pfs0_entries = NULL; - char *nca_pfs0_str_table = NULL; - - u64 nca_pfs0_str_table_offset; - u64 nca_pfs0_data_offset; - - Aes128CtrContext aes_ctx; - - char *programInfoXml = NULL; - char tmp[NAME_BUF_LEN] = {'\0'}; - - u32 npdmEntry = 0; - npdm_t npdm_header; - u8 *npdm_acid_section = NULL; - - u64 npdm_acid_section_b64_size = 0; - char *npdm_acid_section_b64 = NULL; - - u32 acid_flags = 0; - - section_offset = ((u64)dec_nca_header->section_entries[0].media_start_offset * (u64)MEDIA_UNIT_SIZE); - nca_pfs0_offset = (section_offset + dec_nca_header->fs_headers[0].pfs0_superblock.pfs0_offset); - - if (!section_offset || section_offset < NCA_FULL_HEADER_LENGTH || !nca_pfs0_offset) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid offsets for Program NCA section #0!", __func__); - return false; - } - - // Generate initial CTR - unsigned char ctr[0x10]; - u64 ofs = (section_offset >> 4); - - for(i = 0; i < 0x8; i++) - { - ctr[i] = dec_nca_header->fs_headers[0].section_ctr[0x08 - i - 1]; - ctr[0x10 - i - 1] = (unsigned char)(ofs & 0xFF); - ofs >>= 8; - } - - u8 ctr_key[NCA_KEY_AREA_KEY_SIZE]; - memcpy(ctr_key, decrypted_nca_keys + (NCA_KEY_AREA_KEY_SIZE * 2), NCA_KEY_AREA_KEY_SIZE); - aes128CtrContextCreate(&aes_ctx, ctr_key, ctr); - - if (!processNcaCtrSectionBlock(ncmStorage, ncaId, &aes_ctx, nca_pfs0_offset, &nca_pfs0_header, sizeof(pfs0_header), false)) - { - breaks++; - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to read Program NCA section #0 PFS0 partition header!", __func__); - return false; - } - - if (__builtin_bswap32(nca_pfs0_header.magic) != PFS0_MAGIC) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid magic word for Program NCA section #0 PFS0 partition! Wrong KAEK? (0x%08X)\nTry running Lockpick_RCM to generate the keys file from scratch.", __func__, __builtin_bswap32(nca_pfs0_header.magic)); - return false; - } - - if (!nca_pfs0_header.file_cnt || !nca_pfs0_header.str_table_size) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: Program NCA section #0 PFS0 partition is empty! Wrong KAEK?\nTry running Lockpick_RCM to generate the keys file from scratch.", __func__); - return false; - } - - nca_pfs0_entries = calloc(nca_pfs0_header.file_cnt, sizeof(pfs0_file_entry)); - if (!nca_pfs0_entries) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for Program NCA section #0 PFS0 partition entries!", __func__); - return false; - } - - if (!processNcaCtrSectionBlock(ncmStorage, ncaId, &aes_ctx, nca_pfs0_offset + sizeof(pfs0_header), nca_pfs0_entries, (u64)nca_pfs0_header.file_cnt * sizeof(pfs0_file_entry), false)) - { - breaks++; - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to read Program NCA section #0 PFS0 partition entries!", __func__); - goto out; - } - - nca_pfs0_str_table_offset = (nca_pfs0_offset + sizeof(pfs0_header) + ((u64)nca_pfs0_header.file_cnt * sizeof(pfs0_file_entry))); - - nca_pfs0_str_table = calloc((u64)nca_pfs0_header.str_table_size, sizeof(char)); - if (!nca_pfs0_str_table) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for Program NCA section #0 PFS0 string table!", __func__); - goto out; - } - - if (!processNcaCtrSectionBlock(ncmStorage, ncaId, &aes_ctx, nca_pfs0_str_table_offset, nca_pfs0_str_table, (u64)nca_pfs0_header.str_table_size, false)) - { - breaks++; - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to read Program NCA section #0 PFS0 string table!", __func__); - goto out; - } - - nca_pfs0_data_offset = (nca_pfs0_str_table_offset + (u64)nca_pfs0_header.str_table_size); - - // Allocate memory for the programinfo.xml contents, making sure there's enough space - programInfoXml = calloc(NSP_XML_BUFFER_SIZE, sizeof(char)); - if (!programInfoXml) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for the \"programinfo.xml\" contents!", __func__); - goto out; - } - - sprintf(programInfoXml, "\n" \ - "\n" \ - " %u_%u_%u\n", dec_nca_header->sdk_major, dec_nca_header->sdk_minor, dec_nca_header->sdk_micro); - - // Retrieve the main.npdm contents - bool found_npdm = false; - for(i = 0; i < nca_pfs0_header.file_cnt; i++) - { - char *curFilename = (nca_pfs0_str_table + nca_pfs0_entries[i].filename_offset); - - if (strlen(curFilename) == 9 && !strncasecmp(curFilename, "main.npdm", 9) && nca_pfs0_entries[i].file_size > 0) - { - found_npdm = true; - npdmEntry = i; - break; - } - } - - if (!found_npdm) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for the \"programinfo.xml\" contents!", __func__); - goto out; - } - - // Read the META header from the NPDM - if (!processNcaCtrSectionBlock(ncmStorage, ncaId, &aes_ctx, nca_pfs0_data_offset + nca_pfs0_entries[npdmEntry].file_offset, &npdm_header, sizeof(npdm_t), false)) - { - breaks++; - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to read NPDM entry header from Program NCA section #0 PFS0!", __func__); - goto out; - } - - if (__builtin_bswap32(npdm_header.magic) != META_MAGIC) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid NPDM META magic word! Wrong KAEK? (0x%08X)\nTry running Lockpick_RCM to generate the keys file from scratch.", __func__, __builtin_bswap32(npdm_header.magic)); - goto out; - } - - // Allocate memory for the ACID section - npdm_acid_section = malloc(npdm_header.acid_size); - if (!npdm_acid_section) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for the Program NCA NPDM ACID section contents!", __func__); - goto out; - } - - if (!processNcaCtrSectionBlock(ncmStorage, ncaId, &aes_ctx, nca_pfs0_data_offset + nca_pfs0_entries[npdmEntry].file_offset + (u64)npdm_header.acid_offset, npdm_acid_section, (u64)npdm_header.acid_size, false)) - { - breaks++; - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to read ACID section from Program NCA NPDM!", __func__); - goto out; - } - - // If we're dealing with a gamecard title, replace the ACID public key with the patched one - if (useCustomAcidRsaPubKey) memcpy(npdm_acid_section + (u64)NPDM_SIGNATURE_SIZE, rsa_get_public_key(), (u64)NPDM_SIGNATURE_SIZE); - - sprintf(tmp, " %u\n", ((npdm_header.mmu_flags & 0x01) ? 64 : 32)); - strcat(programInfoXml, tmp); - - // Default this one to Release - strcat(programInfoXml, " Release\n"); - - // Retrieve the Base64 conversion length for the whole ACID section - mbedtls_base64_encode(NULL, 0, &npdm_acid_section_b64_size, npdm_acid_section, (u64)npdm_header.acid_size); - if (npdm_acid_section_b64_size <= (u64)npdm_header.acid_size) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid Base64 conversion length for the ACID section from Program NCA NPDM!", __func__); - goto out; - } - - npdm_acid_section_b64 = calloc(npdm_acid_section_b64_size + 1, sizeof(char)); - if (!npdm_acid_section_b64) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for the Base64 converted ACID section from Program NCA NPDM!", __func__); - goto out; - } - - // Perform the Base64 conversion - if (mbedtls_base64_encode((unsigned char*)npdm_acid_section_b64, npdm_acid_section_b64_size + 1, &npdm_acid_section_b64_size, npdm_acid_section, (u64)npdm_header.acid_size) != 0) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: Base64 conversion failed for the ACID section from Program NCA NPDM!", __func__); - goto out; - } - - strcat(programInfoXml, " "); - strcat(programInfoXml, npdm_acid_section_b64); - strcat(programInfoXml, "\n"); - - // TO-DO: Add more ACID flags? - - acid_flags = *((u32*)(&(npdm_acid_section[0x20C]))); - - strcat(programInfoXml, " \n"); - - sprintf(tmp, " %s\n", ((acid_flags & 0x01) ? "true" : "false")); - strcat(programInfoXml, tmp); - - sprintf(tmp, " %s\n", ((acid_flags & 0x02) ? "true" : "false")); - strcat(programInfoXml, tmp); - - strcat(programInfoXml, " \n"); - - // Middleware list - strcat(programInfoXml, " \n"); - - for(i = 0; i < nca_pfs0_header.file_cnt; i++) - { - nso_header_t nsoHeader; - char *curFilename = (nca_pfs0_str_table + nca_pfs0_entries[i].filename_offset); - u64 curFileOffset = (nca_pfs0_data_offset + nca_pfs0_entries[i].file_offset); - - if (!processNcaCtrSectionBlock(ncmStorage, ncaId, &aes_ctx, curFileOffset, &nsoHeader, sizeof(nso_header_t), false)) - { - breaks++; - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to read 0x%016lX bytes from \"%s\" in Program NCA section #0 PFS0 partition!", __func__, sizeof(nso_header_t), curFilename); - proceed = false; - break; - } - - // Check if we're dealing with a NSO - if (__builtin_bswap32(nsoHeader.magic) != NSO_MAGIC) continue; - - // Retrieve middleware list from this NSO - if (!retrieveMiddlewareListFromNso(ncmStorage, ncaId, &aes_ctx, curFilename, curFileOffset, &nsoHeader, programInfoXml)) - { - proceed = false; - break; - } - } - - if (!proceed) goto out; - - strcat(programInfoXml, " \n"); - - // Leave these fields empty (for now) - strcat(programInfoXml, " \n"); - strcat(programInfoXml, " \n"); - - // Symbols list from main NSO - strcat(programInfoXml, " \n"); - - for(i = 0; i < nca_pfs0_header.file_cnt; i++) - { - nso_header_t nsoHeader; - char *curFilename = (nca_pfs0_str_table + nca_pfs0_entries[i].filename_offset); - u64 curFileOffset = (nca_pfs0_data_offset + nca_pfs0_entries[i].file_offset); - - if (!processNcaCtrSectionBlock(ncmStorage, ncaId, &aes_ctx, curFileOffset, &nsoHeader, sizeof(nso_header_t), false)) - { - breaks++; - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to read 0x%016lX bytes from \"%s\" in Program NCA section #0 PFS0 partition!", __func__, sizeof(nso_header_t), curFilename); - proceed = false; - break; - } - - // Check if we're dealing with the main NSO - if (strlen(curFilename) != 4 || strncmp(curFilename, "main", 4) != 0 || __builtin_bswap32(nsoHeader.magic) != NSO_MAGIC) continue; - - // Retrieve symbols list from main NSO - if (!retrieveSymbolsListFromNso(ncmStorage, ncaId, &aes_ctx, curFilename, curFileOffset, &nsoHeader, programInfoXml)) proceed = false; - - break; - } - - if (!proceed) goto out; - - strcat(programInfoXml, " \n"); - - // Leave this field empty (for now) - strcat(programInfoXml, " \n"); - - strcat(programInfoXml, ""); - - *outBuf = programInfoXml; - *outBufSize = strlen(programInfoXml); - - success = true; - -out: - if (npdm_acid_section_b64) free(npdm_acid_section_b64); - - if (npdm_acid_section) free(npdm_acid_section); - - if (!success && programInfoXml) free(programInfoXml); - - if (nca_pfs0_str_table) free(nca_pfs0_str_table); - - if (nca_pfs0_entries) free(nca_pfs0_entries); - - return success; -} diff --git a/legacy/nca.h b/legacy/nca.h index 51010f6..5f147c7 100644 --- a/legacy/nca.h +++ b/legacy/nca.h @@ -365,6 +365,4 @@ bool retrieveCnmtNcaData(NcmStorageId curStorageId, u8 *ncaBuf, cnmt_xml_program bool patchCnmtNca(u8 *ncaBuf, u64 ncaBufSize, cnmt_xml_program_info *xml_program_info, cnmt_xml_content_info *xml_content_info, nca_cnmt_mod_data *cnmt_mod); -bool generateProgramInfoXml(NcmContentStorage *ncmStorage, const NcmContentId *ncaId, nca_header_t *dec_nca_header, u8 *decrypted_nca_keys, bool useCustomAcidRsaPubKey, char **outBuf, u64 *outBufSize); - #endif diff --git a/legacy/nso.c b/legacy/nso.c deleted file mode 100644 index 7f82c2b..0000000 --- a/legacy/nso.c +++ /dev/null @@ -1,430 +0,0 @@ -#include -#include -#include -#include - -#include "nso.h" -#include "lz4.h" -#include "util.h" -#include "ui.h" - -/* Extern variables */ - -extern int breaks; -extern int font_height; - -/* Statically allocated variables */ - -static u8 *nsoBinaryData = NULL; -static u64 nsoBinaryDataSize = 0; - -static u64 nsoBinaryTextSectionOffset = 0; -static u64 nsoBinaryTextSectionSize = 0; - -static u64 nsoBinaryRodataSectionOffset = 0; -static u64 nsoBinaryRodataSectionSize = 0; - -static u64 nsoBinaryDataSectionOffset = 0; -static u64 nsoBinaryDataSectionSize = 0; - -void freeNsoBinaryData() -{ - if (nsoBinaryData) - { - free(nsoBinaryData); - nsoBinaryData = NULL; - } - - nsoBinaryDataSize = 0; - - nsoBinaryTextSectionOffset = 0; - nsoBinaryTextSectionSize = 0; - - nsoBinaryRodataSectionOffset = 0; - nsoBinaryRodataSectionSize = 0; - - nsoBinaryDataSectionOffset = 0; - nsoBinaryDataSectionSize = 0; -} - -bool loadNsoBinaryData(NcmContentStorage *ncmStorage, const NcmContentId *ncaId, Aes128CtrContext *aes_ctx, u64 nso_base_offset, nso_header_t *nsoHeader) -{ - if (!ncmStorage || !ncaId || !aes_ctx || !nso_base_offset || !nsoHeader) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid parameters to load .text, .rodata and .data sections from NSO in Program NCA!", __func__); - return false; - } - - u8 i; - - u8 *nsoTextSection = NULL; - u64 nsoTextSectionSize = 0; - - u8 *nsoRodataSection = NULL; - u64 nsoRodataSectionSize = 0; - - u8 *nsoDataSection = NULL; - u64 nsoDataSectionSize = 0; - - u8 *curCompressedSection; - u64 curCompressedSectionSize; - u64 curCompressedSectionOffset; - u8 curSectionFlag; - - u8 *curDecompressedSection; - u64 curDecompressedSectionSize; - - bool success = true; - - freeNsoBinaryData(); - - for(i = 0; i < 3; i++) - { - curCompressedSection = NULL; - curCompressedSectionSize = (i == 0 ? (u64)nsoHeader->text_compressed_size : (i == 1 ? (u64)nsoHeader->rodata_compressed_size : (u64)nsoHeader->data_compressed_size)); - curCompressedSectionOffset = (nso_base_offset + (i == 0 ? (u64)nsoHeader->text_segment_header.file_offset : (i == 1 ? (u64)nsoHeader->rodata_segment_header.file_offset : (u64)nsoHeader->data_segment_header.file_offset))); - curSectionFlag = (1 << i); - - curDecompressedSection = NULL; - curDecompressedSectionSize = (i == 0 ? (u64)nsoHeader->text_segment_header.decompressed_size : (i == 1 ? (u64)nsoHeader->rodata_segment_header.decompressed_size : (u64)nsoHeader->data_segment_header.decompressed_size)); - - // Load section - curCompressedSection = malloc(curCompressedSectionSize); - if (!curCompressedSection) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for the compressed %s section from NSO in Program NCA!", __func__, (i == 0 ? ".text" : (i == 1 ? ".rodata" : ".data"))); - success = false; - break; - } - - if (!processNcaCtrSectionBlock(ncmStorage, ncaId, aes_ctx, curCompressedSectionOffset, curCompressedSection, curCompressedSectionSize, false)) - { - breaks++; - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to read 0x%016lX bytes %s section from NSO in Program NCA!", __func__, curCompressedSectionSize, (i == 0 ? ".text" : (i == 1 ? ".rodata" : ".data"))); - free(curCompressedSection); - success = false; - break; - } - - if (nsoHeader->flags & curSectionFlag) - { - if (curDecompressedSectionSize <= curCompressedSectionSize) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid decompressed size for %s section from NSO in Program NCA!", __func__, (i == 0 ? ".text" : (i == 1 ? ".rodata" : ".data"))); - free(curCompressedSection); - success = false; - break; - } - - // Uncompress section - curDecompressedSection = malloc(curDecompressedSectionSize); - if (!curDecompressedSection) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for the decompressed %s section from NSO in Program NCA!", __func__, (i == 0 ? ".text" : (i == 1 ? ".rodata" : ".data"))); - free(curCompressedSection); - success = false; - break; - } - - if (LZ4_decompress_safe((const char*)curCompressedSection, (char*)curDecompressedSection, (int)curCompressedSectionSize, (int)curDecompressedSectionSize) != (int)curDecompressedSectionSize) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to decompress %s section from NSO in Program NCA!", __func__, (i == 0 ? ".text" : (i == 1 ? ".rodata" : ".data"))); - free(curDecompressedSection); - free(curCompressedSection); - success = false; - break; - } - - free(curCompressedSection); - - switch(i) - { - case 0: - nsoTextSection = curDecompressedSection; - nsoTextSectionSize = curDecompressedSectionSize; - break; - case 1: - nsoRodataSection = curDecompressedSection; - nsoRodataSectionSize = curDecompressedSectionSize; - break; - case 2: - nsoDataSection = curDecompressedSection; - nsoDataSectionSize = curDecompressedSectionSize; - break; - default: - break; - } - } else { - switch(i) - { - case 0: - nsoTextSection = curCompressedSection; - nsoTextSectionSize = curCompressedSectionSize; - break; - case 1: - nsoRodataSection = curCompressedSection; - nsoRodataSectionSize = curCompressedSectionSize; - break; - case 2: - nsoDataSection = curCompressedSection; - nsoDataSectionSize = curCompressedSectionSize; - break; - default: - break; - } - } - } - - curCompressedSection = curDecompressedSection = NULL; - - if (success) - { - // Calculate full binary size - u64 finalTextSectionSize = nsoTextSectionSize; - u64 finalRodataSectionSize = nsoRodataSectionSize; - - nsoBinaryDataSize = nsoTextSectionSize; - - if ((u64)nsoHeader->rodata_segment_header.memory_offset > nsoBinaryDataSize) - { - nsoBinaryDataSize += ((u64)nsoHeader->rodata_segment_header.memory_offset - nsoBinaryDataSize); - } else - if ((u64)nsoHeader->rodata_segment_header.memory_offset < nsoBinaryDataSize) - { - finalTextSectionSize -= (nsoBinaryDataSize - (u64)nsoHeader->rodata_segment_header.memory_offset); - nsoBinaryDataSize -= (nsoBinaryDataSize - (u64)nsoHeader->rodata_segment_header.memory_offset); - } - - nsoBinaryDataSize += nsoRodataSectionSize; - - if ((u64)nsoHeader->data_segment_header.memory_offset > nsoBinaryDataSize) - { - nsoBinaryDataSize += ((u64)nsoHeader->data_segment_header.memory_offset - nsoBinaryDataSize); - } else - if ((u64)nsoHeader->data_segment_header.memory_offset < nsoBinaryDataSize) - { - finalRodataSectionSize -= (nsoBinaryDataSize - (u64)nsoHeader->data_segment_header.memory_offset); - nsoBinaryDataSize -= (nsoBinaryDataSize - (u64)nsoHeader->data_segment_header.memory_offset); - } - - nsoBinaryDataSize += nsoDataSectionSize; - - nsoBinaryData = calloc(nsoBinaryDataSize, sizeof(u8)); - if (nsoBinaryData) - { - memcpy(nsoBinaryData, nsoTextSection, finalTextSectionSize); - memcpy(nsoBinaryData + (u64)nsoHeader->rodata_segment_header.memory_offset, nsoRodataSection, finalRodataSectionSize); - memcpy(nsoBinaryData + (u64)nsoHeader->data_segment_header.memory_offset, nsoDataSection, nsoDataSectionSize); - - nsoBinaryTextSectionOffset = 0; - nsoBinaryTextSectionSize = finalTextSectionSize; - - nsoBinaryRodataSectionOffset = (u64)nsoHeader->rodata_segment_header.memory_offset; - nsoBinaryRodataSectionSize = finalRodataSectionSize; - - nsoBinaryDataSectionOffset = (u64)nsoHeader->data_segment_header.memory_offset; - nsoBinaryDataSectionSize = nsoDataSectionSize; - } else { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate %lu bytes for full decompressed NSO in Program NCA!", __func__, nsoBinaryDataSize); - nsoBinaryDataSize = 0; - success = false; - } - } - - if (nsoTextSection) free(nsoTextSection); - if (nsoRodataSection) free(nsoRodataSection); - if (nsoDataSection) free(nsoDataSection); - - return success; -} - -bool retrieveMiddlewareListFromNso(NcmContentStorage *ncmStorage, const NcmContentId *ncaId, Aes128CtrContext *aes_ctx, const char *nso_filename, u64 nso_base_offset, nso_header_t *nsoHeader, char *programInfoXml) -{ - if (!ncmStorage || !ncaId || !aes_ctx || !nso_filename || !strlen(nso_filename) || !nso_base_offset || !nsoHeader || !programInfoXml) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid parameters to retrieve middleware list from NSO in Program NCA!", __func__); - return false; - } - - u64 i; - - char tmp[NAME_BUF_LEN] = {'\0'}; - - if (!loadNsoBinaryData(ncmStorage, ncaId, aes_ctx, nso_base_offset, nsoHeader)) return false; - - for(i = 0; i < nsoBinaryRodataSectionSize; i++) - { - char *curStr = ((char*)nsoBinaryData + nsoBinaryRodataSectionOffset + i); - - if (strncmp(curStr, "SDK MW+", 7) != 0) continue; - - // Found a match - char *mwDev = (curStr + 7); - char *mwName = (strchr(mwDev, '+') + 1); - - // Filter nnSdk entries - if (!strncasecmp(mwName, "NintendoSdk_nnSdk", 17)) - { - i += strlen(curStr); - continue; - } - - sprintf(tmp, " \n" \ - " %s\n" \ - " %.*s\n" \ - " %s\n" \ - " \n", \ - mwName, \ - (int)(mwName - mwDev - 1), mwDev, \ - nso_filename); - - strcat(programInfoXml, tmp); - - // Update counter - i += strlen(curStr); - } - - freeNsoBinaryData(); - - return true; -} - -bool retrieveSymbolsListFromNso(NcmContentStorage *ncmStorage, const NcmContentId *ncaId, Aes128CtrContext *aes_ctx, const char *nso_filename, u64 nso_base_offset, nso_header_t *nsoHeader, char *programInfoXml) -{ - if (!ncmStorage || !ncaId || !aes_ctx || !nso_filename || !strlen(nso_filename) || !nso_base_offset || !nsoHeader || !programInfoXml) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid parameters to retrieve symbols list from NSO in Program NCA!", __func__); - return false; - } - - u64 i; - - bool success = false; - - char tmp[NAME_BUF_LEN] = {'\0'}; - - u32 mod_magic_offset; - u32 mod_magic; - s32 dynamic_section_offset; - - bool armv7; - - u64 dynamic_block_size; - u64 dynamic_block_cnt; - - bool found_strtab = false; - u64 symbol_str_table_offset = 0; - - bool found_symtab = false; - u64 symbol_table_offset = 0; - - bool found_strsz = false; - u64 symbol_str_table_size = 0; - - char *symbol_str_table = NULL; - - u64 cur_symbol_table_offset = 0; - - if (!loadNsoBinaryData(ncmStorage, ncaId, aes_ctx, nso_base_offset, nsoHeader)) return false; - - mod_magic_offset = *((u32*)(&(nsoBinaryData[0x04]))); - mod_magic = *((u32*)(&(nsoBinaryData[mod_magic_offset]))); - dynamic_section_offset = ((s32)mod_magic_offset + *((s32*)(&(nsoBinaryData[mod_magic_offset + 0x04])))); - - if (__builtin_bswap32(mod_magic) != MOD_MAGIC) - { - uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: invalid MOD0 magic word in decompressed NSO from Program NCA! (0x%08X)", __func__, __builtin_bswap32(mod_magic)); - goto out; - } - - armv7 = (*((u64*)(&(nsoBinaryData[dynamic_section_offset]))) > (u64)0xFFFFFFFF || *((u64*)(&(nsoBinaryData[dynamic_section_offset + 0x10]))) > (u64)0xFFFFFFFF); - - // Read dynamic section - dynamic_block_size = (armv7 ? 0x08 : 0x10); - dynamic_block_cnt = ((nsoBinaryDataSize - dynamic_section_offset) / dynamic_block_size); - - for(i = 0; i < dynamic_block_cnt; i++) - { - if ((nsoBinaryDataSize - dynamic_section_offset - (i * dynamic_block_size)) < dynamic_block_size) break; - - u64 tag = (armv7 ? (u64)(*((u32*)(&(nsoBinaryData[dynamic_section_offset + (i * dynamic_block_size)])))) : *((u64*)(&(nsoBinaryData[dynamic_section_offset + (i * dynamic_block_size)])))); - u64 val = (armv7 ? (u64)(*((u32*)(&(nsoBinaryData[dynamic_section_offset + (i * dynamic_block_size) + 0x04])))) : *((u64*)(&(nsoBinaryData[dynamic_section_offset + (i * dynamic_block_size) + 0x08])))); - - if (!tag) break; - - if (tag == DT_STRTAB && !found_strtab) - { - // Retrieve symbol string table offset - symbol_str_table_offset = val; - found_strtab = true; - } - - if (tag == DT_SYMTAB && !found_symtab) - { - // Retrieve symbol table offset - symbol_table_offset = val; - found_symtab = true; - } - - if (tag == DT_STRSZ && !found_strsz) - { - // Retrieve symbol string table size - symbol_str_table_size = val; - found_strsz = true; - } - - if (found_strtab && found_symtab && found_strsz) break; - } - - if (!found_strtab || !found_symtab || !found_strsz) - { - // Nothing to do here if we can't find what we need - success = true; - goto out; - } - - // Point to the symbol string table - symbol_str_table = ((char*)nsoBinaryData + symbol_str_table_offset); - - // Retrieve symbol list - cur_symbol_table_offset = symbol_table_offset; - while(true) - { - if (symbol_table_offset < symbol_str_table_offset && cur_symbol_table_offset >= symbol_str_table_offset) break; - - u32 st_name = *((u32*)(&(nsoBinaryData[cur_symbol_table_offset]))); - u8 st_info = (armv7 ? nsoBinaryData[cur_symbol_table_offset + 0x0C] : nsoBinaryData[cur_symbol_table_offset + 0x04]); - //u8 st_other = (armv7 ? nsoBinaryData[cur_symbol_table_offset + 0x0D] : nsoBinaryData[cur_symbol_table_offset + 0x05]); - u16 st_shndx = (armv7 ? *((u16*)(&(nsoBinaryData[cur_symbol_table_offset + 0x0E]))) : *((u16*)(&(nsoBinaryData[cur_symbol_table_offset + 0x06])))); - u64 st_value = (armv7 ? (u64)(*((u32*)(&(nsoBinaryData[cur_symbol_table_offset + 0x04])))) : *((u64*)(&(nsoBinaryData[cur_symbol_table_offset + 0x08])))); - //u64 st_size = (armv7 ? (u64)(*((u32*)(&(nsoBinaryData[cur_symbol_table_offset + 0x08])))) : *((u64*)(&(nsoBinaryData[cur_symbol_table_offset + 0x10])))); - - //u8 st_vis = (st_other & 0x03); - u8 st_type = (st_info & 0x0F); - //u8 st_bind = (st_info >> 0x04); - - if (st_name >= symbol_str_table_size) break; - - cur_symbol_table_offset += (armv7 ? 0x10 : 0x18); - - // TO-DO: Add more filters? - if (!st_shndx && !st_value && st_type != ST_OBJECT) - { - sprintf(tmp, " \n" \ - " %s\n" \ - " %s\n" \ - " \n", \ - symbol_str_table + st_name, \ - nso_filename); - - strcat(programInfoXml, tmp); - } - } - - success = true; - -out: - freeNsoBinaryData(); - - return success; -} diff --git a/legacy/nso.h b/legacy/nso.h deleted file mode 100644 index d5b0063..0000000 --- a/legacy/nso.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#ifndef __NSO_H__ -#define __NSO_H__ - -#include - -#define NSO_MAGIC (u32)0x4E534F30 // "NSO0" -#define MOD_MAGIC (u32)0x4D4F4430 // "MOD0" - -#define DT_STRTAB 0x05 -#define DT_SYMTAB 0x06 -#define DT_STRSZ 0x0A - -#define ST_OBJECT 0x01 - -typedef struct { - u32 file_offset; - u32 memory_offset; - u32 decompressed_size; -} PACKED segment_header_t; - -typedef struct { - u32 region_offset; - u32 region_size; -} PACKED rodata_extent_t; - -typedef struct { - u32 magic; - u32 version; - u32 reserved1; - u32 flags; - segment_header_t text_segment_header; - u32 module_offset; - segment_header_t rodata_segment_header; - u32 module_file_size; - segment_header_t data_segment_header; - u32 bss_size; - u8 elf_note_build_id[0x20]; - u32 text_compressed_size; - u32 rodata_compressed_size; - u32 data_compressed_size; - u8 reserved2[0x1C]; - rodata_extent_t rodata_api_info; - rodata_extent_t rodata_dynstr; - rodata_extent_t rodata_dynsym; - u8 text_decompressed_hash[0x20]; - u8 rodata_decompressed_hash[0x20]; - u8 data_decompressed_hash[0x20]; -} PACKED nso_header_t; - -// Retrieves the middleware list from a NSO stored in a partition from a NCA file -bool retrieveMiddlewareListFromNso(NcmContentStorage *ncmStorage, const NcmContentId *ncaId, Aes128CtrContext *aes_ctx, const char *nso_filename, u64 nso_base_offset, nso_header_t *nsoHeader, char *programInfoXml); - -// Retrieves the symbols list from a NSO stored in a partition from a NCA file -bool retrieveSymbolsListFromNso(NcmContentStorage *ncmStorage, const NcmContentId *ncaId, Aes128CtrContext *aes_ctx, const char *nso_filename, u64 nso_base_offset, nso_header_t *nsoHeader, char *programInfoXml); - -#endif