Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ThalissonTMora/shaiya-chat-native-re/llms.txt

Use this file to discover all available pages before exploring further.

The .c files committed to this repository are generated by a set of Ghidra headless-analysis scripts that export decompiled C from specific virtual addresses in the Shaiya Core V9 binaries. This page walks through installing the required tools, setting environment variables, and running or customising the export scripts. All scripts must be run from the repository root and all binaries must be verified before use (see the Binaries page).

Prerequisites

The scripts require a specific JDK version and a matching Ghidra release. Both are expected to live under ~/tools/ so the scripts can locate them via environment variables.
ToolVersionExpected path
JDK21 (21.0.6+7)~/tools/jdk-21.0.6+7
Ghidra11.2.1 PUBLIC~/tools/ghidra_11.2.1_PUBLIC
1

Download and unpack JDK 21

Obtain the jdk-21.0.6+7 build (Eclipse Temurin or equivalent) and unpack it to ~/tools/:
tar -xzf jdk-21.0.6+7-linux-x64.tar.gz -C ~/tools/
# Result: ~/tools/jdk-21.0.6+7/
2

Download and unpack Ghidra 11.2.1

Download ghidra_11.2.1_PUBLIC from the Ghidra releases page and unpack it:
unzip ghidra_11.2.1_PUBLIC_20241105.zip -d ~/tools/
# Result: ~/tools/ghidra_11.2.1_PUBLIC/
3

Set environment variables

Export JAVA_HOME and GHIDRA_HOME before running any script. Add these lines to your shell profile (.bashrc, .zshrc, etc.) for persistence:
export JAVA_HOME=~/tools/jdk-21.0.6+7
export GHIDRA_HOME=~/tools/ghidra_11.2.1_PUBLIC
Verify the paths resolve correctly:
$JAVA_HOME/bin/java -version
ls $GHIDRA_HOME/support/analyzeHeadless
4

Verify binaries

Before running any export script, confirm that the binaries in bin/ match their expected MD5 hashes:
md5sum bin/Game.exe bin/ps_game.exe bin/ps_login.exe
# c1edd96639ad81835624b9c4516ac781  bin/Game.exe
# 91b212afbe6623382713772489dc82ce  bin/ps_game.exe
# de5b348cca36e0585f06be93f013fa6d  bin/ps_login.exe
5

Run an export script

All scripts live under tools/ghidra/ and must be invoked from the repository root:
./tools/ghidra/decompile-game-chat.sh
Generated .c files are written into the appropriate output folder (game-chat-native/, psgame-chat-native/, or pslogin-chat-native/). A copy of the manifest used for that run is also written to the output folder when the script finishes.

Decompile Scripts Reference

Each script targets one binary (or a subset of two) and writes output to a specific folder. Never run a script and redirect its output to a different folder than listed here.
ScriptBinaryOutput folderPurpose
decompile-game-chat.shGame.exegame-chat-native/Full client chat export driven by game-chat-functions.manifest
decompile-psgame-chat.shps_game.exepsgame-chat-native/Full world-server chat export driven by psgame-chat-functions.manifest
decompile-pslogin-crypto.shps_login.exepslogin-chat-native/Login-server key-blob path driven by pslogin-crypto-functions.manifest
decompile-crypto.shGame.exe + ps_game.exe*/crypto/ subsetAES-CTR cipher functions from both client and server
decompile-mini.shAny target + custom manifestSame as targetFast subset export for a single custom manifest file
Run any script from the repo root:
./tools/ghidra/decompile-game-chat.sh
./tools/ghidra/decompile-psgame-chat.sh
./tools/ghidra/decompile-pslogin-crypto.sh

Subset Export with decompile-mini.sh

When you only need to regenerate a small slice of functions — for example, the balloon-UI writer group — use decompile-mini.sh with a custom manifest file. This avoids a full re-analysis of the entire binary and is significantly faster.
./tools/ghidra/decompile-mini.sh game tools/ghidra/balloon-ui-writers.manifest
The first argument selects the target binary (game, psgame, or pslogin). The second argument is the path to any manifest file in the format described below. Output is written to the same folder as the corresponding full export script (i.e., gamegame-chat-native/).

Manifest File Format

Every export script is driven by a manifest: a tab-separated text file that lists the functions to decompile. The header comment on line 1 identifies the binary, MD5, ImageBase, and the regeneration script.
# binary=Game.exe md5=c1edd96639ad81835624b9c4516ac781 imagebase=0x00400000 regen=tools/ghidra/decompile-game-chat.sh
category	SymbolName	0x0047F400
Each data row has exactly three tab-separated fields:
FieldDescriptionExample
categoryLogical grouping used in the top-category tablehandlers
SymbolNameThe name Ghidra assigns to the exported functionChat_ProcessIncoming
0xVAAbsolute virtual address (relative to ImageBase 0x00400000)0x0047F400
Comment lines starting with # are ignored by the script and can be used freely to document sections of the manifest. The category field has no runtime effect — it is purely for human organisation and the top-category summary in the README.

Adding Functions to a Manifest

To add a new function to an existing export:
  1. Find the function’s virtual address in Ghidra (right-click → Copy Address).
  2. Decide on a category and a descriptive symbol name.
  3. Append a row to the appropriate manifest file:
handlers	Chat_NewHandler_1115	0x005E5A00
  1. Re-run the corresponding export script to regenerate the output folder:
./tools/ghidra/decompile-game-chat.sh
The new .c file will appear alongside the existing exports in game-chat-native/.

The ExportDecompileByAddress.java Script

The Ghidra headless scripts call a custom Java script located at:
tools/ghidra/scripts/ExportDecompileByAddress.java
This script is invoked by analyzeHeadless for each address in the manifest. It decompiles the function at the given VA and writes a .c file with a standardised header comment that includes the binary name, MD5, ImageBase, and the manifest row that triggered the export. You do not need to edit this file directly — all customisation is done through the manifest files and the shell wrapper scripts.

Rules

Never mix .c files from different binaries in the same folder. The header comment in every generated file (// binary=Game.exe md5=...) ties it to a specific executable. Mixing files from Game.exe and ps_game.exe in the same folder corrupts the corpus and breaks manifest-driven traceability.
  • Do not hand-edit generated .c files. They are outputs, not sources. Any manual change will be overwritten the next time the export script runs. If the decompilation is wrong, fix the analysis in Ghidra, update the manifest if needed, and regenerate.
  • Headers in .c files identify binary + MD5. Use these headers to verify provenance when reviewing pull requests or merging contributions.
  • All VAs are relative to ImageBase 0x00400000. There is no ASLR. Load each binary in Ghidra with ImageBase set to 0x00400000 or the addresses in the manifests will not match.

Build docs developers (and LLMs) love