Random Homebrew: Tuyo Kiss
Tuyo Kiss is an interactive graphic novel for the PSP
Friends: Coding 'n Cracking - Nymphaea - PS3 Forum - darkforestgroup - daxhordes.org - Tgames - coldbird - gopsp.it - pspstation.org - prometheus - hgoel.info - MakeSmartTV - ps vita

Display text in game from plugin

Forum rules
Any post not directly related to programming will be moderated.
Do not request people to code something for you.
Avoid posting messages that do not bring anything to the conversation. We want the threads in this subforum to stay focused.

Re: Display text in game from plugin

Postby m0skit0 » Thu Dec 30, 2010 12:02 pm

svanheulen wrote:the game has a stub for functions and the kernel points them to the correct functions

Right, except it has a stub for each imported function (functions used from the firmware, every sceWhatever()). When kernel loads the ELF, it resolves those stubs with correct call, be it a J (user-mode call) or a SYSCALL (kernel-mode call).

svanheulen wrote:So you just point it to your own function after the kernel does it's thing?

That's it. You overwrite the kernel resolved call. This way every time the game calls that function, your function will execute instead. Of course you can still call the original function after you're done with your own processing. You have to wait for this since otherwise the kernel will overwrite your hook. But this way you also overwrite the kernel call. This shouldn't be a problem if the same function is included on your plugin's stubs (supposing you want to call the kernel service).

svanheulen wrote:How do you find the stub address?

Run prxtool on the ELF. However having the stubs addresses hardcoded will make it work only on that specific game. Best option for what you want to do is coding your plugin so it searches for the stubs section, or at least the stubs you want to hook. This can be done quite easily parsing the memory for the name of the library, then finding pointers to it. Most likely there will be only one pointer, and included on the library stub descriptor, which also points to the stubs themselves. You can look how this is done in detail by checking my Game Dump Processor (aka moskitool). It's written to be run on PC, but it can easily be ported to run on PSP. Feel free to reuse the code.
I wanna lots of mov al,0xb
Image
"just not into this RA stuffz"
User avatar
m0skit0
Guru
 
Posts: 4787
Joined: Mon Sep 27, 2010 6:01 pm

Re: Display text in game from plugin

Postby StorMyu » Tue Apr 24, 2012 3:19 pm

As suggested by M0skit0, I'm necro-posting :lol:

m0skit0 wrote:
JJS wrote:I think it is always called user_main.

It's not always called user_main, IIRC. Anyway you cannot assume it will be always called user_main since it can be called anything.

The best way to do what you're asking for is hooking sceKernelCreateThread() system call.

I coded a plugin for a friend some time ago for translation, which does some hooking on the file I/O part, to replace original game files with translated ones. I think I posted the source code in Daxhordes, I'll take a look and bring it around here.

EDIT: found it, here it is. It's an older version than the one I have in my computer IIRC, but anyway it explains everything you need to know to hook system calls from a plugin. Some stuff is in spanish, although code comments are in english. Good luck ;)


I tried to use the plugin of M0skit0, which was basically something I was attempting to do, but I have a little problem while using it:
Code: Select all
SceUID find_stop_game_thread(void)
{
   SceUID uid_list[MAX_THREADS], ret;
   SceKernelThreadInfo thread_info;
   int i, count;

   // Until user_main thread shows up...
   while(1)
   {
      // Getting threads list
      ret = sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, uid_list, MAX_THREADS, &count);
   
      if(ret < 0)
      {
         write_debug(" ERROR GETTING THREAD LIST  ", (void*)&ret, sizeof(ret));
         return ret;
      }

      // Searching for main game thread
      thread_info.size = sizeof(thread_info);
      for(i=0; i<count; i++)
      {
      
         ret = sceKernelReferThreadStatus(uid_list[i], &thread_info);

         if (ret < 0)
            write_debug(" ERROR GETTING THREAD INFO  ", (void*)&(uid_list[i]), sizeof(SceUID));

         else if(strcmp(thread_info.name, GAME_THREAD) == 0)
         {
            ret = sceKernelSuspendThread(uid_list[i]);

            if (ret < 0)
            {
               write_debug(" ERROR SUSPENDING THREAD ", (void*)&(uid_list[i]), sizeof(SceUID));
               return ret;
            }

            return (int)uid_list[i];
         }
      }

      sceKernelDelayThread(10000);
   }

   return (SceUID)-1;
}

I've got the "ERROR SUSPENDING THREAD", even if everything is perfectly set up, I guess the game's thread must be "unstoppable" per se, and so everything that follows can't be happening.
To sum up:
The plugin will wait till the game's module is launched, and then try to suspend it (for further use such as hooking the SceIoOpen stub)

But here I have that problem and apparently no idea on how to fix it. If someone got any idea I'll be glad to hear it.
Thanks for reading.
StorMyu
 
Posts: 21
Joined: Wed Aug 17, 2011 1:39 pm

Re: Display text in game from plugin

Postby m0skit0 » Tue Apr 24, 2012 3:26 pm

What exact error code are you getting?
I wanna lots of mov al,0xb
Image
"just not into this RA stuffz"
User avatar
m0skit0
Guru
 
Posts: 4787
Joined: Mon Sep 27, 2010 6:01 pm

Re: Display text in game from plugin

Postby StorMyu » Tue Apr 24, 2012 5:24 pm

I don't get any error, your code puts every "problem" in a Debug file in the memory stick, and it tells me:
ERROR SUSPENDING THREAD, as the part of the code I've posted do:
Code: Select all
ret = sceKernelSuspendThread(uid_list[i]);

            if (ret < 0)
            {
               write_debug(" ERROR SUSPENDING THREAD ", (void*)&(uid_list[i]), sizeof(SceUID));
               return ret;
            }

