mirror of
https://github.com/Thesola10/umd-livepatch.git
synced 2025-04-20 06:23:22 +00:00
obtained disc ID on insert
This commit is contained in:
parent
cd6d4822fa
commit
dca4cf09f4
2
Makefile
2
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
|
||||
|
94
io_funcs.c
Normal file
94
io_funcs.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include "io_funcs.h"
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
65
io_funcs.h
Normal file
65
io_funcs.h
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef __IO_FUNCS_H
|
||||
#define __IO_FUNCS_H
|
||||
|
||||
#include <pspkernel.h>
|
||||
#include <systemctrl.h>
|
||||
|
||||
/*
|
||||
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
|
28
main.c
28
main.c
@ -10,14 +10,13 @@
|
||||
* without requiring a dump.
|
||||
*/
|
||||
|
||||
#include <pspkernel.h>
|
||||
#include <systemctrl.h>
|
||||
#include "io_funcs.h"
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
124
patch_syscall.c
124
patch_syscall.c
@ -1,124 +0,0 @@
|
||||
#include <pspkernel.h>
|
||||
#include <pspdisplay_kernel.h>
|
||||
#include <pspsysmem_kernel.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <systemctrl.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user