Blue Posted August 31, 2013 Posted August 31, 2013 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.) Quote
Nanashi3 Posted August 31, 2013 Posted August 31, 2013 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. Quote
Blue Posted August 31, 2013 Posted August 31, 2013 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 Quote
xyz Posted August 31, 2013 Posted August 31, 2013 … 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. Quote
Nanashi3 Posted August 31, 2013 Posted August 31, 2013 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. xyz 1 Quote
Blue Posted August 31, 2013 Posted August 31, 2013 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? Quote
xyz Posted August 31, 2013 Posted August 31, 2013 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. Quote
Blue Posted September 1, 2013 Posted September 1, 2013 xyz, so I still need a separate tool to actually reinsert the text, is that right? Can hkki even handle that in WoF's case? Quote
Blue Posted September 8, 2013 Posted September 8, 2013 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? Quote
Nanashi3 Posted September 9, 2013 Posted September 9, 2013 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... Quote
Blue Posted September 22, 2013 Posted September 22, 2013 @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! Quote
Nanashi3 Posted September 23, 2013 Posted September 23, 2013 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 Blue 1 Quote
Blue Posted September 23, 2013 Posted September 23, 2013 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). Quote
Nanashi3 Posted September 23, 2013 Posted September 23, 2013 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. expelian 1 Quote
com3lon03 Posted October 8, 2013 Author Posted October 8, 2013 stay strong guys  im gonna look some more help Quote
expelian Posted December 3, 2013 Posted December 3, 2013 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. Quote
Nanashi3 Posted December 3, 2013 Posted December 3, 2013 (edited) As requested, here is a Windows build of the latest source tree:hkki-3eaa1f6b3ebc3bf0dc04b17ee8cde478eb4ee264.7z  download linkhttp://www.embedupload.com/?d=8HUTFJIFQJIt 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 December 3, 2013 by Nanashi3 expelian 1 Quote
expelian Posted December 4, 2013 Posted December 4, 2013 Thank you Nanashi. That's really helpful. Quote
Blue Posted December 4, 2013 Posted December 4, 2013 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... Quote
vocaotome Posted January 3, 2014 Posted January 3, 2014 Wow, Nanashi3, thanks a lot for this awesome tool!  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?  Quote
xyz Posted January 7, 2014 Posted January 7, 2014 There's a bug in hkki, it doesn't work with some games, i.e. WoF, WoF: Prologue and probably others.I've fixed it here: https://github.com/lnz/hkki/pull/1 and am waiting for repo maintainer to merge it. In meantime you could use my fork located here: https://github.com/xyzz/hkki Quote
vocaotome Posted January 7, 2014 Posted January 7, 2014 Thanks xyz! Now if I could only figure out how to set things up so I can recompile the program... *is a noob* Quote
Blue Posted January 7, 2014 Posted January 7, 2014 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?) Quote
xyz Posted January 7, 2014 Posted January 7, 2014 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). Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.