6 KiB
6 KiB
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+0xc0list andthis+0xb0map (connect handlers / registration RMI). - What
dbc_chat/Servers2DbcProxyis used for (chat logging?). - Startup/main loop, config parsing.
- Payload layouts of each RMI (proxy marshalling functions
0x140010290…0x140011590).