Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to create an engine patch #67

Open
KionX opened this issue Jan 27, 2024 · 0 comments
Open

How to create an engine patch #67

KionX opened this issue Jan 27, 2024 · 0 comments

Comments

@KionX
Copy link
Collaborator

KionX commented Jan 27, 2024

How to create an engine patch

Tested under Windows.
For those who ask if it can be simpler: No.

Step-by-step example of manual crash analysis

Preparation of the required software(strong recomended).

Install MSYS2: www.msys2.org
Install GCC x32/x64 via MSYS console:
x32: pacman -S mingw-w64-i686-gcc
x64: pacman -S mingw-w64-x86_64-gcc
Optional pacman -S mingw-w64-i686-make

The latest release of the EXE patcher:
Repo with guide: github.com/FAForever/FA_Patcher
Direct download: github.com/FAForever/FA_Patcher/releases/latest/download/FaP.exe

Basic EXE of the game:
content.faforever.com/build/ForgedAlliance_base.exe

Optionally install Git: git-scm.com

Engine patches: github.com/FAForever/FA-Binary-Patches

Put the EXE of the patcher, the base EXE of the game, the patches of the engine in one folder.

To compile a patch, just run FaP.exe
By default, a new file is created in the same folder and named ForgedAlliance_exxt.exe
In config.txt you can specify paths and other patcher settings.

What's where?

/hooks contains only ASM.
/section contains ASM/C/C++(the standard library is partially available).
define.h(created by the patcher) contains all addresses from /section.

All or almost all known engine structures: /section/include/moho.h
Pointers to common functions and main classes: /section/include/global.h
Everything you need to work with LUA: /section/include/LuaAPI.h
List of all engine functions that are called from LUA: /section/include/LuaCFuncs.h
Misc info: /Info.txt

How do I add a new LUA function?

Examples:
Global function: /section/SimSetCommandSource.cpp
Another way to add global function: /section/CopyToClipBoard.cpp
Class methods: /section/ProjectileNewMethods.cpp
Console var: /section/IconScale.cpp
Lua table methods: /section/GetTableSize.cpp

The subtleties of working with the section.

You can mix everything in the section files(very don't recommend it).
Example: /section/gpg_net.cpp

If you need to work with the processor register from C, you can do this: register int eax asm("eax");

Subtleties of working with hooks.

The main rules are described in the patch repo.

It is critically important to make sure that the hooks are embedded exactly(bytes, registers, stack) and do not break the rest of the code.
If the hook does not fit, you can transfer part of the instructions to the /section file.
Example: /hooks/HUpgradeProgressFix.cpp , /section/UpgradeProgressFix.cpp

You can also place the code in several unoccupied places.
Example: /hooks/HFix4GB.cpp

GCC always compiles JMP/CALL with a long(4 bytes) offset.
The way to make it use a short(1 byte): JMP .-0x73;
If you use CALL, you need to return via RET or fix the stack before returning.

Global variables can be declared in both hooks and section files.

Example of string patching: /hooks/LuaMessages.cpp
Example of loading a DLL: /hooks/HFAExtLoad.cpp , /section/FAExtLoad.cpp

C++ Demanglers

demangler.com
d.fuqu.jp/c++filtjs

Profilers

Lua in game: github.com/FAForever/FAFProfiler

@KionX KionX pinned this issue Jan 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant