static int lua_downstring(lua_State *L){ int argc = lua_gettop(L); #ifndef SKIP_ERROR_HANDLING if (argc != 1) return luaL_error(L, "wrong number of arguments"); #endif const char* url = luaL_checkstring(L,1); httpcContext context; Result ret = httpcOpenContext(&context, (char*)url , 0); #ifndef SKIP_ERROR_HANDLING if(ret==0){ #endif httpcBeginRequest(&context); /*httpcReqStatus loading; httpcGetRequestState(&context, &loading); while (loading == 0x5){ httpcGetRequestState(&context, &loading); }*/ u32 statuscode=0; u32 contentsize=0; httpcGetResponseStatusCode(&context, &statuscode, 0); char text[128]; sprintf(text,"%i",statuscode); if (statuscode != 200) luaL_error(L, text); httpcGetDownloadSizeState(&context, NULL, &contentsize); unsigned char *buffer = (unsigned char*)malloc(contentsize+1); httpcDownloadData(&context, buffer, contentsize, NULL); buffer[contentsize] = 0; lua_pushlstring(L,(const char*)buffer,contentsize); free(buffer); #ifndef SKIP_ERROR_HANDLING }else luaL_error(L, "error opening url"); #endif httpcCloseContext(&context); return 1; }
/*** Open an url in the context. @function :open @tparam string url the url to open @tparam[opt="GET"] string method method to use; can be `"GET"`, `"POST"`, `"HEAD"`, `"PUT"` or `"DELETE"` @treturn[1] boolean `true` if everything went fine @treturn[2] boolean `false` in case of error @treturn[2] integer error code */ static int httpc_open(lua_State *L) { httpcContext *context = lua_touserdata(L, 1); char *url = (char*)luaL_checkstring(L, 2); char *smethod = (char*)luaL_optstring(L, 3, "GET"); HTTPC_RequestMethod method = HTTPC_METHOD_GET; // default to GET if (strcmp(smethod, "POST")) { method = HTTPC_METHOD_POST; } else if (strcmp(smethod, "HEAD")) { method = HTTPC_METHOD_HEAD; } else if (strcmp(smethod, "PUT")) { method = HTTPC_METHOD_PUT; } else if (strcmp(smethod, "DELETE")) { method = HTTPC_METHOD_DELETE; } Result ret = 0; ret = httpcOpenContext(context, method, url, 0); if (ret != 0) { lua_pushboolean(L, false); lua_pushinteger(L, ret); return 2; } lua_pushboolean(L, true); return 1; }
Result http_getactual_payloadurl(char *requrl, char *outurl, u32 outurl_maxsize) { Result ret=0; httpcContext context; ret = httpcOpenContext(&context, requrl, 1); if(ret!=0)return ret; ret = httpcAddRequestHeaderField(&context, "User-Agent", "hblauncher_loader/"VERSION); if(ret!=0) { httpcCloseContext(&context); return ret; } ret = httpcBeginRequest(&context); if(ret!=0) { httpcCloseContext(&context); return ret; } ret = httpcGetResponseHeader(&context, "Location", outurl, outurl_maxsize); httpcCloseContext(&context); return 0; }
const char* HttpService::get(char *url) { u32 statuscode = 0; u32 contentsize = 0; u8 *buf; httpcContext context; Result ret = 0; ret = httpcOpenContext(&context, url, 1); ret = httpcBeginRequest(&context); if(ret!=0)return NULL; ret = httpcGetResponseStatusCode(&context, &statuscode, 0); if(ret!=0)return NULL; if(statuscode!=200)return NULL; ret=httpcGetDownloadSizeState(&context, NULL, &contentsize); if(ret!=0)return NULL; buf = (u8*)malloc(contentsize + 1); if(buf==NULL)return NULL; memset(buf, 0, contentsize + 1); ret = httpcDownloadData(&context, buf, contentsize, NULL); if(ret!=0) { free(buf); return NULL; } httpcCloseContext(&context); return (const char*)buf; }
Result DownloadFile_Internal(const char *url, void *out, bool bProgress, void (*write)(void* out, unsigned char* buffer, u32 readSize)) { httpcContext context; u32 fileSize = 0; u32 procSize = 0; Result ret = 0; Result dlret = HTTPC_RESULTCODE_DOWNLOADPENDING; u32 status; u32 bufSize = 0x100000; u32 readSize = 0; httpcOpenContext(&context, HTTPC_METHOD_GET, (char*)url, 1); ret = httpcBeginRequest(&context); if (ret != 0) goto _out; ret = httpcGetResponseStatusCode(&context, &status, 0); if (ret != 0) goto _out; if (status != 200) { ret = status; goto _out; } ret = httpcGetDownloadSizeState(&context, NULL, &fileSize); if (ret != 0) goto _out; { unsigned char *buffer = (unsigned char *)linearAlloc(bufSize); if (buffer == NULL) { printf("Error allocating download buffer\n"); ret = -1; goto _out; } while (dlret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING) { memset(buffer, 0, bufSize); dlret = httpcDownloadData(&context, buffer, bufSize, &readSize); write(out, buffer, readSize); procSize += readSize; if (bProgress) { PrintProgress(fileSize, procSize); } } linearFree(buffer); } _out: httpcCloseContext(&context); return ret; }
int main() { Result ret=0; httpcContext context; // Initialize services srvInit(); aptInit(); hidInit(NULL); gfxInit(); //gfxSet3D(true); // uncomment if using stereoscopic 3D httpcInit(); ret = httpcOpenContext(&context, "http://10.0.0.3/httpexample_rawimg.bin", 0);//Change this to your own URL. if(ret==0) { ret=http_download(&context); httpcCloseContext(&context); } // Main loop while (aptMainLoop()) { gspWaitForVBlank(); hidScanInput(); // Your code goes here u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; // break in order to return to hbmenu // Flush and swap framebuffers gfxFlushBuffers(); gfxSwapBuffers(); } // Exit services httpcExit(); gfxExit(); hidExit(); aptExit(); srvExit(); return 0; }
static int lua_download(lua_State *L){ int argc = lua_gettop(L); #ifndef SKIP_ERROR_HANDLING if (argc != 2) return luaL_error(L, "wrong number of arguments"); #endif const char* url = luaL_checkstring(L,1); const char* file = luaL_checkstring(L,2); httpcContext context; Result ret = httpcOpenContext(&context, (char*)url , 0); #ifndef SKIP_ERROR_HANDLING if(ret==0){ #endif httpcBeginRequest(&context); /*httpcReqStatus loading; httpcGetRequestState(&context, &loading); while (loading == 0x5){ httpcGetRequestState(&context, &loading); }*/ u32 statuscode=0; u32 contentsize=0; httpcGetResponseStatusCode(&context, &statuscode, 0); #ifndef SKIP_ERROR_HANDLING if (statuscode != 200) luaL_error(L, "download request error"); #endif httpcGetDownloadSizeState(&context, NULL, &contentsize); u8* buf = (u8*)malloc(contentsize); memset(buf, 0, contentsize); httpcDownloadData(&context, buf, contentsize, NULL); Handle fileHandle; u32 bytesWritten; FS_Archive sdmcArchive=(FS_Archive){ARCHIVE_SDMC, (FS_Path){PATH_EMPTY, 1, (u8*)""}}; FS_Path filePath=fsMakePath(PATH_ASCII, file); FSUSER_OpenFileDirectly( &fileHandle, sdmcArchive, filePath, FS_OPEN_CREATE|FS_OPEN_WRITE, 0x00000000); FSFILE_Write(fileHandle, &bytesWritten, 0, buf, contentsize,0x10001); FSFILE_Close(fileHandle); svcCloseHandle(fileHandle); free(buf); #ifndef SKIP_ERROR_HANDLING }else luaL_error(L, "error opening url"); #endif httpcCloseContext(&context); return 0; }
static Result action_url_install_open_src(void* data, u32 index, u32* handle) { url_install_data* installData = (url_install_data*) data; Result res = 0; httpcContext* context = (httpcContext*) calloc(1, sizeof(httpcContext)); if(context != NULL) { if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, installData->urls[index], 1))) { char userAgent[128]; snprintf(userAgent, sizeof(userAgent), "Mozilla/5.0 (Nintendo 3DS; Mobile; rv:10.0) Gecko/20100101 FBI/%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO); if(R_SUCCEEDED(res = httpcSetSSLOpt(context, SSLCOPT_DisableVerify)) && R_SUCCEEDED(res = httpcAddRequestHeaderField(context, "User-Agent", userAgent)) && R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &installData->responseCode, 0))) { if(installData->responseCode == 200) { *handle = (u32) context; } else if(installData->responseCode == 301 || installData->responseCode == 302 || installData->responseCode == 303) { memset(installData->urls[index], '\0', URL_MAX); if(R_SUCCEEDED(res = httpcGetResponseHeader(context, "Location", installData->urls[index], URL_MAX))) { httpcCloseContext(context); free(context); return action_url_install_open_src(data, index, handle); } } else { res = R_FBI_HTTP_RESPONSE_CODE; } } if(R_FAILED(res)) { httpcCloseContext(context); } } if(R_FAILED(res)) { free(context); } } else { res = R_FBI_OUT_OF_MEMORY; } return res; }
Result get_redirect(char *url, char *out, size_t out_size, char *user_agent) { Result ret; httpcContext context; ret = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 0); if(R_FAILED(ret)) return ret; ret = httpcAddRequestHeaderField(&context, "User-Agent", user_agent); if(R_SUCCEEDED(ret)) ret = httpcBeginRequest(&context); if(R_FAILED(ret)) { httpcCloseContext(&context); return ret; } ret = httpcGetResponseHeader(&context, "Location", out, out_size); httpcCloseContext(&context); return ret; }
static Result action_install_cdn_open_src(void* data, u32 index, u32* handle) { install_cdn_data* installData = (install_cdn_data*) data; Result res = 0; httpcContext* context = (httpcContext*) calloc(1, sizeof(httpcContext)); if(context != NULL) { char url[256]; if(index == 0) { snprintf(url, 256, "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/%016llX/tmd", installData->ticket->titleId); } else { snprintf(url, 256, "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/%016llX/%08lX", installData->ticket->titleId, installData->contentIds[index - 1]); } if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, url, 1))) { httpcSetSSLOpt(context, SSLCOPT_DisableVerify); if(R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &installData->responseCode, 0))) { if(installData->responseCode == 200) { *handle = (u32) context; } else { res = R_FBI_HTTP_RESPONSE_CODE; } } if(R_FAILED(res)) { httpcCloseContext(context); } } if(R_FAILED(res)) { free(context); } } else { res = R_FBI_OUT_OF_MEMORY; } return res; }
Result downloadPage(Handle httpcHandle, char* url, const short* filename) { Result ret; httpcContext context; u32 statuscode, size; ret = httpcOpenContext(httpcHandle, &context, url); if(!ret) { ret = httpcBeginRequest(&context); if(ret) goto exit; ret = httpcGetResponseStatusCode(&context, &statuscode); if(ret || statuscode != 200) goto exit; ret = httpcGetDownloadSizeState(&context, 0, &size); if(ret) goto exit; ret = downloadPageToSDCard(&context, filename, size); exit: httpcCloseContext(httpcHandle, &context); } return ret; }
int httpGet(const char* url, u8** buf, u32* size) { httpcContext context; CHECK(httpcOpenContext(&context, HTTPC_METHOD_GET, (char*)url, 0), "Could not open HTTP context"); // Add User Agent field (required by Github API calls) CHECK(httpcAddRequestHeaderField(&context, (char*)"User-Agent", (char*)"ARN-UPDATER"), "Could not set User Agent"); CHECK(httpcBeginRequest(&context), "Could not begin request"); // Add root CA required for Github and AWS URLs CHECK(httpcAddTrustedRootCA(&context, digicert_cer, digicert_cer_len), "Could not add Digicert root CA"); CHECK(httpcAddTrustedRootCA(&context, cybertrust_cer, cybertrust_cer_len), "Could not add Cybertrust root CA"); u32 statuscode = 0; CHECK(httpcGetResponseStatusCode(&context, &statuscode, 0), "Could not get status code"); if (statuscode != 200) { // Handle 3xx codes if (statuscode >= 300 && statuscode < 400) { char newUrl[1024]; CHECK(httpcGetResponseHeader(&context, (char*)"Location", newUrl, 1024), "Could not get Location header for 3xx reply"); CHECK(httpcCloseContext(&context), "Could not close HTTP context"); return httpGet(newUrl, buf, size); } throw formatErrMessage("Non-200 status code", statuscode); } CHECK(httpcGetDownloadSizeState(&context, NULL, size), "Could not get file size"); *buf = (u8*)std::malloc(*size); if (*buf == NULL) throw formatErrMessage("Could not allocate enough memory", *size); std::memset(*buf, 0, *size); CHECK(httpcDownloadData(&context, *buf, *size, NULL), "Could not download data"); CHECK(httpcCloseContext(&context), "Could not close HTTP context"); return 1; }
void downloadfile() { consoleSelect(&topScreen); char *url2 = "http://mabel.nonm.co.uk/woop/download.php"; //char *url2 = url; char *file_name; file_name = strrchr( url2, '/' ) + 1; printf("Downloading %s to %s\n",url2,file_name); gfxFlushBuffers(); ret = httpcOpenContext(&context, url2 , 0); gfxFlushBuffers(); if(ret==0) { ret=http_downloadsave(&context, file_name); gfxFlushBuffers(); httpcCloseContext(&context); } }
Result http_haxx(char *requrl, u8 *cert, u32 certsize, targeturlctx *first_targeturlctx) { Result ret=0; httpcContext context; u32 *linearaddr = NULL; Handle httpheap_sharedmem_handle=0; Handle ropvmem_sharedmem_handle=0; Handle httpc_sslc_handle = 0; u32 i; ret = httpcOpenContext(&context, HTTPC_METHOD_POST, requrl, 1); if(ret!=0)return ret; ret = httpcAddPostDataAscii(&context, "form_name", "form_value"); if(ret!=0) { httpcCloseContext(&context); return ret; } //Locate the physmem for the httpc sharedmem. With the current cmpblock, there can only be one POST struct that was ever written into sharedmem, with the name/value from above. printf("Searching for the httpc sharedmem in physmem...\n"); ret = locate_sharedmem_linearaddr(&linearaddr); if(ret!=0) { printf("Failed to locate the sharedmem in physmem.\n"); httpcCloseContext(&context); return ret; } printf("Writing the haxx to physmem...\n"); ret = writehax_sharedmem_physmem(linearaddr); if(ret!=0) { printf("Failed to setup the haxx.\n"); httpcCloseContext(&context); return ret; } printf("Triggering the haxx...\n"); ret = _httpcCloseContext(&context, &httpheap_sharedmem_handle, &ropvmem_sharedmem_handle, &httpc_sslc_handle); if(R_FAILED(ret)) { printf("httpcCloseContext returned 0x%08x.\n", (unsigned int)ret); return ret; } httpheap_sharedmem = (vu32*)mappableAlloc(httpheap_size); if(httpheap_sharedmem==NULL) { ret = -2; svcCloseHandle(httpheap_sharedmem_handle); svcCloseHandle(ropvmem_sharedmem_handle); svcCloseHandle(httpc_sslc_handle); return ret; } ropvmem_sharedmem = (vu32*)mappableAlloc(ropvmem_size); if(ropvmem_sharedmem==NULL) { ret = -3; mappableFree((void*)httpheap_sharedmem); svcCloseHandle(httpheap_sharedmem_handle); svcCloseHandle(ropvmem_sharedmem_handle); svcCloseHandle(httpc_sslc_handle); return ret; } if(R_FAILED(ret=svcMapMemoryBlock(httpheap_sharedmem_handle, (u32)httpheap_sharedmem, MEMPERM_READ | MEMPERM_WRITE, MEMPERM_READ | MEMPERM_WRITE))) { svcCloseHandle(httpheap_sharedmem_handle); mappableFree((void*)httpheap_sharedmem); httpheap_sharedmem = NULL; svcCloseHandle(ropvmem_sharedmem_handle); mappableFree((void*)ropvmem_sharedmem); ropvmem_sharedmem = NULL; svcCloseHandle(httpc_sslc_handle); printf("svcMapMemoryBlock with the httpheap sharedmem failed: 0x%08x.\n", (unsigned int)ret); return ret; } if(R_FAILED(ret=svcMapMemoryBlock(ropvmem_sharedmem_handle, (u32)ropvmem_sharedmem, MEMPERM_READ | MEMPERM_WRITE, MEMPERM_READ | MEMPERM_WRITE))) { svcUnmapMemoryBlock(httpheap_sharedmem_handle, (u32)httpheap_sharedmem); svcCloseHandle(httpheap_sharedmem_handle); mappableFree((void*)httpheap_sharedmem); httpheap_sharedmem = NULL; svcCloseHandle(ropvmem_sharedmem_handle); mappableFree((void*)ropvmem_sharedmem); ropvmem_sharedmem = NULL; svcCloseHandle(httpc_sslc_handle); printf("svcMapMemoryBlock with the ropvmem sharedmem failed: 0x%08x.\n", (unsigned int)ret); return ret; } printf("Finishing haxx setup with sysmodule memory...\n"); ret = setuphaxx_httpheap_sharedmem(first_targeturlctx); if(R_FAILED(ret)) { printf("Failed to finish haxx setup: 0x%08x.\n", (unsigned int)ret); } else { printf("Finalizing...\n"); } svcUnmapMemoryBlock(httpheap_sharedmem_handle, (u32)httpheap_sharedmem); svcCloseHandle(httpheap_sharedmem_handle); mappableFree((void*)httpheap_sharedmem); httpheap_sharedmem = NULL; svcUnmapMemoryBlock(ropvmem_sharedmem_handle, (u32)ropvmem_sharedmem); svcCloseHandle(ropvmem_sharedmem_handle); mappableFree((void*)ropvmem_sharedmem); ropvmem_sharedmem = NULL; if(R_FAILED(ret)) { svcCloseHandle(httpc_sslc_handle); return ret; } printf("Running setup with sslc...\n"); ret = setuphax_http_sslc(httpc_sslc_handle, cert, certsize); svcCloseHandle(httpc_sslc_handle);//Normally sslcExit should close this, but close it here too just in case. if(R_FAILED(ret)) { printf("Setup failed with sslc: 0x%08x.\n", (unsigned int)ret); return ret; } printf("Testing httpc with non-targeted URLs...\n"); for(i=0; i<2; i++) { ret = httpcOpenContext(&context, HTTPC_METHOD_POST, requrl, 1); if(R_FAILED(ret)) { printf("httpcOpenContext returned 0x%08x, i=%u.\n", (unsigned int)ret, (unsigned int)i); return ret; } ret = httpcAddRequestHeaderField(&context, "User-Agent", "ctr-httpwn/"VERSION); if(R_FAILED(ret)) { printf("httpcAddRequestHeaderField returned 0x%08x, i=%u.\n", (unsigned int)ret, (unsigned int)i); httpcCloseContext(&context); return ret; } ret = httpcAddPostDataAscii(&context, "form_name", "form_value"); if(R_FAILED(ret)) { printf("httpcAddPostDataAscii returned 0x%08x, i=%u.\n", (unsigned int)ret, (unsigned int)i); httpcCloseContext(&context); return ret; } ret = httpcCloseContext(&context); if(R_FAILED(ret)) { printf("httpcCloseContext returned 0x%08x, i=%u.\n", (unsigned int)ret, (unsigned int)i); return ret; } } return 0; }
int main() { const char build_time[] = __DATE__ " " __TIME__; dlCounter = 0; ret = 0; gfxInitDefault(); consoleInit(GFX_TOP, &topScreen); consoleInit(GFX_BOTTOM, &bottomScreen); consoleSelect(&topScreen); /*printf("%s by %s\n", APPTITLE, APPAUTHOR);*/ printf("Koopa Cruiser by jsa\n"); printf("Version: %s\n", VERSION); //printf("--dev build--\n"); printf("Modified: %s\n", __TIMESTAMP__); printf("Built: %s\n\n", build_time); printf("Press X to save the page\n"); printf("Press START to exit.\n"); printf("Press B to start the swkbd applet\n\n"); gfxFlushBuffers(); httpcInit(); //Change this to your own URL. url = "http://mabel.nonm.co.uk/woop/view.php"; printf("Loading %s\n\n",url); gfxFlushBuffers(); ret = httpcOpenContext(&context, url , 0); //printf("return from httpcOpenContext: %"PRId32"\n",ret); gfxFlushBuffers(); if(ret==0) { ret=http_download(&context); //printf("return from http_download: %"PRId32"\n",ret); gfxFlushBuffers(); httpcCloseContext(&context); } // Main loop while (aptMainLoop()) { gspWaitForVBlank(); hidScanInput(); // Your code goes here u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; // break in order to return to hbmenu if (kDown & KEY_X) { downloadfile(); } /*if (kDown & KEY_B) { printf("Launching swkbd.\n"); if(APT_PrepareToStartLibraryApplet(APPID_MIIVERSE_POSTING)) printf("Preparing to launch applet\n"); Result rc = APT_LaunchLibraryApplet(APPID_MIIVERSE_POSTING, 0, NULL, 0); if (rc) printf("APT_LaunchLibraryApplet: %08lX\n", rc); printf("this is probably broken!\n"); }*/ if(kDown & KEY_B) { printf("woah!\n"); swkbd_Init(); char buf[256]; strcpy(buf,"Hello world!"); } if(kDown & KEY_SELECT) { swkbd_GetStr(buf, 256); printf(buf); printf("\n"); } // Flush and swap framebuffers gfxFlushBuffers(); gfxSwapBuffers(); } // Exit services httpcExit(); gfxExit(); return 0; }
Result download_config(char *url, u8 *cert, u32 certsize, u8 *filebuffer, u32 dlsize, u32 *out_statuscode) { Result ret=0; u32 statuscode=0; httpcContext context; ret = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1); if(R_FAILED(ret)) { printf("httpcOpenContext returned 0x%08x.\n", (unsigned int)ret); return ret; } ret = httpcAddRequestHeaderField(&context, "User-Agent", "ctr-httpwn/"VERSION); if(R_FAILED(ret)) { printf("httpcAddRequestHeaderField returned 0x%08x.\n", (unsigned int)ret); httpcCloseContext(&context); return ret; } ret = httpcAddTrustedRootCA(&context, cert, certsize); if(R_FAILED(ret)) { printf("httpcAddTrustedRootCA returned 0x%08x.\n", (unsigned int)ret); httpcCloseContext(&context); return ret; } ret = httpcBeginRequest(&context); if(R_FAILED(ret)) { printf("httpcBeginRequest returned 0x%08x.\n", (unsigned int)ret); httpcCloseContext(&context); return ret; } ret = httpcGetResponseStatusCode(&context, &statuscode, 0); if(R_FAILED(ret)) { printf("httpcGetResponseStatusCode returned 0x%08x.\n", (unsigned int)ret); httpcCloseContext(&context); return ret; } if(out_statuscode)*out_statuscode = statuscode; if(statuscode==200 || statuscode==500) { ret = httpcDownloadData(&context, filebuffer, dlsize, NULL); if(ret!=0 && statuscode==200) { printf("httpcDownloadData returned 0x%08x.\n", (unsigned int)ret); httpcCloseContext(&context); return ret; } } ret = httpcCloseContext(&context); if(R_FAILED(ret)) { printf("httpcCloseContext returned 0x%08x.\n", (unsigned int)ret); return ret; } if(statuscode!=200) { printf("Invalid statuscode: %u.\n", (unsigned int)statuscode); return -5; } return 0; }
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; }
static int lua_downstring(lua_State *L){ int argc = lua_gettop(L); #ifndef SKIP_ERROR_HANDLING if (argc < 1 || argc > 4) return luaL_error(L, "wrong number of arguments"); #endif const char* url = luaL_checkstring(L,1); const char* headers = (argc >= 2) ? luaL_checkstring(L,2) : NULL; u8 method = (argc >= 3) ? luaL_checkinteger(L,3) : 0; const char* postdata = (argc >= 4) ? luaL_checkstring(L,4) : NULL; httpcContext context; HTTPC_RequestMethod useMethod = HTTPC_METHOD_GET; if(method <= 3 && method >= 1) useMethod = (HTTPC_RequestMethod)method; u32 statuscode=0; do { if (statuscode >= 301 && statuscode <= 308) { char newurl[4096]; httpcGetResponseHeader(&context, (char*)"Location", &newurl[0], 4096); url = &newurl[0]; httpcCloseContext(&context); } Result ret = httpcOpenContext(&context, useMethod, (char*)url , 0); // Lets just disable SSL verification instead of loading default certs. httpcSetSSLOpt(&context, SSLCOPT_DisableVerify); if(headers != NULL){ char *tokenheader = (char*)malloc(strlen(headers)+1); strcpy(tokenheader, headers); char *toker = tokenheader; char *headername = NULL; char *headervalue = NULL; do { headername = strtok(toker, ":"); if (headername == NULL) break; headervalue = strtok(NULL, "\n"); if (headervalue == NULL) break; if (headervalue[0] == ' ') headervalue++; httpcAddRequestHeaderField(&context, headername, headervalue); toker = NULL; } while (headername != NULL && headervalue != NULL); free(tokenheader); } if (useMethod == HTTPC_METHOD_POST && postdata != NULL) { httpcAddPostDataRaw(&context, (u32*)postdata, strlen(postdata)); } #ifndef SKIP_ERROR_HANDLING if(ret==0){ #endif httpcBeginRequest(&context); long int contentsize=0; // Crash on the += if u32. WTF? u32 readSize=0; httpcGetResponseStatusCode(&context, &statuscode, 0); if (statuscode == 200) { unsigned char *buffer = (unsigned char*)malloc(0x1000); do { ret = httpcDownloadData(&context, buffer+contentsize, 0x1000, &readSize); contentsize += readSize; if (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING) buffer = (unsigned char*)realloc(buffer, contentsize + 0x1000); } while (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING); buffer = (unsigned char*)realloc(buffer, contentsize + 1); buffer[contentsize] = 0; lua_pushlstring(L,(const char*)buffer,contentsize); free(buffer); } #ifndef SKIP_ERROR_HANDLING } #endif } while ((statuscode >= 301 && statuscode <= 303) || (statuscode >= 307 && statuscode <= 308)); #ifndef SKIP_ERROR_HANDLING if ((statuscode < 200 && statuscode > 226) && statuscode != 304) luaL_error(L, "error opening url"); #endif httpcCloseContext(&context); return 1; }
Result http_download_payload(char *url, u32 *payloadsize) { Result ret=0; u32 statuscode=0; u32 contentsize=0; httpcContext context; ret = httpcOpenContext(&context, url, 1); if(ret!=0)return ret; ret = httpcAddRequestHeaderField(&context, "User-Agent", "hblauncher_loader/"VERSION); if(ret!=0) { httpcCloseContext(&context); return ret; } ret = httpcBeginRequest(&context); if(ret!=0) { httpcCloseContext(&context); return ret; } ret = httpcGetResponseStatusCode(&context, &statuscode, 0); if(ret!=0) { httpcCloseContext(&context); return ret; } if(statuscode!=200) { printf("Error: server returned HTTP statuscode %u.\n", (unsigned int)statuscode); httpcCloseContext(&context); return -2; } ret=httpcGetDownloadSizeState(&context, NULL, &contentsize); if(ret!=0) { httpcCloseContext(&context); return ret; } if(contentsize==0 || contentsize>PAYLOAD_TEXTMAXSIZE) { printf("Invalid HTTP content-size: 0x%08x.\n", (unsigned int)contentsize); ret = -3; httpcCloseContext(&context); return ret; } ret = httpcDownloadData(&context, filebuffer, contentsize, NULL); if(ret!=0) { httpcCloseContext(&context); return ret; } httpcCloseContext(&context); *payloadsize = contentsize; return 0; }
static int lua_sendmail(lua_State *L){ //BETA func int argc = lua_gettop(L); #ifndef SKIP_ERROR_HANDLING if (argc != 3) return luaL_error(L, "wrong number of arguments"); #endif char* to = (char*)luaL_checkstring(L,1); char* subj = (char*)luaL_checkstring(L,2); char* mex = (char*)luaL_checkstring(L,3); int req_size = 70; int nss = SpaceCounter(subj); int nsm = SpaceCounter(mex); req_size = req_size + nss * 2 + nsm * 2 + strlen(subj) + strlen(mex) + strlen(to); char* url = (char*)malloc(req_size); strcpy(url,"http://rinnegatamante.netsons.org/tmp_mail_lpp_beta.php?t="); strcat(url,to); strcat(url,"&s="); char* subj_p = subj; char* url_p = &url[strlen(url)]; while (*subj_p){ if (subj_p[0] == 0x20){ url_p[0] = '%'; url_p++; url_p[0] = '2'; url_p++; url_p[0] = '0'; }else url_p[0] = subj_p[0]; url_p++; subj_p++; } strcat(url,"&b="); char* mex_p = mex; url_p = &url[strlen(url)]; while (*mex_p){ if (mex_p[0] == 0x20){ url_p[0] = '%'; url_p++; url_p[0] = '2'; url_p++; url_p[0] = '0'; }else url_p[0] = mex_p[0]; url_p++; mex_p++; } url_p[0] = 0; httpcContext context; Result ret = httpcOpenContext(&context, (char*)url , 0); #ifndef SKIP_ERROR_HANDLING if(ret==0){ #endif httpcBeginRequest(&context); HTTPC_RequestStatus loading; httpcGetRequestState(&context, &loading); while (loading == HTTPC_STATUS_REQUEST_IN_PROGRESS){ httpcGetRequestState(&context, &loading); } u32 statuscode=0; u32 contentsize=0; httpcGetResponseStatusCode(&context, &statuscode, 0); if (statuscode != 200) luaL_error(L, "request error"); httpcGetDownloadSizeState(&context, NULL, &contentsize); u8 response; httpcDownloadData(&context, &response, contentsize, NULL); lua_pushboolean(L,response); free(url); #ifndef SKIP_ERROR_HANDLING }else luaL_error(L, "error opening url"); #endif httpcCloseContext(&context); return 1; }
int main() { httpcInit(); gfxInitDefault(); gfxSet3D(false); Result ret = filesystemInit(); PrintConsole topConsole, bttmConsole; consoleInit(GFX_TOP, &topConsole); consoleInit(GFX_BOTTOM, &bttmConsole); consoleSelect(&topConsole); consoleClear(); state_t current_state = STATE_NONE; state_t next_state = STATE_INITIAL; static char top_text[2048]; top_text[0] = '\0'; int selected_slot = 0; int firmware_version[firmware_length] = {0, 0, 9, 0, 0}; int firmware_selected_value = 0; static char payload_name[256]; u8* payload_buf = NULL; u32 payload_size = 0; while (aptMainLoop()) { hidScanInput(); if(hidKeysDown() & KEY_START)break; // transition function if(next_state != current_state) { switch(next_state) { case STATE_INITIAL: strcat(top_text, " Welcome to the oot3dhax installer! Please proceedwith caution, as you might lose data if you don't.You may press START at any time to return to menu.\n Press A to continue.\n\n"); break; case STATE_SELECT_SLOT: strcat(top_text, " Please select the savegame slot oot3dhax will be\ninstalled to. D-Pad to select, A to continue.\n"); break; case STATE_SELECT_FIRMWARE: strcat(top_text, "\n\n\n 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"); break; case STATE_DOWNLOAD_PAYLOAD: getPayloadName(firmware_version, payload_name); sprintf(top_text, "%s\n\n\n Downloading payload... %s\n", top_text, payload_name); break; case STATE_INSTALL_PAYLOAD: strcat(top_text, " Installing payload...\n"); break; case STATE_INSTALLED_PAYLOAD: strcat(top_text, " Done! oot3dhax was successfully installed."); break; case STATE_ERROR: strcat(top_text, " Looks like something went wrong. :(\n"); break; default: break; } current_state = next_state; } consoleSelect(&topConsole); printf("\x1b[0;%dHoot3dhax installer", (50 - 17) / 2); printf("\x1b[1;%dHby smea, yellows8, phase, and meladroit\n\n\n", (50 - 38) / 2); printf(top_text); // state function switch(current_state) { case STATE_INITIAL: if(hidKeysDown() & KEY_A)next_state = STATE_SELECT_SLOT; 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 >= firmware_length) firmware_selected_value = firmware_length - 1; if(hidKeysDown() & KEY_UP)firmware_version[firmware_selected_value]++; if(hidKeysDown() & KEY_DOWN)firmware_version[firmware_selected_value]--; if(firmware_version[firmware_selected_value] < 0) firmware_version[firmware_selected_value] = 0; if(firmware_version[firmware_selected_value] >= firmware_num_values[firmware_selected_value]) firmware_version[firmware_selected_value] = firmware_num_values[firmware_selected_value] - 1; if(hidKeysDown() & KEY_A)next_state = STATE_DOWNLOAD_PAYLOAD; int offset = 28 + firmware_format_offsets[firmware_selected_value]; printf((firmware_version[firmware_selected_value] < firmware_num_values[firmware_selected_value] - 1) ? "%*s^%*s" : "%*s-%*s", offset, " ", 50 - offset - 1, " "); printf(" Selected firmware: " "%s %s-%s-%s %s" "\n", firmware_labels[0][firmware_version[0]], firmware_labels[1][firmware_version[1]], firmware_labels[2][firmware_version[2]], firmware_labels[3][firmware_version[3]], firmware_labels[4][firmware_version[4]]); printf((firmware_version[firmware_selected_value] > 0) ? "%*sv%*s" : "%*s-%*s", offset, " ", 50 - offset - 1, " "); } break; case STATE_DOWNLOAD_PAYLOAD: { httpcContext context; static char url[512]; sprintf(url, "http://smealum.github.io/ninjhax2/Pvl9iD2Im5/otherapp/%s.bin", payload_name); Result ret = httpcOpenContext(&context, url, 0); if(ret) { sprintf(status, "Failed to open http context\n Error code: %08X", (unsigned int)ret); next_state = STATE_ERROR; break; } ret = http_download(&context, &payload_buf, &payload_size); if(ret) { sprintf(status, "Failed to download payload\n Error code: %08X", (unsigned int)ret); next_state = STATE_ERROR; break; } next_state = STATE_INSTALL_PAYLOAD; } break; case STATE_INSTALL_PAYLOAD: { static char filename[128]; sprintf(filename, "save0x.bin.%s", firmware_labels[4][firmware_version[4]]); read_payload(filename, save_buffer); sprintf(filename, "/save0%d.bin", selected_slot); Result ret = write_savedata(filename, save_buffer, save_size); if(ret) { sprintf(status, "Failed to install %s.\n Error code: %08X", filename, (unsigned int)ret); next_state = STATE_ERROR; break; } } { Result ret = write_savedata("/payload.bin", payload_buf, payload_size); if(ret) { sprintf(status, "Failed to install payload\n Error code : %08X", (unsigned int)ret); next_state = STATE_ERROR; break; } next_state = STATE_INSTALLED_PAYLOAD; } break; case STATE_INSTALLED_PAYLOAD: next_state = STATE_NONE; break; default: break; } consoleSelect(&bttmConsole); printf("\x1b[0;0H \n Found a bug? Go to\n https://github.com/meladroit/oot3dhax_installer/ \n\n Current status:\n %s\n", status); gspWaitForVBlank(); } filesystemExit(); gfxExit(); httpcExit(); return 0; }
Result InitializeClockOffset() { /* Compares the system clock with current UTC time from timeapi.com */ /* ESSENTIAL for correct OTP generation, unless system clock is UTC */ /* Returns difference, in seconds. */ /* Add the result of this function to the 3DS time to get UTC. */ if (IsValidTimeOffset(g_SystemClockUtcOffset)) return true; Result ret = 0; unsigned long statusCode = 0; unsigned long contentSize = 0; unsigned char *buffer = NULL; httpcContext context; // NOTE: Uninitialized memory httpcInit(0); char * url = "http://old-labs.muffinti.me/atoolyoucanputonthewall.php"; /* put this line into a blank PHP file: <?php date_default_timezone_set("UTC"); echo time(); exit; ?> */ /* URL returning current time in UTC */ if (ret) { ret = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1); } if (ret) { ret = httpcBeginRequest(&context); } if (ret) { ret = httpcGetResponseStatusCode(&context, &statusCode); if (ret && statusCode != 200) { printf("WARNING: HTTP status code returned was %d\n", statusCode); } } if (ret) { ret = httpcGetDownloadSizeState(&context, NULL, &contentSize); } if (ret) { if(contentSize+1 < contentSize) { ret = R_TINYTOT_OVERFLOW; // overflow -- do not allow } } if (ret) { buffer = (unsigned char*)malloc(contentSize+1); if(buffer == NULL) { ret = R_TINYTOT_OUTOFMEMORY; } } if (ret) { memset(buffer, 0, contentSize+1); // zero that last byte also ret = httpcDownloadData(&context, buffer, contentSize, NULL); } if (ret) { time_t utcTime = (time_t)atol(buffer); time_t systemTime = time(NULL); signed long timeDifference = systemTime - utcTime; /* time(NULL) + timeDifference = UTC */ g_SystemClockUtcOffset = timeDifference; } if (NULL != buffer) { free(buffer); } return ret; }
Result DownloadTitle(std::string titleId, std::string encTitleKey, std::string titleName, std::string region) { // Convert the titleid to a u64 for later use char* nTitleId = parse_string(titleId); u64 uTitleId = u8_to_u64((u8*)nTitleId, BIG_ENDIAN); free (nTitleId); // Wait for wifi to be available u32 wifi = 0; Result ret = 0; Result res = 0; while(R_SUCCEEDED(ret = ACU_GetWifiStatus(&wifi)) && wifi == 0) { hidScanInput(); if (hidKeysDown() & KEY_B) { ret = -1; break; } } if (R_FAILED(ret)) { printf("Unable to access internet.\n"); return ret; } std::string outputDir = "/CIAngel"; if (titleName.length() == 0) { titleName = titleId; } // Include region in filename if (region.length() > 0) { titleName = titleName + " (" + region + ")"; } std::string mode_text; if(config.GetMode() == CConfig::Mode::DOWNLOAD_CIA) { mode_text = "create"; } else if(config.GetMode() == CConfig::Mode::INSTALL_CIA) { mode_text = "install"; } printf("Starting - %s\n", titleName.c_str()); // If in install mode, download/install the SEED entry if (config.GetMode() == CConfig::Mode::INSTALL_CIA) { // Download and install the SEEDDB entry if install mode // Code based on code from FBI: https://github.com/Steveice10/FBI/blob/master/source/core/util.c#L254 // Copyright (C) 2015 Steveice10 u8 seed[16]; static const char* regionStrings[] = {"JP", "US", "GB", "GB", "HK", "KR", "TW"}; u8 region = CFG_REGION_USA; CFGU_GetSystemLanguage(®ion); if(region <= CFG_REGION_TWN) { char url[128]; snprintf(url, 128, SEED_URL "0x%016llX/ext_key?country=%s", uTitleId, regionStrings[region]); httpcContext context; if(R_SUCCEEDED(res = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1))) { httpcSetSSLOpt(&context, SSLCOPT_DisableVerify); u32 responseCode = 0; if(R_SUCCEEDED(res = httpcBeginRequest(&context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(&context, &responseCode, 0))) { if(responseCode == 200) { u32 pos = 0; u32 bytesRead = 0; while(pos < sizeof(seed) && (R_SUCCEEDED(res = httpcDownloadData(&context, &seed[pos], sizeof(seed) - pos, &bytesRead)) || (u32)res == HTTPC_RESULTCODE_DOWNLOADPENDING)) { pos += bytesRead; } } else { res = -1; } } httpcCloseContext(&context); } if (R_SUCCEEDED(res)) { res = InstallSeed(uTitleId, seed); if (R_FAILED(res)) { printf("Error installing SEEDDB entry: 0x%lx\n", res); } } } } // Make sure the CIA doesn't already exist std::string cp = outputDir + "/" + titleName + ".cia"; if (config.GetMode() == CConfig::Mode::DOWNLOAD_CIA && FileExists(cp.c_str())) { printf("%s already exists.\n", cp.c_str()); return 0; } std::ofstream ofs; FILE *oh = fopen((outputDir + "/tmp/tmd").c_str(), "wb"); if (!oh) { printf("Error opening %s/tmp/tmd\n", outputDir.c_str()); return -1; } res = DownloadFile((NUS_URL + titleId + "/tmd").c_str(), oh, false); fclose(oh); if (res != 0) { printf("Could not download TMD. Internet/Title ID is OK?\n"); return res; } // Read version std::ifstream tmdfs; tmdfs.open(outputDir + "/tmp/tmd", std::ofstream::out | std::ofstream::in | std::ofstream::binary); char titleVersion[2]; tmdfs.seekg(top+0x9C, std::ios::beg); tmdfs.read(titleVersion, 0x2); tmdfs.close(); CreateTicket(titleId, encTitleKey, titleVersion, outputDir + "/tmp/ticket"); printf("Now %s the CIA...\n", mode_text.c_str()); res = ProcessCIA(outputDir + "/tmp", titleName); if (res != 0) { printf("Could not %s the CIA.\n", mode_text.c_str()); return res; } if (config.GetMode() == CConfig::Mode::DOWNLOAD_CIA) { rename((outputDir + "/tmp/" + titleName + ".cia").c_str(), (outputDir + "/" + titleName + ".cia").c_str()); } printf(" DONE!\n"); return res; }
static int lua_download(lua_State *L){ int argc = lua_gettop(L); #ifndef SKIP_ERROR_HANDLING if (argc < 2 || argc > 5) return luaL_error(L, "wrong number of arguments"); #endif const char* url = luaL_checkstring(L,1); const char* file = luaL_checkstring(L,2); const char* headers = (argc >= 3) ? luaL_checkstring(L,3) : NULL; u8 method = (argc >= 4) ? luaL_checkinteger(L,4) : 0; const char* postdata = (argc >= 5) ? luaL_checkstring(L,5) : NULL; httpcContext context; u32 statuscode=0; HTTPC_RequestMethod useMethod = HTTPC_METHOD_GET; if(method <= 3 && method >= 1) useMethod = (HTTPC_RequestMethod)method; do { if (statuscode >= 301 && statuscode <= 308) { char newurl[4096]; httpcGetResponseHeader(&context, (char*)"Location", &newurl[0], 4096); url = &newurl[0]; httpcCloseContext(&context); } Result ret = httpcOpenContext(&context, useMethod, (char*)url, 0); // Just disable SSL verification instead of loading default certs. httpcSetSSLOpt(&context, SSLCOPT_DisableVerify); if(headers != NULL){ char *tokenheader = (char*)malloc(strlen(headers)+1); strcpy(tokenheader, headers); char *toker = tokenheader; char *headername = NULL; char *headervalue = NULL; do { headername = strtok(toker, ":"); if (headername == NULL) break; headervalue = strtok(NULL, "\n"); if (headervalue == NULL) break; if (headervalue[0] == ' ') headervalue++; httpcAddRequestHeaderField(&context, headername, headervalue); toker = NULL; } while (headername != NULL && headervalue != NULL); free(tokenheader); } if (useMethod == HTTPC_METHOD_POST && postdata != NULL) { httpcAddPostDataRaw(&context, (u32*)postdata, strlen(postdata)); } #ifndef SKIP_ERROR_HANDLING if(ret==0){ #endif httpcBeginRequest(&context); u32 contentsize=0; httpcGetResponseStatusCode(&context, &statuscode, 0); if (statuscode == 200){ u32 readSize = 0; long int bytesWritten = 0; u8* buf = (u8*)malloc(0x1000); memset(buf, 0, 0x1000); Handle fileHandle; FS_Archive sdmcArchive=(FS_Archive){ARCHIVE_SDMC, (FS_Path){PATH_EMPTY, 1, (u8*)""}}; FS_Path filePath=fsMakePath(PATH_ASCII, file); FSUSER_OpenFileDirectly( &fileHandle, sdmcArchive, filePath, FS_OPEN_CREATE|FS_OPEN_WRITE, 0x00000000); do { ret = httpcDownloadData(&context, buf, 0x1000, &readSize); FSFILE_Write(fileHandle, NULL, bytesWritten, buf, readSize, 0x10001); bytesWritten += readSize; } while (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING); FSFILE_Close(fileHandle); svcCloseHandle(fileHandle); free(buf); } #ifndef SKIP_ERROR_HANDLING } #endif } while ((statuscode >= 301 && statuscode <= 303) || (statuscode >= 307 && statuscode <= 308)); #ifndef SKIP_ERROR_HANDLING if ((statuscode < 200 && statuscode > 226) && statuscode != 304) luaL_error(L, "error opening url"); #endif httpcCloseContext(&context); lua_pushinteger(L, statuscode); return 1; }