static bool ndspFindAndLoadComponent(void) { Result rc; Handle rsrc; void* bin; componentProgMask = 0xFF; componentDataMask = 0xFF; // Try loading the DSP component from the filesystem do { static const char dsp_filename[] = "/3ds/dspfirm.cdc"; FS_Archive arch = { ARCHIVE_SDMC, { PATH_EMPTY, 1, (u8*)"" }, 0 }; FS_Path path = { PATH_ASCII, sizeof(dsp_filename), (u8*)dsp_filename }; rc = FSUSER_OpenFileDirectly(&rsrc, arch, path, FS_OPEN_READ, 0); if (R_FAILED(rc)) break; u64 size = 0; rc = FSFILE_GetSize(rsrc, &size); if (R_FAILED(rc)) { FSFILE_Close(rsrc); break; } bin = malloc(size); if (!bin) { FSFILE_Close(rsrc); break; } u32 dummy = 0; rc = FSFILE_Read(rsrc, &dummy, 0, bin, size); FSFILE_Close(rsrc); if (R_FAILED(rc)) { free(bin); return false; } componentBin = bin; componentSize = size; componentFree = true; return true; } while (0); // Try loading the DSP component from hb:ndsp rsrc = envGetHandle("hb:ndsp"); if (rsrc) do { extern u32 fake_heap_end; u32 mapAddr = (fake_heap_end+0xFFF) &~ 0xFFF; rc = svcMapMemoryBlock(rsrc, mapAddr, 0x3, 0x3); if (R_FAILED(rc)) break; componentSize = *(u32*)(mapAddr + 0x104); bin = malloc(componentSize); if (bin) memcpy(bin, (void*)mapAddr, componentSize); svcUnmapMemoryBlock(rsrc, mapAddr); if (!bin) break; componentBin = bin; componentFree = true; return true; } while (0); return false; }
Result hidInit(void) { u8 val=0; Result ret=0; if (AtomicPostIncrement(&hidRefCount)) return 0; // Request service. ret = srvGetServiceHandle(&hidHandle, "hid:USER"); if (R_FAILED(ret)) ret = srvGetServiceHandle(&hidHandle, "hid:SPVR"); if (R_FAILED(ret)) goto cleanup0; // Get sharedmem handle. if(R_FAILED(ret=HIDUSER_GetHandles(&hidMemHandle, &hidEvents[HIDEVENT_PAD0], &hidEvents[HIDEVENT_PAD1], &hidEvents[HIDEVENT_Accel], &hidEvents[HIDEVENT_Gyro], &hidEvents[HIDEVENT_DebugPad]))) goto cleanup1; // Map HID shared memory. hidSharedMem=(vu32*)mappableAlloc(0x2b0); if(!hidSharedMem) { ret = -1; goto cleanup1; } if(R_FAILED(ret=svcMapMemoryBlock(hidMemHandle, (u32)hidSharedMem, MEMPERM_READ, 0x10000000)))goto cleanup2; APT_CheckNew3DS(&val); if(val) { ret = irrstInit(); } // Reset internal state. kOld = kHeld = kDown = kUp = 0; return ret; cleanup2: svcCloseHandle(hidMemHandle); if(hidSharedMem != NULL) { mappableFree((void*) hidSharedMem); hidSharedMem = NULL; } cleanup1: svcCloseHandle(hidHandle); cleanup0: AtomicDecrement(&hidRefCount); return ret; }
void gfxInit() { gspInit(); gfxSharedMemory=(u8*)0x10002000; GSPGPU_AcquireRight(NULL, 0x0); //setup our gsp shared mem section svcCreateEvent(&gspEvent, 0x0); GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &gfxThreadID); svcMapMemoryBlock(gspSharedMemHandle, (u32)gfxSharedMemory, 0x3, 0x10000000); // default gspHeap configuration : // topleft1 0x00000000-0x00046500 // topleft2 0x00046500-0x0008CA00 // bottom1 0x0008CA00-0x000C4E00 // bottom2 0x000C4E00-0x000FD200 // if 3d enabled : // topright1 0x000FD200-0x00143700 // topright2 0x00143700-0x00189C00 gfxTopLeftFramebuffers[0]=linearAlloc(0x46500); gfxTopLeftFramebuffers[1]=linearAlloc(0x46500); gfxBottomFramebuffers[0]=linearAlloc(0x38400); gfxBottomFramebuffers[1]=linearAlloc(0x38400); gfxTopRightFramebuffers[0]=linearAlloc(0x46500); gfxTopRightFramebuffers[1]=linearAlloc(0x46500); enable3d=false; //initialize framebuffer info structures gfxSetFramebufferInfo(GFX_TOP, 0); gfxSetFramebufferInfo(GFX_BOTTOM, 0); //GSP shared mem : 0x2779F000 gxCmdBuf=(u32*)(gfxSharedMemory+0x800+gfxThreadID*0x200); currentBuffer[0]=0; currentBuffer[1]=0; // Initialize event handler and wait for VBlank gspInitEventHandler(gspEvent, (vu8*)gfxSharedMemory, gfxThreadID); gspWaitForVBlank(); GSPGPU_SetLcdForceBlack(NULL, 0x0); }
Result fontEnsureMapped(void) { if (g_sharedFont) return 0; Result res = 0; Handle hSharedFont = 0; res = APT_GetSharedFont(&hSharedFont, &sharedFontAddr); if (R_FAILED(res)) return res; // Map the shared font if it's not already mapped. res = svcMapMemoryBlock(hSharedFont, 0, MEMPERM_READ, MEMPERM_DONTCARE); svcCloseHandle(hSharedFont); if (R_FAILED(res) && res != 0xE0A01BF5) return res; g_sharedFont = (CFNT_s*)(sharedFontAddr+0x80); charPerSheet = g_sharedFont->finf.tglp->nRows * g_sharedFont->finf.tglp->nLines; return 0; }
Result irrstInit(void) { if (AtomicPostIncrement(&irrstRefCount)) return 0; Result ret=0; // Request service. if(R_FAILED(ret=srvGetServiceHandle(&irrstHandle, "ir:rst"))) goto cleanup0; // Get sharedmem handle. if(R_FAILED(ret=IRRST_GetHandles(&irrstMemHandle, &irrstEvent))) goto cleanup1; // Initialize ir:rst if(envGetHandle("ir:rst") == 0) ret = IRRST_Initialize(10, 0); // Map ir:rst shared memory. irrstSharedMem=(vu32*)mappableAlloc(0x98); if(!irrstSharedMem) { ret = -1; goto cleanup1; } if(R_FAILED(ret = svcMapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem, MEMPERM_READ, 0x10000000))) goto cleanup2; // Reset internal state. kHeld = 0; return 0; cleanup2: svcCloseHandle(irrstMemHandle); if(irrstSharedMem != NULL) { mappableFree((void*) irrstSharedMem); irrstSharedMem = NULL; } cleanup1: svcCloseHandle(irrstHandle); cleanup0: AtomicDecrement(&irrstRefCount); return ret; }
void gfxInit(GSPGPU_FramebufferFormats topFormat, GSPGPU_FramebufferFormats bottomFormat, bool vrambuffers) { void *(*screenAlloc)(size_t); if (vrambuffers) { screenAlloc=vramAlloc; screenFree=vramFree; } else { screenAlloc=linearAlloc; screenFree=linearFree; } gspInit(); gfxSharedMemory=(u8*)mappableAlloc(0x1000); GSPGPU_AcquireRight(0x0); //setup our gsp shared mem section svcCreateEvent(&gspEvent, 0x0); GSPGPU_RegisterInterruptRelayQueue(gspEvent, 0x1, &gspSharedMemHandle, &gfxThreadID); svcMapMemoryBlock(gspSharedMemHandle, (u32)gfxSharedMemory, 0x3, 0x10000000); // default gspHeap configuration : // topleft1 0x00000000-0x00046500 // topleft2 0x00046500-0x0008CA00 // bottom1 0x0008CA00-0x000C4E00 // bottom2 0x000C4E00-0x000FD200 // if 3d enabled : // topright1 0x000FD200-0x00143700 // topright2 0x00143700-0x00189C00 u32 topSize = 400 * 240 * __get_bytes_per_pixel(topFormat); u32 bottomSize = 320 * 240 * __get_bytes_per_pixel(bottomFormat); gfxTopLeftFramebuffers[0]=screenAlloc(topSize); gfxTopLeftFramebuffers[1]=screenAlloc(topSize); gfxBottomFramebuffers[0]=screenAlloc(bottomSize); gfxBottomFramebuffers[1]=screenAlloc(bottomSize); gfxTopRightFramebuffers[0]=screenAlloc(topSize); gfxTopRightFramebuffers[1]=screenAlloc(topSize); enable3d=false; //set requested modes gfxSetScreenFormat(GFX_TOP,topFormat); gfxSetScreenFormat(GFX_BOTTOM,bottomFormat); //initialize framebuffer info structures gfxSetFramebufferInfo(GFX_TOP, 0); gfxSetFramebufferInfo(GFX_BOTTOM, 0); //GSP shared mem : 0x2779F000 gxCmdBuf=(u32*)(gfxSharedMemory+0x800+gfxThreadID*0x200); currentBuffer[0]=0; currentBuffer[1]=0; // Initialize event handler and wait for VBlank gspInitEventHandler(gspEvent, (vu8*) gfxSharedMemory, gfxThreadID); gspWaitForVBlank(); GSPGPU_SetLcdForceBlack(0x0); }
D3DSDevice D3DSDevice::CreateDevice( GSPGPU_FramebufferFormats FBFormatTop, GSPGPU_FramebufferFormats FBFormatBottom, bool bVRamBuffers, bool bEnable3D ) { D3DSDevice device; device.m_b3DEnabled = bEnable3D; device.m_FBFormatTop = FBFormatTop; device.m_FBFormatBottom = FBFormatBottom; // select allocator void* (*allocator)(size_t); if (bVRamBuffers) { allocator = vramAlloc; device.dealloc = vramFree; } else { allocator = linearAlloc; device.dealloc = linearFree; } gspInit(); device.m_pSharedMemory = (u8*) mappableAlloc( 0x1000 ); GSPGPU_AcquireRight( 0x0 ); // create shared memory svcCreateEvent( &device.m_hGSPEvent, 0x0 ); GSPGPU_RegisterInterruptRelayQueue( device.m_hGSPEvent, 0x1, &device.m_hGSPSharedMemory, &device.m_ThreadId ); svcMapMemoryBlock( device.m_hGSPSharedMemory, (u32)device.m_pSharedMemory, (MemPerm)(MEMPERM_READ|MEMPERM_WRITE), MEMPERM_DONTCARE ); // allocate framebuffers... u32 bytes_top = 400 * 240 * D3DSDevice::GetBytesPerPixel( FBFormatTop ); u32 bytes_bottom = 320 * 240 * D3DSDevice::GetBytesPerPixel( FBFormatBottom ); device.m_FBBottom[0] = (u8*) allocator( bytes_bottom ); device.m_FBBottom[1] = (u8*) allocator( bytes_bottom ); device.m_FBTop[ 0 ] = (u8*) allocator( bytes_top ); device.m_FBTop[ 1 ] = (u8*) allocator( bytes_top ); if (device.m_b3DEnabled) { device.m_FBTop[ 2 ] = (u8*) allocator( bytes_top ); device.m_FBTop[ 3 ] = (u8*) allocator( bytes_top ); } device.SetFramebufferInfo( D3DS_SCREEN_TOP, 0 ); device.SetFramebufferInfo( D3DS_SCREEN_BOTTOM, 0 ); gxCmdBuf = (u32*) (device.m_pSharedMemory + 0x800 + device.m_ThreadId*0x200 ); gspInitEventHandler( device.m_hGSPEvent, (vu8*)device.m_pSharedMemory, device.m_ThreadId ); gspWaitForVBlank(); GSPGPU_SetLcdForceBlack( 0x0 ); return device; }
int main() { Handle rsrc; bool failed = true; gfxInitDefault(); consoleInit(GFX_TOP, NULL); printf("\x1b[10;10HFetching DSP component...\x1b[12;10H"); rsrc = envGetHandle("hb:ndsp"); if (!rsrc) { printf("\x1b[31;1mFailed\x1b[0m: Need to run using *hax 2.0+"); } else do { Result rc; u32 len; void* bin; extern u32 fake_heap_end; char* filename = "sdmc:/3ds/dspfirm.cdc"; u32 mapAddr = (fake_heap_end+0xFFF) &~ 0xFFF; rc = svcMapMemoryBlock(rsrc, mapAddr, 0x3, 0x3); if (R_FAILED(rc)) break; len = *(u32*)(mapAddr + 0x104); bin = malloc(len); if (bin) memcpy(bin, (void*)mapAddr, len); svcUnmapMemoryBlock(rsrc, mapAddr); if (!bin) break; FILE* file = fopen(filename, "wb"); if (!file) break; fwrite(bin, 1, len, file); fclose(file); failed = false; printf("\x1b[32;1mDone\x1b[0m: No further steps needed!\n"); free(bin); } while (0); if (rsrc && failed) printf("\x1b[31;1mFailed\x1b[0m: Unknown error. Try again."); printf("\x1b[28;15HPress START to exit."); while (aptMainLoop()) { hidScanInput(); u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForVBlank(); } gfxExit(); return 0; }
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; }