 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
ixalon
Joined: 17 Jul 2006 Posts: 6
|
Posted: Sun Jul 06, 2008 6:09 am Post subject: Patching SceHttp_Library |
|
|
Hi guys,
I'm pulling my hair out trying to patch an export in SceHttp_Library (libhttp.prx) from a kernel mode PRX.
libhttp.prx loads, I run through the nidtable and replace the function pointer with one to my PRX's version. All seems good.
However, when I fire up VSH and try the internet browser, it just displays the 'busy' blob for a few seconds and I'm just left in the XMB with no exceptions being shown over psplink
Anyone know what's going on? The trigger for this seems loading libhttp.prx as even when I don't patch its exports the same thing happens. If I don't load libhttp.prx the browser opens correctly.
Hope someone can enlighten me to my probably silly mistake!
Chris
| Code: | #include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
PSP_MODULE_INFO("httppatch", PSP_MODULE_KERNEL, 1, 1);
void Debug(char *msg) {
printf(msg);
int hFile;
hFile = sceIoOpen("ms0:/debug.txt", PSP_O_CREAT|PSP_O_APPEND|PSP_O_WRONLY, 0777);
sceIoWrite(hFile, msg, sizeof(msg));
sceIoClose(hFile);
}
int snprintf(char *a, size_t b, const char * c, ...) {
return 0;
}
typedef int (*sceHttpCreateTemplate_Delegate)(char *agent, int unknown1, int unknown2);
sceHttpCreateTemplate_Delegate sceHttpCreateTemplate_Orig = 0;
int ixHttpCreateTemplate(char *agent, int unknown1, int unknown2)
{
char buf[100];
sprintf(buf, "sceHttpCreateTemplate(%s, %d, %d)\n", agent, unknown1, unknown2);
Debug(buf);
return (*sceHttpCreateTemplate_Orig)(agent, unknown1, unknown2);
}
void* patchNIDTable(SceModule *mod, char* lib, char* func, void *newProcAddr) {
u32* ent_next = (u32*)mod->ent_top;
u32* ent_end = (u32*)mod->ent_top + (mod->ent_size >> 2);
u32 nid = libsNameToNid(func);
while (ent_next < ent_end)
{
SceLibraryEntryTable* ent = (SceLibraryEntryTable*)ent_next;
if (ent->libname && strcmp(ent->libname, lib) == 0)
{
int count = ent->stubcount + ent->vstubcount;
u32* nidtable = (u32*)ent->entrytable;
int i;
for (i = 0; i < count; i++)
{
if (nidtable[i] == nid)
{
u32* procAddr =(u32*)nidtable[count+i];
if (newProcAddr) {
nidtable[count+i] = (u32)newProcAddr;
}
return procAddr;
}
}
return 0;
}
ent_next += ent->len; // len in 32-bit words.
}
return 0;
}
void LoadAndStart(char *lib, int w) {
printf("Loading and starting %s... ", lib);
int result = pspSdkLoadStartModule(lib, w);
printf("Done (%08x)\n", result);
}
int main_thread(SceSize args, void *argp)
{
sceKernelDelayThread(10*100000);
printf("main_thread running...\n");
// load libraries
//pspSdkInstallKernelLoadModulePatch(); // causes crash
pspSdkInstallNoDeviceCheckPatch();
pspSdkInstallNoPlainModuleCheckPatch();
printf("loading libs...\n");
LoadAndStart("flash0:/kd/ifhandle.prx", PSP_MEMORY_PARTITION_KERNEL);
LoadAndStart("flash0:/kd/pspnet.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/pspnet_inet.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/pspnet_apctl.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/pspnet_resolver.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/libparse_uri.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/libparse_http.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/libhttp.prx", PSP_MEMORY_PARTITION_USER);
// Hook function function
SceModule *mod;
mod = sceKernelFindModuleByName("SceHttp_Library");
if(mod) {
printf("found SceHttp_Library module - %d\r\n", mod->modid);
sceHttpCreateTemplate_Orig = patchNIDTable(mod, "sceHttp", "sceHttpCreateTemplate", ixHttpCreateTemplate);
if(sceHttpCreateTemplate_Orig == 0) {
printf("Could not hook sceHttpCreateTemplate function\n");
sceKernelTerminateDeleteThread(0);
sceKernelExitDeleteThread(0);
}
printf("patched old sceHttpCreateTemplate at %p with %p\r\n", (u32)sceHttpCreateTemplate_Orig, (u32)ixHttpCreateTemplate);
} else {
printf("SceHttp_Library module not found\r\n");
}
sceKernelExitDeleteThread(0);
return 0;
}
/* Entry point */
int module_start(SceSize args, void *argp)
{
int thid;
thid = sceKernelCreateThread("httppatch", main_thread, 0x18, 0x10000, 0, NULL);
if(thid >= 0)
{
sceKernelStartThread(thid, args, argp);
}
return 0;
}
/* Module stop entry */
int module_stop(SceSize args, void *argp)
{
return 0;
}
|
Running the above gives:
| Code: | loading libs...
Loading and starting flash0:/kd/ifhandle.prx... Done (04ff8973)
Loading and starting flash0:/kd/pspnet.prx... Done (04ff4f0b)
Loading and starting flash0:/kd/pspnet_inet.prx... Done (04ff0421)
Loading and starting flash0:/kd/pspnet_apctl.prx... Done (04fee435)
Loading and starting flash0:/kd/pspnet_resolver.prx... Done (04fec449)
Loading and starting flash0:/kd/libparse_uri.prx... Done (04fe8e5d)
Loading and starting flash0:/kd/libparse_http.prx... Done (04fe6a71)
Loading and starting flash0:/kd/libhttp.prx... Done (04fe3305)
found SceHttp_Library module - 83768069
patched old sceHttpCreateTemplate at 9cbe388 with 8827d43c |
|
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Sun Jul 06, 2008 6:52 am Post subject: |
|
|
You are patching a user2user export to a kernel function!
That causes user code to jump to kernel code, and that's not allowed. |
|
| Back to top |
|
 |
ixalon
Joined: 17 Jul 2006 Posts: 6
|
Posted: Mon Jul 07, 2008 3:28 am Post subject: |
|
|
Thanks moonlight... Knew I'd have made a glaringly simple error!
Still having problems though - stripping out all the nid table patching, if I do nothing more than load libhttp.prx in anything (kernel mode or user mode PRX) then the browser won't start.
e.g.
| Code: | ...
PSP_MODULE_INFO("httppatch", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
...
int main(SceSize args, void *argp)
{
LoadAndStart("flash0:/kd/ifhandle.prx", PSP_MEMORY_PARTITION_KERNEL);
LoadAndStart("flash0:/kd/pspnet.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/pspnet_inet.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/pspnet_apctl.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/pspnet_resolver.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/libparse_uri.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/libparse_http.prx", PSP_MEMORY_PARTITION_USER);
LoadAndStart("flash0:/kd/libhttp.prx", PSP_MEMORY_PARTITION_USER);
sceKernelExitThread(0);
return 0;
} |
|
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Mon Jul 07, 2008 4:14 am Post subject: |
|
|
| probably vsh will try to load those modules by itself, and since you have loaded them, they will return the exclusive load error to the vsh module calling the loadmodule function, and it will abort the browser load. |
|
| Back to top |
|
 |
ixalon
Joined: 17 Jul 2006 Posts: 6
|
Posted: Mon Jul 07, 2008 5:51 am Post subject: |
|
|
Ack! :(
Is there any way to patch usermode library functions in a way that built-in VSH plugins use the patched versions?
Could I patch sceKernelLoadModule and all its variants to ignore exclusive load errors and just return the module id of the already loaded module? Or could I patch it to check for attempts to load flash0:/kd/libhttp.prx and redirect it towards say ms0:/mypatched_libhttp.prx |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Mon Jul 07, 2008 6:37 pm Post subject: |
|
|
Yes, i guess you can patch loadmodule to fake results, don't forget to patch startmodule too if necessary.
In case of loadmodule, you have to patch the user import, not the kernel import, that despites having same name is a different function. You may have to patch too sceKernelLoadModuleVSH, but I don't think those net modules are loaded with that function, but you never know. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|