Skip to content

CDKeyMessage

Michał Kapała edited this page Aug 19, 2024 · 2 revisions

A simplified UDP version of GS message protocol for CD-Key service based on SimpleMessage.

struct CDKeyMessage {
  unsigned char type;
  unsigned int size;
  unsigned char* payload;
};

Type is always 0xD3. Size is big endian-encoded.

The payload is a DataList encrypted with Blowfish using a static key.

Requests

The request type is identified by the second value in the data list (reqId).

ID Request
1 Challenge
2 Key activation
3 Authorization
4 Validation
5 Player status
6 Disconnection
7 Still alive

Challenge

Initial handshake with the server. Performed before activation and auth requests.

Request

[
    "1", # msgId, incremental
    "1", # reqId
    "1", # unknown, always 1
    []   # empty list
]

Response

[
    "1", # msgId, incremental
    "1", # reqId
    "1", # unknown, always 1
    [
        "38", # result - GSSUCCESS
        [
            # a buffer of arbitrary length
            b'b\x00\x00\x00\x14\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x01\x02\x03\x04'
        ]
    ]
]

Key activation

Activates a CD key. This request usually happens once, the game keeps activation info cached and starts off with challenge+auth requests for subsequent runs.

Request

[
    "2", # msgId, incremental
    "2", # reqId
    "2", # unknown, always 2
    [
        # SHA1 off challenge + key
        b'<20B>',
        # game name + key hash
        b'\xcc\xd4hH{\x02\x8b[\xf2\xa0\xebG\xd0J4\xd7/\xa4dW'  

    ] 
]

Response

[
    "2", # msgId, incremental
    "2", # reqId
    "2", # unknown
    [
        "38", # result - GSSUCCESS
        [
            # activation id (16B)
            b'b\x00\x00\x00\x0b\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33',
            # unknown buffer (16B)
            b'b\x00\x00\x00\x0b\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44'
        ]
    ]
]

Authorization

Authorizes the game by its activation ID and static hash of game name + key.

Request

[
    "3", # msgId, incremental
    "3", # reqId
    "1", # unknown, always 1
    [
        # activation id
        b'b\x00\x00\x00\x0b\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33',
        # game name + key hash
        b'\xcc\xd4hH{\x02\x8b[\xf2\xa0\xebG\xd0J4\xd7/\xa4dW'

    ] 
]

Response

[
    "3", # msgId, incremental
    "3", # reqId
    "1", # unknown
    [
        "38", # result - GSSUCCESS
        [
            # authorization id (20B)
            b'b\x00\x00\x00\x0f\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55'
        ]
    ]
]

Validation

The authorization ID is checked against the game's name (GSConnect's dp parameter).

Request

[
    '4', # msgId, incremental
    '4', # reqId
    '2', # unknown, always 2
    [
        # auth id
        b'b\x00\x00\x00\x0f\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55',
        # game name
        'HEROES_657d2c2ebadc6a1d'
    ]
]

Response

[
    "4", # msgId, incremental
    "4", # reqId
    "2", # unknown
    [
        "38", # result - GSSUCCESS
        [
            # CDKEY_PLAYER_STATUS.E_PLAYER_VALID
            '2',
            # authorization id (20B)
            b'b\x00\x00\x00\x0b\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66'
        ]
    ]
]

Still alive

A keepalive notification, needs no response.

Request

[
    '0', # msgId, always 0
    '7'  # reqId
]
Clone this wiki locally