Stock Shaiya Core V9 server builders copy the player name into a stack-allocatedDocumentation 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.
char[21] using a null-terminated do/while loop, but never call memset on that 21-byte region before sending. The wire send size is always strlen(name) + 0x18 — meaning the full 21-byte name field is placed on the wire every time. As a result, bytes [strlen(name)..20] are uninitialized stack residue rather than zero padding. This page presents the static evidence for that claim, documents the simulation tooling, and explains what emulator authors must account for when replaying or generating Pattern B chat packets.
Pattern B Paths — Stock Behavior
Every Pattern B chat builder in the V9 binary follows the same pattern: copy name via a null-terminated loop, skip any tailmemset, and send with a fixed size that includes the entire 21-byte field.
The send size
len + 0x18 (or len + 0x19 for some variants) accounts for the full 21-byte char[21] name field on every path. No Pattern B path conditionally shortens the name segment.| Path | Builder / VA | Tail zeroed? | Key addresses |
|---|---|---|---|
Guild 0x1104 | Chat_BroadcastGuild @ 0x00432530 | No | copy @ 0x004325B0, send @ 0x00432615 |
Admin guild 0xF104 | AdminChat_BuildGuildPacket @ 0x00432770 | No | send @ 0x00432818 |
| GM guild relay | — @ 0x004070BC / 0x0040714E | No | — |
Megaphone 0x1108 | Chat_ProcessIncoming → Chat_BroadcastNamed | No | copy @ 0x0047F580, add edi,0x18 @ 0x0047F5A3 |
Trade 0x1103 | Chat_ProcessIncoming case 0x1103 | No | copy @ 0x0047F760, queue flush |
Area 0x1111 | Chat_ProcessIncoming case 0x1111 | No | copy @ 0x0047FBD0 |
Monitor 0xF502 | Chat_BuildOutgoing_F502 @ 0x0047F260 | No | copy @ 0x0047F2B0, send @ 0x0047F32C |
Static Evidence
The table below lists every material claim in this analysis together with its verification status. All confirmations were produced by static disassembly of the V9ps_game.exe and Game.exe binaries; no runtime execution was required.
| Claim | Status | Basis |
|---|---|---|
Send size includes all 21 name bytes (len+0x18 / len+0x19 everywhere) | CONFIRMED | Size literal present at every Pattern B send callsite |
Server does NOT memset name tail before SConnection_Send | CONFIRMED | 5 chat-tagged Pattern B direct sends; 0 memset / rep stos found in 80-instruction window before each send |
MSVC prologue does NOT zero stack (sub esp,N + cookie xor only; no rep stos before copy loop) | CONFIRMED | Prologue disassembly on all 5 builders |
Trade/area builders also skip tail memset (0x1103 copy @ 0x0047F760, 0x1111 copy @ 0x0047FBD0) | CONFIRMED absent | No memset / rep stos in 80-insn window |
| Client recv pre-zeros its local name buffer | CONFIRMED | Handler_ChatGuild @ 0x005E5310: xor eax,eax + 5× mov [esp+…],eax @ 0x005E5324–0x005E5342, executed before PacketRead_String |
No memset / rep stos after call 0x005F4780 @ 0x005E534F; wire bytes [0..20] land verbatim in client buffer | CONFIRMED absent | Disassembly of post-call window |
Bytes [strlen..20] are NOT zero | INFERRED | No code path on server zeroes the tail |
Bytes [strlen..20] are prior-stack residue (non-zero, ~99% static confidence) | INFERRED | MSVC stack frame reuse; no zeroing observed |
| Stock client UI does NOT break on non-zero tail | INFERRED | ChatWhisperTradeGuildZoneMega_vfn @ 0x0059BDB0 scans until NUL; the early NUL at name[strlen] hides all tail bytes |
CONFIRMED rows are based on direct disassembly evidence — specific VA ranges were inspected and the claimed instruction (or its absence) was verified.
Simulation Tool — build_pattern_b_packet.py
The script tools/padding/build_pattern_b_packet.py constructs a Pattern B chat packet with three selectable tail-fill strategies, allowing emulators and test harnesses to reproduce or diverge from stock server behavior.
Modes
zero— tail bytes[strlen..20]are0x00. Produces a well-formed C-string but does not match stock server output.garbage— tail bytes are filled with a deterministic pseudo-random sequence seeded by--seed. Best approximation of stock uninitialized stack residue.stock— tail bytes are filled with a repeating0xCC-like pattern (MSVC debug stack fill). An approximation; use a wire capture to pin real values.
Usage
Expected Outcomes
| Tail mode | Bytes [strlen..20] | Stock server match? | Stock client UI |
|---|---|---|---|
zero | 0x00… | No (stock does not memset) | OK (valid C-string) |
garbage | Non-zero random | Yes (static inference) | OK if name[strlen] == '\0' |
stock | Repeating 0xCC-like stack fill | Approximation only | OK if early NUL present |
Reproduce the Static Scan
Use the steps below to independently verify the claims in the Static Evidence table.Scan all direct Pattern B chat sends
Run the bundled scanner against the server binary. It identifies every chat-tagged Pattern B
SConnection_Send callsite and reports whether a memset or rep stos appears in the preceding 80 instructions.Inspect the guild builder (no rep stos between copy and send)
Disassemble the
Chat_BroadcastGuild function. Confirm the copy loop at 0x004325B0, the absence of any rep stos or memset call, and the send at 0x00432615.