Skip to content

Instantly share code, notes, and snippets.

@dots-tb
Last active April 12, 2020 11:45
Show Gist options
  • Save dots-tb/0357e1a66db98e81153d0e8204ffce64 to your computer and use it in GitHub Desktop.
Save dots-tb/0357e1a66db98e81153d0e8204ffce64 to your computer and use it in GitHub Desktop.
FAPS Vita MIPS reset vector test
#include <vitasdkkern.h>
#include <taihen.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
static const unsigned char cxt130_bin[] = {
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x09, 0x80, 0x03, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x80, 0x09,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
};
#define printf ksceDebugPrintf
#define RESET_VECTOR_FILE "ux0:/data/mips_rst.bin"
int (* SceKernelSuspendForDriver_2BB92967)(int);
int (* SceKernelSuspendForDriver_4DF40893)(int);
int (* SceGrabForDriver_072B8D93)(int);
volatile uint32_t *sram_addr;
static tai_hook_ref_t ksceSblSmCommCallFunc_ref;
SceUID hook = -1;
static SceUID write_reset_vector() {
int fd = ksceIoOpen(RESET_VECTOR_FILE, SCE_O_RDONLY, 0);
if(fd > 0){
printf("ksceIoRead %x\n", ksceIoRead(fd, (void*)*sram_addr, 0x1000));
__asm__("dsb sy" ::: "memory");
ksceIoClose(fd);
}
return fd;
}
static SceUID ksceSblSmCommCallFunc_patched(int id, int service_id, int *f00d_resp, void *data, int size) {
SceUID ret, state;
ENTER_SYSCALL(state);
if(service_id == 0x10006) {
ret = TAI_CONTINUE(SceUID, ksceSblSmCommCallFunc_ref, id, service_id, f00d_resp, data, 0);
printf("ksceSblSmCommCallFunc_patched %x\n", ret);
ksceKernelDelayThread(10000);
write_reset_vector();
*f00d_resp = 0;
ret = 0;
} else
ret = TAI_CONTINUE(SceUID, ksceSblSmCommCallFunc_ref, id, service_id, f00d_resp, data, size);
EXIT_SYSCALL(state);
return ret;
}
typedef struct SceSelfInfo // size is 0x90
{
SceUInt64 program_authority_id;
SceUInt64 padding1;
uint8_t capability[0x20];
uint8_t attribute[0x20];
uint8_t padding2[0x10];
uint8_t klicensee[0x10];
uint32_t unk_70;
uint32_t unk_74;
uint32_t unk_78;
uint32_t unk_7C;
uint32_t unk_80; // ex: 0x10
uint32_t unk_84;
uint32_t unk_88;
uint32_t unk_8C;
} SceSelfInfo;
typedef struct SceSblSmCommContext130 // size is 0x130 as its name indicates
{
uint32_t unk_0;
uint32_t self_type; // kernel = 0, user = 1, SM = 2
SceSelfInfo caller_self_auth_info; // can be obtained with sceKernelGetSelfInfoForKernel
SceSelfInfo called_self_auth_info; // set by F00D in F00D SceSblSmCommContext130 response
uint32_t path_id; // can be obtained with sceSblACMgrGetPathIdForKernel or sceIoGetPathIdExForDriver
uint32_t unk_12C;
} SceSblSmCommContext130;
int f00d_start_compat_sm(uint32_t *id) {
SceSblSmCommContext130 sm_cxt;
memset(&sm_cxt, 0, sizeof(sm_cxt));
ksceSblACMgrGetPathId("os0:sm/compat_sm.self", &sm_cxt.path_id);
memcpy(&sm_cxt.caller_self_auth_info, cxt130_bin, sizeof(cxt130_bin));
sm_cxt.self_type = (sm_cxt.self_type & 0xFFFFFFF0) | 2;
int ret = ksceSblSmCommStartSmFromFile(0,"os0:sm/compat_sm.self", 0, &sm_cxt, id);
printf("ksceSblSmCommStartSmFromFile %x\n", ret);
return ret;
}
int f00d_write_reset_vector(uint32_t r_0xfbc) {
uint32_t resp[2];
uint32_t data[2];
uint32_t id;
printf("SceKernelSuspendForDriver_4DF40893 %x\n", SceKernelSuspendForDriver_4DF40893(0));
int ret = f00d_start_compat_sm(&id);
if(ret == 0) {
memset(&data, 0, sizeof(data));
memset(&resp, 0, sizeof(resp));
data[0] = r_0xfbc;
data[1] = ret;
ret = ksceSblSmCommCallFunc(id, 0x10006, &resp, data, 8);
ksceKernelDelayThread(10000);
//write_reset_vector();
printf("ksceSblSmCommCallFunc 0x10006 %x %x %x\n", ret, resp[0], resp[1]);
ret = ksceSblSmCommStopSm(id, &resp);
printf("ksceSblSmCommStopSm %x\n", ret);
}
printf("SceKernelSuspendForDriver_2BB92967 %x\n",SceKernelSuspendForDriver_2BB92967(0));
}
void _start() __attribute__ ((weak, alias ("module_start")));
int module_start(SceSize argc, const void *args){
printf("FAPS COMPATRIOT TEST\n");
hook = taiHookFunctionImportForKernel(KERNEL_PID, &ksceSblSmCommCallFunc_ref, "SceCompat", TAI_ANY_LIBRARY, 0xDB9FC204, ksceSblSmCommCallFunc_patched);
module_get_export_func(KERNEL_PID, "SceSysmem", TAI_ANY_LIBRARY, 0x2BB92967, (uintptr_t *) &SceKernelSuspendForDriver_2BB92967);
module_get_export_func(KERNEL_PID, "SceSysmem", TAI_ANY_LIBRARY, 0x4DF40893, (uintptr_t *) &SceKernelSuspendForDriver_4DF40893);
module_get_export_func(KERNEL_PID, "SceLowio", 0x81C54BED, 0x072B8D93, (uintptr_t *)&SceGrabForDriver_072B8D93);
tai_module_info_t tai_info;
tai_info.size = sizeof(tai_module_info_t);
printf("taiGetModuleInfoForKernel %x\n",taiGetModuleInfoForKernel(KERNEL_PID, "SceCompat", &tai_info));
printf("module_get_offset %x\n", module_get_offset(KERNEL_PID, tai_info.modid, 1, 0x15DC, (uintptr_t *)&sram_addr));
printf("sram vaddr %x\n", *sram_addr);
printf("kscePowerSetCompatClockFrequency(0x14d) %x\n", kscePowerSetCompatClockFrequency(0x14d));
printf("SceGrabForDriver_072B8D93 %x\n", SceGrabForDriver_072B8D93(0));
f00d_write_reset_vector(0);
return SCE_KERNEL_START_SUCCESS;
}
int module_stop(SceSize argc, const void *args){
if(hook>-1)
taiHookReleaseForKernel(hook, ksceSblSmCommCallFunc_ref);
return SCE_KERNEL_STOP_SUCCESS;
}
@dots-tb
Copy link
Author

dots-tb commented Apr 12, 2020

Turns out I actually needed the thing Princess put in...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment