forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Patching SceHttp_Library

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
ixalon



Joined: 17 Jul 2006
Posts: 6

PostPosted: Sun Jul 06, 2008 6:09 am    Post subject: Patching SceHttp_Library Reply with quote

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
View user's profile Send private message
moonlight



Joined: 26 Oct 2005
Posts: 567

PostPosted: Sun Jul 06, 2008 6:52 am    Post subject: Reply with quote

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
View user's profile Send private message
ixalon



Joined: 17 Jul 2006
Posts: 6

PostPosted: Mon Jul 07, 2008 3:28 am    Post subject: Reply with quote

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
View user's profile Send private message
moonlight



Joined: 26 Oct 2005
Posts: 567

PostPosted: Mon Jul 07, 2008 4:14 am    Post subject: Reply with quote

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
View user's profile Send private message
ixalon



Joined: 17 Jul 2006
Posts: 6

PostPosted: Mon Jul 07, 2008 5:51 am    Post subject: Reply with quote

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
View user's profile Send private message
moonlight



Joined: 26 Oct 2005
Posts: 567

PostPosted: Mon Jul 07, 2008 6:37 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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