Jump to content

request for psp hackers


Recommended Posts

Still, if it works, it's going be a memorable day! So, to make things clear: WoF FD is a go; WoF, WoF2 & WoF2 FD is a no. Right?

At this point I would settle for a clear game script of WoF FD, WoF2 & WoF2 FD... Getting a translation of those is my lifetime project :)

Link to comment
Share on other sites

…

Great tutorial, thanks for it (didn't know about param.sfo/pack-pbp; my technique always has been mkisofs). But I actually wanted to know what did you change in this particular EBOOT, since this is the most interesting stuff and there's very little information on that.

Link to comment
Share on other sites

Hi xyz,

The mods? they're a couple of assembly instructions that circumvent how the program originally runs. A "NoUmd" patch if you want.

For instance, sceUmdCheckMedium and sceUmdActivate are typically called once in the whole game during the startup sequence.

The C code (higher level) would be like this:

if(sceUmdCheckMedium() != 0)

{

   if(sceUmdActivate(1, "disc0:") >= 0)

   {

      sceUmdWaitDriveStat(PSP_UMD_READY);

      //...

   }

}

It translates to this:

.text:088056A0                 jal     sceKernelRegisterExitCallback

.text:088056A4                 move    $a0, $v0

.text:088056A8                 jal     sceUmdCheckMedium

.text:088056AC                 nop

.text:088056B0                 bnez    $v0, loc_88056C0

.text:088056B4                 nop

.text:088056B8                 jal     sub_8871B94

; call to a subroutine @8871B94, which itself calls sceUmdWaitDriveStatCB


.text:088056BC                 li      $a0, 2

.text:088056C0

.text:088056C0 loc_88056C0:

.text:088056C0                 lui     $a1, 0x88F

.text:088056C4                 li      $a0, 1

.text:088056C8                 jal     sceUmdActivate

.text:088056CC                 la      $a1, aDisc0      # "disc0:"

.text:088056D0                 bgezl   $v0, loc_88056E0

.text:088056D4                 li      $a0, 0x20

.text:088056D8                 b       loc_8805734

.text:088056DC                 li      $v0, 0xFFFFFFFF

.text:088056E0  # ---------------------------------------------------------------------------

.text:088056E0

.text:088056E0 loc_88056E0:

.text:088056E0                 jal     sub_8871B94

; ditto above


.text:088056E4                 nop

.text:088056E8                 la      $a0, unk_9CB2494


conversely sceUmdGetDriveStat, sceUmdWaitDriveStat and friends are called at several locations before a read is attempted. We don't need them, since we're not reading from UMD any longer. 1) So the first task is to reference all locations that want to read from disc0:, and somehow have them read from ms0: (hardcoded string modification) - this is done in a hex editor. If it is simply "disc0:", I lookup in IDA what uses such a string (1st: sceUmdActivate itself, 2nd: ADXT::SetDevice) - only 2nd requires "disc0:" be changed into "ms0:" 2) Then I blank out ("NOP") the whole code block after I checked out there was really nothing interesting inside. I switch between IDA View and Hex View to find patterns to locate code (or I am smarter and I compute where modifications should go)
.text:088056A0                 jal     sceKernelRegisterExitCallback

.text:088056A4                 move    $a0, $v0

.text:088056A8                 nop

.text:088056AC                 nop

.text:088056B0                 nop

.text:088056B4                 nop

.text:088056B8                 nop

.text:088056BC                 nop

.text:088056C0                 nop

.text:088056C4                 nop

.text:088056C8                 nop

.text:088056CC                 nop

.text:088056D0                 nop

.text:088056D4                 nop

.text:088056D8                 nop

.text:088056DC                 nop

.text:088056E0                 nop

.text:088056E4                 nop

.text:088056E8                 la      $a0, unk_9CB2494

3) Patching the remaining calls 3A) sceUmdGetDriveStat a quick google lookup says it returns an integer.
pspUmdState { 

   PSP_UMD_NOT_PRESENT = 0x01, PSP_UMD_PRESENT = 0x02, PSP_UMD_CHANGED = 0x04, PSP_UMD_INITING = 0x08, 

   PSP_UMD_INITED = 0x10, PSP_UMD_READY = 0x20 

 }
