ChatServer Protocol Research
Hi!
I'm currently researching the protocol between the ChatServer and the game client. I captured my packets in 2012 for season 6 episode 3 on GMO.
First of all, has this been done before? Are there any informations available already? I used the search alot and could not find anything related.
Actually, I've almost finished my ChatServer, just one vital part is unfinished: How is the client authenticating?
I can tell you what I know already about this mechanism:
1. Game client sends to the server that it wants to open a chat (C1 0D CA [Friend Name])
2. Game server answers this with a packet like this:
Code:
|---------------------IP-------------------| |rid| |--ticket-| ix |----------NAME-------------| Success
C3 24 CA 32 31 31 2E 34 33 2E 31 35 36 2E 31 39 35 00 5B 00 71 00 A8 07 01 4B 4B 4B 4B 4B 4B 4B 00 00 00 01
ix: player index; 0 is the creator, 1 seems to be sent to the friend (or other way around).
rid: room id
ticket: a random number which is probably sent to the chat server later for authentication?
Success: 0: no success; 1: success; 2: chat server unavailable
3. Client connects to the chat server (ip which was sent in the packet, port 55980).
4. Client sends a authentication packet to the chat server (encrypted; all data coming from the client is encrypted, like Client -> GS communication)
The decrypted packets looks like this:
Code:
|rid| | prob. ticket+ix (encrypted?) |
C1 10 00 00 5B 00 C5 FD 0A 33 C1 CC 66 67 21 F3 32
The last part has to contain the ticket and the player index, otherwise the chat server would not be able to tell which player actually connected.
I think it's encrypted by simple modulus, because it's 11 bytes long - the length of an encrypted block. Decrypted it would be max 8 bytes, enough to hold ticket and player index.
Do you have any hints, or am I on the right track?
The other packets are a non-brainer. I found the following packet types:
S -> C (all packets not encrypted):
c1 0f 01 ... : Player joined the room
c2 n n 02 ... : List of players currently in the room
c1 n 04 ix [Message length] [Message encrypted by XOR3-key] : Message of a player
C -> S (XOR32-encrypted):
c1 10 00 00 ... : Authentification, see above
c1 n 04 ix [Message length] [Message] : Message of a player
c1 03 05 : Keep connection alive packets, sent every few seconds. I guess you could implement something to disconnect a player if it did not send it for a specific period of time.
Do you know any other packets, or is this complete? I could imagine there is one with packet type 0x03, which I didn't find yet.
Re: ChatServer Protocol Research
maybe it help you chatserver+pdb/map.
Re: ChatServer Protocol Research
Ashlay why pdb if is source is available
Re: ChatServer Protocol Research
Thanks ashlay, but I think I found the authentication mechanism without it ;)
It seems like, I have decrypted the packets of my example from client to chat server with a wrong xor32 key back then. I remember in the last months of Season 6, Webzen changed them almost after every maintenance.
Now I tried it again with the most current one I have (AB 11 ...):
Encrypted packet: c1 10 00 fe bd 9e 96 c8 91 6a 51 06 aa 35 8c 83
Decrypted packet: C1 10 00 00 5B 00 CD FD 93 C8 FA 9B CA F8 98 FC
It's now pretty obvious from the last byte, that again the funny XOR-3-"Encryption" (FC CF AB) was used :)
Encrypted: CD FD 93 C8 FA 9B CA F8 98 FC
Decrypted: 31 32 38 34 35 30 36 37 33 00
So, what are my eyes seeing? The decrypted bytes contain a string of a number, here "128450673" which is 07A80071 in hex.
Do you remember, the ticket which was sent before to the client was 71 00 A8 07 ? :w00t:
I hope someone else can use this information, too ;)
Re: ChatServer Protocol Research
Quote:
Originally Posted by
Razzor
Ashlay why pdb if is source is available
Share them with everyone.
Re: ChatServer Protocol Research
Quote:
Originally Posted by
SOFTakaXimera
Share them with everyone.
Why bother? They prefer to keep the source to themselves and release one thing or two just to receive some compliments like good job.
Re: ChatServer Protocol Research
ChatServer ProtocolCore Pseudo-Code (IDA 6.8) thanks to Ashlay (using PacketTwister yet T_T because is from: Ex702 Chs):
Code:
//----- (004294C0) --------------------------------------------------------int __cdecl ProtocolCore(unsigned __int8 a1, char *src, int a3, int a4){ int v4; // edi@1 char v5; // al@1 char v6; // dl@6 __int16 v8; // [sp+Ch] [bp-1034h]@1 char dst[4]; // [sp+830h] [bp-810h]@1 int v10; // [sp+103Ch] [bp-4h]@1 CStreamPacketEngine_Server::CStreamPacketEngine_Server((int)&v8); LOWORD(v4) = 0; v10 = 0; v8 = 0; memset(dst, 0, 0x800u); v5 = *src; if ( *src == -63 || v5 == -61 ) { v6 = src[2]; LOWORD(v4) = (unsigned __int8)src[1]; *(_WORD *)dst = *(_WORD *)src; dst[2] = v6; } else if ( v5 == -62 || v5 == -60 ) { v4 = (unsigned __int8)src[2] | ((unsigned __int8)src[1] << 8); *(_DWORD *)dst = *(_DWORD *)src; } if ( !CStreamPacketEngine_Server::AddData((CStreamPacketEngine_Server *)&v8, src, v4) ) { CLogProc::Add((CLogProc *)&cLog, "error-L1 : CStreamPacketEngine Adding Error head:%x %d ", a1, a4); CLogProc::Add( (CLogProc *)&cLog, "error-L1 : %x%x%x%x%x", (unsigned __int8)*src, (unsigned __int8)src[1], (unsigned __int8)src[2], (unsigned __int8)src[3], (unsigned __int8)src[4]);LABEL_9: v10 = -1; CStreamPacketEngine_Server::~CStreamPacketEngine_Server((CStreamPacketEngine_Server *)&v8); return 0; } if ( CStreamPacketEngine_Server::ExtractPacket((CStreamPacketEngine_Server *)&v8, dst) ) { CLogProc::Add((CLogProc *)&cLog, "error-L1 : CStreamPacketEngine ExtractPacket Error : head:%x %d", a1, a4); CLogProc::Add( (CLogProc *)&cLog, "error-L1 : %x%x%x%x%x", (unsigned __int8)*src, (unsigned __int8)src[1], (unsigned __int8)src[2], (unsigned __int8)src[3], (unsigned __int8)src[4]); goto LABEL_9; } switch ( a1 ) { case 0u: CSRoomJoinUser((struct PMSG_ROOMLOGIN *)dst, a4); break; case 4u: CSRoomChatMsg((struct PMSG_ROOM_CHATMSG *)dst, a4); break; case 5u: CSLiveCheck((struct PBMSG_HEAD *)dst, a4); break; default: CLogProc::Add((CLogProc *)&cLog, "error-L1 : Unkonw protocol (%d) index : (%d)", a1, a4); break; case 1u: case 2u: break; } v10 = -1; CStreamPacketEngine_Server::~CStreamPacketEngine_Server((CStreamPacketEngine_Server *)&v8); return 1;}// 493450: using guessed type void CLogProc::Add(CLogProc *__hidden this, char *, ...);
PS: Is possible re-make ChatServer Protocol using this for old versions (like: Season 4) ? I'm thinking that Season 4.5/4.6 working with: 1.1.9.0 ChatServer
Re: ChatServer Protocol Research
@Kiosani: Thanks, so client is only sending 0x00, 0x04 and 0x05 packet types which I already found :)
Re: ChatServer Protocol Research
Quote:
Originally Posted by
Kiosani
ChatServer ProtocolCore Pseudo-Code (IDA 6.8) thanks to Ashlay (using PacketTwister yet T_T because is from: Ex702 Chs):
Code:
//----- (004294C0) --------------------------------------------------------int __cdecl ProtocolCore(unsigned __int8 a1, char *src, int a3, int a4){ int v4; // edi@1 char v5; // al@1 char v6; // dl@6 __int16 v8; // [sp+Ch] [bp-1034h]@1 char dst[4]; // [sp+830h] [bp-810h]@1 int v10; // [sp+103Ch] [bp-4h]@1 CStreamPacketEngine_Server::CStreamPacketEngine_Server((int)&v8); LOWORD(v4) = 0; v10 = 0; v8 = 0; memset(dst, 0, 0x800u); v5 = *src; if ( *src == -63 || v5 == -61 ) { v6 = src[2]; LOWORD(v4) = (unsigned __int8)src[1]; *(_WORD *)dst = *(_WORD *)src; dst[2] = v6; } else if ( v5 == -62 || v5 == -60 ) { v4 = (unsigned __int8)src[2] | ((unsigned __int8)src[1] << 8); *(_DWORD *)dst = *(_DWORD *)src; } if ( !CStreamPacketEngine_Server::AddData((CStreamPacketEngine_Server *)&v8, src, v4) ) { CLogProc::Add((CLogProc *)&cLog, "error-L1 : CStreamPacketEngine Adding Error head:%x %d ", a1, a4); CLogProc::Add( (CLogProc *)&cLog, "error-L1 : %x%x%x%x%x", (unsigned __int8)*src, (unsigned __int8)src[1], (unsigned __int8)src[2], (unsigned __int8)src[3], (unsigned __int8)src[4]);LABEL_9: v10 = -1; CStreamPacketEngine_Server::~CStreamPacketEngine_Server((CStreamPacketEngine_Server *)&v8); return 0; } if ( CStreamPacketEngine_Server::ExtractPacket((CStreamPacketEngine_Server *)&v8, dst) ) { CLogProc::Add((CLogProc *)&cLog, "error-L1 : CStreamPacketEngine ExtractPacket Error : head:%x %d", a1, a4); CLogProc::Add( (CLogProc *)&cLog, "error-L1 : %x%x%x%x%x", (unsigned __int8)*src, (unsigned __int8)src[1], (unsigned __int8)src[2], (unsigned __int8)src[3], (unsigned __int8)src[4]); goto LABEL_9; } switch ( a1 ) { case 0u: CSRoomJoinUser((struct PMSG_ROOMLOGIN *)dst, a4); break; case 4u: CSRoomChatMsg((struct PMSG_ROOM_CHATMSG *)dst, a4); break; case 5u: CSLiveCheck((struct PBMSG_HEAD *)dst, a4); break; default: CLogProc::Add((CLogProc *)&cLog, "error-L1 : Unkonw protocol (%d) index : (%d)", a1, a4); break; case 1u: case 2u: break; } v10 = -1; CStreamPacketEngine_Server::~CStreamPacketEngine_Server((CStreamPacketEngine_Server *)&v8); return 1;}// 493450: using guessed type void CLogProc::Add(CLogProc *__hidden this, char *, ...);
PS: Is possible re-make ChatServer Protocol using this for old versions (like: Season 4) ? I'm thinking that Season 4.5/4.6 working with: 1.1.9.0 ChatServer
U need protocol functions only, dont need to decompile PacketTwister.
Re: ChatServer Protocol Research
what is the problem to use ida to retrieve the packets from chatserver? lol
Re: ChatServer Protocol Research
Quote:
Originally Posted by
SmileYzn
what is the problem to use ida to retrieve the packets from chatserver? lol
Well, I don't know why you 'lol', but ofc there are some "problems":
First, IDA is not cheap (and I don't like warez). Second, I have no experience using it. Something simple like a chat server is not hard to rewrite, and the packets don't seem to be complicated.
Re: ChatServer Protocol Research
Quote:
Originally Posted by
nevS
Well, I don't know why you 'lol', but ofc there are some "problems":
First, IDA is not cheap (and I don't like warez). Second, I have no experience using it. Something simple like a chat server is not hard to rewrite, and the packets don't seem to be complicated.
The problem is not packets itself bro, but headers for it.
Also as far, chatserver do not changed packet headers or structs on new versions.
EDIT: Have fun with packets, download here
Re: ChatServer Protocol Research
@SmileYzn: Thanks, I looked into it, but it doesn't contain additional information for me ;) I already have all packets which the client sends, and it seems like it doesn't use structs to send packets back to the client. The code is a big mess, so I won't even try to understand this.
Re: ChatServer Protocol Research
Quote:
Originally Posted by
nevS
@
SmileYzn: Thanks, I looked into it, but it doesn't contain additional information for me ;) I already have all packets which the client sends, and it seems like it doesn't use structs to send packets back to the client. The code is a big mess, so I won't even try to understand this.
what you need? Since chatserver connects with other server (is join server i guess) to retrieve information about accounts.
Also if you have a packed, you need to look the struct on both sides
Re: ChatServer Protocol Research
Well, I'm just interested in the packets sent between chat server and game client. The other stuff is totally different on my servers.
I guess I already have all required packets sent to client, but would be cool if I would know it for sure.