From dca4cf09f4c7c948490ac0996b95300514b7c3fc Mon Sep 17 00:00:00 2001 From: TheSola10 Date: Wed, 2 Apr 2025 14:41:22 +0200 Subject: [PATCH] obtained disc ID on insert --- Makefile | 2 +- io_funcs.c | 94 ++++++++++++++++++++++++++++++++++++ io_funcs.h | 65 +++++++++++++++++++++++++ main.c | 28 +++-------- patch_syscall.c | 124 ------------------------------------------------ 5 files changed, 166 insertions(+), 147 deletions(-) create mode 100644 io_funcs.c create mode 100644 io_funcs.h delete mode 100644 patch_syscall.c diff --git a/Makefile b/Makefile index c5e8c6e..62f8c4b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ TARGET = umd_livepatch -C_OBJS = main.o +C_OBJS = io_funcs.o main.o OBJS = $(C_OBJS) imports.o all: $(TARGET).prx INCDIR = $(ARKROOT)/common/include $(ARKROOT)/core/systemctrl/include diff --git a/io_funcs.c b/io_funcs.c new file mode 100644 index 0000000..bb04678 --- /dev/null +++ b/io_funcs.c @@ -0,0 +1,94 @@ +#include "io_funcs.h" +#include + +extern PspIoDrvFuncs reserveUmdFuncs; + +static char umd_id[11] = {0}; + +static char first_read = 1; + +static char hdr[ISO_SECTOR_SIZE]; + +static inline u32 +_impl_lp_lbaToAddr(struct LbaParams *param) +{ + u32 offset; + + if (!param->byte_size_start) { + offset = param->lba_top * ISO_SECTOR_SIZE; + } else if (param->byte_size_centre) { + offset = param->lba_top * ISO_SECTOR_SIZE - param->byte_size_start + ISO_SECTOR_SIZE; + } else if (!param->byte_size_last) { + offset = param->lba_top * ISO_SECTOR_SIZE + param->byte_size_start; + } else { + offset = param->lba_top * ISO_SECTOR_SIZE - param->byte_size_start + ISO_SECTOR_SIZE; + } + + return offset; +} + +static inline int +_impl_lp_readDiscHeader(PspIoDrvFileArg *arg, const char *devname, void *outdata) +{ + int ret; + + struct LbaParams param = { + .unknown1 = 0, + .cmd = 0, /* read */ + .lba_top = 0x8000 / ISO_SECTOR_SIZE, + .lba_size = 1, + .byte_size_total = ISO_SECTOR_SIZE, + .byte_size_centre = ISO_SECTOR_SIZE, + .byte_size_start = 0, + .byte_size_last = 0 + }; + + ret = reserveUmdFuncs.IoDevctl(arg, devname, lp_UmdIoctl_READ_SECTORS, + ¶m, sizeof param, outdata, ISO_SECTOR_SIZE); + return ret; +} + + +static int +_impl_lp_devctlRead(PspIoDrvFileArg *arg, const char *devname, + unsigned int cmd, struct LbaParams *param, int inlen, + void *outdata, int outlen) +{ + u32 offset = _impl_lp_lbaToAddr(param); + int ret; + + if (first_read) { + ret = reserveUmdFuncs.IoDevctl(arg, devname, cmd, param, inlen, outdata, outlen); + + _impl_lp_readDiscHeader(arg, devname, &hdr); + strncpy(umd_id, hdr + 0x373, 10); + umd_id[10] = 0; + Kprintf("Disc ID obtained: '%s'\n", umd_id); + + first_read = 0; + + return ret; + } + +passthru: + return reserveUmdFuncs.IoDevctl(arg, devname, cmd, param, inlen, outdata, outlen); +} + +int +patched_IoDevctl(PspIoDrvFileArg *arg, const char *devname, + unsigned int cmd, void *indata, int inlen, + void *outdata, int outlen) +{ + switch ((lp_UmdIoctl) cmd) { + case lp_UmdIoctl_READ_GENERAL: + case lp_UmdIoctl_READ_CACHE: + case lp_UmdIoctl_READ_SECTORS: + return _impl_lp_devctlRead(arg, devname, cmd, (struct LbaParams *) indata, + inlen, outdata, outlen); + default: + goto passthru; + } + +passthru: + return reserveUmdFuncs.IoDevctl(arg, devname, cmd, indata, inlen, outdata, outlen); +} diff --git a/io_funcs.h b/io_funcs.h new file mode 100644 index 0000000..1ac55c8 --- /dev/null +++ b/io_funcs.h @@ -0,0 +1,65 @@ +#ifndef __IO_FUNCS_H +#define __IO_FUNCS_H + +#include +#include + +/* + UMD access RAW routine + + lba_param[0] = 0 , unknown + lba_param[1] = cmd,3 = ctrl-area , 0 = data-read + lba_param[2] = top of LBA + lba_param[3] = total LBA size + lba_param[4] = total byte size + lba_param[5] = byte size of center LBA + lba_param[6] = byte size of start LBA + lba_param[7] = byte size of last LBA + */ + +typedef enum: int { + lp_UmdIoctl_01F00003 = 0x01F00003, + lp_UmdIoctl_01F010DB = 0x01F010DB, + + lp_UmdIoctl_DISC_TYPE = 0x01F20001, + lp_UmdIoctl_SEEK_RAW = 0x01F100A3, + lp_UmdIoctl_CACHE_ADD = 0x01F100A4, + lp_UmdIoctl_CACHE_ADD2 = 0x01F300A5, + + /* Cache control, worth intercepting */ + lp_UmdIoctl_01F300A7 = 0x01F300A7, + lp_UmdIoctl_01F300A8 = 0x01F300A8, + lp_UmdIoctl_01F300A9 = 0x01F300A9, + lp_UmdIoctl_NUM_SECTORS = 0x01F20002, + lp_UmdIoctl_NUM_SECTORS2 = 0x01F20003, + lp_UmdIoctl_01E18030 = 0x01E18030, + lp_UmdIoctl_01E180D3 = 0x01E180D3, + lp_UmdIoctl_01E080A8 = 0x01E080A8, + lp_UmdIoctl_GET_SECTOR_BUF = 0x01E28035, + lp_UmdIoctl_GET_SECTOR_SIZE = 0x01E280A9, + lp_UmdIoctl_01E38034 = 0x01E38034, + lp_UmdIoctl_READ_GENERAL = 0x01E380C0, + lp_UmdIoctl_READ_SECTORS = 0x01F200A1, + lp_UmdIoctl_READ_CACHE = 0x01F200A2, + lp_UmdIoctl_GET_INFO = 0x01E38012 +} lp_UmdIoctl; + +struct LbaParams { + int unknown1; // 0 + int cmd; // 4 + int lba_top; // 8 + int lba_size; // 12 + int byte_size_total; // 16 + int byte_size_centre; // 20 + int byte_size_start; // 24 + int byte_size_last; // 28 +}; + +#define ISO_SECTOR_SIZE 2048 + +int +patched_IoDevctl(PspIoDrvFileArg *arg, const char *devname, + unsigned int cmd, void *indata, int inlen, + void *outdata, int outlen); + +#endif //__IO_FUNCS_H diff --git a/main.c b/main.c index 0d70807..573b5bf 100644 --- a/main.c +++ b/main.c @@ -10,14 +10,13 @@ * without requiring a dump. */ -#include -#include +#include "io_funcs.h" #include PSP_MODULE_INFO("umd_livepatch", PSP_MODULE_KERNEL, 2, 1); -int module_found = 0; -int loader_found = 0; + +void lp_patchFunction(u32 addr, void *newaddr, void *fptr); PspIoDrvFuncs reserveUmdFuncs; @@ -43,7 +42,6 @@ PspIoDrv patchedUmdDriver = { #define MAX_MODULE_NUMBER 256 - // Bogus read to test intercepting static int patched_IoRead(PspIoDrvFileArg *arg, char *data, int len) { @@ -73,23 +71,9 @@ int module_start(SceSize argc, void *argp) patchedUmdFuncs = reserveUmdFuncs; - patchedUmdFuncs.IoRead = &patched_IoRead; + umdDriver->funcs->IoRead = patched_IoRead; + umdDriver->funcs->IoDevctl = patched_IoDevctl; - if (ret = sceIoAddDrv(&reserveUmdDriver)) { - Kprintf("Reserve failed: 0x%08x\n", ret); - return ret; - } else { - Kprintf("Reserved previous UMD driver!\n"); - } - - sceIoDelDrv("umd"); - - if (ret = sceIoAddDrv(&patchedUmdDriver)) { - Kprintf("Install failed: 0x%08x\n", ret); - return ret; - } else { - Kprintf("Installed our own UMD driver!\n"); - } return 0; } @@ -100,7 +84,7 @@ int module_stop(void) sceIoAddDrv(&originalUmdDriver); sceIoDelDrv("umdraw"); - Kprintf("Restored original UMD driver.\n"); + Kprintf("Restored original UMD driver\n"); return 0; } diff --git a/patch_syscall.c b/patch_syscall.c deleted file mode 100644 index 0a39ae8..0000000 --- a/patch_syscall.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#define _impl_lp_mkJump$(a, f) _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), a) -#define _impl_lp_mkCall$(a, f) _sw(0x0C000000 | (((u32)(f) >> 2) & 0x03ffffff), a) - -#define _impl_lp_mkRedirect$(a, f) { \ - u32 address = a; \ - _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), address); \ - _sw(0, address+4); \ -} - -void sceDisplaySetBrightness_Patched(int brightness, int unk1) -{ - //Set Brightness here - sceDisplaySetBrightness(brightness, unk1); -} - -u32 lp_findSyscall(const char *modname, const char *lib, u32 nid) -{ - int i = 0, u; - - /* try and find the module by name */ - SceModule *mod = sceKernelFindModuleByName(modname); - - /* if fail */ - if (!mod) - { - /* fail */ - return 0; - } - - /* copy over the structure data */ - u32 entry_size = mod->ent_size; - u32 entry_start = (u32)mod->ent_top; - - /* loop until end of entry table */ - while (i < entry_size) - { - /* cast structure to memory */ - SceLibraryEntryTable *entry = (SceLibraryEntryTable *)(entry_start + i); - - /* if there is a libname, compare it to the lib else if there is no lib and there is no libname */ - if ((entry->libname && (strcmp(entry->libname, lib) == 0)) || (lib == NULL && entry->libname == NULL)) - { - /* copy the table pointer and get the total number of entries */ - u32 *table = entry->entrytable; - int total = entry->stubcount + entry->vstubcount; - - /* if there is some entries continue */ - if (total > 0) - { - /* loop through the entries */ - for (u = 0; u < total; u++) - { - /* if the nid matches */ - if (table[u] == nid) - { - /* return the pointer */ - return table[u + total]; - } - } - } - } - - /* increment the counter */ - i += (entry->len << 2); - } - - /* could not find function */ - return 0; -} - -void lp_patchSyscall(u32 addr, void *newaddr) -{ - u32 *vectors, i; - - /* get the vectors address from the co-processor */ - __asm__ volatile ("cfc0 %0, $12\n" "nop\n" : "=r" (vectors)); - - /* loop through them */ - for (i = 0; i < 0x1000; i++) { - /* if this is the address */ - if (vectors[i + 4] == addr) { - /* then replace it :D */ - vectors[i + 4] = (u32) newaddr; - } - } -} - -void lp_patchFunction(u32 addr, void *newaddr, void *fptr) -{ - static u32 patch_buffer[3]; - _sw(_lw(addr + 0x00), (u32) patch_buffer + 0x00); - _sw(_lw(addr + 0x04), (u32) patch_buffer + 0x08); - _impl_lp_mkJump$((u32) patch_buffer + 0x04, addr + 0x08); - _impl_lp_mkRedirect$(addr, newaddr); - fptr = (void *)patch_buffer; -} - -static void ClearCaches(void) -{ - sceKernelIcacheClearAll(); - sceKernelDcacheWritebackAll(); -} - -static void PatchBrightness(void) -{ - /* find the Brightness module */ - u32 text_addr = lp_findSyscall("sceDisplay_Service", "sceDisplay_driver", 0xFF5A5D52); // 6.20 NID - if (text_addr != 0) { - /* patch the Brightness set */ - lp_patchSyscall(text_addr, sceDisplaySetBrightness_Patched); - /* ok, lets patch it */ - lp_patchFunction(text_addr, sceDisplaySetBrightness_Patched, sceDisplaySetBrightness); - // Clear caches - ClearCaches(); - } -}