int main() { initSrv(); aptInit(APPID_APPLICATION); gspGpuInit(); hidInit(NULL); aptSetupEventHandler(); APP_STATUS status; while((status=aptGetStatus())!=APP_EXITING) { if(status==APP_RUNNING) { u32 PAD=hidSharedMem[7]; u32 regData=PAD|0x01000000; GSPGPU_WriteHWRegs(NULL, 0x202A04, (u32*)®Data, 4); renderEffect(); swapBuffers(); copyBuffer(); } svc_sleepThread(16666666); } hidExit(); gspGpuExit(); aptExit(); svc_exitProcess(); return 0; }
void _main(paramblk_t* p) { gspHeap = (u8*)p->linear_heap; gspHeap_size = p->linear_size; initSrv(); srv_RegisterClient(NULL); gspGpuInit(); resetConsole(); print_str("hello\n"); print_str("_firm_appmemalloc "); print_hex((u32)_firm_appmemalloc); print_str("\n"); print_str("code address "); print_hex((u32)p->code_data); print_str("\n"); print_str("code size "); print_hex(p->code_size); print_str("\n"); setupStub((u8*)p->code_data); Result ret = apply_map(&p->map, (u8*)p->code_data, HANS_LOADER_SIZE); print_str("applied map "); print_hex(ret); print_str("\n"); ret = invalidateIcache(p->nssHandle); ret = runStub(p->nssHandle, &p->map, (u8*)p->code_data); print_hex(ret); while(1); gspGpuExit(); }
void runTitle(u8 mediatype, u32* argbuf, u32 argbuflength, u32 tid_low, u32 tid_high) { initSrv(); gspGpuInit(); // free extra data pages if any freeDataPages(0x14000000); freeDataPages(0x30000000); // allocate gsp heap svc_controlMemory((u32*)&gspHeap, 0x0, 0x0, 0x02000000, 0x10003, 0x3); // put new argv buffer on stack u32 argbuffer[0x200]; u32 argbuffer_length = argbuflength; memcpy(argbuffer, argbuf, argbuflength); argbuffer[0]++; memorymap_t* mmap = getMmapArgbuf(argbuffer, argbuffer_length); // grab fs:USER handle Handle fsuserHandle = 0x0; int i; for(i=0; i<_serviceList.num; i++)if(!strcmp(_serviceList.services[i].name, "fs:USER"))fsuserHandle=_serviceList.services[i].handle; if(!fsuserHandle)*(vu32*)0xCAFE0001=0; getProcessMap(fsuserHandle, mediatype, tid_low, tid_high, mmap, (u32*)gspHeap); argbuffer_length = (u32)((void*)mmap - (void*)argbuffer) + size_memmap(*mmap); gspGpuExit(); exitSrv(); // free heap (has to be the very last thing before jumping to app as contains bss) u32 out; svc_controlMemory(&out, (u32)_heap_base, 0x0, _heap_size, MEMOP_FREE, 0x0); _changeProcess(-2, argbuffer, argbuffer_length); }
void run3dsx(Handle executable, u32* argbuf) { initSrv(); gspGpuInit(); // free extra data pages if any freeDataPages(0x14000000); freeDataPages(0x30000000); // reset menu ropbin (in case of a crash) { u32 _argbuf = 0; svc_controlMemory((u32*)&gspHeap, 0x0, 0x0, 0x01000000, 0x10003, 0x3); patchMenuRop(1, &_argbuf, 4); svc_controlMemory((u32*)&gspHeap, (u32)gspHeap, 0x0, 0x01000000, MEMOP_FREE, 0x0); } // duplicate service list on the stack // also add hid:SPVR as hid:USER if appropriate // (for backwards compat as old homebrew only supports hid:USER) u8 serviceBuffer[0x4+0xC*(_serviceList.num + 1)]; service_list_t* serviceList = (service_list_t*)serviceBuffer; serviceList->num = _serviceList.num; int i; for(i=0; i<_serviceList.num; i++) { memcpy(serviceList->services[i].name, _serviceList.services[i].name, 8); svc_duplicateHandle(&serviceList->services[i].handle, _serviceList.services[i].handle); } // handle hid:USER missing case { Handle hidUSER = 0; if(srv_getServiceHandle(NULL, &hidUSER, "hid:USER") && !srv_getServiceHandle(NULL, &hidUSER, "hid:SPVR")) { memcpy(serviceList->services[serviceList->num].name, "hid:USER", 8); serviceList->services[serviceList->num].handle = hidUSER; serviceList->num++; }else svc_closeHandle(hidUSER); } vu32* targetProcessIndex = &_targetProcessIndex; if(*targetProcessIndex == -2) { // create local copy of process map u32 _customProcessBuffer[0x40]; memorymap_t* const _customProcessMap = (memorymap_t*)_customProcessBuffer; memcpy(_customProcessBuffer, customProcessBuffer, sizeof(_customProcessBuffer)); // adjust it given the information we now have such as text size, data location and size... MemInfo minfo; PageInfo pinfo; // get .text info Result ret = svc_queryMemory(&minfo, &pinfo, 0x00100000); _customProcessMap->header.text_end = minfo.size + 0x00100000; // get rodata info ret = svc_queryMemory(&minfo, &pinfo, _customProcessMap->header.text_end); _customProcessMap->header.data_address = minfo.size + _customProcessMap->header.text_end; // get data info ret = svc_queryMemory(&minfo, &pinfo, _customProcessMap->header.data_address); _customProcessMap->header.data_size = minfo.size; // setup 3dsx with custom local map setup3dsx(executable, (memorymap_t*)_customProcessMap, serviceList, argbuf); }else setup3dsx(executable, (memorymap_t*)app_maps[*targetProcessIndex], serviceList, argbuf); FSFILE_Close(executable); gspGpuExit(); exitSrv(); // grab ns:s handle Handle nssHandle = 0x0; for(i=0; i<_serviceList.num; i++)if(!strcmp(_serviceList.services[i].name, "ns:s"))nssHandle=_serviceList.services[i].handle; if(!nssHandle)*(vu32*)0xCAFE0001=0; // use ns:s to launch/kill process and invalidate icache in the process // Result ret = NSS_LaunchTitle(&nssHandle, 0x0004013000003702LL, 0x1); Result ret = NSS_LaunchTitle(&nssHandle, 0x0004013000002A02LL, 0x1); if(ret)*(u32*)0xCAFE0002=ret; svc_sleepThread(100*1000*1000); // ret = NSS_TerminateProcessTID(&nssHandle, 0x0004013000003702LL, 100*1000*1000); ret = NSS_TerminateProcessTID(&nssHandle, 0x0004013000002A02LL, 100*1000*1000); if(ret)*(u32*)0xCAFE0003=ret; // invalidate_icache(); // free heap (has to be the very last thing before jumping to app as contains bss) u32 out; svc_controlMemory(&out, (u32)_heap_base, 0x0, _heap_size, MEMOP_FREE, 0x0); start_execution(); }