Hello all, I am kinda going to use this post as a log of my packet study progress. Feel free to comment, contribute, correct and fill the gaps (and why not flame a bit, just a bit!)
Some background info: I'm kinda new to packet stuff, Usually I used to made my bots and tools calling game functions directly. Well, I have just hooked conquer packets recv/send functions and start sniffing them. I'm using C++.
This is about the current lastest oficial conquer patch: 6715.
I'm starting with some chat packets, here are some received ones:
I am surprised that I can just replay a recv chat packet to client (send the packet again to client) and it just worked well (re-displayed the chat message). I thought that it could have some packet count/time check or some mechanism to invalidate "wrong packets". Well, maybe is just about the chat, I will try later with other packets type.
So, with this stuff in mind I think it's all about dissecting other packets and PARSING them FTW. Seems much more easier than hooking dozen of game functions. If someone have some packet functions parser or related stuff to share could save me time, otherwise I'm just writing mines atm.
It's using for encoding and decoding the packet body (offset 4 and beyond). There is a time mechanism. Here's the older packet structure for reference: .
Well, I have looked about google's proto buffers, didn't feel confortable using it. Even not sure conquer is using it for serializing its structures, I think its still possible using it to de-serializing packets in any shape you may want. Well, for my purpose I dont need to know what means every single byte from packet (not yet) so I find easy doing a "raw" parsing like this:
Well, I am happy with the result. Just need to make the union structs stuff to handle it in a general fashion. C++ Struct Padding was a concept I didn't know and took me an hour of debugging to find out what was happing that my code was not working (in the begining)... Dam crap (awesome =p) otimizations!
Don't expect me to do this for every packet type, with this I think it's enough for manipulating packets buffers in C++.
Field's number of what? It doesn't seem correlated with message's fields (I could not see any correlation with the number 08 at least).
I think I'm done with chat packets. I feelling ready to move on, this basic packet's manipulation seems enough. For post completeness, just sharing more organized code. I did a union implementation for chat/system messages but it turned out very ugly code. Some object oriented hierarchy just came in handy (see below).
This output:
Code:
Received packets: 13
Found Chat Message Packet, dissecting:
(~asd~)ahmed~) -> All : Buy 30 [Item SeniorEXPBall 1076943851 4294967295] Offer
Found a System Message Packet, dissecting:
SYSTEM -> ALLUSERS: <BeTshR> defeated a devil in the Deityland and received a rare treasure FaithfulJadeBox!
Found Chat Message Packet, dissecting:
MaFiaa -> All : #36[Item SuperTriumphRapier(+12) 1075430744 4293649791] [Item SuperLordPistol(+12) 1075430745 4293649791]
Found a System Message Packet, dissecting:
SYSTEM -> ALLUSERS: <Zeck> defeated a devil in the Deityland and received a rare treasure DeitylandYellowRunePack!
Found Chat Message Packet, dissecting:
*~BlacK~Wing~* -> All : #36[Item VioletGem 1083046370 4293395709][Item MoonGem 1083028805 4278255360]#36
Found a System Message Packet, dissecting:
SYSTEM -> ALLUSERS: <romansya> defeated a devil in the Deityland and received a rare treasure DeitylandAttributePack!
Sorry for duplicating almost identical methods in both derived class, didn't figure it out another way of coding...
I hope I could motivate and helped someone else interested in packet sniffing/manipulation. I've enjoyed the process a lot! This is
definitely not a step by step tutorial but it can give some directions on how abstract packet buffers into classes, at least. It's not even a tutorial, its missing some code, but I think I put sufficient for anyone interested enough to follow along.
Google protocol buffers is a packing encoder for structured data. That byte is the only guaranteed to be it's own variable. It's the number of fields / variables in that structure. For the chat packet, that's the user ID / timestamp, channel, style, color, mesh1, mesh2, string list count, and string packer. 8 fields in total. If you'd like to decode this packet, you more or less have to use Google Protocol Buffers.
Google protocol buffers is a packing encoder for structured data. That byte is the only guaranteed to be it's own variable. It's the number of fields / variables in that structure. For the chat packet, that's the user ID / timestamp, channel, style, color, mesh1, mesh2, string list count, and string packer. 8 fields in total. If you'd like to decode this packet, you more or less have to use Google Protocol Buffers.
Spirited, thank you again! Now I realized and I am convinced about the need of using google protocol buffer (you had to say it out loud twice, right? ). I notice that some packets of same type were changing a bit their internal offsets, so I dig a bit about packet encoding.
This reference:
specifically shows how to do it (encode/decode) manually (the way I like to do). Basically it uses 7 bit encoding (to shrink bytes / network bandwidth traffic I believe) and a tag (pair key-wiretype) to serialize data.
If someone interested about 7 bit encoding, this video explain it nicely
So, that previous "unknown byte" of value 0x08 means the following:
0x 08 = 0b 0(000 1)(000) => field number 1 and datatype = 0 (varint), so it's expected that next bytes following on the stream to be a varint (int32, int64 etc) encoded in 7 bits. So in the first example we have in the begining of the chat packet:
Code:
A B C D E F
3f 00 59 08 | 08 | ff ff ff ff 0f | 10 | d0 0f |18 00 ...
It is decoded as following:
A: packet lenght = 0x3f
B: packet type = 0x859
C: tag (key-wiretype) = pair(1, 0) = field 1 is varint (below)
D: varint = decode7bits(ff ff ff ff 0f) = 0xffffff7f
E: tag = pair(2, 0) => next field is varint
F: varint = decode7bits(d0 0f) = 0xf28
and so on...
I've just write a 7bit encode and decode functions do parse the packets manually, but I will give a try using .proto files before brushing bits everywhere, seems cleaner.
It's very trick to use 7bits encoding to pack packets, you dont need to use all bytes of the data type if you dont used large numbers too often. The next output is just to ilustrate this point of view. I mean, if you have a lot of DWORDs (four bytes) that often just fill 2 bytes of non-zeros numbers, why send a bunch of zeros to network?
What is very nice in this encoding is that the packet stream has already a structure (flexible) signed inside it, I mean, some metadata usefull for reversing without touching the assembly!
I will have a break guys, real job is killing me. I will be back in a couple of weeks, I believe. Cya! As always, have fun!
One function to rule them all!
I don't think I will need one .proto for every message now (but it will need one class for each packet type as usual, kinda same amount of coding work)... I had to do this before my break, it was exploding inside my mind. Cya!
[ProtoContract]
[Packet(PacketType.Message)]
public partial class MessagePacket
{
[ProtoMember(1, IsRequired = true)]
private int ColorRBG
{
get { return Color.ToArgb(); }
set { Color = Color.FromArgb(value); }
}
[ProtoMember(2, IsRequired = true)]
public MessageActionType ChatType { get; set; }
/// <summary>
/// = ChatStyleType.NORMAL;
/// </summary>
[ProtoMember(3, IsRequired = true)]
public ChatStyleType StyleType { get; set; } = ChatStyleType.NORMAL;
/// <summary>
/// = (DateTime.Now.Hour * 100) + DateTime.Now.Minute;
/// </summary>
[ProtoMember(4, IsRequired = true)]
public int MessageUID { get; set; } = (DateTime.Now.Hour * 100) + DateTime.Now.Minute;
[ProtoMember(5, IsRequired = true)]
public int RecipientMesh { get; set; }
[ProtoMember(6, IsRequired = true)]
public uint SenderMesh { get; set; }
/// <summary>
/// Bit flags
/// </summary>
[ProtoMember(7, IsRequired = true)]
public KingdomOfficialTitleType KingdomTitles { get; set; }
/// <summary>
/// = 1
/// This decides which of the 2 string will be shown from official_type.dat.
/// </summary>
[ProtoMember(8, IsRequired = true)]
public byte TitleNameIndex { get; set; } = 1;
[ProtoMember(9, IsRequired = true)]
public byte Unknow2 { get; set; }
/// <summary>
/// = 7;
/// </summary>
[ProtoMember(10, IsRequired = true, OverwriteList = true)]
public string[] Strings { get; set; } = new string[7] { "SYSTEM", "ALLUSERS", "", "", "", "", "" };
/// <summary>
/// = "SYSTEM"
/// </summary>
[Ignore]
public string From
{
get { return Strings[0]; }
set { Strings[0] = value; }
}
/// <summary>
/// = "ALLUSERS"
/// </summary>
[Ignore]
public string To
{
get { return Strings[1]; }
set { Strings[1] = value; }
}
[Ignore]
public string MessageDate
{
get { return Strings[2]; }
set { Strings[2] = value; }
}
[Ignore]
public string Text
{
get { return Strings[3]; }
set { Strings[3] = value; }
}
[Ignore]
public string Unknwon1
{
get { return Strings[4]; }
set { Strings[4] = value; }
}
[Ignore]
public string Unknwon2
{
get { return Strings[5]; }
set { Strings[5] = value; }
}
[Ignore]
public string ServerName
{
get { return Strings[6]; }
set { Strings[6] = value; }
}
[Ignore]
public ushort SenderServerId
{
get { return (ushort)SenderMesh; }
set { SenderMesh = (uint)(value & 0xffff) | (uint)(RecipientServerId << 16); }
}
[Ignore]
public ushort RecipientServerId
{
get { return (ushort)(SenderMesh >> 16); }
set { SenderMesh = (uint)(SenderServerId & 0xffff) | (uint)(value << 16); }
}
/// <summary>
/// = Color.Yellow;
/// </summary>
[Ignore]
public Color Color { get; set; } = Color.Yellow;
}
Yes! I have just set to "auto" decode every packet received and works very well with other types. But it fail to decode on some packets (show not enumerated typewires), didnt make a deep analysis yet, but I guess not every packet is encoded...
Wow, what a spoiler!!! Thanks man!
Well, my nexts learning/challenging steps is going to struct the packets to make an "item on ground manager" and an "entity manager". I can't wait to start dissecting them, but so much to do in real job... I will be back!
Understanding the Packet System - Basics of a Packet explained 11/03/2012 - Cabal Online - 30 Replies Read the advice first...
*****************UPDATED 12/11/2011*********************************
**** ADDED VB6 PROXY BOT SOURCE-CODE, WORKING EXAMPLE OF PROXY BOT******
************************************************* *****************
The following CONSTANTS have been flagged, this means they appear in EVERY Packet exchange from client to server and server to client
Red = Packet Id - Each packet has a unique ID number, in this case AA02, Each Packet id Relates to a specific...
[Request] Packet Structure for CharData Packet 05/16/2011 - Silkroad Online - 4 Replies can someone tell me which structure the CharData packet has? i would really appreciate this, since im still noob in such things. its just too high for me/ too much information for my head. :handsdown:
S->C(3013)...
[Question] Packet data , packet editing ?? 10/13/2009 - 9Dragons - 2 Replies I would like to know :
What is packet data?
How do i get the address for hacking a item in game?
How to use it ??