May 29th, 2016, 10:28
(This post was last modified: May 29th, 2016, 10:29 by Seravy.)
Posts: 10,463
Threads: 394
Joined: Aug 2015
(May 29th, 2016, 08:01)Bogus Wrote: hi. ive recently started modding mom after stumbling across this page. i used the tweaker at first and eventually sat down and started disassembling. i never used a disassembler before, but serenas database proved to be very helpful.
i did a couple of small things first and then happened to find the function that displays the item window (if you right click an item). since i have a number of items with more than 5 powers, i thought it to be a good idea to have this function display more than 5 powers.
i first wanted to increase the size of the window but that seemed very complicated or impossible. i found out how the strings for the item powers and the descriptions (the part after the comma) are made and so removed the descriptions instead to make room for more powers. i reused the stack adress for the descriptions to take the powers instead, because the descriptions are longer. this part worked fine.
next up i tried to split up the window into to columns of 5 powers each, in case there were more than 5. that didnt work, whenever the item had more than 5 powers, the strings and icons would appear at weird locations and occasionally jumble around. so i tried to jump back and forth between the 2 columns working from the top down. this didnt work either.
in fact, what happens is that the strings change their (utterly wrong) location when the mouse is moved / pressed. the icons dont appear at all.
i dont have an idea why this would happen, i have no experience writing assembly language but from the looks of it, the code is fine. ida can read it and creates a diagram from it that looks like it should.
the memory on the stack i use for my vars should be free as it is in the area that would normally be used by the strings for the item powers. i dont knowingly use any registers other than the ones that are used originally in that location. my best guess at this point is that the game translates my code differently than ida and somehow reads in mouse pointer data.
ive uploaded the databases for the 2 functions on my github. the far calls are based on my wizards.exe and are different from the ones used in serenas db. im unsure tho which version that is based on or which one i am using. in the strings function i only changed a few bytes however, and in the display function the changed code block contains only 2 far calls . (4 originally, 2 are removed)
the get strings function goes from offset 5e5cf to 5eb0a. named sub_69d8f in serenas db
the display function goes from offset 617fc to 619c4. named sub_6cccc in serenas db
https://github.com/KlonZK/master-of-magic
I'm assuming you moved the location of, or otherwise interfered with the far calls used. If so, did you update the relocation tables? (if it's in the ovr part of the file then it needs to be done to the relocation table of the segment instead of the global one.)
Also, did you take the addresses for the calls from the exe file or the disassembler? The latter shows already relocated addresses which cannot be used in the source.
May 29th, 2016, 11:07
(This post was last modified: May 29th, 2016, 11:19 by Bogus.)
Posts: 11
Threads: 0
Joined: May 2016
(May 29th, 2016, 10:28)Seravy Wrote: I'm assuming you moved the location of, or otherwise interfered with the far calls used. If so, did you update the relocation tables? (if it's in the ovr part of the file then it needs to be done to the relocation table of the segment instead of the global one.)
Also, did you take the addresses for the calls from the exe file or the disassembler? The latter shows already relocated addresses which cannot be used in the source.
nope, i didnt move the calls and i took the calls from the exe, not the db. i did remove 2 of the calls, but i tested the exe after removing the calls and changing the adress of the strings, and it worked. it displayed the strings and icons in the normal locations but without the descriptions, as intended. i just jumped over these calls for the test, but to add the code for my changes i needed the space. maybe i just cant have any other code where a call would normally happen?
Posts: 10,463
Threads: 394
Joined: Aug 2015
(May 29th, 2016, 11:07)Bogus Wrote: (May 29th, 2016, 10:28)Seravy Wrote: I'm assuming you moved the location of, or otherwise interfered with the far calls used. If so, did you update the relocation tables? (if it's in the ovr part of the file then it needs to be done to the relocation table of the segment instead of the global one.)
Also, did you take the addresses for the calls from the exe file or the disassembler? The latter shows already relocated addresses which cannot be used in the source.
nope, i didnt move the calls and i took the calls from the exe, not the db. i did remove 2 of the calls, but i tested the exe after removing the calls and changing the adress of the strings, and it worked. it displayed the strings and icons in the normal locations but without the descriptions, as intended. i just jumped over these calls for the test, but to add the code for my changes i needed the space. maybe i just cant have any other code where a call would normally happen?
I assume by deleting you mean replacing by NOP (90h). Those, if a relocation entry points at them, tend to get turned into something that does not cause an immediate crash but might corrupt data in memory. If you disassemble the file after doing that, it'll show something like "add es:[bx+si],70h" in red. There is no crash because it's a valid instruction, but it DOES change data in the memory somewhere at random so it shouldn't be left that way.
You either must leave every far call on the exact same address still functional, or skip them through a jump (only the last two bytes of the 5 byte far call instruction get relocated so replacing 9A,xx,xx,xx,xx with EB,03,xx,xx,xx is safe), or find the relocation table entry referring to that far call and move it to point to the new position of the call. It's also possible to remove or add them if you remove or add into/from the relocation table but in this case you also need to update their size entry in the stubs.
The relocation table itself is located at the end of the segment (only for ovr segments!) and is hidden in the disassembler (you need to find it with a hex editor), and contains 2 bytes per entry which is the offset within the segment (remember the last 2 bytes of the far call is being relocated).
Example : there is a far call at ovr114:0378h. You make changes to the code and it ends up at ovr114:0445h (you find this out by disassembling the file again after the changes, the far call will be red and code where it originally was will be randomly messed up).
First you calculate 0378h+3=037Bh. then you find 7B 03 at the end of the segment in the hex editor. You replace that by 48 04.
Then disassemble again and if it worked the far call will not properly show up and you can click on it to enter the called procedure as usual.
May 29th, 2016, 16:46
(This post was last modified: May 29th, 2016, 16:49 by Bogus.)
Posts: 11
Threads: 0
Joined: May 2016
well that explains the random weirdness that i experienced, thanks a lot for this explanation.
otherwise, i didnt yet look into the whole overlay buisness. where does ida show me which overlay segment im in or if its overlay at all?
also, why calculate 0378 +3? that doesnt quite make sense to me, did you want to write something else?
does the table have a header of some sorts to find it or is just data? where would i find that stub entry to remove these calls? i think i need those bytes the calls take up.
May 30th, 2016, 03:27
(This post was last modified: May 30th, 2016, 03:29 by Seravy.)
Posts: 10,463
Threads: 394
Joined: Aug 2015
(May 29th, 2016, 16:46)Bogus Wrote: well that explains the random weirdness that i experienced, thanks a lot for this explanation.
otherwise, i didnt yet look into the whole overlay buisness. where does ida show me which overlay segment im in or if its overlay at all?
also, why calculate 0378 +3? that doesnt quite make sense to me, did you want to write something else?
does the table have a header of some sorts to find it or is just data? where would i find that stub entry to remove these calls? i think i need those bytes the calls take up.
switch the view from graph to text and you see the segment and offset for each line of code.
+3 because a far call is 9A xx xx yy yy where yy yy is the part the relocation needs to point at, the 3rd byte of the 5 byte instruction. To be more specific, xxxx is the offset of the jump, and yyyy is the segment, and relocation only needs to be done to segment addresses.
the table is just data at the end of the segment. The easiest way to find is going to the beginning of the next segment in the hex editor and move backwards. The 00s are the empty space where you can add more relocation entries, and the numbers before them are the entries in use.
ofc if you know the entry you are looking for, hitting search for the exact bytes inside the segment you work on will get it found the fastest.
The stub shows up in IDA and the line marked "relsize" is the size of the relocation. (It's in bytes so 1 entry adds or subtracts 2 from this number)
May 30th, 2016, 07:21
(This post was last modified: May 30th, 2016, 07:23 by Bogus.)
Posts: 11
Threads: 0
Joined: May 2016
alright, thx. you have been a great help. for now, jumping over the calls was enough, i made some room.
change function at 5e5cf to return strings for up to 10 powers and ignore descriptions:
5e5d7: 8b 7e 08 -> xx xx 0a
5e5f1: ba 28 00 -> xx 14 xx
5e606: 83 7e fe 05 -> xx xx xx 0a
5eac8: 59 59 -> eb 1d
5e6a0, 5e724, 5e7a8, 5e831, 5e8b5, 5e939, 5e9c0, 5eaf3, 5eaf8: 83 fe 05 -> xx xx 0a
5eafd: be 05 00 -> xx 0a xx
display function at 617fc:
use large font for up to 8 powers in display
618bb: 83 7e fc 05 -> xx xx xx 09
display strings and icons in new locations and use the new pointer to the strings:
replace code block from 61937 to 619be with
C6 46 ED 00 C7 46 EB 00 00 BB 0B 00 3B 76 FC 7D
72 EB 2C XX XX XX XX XX 83 C4 08 57 8B C6 BA 14
00 F7 EA 8D 96 C8 FE 03 C2 50 8B 46 E9 8B 56 F8
03 D0 52 8B 46 EF 90 50 XX XX XX XX XX EB 3D 8B
46 EB F7 6E FA 89 46 E9 80 7E ED 01 7D 04 EB 0E
XX XX BB 80 00 FF 46 EB C6 46 ED 00 EB 04 C6 46
ED 01 8B C3 05 09 00 89 46 EF FF 76 0A 57 8B 46
E9 05 22 00 50 53 E9 9A FF 90 XX XX 46 83 C4 08
E9 86 FF 90 90 90 90 90
the X are the far call locations.
there is some room for optimization, and removing the description code frees up some space in the area that is currently unsused.
|