| 1 | [[TOC]] |
| 2 | = Unofficial Steam Friends Protocol Specification = |
| 3 | == Introduction == |
| 4 | Steam Friends is an instant messaging protocol that is built into Steam, a game content delivery system developed by Valve. This page details the protocol specification for Steam Friends as was ascertained though reverse-engineering. |
| 5 | |
| 6 | == Connection == |
| 7 | Steam Friends uses UDP on port 27017. Connections have been made to the following servers: |
| 8 | * 68.142.64.165 |
| 9 | * 68.142.64.164 |
| 10 | |
| 11 | == Layers == |
| 12 | On top of UDP, another layer is implemented to keep track of sequencing and splitting of packets. This layers prepends every packet with the following 36-byte structure: |
| 13 | |
| 14 | || ||0||4||8||12|| |
| 15 | ||'''00:'''||"VS01"||type||destination||source|| |
| 16 | ||'''10:'''||sequence #||response #||split count ||seq. # of 1st packet|| |
| 17 | ||'''20:'''||data length|| || || || |
| 18 | |
| 19 | '''Note:''' These values are little-endian, which is not network order. |
| 20 | |
| 21 | ||'''Field'''||'''type'''||'''Length (bytes)'''||'''Description''' |
| 22 | ||"VS01"||string (non-null terminated)||4||the 4 characters 'V', 'S', '0', '1' |
| 23 | ||type||bit-field||4||a bit field describing the type of packet (needs further analysis) |
| 24 | ||destination||integer||4||the destination ID of the packet |
| 25 | ||source||integer||4||the source ID of the packet |
| 26 | ||sequence #||integer||4||the packet's sequence number. server and client keep track of own numbers |
| 27 | ||response #||integer||4||if packet is sent as response to another packet, this is that packet sequence # |
| 28 | ||split count||integer||4||the number of packets the current message was split in to |
| 29 | ||seq. # of 1st packet||integer||4||the sequence number of the first packet for current message |
| 30 | ||data length||integer||4||the length of the data that follows |
| 31 | |
| 32 | |
| 33 | == Login sequence == |
| 34 | 1. Client initiates the login by sending a type '0x00020004' packet to the server with no data, and sequence # 1 |
| 35 | {{{ |
| 36 | 00: 56 53 30 31 00 00 01 04 00 02 00 00 00 00 00 00 |
| 37 | 10: 01 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 |
| 38 | 20: 00 00 00 00 |
| 39 | }}} |
| 40 | 1. Server responds with type '0x04020004' (first one ORed with 0x04000000) with 4 bytes of data attached '''(although the data length field is 0)''', sequence: 1, response: 1, src: 0x00000200 |
| 41 | {{{ |
| 42 | 00: 56 53 30 31 04 00 02 00 00 00 00 00 00 02 00 00 |
| 43 | 10: 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |
| 44 | 20: 00 00 00 00 f9 8d 22 25 |
| 45 | }}} |
| 46 | 1. Client responds with type '0x04030004' (previous ORed with 0x00010000) with 4 bytes of data attached (with 4 as data size). That 4 bytes corresponds to the 4 bytes that the server sent XORed with 0xA426DF2B. sequence: 2, response: 1, dest: 0x00000200 |
| 47 | {{{ |
| 48 | 00: 56 53 30 31 04 00 03 04 00 02 00 00 00 00 00 00 |
| 49 | 10: 02 00 00 00 01 00 00 00 01 00 00 00 02 00 00 00 |
| 50 | 20: 04 00 00 00 d2 52 04 81 |
| 51 | }}} |
| 52 | 1. Server responds with type '0x04040000' (possibly as some sort of ACK). sequence: 2, response: 2, dest: this becomes the source for all subsequent packets from client |
| 53 | {{{ |
| 54 | 00: 56 53 30 31 00 00 04 04 00 34 7e fe 00 02 00 00 |
| 55 | 10: 02 00 00 00 02 00 00 00 01 00 00 00 02 00 00 00 |
| 56 | 20: 00 00 00 00 |
| 57 | }}} |
| 58 | 1. Server sends type '0x0406001c' with the following data stream: "17 05 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 00 00 00 01 00 00 00". sequence: 3, response: 2 |
| 59 | {{{ |
| 60 | 00: 56 53 30 31 1c 00 06 04 00 34 7e fe 00 02 00 00 |
| 61 | 10: 03 00 00 00 02 00 00 00 01 00 00 00 03 00 00 00 |
| 62 | 20: 1c 00 00 00 17 05 00 00 ff ff ff ff ff ff ff ff |
| 63 | 30: ff ff ff ff ff ff ff ff 01 00 00 00 01 00 00 00 |
| 64 | }}} |
| 65 | 1. Client responds type '0x040600a4' with the following data stream: "18 05 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 00 00 00 80 00 00 00 [132 bytes here] 00 00 00 00". The 132 bytes are always different. |
| 66 | {{{ |
| 67 | 00: 56 53 30 31 a4 00 06 04 00 02 00 00 00 34 7e fe |
| 68 | 10: 03 00 00 00 03 00 00 00 01 00 00 00 03 00 00 00 |
| 69 | 20: a4 00 00 00 18 05 00 00 ff ff ff ff ff ff ff ff |
| 70 | 30: ff ff ff ff ff ff ff ff 01 00 00 00 80 00 00 00 |
| 71 | 40: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx |
| 72 | 50: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx |
| 73 | 60: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx |
| 74 | 70: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx |
| 75 | 80: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx |
| 76 | 90: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx |
| 77 | a0: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx |
| 78 | b0: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx |
| 79 | c0: xx xx xx xx 00 00 00 00 |
| 80 | }}} |
| 81 | 1. Server responds with type '0x04060018' with the following data: "19 05 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 00 00 00" |
| 82 | {{{ |
| 83 | 00: 56 53 30 31 18 00 06 04 00 34 7e fe 00 02 00 00 |
| 84 | 10: 04 00 00 00 03 00 00 00 01 00 00 00 04 00 00 00 |
| 85 | 20: 18 00 00 00 19 05 00 00 ff ff ff ff ff ff ff ff |
| 86 | 30: ff ff ff ff ff ff ff ff 01 00 00 00 |
| 87 | }}} |
| 88 | |
| 89 | == Encryption == |
| 90 | |