Kaplas80 / TF3

Translation Framework v3
MIT License
20 stars 1 forks source link

[Feature request] Script support for patching strings from a list of offsets #21

Closed mosamadeeb closed 2 years ago

mosamadeeb commented 2 years ago

Is your feature request related to a problem? Please describe. I would like to suggest a method of passing a list of offsets to a converter using the game script. Those offsets would point to offsets of strings that can be extracted/translated, where the only thing that needs to be updated would be the offsets themselves (i.e. write new string offset at address x, where x was given to the converter from the game script).

Describe the solution you'd like A way of passing a list of offsets (or a list of lists of offsets, if a string's offset is written in multiple places) to a converter so that strings can be extracted from those offsets, and can be written back with the offsets updated.

Describe alternatives you've considered A Parameter can be added to the script and used with the converter, so two alternatives I can think of are:

However, the first alternative sounds more of a hack than a solution, and the second alternative would require that the converter gets the current working directory and looks for the file somewhere (maybe in the scripts folder). This would have to be updated (either in the script or in the converter class) whenever the script directory in TF3.Core changes, so it also sounds like a hack.

If TF3.Core had a method of getting the script directory, that can be used from inside a plugin, then this would make the 2nd alternative slightly more valid.

Additional context I am suggesting this method to allow patching files that do not have an easily reversible format, or files in which the strings are not easy to detect/distinguish from other data (except when checked by human eyes). An example would be PS3 EBOOTs, where you can patch an elf by converting the file offsets to the virtual addresses and updating them, after adding the strings to the end of a segment.

Kaplas80 commented 2 years ago

I'm not sure if it is possible to create a "generic plugin" for that kind of translation. For example, in Windows .exe files, it isn't enough just adding the new strings at the end of the file, but you need to define a new exe section in the header with proper permissions. Fortunately, there is a library in C# that does it, but I don't know if something similar exists for elf files.

In TF2, I used a similar approach to translate the strings inside the .exe of Trails in the Sky: First I searched all strings with Ghidra and made a list of strings offsets and their references inside the code. To update the references, I had to search what type of instruction referenced the string and update it properly. But I have no knowledge about PS3 opcodes, so I don't know how it references the memory positions.

And about the method to get the scripts folder, I think it isn't necessary. That folder is always relative to the TF3 executable, so you should be able to access it like I do to the plugins folder in this line

mosamadeeb commented 2 years ago

Well, that answers all of my questions, thanks!

The way I wrote it was a bit confusing, but I wasn't asking for a generic patcher, just a way of passing on a list (and where that list should be stored). The converters themselves would be provided by each plugin that needs them.

But because of this:

That folder is always relative to the TF3 executable, so you should be able to access it like I do to the plugins folder in this line

I now know that I can just load a file from the scripts/plugins folders.

As for the elf patching, it's really simple. I was using a python script to do this, and all it does is write the strings at the end of a segment, and patch the offsets (after converting them to the virtual space). The segment that the strings will be written to can then have its file/virtual sizes updated, and it would work just fine. This isn't a concrete method, but it usually doesn't have issues if the executable has an empty segment defined (so I don't have to define a new segment).

This works because PS3 elfs just load data from an offset table, so I don't have to update any instructions, just the offsets themselves (inside the table).

First I searched all strings with Ghidra and made a list of strings offsets and their references inside the code.

This is exactly the same format I want to have. Do you think it would be more appropriate to store these offsets in a separate json in the scripts folder?

Kaplas80 commented 2 years ago

Do you think it would be more appropriate to store these offsets in a separate json in the scripts folder?

Yes, I think it's better to keep the offsets in a separated file, in that way, we can reuse the plugin for other games.

mosamadeeb commented 2 years ago

Thanks, that answers all of my questions.