Live wire capture is the final validation step after static RE — it confirms that byte offsets, field sizes, and padding behavior match what was decompiled from the binary. Use static analysis findings first to know exactly what you are looking for on the wire, then use this guide to set up the capture and verify each claim.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.
No live capture is performed automatically by the corpus tools. Use this checklist on your own client/server pair running
Game.exe MD5 c1edd966… and ps_game.exe MD5 91b212af…. Game port is typically 30800/tcp — confirm in your server.ini / client connect.cfg.Prerequisites
| Tool | Role |
|---|---|
Wireshark / tcpdump | TCP payload capture after game handshake (post-0xA101 if encryption enabled) |
x64dbg on ps_game.exe or Game.exe | Hook plaintext at SConnection_Send / recv dispatch |
| Optional Frida / custom DLL | Stable logging of [opcode, len, hex] at 0x004ED0E0 |
Connection_DecryptInbound @ 0x00464FA0 (server) or client PacketPayload_Decrypt @ 0x00401080, before Chat_ProcessIncoming @ 0x0047F400 / client PacketDispatcher @ 0x005F1E10.
Wireshark / tcpdump BPF Filter
ReplaceSERVER_IP and PORT with your server’s IP and game port:
SConnection_EnqueueWrite @ 0x004EF080), strip that header in a Lua dissector before matching 0x11xx.
Capture Triggers by Opcode
| Opcode | Channel | Typical trigger |
|---|---|---|
0x1101 | Normal | Any chat message in the default channel |
0x1102 | Whisper | /w PlayerName message — expect two S→C frames (dir=0 to target, dir=1 echo) |
0x1103 | Trade | Chat in trade channel |
0x1104 | Guild | Chat in guild channel |
0x1108 | Megaphone | Megaphone item use |
0x1111 | Area | Area/zone channel message |
0x1109 / 0x110A | NPC/script zone push | Trigger zone script or NPC dialog — server-side only (S→C) |
0x110B | Channel label | Entity label push — S→C only |
char[21] Tail Capture — D1 Artifact
Pattern B packets (0x1103, 0x1104, 0x1108, 0x1111) carry a char[21] sender name field. Static analysis of Chat_BroadcastGuild @ 0x00432530 confirms no memset before SConnection_Send — the tail bytes after the NUL terminator are uninit stack residue.
Set breakpoint at SConnection_Send
In x64dbg (32-bit), attach to On hit (stdcall):
ps_game.exe and set:[ESP+4] = SConnection*, [ESP+8] = payload pointer, [ESP+0xC] = size.Filter for guild packets
Add a conditional log command:Filter hits where
*(u16*)payload == 0x1104 and size == 0x18 + *(payload+23).Hexdump the name[21] field
Log the 21 bytes starting at For a guild packet from a player named “JACKSON” (6 chars): bytes
payload+2:0x00–0x05 = 4A41434B534F4E, byte 0x06 = 0x00 (NUL), bytes 0x07–0x14 = tail.Classify tail bytes
Inspect bytes at indices
strlen(name)+1 through 20:| Outcome | Tag |
|---|---|
All 0x00 | Emulator zero-fill — not stock |
| Non-zero stable garbage | CONFIRMED stack junk — zero-fill in emulator |
| Varies per send | Log multiple sends to characterize |
Pattern B Field Offsets
| Opcode | Dir | size formula | name[21] region | Len byte | Text start |
|---|---|---|---|---|---|
0x1104 guild | S→C | len+0x18 | payload+2 … payload+22 | payload+23 | payload+24 |
0x1103 trade | S→C | len+0x18 | payload+2 … payload+22 | payload+23 | payload+24 |
0x1108 megaphone | S→C | len+0x18 | payload+2 … payload+22 | payload+23 | payload+24 |
0x1111 area | S→C | len+0x18 | payload+2 … payload+22 | payload+23 | payload+24 |
0x1102 whisper | S→C | len+0x19 | payload+3 … payload+23 | payload+24 | payload+25 |
0x1102 whisper | C→S | len+0x18 | payload+2 … payload+22 (target[21]) | payload+23 | payload+24 |
0x0812 alliance | S→C | len+0x1C | payload+2 … payload+22 | payload+23 | payload+24 |
NPC Script Push Capture — D4 Artifact
Captures of0x1109 / 0x110A / 0x110B require triggering the right in-game event.
Identify the trigger
| Opcode | Typical trigger | Builder VA |
|---|---|---|
0x1109 | NPC/script zone chat | 0x004C6A80 (flag 0) / 0x004C6F50 (flag 1) |
0x110A | Union message ID push | 0x004C8310 |
0x110B | Channel label on entity | 0x004C8520 |
Break at SConnection_Send and filter
opcode = *(u16*)payload, size, and the first min(size, 64) bytes.Finding Opcodes in Captures with offline tools
extract_plaintext_opcodes.py
Use this tool on any decrypted binary blob or packet dump:scan_capture_logs.py
Scan existing MITM/session log files foropcode=0xXXXX markers and raw hex patterns:
0xA101 Counter Capture — D3 Artifact
Capturing the0xA101 login packet for counter derivation requires an additional step to obtain the PRNG seed.
Capture the login packet
Run
tcpdump or Wireshark on the login port (typically ~30900) at the moment the client connects:Extract the 197-byte plaintext
The
0xA101 packet is plaintext on the login socket. Export the 197-byte body as hex.Capture the PRNG seed from memory
In x64dbg (32-bit) attached to On hit at
Game.exe, set two breakpoints:0x00404610, dump the 128-byte PRNG buffer from the buffer pointer passed in EAX.Whisper C→S vs S→C (0x1102)
The whisper opcode has different layouts in each direction:| Direction | Layout (after opcode) | size | Notes |
|---|---|---|---|
| C→S | target[21] @ +0x02 · len @ +0x17 · text @ +0x18 | len+0x18 | PacketSend_Whisper @ 0x005ED160 |
| S→C | dir @ +0x02 · name[21] @ +0x03 · len @ +0x18 · text @ +0x19 | len+0x19 | Dual send @ 0x0047F685, 0x0047F6F9 |
payload+0x16 (last byte of C→S target[21]) @ 0x0047F608 before World_FindUserByName. One whisper A→B produces two S→C 0x1102 frames: dir=0 to target, dir=1 echo back to sender.
Limitations
- Encryption: NAT/port forwarding changes endpoint IPs — BPF must follow the actual TCP stream.
- Script-only opcodes:
0x1109/0x110A/0x110Brequire triggering the right NPC or zone script. Empty captures usually mean wrong trigger, not wrong VA. - Session vs game port: existing
ps_session_redis/captures/logs cover the session port only — they contain0xA101but not game-channel0x11xxopcodes.