Skip to content

Commit

Permalink
rePatch reDux0 release 1
Browse files Browse the repository at this point in the history
  • Loading branch information
dots-tb committed Mar 25, 2018
1 parent 84ba566 commit 5a6de55
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 65 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ target_link_libraries(${PROJECT_NAME}
SceIofilemgrForDriver_stub
SceDebugForDriver_stub
SceSysrootForKernel_stub
SceSblACMgrForDriver_stub
)
vita_create_self(${PROJECT_NAME}.skprx ${PROJECT_NAME}
UNSAFE
Expand Down
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
# How to use:
# rePatch reDux0:

This plugin serves as a substitute for the patch folder when an existing update is present on official cartridges or other encrypted formats. It also has the benefit of loading decrypted content on 3.65.

Official rePatch support discord: https://discord.gg/gPTwn3J
Note: Be wary of using a Vitamin dumped(or similar) eboot, it will be effected by save issues.

Original rePatch: https://github.com/SilicaAndPina/rePatch

3.65 Confirmed working: https://twitter.com/dots_tb/status/972922611536576512

Eboot.bin patching added based off: https://github.com/GabyPCgeeK/rePatch

First install the plugin by adding it to the *KERNEL line
after that create a folder on ux0 called "rePatch"
inside that folder put another folder of the titleid for the game
and in there, simply place the files you want to replace,
it works exactly the same as ux0:patch does on 3.60.
only you dont need the param.sfo file in sce_sys.
# How to use:

1. Install the plugin as any other kernel plugin, being sure to add it to the *KERNEL section of your config.txt.
2. Create the folder ux0:rePatch
3. Create a folder within the rePatch folder with the TITLE ID of the game you wish to patch.
4. Place decrypted content within this TITLE ID folder. Exclude the sce_sys folder.
5. You may delete overlapping files within the original patch folder or app folder to save space.

Developed by SilicaAndPina & dots-tb

Intended to allow you to patch games even if theres an update installed.
Developed by dots-tb & SilicaAndPina
157 changes: 102 additions & 55 deletions repatch.c
Original file line number Diff line number Diff line change
@@ -1,96 +1,143 @@
//
// SilicaTeam 2.0 @dots_tb @SilicaAndPina ‏
// RePatch -- PATCHING WITH FREEDOM
/*
rePatch 1.0 reDux0 -- PATCHING WITH FREEDOM
Brought to you by SilicaTeam 2.0 --
Dev and "reV ur engines" by @dots_tb
with support from @SilicaAndPina and @CelesteBlue123 (especially his """holy grail""")
// Based off ioPlus by @dots_tb: https://github.com/CelesteBlue-dev/PSVita-RE-tools/tree/master/ioPlus/
// GabyPCgeeK for eboot.bin parsing https://github.com/GabyPCgeeK/rePatch/blob/master/repatch.c
Testing team:
AlternateZero
bopz
@IcySon55
DuckySushi
Analog Man
Pingu (@mcdarkjedii)
Radziu
Special thanks to:
VitaPiracy, especially Radziu for shilling it
Motoharu for his RE work on the wiki
TheFlow for creating a need for this plugin
No thanks to:
Coderx3(Banana man)
Based off ioPlus by @dots_tb: https://github.com/CelesteBlue-dev/PSVita-RE-tools/tree/master/ioPlus/
*/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/syslimits.h>
#include <vitasdkkern.h>
#include <taihen.h>

#define printf ksceDebugPrintf
#define MAX_PATH_LEN 128

static int hooks_uid[3];
static tai_hook_ref_t ref_hooks[3];

static int getNewPath(const char *old_path, char *new_path, const char *titleid) {
#define rePatchFolder "ux0:rePatch"

//https://wiki.henkaku.xyz/vita/SceIofilemgr
typedef struct io_scheduler_item //size is 0x14 - allocated from SceIoScheduler heap
{
uint32_t* unk_0; // parent
uint32_t unk_4; // 0
uint32_t unk_8; // 0
uint32_t unk_C; // 0
uint32_t unk_10; // pointer to unknown module data section
} io_scheduler_item;


static int getNewPath(const char *old_path, char *new_path, SceUID pid, size_t maxPath, int opt) {
char *old_path_file = strchr(old_path, ':') + 1;
if(old_path_file[0] == '/')
old_path_file++;
if(titleid != NULL)
snprintf(new_path, MAX_PATH_LEN, "ux0:/rePatch/%s/%s",titleid,old_path_file);
else {
if(opt) {
char titleid[32];
if(ksceKernelGetProcessTitleId(pid, titleid, sizeof(titleid))<0)
return 0;
snprintf(new_path, maxPath, rePatchFolder"/%s/%s",titleid,old_path_file);
} else {
if((old_path_file = strchr(old_path_file, '/'))==NULL)
return 0;
snprintf(new_path, MAX_PATH_LEN, "ux0:/rePatch%s",old_path_file);
snprintf(new_path, maxPath, rePatchFolder"%s",old_path_file);
}
return 1;
SceIoStat k_stat;
if(ksceIoGetstat(new_path, &k_stat)<0)
return 0;
int len = strnlen(new_path, maxPath);
if(len < maxPath)
return len;
return 0;
}

static int ksceIoOpenForPid_patched(SceUID pid, const char *filename, int flag, SceIoMode mode) {
static char *confirmPatch(const char *filename) { //For future support of future things.
char *old_path_file = strchr(filename, ':') + 1;
if(old_path_file[0] == '/')
old_path_file++;
if(memcmp(old_path_file,"patch",sizeof("patch")-1)==0
||memcmp(old_path_file,"app",sizeof("app")-1)==0)
return old_path_file;
return 0;
}

static int sceFiosKernelOverlayResolveSyncForDriver_patched(SceUID pid, int resolveFlag, const char *pInPath, char *pOutPath, size_t maxPath) {
int ret = -1, state;
ENTER_SYSCALL(state);
if (memcmp("app0:", filename, sizeof("app0:") - 1)==0) {
char new_path[MAX_PATH_LEN];
char titleid[32];
SceIoStat k_stat;
if((ret = ksceKernelGetProcessTitleId(pid, titleid, sizeof(titleid)))>-1){
getNewPath(filename, new_path, titleid);
if((ret=ksceIoGetstat(new_path, &k_stat))>-1)
ret = ksceIoOpen(new_path, flag, mode);
}
}
if(ret < 0) ret = TAI_CONTINUE(int, ref_hooks[0], pid, filename, flag, mode);
if (memcmp("app0:", pInPath, sizeof("app0:") - 1)==0 && getNewPath(pInPath, pOutPath, pid, maxPath, 1))
ret = 0;
if(ret < 0)ret = TAI_CONTINUE(int, ref_hooks[0], pid, resolveFlag, pInPath, pOutPath, maxPath);
EXIT_SYSCALL(state);
return ret;
}
static int _sceIoGetstat_patched(const char *file, SceIoStat *stat, int r2) {

static char newPath[PATH_MAX];
static int ksceIoOpen_patched(const char *filename, int flag, SceIoMode mode) {
int ret = -1, state;
SceIoStat k_stat;
char filename[MAX_PATH_LEN];
ksceKernelStrncpyUserToKernel(&filename, (uintptr_t)file, sizeof(filename));
ENTER_SYSCALL(state);
if (memcmp("app0:", filename, sizeof("app0:") - 1)==0) {
char new_path[MAX_PATH_LEN];
char titleid[32];
if((ret = ksceKernelGetProcessTitleId( ksceKernelGetProcessId(), titleid, sizeof(titleid)))>-1) {
getNewPath(filename, new_path, titleid);
ret = ksceIoGetstat(new_path, &k_stat);
if(ret > -1)
ksceKernelMemcpyKernelToUser((uintptr_t)stat, &k_stat, sizeof(k_stat));
if((flag&SCE_O_WRONLY) != SCE_O_WRONLY && ksceSblACMgrIsShell(0)) {
if(confirmPatch(filename) && strstr(filename, "/eboot.bin")!=NULL) {
if(getNewPath(filename, newPath, 0, sizeof(newPath), 0))
ret = TAI_CONTINUE(int, ref_hooks[1], newPath, flag, mode);
}
}
if(ret < 0) ret = TAI_CONTINUE(int, ref_hooks[1], file, stat, r2);
}
if(ret <= 0) ret = TAI_CONTINUE(int, ref_hooks[1], filename, flag, mode);
EXIT_SYSCALL(state);
return ret;
}

static int ksceIoOpen_patched(const char *filename, int flag, SceIoMode mode) {
int ret = -1, state;
char new_path[MAX_PATH_LEN];
SceIoStat k_stat;
char titleid[32];

static int io_item_thing_patched(io_scheduler_item *item, int r1) {
int ret, state;
ENTER_SYSCALL(state);
if((flag&SCE_O_WRONLY) != SCE_O_WRONLY&&strstr(filename, "/eboot.bin") != NULL) {
ksceKernelGetProcessTitleId(ksceKernelGetProcessId(), titleid, sizeof(titleid));
if(memcmp("main", titleid, sizeof("main") - 1)==0&&getNewPath(filename, new_path, NULL)) {
if(ksceIoGetstat(new_path, &k_stat)>-1)
ret = TAI_CONTINUE(int, ref_hooks[2], new_path, flag, mode);
}
}
if(ret <= 0) ret = TAI_CONTINUE(int, ref_hooks[2], filename, flag, mode);
ret = TAI_CONTINUE(int, ref_hooks[2], item, r1);
if(ret == 0x80010013 &&item->unk_10 == 0x800) {
item->unk_10 = 1;
//ret = TAI_CONTINUE(int, ref_hooks[1], item, r1);
}
EXIT_SYSCALL(state);
return ret;
}

void _start() __attribute__ ((weak, alias ("module_start")));

int module_start(SceSize argc, const void *args) {
hooks_uid[0] = taiHookFunctionExportForKernel(KERNEL_PID, &ref_hooks[0], "SceIofilemgr", TAI_ANY_LIBRARY, 0xC3D34965, ksceIoOpenForPid_patched);
hooks_uid[1] = taiHookFunctionExportForKernel(KERNEL_PID, &ref_hooks[1], "SceIofilemgr", TAI_ANY_LIBRARY, 0x8E7E11F2, _sceIoGetstat_patched);
hooks_uid[2] = taiHookFunctionImportForKernel(KERNEL_PID, &ref_hooks[2], "SceKernelModulemgr", TAI_ANY_LIBRARY, 0x75192972, ksceIoOpen_patched);
hooks_uid[0] = taiHookFunctionExportForKernel(KERNEL_PID, &ref_hooks[0], "SceFios2Kernel", TAI_ANY_LIBRARY, 0x0F456345, sceFiosKernelOverlayResolveSyncForDriver_patched);
hooks_uid[1] = taiHookFunctionImportForKernel(KERNEL_PID, &ref_hooks[1], "SceKernelModulemgr", TAI_ANY_LIBRARY, 0x75192972, ksceIoOpen_patched);

tai_module_info_t tai_info;
tai_info.size = sizeof(tai_module_info_t);
taiGetModuleInfoForKernel(KERNEL_PID, "SceIofilemgr", &tai_info);

switch(tai_info.module_nid) {
case 0xA96ACE9D://3.65
hooks_uid[2] = taiHookFunctionOffsetForKernel(KERNEL_PID, &ref_hooks[2], tai_info.modid, 0, 0xb3d8, 1, io_item_thing_patched);
break;
case 0x9642948C://3.60
hooks_uid[2] = taiHookFunctionOffsetForKernel(KERNEL_PID, &ref_hooks[2], tai_info.modid, 0, 0xd400, 1, io_item_thing_patched);
break;
}
return SCE_KERNEL_START_SUCCESS;
}

Expand All @@ -99,4 +146,4 @@ int module_stop(SceSize argc, const void *args) {
if (hooks_uid[1] >= 0) taiHookReleaseForKernel(hooks_uid[1], ref_hooks[1]);
if (hooks_uid[2] >= 0) taiHookReleaseForKernel(hooks_uid[2], ref_hooks[2]);
return SCE_KERNEL_STOP_SUCCESS;
}
}

0 comments on commit 5a6de55

Please sign in to comment.