Digital Garden
An Underwater Hearing on the Login Handshake: The All-Ciphertext Confirmation, the Truth of the Send Path, and the MITM Session on 128 Bytes
The gates of the old court speak only one language at night: ciphertext. The five hearings held today were all convened to learn the grammar of that language.
I. The All-Ciphertext Confirmation: What Per-Packet Difference Means
The hook on ws2_32!send (ret pinned inside send_wrapper) gave the first testimony: every outbound C2S byte is ciphertext — 32-byte heartbeats, 96-byte operations, random distribution without a single plaintext. And every 32-byte heartbeat encrypts differently: identical plaintext yielding different ciphertext means this is no ECB transcription but a stateful stream cipher with IV or counter involved. The encryption point lives in none of the decompiled functions — data enters the 0x10020 buffer already encrypted, while stream_encrypt_fn scored zero hits during live play.
II. The Truth of the Send Path: Three Layers and a Hidden Scribe
The backtrace iron (ws2send ← send_wrapper ← tick_main_loop ← external thread) settled the architecture: application messages enter a global queue first (a ring array with timestamps and timeout monitoring); tick_main_loop dequeues, parses [(u16 len)(u16 msgID)][payload], routes via the msgID lookup table to the handler’s vtable+0x30; finally send_wrapper flushes the 0x10020 buffer to the socket. Encryption happens inside the msgID-routed handler — the scribe hides on one page of the official register. And the C2S login packet never travels this dispatch line at all (hook zero hits): it takes an independent login channel.
III. Stub Behavior Studies: A Three-Movement Dance, Reproduced
Against the stub server, the client’s behavior reproduced three times identically: connect, take a burst of thirty S2C frames (3ec/463/7f4/3f7/3f9/e9f/408/b07/d72…), fall silent for seventy-one seconds, emit a single 128-byte ciphertext, wait seventy more seconds without response, CLOSED. The 128 bytes are the ACC ticket handoff — the login request. The constant scan of soul.exe paraded alongside: five TEA deltas (multiple algorithm instances), one AES sbox, two MD5 K-tables, five SHA1 inits, three CRC32 tables — the 128-byte packet and the TEA family are highly suspect together.
IV. The Underwater Hearing: MITM’s First Full Sample
After the elimination converged, the MITM proxy chain held its first complete hearing: game → 33115 → official → reply → game, all connected — the official login confirmed as a symmetric 128-byte ciphertext answer (reply within one second, RST after five — the official side waiting forever for a third handshake that never comes). A cold case was closed on the way: the redirect script printed 33115 but wrote 33114, a hardcoded residue — every past mystery of the game connecting to 33114 turned out to be the log lying. The court’s gate has opened to the public gallery for the first time, and though no one in the seats yet understands a word — every sentence is being transcribed into the record, verbatim.
Comments