int plat_mem_set_exec(void *ptr, size_t size) { #ifdef _WIN32 int ret = VirtualProtect(ptr,size,PAGE_EXECUTE_READWRITE,0); if (ret == 0 && log_cb) log_cb(RETRO_LOG_ERROR, "mprotect(%p, %zd) failed: %d\n", ptr, size, 0); #elif defined(_3DS) int ret = -1; if (ctr_svchack_successful) { unsigned int currentHandle; svcDuplicateHandle(¤tHandle, 0xFFFF8001); ret = svcControlProcessMemory(currentHandle, ptr, 0x0, size, MEMOP_PROT, 0b111); svcCloseHandle(currentHandle); ctr_flush_invalidate_cache(); } else { if (log_cb) log_cb(RETRO_LOG_ERROR, "plat_mem_set_exec called with no svcControlProcessMemory access\n"); exit(1); } #else int ret = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC); if (ret != 0 && log_cb) log_cb(RETRO_LOG_ERROR, "mprotect(%p, %zd) failed: %d\n", ptr, size, errno); #endif return ret; }
void plat_munmap(void *ptr, size_t size) { if (ctr_svchack_successful) { pico_mmap_t* pico_mmap; for (pico_mmap = pico_mmaps; pico_mmap->requested_map; pico_mmap++) { if ((pico_mmap->requested_map == (unsigned int)ptr)) { unsigned int ptr_aligned; unsigned int currentHandle; size = (size + 0xFFF) & ~0xFFF; ptr_aligned = (((unsigned int)pico_mmap->buffer) + 0xFFF) & ~0xFFF; svcDuplicateHandle(¤tHandle, 0xFFFF8001); svcControlProcessMemory(currentHandle, (void*)pico_mmap->requested_map, (void*)ptr_aligned, size, MEMOP_UNMAP, 0b011); svcCloseHandle(currentHandle); free(pico_mmap->buffer); pico_mmap->buffer = NULL; return; } } } free(ptr); }
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); }
void *plat_mremap(void *ptr, size_t oldsize, size_t newsize) { if (ctr_svchack_successful) { pico_mmap_t* pico_mmap; for (pico_mmap = pico_mmaps; pico_mmap->requested_map; pico_mmap++) { if ((pico_mmap->requested_map == (unsigned int)ptr)) { unsigned int ptr_aligned; unsigned int currentHandle; void* tmp; oldsize = (oldsize + 0xFFF) & ~0xFFF; newsize = (newsize + 0xFFF) & ~0xFFF; ptr_aligned = (((unsigned int)pico_mmap->buffer) + 0xFFF) & ~0xFFF; svcDuplicateHandle(¤tHandle, 0xFFFF8001); svcControlProcessMemory(currentHandle, pico_mmap->requested_map, ptr_aligned, oldsize, MEMOP_UNMAP, 0b011); tmp = realloc(pico_mmap->buffer, newsize + 0x1000); if(!tmp) return NULL; pico_mmap->buffer = tmp; ptr_aligned = (((unsigned int)pico_mmap->buffer) + 0xFFF) & ~0xFFF; svcControlProcessMemory(currentHandle, pico_mmap->requested_map, ptr_aligned, newsize, MEMOP_MAP, 0x3); svcCloseHandle(currentHandle); return ptr; } } } return realloc(ptr, newsize); }
void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed) { (void)is_fixed; if (ctr_svchack_successful) { pico_mmap_t* pico_mmap; for (pico_mmap = pico_mmaps; pico_mmap->requested_map; pico_mmap++) { if ((pico_mmap->requested_map == addr)) { unsigned int ptr_aligned, tmp; unsigned int currentHandle; unsigned int perm = 0b011; if (need_exec) perm = 0b111; size = (size + 0xFFF) & ~0xFFF; pico_mmap->buffer = malloc(size + 0x1000); ptr_aligned = (((unsigned int)pico_mmap->buffer) + 0xFFF) & ~0xFFF; svcDuplicateHandle(¤tHandle, 0xFFFF8001); if(svcControlProcessMemory(currentHandle, pico_mmap->requested_map, ptr_aligned, size, MEMOP_MAP, perm) < 0) { if (log_cb) log_cb(RETRO_LOG_ERROR, "could not map memory @0x%08X\n", pico_mmap->requested_map); exit(1); } svcCloseHandle(currentHandle); return (void*)pico_mmap->requested_map; } } } return malloc(size); }
int main(int argc, char **argv) { Result ret = 0; u32 pos; Handle kproc_handledup=0; // Initialize services gfxInitDefault(); consoleInit(GFX_BOTTOM, NULL); printf("hblauncher_loader %s by yellows8.\n", VERSION); ret = svcDuplicateHandle(&kproc_handledup, 0xffff8001); if(ret!=0)printf("svcDuplicateHandle() with the current proc-handle failed: 0x%08x.\n", (unsigned int)ret); if(ret==0) { for(pos=0; pos<PAYLOAD_TEXTMAXSIZE; pos+=0x1000) { ret = svcControlProcessMemory(kproc_handledup, (u32)&PAYLOAD_TEXTADDR[pos >> 2], 0x0, 0x1000, MEMOP_PROT, MEMPERM_READ | MEMPERM_WRITE | MEMPERM_EXECUTE); if(ret!=0) { printf("svcControlProcessMemory with pos=0x%x failed: 0x%08x.\n", (unsigned int)pos, (unsigned int)ret); break; } } } ret = httpcInit(); if(ret!=0) { printf("Failed to initialize HTTPC: 0x%08x.\n", (unsigned int)ret); if(ret==0xd8e06406) { printf("The HTTPC service is inaccessible.\n"); } } if(ret==0) { filebuffer_maxsize = PAYLOAD_TEXTMAXSIZE; filebuffer = (u8*)malloc(filebuffer_maxsize); if(filebuffer==NULL) { printf("Failed to allocate memory.\n"); ret = -1; } else { memset(filebuffer, 0, filebuffer_maxsize); } } ret = load_hblauncher(); free(filebuffer); httpcExit(); if(ret!=0)printf("An error occured, please report this to here if it persists(or comment on an already existing issue if needed), with an image of your 3DS system: https://github.com/yellows8/hblauncher_loader/issues\n"); printf("Press the START button to exit.\n"); // Main loop while (aptMainLoop()) { gspWaitForVBlank(); hidScanInput(); u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; // break in order to return to hbmenu } // Exit services gfxExit(); return 0; }