void PspSpeedTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes) { uint32 time1, time2; uint32 fastcopyTime, memcpyTime; const int iterations = 2000; int intc; intc = pspSdkDisableInterrupts(); time1 = PspRtc::instance().getMicros(); for (int i=0; i<iterations; i++) { PspMemory::fastCopy(dst, src, bytes); } time2 = PspRtc::instance().getMicros(); pspSdkEnableInterrupts(intc); fastcopyTime = time2-time1; intc = pspSdkDisableInterrupts(); time1 = PspRtc::instance().getMicros(); for (int i=0; i<iterations; i++) { memcpy(dst, src, bytes); } time2 = PspRtc::instance().getMicros(); pspSdkEnableInterrupts(intc); memcpyTime = time2-time1; PSP_INFO_PRINT("%d bytes. memcpy[%d], fastcopy[%d]\n", bytes, memcpyTime, fastcopyTime); }
static u32 my_InterlockedExchange(u32 volatile *dst, u32 exchange) { unsigned int flags = pspSdkDisableInterrupts(); u32 origvalue = *dst; *dst = exchange; pspSdkEnableInterrupts(flags); return origvalue; }
int peekDebugChar(unsigned char *ch) { int ret = 0; int intc; *ch = 0; intc = pspSdkDisableInterrupts(); if(g_endp.size > 0) { *ch = g_endp.buffer[g_endp.read_pos]; ret = 1; } pspSdkEnableInterrupts(intc); return ret; }
/* Patch out the exception handler setup call for apps which come after us ;P */ int psplinkPatchException(void) { unsigned int *addr; int intc; intc = pspSdkDisableInterrupts(); addr = libsFindExportAddrByNid(refer_module_by_name("sceExceptionManager", NULL), "ExceptionManagerForKernel", 0x565C0B0E); if(addr) { *addr = (unsigned int) RegisterExceptionDummy; sceKernelDcacheWritebackInvalidateRange(addr, 4); sceKernelIcacheInvalidateRange(addr, 4); } pspSdkEnableInterrupts(intc); return 0; }
/*------------------------------------------------------------------------------*/ void debug_printf( const char *arg, ... ) { char tmp[DEBUG_BUFF_SIZE]; int intc = pspSdkDisableInterrupts(); if ( debug_disp_flag != 0 ){ debug_disp_flag = 0; sprintf( DebugData.buff, "0x%08x\n", sceDisplayGetVcount() ); } va_list ap; va_start( ap, arg ); vsprintf( tmp, arg, ap ); if ( strlen(DebugData.buff) + strlen(tmp) < DEBUG_BUFF_SIZE ){ strcat( DebugData.buff, tmp ); } pspSdkEnableInterrupts( intc ); }
static int add_char(unsigned char ch) { int intc; int total; intc = pspSdkDisableInterrupts(); if(g_total < KPRINTF_BUF_SIZE) { g_buf[g_writepos++] = ch; g_writepos %= KPRINTF_BUF_SIZE; g_total++; } total = g_total; pspSdkEnableInterrupts(intc); return total; }
int libsPatchFunction(SceUID uid, const char *library, unsigned int nid, u16 retval) { unsigned int* addr; int intc; int ret = 0; intc = pspSdkDisableInterrupts(); addr = (unsigned int *) libsFindExportByNid(uid, library, nid); if(addr) { addr[0] = 0x03E00008; addr[1] = 0x24020000 | (unsigned int) retval; sceKernelDcacheWritebackInvalidateRange(addr, 8); sceKernelIcacheInvalidateRange(addr, 8); ret = 1; } pspSdkEnableInterrupts(intc); return ret; }
int main_thread(SceSize args, void *argp) { struct PsplinkContext *ctx; int ret; SceUInt timeout; SceUID thids[20]; int count; int intc; printf("PSPLink USB GDBServer (c) 2k7 TyRaNiD\n"); if(!initialise(args, argp)) { printf("Usage: usbgdb.prx program [args]\n"); sceKernelExitDeleteThread(0); } if(usbAsyncRegister(ASYNC_GDB, &g_endp) < 0) { printf("Could not register GDB provider\n"); sceKernelExitDeleteThread(0); } usbWaitForConnect(); memset(&g_handler, 0, sizeof(g_handler)); g_handler.size = sizeof(g_handler); g_handler.membase = g_context.info.text_addr; g_handler.memtop = g_context.info.text_addr + g_context.info.text_size; g_handler.mbox = sceKernelCreateMbx("GDBMbx", 0, NULL); if(g_handler.mbox < 0) { printf("Could not create message box\n"); sceKernelExitDeleteThread(0); } if(debugRegisterEventHandler(&g_handler) < 0) { printf("Could not register event handler\n"); sceKernelExitDeleteThread(0); } if(GdbHandleException(&g_context.ctx)) { while(1) { timeout = GDB_POLL_TIMEOUT; ret = debugWaitDebugEvent(&g_handler, &ctx, &timeout); if(ret == 0) { DEBUG_PRINTF("ctx %p, epc 0x%08X\n", ctx, ctx->regs.epc); ret = GdbHandleException(ctx); sceKernelWakeupThread(ctx->thid); if(ret == 0) { break; } } else if(ret == SCE_KERNEL_ERROR_WAIT_TIMEOUT) { unsigned char ch; if(peekDebugChar(&ch) && (ch == 3)) { DEBUG_PRINTF("Break Issued\n"); intc = pspSdkDisableInterrupts(); count = psplinkReferThreadsByModule(SCE_KERNEL_TMID_Thread, g_context.uid, thids, 20); if(count > 0) { /* We just break the first thread */ /* Could in theory break on the thread which we are interested in ? */ debugBreakThread(thids[0]); } pspSdkEnableInterrupts(intc); /* Should have a fallback if it just wont stop GdbHandleException(&g_context.ctx); */ } continue; } else { printf("Error waiting for debug event 0x%08X\n", ret); break; } } } debugUnregisterEventHandler(&g_handler); sceKernelExitDeleteThread(0); return 0; }
/* for 6.20/6.35 */ void do_exploit(void) { u32 power_buf_address = 0; //create empty callback int cbid = -1; int result; #ifdef CONFIG_635 if(psp_fw_version == FW_635) { //create a fitting one while(!is_intr_OK((u32)cbid)) { //sceKernelDeleteCallback(cbid); cbid = sceKernelCreateCallback("", NULL, NULL); } } #endif #ifdef CONFIG_620 if (psp_fw_version == FW_620) { cbid = sceKernelCreateCallback("", NULL, NULL); } #endif printk("Got a CBID: 0x%08X\r\n", cbid); //Davee $v1 trick, $v1 would leak the power_buf_address when called on an registered slot 0 scePowerRegisterCallbackPrivate(0, cbid); power_buf_address = get_power_address(cbid); scePowerUnregisterCallbackPrivate(0); printk("power_buf_address 0x%08X\r\n", (uint)power_buf_address); #ifdef CONFIG_635 if(psp_fw_version == FW_635 && !is_pspgo()) { patch_power_arg(cbid, power_buf_address); } #endif //override sysmem function unsigned int smpos = g_offs->patchRangeStart; for(; smpos < g_offs->patchRangeEnd; smpos += 16) { //calculate slot unsigned int slot = get_power_slot_by_address(((u32)0x88000000)+smpos, power_buf_address); //wipe memory with -1... else overriding fails. scePowerUnregisterCallbackPrivate(slot); //register dummy callback (override memory ^^) result = scePowerRegisterCallbackPrivate(slot, cbid); //patching error if(result) break; } //flush changes to memory sync_cache(); //restoring instructions and patching loadexec unsigned int interrupts = pspSdkDisableInterrupts(); #ifdef CONFIG_635 if(psp_fw_version == FW_635) { result = SysMemUserForUser_D8DE5C1E(0xC01DB15D, 0xC00DCAFE, kernelSyscall, 0x12345678, -1); } #endif #ifdef CONFIG_620 if (psp_fw_version == FW_620) { u32 kernel_entry, entry_addr; kernel_entry = (u32) &kernel_permission_call; entry_addr = ((u32) &kernel_entry) - 16; result = sceKernelPowerLock(0, ((u32) &entry_addr) - 0x4234); } #endif pspSdkEnableInterrupts(interrupts); }
int main_thread(SceSize args, void *argp) { int ret; int intc; unsigned char *plow, *phigh; int low, high; memset(g_buf, 0, KPRINTF_BUF_SIZE); g_writepos = 0; g_readpos = 0; g_total = 0; plow = NULL; phigh = NULL; g_eventflag = sceKernelCreateEventFlag("UsbKprintfEvent", 0, 0, 0); if(g_eventflag < 0) { printf("Error creating event flag %08X\n", g_eventflag); } sceKernelRegisterDebugPutchar(PutCharDebug); while(1) { ret = sceKernelWaitEventFlag(g_eventflag, KPRINTF_EVENT, 0x21, 0, 0); if(ret < 0) { sceKernelExitDeleteThread(0); } low = 0; high = 0; intc = pspSdkDisableInterrupts(); if(g_total > 0) { plow = &g_buf[g_readpos]; low = (KPRINTF_BUF_SIZE - g_readpos) < g_total ? (KPRINTF_BUF_SIZE - g_readpos) : g_total ; if(low < g_total) { phigh = g_buf; high = g_total - low; } } pspSdkEnableInterrupts(intc); if((low != 0) && (high == 0)) { printf("%.*s", low, plow); } else if((low != 0) && (high != 0)) { printf("%.*s%.*s", low, plow, high, phigh); } intc = pspSdkDisableInterrupts(); g_total -= (low+high); g_readpos += (low+high); g_readpos %= KPRINTF_BUF_SIZE; pspSdkEnableInterrupts(intc); } return 0; }