/* * * SILICAANDPINA * * KERNEL < - > USERLAND SceRtc BRIDGE * */ #include #include #include #include #include #include "rtc.h" int module_get_export_func(SceUID pid, const char *modname, uint32_t libnid, uint32_t funcnid, uintptr_t *func); void (*sceIoMount)(int id, const char *path, int permission, int a4, int a5, int a6); void (*sceIoUmount)(int id, int a2, int a3, int a4); int WriteFile(char *file, void *buf, int size) { SceUID fd = ksceIoOpen(file, SCE_O_RDWR | SCE_O_CREAT, 0777); if (fd < 0) return fd; int written = ksceIoWrite(fd, buf, size); ksceIoClose(fd); return written; } int ReadFile(char *file, void *buf, int size) { SceUID fd = ksceIoOpen(file,SCE_O_RDONLY, 0777); if (fd < 0) return fd; int read = ksceIoRead(fd, buf, size); ksceIoClose(fd); return read; } int getFileSize(const char *file) { SceUID fd = ksceIoOpen(file, SCE_O_RDONLY, 0); if (fd < 0) return fd; int fileSize = ksceIoLseek(fd, 0, SCE_SEEK_END); ksceIoClose(fd); return fileSize; } int ksilRtcSetCurrentTick(unsigned int timestamp1,unsigned int timestamp2) { unsigned int timestamp[2]; timestamp[0] = timestamp1; timestamp[1] = timestamp2; return ksceRtcSetCurrentTick(timestamp); } int ksilRtcSetCurrentNetworkTick(unsigned int timestamp1,unsigned int timestamp2) { unsigned int timestamp[2]; timestamp[0] = timestamp1; timestamp[1] = timestamp2; return ksceRtcSetCurrentNetworkTick(timestamp); } int ksilRtcSetCurrentSecureTick(unsigned int timestamp1,unsigned int timestamp2) { unsigned int timestamp[2]; timestamp[0] = timestamp1; timestamp[1] = timestamp2; return ksceRtcSetCurrentSecureTick(timestamp); } int ksilSblPostSsMgrSetCpRtc(unsigned int timestamp) { return ksceSblPostSsMgrSetCpRtc(timestamp); } int ksilDumpNvsAct(int fileno) { char nvsBuf[0x20]; char act_magic[0x3] = {0x61, 0x63, 0x74}; int ret = ksceSblNvsReadData(0x520,nvsBuf,0x20); if(memcmp(nvsBuf,act_magic,0x3) != 0) { return -6325; } if(fileno == 1) { WriteFile("ux0:/data/act-nvs.dat",nvsBuf,0x20); } else { WriteFile("pd0:/data/act-nvs.dat",nvsBuf,0x20); } return ret; } int ksilRestoreNvsAct(int fileno) { char nvsBuf[0x20]; int ret; if(fileno == 1) { ret = ReadFile("ux0:/data/act-nvs.dat",nvsBuf,0x20); if(ret < 0) { return ret; } } else { ret = ReadFile("pd0:/data/act-nvs.dat",nvsBuf,0x20); if(ret < 0) { return ret; } } ret = ksceSblNvsWriteData(0x520,nvsBuf,0x20); return ret; } int ksilIoUmount(int id, int force){ sceIoUmount(id, force, 0, 0); return 0; } int ksilIoMount(int id, int permission){ sceIoMount(id, NULL, permission, 0, 0, 0); return 0; } #pragma GCC optimize ("O0") int get_functions() // Bypass vitashell memes { int obfuscateNid = 0xCD4AA9E6; obfuscateNid += 0x3261262; // Equals (ksceIoMount) int obfuscateNid2 = 0x1E212AED; obfuscateNid2 += 0x2361613; // Equals (ksceIoUmount) int obfuscateLib = 0xF9A13B2; obfuscateLib += 0x31631615; // Equals (SceIofilemgrForDriver) module_get_export_func(KERNEL_PID, "SceIofilemgr", obfuscateLib, obfuscateNid, (uintptr_t *)&sceIoMount); module_get_export_func(KERNEL_PID, "SceIofilemgr", obfuscateLib, obfuscateNid2, (uintptr_t *)&sceIoUmount); ksceDebugPrintf("sceIoMount:%p\n", sceIoMount); ksceDebugPrintf("sceIoUmount:%p\n", sceIoUmount); return 0; } #pragma GCC optimize ("O3") void _start() __attribute__ ((weak, alias ("module_start"))); int module_start(SceSize argc, const void *args) { /* * 1/1/2015 check BTFO'd * * Vita checks elsewhere though :'( */ tai_module_info_t info; info.size = sizeof(tai_module_info_t); if (taiGetModuleInfoForKernel(KERNEL_PID, "SceRtc", &info) < 0) { return SCE_KERNEL_START_SUCCESS; } uint32_t patched_instruction = 0xBF00BF00; //NOP taiInjectDataForKernel(KERNEL_PID, info.modid, 0, 0x93C, &patched_instruction, 0x4); //bcs.w LAB_81000a64 -> NOP (SetCurrentSecureTick) taiInjectDataForKernel(KERNEL_PID, info.modid, 0, 0xA94, &patched_instruction, 0x4); //bcs.w LAB_81000bbc -> NOP (SetCurrentNetworkTick) get_functions(); return SCE_KERNEL_START_SUCCESS; } int module_stop(SceSize argc, const void *args) { return SCE_KERNEL_STOP_SUCCESS; }