My API trace prx (and a question :)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
noxa
Posts: 39
Joined: Sat Aug 05, 2006 9:03 am
Contact:

My API trace prx (and a question :)

Post by noxa »

I've needed a general API tracing tool for awhile and had been putting it off, but I finally came around to writing it yesterday. It allows you to define the routines you want to hook in a file and have them all logged to stdout. It's similar to the apihook stuff in psplink (and half based on it), but allows for a variable number of hooks (up to the amount of memory available for the lookup table).

You can find the source here:
http://dev.ixtli.com/pspdev/browser/trunk/hooker
(or svn directly at svn://svn.ixtli.com/pspdev/trunk/hooker)
If you just want to run it, grab the prx and the hooks.txt file.

I've compiled it on the latest sdk with an old toolchain and only tested on 3.52 M33, so good luck.
To use, just load psplink, load the module (make sure hooks.txt is next to it), and then run your elf/eboot/etc. You should see everything in the console.

In the hooks.txt checked in, only the IO and graphics routines are enabled. The first field is 0/1 for enabled, so you can tweak it to what you like. The file was autogenerated by a tool also in the repository that walks psplibdoc and finds the C declarations in the sdk and builds the parameter format from them. It's not perfect, and psplibdoc hasn't been touched in 5 months (afaik), so new stuff is missing.

It handles basic reentrance, although I still recommend keeping sceIoWrite off as it's used to print stuff and if you hook it you'll end up getting a mess. Also, under certain circumstances, things will go south and you'll have to hard reset your PSP - usually caused by hooking something that the exception handler uses, which if the app crashes of course would not work. Also game shutdown doesn't seem to work (and psplink won't reset itself) - not sure why, as I could hook only one routine and it still won't work. I'm thinking it's a bug in psplink/M33.

--

So there that is; but I have a question I was hoping someone here can answer... This only works when running psplink standalone. That's all good and all, but I really wanted to get traces of real games, and that requires running while they are. I'm running on FW 3.52 M33 and when I set psplink and my plugin to start when games start (via the recovery menu), psplink starts fine and I can interact with the shell, however my prx doesn't load. If I try to load it, I tend to get different errors that vary on the way I try to load it (sometimes, the game I'm trying to run will fail to even start). The most common error is 0x800200d9 (failed to allocate memory block)

This is where I enter in to a realm that I'm not very familiar with... There are two ideas that I had that I think may be causing the issue:

1. I have PSP_FW_VERSION=150 in my makefile, and I'm trying to run it from the OE build of psplink. When I PSP_FW_VERSION=271, however, I get a different error (0x8002013C - library not found). Since the version of psplink that I run from the EBOOT bootstrap is 2.0 final, I'd imagine the 150 would be ok, but with the OE build it's 271, so I thought there would be an issue.

2. My prx is in kernel mode. I know other prxs I've tried (like the simple echo) work and they are in user mode. I'm not sure how to get around this - does psplink not load kernel modules? Looking at modload_cmd I see SceKernelLMOption is NULL - to load in kernel mode, I'd have to have that set with a kernel partition, right? Even if I did that (which I don't want to do - defeats the purpose of having a separate prx), why would it work when run standalone but not when run in a game? psplink is in kernel mode in both cases, right?

If anyone sees any issues with this and think they know how to get it working, please let me know. Worst case I move all the code in to psplink itself, but then it becomes harder to share as I don't have svn access.

Let me know if you have any questions!
KickinAezz
Posts: 328
Joined: Sun Jun 03, 2007 10:05 pm

Post by KickinAezz »

duz it capture args passed?
noxa
Posts: 39
Joined: Sat Aug 05, 2006 9:03 am
Contact:

Post by noxa »

Yep, the output looks something like this:

Code: Select all

