diff --git a/app/main.c b/app/main.c index ddbd018..1b42df9 100644 --- a/app/main.c +++ b/app/main.c @@ -77,6 +77,80 @@ int getFileSize(const char *file) { return fileSize; } +int CopyFile(char *src, char *dst) +{ + int size = getFileSize(src); + if (size <= -1){ + printf("getFileSize Failed, ret: 0x%x\n",size); + } + else + { + char *buffer = malloc(size); + ret = ReadFile(src,buffer,size); + if (ret <= -1) + { + printf("ReadFile failed 0x%x\n",ret); + } + + ret = WriteFile(dst,buffer,size); + if (ret <= -1){ + printf("WriteFile failed 0x%x\n",ret); + } + } + return ret; +} + +int restore_act() +{ + printf("Activation Data not Found! 0x%x\nChecking for backup...",ret); + int is_ux0 = getFileSize("ux0:/data/act.dat") > 0; + int is_pd0 = getFileSize("pd0:/data/act.dat") > 0; + + if( is_ux0 || is_pd0 ) + { + printf("Activation Data backup found!\n"); + printf("Press any key to restore (existing activation data will be overwritten)\n"); + get_key(); + if(is_ux0) + { + CopyFile("ux0:/data/act.dat","tm0:/activate/act.dat"); + CopyFile("ux0:/data/actsig.dat","tm0:/activate/actsig.dat"); + CopyFile("ux0:/data/act.dat","tm0:/activate/act.dat"); + ret = silRestoreNvsAct(0x1); + } + else if(is_pd0) + { + + CopyFile("pd0:/data/act.dat","tm0:/activate/act.dat"); + CopyFile("pd0:/data/actsig.dat","tm0:/activate/actsig.dat"); + CopyFile("pd0:/data/act.dat","tm0:/activate/act.dat"); + ret = silRestoreNvsAct(0x0); + } + // Check Success + if(ret <= -1) + { + printf("ksceSblNvsWriteData failed 0x%x",ret); + } + else + { + printf("Activation data restored!"); + get_key(); + sceKernelExitProcess(0); + } + } + else + { + printf("No backup data found.\n"); + printf("if you have a backup of Activation Data please place it in ux0:/data\n\n"); + printf(" - ux0:/data/act.dat\n"); + printf(" - ux0:/data/actsig.dat\n"); + printf(" - ux0:/data/act-nvs.dat\n"); + + get_key(); + sceKernelExitProcess(0); + } + return ret; +} @@ -135,18 +209,13 @@ void main() { printf("OK\n"); - - - printf("Finding expiration start date..."); unsigned char startDate[0x4]; fd = sceIoOpen("tm0:/activate/act.dat",SCE_O_RDONLY, 0444); if(fd <= -1) { - printf("\ntm0:/activate/act.dat not found, cannot proceed :'( 0x%x\n",ret); - get_key(); - sceKernelExitProcess(0); + restore_act(); } sceIoLseek(fd,0xC,SCE_SEEK_SET); @@ -156,16 +225,12 @@ void main() { fd = sceIoOpen("tm0:/activate/actsig.dat",SCE_O_RDONLY, 0444); if(fd <= -1) { - printf("\ntm0:/activate/actsig.dat not found, cannot proceed :'( 0x%x\n",ret); - get_key(); - sceKernelExitProcess(0); + restore_act(); } sceIoClose(fd); printf(" found: 0x%02X%02X%02X%02X\n",startDate[0],startDate[1],startDate[2],startDate[3]); - - - printf("Backing up activation files... "); + printf("Backing up activation files...\n"); uint32_t buf[3]; buf[0] = 0x00; @@ -177,60 +242,18 @@ void main() { _vshIoMount(0xC00, 0, 2, buf); //backup actdat - int size = getFileSize("tm0:/activate/act.dat"); - if (size <= -1){ - printf("getFileSize Failed, ret: 0x%x\n",size); - } - else - { - char *actdat = malloc(size); - ret = ReadFile("tm0:/activate/act.dat",actdat,size); - if (ret <= -1) - { - printf("ReadFile act failed 0x%x\n",ret); - } - - ret = WriteFile("pd0:/data/act.dat",actdat,size); - if (ret <= -1){ - printf("WriteFile act failed 0x%x\n",ret); - } - ret = WriteFile("ux0:/data/act.dat",actdat,size); - if (ret <= -1){ - printf("WriteFile act failed 0x%x\n",ret); - } - } - - //backup actsig - size = getFileSize("tm0:/activate/actsig.dat"); - if (size <= -1){ - printf("getFileSize failed ret: 0x%x\n",size); - } - else - { - char *actsig = malloc(size); - - ret = ReadFile("tm0:/activate/actsig.dat",actsig,size); - if (ret <= -1){ - printf("ReadFile actsig failed 0x%x\n",ret); - } - - ret = WriteFile("pd0:/data/actsig.dat",actsig,size); - if (ret <= -1){ - printf("WriteFile actsig failed 0x%x\n",ret); - } - - ret = WriteFile("ux0:/data/actsig.dat",actsig,size); - if (ret <= -1){ - printf("WriteFile actsig failed 0x%x\n",ret); - } - } - - //backup nvs + CopyFile("tm0:/activate/act.dat","ux0:/data/act.dat"); + CopyFile("tm0:/activate/act.dat","pd0:/data/act.dat"); + //backup actsig + CopyFile("tm0:/activate/actsig.dat","ux0:/data/actsig.dat"); + CopyFile("tm0:/activate/actsig.dat","pd0:/data/actsig.dat"); + + ret = silDumpNvsAct(0x0); if (ret <= -1){ - printf("ksceSblNvsReadData failed 0x%x\n",ret); - } + printf("ksceSblNvsReadData failed 0x%x\n",ret); + } ret = silDumpNvsAct(0x1); if (ret <= -1){ printf("ksceSblNvsReadData failed 0x%x\n",ret); @@ -254,28 +277,37 @@ void main() { else if(vshSblAimgrIsDEX()) { printf("Calculating PSTime: "); - unsigned long long int timestamp; - memset(×tamp,0,sizeof(unsigned long long int)); - timestamp = *((unsigned int*)&startDate); - timestamp = ((timestamp * 1000) + 62135596800000) * 1000; + unsigned int _startDate = *((unsigned int*)&startDate); + + uint64_t timestamp = 0; + timestamp = ((_startDate * 1000) + 62135596800000) * 1000; + printf("PSTIME: %llx\n",timestamp); + + if(_startDate < 1420070400); + { + printf("Warn: Start Date is Before 1/1/2015\n"); + printf("It's impossible to set the time before 1/1/2015.\n"); + printf("However i can cause an overflow when reading to make it *appear* as 1/1/2015\n"); + printf("doing this will break trophy earning though.\n"); + printf("\nPress any key to continue\n"); + + get_key(); + timestamp = 0xFFEEDDCCBBAA9988ull; + //printf("NEW PSTIME: %llx\n",timestamp); + + } - printf("%llx\n",timestamp); + printf("Creating splits..\n"); - char hexint[15]; - memset(hexint,0,15); + + unsigned int split1 = timestamp >> 32; + unsigned int split2 = timestamp & 0xffffffff; + - sprintf(hexint,"%llx",timestamp); - - char ts1[7] = {hexint[0],hexint[1],hexint[2],hexint[3],hexint[4],hexint[5],0x00}; - unsigned long long int split1 = (unsigned int)strtoul(ts1, NULL, 16); - printf("Split1: %llx\n",split1); - - - char ts2[10] = {hexint[6],hexint[7],hexint[8],hexint[9],hexint[10],hexint[11],hexint[12],hexint[13],hexint[14],0x00}; - unsigned long long int split2 = (unsigned int)strtoul(ts2, NULL, 16); - printf("Split2: %llx\n",split2); + printf("Split1: %x\n",split1); + printf("Split2: %x\n",split2); printf("Updating SecureTick.. "); ret = silRtcSetCurrentSecureTick(split2,split1); diff --git a/app/rtcUserBridge.h b/app/rtcUserBridge.h index d7d3e3b..87b5deb 100644 --- a/app/rtcUserBridge.h +++ b/app/rtcUserBridge.h @@ -2,4 +2,5 @@ int silRtcSetCurrentTick(unsigned int timestamp1, unsigned int timestamp2); int silRtcSetCurrentNetworkTick(unsigned int timestamp1, unsigned int timestamp2); int silRtcSetCurrentSecureTick(unsigned int timestamp1, unsigned int timestamp2); int silSblPostSsMgrSetCpRtc(unsigned int timestamp); -int silDumpNvsAct(unsigned int filenos); \ No newline at end of file +int silDumpNvsAct(unsigned int fileno); +int silRestoreNvsAct(unsigned int fileno); \ No newline at end of file diff --git a/kern/exports.yml b/kern/exports.yml index 026584e..504f5e9 100644 --- a/kern/exports.yml +++ b/kern/exports.yml @@ -14,4 +14,5 @@ kern_clockset: - ksilRtcSetCurrentNetworkTick - ksilRtcSetCurrentTick - ksilSblPostSsMgrSetCpRtc - - ksilDumpNvsAct \ No newline at end of file + - ksilDumpNvsAct + - ksilRestoreNvsAct \ No newline at end of file diff --git a/kern/kern_clockset.c b/kern/kern_clockset.c index 6100344..1294360 100644 --- a/kern/kern_clockset.c +++ b/kern/kern_clockset.c @@ -23,6 +23,25 @@ int WriteFile(char *file, void *buf, int 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) { @@ -62,9 +81,15 @@ int ksilSblPostSsMgrSetCpRtc(unsigned int timestamp) int ksilDumpNvsAct(int fileno) { char nvsBuf[0x20]; - memset(nvsBuf,0x00,0x520); + 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); @@ -76,6 +101,33 @@ int ksilDumpNvsAct(int fileno) 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; +} + void _start() __attribute__ ((weak, alias ("module_start"))); int module_start(SceSize argc, const void *args) diff --git a/kern/rtc.h b/kern/rtc.h index 6c2a680..f7aeeea 100644 --- a/kern/rtc.h +++ b/kern/rtc.h @@ -4,4 +4,5 @@ int ksceRtcSetCurrentSecureTick(unsigned int* timestamp); int ksceSblPostSsMgrSetCpRtc(unsigned int timestamp); -int ksceSblNvsReadData(int offset,void* buffer,int size); \ No newline at end of file +int ksceSblNvsReadData(int offset,void* buffer,int size); +int ksceSblNvsWriteData(int offset,void* buffer,int size); \ No newline at end of file diff --git a/kern/rtcKernelBridge.h b/kern/rtcKernelBridge.h index d1712b5..c67aa80 100644 --- a/kern/rtcKernelBridge.h +++ b/kern/rtcKernelBridge.h @@ -2,4 +2,5 @@ int ksilRtcSetCurrentTick(unsigned int timestamp1, unsigned int timestamp2); int ksilRtcSetCurrentNetworkTick(unsigned int timestamp1, unsigned int timestamp2); int ksilRtcSetCurrentSecureTick(unsigned int timestamp1, unsigned int timestamp2); int ksilSblPostSsMgrSetCpRtc(unsigned int timestamp); -int ksilDumpNvsAct(unsigned int fileno); \ No newline at end of file +int ksilDumpNvsAct(unsigned int fileno); +int ksilRestoreNvsAct(unsigned int fileno); \ No newline at end of file diff --git a/user/exports.yml b/user/exports.yml index bfcba60..31ec936 100644 --- a/user/exports.yml +++ b/user/exports.yml @@ -15,3 +15,4 @@ user_clockset: - silRtcSetCurrentSecureTick - silSblPostSsMgrSetCpRtc - silDumpNvsAct + - silRestoreNvsAct \ No newline at end of file diff --git a/user/rtcKernelBridge.h b/user/rtcKernelBridge.h index d1712b5..c67aa80 100644 --- a/user/rtcKernelBridge.h +++ b/user/rtcKernelBridge.h @@ -2,4 +2,5 @@ int ksilRtcSetCurrentTick(unsigned int timestamp1, unsigned int timestamp2); int ksilRtcSetCurrentNetworkTick(unsigned int timestamp1, unsigned int timestamp2); int ksilRtcSetCurrentSecureTick(unsigned int timestamp1, unsigned int timestamp2); int ksilSblPostSsMgrSetCpRtc(unsigned int timestamp); -int ksilDumpNvsAct(unsigned int fileno); \ No newline at end of file +int ksilDumpNvsAct(unsigned int fileno); +int ksilRestoreNvsAct(unsigned int fileno); \ No newline at end of file diff --git a/user/user_clockset.c b/user/user_clockset.c index 9e10f36..23172c6 100644 --- a/user/user_clockset.c +++ b/user/user_clockset.c @@ -31,7 +31,11 @@ int silDumpNvsAct(unsigned int fileno) { return ksilDumpNvsAct(fileno); } - +int silRestoreNvsAct(unsigned int fileno) +{ + return ksilRestoreNvsAct(fileno); +} +void _start() __attribute__ ((weak, alias ("module_start"))); int module_start(SceSize argc, const void *args) { return SCE_KERNEL_START_SUCCESS; }