server-re/decomp/MessageServer_Release_x64/evidence.md

82 lines
6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MessageServer_Release_x64.exe — finding ledger
- SHA-256 `7911b15c4379625eaa12ff227708aa3a033bc6ac2cf6b34283136e3a62df25f1`, 1,850,368 bytes
- PE32+ x86-64, Windows CUI, MSVC linker 10.0 (VS2010), timestamp 2013-02-06 09:50:56 UTC
- PDB reference `c:\work\Project\Output\exe\MessageServer_Release_x64.pdb` (GUID cde07e33-d76f-49e7-887c-43afecaef251, age 1) — PDB not available
- Imports: WS2_32, MSWSOCK, WINMM, KERNEL32, USER32, ADVAPI32, OLEAUT32, MSVCP100, RPCRT4, MSVCR100, BugTrapU-x64, ole32, dbghelp
- Ghidra 12.1.2 via REA 6.5.0: 7,728 procedures, 1,803 defined strings (`ev_3112fedf…`)
- Full Evidence: `evidence-bundle.json` (18 records). Static analysis only — nothing observed at runtime.
## Status: first pass (RMI protocol surface). Startup, config parsing, DBC link not yet decompiled.
## Language: C++ (MSVC 2010) — confirmed
180 RTTI descriptors (`.?AV…`), `__CxxFrameHandler3`, MSVCP100 import.
## Third-party libraries (all already documented in `third-party/README.md`)
| Library | Signal in this binary |
|---|---|
| ProudNet (static) | 51 `Proud::` RTTI classes (`CNetServerImpl`, `CNetClientImpl`, …), assert strings |
| TinyXML 2.5.x (static) | `TiXml*` RTTI; error table incl. `Memory allocation failed.` (removed in 2.6) |
| BugTrap | `BugTrapU-x64.dll` import, `BT_SetAppVersion`, `BT_SetSupportEMail` |
| dbghelp | import |
| ATL | `CAtlException` RTTI |
No new library found.
## Outputs
| Path | Content |
|---|---|
| `full/functions/<addr>.c`, `full/index.tsv` | Ghidra headless pseudocode for 7,370 functions (2 failed: `0x14000cfa0` overlapping varnodes, `0x140039f20` timeout) |
| `full/vtables.tsv` | 2,624 RTTI vftable slots |
| `<addr>.pseudo.c` | Copies of the analysed functions below |
## Findings
| # | Conclusion | Type | Evidence |
|---|---|---|---|
| 1 | Server-to-server chat/notice relay. RTTI classes: `RNP::Servers2MsgStub` (inbound), `RNP::Msg2ServersProxy` (outbound), `MagiMsgNetwork`/`MagiMsgServer` app classes | Observed (RTTI); role is inference | `full/vtables.tsv` |
| 2 | `Servers2MsgStub::ProcessReceivedMessage` (`0x140011930`) dispatches 8 RMI IDs 0x3a99–0x3aa0 (table below) | Observed | `0x140011930.pseudo.c`, `ev_1d95f4cc…` |
| 3 | Handlers are overridden in `MagiMsgNetwork` vftable `0x14015a9e8` slots 7–14 | Observed | `full/vtables.tsv` |
| 4 | Whisper / all-chat / enchant notice / mail notify / unique-item notice / channel chat: collect **every** connected host ID from the host list (`this+0xc0`, lock `this+0x110`) and forward via the proxy — i.e. broadcast to all connected servers; target filtering is left to receivers | Observed (code); "receivers filter" is **inference** | `0x140007480.pseudo.c`, `0x1400075d0.pseudo.c`, `ev_f3d6252d…`, `ev_227d432a…` |
| 5 | Guild chat: same broadcast but **excludes the sending host** | Observed | `0x140007340.pseudo.c`, `0x1400078e0.pseudo.c` |
| 6 | Whisper ACK: unicast — looks up a key from the payload in a hash table (`this+0xb0`, bucket count `this+0xd0`) and forwards only if found | Observed; meaning of the key (server ID vs. char ID) **unknown** | `0x140007770.pseudo.c` |
| 7 | Each handler logs/profiles via `FUN_1400486e0(name, …)` with `timeGetTime()` | Observed call; purpose **inference** | handlers |
| 8 | Also links to DBC (`Servers2DbcProxy` 512 slots, `Dbc2ServersStub`, `MGDBCMsgSession`) and to Agent (`Agent2ServerStub`, `Server2AgentProxy`, `MGSAgentSession`) | Observed (RTTI) | `full/vtables.tsv` |
| 9 | Config files referenced: `option\agent.xml`, `option\customoption.xml`, `option\patch.xml`, `option\service_control.xml` | Observed (strings); which are read **unknown** | strings |
### RMI table (Servers2Msg)
| RMI ID | Name | Handler | Routing | Proxy vfn offset |
|---|---|---|---|---|
| 0x3a99 | REQ_MSG_WHISPER | `0x1400075d0` | all hosts | +0x28 |
| 0x3a9a | REQ_MSG_WHISPER_ACK | `0x140007770` | lookup → one host | +0x40 |
| 0x3a9b | REQ_MSG_GUILD_CHATTING | `0x1400078e0` | all except sender | +0x48 |
| 0x3a9c | REQ_MSG_ALL_CHATTING | `0x140007a30` | all hosts | +0x58 |
| 0x3a9d | REQ_MSG_ALL_ENCHANT_NOTICE | `0x140007b80` | all hosts | +0x68 |
| 0x3a9e | REQ_MSG_NEW_MAIL_NOTIFY | `0x140007dd0` | all hosts | +0x78 |
| 0x3a9f | REQ_MSG_ALL_UNIQUE_ITEM_GET_NOTICE | `0x140007ca0` | all hosts | +0xa8 |
| 0x3aa0 | REQ_MSG_CHANNEL_CHATTING | `0x140007ed0` | all hosts | +0xb8 |
## Config, startup and DBC (second pass)
Shared framework findings are written up in `docs/SHARED_FRAMEWORK.md`. The
MessageServer-specific points are:
| # | Conclusion | Type | Evidence |
|---|---|---|---|
| 10 | Startup (`0x140004f00`) runs these steps in order: AGENT, DB_LOAD (4 DBC session pools: GAME/LOG/CHAT/EMERGENCY), SESSION_CONNECT, SERVER_RUN. The main loop pumps `DBCSessionManager` and `AgentSession`, and retries failed connects | Observed | `full/functions/0x140004f00.c` |
| 11 | Its default config file is `option\msg_serveroption.xml`. If `argv[1]` is numeric it runs in agent mode | Observed | `0x14012e5c0`, `0x14005c7b0` |
| 12 | The option loader parses peers agentmanager, db_cache, db_log_cache, msg/gm/auction/manager/match/agent_server and api. It ignores gate/dungeon/pvp/guild/lobby | Observed | `0x14005dc20` |
| 13 | The Dbc2Servers dispatcher `0x140039f20` failed to decompile (timeout) | Observed | `full/index.tsv` |
| 14 | `0x140007480`/`0x140007340` iterate the host list at `+0xc0`. Where hosts are added to that list remains **unknown** | Open | |
## Proposed names (not applied)
| Address | Name |
|---|---|
| `0x140011930` | `Servers2MsgStub::ProcessReceivedMessage` |
| `0x140007480` | `MagiMsgNetwork::CollectAllHosts` |
| `0x140007340` | `MagiMsgNetwork::CollectAllHostsExcept` |
| `0x1400075d0`…`0x140007ed0` | `MagiMsgNetwork::On<RMI name>` per table |
## Open questions
- Where host IDs are inserted into `this+0xc0` list and `this+0xb0` map (connect handlers / registration RMI).
- What `dbc_chat` / `Servers2DbcProxy` is used for (chat logging?).
- Startup/main loop, config parsing.
- Payload layouts of each RMI (proxy marshalling functions `0x140010290`…`0x140011590`).