Um, okay. So we patch the call to always return 0x20. Return values are stored in $v0 and $v1 in MIPS. So when I see:
.text:088AE15C                 jal     sceUmdGetDriveStat

.text:088AE160                 nop

I want this instead:
.text:088AE15C                 li $v0, 0x20

.text:088AE160                 nop

I pay extra attention to the instruction after jal because it is executed before the call, I do not want it to have undesirable effects. Having checked all xrefs, I know all sceUmdGetDriveStat calls use a nop instruction in the delay slot, so no need for inversion. To get the 32-bit opcode for the load instruction ( "li $v0, 0x20" ), you either find the same instruction elsewhere in the program (this one is relatively easy to find), or you compile one. PPSSPP has a debugger window in which you can Assemble opcode
Assemble opcode, value: "li v0,0x20", click OK Right click on assembled instruction => go in memory view and see corresponding 32-bit word
To sum up:
Search
: 88B3230E (stub call jal sceUmdGetDriveStat)
Replace all
: 20000224 (li $v0, 0x20)
3B) sceUmdWaitDriveStatCB This is referenced in a single function that serves as wrapper & called from several locations. I should have the replacement code call the CB and return a >=0 value, but things seem to work just as well without, so I don't really care
.text:08871B94  # =============== S U B R O U T I N E =======================================

.text:08871B94

.text:08871B94 sub_8871B94:

.text:08871B94                 addiu   $sp, -0x10

.text:08871B98                 sw      $ra, 0x10+var_4($sp)

.text:08871B9C                 sw      $s0, 0x10+var_8($sp)

.text:08871BA0                 move    $s0, $a0

.text:08871BA4                 move    $a0, $s0

.text:08871BA8

.text:08871BA8 loc_8871BA8:

.text:08871BA8                 jal     sceUmdWaitDriveStatCB

.text:08871BAC                 li      $a1, 0x2710

After
.text:08871B94  # =============== S U B R O U T I N E =======================================

.text:08871B94                 jr $ra

.text:08871B98                 nop

; nop in delay slot

substitution sequence is 0800E003 00000000

3C) sceUmdWaitDriveStat calls were guarded behind a sceUmdGetDriveStat check. Since we replaced that in 3A), no need to patch anything

I suggest you try to compile simple homebrews and see the assembly output. It is another useful way to learn how high-level constructs are translated into machine code.

PPSSPP features a basic debugger so you can also see how tests, branches, etc. work out.

Link to comment
Share on other sites

Nanashi3, this is really great, many thanks for explaining thoroughly.

Blue, you still need to modify the data, in WoF case that'd be UNI files which contain STCM2L scripts and other resources like images and whatnot. The patch provided by Nanashi3 eliminates the need to rebuild the whole .ISO when changing files.

Link to comment
Share on other sites

I reinserted text into Amnesia successfully, but the letters have too much space between them, so it's unreadable.

I got WoFFD to run under the homebrew section of ppsspp, but I have no idea what to do now, so I'm dropping this. It would be fun to have a clean script though...

But on the bright side, hkki can handle a lot of scripts indeed! I managed to get a clean script of Crowd :)

Speaking of scripts, I'm trying to extract some from a certain game the title of which I would rather not mention... I know where they are - in a *.dns file, which I decrypted and it turned out to be a cpk file, but when I'm trying to extract that, utf_tab can't find a valid @utf table :( I also tried CRI, but it says it's not a valid CPK file despite showing what's inside.

Any suggestions about how to handle this?

Link to comment
Share on other sites

  • 2 weeks later...

It seems some UTF tables are encrypted.

