fixit98
Experte
Beiträge: 610
Gruppe: User
Registriert seit: Nov 2009
Status:
Abwesend
Danke erhalten: 525
|
RE: Plugins an 6.XX Kernel anpassen
Btw: Würde der hier funken? Ist von dridri
isoloader.c
#include <pspiofilemgr.h>
#include "isoloader.h"
#include "debug.h"
void print_to_screen(char*);
void mysprintf1(char *xobuff, const char *xifmt, u32 xidata);
int realKernelLoadModule(const char*, int, void*);
int realKernelStartModule(SceUID, int, void*, int*, void*);
int realKernelQueryModuleInfo(SceUID, void*);
//#define ISO_FILE "ms0:/ISO/wipeoutpulse.iso"
#define ISO_PATH "ms0:/ISO/wipeoutpulse"
int ExtractFile(const char* _src, const char* dst);
void PatchModuleStart();
void prePatch();
void doPatch();
int iso_module_start(int args, void* argp);
ISO* iso = NULL;
SceUID IsoFd;
SceUID modid;
u32 text_addr;
int realIoOpen(const char* _file, int mode, int rights);
int realIoDopen(const char* _dir);
int realIoMkdir(const char* dir, SceMode mode);
int realIoRmdir(const char *dir);
int realIoDevctl(const char* dev, unsigned int cmd, void* indata, int inlen, void* outdata, int outlen);
int realIoGetstat(const char* file, SceIoStat* stat);
int realIoRemove(const char* file);
u32 IoOpen = 0x0;
u32 IoDopen = 0x0;
u32 IoMkdir = 0x0;
u32 IoRmdir = 0x0;
u32 IoDevctl = 0x0;
u32 IoGetstat = 0x0;
u32 IoRemove = 0x0;
u32 KernelLoadModule = 0x0;
void run_iso(){
get_call_nidtable(0x977DE386, &((u32*)realKernelLoadModule)[1]);
get_call_nidtable(0x50F0C1EC, &((u32*)realKernelStartModule)[1]);
get_call_nidtable(0x748CBED9, &((u32*)realKernelQueryModuleInfo)[1]);
SceUID mod_fd = sceIoOpen("ms0:/ISO/wipeoutpulse/PSP_GAME/SYSDIR/EBOOT_dec.BIN", PSP_O_RDONLY, 777);
GetModuleInfo(mod_fd);
GetModuleImports(mod_fd);
sceIoClose(mod_fd);
struct SceKernelLMOption option;
memset((void*)&option, 0x0, sizeof(struct SceKernelLMOption));
option.size = sizeof(struct SceKernelLMOption);
option.mpidtext = 2;
option.mpiddata = 2;
option.access = 1;
modid = realKernelLoadModule("ms0:/ISO/wipeoutpulse/PSP_GAME/SYSDIR/EBOOT.BIN", 0, &option);
LOGSTR1("realKernelLoadModule returned 0x%08lX\n", modid);
char txt[128] = "";
mysprintf1(txt, "realKernelLoadModule returned 0x%08lX", modid);
print_to_screen(txt);
PatchModuleStart();
realKernelStartModule(modid, sizeof("disc0:/PSP_GAME/SYSDIR/EBOOT.BIN"), "disc0:/PSP_GAME/SYSDIR/EBOOT.BIN", 0, NULL);
sceKernelExitDeleteThread(0);
return;
}
char real_path[512] = "";
int sceIoOpenPatched(const char* _file, int mode, int rights){
char* file = (char*)_file;
// LOGSTR3("sceIoOpenPatched(\"%s\", %d, %d)\n", (int)file, mode, rights);
if(file[0] == 'd'){
file = file + 6;
strcpy(real_path, ISO_PATH);
strcat(real_path, file);
file = real_path;
}
// LOGSTR3("realIoOpen(\"%s\", %d, %d)\n", (int)file, mode, rights);
return realIoOpen(file, mode, rights);
}
int sceIoDopenPatched(const char* _dir){
char* dir = (char*)_dir;
// LOGSTR1("sceIoDopenPatched(\"%s\")\n", (int)dir);
if(dir[0] == 'd'){
dir = dir + 6;
strcpy(real_path, ISO_PATH);
strcat(real_path, dir);
dir = real_path;
}
// LOGSTR1("realIoDopen(\"%s\")\n", (int)dir);
return realIoDopen(dir);
}
int sceIoMkdirPatched(const char* dir, SceMode mode){
// LOGSTR2("realIoMkdir(\"%s\", %d)\n", (int)dir, mode);
return realIoMkdir(dir, mode);
}
int sceIoRmdirPatched(const char *dir){
// LOGSTR1("realIoRmdir(\"%s\")\n", (int)dir);
return realIoRmdir(dir);
}
int sceIoDevctlPatched(const char* dev, unsigned int cmd, void* indata, int inlen, void* outdata, int outlen){
// LOGSTR8("realIoDevctl(\"%s\", 0x%08lX, 0x%08lX, %d, 0x%08lX, %d)\n", (int)dev, cmd, (int)indata, inlen, (int)outdata, outlen, 0, 0);
return realIoDevctl(dev, cmd, indata, inlen, outdata, outlen);
}
int sceIoGetstatPatched(const char* _file, SceIoStat* stat){
char* file = (char*)_file;
// LOGSTR2("sceIoGetstatPatched(\"%s\", 0x%08lX)\n", (int)file, (u32)stat);
if(file[0] == 'd'){
file = file + 6;
strcpy(real_path, ISO_PATH);
strcat(real_path, file);
file = real_path;
}
// LOGSTR2("realIoGetstat(\"%s\", 0x%08lX)\n", (int)file, (u32)stat);
return realIoGetstat(file, stat);
}
int sceIoRemovePatched(const char* file){
// LOGSTR1("realIoRemove(\"%s\")\n", (int)file);
return realIoRemove(file);
}
int sceKernelLoadModulePatched(const char* _path, int flags, SceKernelLMOption* option){
char* path = (char*)_path;
// LOGSTR3("sceKernelLoadModulePatched(\"%s\")\n", (int)path, flags, (int)option);
if(path[0] == 'd'){
path = path + 6;
strcpy(real_path, ISO_PATH);
strcat(real_path, path);
path = real_path;
}
// LOGSTR3("realKernelLoadModule(\"%s\")\n", (int)path, flags, (int)option);
return realKernelLoadModule(path, flags, option);
}
int (*real_module_start)(int, void*) = NULL;
u32 module_start_d0;
u32 module_start_d1;
void PatchModuleStart(){
// text_addr is always the same
text_addr = 0x08807C00;
LOGSTR1("iso.text_addr = 0x%08lX\n", text_addr);
real_module_start = (void*)text_addr + 0x00000000;
module_start_d0 = ((u32*)real_module_start)[0];
module_start_d1 = ((u32*)real_module_start)[1];
// patch the 2 first opcodes by a jump to my iso_module_start
((u32*)real_module_start)[0] = MAKE_JUMP(iso_module_start);
((u32*)real_module_start)[1] = 0x00000000;
prePatch();
}
void prePatch(){
IoOpen = FindImport(text_addr, "IoFileMgrForUser", 0x109F50BC);
IoDopen = FindImport(text_addr, "IoFileMgrForUser", 0xB29DDF9C);
IoMkdir = FindImport(text_addr, "IoFileMgrForUser", 0x06A70004);
IoRmdir = FindImport(text_addr, "IoFileMgrForUser", 0x1117C65F);
IoDevctl = FindImport(text_addr, "IoFileMgrForUser", 0x54F5FB11);
IoGetstat = FindImport(text_addr, "IoFileMgrForUser", 0xACE946E8);
IoRemove = FindImport(text_addr, "IoFileMgrForUser", 0xF27A9C51);
KernelLoadModule = FindImport(text_addr, "ModuleMgrForUser", 0x977DE386);
}
int iso_module_start(int args, void* argp){
// Get the real syscalls
if(((u32*)realIoOpen)[1] == 0x0){
((u32*)realIoOpen)[1] = ((u32*)IoOpen)[1];
((u32*)realIoDopen)[1] = ((u32*)IoDopen)[1];
((u32*)realIoMkdir)[1] = ((u32*)IoMkdir)[1];
((u32*)realIoRmdir)[1] = ((u32*)IoRmdir)[1];
((u32*)realIoDevctl)[1] = ((u32*)IoDevctl)[1];
((u32*)realIoGetstat)[1] = ((u32*)IoGetstat)[1];
((u32*)realIoRemove)[1] = ((u32*)IoRemove)[1];
((u32*)realKernelLoadModule)[1] = ((u32*)KernelLoadModule)[1];
}
// Then patch them
_sw(MAKE_JUMP(sceIoOpenPatched), IoOpen); _sw(0x00000000, IoOpen+4);
_sw(MAKE_JUMP(sceIoDopenPatched), IoDopen); _sw(0x00000000, IoDopen+4);
_sw(MAKE_JUMP(sceIoMkdirPatched), IoMkdir); _sw(0x00000000, IoMkdir+4);
_sw(MAKE_JUMP(sceIoRmdirPatched), IoRmdir); _sw(0x00000000, IoRmdir+4);
_sw(MAKE_JUMP(sceIoDevctlPatched), IoDevctl); _sw(0x00000000, IoDevctl+4);
_sw(MAKE_JUMP(sceIoGetstatPatched), IoGetstat); _sw(0x00000000, IoGetstat+4);
_sw(MAKE_JUMP(sceIoRemovePatched), IoRemove); _sw(0x00000000, IoRemove+4);
_sw(MAKE_JUMP(sceKernelLoadModulePatched), KernelLoadModule); _sw(0x00000000, KernelLoadModule+4);
// Restore the two first opcodes
((u32*)real_module_start)[0] = module_start_d0;
((u32*)real_module_start)[1] = module_start_d1;
return real_module_start(args, argp);
}
static int n_alloc = 0;
static int n_free = 0;
void* geMalloc(int size){
n_alloc++;
u32 id = sceKernelAllocPartitionMemory(2, "alloc", 0, size+8, NULL);
u32* var = (u32*)sceKernelGetBlockHeadAddr(id);
var[0] = id; //Store the ID in the first byte
var[1] = size; //Store the size on the 2nd byte
return var+8; //Then return block +2 (id + size)
}
void geFree(void* data){
n_free++;
u32* var
void* geRealloc(void* last, int size){
u32 old_size = ((u32*)last)[1]; //The size is stored in the 2nd byte
u32* new_ptr = (u32*)geMalloc(size); //Do a geMalloc with new size
memcpy(new_ptr, ((u32*)last), old_size); //Copy the lod data
geFree(last); //geFree the last block
return new_ptr; //Then return the new pointer
}
isoloader.h
#include <pspkernel.h>
#include <pspiofilemgr.h>
#include <stdio.h>
#include <stdarg.h>
#include "isomodule.h"
typedef struct Directory {
int level;
char name[128];
char path[1024];
} Directory;
typedef struct File {
char path[1024];
char name[256];
u32 addr;
u32 size;
PspIoDrvFileArg* arg;
int fd;
int seek_cur;
} File;
typedef struct ISO {
char filename[2048];
char name[256];
Directory* dirs;
File* files;
int nDirs;
int nFiles;
} ISO;
ISO* IsoLoad(SceUID fd);
File* IsoGetFile(ISO* iso, const char* filename);
void GetModuleInfo(SceUID fd);
void GetModuleImports(SceUID fd);
u32 FindImport(u32 text_addr, const char* lib, u32 nid);
void PatchImport(u32 text_addr, const char* lib, u32 nid, u32 patch);
void* geMalloc(int size);
void geFree(void* data);
void* geRealloc(void* last, int size);
void DebugPrint(const char *format, ...);
isoimports.s
.macro AddImp funcname
.globl \funcname
.ent \funcname
\funcname:
jr $ra
nop
.end \funcname
.endm
.file 1 "isoimports.c"
.section .mdebug.eabi32
.section .gcc_compiled_long32
.previous
.text
.align 2
AddImp sceKernelLoadExec
AddImp realKernelLoadModule
AddImp realKernelLoadModuleMs
AddImp realKernelStartModule
AddImp realKernelQueryModuleInfo
AddImp realIoOpen
AddImp realIoDopen
AddImp realIoMkdir
AddImp realIoRmdir
AddImp realIoDevctl
AddImp realIoGetstat
AddImp realIoRemove
.ident "ISO-SDK"
isodriver.c
#include <pspkernel.h>
#include <pspiofilemgr.h>
#include <stdio.h>
#include "isoloader.h"
#include "debug.h"
int CopyTextToFormatedText(const char* src, char* out, int max);
void UpDir(char* path);
void CheckPath(Directory* dirs, int j);
ISO* IsoLoad(SceUID fd){
if(fd<0)return NULL;
int levels[64] = { 0 };
ISO* iso = (ISO*)geMalloc(sizeof(ISO));
Directory* dirs = (Directory*)geMalloc(sizeof(Directory)*64);
memset(dirs, 0, sizeof(Directory)*64);
File* files = (File*)geMalloc(sizeof(File)*256);
int i=0, j=0, k=0, a=0, len=0, nFiles=0, pos=0, size=0;
char name[256], path[1024];
char* buffer = (char*)geMalloc(sizeof(char)*4096);
memset(buffer, 0, 4096);
//Get CD Name
sceIoLseek(fd, 0x8000, PSP_SEEK_SET);
sceIoRead(fd, buffer, 128);
CopyTextToFormatedText(strstr(buffer, "CD001")+7, iso->name, 128);
//Get Dirs
memset(buffer, 0, 4096);
i = 0x9010;
while(buffer[0]==0){
sceIoLseek(fd, i, PSP_SEEK_SET);
sceIoRead(fd, buffer, 1024);
i += 0x0800;
}
for(i=0, j=0; i<1024;){
memset(levels, 0, sizeof(int)*64);
dirs[j].level = buffer[i];
len = CopyTextToFormatedText(buffer+i+2, dirs[j].name, 256);
CheckPath(dirs, j);
i += (8 + len);
for(i=i;((i<1024)&&(buffer[i]==0));i++);
j++;
if(buffer[i]+buffer[i+1]+buffer[i+2]+buffer[i+3]+buffer[i+4]+buffer[i+5]+buffer[i+6]+buffer[i+7]==0)break;
}
iso->dirs = dirs;
iso->nDirs = j;
//Get Files
j = 0;
k = 0xB010;
// LOGSTR0("Files list :\n");
while(1){
i = 0x70;
pos = size = 0;
sceIoLseek(fd, k, PSP_SEEK_SET);
sceIoRead(fd, buffer, 1024);
if(buffer[0]!=0x08)break;
while(1){
len = CopyTextToFormatedText(buffer+i+1, name, 256);
for(a=(i+1+len); buffer[a]==0; a++);
if(buffer[a]==0x0d){
if(j>0){
strcpy(path, dirs[j-1].path);
strcat(path, name);
}else{
strcpy(path, "/");
strcat(path, name);
}
pos = ((u8)buffer[i-30] | (u8)buffer[i-29]<<8 | (u8)buffer[i-28]<<16 | (u8)buffer[i-27]<<24) * 2048;
size = ((u8)buffer[i-22] | (u8)buffer[i-21]<<8 | (u8)buffer[i-20]<<16 | (u8)buffer[i-19]<<24);
files[nFiles].addr = pos;
files[nFiles].size = size;
files[nFiles].fd = ((int)name - size + (int)path);
strcpy(files[nFiles].name, name);
strcpy(files[nFiles].path, path);
// LOGSTR1(" \"%s\"\n", (int)files[nFiles].path);
nFiles++;
}else if((u8)buffer[a]==0x8d){
}
i += ((a-i)+42);
if(buffer[i]+buffer[i+1]+buffer[i+2]+buffer[i+3]+buffer[i+4]+buffer[i+5]+buffer[i+6]+buffer[i+7]==0)break;
}
if(/*(k>=0xC9B0)||*/(j>iso->nDirs))break;
k += 0x0800;
j++;
}
iso->files = files;
iso->nFiles = nFiles;
geFree(buffer);
return iso;
}
File* IsoGetFile(ISO* iso, const char* filename){
int i = 0;
for(i=0; i<iso->nFiles; i++){
if(!strcmp(filename, iso->files[i].path)){
return &iso->files[i];
}
}
return (File*)0x80010002;
}
int GetParent(Directory* dirs, int j){
return dirs[j].level-2;
}
void CheckPath(Directory* dirs, int j){
char DIRS[256][64] = { "" };
int i=j, parent=j, k=0;
while(i>=0){
i = parent;
parent = GetParent(dirs, i);
strcpy(DIRS[k], dirs[i].name);
k++;
}
memset(dirs[j].path, 0, 1024);
strcpy(dirs[j].path, "/");
for(k=k-2; k>=0; k--){
strcat(dirs[j].path, DIRS[k]);
strcat(dirs[j].path, "/");
}
}
void UpDir(char* path){
int i = 0;
for(i=strlen(path); i>=0; i--){
if((i!=(int)strlen(path))&&(path[i]=='/'))break;
path[i] = 0;
}
}
int CopyTextToFormatedText(const char* src, char* out, int max){
memset(out, 0, max);
int i = 0;
int len = 0;
for(i=0; ((i<max)&&(i<(int)strlen(src))); i++){
if((src[i]==0) || (src[i]<=0x07) || (src[i]==0x20 && src[i+1]==0x20 && src[i+2]==0x20 && src[i+3]==0x20)){
break;
}
out[i] = src[i];
len++;
}
return len;
}
|
|