Jump to content

Recommended Posts

Posted

Whoa! O_O You really know your stuff... I haven't tested anything yet, but I wonder if this method would be applicable to the other 3 WoF games? (The whole series is completed at 4. I want all of them out eventually.)

Posted

Uuuuuuuh...

This is embarrassing, but I got things mixed up. What I posted earlier refers to the WOF fandisc and not to wand of fortune itself.

Remarks about incompatible STCM2L still applies, though.

Posted

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 :)

Posted

…

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.

Posted

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.

Posted

xyz probably understands your answer, but to me it's higher level magic...

My question is: are you able to modify the first WoF's file the same way? If it's not too much trouble, could you do it?

Posted

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.

Posted

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?

Posted

Syntax 1:

mkdir INSTALL.DNS.cpk_output

quickbms.exe cpk.bms INSTALL.DNS.cpk INSTALL.DNS.cpk_output

Syntax 2:

cpk_unpack.exe INSTALL.DNS.cpk

Either way, you end up with STCM2L in the scripts subfolder, which cannot be parsed by hkki...

  • 2 weeks later...
Posted

@Nanashi3:

Nope, it doesn't work.

Game is Diabolik Lovers (you may now start throwing tomatoes at me) and the script I want is located in Instal.dns

Trust rejet to come up with something weird!

Posted

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

Posted

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).

Posted

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.

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

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.

Posted (edited)

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
Posted

Well, hkki is very cool as it is... I would love it if it was able to read the script files from the Wand of Fortune game series (particularly WoF2 and WoF2FD...)

And maybe scripts from Hiiro no Kakera DS...

  • 5 weeks later...
Posted

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?
 

Posted

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?)

Posted

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).

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...