Tux Posted October 26, 2015 Posted October 26, 2015 I've figured out how scripts work in Pokémon , and therefore wrote a script disassembler (in Python 3.x). Sorry if it's a mess. There are basically two scripts run at the same time: the "common" script, used for a lot of things, loaded after the "Health and safety" screen, and the current map's own script. I don't know where the common script is stored, so I've dumped it from RAM (you can find it in in the link below, along with the disassembler). This common script seems to do strange things anyways. For everything else, refer to the disassembler various docstrings. I consider the Daycare's script (M3_houseD_1F.fsys/1) to be a good script to begin with. The test script (in Script_test.fsys) is interesting too. Download link (download the source code, since it's Python): https://github.com/TuxSH/XDscriptTools/releases/tag/v0.1
StarsMmd Posted October 26, 2015 Posted October 26, 2015 I've figured out how scripts work in Pokémon , and therefore wrote a script disassembler (in Python 3.x). Sorry if it's a mess.There are basically two scripts run at the same time: the "common" script, used for a lot of things, loaded after the "Health and safety" screen, and the current map's own script. I don't know where the common script is stored, so I've dumped it from RAM (you can find it in in the link below, along with the disassembler). This common script seems to do strange things anyways. For everything else, refer to the disassembler various docstrings. I consider the Daycare's script (M3_houseD_1F.fsys/1) to be a good script to begin with. The test script (in Script_test.fsys) is interesting too. Download link (download the source code, since it's Python): https://github.com/TuxSH/XDscriptTools/releases/tag/v0.1 So excited to play around with this! Can it reassemble the scripts as well?
Tux Posted October 26, 2015 Author Posted October 26, 2015 No, it can just disassemble. If you want to modify the script, you will have to do this by hand. Since all code offsets (in FTBL, HEAD, jumps and calls) are absolute, the easiest way to add code to an existing function, though a little bit hackish, is to add the code at the end of the CODE section, jump to this portion, and jump back (as well as updating the script total size (offset 4), and the CODE section size (CODE offset 4)).
StarsMmd Posted October 26, 2015 Posted October 26, 2015 No, it can just disassemble.If you want to modify the script, you will have to do this by hand. Since all code offsets (in FTBL, HEAD, jumps and calls) are absolute, the easiest way to add code to an existing function, though a little bit hackish, is to add the code at the end of the CODE section, jump to this portion, and jump back (as well as updating the script total size (offset 4), and the CODE section size (CODE offset 4)). Did you manage to figure out what the sections at the bottom are for, i.e. GVAR, STRG, VECT, GIRI, ARRY. Also do you know any ways to decrease the compressed file sizes? For example, redundant data or unnecessary data.
StarsMmd Posted October 26, 2015 Posted October 26, 2015 There are basically two scripts run at the same time: the "common" script, used for a lot of things, loaded after the "Health and safety" screen, and the current map's own script. I don't know where the common script is stored, so I've dumped it from RAM (you can find it in in the link below, along with the disassembler). This common script seems to do strange things anyways. For everything else, refer to the disassembler various docstrings. Download link (download the source code, since it's Python): https://github.com/TuxSH/XDscriptTools/releases/tag/v0.1 I'm not sure how I never noticed this before but the "common" script is in common_rel from common.fsys starting at offset 0x5BEE4.
Tux Posted October 26, 2015 Author Posted October 26, 2015 I'm not sure how I never noticed this before but the "common" script is in common_rel from common.fsys starting at offset 0x5BEE4. Thank you . I've looked at this file, but I have not bothered searching for "TCOD"
StarsMmd Posted October 26, 2015 Posted October 26, 2015 Thank you . I've looked at this file, but I have not bothered searching for "TCOD" hahaha I'm always surprised by how much is in common_rel. When I look for things I find them there like 80% of the time. btw, have you managed to do anything cool by editing the scripts?
Tux Posted October 26, 2015 Author Posted October 26, 2015 I've not tried to modify anything ... but looking at the code, you can lift the restriction on Shadow Pkms in the Daycare (w/o adding any instruction, just by modifiying the existing ones), and I'm sure you can change the Pokémon given by Duking (+ Elekid, + the Johto starters) (again w/o adding anything), refer to Party::recieveGiftOrEventPkm(id)
StarsMmd Posted October 26, 2015 Posted October 26, 2015 I've not tried to modify anything ... but looking at the code, you can lift the restriction on Shadow Pkms in the Daycare (w/o adding any instruction, just by modifiying the existing ones), and I'm sure you can change the Pokémon given by Duking (+ Elekid, + the Johto starters) (again w/o adding anything), refer to Party::recieveGiftOrEventPkm(id) Sounds good. So I've been looking at some of the disassembled scripts and I think I'm starting to get a feel for how it all works. For class methods like Party::recieveGiftOrEventPkm(id) or Character::setVisibility did you find out what they do by trial and error and did you name them yourself?
Tux Posted October 26, 2015 Author Posted October 26, 2015 Sounds good. So I've been looking at some of the disassembled scripts and I think I'm starting to get a feel for how it all works. For class methods like Party::recieveGiftOrEventPkm(id) or Character::setVisibility did you find out what they do by trial and error and did you name them yourself? Named them myself (see FunctionInfo for the "whole" list). For Party::recieveGiftOrEvent I already knew the function that was used to generate never-shiny-if-shadow/can-be-shiny-if-not Pokémon, and for Character::setVisibility it was indeed by trial and error when debugging.
StarsMmd Posted October 26, 2015 Posted October 26, 2015 Named them myself (see FunctionInfo for the "whole" list).For Party::recieveGiftOrEvent I already knew the function that was used to generate never-shiny-if-shadow/can-be-shiny-if-not Pokémon, and for Character::setVisibility it was indeed by trial and error when debugging. Yeah I'm looking through your code now. Impressive work .
Tux Posted October 28, 2015 Author Posted October 28, 2015 Looks like there is a buffer overflow vulnerability in the implementation of the script version of printf: ROM:801BE670 # int __fastcall scriptPrintf(void *format, void *args) ROM:801BE670 scriptPrintf: # CODE XREF: scriptStdFunctions2Handler+270p ROM:801BE670 ROM:801BE670 .set var_12C, -0x12C ROM:801BE670 .set sprintf_buffer, -0x128 ROM:801BE670 .set var_28, -0x28 ROM:801BE670 .set var_1C, -0x1C ROM:801BE670 .set lr, 4 ROM:801BE670 ROM:801BE670 stwu r1, -0x130(r1) ROM:801BE674 mflr r0 ROM:801BE678 stw r0, 0x130+lr(r1) ROM:801BE67C stmw r25, 0x130+var_1C(r1) ROM:801BE680 mr r26, r3 ROM:801BE684 mr r29, r4 # ... NOTE: this function refers to "script error line[%d] : printf argument %d error \n" ROM:801BE840 loc_801BE840: # CODE XREF: scriptPrintf+1C4j ROM:801BE840 add r3, r29, r27 # var ROM:801BE844 lha r0, 0(r3) ROM:801BE848 cmpwi r0, 3 ROM:801BE84C bne loc_801BE884 ROM:801BE850 lwz r4, 0x954(r26) # dst ROM:801BE854 bne loc_801BE860 ROM:801BE858 lwz r6, 4(r3) ROM:801BE85C b loc_801BE868 ROM:801BE860 # --------------------------------------------------------------------------- ROM:801BE860 ROM:801BE860 loc_801BE860: # CODE XREF: scriptPrintf+1E4j ROM:801BE860 bl scriptConvertToString ROM:801BE864 mr r6, r3 ROM:801BE868 ROM:801BE868 loc_801BE868: # CODE XREF: scriptPrintf+1ECj ROM:801BE868 addi r3, r1, 0x130+sprintf_buffer # str ROM:801BE86C addi r4, r2, -0x56E8 # aSS # format ROM:801BE870 mr r5, r3 ROM:801BE874 crclr 4*cr1+eq ROM:801BE878 bl sprintf # "%s%s" # BOOOOOOOOOOOOOOOOOOOOOOOOOOOOOM ROM:801BE87C mr r25, r3 ROM:801BE880 b loc_801BEA20 # ... # the buffer is cleared IFF '\\n' is encountered ROM:801BEA2C # --------------------------------------------------------------------------- ROM:801BEA2C ROM:801BEA2C loc_801BEA2C: # CODE XREF: scriptPrintf+80j ROM:801BEA2C cmpwi r0, 0x5C # '\' ROM:801BEA30 bne loc_801BEAB8 ROM:801BEA34 addi r30, r30, 1 ROM:801BEA38 lbz r0, 0(r30) ROM:801BEA3C extsb r0, r0 ROM:801BEA40 cmpwi r0, 'n' # '\n' ROM:801BEA44 bne loc_801BEA94 ROM:801BEA48 addi r3, r1, 0x130+sprintf_buffer # str ROM:801BEA4C addi r4, r2, -0x56D8 # aS_0 # format ROM:801BEA50 mr r5, r3 ROM:801BEA54 crclr 4*cr1+eq ROM:801BEA58 bl sprintf ROM:801BEA5C addi r3, r1, 0x130+sprintf_buffer # msg ROM:801BEA60 crclr 4*cr1+eq ROM:801BEA64 bl sendToLog # '%s\n' ROM:801BEA68 li r5, 0 ROM:801BEA6C li r0, 0x100 ROM:801BEA70 addi r3, r1, 0x130+sprintf_buffer ROM:801BEA74 li r4, 0 ROM:801BEA78 mtctr r0 ROM:801BEA7C ROM:801BEA7C loc_801BEA7C: # CODE XREF: scriptPrintf+418j ROM:801BEA7C stb r4, 0(r3) # clear temporary buffer ROM:801BEA80 addi r5, r5, 1 ROM:801BEA84 addi r3, r3, 1 ROM:801BEA88 bdnz loc_801BEA7C ROM:801BEA8C li r25, 0 ROM:801BEA90 b loc_801BEAC4 # ... ROM:801BEAB8 ROM:801BEAB8 loc_801BEAB8: # CODE XREF: scriptPrintf+3C0j ROM:801BEAB8 addi r3, r1, 0x130+sprintf_buffer ROM:801BEABC stbx r0, r3, r25 ROM:801BEAC0 addi r25, r25, 1 ROM:801BEAC4 ROM:801BEAC4 loc_801BEAC4: # CODE XREF: scriptPrintf+3B8j ROM:801BEAC4 # scriptPrintf+420j ... ROM:801BEAC4 addi r30, r30, 1 ROM:801BEAC8 ROM:801BEAC8 loc_801BEAC8: # CODE XREF: scriptPrintf+74j ROM:801BEAC8 lbz r3, 0(r30) ROM:801BEACC extsb r0, r3 ROM:801BEAD0 cmpwi r0, 0 ROM:801BEAD4 bne loc_801BE6E8 ROM:801BEAD8 addi r3, r1, 0x130+sprintf_buffer # msg ROM:801BEADC lbzx r0, r3, r25 ROM:801BEAE0 extsb r0, r0 ROM:801BEAE4 cmpwi r0, 0xA # '\n' ROM:801BEAE8 beq loc_801BEB04 ROM:801BEAEC cmpwi r25, 0 ROM:801BEAF0 beq loc_801BEB04 ROM:801BEAF4 li r0, 0xA ROM:801BEAF8 stbx r0, r3, r25 # msg ROM:801BEAFC crclr 4*cr1+eq ROM:801BEB00 bl sendToLog ROM:801BEB04 ROM:801BEB04 loc_801BEB04: # CODE XREF: scriptPrintf+478j ROM:801BEB04 # scriptPrintf+480j ROM:801BEB04 li r3, 0 # empty string ROM:801BEB08 ROM:801BEB08 loc_801BEB08: # CODE XREF: scriptPrintf+11Cj ROM:801BEB08 # scriptPrintf+1BCj ... ROM:801BEB08 lmw r25, 0x130+var_1C(r1) ROM:801BEB0C lwz r0, 0x130+lr(r1) ROM:801BEB10 mtlr r0 ROM:801BEB14 addi r1, r1, 0x130 ROM:801BEB18 blr ROM:801BEB18 # End of function scriptPrintf
StarsMmd Posted October 29, 2015 Posted October 29, 2015 Hey, do you think you could add to the script disassembler so that each instruction has it's offset in the script file next to it? It will make it a bit easier to figure out where to go to manually change instructions. Thanks
Tux Posted October 29, 2015 Author Posted October 29, 2015 Done, I've added "--display-code-offsets".
StarsMmd Posted October 29, 2015 Posted October 29, 2015 Done, I've added "--display-code-offsets". sweet, thanks. Gonna come in handy
StarsMmd Posted November 8, 2015 Posted November 8, 2015 Done, I've added "--display-code-offsets". Is the display code offsets option live on github?
StarsMmd Posted April 12, 2016 Posted April 12, 2016 Hey, are you still working on this and have you looked into the scripts any further? I spent a lot of time looking at a bunch of the scripts recently and it's really started to make sense to me. I even tested out a few minor changes which I made manually and it all works as one would expect. In particular have you discovered any more classes/class functions? I've identified a handful more from what was in the repo last time I checked (like giving the player items and triggering battles) and thought I could help add to the list if you haven't discovered them yet. I was also wondering if you knew the significance of the "setline" that appears throughout the scripts because it's just about the only thing I don't understand at this point.
Tux Posted May 14, 2016 Author Posted May 14, 2016 Sorry for not reponding ^^' In particular have you discovered any more classes/class functions? I've identified a handful more from what was in the repo last time I checked (like giving the player items and triggering battles) and thought I could help add to the list if you haven't discovered them yet. I didn't made any research on for some time; however I've identified some other classes (Shadow Pokémon handling, party handling) but the problem is that I'm missing the significance of many of their methods... feel free to PR though. I was also wondering if you knew the significance of the "setline" that appears throughout the scripts because it's just about the only thing I don't understand at this point. It's debugging information, and it's most likely a remnant of a higher-level language being assembled.
StarsMmd Posted May 14, 2016 Posted May 14, 2016 Sorry for not reponding ^^'I didn't made any research on for some time; however I've identified some other classes (Shadow Pokémon handling, party handling) but the problem is that I'm missing the significance of many of their methods... feel free to PR though. It's debugging information, and it's most likely a remnant of a higher-level language being assembled. That's okay So do you know what happens if the setlines are overwritten? Also, does that mean that you never need to use them when writing your own scripts?
Tux Posted May 19, 2016 Author Posted May 19, 2016 That's okay So do you know what happens if the setlines are overwritten? Also, does that mean that you never need to use them when writing your own scripts? It's only debugging info iirc. Pokémon has a debugging menu disabled on retail. I've made a code to make it appear a while ago, but it was PAL only and doesn't work on latest Dolphin releases. Basically it just displays timers, currently running functions on each task with the lines, and the free stack space for each task.
StarsMmd Posted May 19, 2016 Posted May 19, 2016 It's only debugging info iirc.Pokémon has a debugging menu disabled on retail. I've made a code to make it appear a while ago, but it was PAL only and doesn't work on latest Dolphin releases. Basically it just displays timers, currently running functions on each task with the lines, and the free stack space for each task. Oh that's cool. It might be possible to shrink the scripts by removing all the debugging lines. Would make it a lot easier to add new functions without having to worry about the compression sizes!
Tux Posted May 21, 2016 Author Posted May 21, 2016 Why is compression size an issue? Be careful as you'll need to move all branches since they are absolute.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now