#endif
#include <option.h>
-#define TEXT_PATH PATH_EXEFS_TEXT "/0000000000000000"
-#define DATA_PATH PATH_EXEFS_DATA "/0000000000000000"
-#define RO_PATH PATH_EXEFS_RO "/0000000000000000"
-#define LANG_PATH PATH_LOCEMU "/0000000000000000"
+#define MERGE_PATH PATH_EXEFS "/0000000000000000"
+#define TEXT_PATH PATH_EXEFS_TEXT "/0000000000000000"
+#define DATA_PATH PATH_EXEFS_DATA "/0000000000000000"
+#define RO_PATH PATH_EXEFS_RO "/0000000000000000"
+#define LANG_PATH PATH_LOCEMU "/0000000000000000"
const char hexDigits[] = "0123456789ABCDEF";
{
// TODO - Implement. Needs some thought. This should allow usage of files off SD rather than RomFS.
- /* Okay, so in a nutshell, here's how the alternatives work:
- * -----------------------------------------------------------------
- * NTR / layeredFS
- *
- * NTR injects itself in the process' memory, so the plugin running
- * is a part of the program for all intents. That explains a few
- * things.
- *
- * What layeredFS does is hook fsRegArchive with its' own callback,
- * and fsOpenFile as well (in the program.) The fsRegArchive hook
- * registers a SDMC archive as ram:/ (instead of rom:/) as well as
- * the usual setup. When calling fsOpenFile, it checks to see if
- * a rom:/ path is used and if a file exists at ram:/ (and if so,
- * replaces o -> a.
- *
- * Things running in NTR are automatically patched for SD access,
- * too, which can be solved from here (considering we patch OURSELF
- * to do so in loader)
- *
- * layeredFS lacks any comments to help decipher but that's what I
- * understand, at least.
- *
- * While it also could memsearch at runtime and work as generic,
- * it doesn't. It uses a python script to find static offsets.
- * There's really no good reason for it to be implemented this way.
- *
- * -----------------------------------------------------------------
- * HANS
- *
- * So, considering the code isn't terribly well documented, this may
- * be wrong. Feel free to correct me.
- *
- * All the archive mounting/reading functions are taken over by HANS
- * and replaced with its own hooks instead.
- *
- * HANS does so in an incredibly interesting way using darm. It
- * disassembles the code to find what it's looking for, and extracts
- * offsets from branches. It calculates where it can inject the code
- * and re-allocates the space for its own hooks.
- *
- * In the end, HANS takes over the RomFS mounting code so it mounts
- * off the SD rather than the game. It doesn't take over fsOpenFile
- * because the game has correct handles passed around for the RomFS.
- *
- * This is probably incredibly inefficient but also entirely fool-
- * proof.
- * -----------------------------------------------------------------
- *
- * The best approach here is to implement the hooks like layeredFS
- * does and append code to the text segment. This has a few
- * negatives, namely, we have to write it as assembler.
- *
- * Otherwise, it is completely viable to do this from loader.
- */
+ // FUTURE NOTE - Luma has this halfway w/ Romfs redirection. Their method consists of overwriting
+ // a known unused SDK function (possibly?) which is a clever workaround for lack of code expansion.
}
void
if (!(highTid == 0x00040000 || highTid == 0x00040002) && !config.options[OPTION_LOADER_DUMPCODE_ALL])
return;
- static char text_path[] = TEXT_PATH;
- static char data_path[] = DATA_PATH;
- static char ro_path[] = RO_PATH;
- Handle code_f;
+ if (config.options[OPTION_LOADER_DUMPCODE_MERGED]) {
+ static char merge_path[] = MERGE_PATH;
+ Handle code_f;
- hexdump_titleid(progId, text_path);
- hexdump_titleid(progId, data_path);
- hexdump_titleid(progId, ro_path);
+ hexdump_titleid(progId, merge_path);
- u32 len;
+ u32 len;
- // Text section.
+ u32 size = (shared->text_size + shared->ro_size + shared->data_size) << 12;
- // Attempts to load code section from SD card, including system titles/modules/etc.
- if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, text_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) {
- FSFILE_Read(code_f, &len, 0, (void*)shared->text_addr, shared->text_size << 12);
- logstr(" loaded text from ");
- logstr(text_path);
- logstr("\n");
- }
- // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title
- else if (config.options[OPTION_LOADER_DUMPCODE]) {
- if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, text_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) {
- FSFILE_Write(code_f, &len, 0, (void*)shared->text_addr, shared->text_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
- logstr(" dumped text to ");
+ // Attempts to load code section from SD card, including system titles/modules/etc.
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, merge_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) {
+ FSFILE_Read(code_f, &len, 0, (void*)shared->text_addr, size);
+ logstr(" loaded codebin from ");
+ logstr(merge_path);
+ logstr("\n");
+ }
+ // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title
+ else if (config.options[OPTION_LOADER_DUMPCODE]) {
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, merge_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) {
+ FSFILE_Write(code_f, &len, 0, (void*)shared->text_addr, size, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
+ logstr(" dumped codebin to ");
+ logstr(merge_path);
+ logstr("\n");
+ }
+ }
+ FSFILE_Close(code_f);
+ } else {
+ static char text_path[] = TEXT_PATH;
+ static char data_path[] = DATA_PATH;
+ static char ro_path[] = RO_PATH;
+ Handle code_f;
+
+ hexdump_titleid(progId, text_path);
+ hexdump_titleid(progId, data_path);
+ hexdump_titleid(progId, ro_path);
+
+ u32 len;
+
+ // Text section.
+
+ // Attempts to load code section from SD card, including system titles/modules/etc.
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, text_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) {
+ FSFILE_Read(code_f, &len, 0, (void*)shared->text_addr, shared->text_size << 12);
+ logstr(" loaded text from ");
logstr(text_path);
logstr("\n");
}
- }
- FSFILE_Close(code_f);
+ // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title
+ else if (config.options[OPTION_LOADER_DUMPCODE]) {
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, text_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) {
+ FSFILE_Write(code_f, &len, 0, (void*)shared->text_addr, shared->text_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
+ logstr(" dumped text to ");
+ logstr(text_path);
+ logstr("\n");
+ }
+ }
+ FSFILE_Close(code_f);
- // Data section.
+ // Data section.
- // Attempts to load code section from SD card, including system titles/modules/etc.
- if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, data_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) {
- FSFILE_Read(code_f, &len, 0, (void*)shared->data_addr, shared->data_size << 12);
- logstr(" loaded data from ");
- logstr(data_path);
- logstr("\n");
- }
- // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title
- else if (config.options[OPTION_LOADER_DUMPCODE]) {
- if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, data_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) {
- FSFILE_Write(code_f, &len, 0, (void*)shared->data_addr, shared->data_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
- logstr(" dumped data to ");
+ // Attempts to load code section from SD card, including system titles/modules/etc.
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, data_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) {
+ FSFILE_Read(code_f, &len, 0, (void*)shared->data_addr, shared->data_size << 12);
+ logstr(" loaded data from ");
logstr(data_path);
logstr("\n");
}
- }
- FSFILE_Close(code_f);
+ // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title
+ else if (config.options[OPTION_LOADER_DUMPCODE]) {
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, data_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) {
+ FSFILE_Write(code_f, &len, 0, (void*)shared->data_addr, shared->data_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
+ logstr(" dumped data to ");
+ logstr(data_path);
+ logstr("\n");
+ }
+ }
+ FSFILE_Close(code_f);
- // RO Section.
+ // RO Section.
- // Attempts to load code section from SD card, including system titles/modules/etc.
- if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, ro_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) {
- FSFILE_Read(code_f, &len, 0, (void*)shared->ro_addr, shared->ro_size << 12);
- logstr(" loaded ro from ");
- logstr(ro_path);
- logstr("\n");
- }
- // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title
- else if (config.options[OPTION_LOADER_DUMPCODE]) {
- if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, ro_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) {
- FSFILE_Write(code_f, &len, 0, (void*)shared->ro_addr, shared->ro_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
- logstr(" dumped ro to ");
+ // Attempts to load code section from SD card, including system titles/modules/etc.
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, ro_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) {
+ FSFILE_Read(code_f, &len, 0, (void*)shared->ro_addr, shared->ro_size << 12);
+ logstr(" loaded ro from ");
logstr(ro_path);
logstr("\n");
}
+ // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title
+ else if (config.options[OPTION_LOADER_DUMPCODE]) {
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, ro_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) {
+ FSFILE_Write(code_f, &len, 0, (void*)shared->ro_addr, shared->ro_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
+ logstr(" dumped ro to ");
+ logstr(ro_path);
+ logstr("\n");
+ }
+ }
+ FSFILE_Close(code_f);
}
- FSFILE_Close(code_f);
}
// This is only for the .code segment.