2021-03-19 13:21:32 -04:00
|
|
|
# PSO Ep 1 & 2 (Gamecube) Client/Server Packets Decrypter Tool
|
|
|
|
|
|
|
|
This is a tool that will take raw binary PSO client and server packet data dumps generated from a packet capture tool
|
|
|
|
(such as Wireshark) and display the decrypted packet data.
|
|
|
|
|
|
|
|
I put this tool together for myself to help further my understanding of PSO's network communication. More specifically,
|
|
|
|
to help me troubleshoot why my attempts at setting up Sylverant's open source [login_server](https://github.com/Sylverant/login_server)
|
|
|
|
to serve up quests for download was resulting in unusable quest files on Gamecube memory cards. Understanding the
|
|
|
|
quest download communication better by analyzing the packets being sent from a working implementation and comparing it
|
|
|
|
to what my local login_server instance was sending proved invaluable to me.
|
|
|
|
|
|
|
|
## Network Protocol
|
|
|
|
|
2021-03-24 18:13:22 -04:00
|
|
|
After the initial `0x02` or `0x17` packet sent from the server to the client (which contains the client and server
|
|
|
|
encryption keys), all subsequent communication between the server and client is encrypted. When you have the full set
|
|
|
|
of packets, beginning with the `0x02` or `0x17` packet, it is pretty trivial to decrypt the entire set of data.
|
2021-03-19 13:21:32 -04:00
|
|
|
|
|
|
|
```text
|
|
|
|
'Welcome' packet. id=17, flags=0, size=276
|
|
|
|
0000 | 17 00 14 01 44 72 65 61 6D 43 61 73 74 20 50 6F | ....DreamCast Po
|
|
|
|
0010 | 72 74 20 4D 61 70 2E 20 43 6F 70 79 72 69 67 68 | rt Map. Copyrigh
|
|
|
|
0020 | 74 20 53 45 47 41 20 45 6E 74 65 72 70 72 69 73 | t SEGA Enterpris
|
|
|
|
0030 | 65 73 2E 20 31 39 39 39 00 00 00 00 00 00 00 00 | es. 1999........
|
|
|
|
0040 | 00 00 00 00 6B 81 4B 4F 01 A2 65 78 54 68 69 73 | ....k.KO..exThis
|
|
|
|
0050 | 20 73 65 72 76 65 72 20 69 73 20 69 6E 20 6E 6F | server is in no
|
|
|
|
0060 | 20 77 61 79 20 61 66 66 69 6C 69 61 74 65 64 2C | way affiliated,
|
|
|
|
0070 | 20 73 70 6F 6E 73 6F 72 65 64 2C 20 6F 72 20 73 | sponsored, or s
|
|
|
|
0080 | 75 70 70 6F 72 74 65 64 20 62 79 20 53 45 47 41 | upported by SEGA
|
|
|
|
0090 | 20 45 6E 74 65 72 70 72 69 73 65 73 20 6F 72 20 | Enterprises or
|
|
|
|
00A0 | 53 4F 4E 49 43 54 45 41 4D 2E 20 54 68 65 20 70 | SONICTEAM. The p
|
|
|
|
00B0 | 72 65 63 65 64 69 6E 67 20 6D 65 73 73 61 67 65 | receding message
|
|
|
|
00C0 | 20 65 78 69 73 74 73 20 6F 6E 6C 79 20 69 6E 20 | exists only in
|
|
|
|
00D0 | 6F 72 64 65 72 20 74 6F 20 72 65 6D 61 69 6E 20 | order to remain
|
|
|
|
00E0 | 63 6F 6D 70 61 74 69 62 6C 65 20 77 69 74 68 20 | compatible with
|
|
|
|
00F0 | 70 72 6F 67 72 61 6D 73 20 74 68 61 74 20 65 78 | programs that ex
|
|
|
|
0100 | 70 65 63 74 20 69 74 2E 00 00 00 00 00 00 00 00 | pect it.........
|
|
|
|
0110 | 00 00 00 00 | ....
|
|
|
|
|
|
|
|
server_key = 0x4f4b816b
|
|
|
|
client_key = 0x7865a201
|
|
|
|
```
|
|
|
|
|
2021-03-24 18:13:22 -04:00
|
|
|
Note, sometimes the packet will contain significantly less text than what is shown above. As well, the first bit of
|
|
|
|
text may be slightly different depending on if it was received from a login or ship server, etc. The above output is
|
2021-03-19 13:21:32 -04:00
|
|
|
from a Fuzziqer [newserv](https://github.com/fuzziqersoftware/newserv) I was testing with.
|
|
|
|
|
|
|
|
Also of note is that Sylverant's login_server currently seems to always use identical server and client keys (I believe
|
|
|
|
this is a bug in libsylverant's usage of its random number generator library). This does not cause problems, but it is
|
|
|
|
weird to see when you first notice it.
|
|
|
|
|
|
|
|
Some relevant reading regarding PSO's network protocol:
|
|
|
|
|
|
|
|
* [Network Protocol](http://web.archive.org/web/20171201191557/http://sharnoth.com/psodevwiki/net/protocol)
|
|
|
|
* [Network Protocol Messages](http://web.archive.org/web/20171201191532/http://sharnoth.com/psodevwiki/net/messages)
|
|
|
|
* ["Detailed" Message Flow](http://web.archive.org/web/20171201191527/http://sharnoth.com/psodevwiki/net/message_flow)
|
|
|
|
|
|
|
|
Currently, [libsylverant](https://github.com/Sylverant/libsylverant) has the cleanest and easiest to use PSO encryption
|
|
|
|
API, and that is what is used by this tool.
|
|
|
|
|
|
|
|
**Note that the PSO encryption method (and thus, the `CRYPT_` API provided by libsylverant) is stateful**. That is, you
|
|
|
|
cannot just use it to arbitrarily decrypt any single random packet and expect it to result in readable data. To
|
|
|
|
correctly decrypt any individual packet from either client or server, you need to work through the full sequence of
|
|
|
|
packets (for either client or server) beginning with the very first client or server packet (**after** the `0x17`
|
|
|
|
packet) up to the packet(s) you really wanted, decrypting all of it along the way.
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
### Capturing Packets from PSO
|
|
|
|
|
|
|
|
This is probably easiest if you already have Dolphin set up to run PSO with a working network configuration. In such
|
|
|
|
a configuration, you can capture from your local computer right away.
|
|
|
|
|
|
|
|
I do not have this set up and I cannot be bothered to figure out the janky "Tap" set up that Dolphin requires. Mostly
|
|
|
|
because I am lazy. And because I have a router running [OpenWrt](https://openwrt.org/) which allows me to easily set up
|
|
|
|
packet mirroring with a special iptables kernel module loaded so that I can capture packets directly from my Gamecube.
|
|
|
|
|
2021-03-24 18:13:22 -04:00
|
|
|
If you're running the PSO server yourself, then you can just capture packets from that same machine, no special setup
|
|
|
|
required.
|
|
|
|
|
|
|
|
I'm not going to go into details here on setting up any of these methods. If you're knowledgeable enough to be
|
|
|
|
considering doing packet capture analysis of any sort in the first place, then you should be able to set up either
|
|
|
|
method yourself.
|
2021-03-19 13:21:32 -04:00
|
|
|
|
|
|
|
### Dumping PSO Server/Client Communication Data Dumps with Wireshark
|
|
|
|
|
|
|
|
It is easy to generate packet data dumps containing _just_ the PSO packet data we are interested in with Wireshark.
|
|
|
|
|
|
|
|
After taking a capture of a PSO server/client session, find the TCP packet sent from the server to the client that
|
|
|
|
contains the `0x17` packet. This should be easy enough to find as it will be one of the first TCP packets sent from the
|
2021-03-24 18:13:22 -04:00
|
|
|
server to the client and contains a clear-text string similar to `DreamCast Port Map. Copyright SEGA Enterprises. 1999`.
|
2021-03-19 13:21:32 -04:00
|
|
|
|
|
|
|
Once you've found this packet, right-click it from the top packet list and select "Follow" then "TCP Stream". This will
|
|
|
|
bring up a window that shows the raw data, colour-coded to show data originating from the client and server. Use the
|
|
|
|
drop-downs and buttons at the bottom of this window to save "Raw"-format data for the client and server in
|
|
|
|
**individual** files.
|
|
|
|
|
|
|
|
### Decrypting
|
|
|
|
|
|
|
|
Assuming you saved the data to two files, `server.bin` (containing server-to-client packets) and `client.bin`
|
|
|
|
(containing client-to-server packets), you can run the tool like so:
|
|
|
|
|
|
|
|
```text
|
|
|
|
decrypt_packets /path/to/server.bin /path/to/client.bin
|
|
|
|
```
|