And since the code can't suspend the main thread of the game, the code just stop itself but there's no harm.
StorMyu
 
Posts: 21
Joined: Wed Aug 17, 2011 1:39 pm

Re: Display text in game from plugin

Postby m0skit0 » Tue Apr 24, 2012 5:47 pm

Ok, but that code also writes the SceUID of the thread that cannot be stopped. Also make it write the error code to the file as well. Or just use PSPLink to check the SceUID passed to and the value returned by sceKernelSuspendThread() ;)
I wanna lots of mov al,0xb
Image
"just not into this RA stuffz"
User avatar
m0skit0
Guru
 
Posts: 4787
Joined: Mon Sep 27, 2010 6:01 pm

Re: Display text in game from plugin

Postby StorMyu » Tue Apr 24, 2012 7:06 pm

Image

Yeah but, it's a bit weird... I'm not even sure what's what ^^
Technically it's the name of the thread but the error log gives me this.

In case you're wondering:
Code: Select all
void write_debug(const char* description, void* value, unsigned int size)
{
   SceUID fd;

   if ((fd = sceIoOpen(DEBUG_PATH, PSP_O_CREAT | PSP_O_WRONLY | PSP_O_APPEND ,0777)) >= 0)
   {
      sceIoWrite(fd, description, strlen(description));
      if (value != NULL)
         sceIoWrite(fd, value, size);
      sceIoClose(fd);
   }

So we have the name of the description error which is:
" ERROR SUSPENDING THREAD " (space are important) and then...
sceIoWrite(fd, value, size);

Of: write_debug(" ERROR SUSPENDING THREAD ", (void*)&(uid_list[i]), sizeof(SceUID));
Where value = (void*)&(uid_list[i]) and size (well it's obvious)
StorMyu
 
Posts: 21
Joined: Wed Aug 17, 2011 1:39 pm

Re: Display text in game from plugin

Postby m0skit0 » Tue Apr 24, 2012 8:48 pm

Yeah, that's it. I think what confuses you is that the values are expressed in little-endian, which means you have to reverse the byte order: so the thread ID is 03F05C39 (the 32-bit value after "ERROR SUSPENDING THREAD", it's not the thread name but the thread ID -every "kernel object" in PSP has a 32-bit identifier named SceUID-) and the error code is 800201A2 (the 32-bit value after "ERROR FINDING GAME THREAD", which if you look at the code is the value returned from the function -the ret variable-). The error code means: thread already DORMANT. So you simply can't suspend that 03F05C39 thread because it's already suspended.
I wanna lots of mov al,0xb
Image
"just not into this RA stuffz"
User avatar
m0skit0
Guru
 
Posts: 4787
Joined: Mon Sep 27, 2010 6:01 pm

Re: Display text in game from plugin

Postby StorMyu » Wed Apr 25, 2012 7:21 pm

I knew about the Little_endian, but "03F05C39" I thought the plugin was supposed to give a thread name as an error since it's comparing it with the main module name...
Also, I thought the second error was irelevant, since the first problem was here so I haven't looked at it and yeah it sounds logic now....

But I don't see any work-around for that matter... any idea ? Because I tried to "continue" the code if the error it gives was this one (if it was already suspended) but no way, not working...
StorMyu
 
Posts: 21
Joined: Wed Aug 17, 2011 1:39 pm

Re: Display text in game from plugin

Postby m0skit0 » Thu Apr 26, 2012 8:59 am

StorMyu wrote:but "03F05C39" I thought the plugin was supposed to give a thread name as an error

Use PSPLink if you want to know the thread name (irrelevant anyway). There could be several threads with the same name, that's why the UID (which is unique) is logged instead. You can log the thread name if you want, but you have to query the kernel about that thread information.

StorMyu wrote: I don't see any work-around for that matter... any idea ?

Yeah, wait until the thread is resumed to suspend it again yourself, or just continue processing remaining threads.

StorMyu wrote: I tried to "continue" the code if the error it gives was this one (if it was already suspended) but no way, not working...

Not working why? Any more details? What did you continue? You exited that function or you continued processing the remaining threads?
I wanna lots of mov al,0xb
Image
"just not into this RA stuffz"
User avatar
m0skit0
Guru
 
Posts: 4787
Joined: Mon Sep 27, 2010 6:01 pm

Re: Display text in game from plugin

Postby StorMyu » Thu Apr 26, 2012 10:46 am

m0skit0 wrote:
StorMyu wrote: I don't see any work-around for that matter... any idea ?

Yeah, wait until the thread is resumed to suspend it again yourself, or just continue processing remaining threads.

StorMyu wrote: I tried to "continue" the code if the error it gives was this one (if it was already suspended) but no way, not working...

Not working why? Any more details? What did you continue? You exited that function or you continued processing the remaining threads?

the original code was just giving an error and returned the error name to print it
I just tried to continue it by returning the UID of the thread as if it were suspended by sceKernelSuspendThread
to see if the code will success in patching the stub, which it doesn't, probably because the module was not fully loaded I don't know...
So yeah I'm gonna try to continue the loop until the main thread is not suspended anymore by putting some sceKernelDelayThread(10000); at the end of the infinite loop till it finally success in suspending it and then continue the code as usual.

Quick question though, why do we have to suspend the main thread to patch the STUB ?
StorMyu
 
Posts: 21
Joined: Wed Aug 17, 2011 1:39 pm

PreviousNext

Return to Programming

Who is online

Users browsing this forum: No registered users and 3 guests