1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-12-23 00:52:10 +00:00

Update to v1.1.10.

This commit is contained in:
Pablo Curiel 2020-04-18 23:03:58 -04:00
parent a999447580
commit ff3141f5d6
8 changed files with 100 additions and 121 deletions

View file

@ -33,7 +33,7 @@ include $(DEVKITPRO)/libnx/switch_rules
VERSION_MAJOR := 1
VERSION_MINOR := 1
VERSION_MICRO := 9
VERSION_MICRO := 10
APP_TITLE := nxdumptool
APP_AUTHOR := DarkMatterCore

View file

@ -78,6 +78,14 @@ If you like my work and you'd like to support me in any way, it's not necessary,
Changelog
--------------
**v1.1.10:**
* Built using libnx v3.1.0.
* Updated save.c/h to reflect changes made by shchmue in Lockpick_RCM. Fixes crashes under HOS 10.0.0.
* Fixed a nasty stack corruption issue caused by improper handling of FatFs objects. Fixes ES savefile mounting errors throughout the application (e.g. batch mode, ticket dumping).
This is only a bugfix release. I don't expect to release any new versions until the rewrite is finished - the only exception being fixing some kind of feature-breaking bug. Please understand.
**v1.1.9:**
* Built using libnx commit d7e6207.

View file

@ -1,4 +1,3 @@
#include <switch/arm/atomics.h>
#include <switch/services/sm.h>
#include <stdlib.h>
#include <string.h>

View file

@ -134,7 +134,7 @@ bool retrieveProcessMemory(keyLocation *location)
u64 pids[300];
u32 num_processes;
result = svcGetProcessList(&num_processes, pids, 300);
result = svcGetProcessList((s32*)&num_processes, pids, 300);
if (R_FAILED(result))
{
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: svcGetProcessList failed! (0x%08X)", __func__, result);
@ -763,59 +763,6 @@ void mgf1(const u8 *data, size_t data_length, u8 *mask, size_t mask_length)
free(data_counter);
}
void dumpSharedTikSavedata(void)
{
FRESULT fr;
FIL save;
u32 size, blk, i, j;
u32 rd_b, wr_b;
FILE *out;
for(i = 0; i < 2; i++)
{
fr = FR_OK;
memset(&save, 0, sizeof(FIL));
size = 0;
blk = DUMP_BUFFER_SIZE;
out = NULL;
fr = f_open(&save, (i == 0 ? "sys:/save/80000000000000e3" : "sys:/save/80000000000000e4"), FA_READ | FA_OPEN_EXISTING);
if (fr) continue;
size = f_size(&save);
if (!size)
{
f_close(&save);
continue;
}
out = fopen((i == 0 ? "sdmc:/80000000000000e3" : "sdmc:/80000000000000e4"), "wb");
if (!out)
{
f_close(&save);
continue;
}
for(j = 0; j < size; j += blk)
{
if ((size - j) < blk) blk = (size - j);
rd_b = wr_b = 0;
fr = f_read(&save, dumpBuf, blk, &rd_b);
if (fr || rd_b != blk) break;
wr_b = fwrite(dumpBuf, 1, blk, out);
if (wr_b != blk) break;
}
fclose(out);
f_close(&save);
}
}
int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_enc_key, u8 *out_dec_key)
{
int ret = -1;
@ -865,8 +812,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
u8 *D = NULL, *N = NULL, *E = NULL;
FRESULT fr;
FIL eTicketSave;
FRESULT fr = FR_OK;
FIL *eTicketSave = NULL;
save_ctx_t *save_ctx = NULL;
allocation_table_storage_ctx_t fat_storage;
@ -984,7 +931,6 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
{
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: NCA rights ID unavailable in this console!", __func__);
ret = -2;
dumpSharedTikSavedata();
return ret;
}
@ -1037,11 +983,19 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
setcal_eticket_retrieved = true;
}
eTicketSave = calloc(1, sizeof(FIL));
if (!eTicketSave)
{
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for FatFs file descriptor!", __func__);
return ret;
}
// FatFs is used to mount the BIS System partition and read the ES savedata files to avoid 0xE02 (file already in use) errors
fr = f_open(&eTicketSave, (rightsIdType == 1 ? BIS_COMMON_TIK_SAVE_NAME : BIS_PERSONALIZED_TIK_SAVE_NAME), FA_READ | FA_OPEN_EXISTING);
fr = f_open(eTicketSave, (rightsIdType == 1 ? BIS_COMMON_TIK_SAVE_NAME : BIS_PERSONALIZED_TIK_SAVE_NAME), FA_READ | FA_OPEN_EXISTING);
if (fr)
{
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to open ES %s eTicket save! (%u)", __func__, (rightsIdType == 1 ? "common" : "personalized"), fr);
free(eTicketSave);
return ret;
}
@ -1049,11 +1003,12 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
if (!save_ctx)
{
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to allocate memory for ticket savefile context!");
f_close(&eTicketSave);
f_close(eTicketSave);
free(eTicketSave);
return ret;
}
save_ctx->file = &eTicketSave;
save_ctx->file = eTicketSave;
save_ctx->tool_ctx.action = 0;
if (!save_process(save_ctx))
@ -1062,7 +1017,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
strcat(strbuf, tmp);
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
free(save_ctx);
f_close(&eTicketSave);
f_close(eTicketSave);
free(eTicketSave);
return ret;
}
@ -1073,7 +1029,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
save_free_contexts(save_ctx);
free(save_ctx);
f_close(&eTicketSave);
f_close(eTicketSave);
free(eTicketSave);
return ret;
}
@ -1084,7 +1041,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
save_free_contexts(save_ctx);
free(save_ctx);
f_close(&eTicketSave);
f_close(eTicketSave);
free(eTicketSave);
return ret;
}
@ -1156,7 +1114,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
save_free_contexts(save_ctx);
free(save_ctx);
f_close(&eTicketSave);
f_close(eTicketSave);
free(eTicketSave);
if (!proceed) return ret;
@ -1164,7 +1123,6 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
{
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to find a matching eTicket entry for NCA rights ID!", __func__);
ret = -2;
dumpSharedTikSavedata();
return ret;
}

