// Test access to "am" service, which we shouldn't have access to, unless khax succeeds. Result test_am_access_inner() { Handle testHandle; Result res = srvGetServiceHandleDirect(&testHandle, "am:u"); if (testHandle) svcCloseHandle(testHandle); return res; }
void testService(const char *name) { Handle amHandle = 0; Result res; // Call am:u service res = srvGetServiceHandleDirect(&amHandle, name); printf("%s init1 result/handle: res=%lu handle=%lu\n", name, res, amHandle); if(amHandle) { svcCloseHandle(amHandle); } }
Result srvGetServiceHandle(Handle* out, const char* name) { /* Look in service-list given to us by loader. If we find find a match, we return it. */ Handle h = envGetHandle(name); if(h != 0) { return svcDuplicateHandle(out, h); } /* Normal request to service manager. */ return srvGetServiceHandleDirect(out, name); }
Result filesystemInit() { Result ret; fsInit(); if (R_FAILED(ret = srvGetServiceHandleDirect(&fsHandle, "fs:USER"))) return ret; if (R_FAILED(ret = FSUSER_Initialize(fsHandle))) return ret; fsUseSession(fsHandle, false); sdmcArchive = (FS_Archive){ARCHIVE_SDMC, (FS_Path){PATH_EMPTY, 1, (u8*)""}, 0}; if (R_FAILED(ret = FSUSER_OpenArchive(&sdmcArchive))) return ret; saveGameArchive = (FS_Archive){ARCHIVE_SAVEDATA, (FS_Path){PATH_EMPTY, 1, (u8*)""}, 0}; if (R_FAILED(ret = FSUSER_OpenArchive(&saveGameArchive))) return ret; return ret; }
void Player::Init(int argc, char *argv[]) { static bool init = false; frames = 0; if (init) return; // Display a nice version string std::stringstream header; std::string addtl_ver(PLAYER_ADDTL); header << "EasyRPG Player " << PLAYER_VERSION; if (!addtl_ver.empty()) header << " " << addtl_ver; header << " started"; Output::Debug(header.str().c_str()); unsigned int header_width = header.str().length(); header.str(""); header << std::setfill('=') << std::setw(header_width) << "="; Output::Debug(header.str().c_str()); #ifdef GEKKO // Init libfat (Mount SD/USB) if (!fatInitDefault()) { Output::Error("Couldn't mount any storage medium!"); } #elif defined(_3DS) // Starting debug console gfxInitDefault(); consoleInit(GFX_BOTTOM, NULL); APT_SetAppCpuTimeLimit(30); if (osGetKernelVersion() < SYSTEM_VERSION(2, 48, 3)) khaxInit(); // Executing libkhax just to be sure... consoleClear(); // Check if we already have access to csnd:SND, if not, we will perform a kernel privilege escalation Handle csndHandle = 0; use_dsp = false; #ifndef FORCE_DSP srvGetServiceHandleDirect(&csndHandle, "csnd:SND"); if (csndHandle) { Output::Debug("csnd:SND has been selected as audio service."); svcCloseHandle(csndHandle); } else { Output::Debug("csnd:SND is unavailable..."); #endif srvGetServiceHandleDirect(&csndHandle, "dsp::DSP"); if (csndHandle) { Output::Debug("dsp::DSP has been selected as audio service."); use_dsp = true; svcCloseHandle(csndHandle); } else { Output::Error("dsp::DSP is unavailable. Please dump a DSP firmware to use EasyRPG Player. If the problem persists, please report us the issue."); } #ifndef FORCE_DSP } #endif fsInit(); sdmcInit(); #ifndef CITRA3DS_COMPATIBLE romfsInit(); #endif hidInit(); // Enable 804 Mhz mode if on N3DS bool isN3DS; APT_CheckNew3DS(&isN3DS); if (isN3DS) { osSetSpeedupEnable(true); } #endif #if (defined(_WIN32) && defined(NDEBUG) && defined(WINVER) && WINVER >= 0x0600) InitMiniDumpWriter(); #endif srand(time(NULL)); ParseCommandLine(argc, argv); #ifdef EMSCRIPTEN Output::IgnorePause(true); // Create initial directory structure in our private area // Retrieve save directory from persistent storage EM_ASM( FS.mkdir("easyrpg"); FS.chdir("easyrpg"); var dirs = ['Backdrop', 'Battle', 'Battle2', 'BattleCharSet', 'BattleWeapon', 'CharSet', 'ChipSet', 'FaceSet', 'Frame', 'GameOver', 'Monster', 'Movie', 'Music', 'Panorama', 'Picture', 'Sound', 'System', 'System2', 'Title', 'Save']; dirs.forEach(function(dir) { FS.mkdir(dir) }); FS.mount(IDBFS, {}, 'Save'); FS.syncfs(true, function(err) { }); );
int main() { gfxInitDefault(); gfxSet3D(false); PrintConsole topConsole, botConsole; consoleInit(GFX_TOP, &topConsole); consoleInit(GFX_BOTTOM, &botConsole); consoleSelect(&topConsole); consoleClear(); state_t current_state = STATE_NONE; state_t next_state = STATE_INITIALIZE; FS_ProductInfo product_info; char exploitname[64] = {0}; char titlename[64] = {0}; char versiondir[64] = {0}; char displayversion[64] = {0}; u32 flags_bitmask = 0; static char top_text[2048]; char top_text_tmp[256]; top_text[0] = '\0'; int firmware_version[6] = {0}; int firmware_selected_value = 0; int selected_slot = 0; int selected_version = 0; u32 selected_remaster = 0; AM_TitleEntry update_title; bool update_exists = false; int version_maxnum = 0; void* payload_buffer = NULL; size_t payload_size = 0; u64 program_id = 0; while(aptMainLoop()) { hidScanInput(); if(hidKeysDown() & KEY_START) break; // transition function if(next_state != current_state) { memset(top_text_tmp, 0, sizeof(top_text_tmp)); switch(next_state) { case STATE_INITIALIZE: strncat(top_text, "Initializing... You may press START at any time\nto return to menu.\n\n", sizeof(top_text) - 1); break; case STATE_INITIAL: strncat(top_text, "Welcome to sploit_installer: SALT edition!\nPlease proceed with caution, as you might lose\ndata if you don't.\n\nPress A to continue.\n\n", sizeof(top_text) - 1); break; case STATE_SELECT_VERSION: snprintf(top_text_tmp, sizeof(top_text_tmp) - 1, "Auto-detected %s version: %s\nD-Pad to select, A to continue.\n\n", titlename, displayversion); break; case STATE_SELECT_SLOT: snprintf(top_text_tmp, sizeof(top_text_tmp) - 1, "Please select the savegame slot %s will be\ninstalled to. D-Pad to select, A to continue.\n", exploitname); break; case STATE_SELECT_FIRMWARE: strncat(top_text, "Please select your console's firmware version.\nOnly select NEW 3DS if you own a New 3DS (XL).\nD-Pad to select, A to continue.\n", sizeof(top_text) - 1); break; case STATE_DOWNLOAD_PAYLOAD: snprintf(top_text, sizeof(top_text) - 1, "%s\n\n\nDownloading payload...\n", top_text); break; case STATE_COMPRESS_PAYLOAD: strncat(top_text, "Processing payload...\n", sizeof(top_text) - 1); break; case STATE_INSTALL_PAYLOAD: strncat(top_text, "Installing payload...\n\n", sizeof(top_text) - 1); break; case STATE_INSTALLED_PAYLOAD: snprintf(top_text_tmp, sizeof(top_text_tmp) - 1, "Done!\n%s was successfully installed.", exploitname); break; case STATE_ERROR: strncat(top_text, "Looks like something went wrong. :(\n", sizeof(top_text) - 1); break; default: break; } if(top_text_tmp[0]) strncat(top_text, top_text_tmp, sizeof(top_text) - 1); current_state = next_state; } consoleSelect(&topConsole); printf("\x1b[0;%dHsploit_installer: SALT edition\n\n\n", (50 - 31) / 2); printf(top_text); // state function switch(current_state) { case STATE_INITIALIZE: { fsInit(); // get an fs:USER session as the game Result ret = srvGetServiceHandleDirect(&save_session, "fs:USER"); if(R_SUCCEEDED(ret)) ret = FSUSER_Initialize(save_session); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to get game fs:USER session.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } ret = httpcInit(0); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to initialize httpc.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } OS_VersionBin nver_versionbin, cver_versionbin; ret = osGetSystemVersionData(&nver_versionbin, &cver_versionbin); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to get the system version.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } ret = cfguInit(); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to initialize cfgu.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } u8 region = 0; ret = CFGU_SecureInfoGetRegion(®ion); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to get the system region.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } cfguExit(); bool is_new3ds = false; APT_CheckNew3DS(&is_new3ds); firmware_version[0] = is_new3ds; firmware_version[5] = region; firmware_version[1] = cver_versionbin.mainver; firmware_version[2] = cver_versionbin.minor; firmware_version[3] = cver_versionbin.build; firmware_version[4] = nver_versionbin.mainver; u32 pid = 0; ret = svcGetProcessId(&pid, CUR_PROCESS_HANDLE); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to get the process ID for the current process.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } ret = FSUSER_GetProductInfo(&product_info, pid); selected_remaster = product_info.remasterVersion; if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to get the product info for the current process.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } ret = APT_GetProgramID(&program_id); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to get the program ID for the current process.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } u64 update_program_id = 0; if(((program_id >> 32) & 0xFFFF) == 0) update_program_id = program_id | 0x0000000E00000000ULL; if(update_program_id) { ret = amInit(); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to initialize AM.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } ret = AM_GetTitleInfo(1, 1, &update_program_id, &update_title); amExit(); if(R_SUCCEEDED(ret)) update_exists = true; } ret = romfsInit(); if(R_FAILED(ret)) { snprintf(status, sizeof(status) - 1, "Failed to initialize romfs for this application (romfsInit()).\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } ret = load_exploitlist_config("romfs:/exploitlist_config", &program_id, exploitname, titlename, &flags_bitmask); if(ret) { snprintf(status, sizeof(status) - 1, "Failed to select the exploit.\n Error code: %08lX", ret); if(ret == 1) strncat(status, " Failed to\nopen the config file in romfs.", sizeof(status) - 1); if(ret == 2) strncat(status, " This title is not supported.", sizeof(status) - 1); next_state = STATE_ERROR; break; } int version_index = 0; u32 this_remaster = 0; char this_displayversion[64] = {0}; while(true) { ret = load_exploitversion(exploitname, &program_id, version_index, &this_remaster, this_displayversion); if(ret) break; if(this_remaster == selected_remaster) { strncpy(displayversion, this_displayversion, 63); selected_version = version_index; } version_index++; } if(version_index == 0) { snprintf(status, sizeof(status) - 1, "Failed to read remaster versions from config."); next_state = STATE_ERROR; break; } version_maxnum = version_index - 1; next_state = STATE_INITIAL; } break; case STATE_INITIAL: { if(hidKeysDown() & KEY_A) { if(version_maxnum != 0) next_state = STATE_SELECT_VERSION; else if(flags_bitmask & 0x10) next_state = STATE_SELECT_FIRMWARE; else next_state = STATE_SELECT_SLOT; } } break; case STATE_SELECT_VERSION: { if(hidKeysDown() & KEY_UP) selected_version++; if(hidKeysDown() & KEY_DOWN) selected_version--; if(hidKeysDown() & KEY_A) { if(flags_bitmask & 0x10) next_state = STATE_SELECT_FIRMWARE; else next_state = STATE_SELECT_SLOT; } if(selected_version < 0) selected_version = 0; if(selected_version > version_maxnum) selected_version = version_maxnum; Result ret = load_exploitversion(exploitname, &program_id, selected_version, &selected_remaster, displayversion); if(ret) { snprintf(status, sizeof(status) - 1, "Failed to read remaster version from config."); next_state = STATE_ERROR; break; } printf((selected_version >= version_maxnum) ? " \n" : " ^\n"); printf(" Selected version: %s \n", displayversion); printf((!selected_version) ? " \n" : " v\n"); } break; case STATE_SELECT_SLOT: { if(hidKeysDown() & KEY_UP) selected_slot++; if(hidKeysDown() & KEY_DOWN) selected_slot--; if(hidKeysDown() & KEY_A) next_state = STATE_SELECT_FIRMWARE; if(selected_slot < 0) selected_slot = 0; if(selected_slot > 2) selected_slot = 2; printf((selected_slot >= 2) ? " \n" : " ^\n"); printf(" Selected slot: %d \n", selected_slot + 1); printf((!selected_slot) ? " \n" : " v\n"); } break; case STATE_SELECT_FIRMWARE: { if(hidKeysDown() & KEY_LEFT) firmware_selected_value--; if(hidKeysDown() & KEY_RIGHT) firmware_selected_value++; if(firmware_selected_value < 0) firmware_selected_value = 0; if(firmware_selected_value > 5) firmware_selected_value = 5; if(hidKeysDown() & KEY_UP) firmware_version[firmware_selected_value]++; if(hidKeysDown() & KEY_DOWN) firmware_version[firmware_selected_value]--; int firmware_maxnum = 256; if(firmware_selected_value == 0) firmware_maxnum = 2; if(firmware_selected_value == 5) firmware_maxnum = 7; if(firmware_version[firmware_selected_value] < 0) firmware_version[firmware_selected_value] = 0; if(firmware_version[firmware_selected_value] >= firmware_maxnum) firmware_version[firmware_selected_value] = firmware_maxnum - 1; if(hidKeysDown() & KEY_A) next_state = STATE_DOWNLOAD_PAYLOAD; int offset = 26; if(firmware_selected_value) { offset += 7; for(int i = 1; i < firmware_selected_value; i++) { offset += 2; if(firmware_version[i] >= 10) offset++; } } printf((firmware_version[firmware_selected_value] < firmware_maxnum - 1) ? "%*s^%*s" : "%*s-%*s", offset, " ", 50 - offset - 1, " "); printf(" Selected firmware: %s %d-%d-%d-%d %s \n", firmware_version[0] ? "New3DS" : "Old3DS", firmware_version[1], firmware_version[2], firmware_version[3], firmware_version[4], regions[firmware_version[5]]); printf((firmware_version[firmware_selected_value] > 0) ? "%*sv%*s" : "%*s-%*s", offset, " ", 50 - offset - 1, " "); } break; case STATE_DOWNLOAD_PAYLOAD: { httpcContext context; static char in_url[512]; static char out_url[512]; snprintf(in_url, sizeof(in_url) - 1, "http://smea.mtheall.com/get_payload.php?version=%s-%d-%d-%d-%d-%s", firmware_version[0] ? "NEW" : "OLD", firmware_version[1], firmware_version[2], firmware_version[3], firmware_version[4], regions[firmware_version[5]]); char user_agent[64]; snprintf(user_agent, sizeof(user_agent) - 1, "salt_sploit_installer-%s", exploitname); Result ret = get_redirect(in_url, out_url, 512, user_agent); if(R_FAILED(ret)) { sprintf(status, "Failed to grab payload url\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } ret = httpcOpenContext(&context, HTTPC_METHOD_GET, out_url, 0); if(R_FAILED(ret)) { sprintf(status, "Failed to open http context\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } ret = download_file(&context, &payload_buffer, &payload_size, user_agent); if(R_FAILED(ret)) { sprintf(status, "Failed to download payload\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } if(flags_bitmask & 0x1) next_state = STATE_COMPRESS_PAYLOAD; else next_state = STATE_INSTALL_PAYLOAD; } break; case STATE_COMPRESS_PAYLOAD: payload_buffer = BLZ_Code(payload_buffer, payload_size, &payload_size, BLZ_NORMAL); next_state = STATE_INSTALL_PAYLOAD; break; case STATE_INSTALL_PAYLOAD: { u32 selected_remaster_version = 0; Result ret = load_exploitconfig(exploitname, &program_id, selected_remaster, update_exists ? &update_title.version : NULL, &selected_remaster_version, versiondir, displayversion); if(ret) { snprintf(status, sizeof(status) - 1, "Failed to find your version of\n%s in the config / config loading failed.\n Error code: %08lX", titlename, ret); if(ret == 1) strncat(status, " Failed to\nopen the config file in romfs.", sizeof(status) - 1); if(ret == 2 || ret == 4) strncat(status, " The romfs config file is invalid.", sizeof(status) - 1); if(ret == 3) { snprintf(status, sizeof(status) - 1, "this update-title version (v%u) of %s is not compatible with %s, sorry\n", update_title.version, titlename, exploitname); next_state = STATE_ERROR; break; } if(ret == 5) { snprintf(status, sizeof(status) - 1, "this remaster version (%04lX) of %s is not compatible with %s, sorry\n", selected_remaster_version, titlename, exploitname); next_state = STATE_ERROR; break; } next_state = STATE_ERROR; break; } if(flags_bitmask & 0x8) { fsUseSession(save_session); Result ret = FSUSER_FormatSaveData(ARCHIVE_SAVEDATA, (FS_Path){PATH_EMPTY, 1, (u8*)""}, 0x200, 10, 10, 11, 11, true); fsEndUseSession(); if(ret) { sprintf(status, "Failed to format savedata.\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } } if(flags_bitmask & 0x2) { Result ret = parsecopy_saveconfig(versiondir, firmware_version[0], selected_slot); if(ret) { sprintf(status, "Failed to install the savefiles with romfs %s savedir.\n Error code: %08lX", firmware_version[0] == 0?"Old3DS" : "New3DS", ret); next_state = STATE_ERROR; break; } } if(flags_bitmask & 0x4) { Result ret = parsecopy_saveconfig(versiondir, 2, selected_slot); if(ret) { sprintf(status, "Failed to install the savefiles with romfs %s savedir.\n Error code: %08lX", "common", ret); next_state = STATE_ERROR; break; } } } { Result ret; if(payload_embed.enabled) { void* buffer = NULL; size_t size = 0; ret = read_savedata(payload_embed.path, &buffer, &size); if(ret) { sprintf(status, "Failed to embed payload\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } if((payload_embed.offset + payload_size + sizeof(u32)) >= size) { sprintf(status, "Failed to embed payload (too large)\n 0x%X >= 0x%X", (payload_embed.offset + payload_size + sizeof(u32)), size); next_state = STATE_ERROR; break; } *(u32*)(buffer + payload_embed.offset) = payload_size; memcpy(buffer + payload_embed.offset + sizeof(u32), payload_buffer, payload_size); ret = write_savedata(payload_embed.path, buffer, size); free(buffer); } else ret = write_savedata("/payload.bin", payload_buffer, payload_size); if(ret) { sprintf(status, "Failed to install payload\n Error code: %08lX", ret); next_state = STATE_ERROR; break; } next_state = STATE_INSTALLED_PAYLOAD; } break; case STATE_INSTALLED_PAYLOAD: next_state = STATE_NONE; break; default: break; } consoleSelect(&botConsole); printf("\x1b[0;0H Current status:\n %s\n", status); gspWaitForVBlank(); } if(payload_buffer) free(payload_buffer); romfsExit(); httpcExit(); svcCloseHandle(save_session); fsExit(); gfxExit(); return 0; }