Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Husbjörn

Pages: [1]
I have recently managed to manipulate a program to set the upper bound of a for-loop to a desirable value through de- and reassembling it.
However, due to reasons I'm not allowed to modify the physical executable file (or rather, I wouldn't be able to release a modified version of it legally). I was therefore wondering what my options are to achieving this patching on the fly? The actual instruction in question is a MOV operation where I need to modify the second, literal argument.
ReadProcessMemory is unable to view this value (presumably because it isn't stored on the heap?) so that won't work. It feels like there should be some way to achieve this.

What I have at my disposal is access to a dll that is loaded and used by the application in question, so I should hopefully have the required access rights. The program in question is furthermore a Win32 application that is always run as an administrator.
Any ideas or suggested reading?  ???

Misc. Tools / [FFX] Skill editor - Ronso (v0.3.1.0)
« on: 2015-08-06 14:08:44 »
Ronso is a skill editor for Final Fantasy X.
As of version 0.3, both emulated PS2 versions of the game and the HD Remaster version released for PC through Steam are supported*.
It works through run-time memory editing and was initially developed as a tool for generating ActionReplay / GameShark / XPloder codes for the PS2. However with the advent of a proper PC version of the game, the application is quite capable of being used as-is and not just as a tool for use with the afforementioned other devices.
As for reliability, the memory regions of interest are identified by scanning for memory patterns that seem to be at constant offsets to the skill and string data. While the Steam version seems a bit trickier with its memory organization than the original PS2 version, I believe that Ronso should now be able to find the skill tables in memory for it too reliably. No guarantees though; I only got my hands on the PC version yesterday at the time of writing this.

The application requires .NET Framework 4.5 and makes use of ReadProcessMemory / WriteProcessMemory, so it will most likely require administrative privileges if you have UAC enabled.
Download Ronso v0.3.1 here.

2016-05-20 - New in version 0.3.1:
Code: [Select]
* Fixed a bug where changing the damage calculation wouldn't update the skill table.
 * Found addresses for skill category and icon.
 * Found bit flags for "normal" and "extended" delay status infliction.

2016-05-16 - New features in version 0.3:
Code: [Select]
* Preliminary support for the Steam version of the game.
* Can transfer skill data between emulated PS2 versions and the Steam version of the game.
* The window can now be resized.
* Identified miscellaneous bit flag #22 and added a checkbox for this. If set, the actor's equipped weapon's damage formula and strength will be used instead of the ones specified for the skill itself.

2015-08-16 - New features in version 0.2:
Code: [Select]
* Enemy-exclusive skills can be edited.
* The current settings for all skills can be saved and loaded; upon loading, the memory of the opened emulator process is updated to match what was previously saved.
* Individual skills can also be exported / imported.

From what I've been able to find out, skill data is stored in a list of 96 bytes per skill (or rather 95 bytes since it appears the 96:th byte is always 0 and might be used as some kind of separator / padding). The current version of Ronso can edit each and everyone of said bytes. About 2/3:rds of the data is known; should you happen to know of / figure out any other values I would be happy to hear about it.

Skill names and descriptions are stored in a separate memory region and are referenced by skills by an offset into this string table.
Ronso allows you to select offsets as well as edit the strings themselves.

There is no clear "end" of the string table data; the skills use 16-bit offsets into it which means they can at most reference a string stored 65535 bytes in, however the actual string data ends long before this (after 13826 bytes in the english PAL version). Because other languages probably having different-length strings, the string table editor allows you to edit up to offset 17408 (0x4400) from the start of the string table, which I assume should definately be enough for any language version. After the strings there is some unknown data that you probably don't want to overwrite with strings, and a bit after that comes scan descriptions for the main characters. Fortunately there are a couple of appropriately named "Extra xx" entries at the end of the string table. There also are a bunch of named skills that never show their name in the actual game that you can replace and use if you so chose, such as all of Wakka's different overdrive shots, complete with descriptions of the "Wakka's personal skill xy" persuasion.

Most editable fields contain a single byte value. These are to be entered as decimal values for everything except status infliction rates, which use hexadecimal values instead. The reason for this is that 0xfe (254) is considered the highest probability value by the game, whereas an infliction rate of 0xff (255) means the status will be inflicted on the opponent regardless of whether it's immune to it. The only player-accessible skill that uses this by default is Zanmato, which forces infliction of the death status on all targets.
By right-clicking a single-byte field, the flag manager will be opened:

This allows you to view and edit a byte value as either a decimal or hexadecimal value as well as a set of bit flags.
This functionality is also available for the "custom byte" field that can be used to access parts of wider values (such as the animations, string offsets or miscellaneous flags) as their individual bytes.

In addition, skill data can be copied by right-clicking the relevant skill in the list on the left. When a skill is copied it can either be pasted over a different skill, or it can have its individual bytes compared to another skill; both of these operations are available from the same right-click menu of the skill list. In the current version (0.2), only byte fields (including the custom one) are compared by the comparison operation, ie. checkboxes, names and wider-bit fields are not compared against each others.

As for the two animation index fields, the first one is the animation to use for skills that are used on land, while the second one is a special animation that is used if the skill is used under water. These can off course both be set to the same animation id.

Finally, I'll list what I know about those fields that have question marks in their descriptions.
  • Menu - this appears to be a set of bit flags. If bit 7 is set, the skill becomes usable from the menu. However, it cannot target any player character after selecting it from the menu; something else likely affects this, or possibly it is hardcoded to only work with HP-restoring skills.
  • Overdrive - this seems to be the "overdrive cost" of the skill. A value of 20 (0x14) will deplete the entire overdrive gauge while smaller values reduce the overdrive gauge by value/20. Skills that have a non-zero value here will be grayed-out unless the user's overdrive bar is full. The skill will also display the overdrive "cast" animation prior to use if this value is set.
  • Byte 48 - this might be the probability to shatter a petrified target given in decimal percents (0..100)?

Also, thanks to ppbirdman for listing the available effect calculation formulas in his Ultimate Companion Guide.

I have been trying to reverse engineer the battle abilities / skills from FFX and have made decent progress with regards to stats (power, calculation formulas, mp cost, etc.), flags (targets, elements, types, stealing, menu usability), names / descriptions, status infliction / removal rates and visual animations. There are still about 20 bytes of data per skill I haven't been able to decipher however. Also, there doesn't really seem to be much, if any, information on this available online for whatever reason, but I'm pretty sure there are people around who do posess this knowledge judging by youtube videos of "hacks" etc. If not, I'd be happy to share what I've found out.

Anyway, on to my question at hand.
It appears that the visual animations for skills have camera and character animations built-in (though as for the character's casting animation it seems this can sometimes, but not always, be changed by setting byte 25 in the skill data). Unfortunately this has the end result that most animations used for enemy skills tend to have the camera shift away from the targets and focus solely on the caster for the entire duration of the animation, which naturally isn't desirable. I was wondering if anybody know of a way to get around this (if indeed there is one without needing to find and modify the individual animation data itself). I have so far come up with nothing which is rather off-putting.

I noticed that the experience and gil rewards for defeating an enemy can be altered by changing its 0x42e0 and 0x42c0 values.
this page similarly suggests that tha AP value resides at offset 0x42b0.
It however turned out that changing this value has no discernible effect at all. I first thought that it might be that something else has the final say in what the AP value will be, but upon checking the value stored at Actor<word>[0x42b0] with the following simple counter script, it appears that this isn't even set to the actor's AP value as set in scene.bin at all:

0000| 02    2060        # Push self mask value
0003| 02    42B0        # Push AP reward offset value
0006| 80                # Resolve AP reward value of self and push it onto the top of the stack (as a 16-bit word)
0007| 61    03E8        # Push constant 16-bit word value (1000; corresponds to actor AP value set in scene.bin)
000A| 40                # Push true if the top values of the stack (popped) are equal, or false otherwise
000B| 70    0015        # Jump to offset if the values were not equal
000E| 93    "Equal\0"
0015| 93    "Not equal\0"
0026| 73

Memory scanning further reveals that the actual location of the AP value once loaded into RAM is always 15 bytes prior to the gil value, which is 4 bytes wide and followed immediately by the EXP value, occupying another 4 bytes. It is off course possible that the actual memory used by the process does not reflect the actor-data offsets used by the 0x80 instruction and no, altering the value at Actor<word>[0x4248] does not change the AP value either.

Is the memory offset suggested by the above wiki link incorrect or is something else at play here? Any thoughts or theories?

Edit: and what the heck, when previewing this post I notice that it automatically shows "off course" as "off course" even though it doesn't say that in the textarea I submitted? Some easter egg trolling?  ::)
Edit 2: apparently it happens in the final post as well; just to be clear "of course" is spelled with an "of" not an "off", unless you want the whole meaning changed... x)

I wonder if someone would be able to elaborate on exactly how the "select greatest / least from list" instructions (opcodes 0x84 and 0x85) work?
Let's take an example of trying to select an opponent with the lowest HP to illustrate my point:

02    20b0                # Push current actor's active enemy mask
03    4160                # Push offset to HP value of (target) actor(s) as given in the above mask
80                        # Pop last two values from the stack and push a list of all HP values for the current actor's active enemies
85                        # Select the lowest value(s?) from the list at the top of the stack

I would have assumed that the above would push a 16-bit mask onto the stack with the bit corresponding to the enemy actor with the lowest HP set.
This does not seem to be the case however as more than one bit seems to be set. I could kind of understand if this happened if two actors had the same health which also happened to be the lowest but that is not the case. I then thought that it might push the actual index corresponding to the bit to be set instead (such that it for example pushes 3 for actor 3, rather than a 0%0010 mask) but that doesn't seem to be it either. The last possibility I can imagine is that it pushes the actual lowest HP value, but if this was the case what good is the instruction? While it would be possible to get the actual lowest HP value if we knew the actor to whom it belonged, the same cannot be done in reverse.
Or am I missing the point of these instructions entirely?

Another kind of associated question while we're at it, are lists on the stack formed in some way that they can be manually constructed (or read) by pushing / popping values / addresses or are they their own thing beyond manual control from a script perspective? I am guessing the latter since they tend to be described merely as "datatype 2X".

I've begun looking into modifying some FFVII battle scenes for fun on my free time and have run into a bit of an annoyance with actor animation indices (as in the actual animations performed on the actor's mesh such as "physical attack", "throw", "cast", etc.).
It would seem that these aren't structured in any particular way; some models have a set of valid ID's at 1 .. 5 or something, then there are a bunch of id's that will freeze the battle if they are used and then there can be a usable one again at id 220. Since trial and error for every individual actor gets extremely tedious with 255 possible indices and the fact that the game will freeze once you happen upon an invalid one, forcing a complete restart to investigate the next probable fail-id, I was wondering if it is known where this animation is available (it would make sense that the game is aware of valid indices in one form or another)? My guess would be that it might be stored in the xxda files in battle.lgp but I haven't been able to find any specifications on the format of those. I'd try to dig in and see what I can find out myself but those files are dauntingly large and I see little reason to reinvent the wheel as it were if this information is perhaps already known.

Pages: [1]