mirror of
				https://github.com/Thesola10/umd-livepatch.git
				synced 2025-08-09 22:02:02 +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