Packets/Login/Vanilla
It's worth noting that, for build (1.1.2.4125), the client automatically disconnects after a successful login challenge and proof exchange and sends a reconnect packet right away instead of asking for the realm list.
Opcodes and Errors
Name | Value | Description |
---|---|---|
Authentication | ||
LOGIN_CHALL | 0x00 | Intial information sent by client and then challenge by server. |
LOGIN_PROOF | 0x01 | Proof sent by client and then server. |
RECON_CHALL | 0x02 | Reconnect challenge sent by client and then server. |
RECON_PROOF | 0x03 | Reconnect proof sent by client and then server. |
SURVEY_RESULT | 0x04 | Used for hardware survey. |
Realmlist | ||
REALMLIST | 0x10 | Realmlist request sent by client and realmlist information sent by server. |
Patching | ||
XFER_INITIATE | 0x30 | Used for patching. |
XFER_DATA | 0x31 | Used for patching. |
XFER_ACCEPT | 0x32 | Used for patching. |
XFER_RESUME | 0x33 | Used for patching. |
XFER_CANCEL | 0x34 | Used for patching. |
Name | Value |
---|---|
LOGIN_OK | 0x00 |
LOGIN_FAILED | 0x01 |
LOGIN_FAILED2 | 0x02 |
LOGIN_BANNED | 0x03 |
LOGIN_UNKNOWN_ACCOUNT | 0x04 |
LOGIN_UNKNOWN_ACCOUNT3 | 0x05 |
LOGIN_ALREADYONLINE | 0x06 |
LOGIN_NOTIME | 0x07 |
LOGIN_DBBUSY | 0x08 |
LOGIN_BADVERSION | 0x09 |
LOGIN_DOWNLOAD_FILE | 0x0A |
LOGIN_FAILED3 | 0x0B |
LOGIN_SUSPENDED | 0x0C |
LOGIN_FAILED4 | 0x0D |
LOGIN_CONNECTED | 0x0E |
LOGIN_PARENTALCONTROL | 0x0F |
LOGIN_LOCKED_ENFORCED | 0x10 |
Challenge packets
Offset | Size / Endianness | Type | Name | Description |
---|---|---|---|---|
0x0 | 1 / - | uint8 | command | LOGIN_CHALL (0x0), AuthReconnectionChallenge_Client has RECON_CHALL (0x2). |
0x1 | 1 / - | uint8 | protocol_version | 3 for 1.12, unknown for 1.1. |
0x2 | 2 / Little | uint16 | size | length of package minus the size of the command, protocol_version and size fields (4 bytes). The size can be calculated as 30 (0x1E) + account_name_len, see that field for a maximum. |
0x4 | 4 / Little | uint8[4] | gamename | Always null terminated 'WoW\0' string. |
0x8 | 3 / - | uint8[3] | version | [0x01, 0x01, 0x02] for 1.1.2. [0x01, 0x0C, 0x01] for 1.12.1. |
0xB | 2 / Little | uint16 | build | 4125, aka Revision |
0xD | 4 / Big | uint8[4] | platform | eg '\0x86'. Has a leading zero for 'x86'. |
0x11 | 4 / Big | uint8[4] | os | eg '\0Win'. Has a leading zero for 'Win'. |
0x15 | 4 / Big | uint8[4] | locale | eg 'enUS' |
0x19 | 4 / Little | uint32 | worldregion_bias | Offset in minutes from UTC time, eg. 180 means 180 minutes |
0x1D | 4 / Big | uint32 | ip | client_ip |
0x21 | 1 / - | uint8 | account_name_lenth | Length of the account_name field in bytes. The client can only send 16 characters, but this can still be more than 16 bytes if non-ASCII characters are used. |
0x22 | account_name_len / Big | uint8[account_name_len] | account_name | UTF-8 encoded uppercase string of the username. Not all unicode characters are uppercased correctly. |
(1.1.2.4125)
Offset | Type | Name | Description |
---|---|---|---|
0x1 | uint8 | command | LOGIN_CHALL (0x0) |
0x2 | uint8 | protocol_version | Must be 0. |
0x3 | uint8 | result | |
0x4 | char[32] | B | SRP public server ephemeral |
0x24 | uint8 | g_len | SRP generator length |
0x25 | uint8 | g | SRP generator |
0x26 | uint8 | n_len | SRP modulus length |
0x27 | char[32] | n | SRP modulus |
0x47 | char[32] | srp_salt | SRP user's salt |
0x47 | char[16] | crc_salt | A salt to be used in AuthLogonProof_Client.crc_hash |
(1.12.1.5875)
The AuthLogonChallenge_Server packet has added the two_factor_authentication field and will hang waiting for it to be sent.
Offset | Type | Name | Description |
---|---|---|---|
0x1 | uint8 | command | LOGIN_CHALL (0x0) |
0x2 | uint8 | protocol_version | Must be 0. |
0x3 | uint8 | result | |
0x4 | char[32] | B | SRP public server ephemeral |
0x24 | uint8 | g_len | SRP generator length |
0x25 | uint8 | g | SRP generator |
0x26 | uint8 | n_len | SRP modulus length |
0x27 | char[32] | n | SRP modulus |
0x47 | char[32] | srp_salt | SRP user's salt |
0x47 | char[16] | crc_salt | A salt to be used in AuthLogonProof_Client.crc_hash |
0x57 | bool (size 1 byte) | two_factor_authentication | 0 for disabled. |
Proof packets
(1.1.2.4125)
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | command | 0x1 |
0x1 | uint8[32] | a | |
0x21 | uint8[20] | m1 | |
0x35 | uint8[20] | crc_hash | |
0x49 | uint8 | num_keys |
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | command | 0x1 |
0x1 | uint8 | error | |
0x2 | uint8[20] | m2 | |
0x16 | uint32 | unk |
(1.12.1.5875)
Proof packets changed during Vanilla:
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | command | LOGIN_PROOF (0x1) |
0x1 | uint8[32] | a | Client public key. |
0x21 | uint8[20] | m1 | Client proof. |
0x35 | uint8[20] | crc_hash | |
0x49 | uint8 | num_keys | Used for unknown telemetry. Can be expected to always be 0. |
0x4A | bool (size 1 byte) | two_factor_enabled | If false the packet ends here, if true the two fields below are included. Added in 1.12.x client branch. |
uint8[16] | pin_salt | Salt used for PIN. Only included if two_factor_enabled is true. | |
uint8[20] | pin_hash | Hash used for PIN. Only included if two_factor_enabled is true. |
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | command | LOGIN_PROOF (0x1) |
0x1 | uint8 | error | |
0x2 | uint8[20] | m2 | Server proof. |
0x16 | uint32 | hardware_survey_id | ID of a hardware survey that the client should perform. Set to 0 to not use. |
Reconnection challenge packets
AuthReconnectionChallenge_Client has the same structure as AuthLogonChallenge_Client, except that the command is 0x2.
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | command | 0x2 |
0x1 | uint8 | error | |
0x2 | char[16] | challenge_data | random data, used as a challenge |
0x12 | uint64 | unk1 | |
0x1A | uint64 | unk2 |
Reconnection proof packets
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | command | 0x3 |
0x1 | char[16] | proof_data | |
0x11 | char[20] | client_proof | |
0x25 | char[20] | unk_hash | |
0x39 | uint8 | unk |
To check if the client proof is correct, the server must calculate SHA1(account_name | proof_data | challenge_data | session_key) and compare it to client_proof.
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | command | 0x3 |
0x1 | uint8 | error |
Realm list packets
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | cmd | REALMLIST |
0x1 | uint32 | unknown | null |
The server answers with a packet composed of a RealmHeader_Server, as many RealmInfo_Server as specified and a RealmFooter_Server.
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint8 | cmd | REALMLIST |
0x1 | uint16 | size | size of the rest of packet, without these 3 first bytes |
0x3 | uint32 | unknown | null |
0x7 | uint8 | num_realms | Number of RealmInfo_Server |
The size value can be computed with the part of the header taken into account plus the footer (5+2 bytes) and the size of every RealmInfo_Server which is variable.
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint32 | type | realm type? 0 is normal, 1 is PVP |
0x4 | uint8 | flags | see below |
0x5 | char[] | name | Zero terminated string; name of the Realm |
char[] | addr_port | Zero terminated string; address of the Realm ("ip:port") | |
float | population | Population value. 0 is low, 1 is medium, 2 is high. | |
uint8 | num_chars | The number of chars you have on that server | |
uint8 | time_zone | really? | |
uint8 | unknown |
Flags Meaning 0x01 Color the realm name in red (can't create char?) 0x02 Realm is offline
Offset | Type | Name | Description |
---|---|---|---|
0x0 | uint16 | unk |