To extract from those archives, you may use CriToolpack from Falo ( http://forum.xentax.com/viewtopic.php?f=10&t=10646 )

I have uploaded a modded version which has "extract all" and "extract selected" working correctly http://www.embedupload.com/?d=92EWH2YGVB

 

 

Diabolik Lovers scripts @ http://www.embedupload.com/?d=4PL3GXQPIW

 

Opening fine in hkki AFAICT.

 

Edit: more info about XOR obfuscation in source, and here --> http://wrttn.in/04fb3f by [unknown]

Edit2: another tool https://github.com/shinohane/cpktools

Link to comment
Share on other sites

It seems some UTF tables are encrypted.

To extract from those archives, you may use CriToolpack from Falo ( http://forum.xentax.com/viewtopic.php?f=10&t=10646 )

I have uploaded a modded version which has "extract all" and "extract selected" working correctly http://www.embedupload.com/?d=92EWH2YGVB

 

 

Diabolik Lovers scripts @ http://www.embedupload.com/?d=4PL3GXQPIW

 

Opening fine in hkki AFAICT.

 

Edit: more info about XOR obfuscation in source, and here --> http://wrttn.in/04fb3f by [unknown]

Edit2: another tool https://github.com/shinohane/cpktools

 

Aww yiss! Thank you so much! This will help me on my journeys :)

 

I'm wondering... What programming language would I have to learn to be able to make or modify something like "hkki"? It's an awesome tool, but... No support for names, and I'm curious why it reads some files perfectly and gives up on others (it doesn't want to read scripts from WoF games).

Link to comment
Share on other sites

I'd say, it depends on your previous programming background?

For absolute newcomers you may want to pick up a new language without too much complexity, and which will help you learn better software practices: Ruby or Python.

If you need to find a job, C# and/or Java, with my preference for the former as it has superior debugging capacities and overall a more pleasant syntax.

 

Later, after you have grasped the whys and hows, a lower-level language such as C++ and C.

 

 

Nore re: hkki, I developed a small test suite in ruby to check various IdeaFactory scripts (script data structures)

I think the author maybe erroneously interpreted how the file is divided, thus sometimes it works and other times not.

Link to comment
Share on other sites

  • 2 weeks later...
  • 1 month later...

Good news, the author of hkki updated the files, which now supports a few more scripts STCML2 files.

Also they generously offered to try to improve or add additional functionality to hkki, so if there is any feedback, or issues, post them here, I'm sure it would be helpful.

Though the authors pretty busy and doing this of his own free time, so keep in mind at this stage it can't be promised that they will be implemented.

Link to comment
Share on other sites

As requested, here is a Windows build of the latest source tree:

hkki-3eaa1f6b3ebc3bf0dc04b17ee8cde478eb4ee264.7z  download link

http://www.embedupload.com/?d=8HUTFJIFQJ

It was built using Qt's gcc compiler and http://gladewin32.sourceforge.net/ with this command line:



g++ -I C:\GTK\include\gtk-2.0 -I C:\GTK\include\cairo -I C:\GTK\include\glib-2.0 -I C:\GTK\lib\glib-2.0\include -I C:\GTK\lib\gtk-2.0\include -I C:\GTK\include\pango-1.0 -I C:\GTK\include\atk-1.0 -mms-bitfields -c main.cpp compress.cpp action.cpp stcm2l_file.cpp text_entity.cpp

g++ -o hkki  main.o compress.o action.o stcm2l_file.o text_entity.o -LC:\GTK\lib -lgtk-win32-2.0 -lgmodule-2.0 -lglib-2.0 -lgobject-2.0

Edit: I also published the RSpec test suite I talked about earlier.

https://github.com/mchubby/ideaf_script_format

Edited by Nanashi3
Link to comment
Share on other sites

  • 5 weeks later...

Wow,  Nanashi3, thanks a lot for this awesome tool! :wub:  I finally managed to extract the scripts for quite a number of games I was interested in. You're a blessing from heaven.

 

I was curious about one thing-from what I know hkki cannot be run from DOS or executed as batch script, but is there any way to extract text of multiple script files at a time? If not, are there any plans to implement such a feature?
 

Link to comment
Share on other sites

Thank you, xyz! It's really great that you contribute so much!

Btw, any tips on how to fight the fonts in PSP games? I'm trying figure out what went wrong when I inserted text back into Amnesia (too much empty space between letters; it's either encoding or the width, I guess?)

Link to comment
Share on other sites

Thank you, xyz! It's really great that you contribute so much!

Btw, any tips on how to fight the fonts in PSP games? I'm trying figure out what went wrong when I inserted text back into Amnesia (too much empty space between letters; it's either encoding or the width, I guess?)

First things first! Make sure that's not your emulator (if you're using it to test the game). Try configuring it to use original PSP fonts (google for dumps of those or dump them yourself).
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...