~0x05053717 -> sceGeSetCallback[0xA4FC06A4](0x09FBFC90) from 0x08943560
~0x05053717 <- sceGeSetCallback&#91;0xA4FC06A4&#93; = 0
~0x05053717 -> sceGeEdramGetAddr&#91;0xE47E40E4&#93;&#40;&#41; from 0x08943570
~0x05053717 <- sceGeEdramGetAddr&#91;0xE47E40E4&#93; = 0x04000000
~0x05053717 -> sceGeListEnQueue&#91;0xAB49E76A&#93;&#40;0x08973D40,0x00000000,0,0x00000000&#41; from 0x089435A0
~0x05053717 <- sceGeListEnQueue&#91;0xAB49E76A&#93; = 901516706
~0x05053717 -> sceGeListSync&#91;0x03444EB4&#93;&#40;901516706,0&#41; from 0x089435D0
~0x05053717 <- sceGeListSync&#91;0x03444EB4&#93; = 0
~0x05053717 -> sceGeListEnQueue&#91;0xAB49E76A&#93;&#40;0x489A3960,0x489A3960,0,0x00000000&#41; from 0x08943A20
~0x05053717 <- sceGeListEnQueue&#91;0xAB49E76A&#93; = 901516738
~0x05053717 -> sceGeListUpdateStallAddr&#91;0xE0D68148&#93;&#40;901516738,0x489A39C8&#41; from 0x0894350C
~0x05053717 <- sceGeListUpdateStallAddr&#91;0xE0D68148&#93; = 0
~0x05053717 -> sceGeListUpdateStallAddr&#91;0xE0D68148&#93;&#40;901516738,0x489A39DC&#41; from 0x0894255C
~0x05053717 <- sceGeListUpdateStallAddr&#91;0xE0D68148&#93; = 0
~0x05053717 -> sceGeListUpdateStallAddr&#91;0xE0D68148&#93;&#40;901516738,0x489A3A50&#41; from 0x089433A8
~0x05053717 <- sceGeListUpdateStallAddr&#91;0xE0D68148&#93; = 0
~0x05053717 -> sceGeDrawSync&#91;0xB287BD61&#93;&#40;0&#41; from 0x0891261C
~0x05053717 <- sceGeDrawSync&#91;0xB287BD61&#93; = 0
~0x05053717 -> sceIoOpen&#91;0x109F50BC&#93;&#40;ms0&#58;/psp/game150/trigwars/data/hiscore.bin,1,0666&#41; from 0x0894B5D8
~0x05053717 <- sceIoOpen&#91;0x109F50BC&#93; = 0x80010002
~0x05053717 -> sceIoOpen&#91;0x109F50BC&#93;&#40;ms0&#58;/psp/game150/trigwars/data/textures/whiteplayer.png,1,0666&#41; from 0x0894B5D8
~0x05053717 <- sceIoOpen&#91;0x109F50BC&#93; = 0x00000007
~0x05053717 -> sceIoGetstat&#91;0xACE946E8&#93;&#40;ms0&#58;/psp/game150/trigwars/data/textures/whiteplayer.png,0x09FBEC40&#41; from 0x0894E42C
~0x05053717 <- sceIoGetstat&#91;0xACE946E8&#93; = 0
~0x05053717 -> sceIoLseek&#91;0x27EB27B8&#93;&#40;0x00000007,12288,0&#41; from 0x0894B3E8
~0x05053717 <- sceIoLseek&#91;0x27EB27B8&#93; = 0
the ~{value} is the thread the function is executing on. I could make it less verbose, but for things like async functions and things that cause sleeps, it's helpful to know when a function returns and what the threads are.
KickinAezz
Posts: 328
Joined: Sun Jun 03, 2007 10:05 pm

Post by KickinAezz »

Nice. Very useful.
Are those NID's in [] brackets and args in ()?
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Urm you are just hooking syscalls right ? Well if so then you dont need to worry about reentrancy as long as you link against the kernel libraries which dont go through the syscall gateway.

Oh and incidently while parts of it is a slight reworked version of my psplink code (which you have already admitted) I am sure you are not allowed to just take the code and remove any reference to where it original came from or was based on :)
noxa
Posts: 39
Joined: Sat Aug 05, 2006 9:03 am
Contact:

Post by noxa »

Right - I'm just patching up the syscall table. I noticed weird behavior with psplink when hooking certain routines - maybe caused by psplink_user or other things launched from psplink.

Any tips on how to get kernel mode prxs working from within psplink when not launched standalone? I noticed remotejoy is kernel mode, and may try building some tests later to see if I can get anything at all working. I tried building with build_prx.mak instead of build.mak with BUILDPRX=1, but always got weird compile errors. I'll experiment a bit.

Just way outside my area of knowledge, and finding solid information about this stuff (where stuff=running kernel mode prxs under 3.50+) is difficult. So far I've just been pulling the plug on my PSP every 5 minutes ;(

Ah right - sorry, I updated the README!
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Yah normally you use build_prx.mak cause that creates a prx without a main function which you really shouldn't be using for a kernel mode executable in any case.
noxa
Posts: 39
Joined: Sat Aug 05, 2006 9:03 am
Contact:

Post by noxa »

I've got things working now! I get occasional crashes (bus errors - invalid instruction), probably memory access issues or stack overwriting.

I did find a bug in psplink though - line 191 of psplink/kmode.S should be 8($sp), not 4($sp) - it's loading the same lower word in to the upper word return register. psplink_user/kmode.S has the same issue at line 43.

Thanks again for your help. I've put the latest sources/binary up in my svn repo if anyone wants to take a peek at it.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Thx for that, you wonder how a bug like that lasted so long :)
KickinAezz
Posts: 328
Joined: Sun Jun 03, 2007 10:05 pm

Post by KickinAezz »

This should be updated for 3.71 and be able to run from PSPlink in GAME371 folder. [not 1.5 kernel].
Intrigued by PSP system Since December 2006.
Use it more for Development than for Gaming.
Post Reply