View file

@ -152,7 +152,7 @@ remap_segment_ctx_t *save_remap_init_segments(remap_header_t *header, remap_entr
return NULL;
}
remap_segment_ctx_t *segments = calloc(sizeof(remap_segment_ctx_t), header->map_segment_count);
remap_segment_ctx_t *segments = calloc(header->map_segment_count, sizeof(remap_segment_ctx_t));
if (!segments)
{
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate initial memory for remap segments!", __func__);
@ -164,39 +164,40 @@ remap_segment_ctx_t *save_remap_init_segments(remap_header_t *header, remap_entr
for(i = 0; i < header->map_segment_count; i++)
{
remap_segment_ctx_t *seg = &segments[i];
remap_segment_ctx_t *seg = &(segments[i]);
seg->entries = calloc(1, sizeof(remap_entry_ctx_t));
seg->entry_count = 0;
seg->entries = calloc(1, sizeof(remap_entry_ctx_t*));
if (!seg->entries)
{
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate memory for remap segment entry #%u!", __func__, entry_idx);
goto out;
}
memcpy(seg->entries, &map_entries[entry_idx], sizeof(remap_entry_ctx_t));
seg->entries[seg->entry_count++] = &map_entries[entry_idx];
seg->offset = map_entries[entry_idx].virtual_offset;
map_entries[entry_idx].segment = seg;
seg->entry_count = 1;
entry_idx++;
map_entries[entry_idx++].segment = seg;
while(entry_idx < num_map_entries && map_entries[entry_idx - 1].virtual_offset_end == map_entries[entry_idx].virtual_offset)
{
map_entries[entry_idx].segment = seg;
map_entries[entry_idx - 1].next = &map_entries[entry_idx];
seg->entries = calloc(1, sizeof(remap_entry_ctx_t));
if (!seg->entries)
remap_entry_ctx_t **ptr = calloc(sizeof(remap_entry_ctx_t*), seg->entry_count + 1);
if (!ptr)
{
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate memory for remap segment entry #%u!", __func__, entry_idx);
goto out;
}
memcpy(seg->entries, &map_entries[entry_idx], sizeof(remap_entry_ctx_t));
seg->entry_count++;
entry_idx++;
memcpy(ptr, seg->entries, sizeof(remap_entry_ctx_t*) * seg->entry_count);
free(seg->entries);
seg->entries = ptr;
seg->entries[seg->entry_count++] = &map_entries[entry_idx++];
}
seg->length = (seg->entries[seg->entry_count - 1].virtual_offset_end - seg->entries[0].virtual_offset);
seg->length = (seg->entries[seg->entry_count - 1]->virtual_offset_end - seg->entries[0]->virtual_offset);
}
success = true;
@ -216,8 +217,7 @@ out:
map_entries[entry_idx].segment->entries = NULL;
}
map_entries[entry_idx].segment = NULL;
entry_idx++;
map_entries[entry_idx++].segment = NULL;
while(entry_idx < num_map_entries && map_entries[entry_idx - 1].virtual_offset_end == map_entries[entry_idx].virtual_offset)
{
@ -231,8 +231,7 @@ out:
map_entries[entry_idx].segment->entries = NULL;
}
map_entries[entry_idx].segment = NULL;
entry_idx++;
map_entries[entry_idx++].segment = NULL;
}
}
@ -257,7 +256,7 @@ remap_entry_ctx_t *save_remap_get_map_entry(remap_storage_ctx_t *ctx, u64 offset
{
for(unsigned int i = 0; i < ctx->segments[segment_idx].entry_count; i++)
{
if (ctx->segments[segment_idx].entries[i].virtual_offset_end > offset) return (&ctx->segments[segment_idx].entries[i]);
if (ctx->segments[segment_idx].entries[i]->virtual_offset_end > offset) return ctx->segments[segment_idx].entries[i];
}
}
@ -409,7 +408,7 @@ bool save_ivfc_storage_init(hierarchical_integrity_verification_storage_ctx_t *c
u32 length;
};
static struct salt_source_t salt_sources[6] = {
static const struct salt_source_t salt_sources[6] = {
{"HierarchicalIntegrityVerificationStorage::Master", 48},
{"HierarchicalIntegrityVerificationStorage::L1", 44},
{"HierarchicalIntegrityVerificationStorage::L2", 44},
@ -618,7 +617,7 @@ bool save_ivfc_storage_read(integrity_verification_storage_ctx_t *ctx, void *buf
}
memcpy(data_buffer, ctx->salt, 0x20);
memcpy(data_buffer + 0x20, buffer, count);
memcpy(data_buffer + 0x20, buffer, ctx->sector_size);
sha256CalculateHash(hash, data_buffer, ctx->sector_size + 0x20);
hash[0x1F] |= 0x80;
@ -1336,9 +1335,7 @@ bool save_process(save_ctx_t *ctx)
return success;
}
if (!save_process_header(ctx)) return success;
if (ctx->header_hash_validity == VALIDITY_INVALID)
if (!save_process_header(ctx) || ctx->header_hash_validity == VALIDITY_INVALID)
{
/* Try to parse Header B. */
fr = f_lseek(ctx->file, 0x4000);
@ -1355,9 +1352,7 @@ bool save_process(save_ctx_t *ctx)
return success;
}
if (!save_process_header(ctx)) return success;
if (ctx->header_hash_validity == VALIDITY_INVALID)
if (!save_process_header(ctx) || ctx->header_hash_validity == VALIDITY_INVALID)
{
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: savefile header is invalid!", __func__);
return success;
@ -1717,10 +1712,7 @@ void save_free_contexts(save_ctx_t *ctx)
{
for(unsigned int i = 0; i < ctx->data_remap_storage.header->map_segment_count; i++)
{
for(unsigned int j = 0; j < ctx->data_remap_storage.segments[i].entry_count; j++)
{
if (&(ctx->data_remap_storage.segments[i].entries[j])) free(&(ctx->data_remap_storage.segments[i].entries[j]));
}
if (ctx->data_remap_storage.segments[i].entries) free(ctx->data_remap_storage.segments[i].entries);
}
}
@ -1740,10 +1732,7 @@ void save_free_contexts(save_ctx_t *ctx)
{
for(unsigned int i = 0; i < ctx->meta_remap_storage.header->map_segment_count; i++)
{
for(unsigned int j = 0; j < ctx->meta_remap_storage.segments[i].entry_count; j++)
{
if (&(ctx->meta_remap_storage.segments[i].entries[j])) free(&(ctx->meta_remap_storage.segments[i].entries[j]));
}
if (ctx->meta_remap_storage.segments[i].entries) free(ctx->meta_remap_storage.segments[i].entries);
}
}
@ -1846,14 +1835,14 @@ bool readCertsFromSystemSave()
{
if (loadedCerts) return true;
FRESULT fr;
FIL certSave;
FRESULT fr = FR_OK;
FIL *certSave = NULL;
save_ctx_t *save_ctx = NULL;
allocation_table_storage_ctx_t fat_storage;
save_fs_list_entry_t entry;
allocation_table_storage_ctx_t fat_storage = {0};
save_fs_list_entry_t entry = {0};
u64 internalCertSize;
u64 internalCertSize = 0;
u8 i, j;
UINT br = 0;
@ -1863,7 +1852,14 @@ bool readCertsFromSystemSave()
bool success = false, openSave = false, initSaveCtx = false;
fr = f_open(&certSave, BIS_CERT_SAVE_NAME, FA_READ | FA_OPEN_EXISTING);
certSave = calloc(1, sizeof(FIL));
if (!certSave)
{
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: unable to allocate memory for FatFs file descriptor!", __func__);
goto out;
}
fr = f_open(certSave, BIS_CERT_SAVE_NAME, FA_READ | FA_OPEN_EXISTING);
if (fr != FR_OK)
{
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to open \"%s\" savefile from BIS System partition! (%u)", __func__, BIS_CERT_SAVE_NAME, fr);
@ -1879,7 +1875,7 @@ bool readCertsFromSystemSave()
goto out;
}
save_ctx->file = &certSave;
save_ctx->file = certSave;
save_ctx->tool_ctx.action = 0;
initSaveCtx = save_process(save_ctx);
@ -1987,7 +1983,11 @@ out:
free(save_ctx);
}
if (openSave) f_close(&certSave);
if (certSave)
{
if (openSave) f_close(certSave);
free(certSave);
}
return success;
}

View file

@ -161,7 +161,7 @@ struct remap_entry_ctx_t {
struct remap_segment_ctx_t{
u64 offset;
u64 length;
remap_entry_ctx_t *entries;
remap_entry_ctx_t **entries;
u64 entry_count;
};

View file

@ -4333,7 +4333,7 @@ UIResult uiProcess()
{
if (scrollAmount > 0)
{
cursor = ((uiState == stateNspPatchDumpMenu && cursor == 3) ? 4 : 5);
cursor = ((uiState == stateNspPatchDumpMenu && cursor <= 3) ? 4 : 5);
} else
if (scrollAmount < 0)
{

View file

@ -96,8 +96,8 @@ char strbuf[NAME_BUF_LEN] = {'\0'};
static const char *appLaunchPath = NULL;
FsStorage fatFsStorage;
static bool openBis = false, mountBisFatFs = false;
FsStorage fatFsStorage = {0};
static FATFS *fatFsObj = NULL;
u64 freeSpace = 0;
char freeSpaceStr[32] = {'\0'};
@ -353,33 +353,47 @@ static Result getGameCardStoragePartitionSize(u64 *out)
bool mountSysEmmcPartition()
{
FATFS fs;
Result result = 0;
FRESULT fr = FR_OK;
Result result = fsOpenBisStorage(&fatFsStorage, FsBisPartitionId_System);
result = fsOpenBisStorage(&fatFsStorage, FsBisPartitionId_System);
if (R_FAILED(result))
{
uiDrawString(STRING_DEFAULT_POS, FONT_COLOR_ERROR_RGB, "%s: failed to open BIS System partition! (0x%08X)", __func__, result);
return false;
}
openBis = true;
fatFsObj = calloc(1, sizeof(FATFS));
if (!fatFsObj)
{
uiDrawString(STRING_DEFAULT_POS, FONT_COLOR_ERROR_RGB, "%s: failed to allocate memory for FatFs object!", __func__);
return false;
}
FRESULT fr = f_mount(&fs, BIS_MOUNT_NAME, 1);
fr = f_mount(fatFsObj, BIS_MOUNT_NAME, 1);
if (fr != FR_OK)
{
uiDrawString(STRING_DEFAULT_POS, FONT_COLOR_ERROR_RGB, "%s: failed to mount BIS System partition! (%u)", __func__, fr);
return false;
}
mountBisFatFs = true;
return true;
}
void unmountSysEmmcPartition()
{
if (mountBisFatFs) f_unmount(BIS_MOUNT_NAME);
if (openBis) fsStorageClose(&fatFsStorage);
if (fatFsObj)
{
f_unmount(BIS_MOUNT_NAME);
free(fatFsObj);
fatFsObj = NULL;
}
if (serviceIsActive(&(fatFsStorage.s)))
{
fsStorageClose(&fatFsStorage);
memset(&fatFsStorage, 0, sizeof(FsStorage));
}
}
static bool isServiceRunning(const char *name)