Valhalla Legends Forums Archive | Battle.net Bot Development | I need help decompressing D2 packets

AuthorMessageTime
Juniper
Hi,
I'm actually not sure if this thread belongs to this forum or the "general programming" forum, so if I posted in the wrong place - sorry!  ::)

I've been reading these forums for about 2 weeks now, I must have read every thread with the word "decompress" in it and I even downloaded some VB projects that some people posted but I still can't find something that appears to be very simple to most programmers here.

I'm looking for a took/application that will sniff packets while I'm in a game (D2), decompress the packing that come from bnet servers and parse them to some window online.
I basically just want to be able to see the packets decompressed so I could see what kind of response I get for sending certain packets to bnet.

Does such application exists? can anyone point me in the right direction? please?
thanks in advance,
Jun
March 14, 2006, 10:26 AM
l2k-Shadow
In order to actually have the packets decompress and go to a user-created window, you'd have to make a program which hooks on d2 and packet logs itself, why bother with so much work? Get a packet sniffer such as, WPE PRO (google search will lead you to download link, i'm sure). Then just copy the packets... and use https://davnit.net/bnet/vL/index.php?topic=13890.msg141696#msg141696 code to decompress.
March 14, 2006, 2:13 PM
Juniper
Did anyone write a packet decoder in C?
If so, is there any chance I could get it? or see the source code? it would really help me alot.

thanks.
March 20, 2006, 9:14 PM
Explicit[nK]
You could port the linked code in l2k-Shadow's post to C.
March 20, 2006, 9:52 PM
Juniper
I think that this was already ported from C, I'm looking for the source code, or rather, a working source code in C that decompresses the packets.
March 20, 2006, 10:18 PM
dRAgoN
[quote author=Juniper link=topic=14507.msg148744#msg148744 date=1142893103]
I think that this was already ported from C, I'm looking for the source code, or rather, a working source code in C that decompresses the packets.

[/quote]
https://davnit.net/bnet/vL/phpbbs/index.php?board=31;action=display;threadid=4109;start=msg33961#msg33961

Cant find the original post lol.
March 23, 2006, 6:55 AM
Juniper
Hi,

Is this: https://davnit.net/bnet/vL/phpbbs/index.php?board=31;action=display;threadid=4109;start=msg33961#msg33961 still valid?
Are the packets still compressed today (new patch) like they were when that post was posted (2003)?


thanks,
Juniper
May 24, 2006, 10:01 PM
l2k-Shadow
Yeah, the code still works... I was going to post that link but I saw reference to you downloading VB projects, so I thought that's what you were looking for.
May 24, 2006, 10:10 PM
Juniper
Ok, I'm back! and this time I have some results with me!
I've rewritten the code that Brand.X posted in https://davnit.net/bnet/vL/index.php?topic=585.msg4318#msg4318 .
I am now trying to figure out if I actually got it right, in order to do that I need one (or some) of you to pass the following packets through your packet decompressor and give me the result, so I could compare it to mine.

Here are the packets. Note that these are compressed packets (payload only),  S -> C:

Packet #1: 0c 58 1a 1d 38 62 14 93 8f c9 96 80
Packet #2: 07 1f 7f ff ff ff c0
Packet #3: 0f 52 0c ce 8a 63 c3 8b a9 ca e9 9e 94 59 b0
Packet #4: 10 52 0c ce 8a 63 c3 80 44 e3 42 67 a5 16 6c 00


Someone please decompress these and post the results, I must know if what I did so far is even working.

thanks in advance,
Juniper.
May 29, 2006, 10:21 PM
Infamous
[code]
6D FB 01 15 F4 42 15 93 12 80

8F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

67 BE 1F 50 81 01 59 15 58 12 01 00 0D 4B 00 05

67 BE 1F 50 81 01 71 15 6E 12 01 00 0D 4B 00 05
[/code]
May 30, 2006, 6:04 AM
Juniper
First of all, thanks for replying.
your decoded packets are not the same as mine.

Is your decoding procedure based on Brand.X's code and tables?
Did anyone else try to decode these packets by any change and got a different result?

Thanks,
Juniper
May 30, 2006, 9:38 AM
l2k-Shadow
Juniper you do realize that even if you manage to join a game, you will not be able to stay in it for a long period of time due to the fact that wardenclient check(which has not been publicly documented yet, and unless you can crack it yourself, you will probably not get the information) will just kick you off within a minute of joining the game.

Besides that though I will be posting my decompression results the moment I get home.
May 30, 2006, 7:45 PM
Juniper
Hi,
I've managed to use Brand.X's C code and use it to succesfully decode the packets (results are the same as what teK pasted).

I am wondering about something though. In the GamePacketSize function there is a value saved for "offset". But I haven't yet found out what use that offset has. Can anyone shed some light onto this?

Thanks.
May 30, 2006, 8:09 PM
Ringo
[quote author=Juniper link=topic=14507.msg153449#msg153449 date=1149019747]
I am wondering about something though. In the GamePacketSize function there is a value saved for "offset". But I haven't yet found out what use that offset has. Can anyone shed some light onto this?
[/quote]
It returns the offset to the decompressed data/lengh of the lengh header.
I was gonner post a class i wrote awhile back, but you have got it working now, so no need :P
May 30, 2006, 8:13 PM
Juniper
Hey Ringo,
I didn't quite understand that. It is an offset to some part in the original packet that is already decompressed? Also, what is a lengh header?
May 30, 2006, 8:20 PM
Ringo
hey, my falt, i should have explained it.

Im not to good at explaining things, but i hope you follow.

Its imprtant to note, that TCP can brake packets up/buffer them together when sending, and the best way to parse compleat messages is to have a header with the lengh of the packet being sent.
This way you can check the lengh in the header and snip out the data and read it, or if the data isnt all there, wait untill the rest is sent, so you can compleat the packet and snip/read it.
D2GS protocol uses a header like this, as i will explain with this packet:
[code]
07 1f 7f ff ff ff c0
[/code]
07 is the lengh header in this case, it tells us the lengh of the message is 7 bytes. (including the header)
The Offset for this will be 1, meaning that the header is 1 byte in lengh, so we can strip the data (1f 7f ff ff ff c0) away from the header and decompress it.
The header isnt always 1 byte in lengh, in some cases where the payload is over 0xF0 bytes long, 2 bytes are used ( see GetPacketSize() )

then when the data 1f 7f ff ff ff c0 is decompressed to the following:
[code]
8F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[/code]
The same thing happens again, there maybe multiple decompressed packets inside a compressed packet, and they also maybe broken across compressed packets, and almost all of them have a fixed lengh, apart from a few variable sized packets that have a lengh byte or other method to to work out the decompressed packets lengh.

Im pritty tired, so i hope this makes sence :P
May 30, 2006, 10:06 PM
l2k-Shadow
Each packet length is stored in one byte prior to the actual data, for some packets, however, the size of the packet is larger than 255, thus having to be stored in 2 bytes, offset simply returns the amount of bytes the length is in, being 1 in most cases.
May 30, 2006, 10:30 PM
Juniper
Ok, I understand that now.
So, let me ask you this, I've modified my code to take into consideration the length byte. Meaning, I'm starting to decode the REAL payload now (without the length byte).

Here are some examples:

Original packet (with length byte): 0c 58 0c 87 f0 02 7a 42 32 11 d9 5a
The Lengh byte is 0c, which means my real data should be 11 bytes long.
Decoded data: F6 03 00 00 4F 6C C0 13 D5 13 80


Original packet (with length byte): 0f 52 b8 22 01 62 73 85 56 40 8b 2f 4a 2a 58
The Lengh byte is 0f, which means my real data should be 13 bytes long.
Decoded data: 00 01 AB 8B 3D 01 E5 13 94 13 01 00 0D 46 00 05


Original packet (with length byte): 19 58 0c 87 f0 02 7a 42 32 11 d9 5a 5d 03 0c 06 62 70 e8 43 8e a4 40 d8 be
The Lengh byte is 19, which means my real data should be 24 bytes long.
Decoded data: F6 03 00 00 4F 6C C0 13 D5 13 80 95 9F 05 F9 40 7C E0 7D E2 73 02 00 00

Now, these are all packets that weren't splitted between several packets. As you can see they are short enough to do so.
My problem is that I cannot find the message ID of these packets (and many more packets) on bnet docs, or anywhere else.
Are most of the packets still unmapped?
I'm pretty sure (check my packets if you wish) that I'm decompressing the packets correctly, but I can't figure out what any of these packets actually do.

Can someone help me out?
thanks in advance,
J.
May 30, 2006, 11:27 PM
l2k-Shadow
Unless you're actually attempting to make a d2 game bot and getting past warden, you can safely ignore 99% of the packets. <.<
May 31, 2006, 12:32 AM
Ringo
[quote author=Juniper link=topic=14507.msg153469#msg153469 date=1149031644]
Original packet (with length byte): 0f 52 b8 22 01 62 73 85 56 40 8b 2f 4a 2a 58
The Lengh byte is 0f, which means my real data should be 13 bytes long.
Decoded data: 00 01 AB 8B 3D 01 E5 13 94 13 01 00 0D 46 00 05
[/quote]
That looks pritty much perfect, apart from "00 01" should be "67", so i think you maybe decompressing the lengh header with the payload, causeing it to "smudge"
May 31, 2006, 12:59 AM
Infamous
[quote author=l2k-Shadow link=topic=14507.msg153475#msg153475 date=1149035538]
Unless you're actually attempting to make a d2 game bot and getting past warden, you can safely ignore 99% of the packets. <.<
[/quote]

You don't need to get passed warden to make a game bot, 45 seconds is enough time to kill pindle :)
May 31, 2006, 3:26 AM
Ringo
I just hook a d2 window up as a back ground program in a fake game, to answer warden for multiple bots at a time :P
That way, i can run d2 remotely, and have warden scan a differnt system to what the bots are running from.
May 31, 2006, 9:20 AM
Infamous
[quote author=Ringo link=topic=14507.msg153497#msg153497 date=1149067213]
I just hook a d2 window up as a back ground program in a fake game, to answer warden for multiple bots at a time :P
That way, i can run d2 remotely, and have warden scan a differnt system to what the bots are running from.
[/quote]

Interesting. Mind sharing your code Ringo?
May 31, 2006, 1:50 PM
Juniper
Hi,
I want to clarify a few things that I'm still not sure about.

Again, I want to give an example to best illustrate the situation:

[code]Packet #1: 32 bd 04 4e 0d 01 88 1f 5a 1d 01 59 b1 a1 10 1c 1b 09 e6 87 64 04 65 32 08 81 c0 e6 ba 50 1c 85 00 15 9b 1a 03 71 e8 41 1d 0d 0e[/code]

[code]Packet #2: 1b 56 18 00 78 f2 14 8c 0b c4 60 7c ca 2a b0 00 74 1f 91 66 00 48 8c 10 99 39 80[/code]

As we already know, byte "32" in packet #1 is our length byte, which means the real compressed data payload is 49 bytes.
It's obvious that packet #1 holds less data than 49 bytes, it actually holds 42 bytes of payload. This means that the rest of the payload is in another packet.

This is a good place to ask my first question, when the data payload is fragmented, does the rest of the payload ALWAYS come in the following packet?

Let's suppose for a minute that packet #2 is indeed the continuation of packet #1, my logic says that I should treat packet #2 as if the data in it is a continuity of the data in packet #1. Meaning, the 1st byte of packet #2 is NOT a lenght byte, is this assumption correct?
So I decompress the first 7 bytes of packet#2 normally and glue them back to the data I alredy decoded in packet#1.

Now, after I've managed to identify the full payload that started in packet#1, I'm left with a half decoded packet (packet #2). Should I treat the 8th byte of packet#2 (which is for me, really, the 1st byte of new data) as a length byte? the 8th byte is 8C which is 140 bytes of data.

This is my understanding on how this whole mechanism works, can anyone confirm/deny what I just said?
It's really important to me to understand the complete flow of data.

thanks in advance,
J
May 31, 2006, 2:04 PM
l2k-Shadow
You're on the right track.. but not quite there yet. I think this site may help you understand D2GS a little bit more: http://bnetdocs.valhallalegends.com/content.php?Section=d&id=6 (scroll down to D2GS headers)
June 1, 2006, 5:55 AM
Ringo
[quote author=Juniper link=topic=14507.msg153501#msg153501 date=1149084298]
Hi,
I want to clarify a few things that I'm still not sure about.

Again, I want to give an example to best illustrate the situation:

[code]Packet #1: 32 bd 04 4e 0d 01 88 1f 5a 1d 01 59 b1 a1 10 1c 1b 09 e6 87 64 04 65 32 08 81 c0 e6 ba 50 1c 85 00 15 9b 1a 03 71 e8 41 1d 0d 0e[/code]

[code]Packet #2: 1b 56 18 00 78 f2 14 8c 0b c4 60 7c ca 2a b0 00 74 1f 91 66 00 48 8c 10 99 39 80[/code]

As we already know, byte "32" in packet #1 is our length byte, which means the real compressed data payload is 49 bytes.
It's obvious that packet #1 holds less data than 49 bytes, it actually holds 42 bytes of payload. This means that the rest of the payload is in another packet.

This is a good place to ask my first question, when the data payload is fragmented, does the rest of the payload ALWAYS come in the following packet?

Let's suppose for a minute that packet #2 is indeed the continuation of packet #1, my logic says that I should treat packet #2 as if the data in it is a continuity of the data in packet #1. Meaning, the 1st byte of packet #2 is NOT a lenght byte, is this assumption correct?
So I decompress the first 7 bytes of packet#2 normally and glue them back to the data I alredy decoded in packet#1.

Now, after I've managed to identify the full payload that started in packet#1, I'm left with a half decoded packet (packet #2). Should I treat the 8th byte of packet#2 (which is for me, really, the 1st byte of new data) as a length byte? the 8th byte is 8C which is 140 bytes of data.

This is my understanding on how this whole mechanism works, can anyone confirm/deny what I just said?
It's really important to me to understand the complete flow of data.

thanks in advance,
J
[/quote]

Yeah, you got it now :)
apart from:
[quote]
So I decompress the first 7 bytes of packet#2 normally and glue them back to the data I alredy decoded in packet#1.
[/quote]
Glue the missing data in packet#2 the end of packet #1 so you can re-read its header 0x32, see that you have the whole message, then decompress it.
And yeah, you can safely say that the next packet will be continueing on from the last.

Example:
GetData#1:
[code]
32 bd 04 4e 0d 01 88 1f 5a 1d 01 59 b1 a1 10 1c 1b 09 e6 87 64 04 65 32 08 81 c0 e6 ba 50 1c 85 00 15 9b 1a 03 71 e8 41 1d 0d 0e
[/code]
Packet lengh is 50 (payload of 49) but len(data) is 43 (data is missing), so we we store this data and wait.

GetData#2:
[code]
1b 56 18 00 78 f2 14 8c 0b c4 60 7c ca 2a b0 00 74 1f 91 66 00 48 8c 10 99 39 80
[/code]
Now we can append this to the end of are stored incompleat data:
[code]
32 bd 04 4e 0d 01 88 1f 5a 1d 01 59 b1 a1 10 1c 1b 09 e6 87 64 04 65 32 08 81 c0 e6 ba 50 1c 85 00 15 9b 1a 03 71 e8 41 1d 0d 0e 1b 56 18 00 78 f2 14 8c 0b c4 60 7c ca 2a b0 00 74 1f 91 66 00 48 8c 10 99 39 80
[/code]
Now we re-read the lengh header that says 50, len(data) is => the packet size, so we can snip out the 49 bytes of payload, and skip to the packet past that.
After decompressing the message and snipping it out, go onto the next:
[code]
14 8c 0b c4 60 7c ca 2a b0 00 74 1f 91 66 00 48 8c 10 99 39 80
[/code]
The lengh header says its 20 bytes (19 payload size), and all of the data is already there, so its just a case of decompressing this packets payload untill you come to the odd 0x80 byte, which is safe to presume its part of another broken packet, so again, store what you have and wait for the rest.


[EDIT]:
[quote author=teK link=topic=14507.msg153500#msg153500 date=1149083400]
Interesting. Mind sharing your code Ringo?
[/quote]
Theres not much more to it than the method i said above :P
Set up 3 sockets to listen, one on port 6112 (as bnet) and another on port 6113 (as realm) and another on port 4000 (as d2gs) and have them answer everything as success so d2 can go all the way to ingame, thinking its in a reall realm game.
Also on the same project, have the bot connections so you can make a queue of warden packets and transmite them to d2 as quick as d2 can transmite the result back.
It gets as confusing as you like tho, like when 1 bot does the warden version check on-join, and needs to DL a new warden module. :(
I spose the best tip i can give, is to make full use of the warden client we already have :P
June 1, 2006, 7:31 AM
l2k-Shadow
[quote author=teK link=topic=14507.msg153500#msg153500 date=1149083400]
Interesting. Mind sharing your code Ringo?
[/quote]

I made one of these programs long time ago, basically what you do is make like a gateway between you and battle.net and then when d2 gets the packet with the IP to which to connect for game, edit the IP to yourself and then when your program gets the warden, send it to your open d2 game, d2 game will answer it and you send it back... So basically you just have a d2 dummy running in the background answering warden but everything else you are doing on your own. Does that make sense?
June 1, 2006, 7:24 PM
Infamous
Yes I understand it now. I have started work on it but ran into a problem, how do you create packet 0x50 S>C?

Thanks.
June 1, 2006, 7:31 PM
warz
Has anyone looked into reverse engineering the warden protocol? Is there anything we know about warden as of right now? How does it work? Is there a specific dll file containing the warden related routines? I think I remember there being a warden.dll, or wardenclient.dll or something. I know, after looking at a lot of brood war in a debugger, that warden is present in starcraft and brood war too.

I wouldn't mind doing some reverse engineering in this field.
June 1, 2006, 7:34 PM
Juniper
Hi!
Me again!

Using the tips you guys gave me here I am now able to glue a lot of S>C traffic back together and then decompress it.

There are still some packets that are confusing me though.

Take this packet for example:
[code]01 dc 8a 17 8b 40 18 be 38 87 cc 9e 8a 21 68 92 17 83 92 59 24 ac 4c 0c c1 88 1c 84 01 3c 47 11 42 e8 49 0e c5 e4 20[/code]

This is the data portion of a given TCP segment. My previous D2 packet ended in the previous TCP segment (meaning all bytes required to fill whatever was in the D2 size byte were found in the previous TCP segment).
So this means I need to start processing this packet as a "new" one.

This would also mean that the D2 size byte is "01" meaning that the data portion of our D2 packet is zero bytes in length. That's already fairly odd.
If I for a minute assume this to be correct, that would mean that the first D2 packet to be found in this TCP segment is "01" and then the next one starts with "dc". The size byte in the 2nd packet is "dc" and processing could continue afterwards, having whatever is missing here be appended from following TCP segments, and so on.

The problem I am facing though is when I do as I just described then all the output of the packets/segments that follow this one stop making sense. If I ignore this packet (and all other packets where there apears to be more than 1 D2 packet to be found in the same TCP segment), then all my output continues to make sense. I am able to append segments to eachother forming new/real D2 packets as required by the D2 size byte and they decode/decompress to packets that actually seem to be correct for the situation in question.

So anyway, I guess my question is; if anyone were to encounter the packet I pasted above, how would it be processed? Assume that this is the output of ALL D2 bytes, so INCLUDING the header.

thanks,

J
June 6, 2006, 8:25 PM
Juniper
I don't like to bounce threads, but I'm really stuck without some help on my previous post  :(

Can anyone help me out?

thanks,
J
June 8, 2006, 12:54 PM
bethra
Meh, your name reminds me of the Cartoon Network show with the Asian girl Juniper Lee T_T;
June 8, 2006, 3:50 PM
Yegg
[quote author=Sorc.Polgara link=topic=14507.msg154107#msg154107 date=1149781858]
Meh, your name reminds me of the Cartoon Network show with the Asian girl Juniper Lee T_T;
[/quote]

Why not send him a private message saying that instead of adding a useless post to this thread?
June 8, 2006, 7:36 PM
Quarantine
Yea you're going to send a PM with something as dumb as that, I'd rather make an OT post.
June 8, 2006, 8:05 PM
Yegg
[quote author=Warrior link=topic=14507.msg154113#msg154113 date=1149797142]
Yea you're going to send a PM with something as dumb as that, I'd rather make an OT post.
[/quote]

If it's going to be a stupid post then why do we all need to se it? There are so many stupid posts out there by many people, not necessarily you, but I see them from quite the variety of people. If it "must" be said, then they should just PM it to the other user.
June 8, 2006, 8:33 PM
Ringo
Juniper, check out this post (the packet dumps), it might help you get your head round it.
June 8, 2006, 9:04 PM
Spilled[DW]
I honestly dont know why this post is still alive, as shadow as already said. If you do get into a game the warden client will kick you out within a minute so what is the point? I've already been through all of this before and it's just a dead end. There is plenty of post of helping you with decompression around the forum. Read.
June 10, 2006, 2:05 AM
Quarantine
[quote author=Yegg link=topic=14507.msg154116#msg154116 date=1149798834]
[quote author=Warrior link=topic=14507.msg154113#msg154113 date=1149797142]
Yea you're going to send a PM with something as dumb as that, I'd rather make an OT post.
[/quote]

If it's going to be a stupid post then why do we all need to se it? There are so many stupid posts out there by many people, not necessarily you, but I see them from quite the variety of people. If it "must" be said, then they should just PM it to the other user.
[/quote]

I'd much rather have it as an offtopic post. If someone would PM me "Wow your name sounds like xxxxx" I'd think they were weird stalkers..
June 10, 2006, 10:42 AM
bethra
Yegg, you need to chill out bro.  I don't see a mod tag under your name so stfu.  You remind me of a uptight bastard I know.
June 10, 2006, 4:11 PM
Infamous
[quote author=Spilled link=topic=14507.msg154164#msg154164 date=1149905120]
I honestly dont know why this post is still alive, as shadow as already said. If you do get into a game the warden client will kick you out within a minute so what is the point? I've already been through all of this before and it's just a dead end. There is plenty of post of helping you with decompression around the forum. Read.
[/quote]

There are many ways to get around Warden..Ringo posted one here.
June 10, 2006, 4:38 PM
Juniper
Hi everybody,

Something else/new is bothering me at the moment. I am happily decompressing/decoding a lot of D2 packets already, but every
now and then I stumble on a packet that throws everything out of wack.
Let me paint you some context.

Here are 2 subsequent D2 payloads that my capture prog (tcpdump) is feeding into my script. I feel I should mention that I am
looking at traffic coming from b.net on TCP port 4000 (so D2GS S>C traffic).

OK, here come the packets:
[code][D2 PAYLOAD] 12 44 02 8f ad 40 ba 22 e1 f5 a8 17 44 3f 9f 5a 81 70[/code]
[code][D2 PAYLOAD] f2 05 04 60 c8 3f 07 02 8b 30 4c 6a 3e 1b 2d 35 0d c2 a6 08 5c 19 07 e0 e0 51 48 ac 35 ba b0 64 1f 83 81 44 c0 13 1a 8f 86 da[/code]
[code][D2 PAYLOAD] 0c 2f 05 e1 e0 32 00 a2 c8 0b 1e 1c[/code]
[code][D2 PAYLOAD] 1a 52 08 81 a0 65 2f b8 56 35 04 06 cf 4a 2c d8 2f 05 c7 0c 00 28 64 31 00 ce[/code]

SO we have 4 packet payloads here. They are the data portions of 4 TCP segments following eachother in the TCP flow coming from port 4000.
The size byte of our first packet is 0x12, which is 17 decimal, so everything is there. I am decoding this to:
[code]DECODE] 07 88 03 80 04 02 07 90 03 80 04 02 07 98 03 80 04 02 (18 bytes)[/code]
And then splitting it into real D2 packets:
[code][DECODE] SPLIT: 07 88 03 80 04 02 (6 bytes) = [ACTION] MAPADD (= 07)
[DECODE] SPLIT: 07 90 03 80 04 02 (6 bytes) = [ACTION] MAPADD (= 07)
[DECODE] SPLIT: 07 98 03 80 04 02 (6 bytes) = [ACTION] MAPADD (= 07) [/code]
This completes the processing of our first payload. Untill now, everything for me looks OK (of course, please correct me if I am wrong).

OK, now, our next payload:
[code][D2 PAYLOAD] f2 05 04 60 c8 3f 07 02 8b 30 4c 6a 3e 1b 2d 35 0d c2 a6 08 5c 19 07 e0 e0 51 48 ac 35 ba b0 64 1f 83 81 44 c0 13 1a 8f 86 da[/code]
The first byte is greater than 0xF0, thus we use the first 2 bytes to calculate the size. I won't go into details here, since all of you are familiar with how it's done, but the size calculated from 0xF2 0x05 is 517.
Now, we only have 40 bytes here, so to get to our 517, I will have to append some packets to this one, before I actual start to decode/decompress it. I do this (with more packets than the 3 in my example, since those 3 don't add up to 517 yet, I just didn't want to spam too much).

About 5 seconds (and a lot of TCP segments) later I have enough bytes to make it add up to 517.
The end result is:
[code][DECODE] [DEBUG] Was passed array 'f2 05 04 60 c8 3f 07 02 8b 30 4c 6a 3e 1b 2d 35 0d c2 a6 08 5c 19 07 e0 e0 51 48 ac 35 ba b0 64 1f 83 81 44 c0 13 1a 8f 86 da 0c 2f 05 e1 e0 32 00 a2 c8 0b 1e 1c 1a 52 08 81 a0 65 2f b8 56 35 04 06 cf 4a 2c d8 2f 05 c7 0c 00 28 64 31 00 ce 1a 52 41 82 f1 dc 77 70 72 6a 09 cd 9e 94 59 b0 5e 0b 63 c0 5c 46 31 98 8f 30 07 1f 7f ff ff ff c0 19 52 08 81 a0 65 2f b8 53 35 03 c6 cf 4a 2c d8 2f 05 a7 0b 28 c6 23 13 ee 11 52 14 00 50 e6 5d 70 94 6a 0d 0d 9e 94 79 94 80 09 04 10 a0 02 87 32 e9 2c 67 44 b4 fa d4 0b a2 5a 7c 05 20 5d 12 d3 e5 c4 0b a4 70 d6 09 82 88 30 48 e1 a8 0c 03 41 71 23 86 71 40 77 04 c9 1c 31 83 40 5c 04 61 40 05 0e 65 d2 a3 86 53 50 6a 6c b4 8e 03 cf 9d 8f fc 89 01 a0 7c 5c 30 04 2e 14 00 50 e6 5d 0e 43 f1 15 6a 20 f9 21 1a 52 08 83 f0 dc 86 70 60 6a 05 4d 9e 94 59 b0 5e 0b 0e 44 00 a0 06 62 bb 80 10 52 08 81 a0 65 2f b9 10 6a 06 cd 9e 94 59 b0 0f 2e 83 20 0e 18 09 c3 a2 d1 28 79 09 0b e0 10 52 08 81 a0 65 2f b9 0e 6a 07 8d 9e 94 59 b0 10 52 41 82 f1 dc 77 70 74 6a 0a 8d 9e 94 59 b0 23 03 f0 a0 02 87 32 e9 a9 2c 36 1d 90 03 12 20 33 03 d2 28 e8 ba 0c 80 38 5c 27 0e 8b 44 a1 e4 24 2f 80 10 52 0d 8b ad 81 47 0a 86 a0 6c d9 e9 45 9b 00 34 02 b3 63 46 c1 68 5e 18 0d 0e c8 08 ca 64 25 8f 21 21 74 a2 1a 14 0a c8 30 5e 3b 8e e8 c1 d1 a8 2a 36 4a 94 d6 14 00 50 e6 1a 58 14 00 50 e6 5d 09 46 a0 d0 d9 69 74 19 80 70 c4 4e 1d 16 89 43 c8 48 5f 10 52 08 83 f0 dc 86 70 5e 6a 05 4d 9e 94 59 b0 10 52 0d 8b ad 81 47 0a 46 a0 70 d9 e9 45 9b 00 10 52 08 81 a0 65 2f b9 10 6a 08 4d 9e 94 59 b0 1f 52 14 00 50 e6 5d 72 18 d4 0f 1b 3d' for processing [/code]

So now the above packet is decoded to:
[code][DECODE] AC BD 2A C5 41 13 00 AF 11 8A 16 80 11 1C E4 00 00 AA 01 BD 2A C5 41 0A 69 FE 01 69 BD 2A C5 41 09 AF 11 8A 16 00 00 04 00 00 EF EF 81 F6 88 63 8B 81 01 BF 00 0A 32 FB 65 97 01 E6 11 A9 16 01 00 0D 4B 00 05 96 ED 01 F2 88 61 0B 84 01 FC 0A 00 BB 02 00 7F 7F 01 C6 11 B1 16 01 00 0D 4B 00 05 96 EC 81 ED 08 60 0B 82 00 5C 00 8F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5C 52 00 AB BF F7 97 01 E3 11 A7 16 01 00 0D 4B 00 05 96 EB 01 EA 08 5F 0B 03 01 D3 0A 45 88 7A 95 01 D8 11 BF 16 01 00 0D 82 00 4D 4F B0 D0 00 2F 00 06 00 00 0C 00 00 00 0A 00 05 00 00 1F 30 15 00 00 80 04 02 07 80 03 88 04 02 07 80 03 90 04 02 0A 01 FE AF DF BB 0A 01 FD 9F BF 57 0A 01 FA 3F 7F AF 0A 01 F5 BF B9 94 00 DE 88 7A 95 52 01 F7 11 C1 16 80 19 91 03 20 98 00 00 00 E8 8D A8 57 09 AA 01 DE 88 7A 95 22 2A 33 80 07 29 0A 0E 00 4D D2 93 75 06 00 18 09 11 9C 16 01 00 0D 4B 00 05 96 E9 01 E2 88 5C 0B 02 01 4F B3 AB BF F7 97 01 E2 11 A4 16 01 00 0D 4B 00 05 C9 00 01 04 00 00 A0 18 05 DC 7C 80 38 82 D6 02 00 00 71 42 D2 FB 65 97 01 E0 11 A7 16 01 00 0D 4B 00 05 CF 0A 00 BB 02 00 7F 7F 01 C7 11 B4 16 01 00 0D 4B 00 05 34 CC DE 88 7A 95 11 30 1B 7E 04 BC E2 F9 CA F0 1F 95 BD 85 ED 40 7C 80 38 82 D6 02 00 00 4F B3 C3 95 FF 9B 01 E4 11 A4 16 01 00 0D 4B 00 05 8D 7B 13 00 05 00 00 08 05 64 5A 5D 10 20 A0 00 65 0C 39 82 D6 02 0D 2E 06 04 69 B8 BA 7F 7F 08 C7 11 B4 16 0D 0D 11 00 DE 88 7A FC 05 3F 88 7A 95 D8 11 BF 16 80 95 BE 85 F4 40 7C 80 38 82 D6 02 00 00 2C 0A 32 93 75 06 00 18 96 14 00 9C 16 01 00 0D 4B 00 05 CF 0A 73 02 80 00 9B 01 E1 11 A5 16 01 00 0D 4B 00 05 71 42 D2 FB 65 97 01 E2 11 AA 16 01 00 0D 4B 00 05 29 00 0A 45 88 7A 95 01 CE 11 A7 16 01 00 (566 bytes)[/code]

And then I start splitting it up:

[code][ACTION] [DEBUG] The action ID is AC which has the length of 17 bytes.
[DECODE] SPLIT: AC BD 2A C5 41 13 00 AF 11 8A 16 80 11 1C E4 00 00 (17 bytes)
[ACTION] COMASIGNMENT - A computer player has been  assigned a location in our view (= AC)

[ACTION] [DEBUG] The action ID is AA which has the length of 10 bytes.
[DECODE] SPLIT: AA 01 BD 2A C5 41 0A 69 FE 01 (10 bytes)
[ACTION] COMINFOADD - An object came into our 4 screen view (= AA)

[ACTION] [DEBUG] The action ID is 69 which has the length of 12 bytes.
[DECODE] SPLIT: 69 BD 2A C5 41 09 AF 11 8A 16 00 00 (12 bytes)
[ACTION] COMSTATEASIGN - A computer player stats have changed (= 69)

[ACTION] [DEBUG] The action ID is 04 which has the length of 1 bytes.
[DECODE] SPLIT: 04 (1 bytes)
[ACTION] Message ID 04: *** UNKNOWN ***

[ACTION] [DEBUG] The action ID is 00 which has the length of 1 bytes.
[DECODE] SPLIT: 00 (1 bytes)
[ACTION] Message ID 00: *** UNKNOWN ***

[ACTION] [DEBUG] The action ID is 00 which has the length of 1 bytes.
[DECODE] SPLIT: 00 (1 bytes)
[ACTION] Message ID 00: *** UNKNOWN ***[/code]

And here my script fails. The next byte, after splitup is 0xEF and that's something that, as far as I know, is just not right, I should never bump on a 0xEF packet.
Now, I have no idea, really, where I went wrong exactly. Ringo posted something a while ago (https://davnit.net/bnet/vL/index.php?topic=11756.msg123533#msg123533) that had some code there as an example to show people how packets were split up. I used this and changed the input array to hold my packet (the F2 05 04 ... one). The output then shows the packet being decoded the same way as I do it. You see it being split up exactly like my script is doing and then you see it crash ... at the same byte (0xEF) as my script.
Now, since I don't think that there is actually anything wrong with what Ringo coded, I am thinking that I am being wrong in trying to decode/process the F2 05 04 ... packet. But I don't find any reason why I shouldn't be doing it. That's just where the packet(s) start and I have no idea why or if I should skip anything.

I know this is probably a longshot, but does anybody have a clue what I might be doing wrong here? :)

Thanks in advance!

Juniper










June 12, 2006, 9:03 PM
Ringo
[quote author=Juniper link=topic=14507.msg154291#msg154291 date=1150146238]
[code][DECODE] [DEBUG] Was passed array 'f2 05 04 60 c8 3f 07 02 8b 30 4c 6a 3e 1b 2d 35 0d c2 a6 08 5c 19 07 e0 e0 51 48 ac 35 ba b0 64 1f 83 81 44 c0 13 1a 8f 86 da 0c 2f 05 e1 e0 32 00 a2 c8 0b 1e 1c 1a 52 08 81 a0 65 2f b8 56 35 04 06 cf 4a 2c d8 2f 05 c7 0c 00 28 64 31 00 ce 1a 52 41 82 f1 dc 77 70 72 6a 09 cd 9e 94 59 b0 5e 0b 63 c0 5c 46 31 98 8f 30 07 1f 7f ff ff ff c0 19 52 08 81 a0 65 2f b8 53 35 03 c6 cf 4a 2c d8 2f 05 a7 0b 28 c6 23 13 ee 11 52 14 00 50 e6 5d 70 94 6a 0d 0d 9e 94 79 94 80 09 04 10 a0 02 87 32 e9 2c 67 44 b4 fa d4 0b a2 5a 7c 05 20 5d 12 d3 e5 c4 0b a4 70 d6 09 82 88 30 48 e1 a8 0c 03 41 71 23 86 71 40 77 04 c9 1c 31 83 40 5c 04 61 40 05 0e 65 d2 a3 86 53 50 6a 6c b4 8e 03 cf 9d 8f fc 89 01 a0 7c 5c 30 04 2e 14 00 50 e6 5d 0e 43 f1 15 6a 20 f9 21 1a 52 08 83 f0 dc 86 70 60 6a 05 4d 9e 94 59 b0 5e 0b 0e 44 00 a0 06 62 bb 80 10 52 08 81 a0 65 2f b9 10 6a 06 cd 9e 94 59 b0 0f 2e 83 20 0e 18 09 c3 a2 d1 28 79 09 0b e0 10 52 08 81 a0 65 2f b9 0e 6a 07 8d 9e 94 59 b0 10 52 41 82 f1 dc 77 70 74 6a 0a 8d 9e 94 59 b0 23 03 f0 a0 02 87 32 e9 a9 2c 36 1d 90 03 12 20 33 03 d2 28 e8 ba 0c 80 38 5c 27 0e 8b 44 a1 e4 24 2f 80 10 52 0d 8b ad 81 47 0a 86 a0 6c d9 e9 45 9b 00 34 02 b3 63 46 c1 68 5e 18 0d 0e c8 08 ca 64 25 8f 21 21 74 a2 1a 14 0a c8 30 5e 3b 8e e8 c1 d1 a8 2a 36 4a 94 d6 14 00 50 e6 1a 58 14 00 50 e6 5d 09 46 a0 d0 d9 69 74 19 80 70 c4 4e 1d 16 89 43 c8 48 5f 10 52 08 83 f0 dc 86 70 5e 6a 05 4d 9e 94 59 b0 10 52 0d 8b ad 81 47 0a 46 a0 70 d9 e9 45 9b 00 10 52 08 81 a0 65 2f b9 10 6a 08 4d 9e 94 59 b0 1f 52 14 00 50 e6 5d 72 18 d4 0f 1b 3d' for processing [/code][/quote]
I think your compression buffer is broken, because the message is only 106 bytes long, followed by a singlely compressed ping responce (07 1f 7f ff ff ff c0).
So i would say that F2 05 is part of a broken compressed packet. (check your recv buffer, that handles incoming data from the socket)

[EDIT]:
eh, i think your compressed data (quoted data), is currrupt through out.
June 14, 2006, 10:34 AM
warz
D2 game server programming looks fun. Hm. Reverse engineering warden might be fun too.
June 14, 2006, 12:26 PM
Juniper
[quote author=warz link=topic=14507.msg154345#msg154345 date=1150287960]
D2 game server programming looks fun. Hm. Reverse engineering warden might be fun too.
[/quote]

Perhaps, but I'm still at a point where I'm trying to figure out why my script for dcoding/decompressing data comming for b.net  isn't working perfectly :(

J
June 14, 2006, 12:35 PM
Ringo
[quote author=Juniper link=topic=14507.msg154346#msg154346 date=1150288508]
Perhaps, but I'm still at a point where I'm trying to figure out why my script for dcoding/decompressing data comming for b.net  isn't working perfectly :(

J
[/quote]
Lets see it then :p



[quote author=warz link=topic=14507.msg154345#msg154345 date=1150287960]
D2 game server programming looks fun. Hm. Reverse engineering warden might be fun too.
[/quote]
It might, but i bet it will become a nightmare :P
I was trying to make my own waren client awhile back (but got board, due to lack of interest and problems porting the RC4 functions)

Heres what iv found out about warden so far: (apart from warden being pritty dumb)
the payloads of S>C and C>S are both encrpyted with the same RC4 encryption algorithm, so i thought i would try port some random google'ed RC4 source code to vb so i could try de-encrypt the payloads.
(The encryption key, is the game hash (issued by the realm))
[code]
To: cypherpunks@toad.com
Subject: Thank you Bob Anderson
From: nobody@ jpunix.com
Date: Fri, 9 Sep 1994 22:11:49 -0500
Complaints-To: postmaster@jpunix.com
Remailed -By: remailer@ jpunix.com
Sender: owner-cypherpunks@toad.com

--------------------------------------------------------------------------------

SUBJECT:  RC4 Source Code


i 've tested this.  It is compatible with the RC4 object module
that comes in the various RSA toolkits.

/* rc4.h */
typedef struct rc4_key
{
     unsigned char state[256];
     unsigned char x;
     unsigned char y;
} rc4_key;
void prepare_key(unsigned char *key_data_ptr,int key_data_len,
rc4_key *key);
void rc4(unsigned char *buffer_ptr,int buffer_len,rc4_key * key);


/*rc4.c */
#include "rc4.h"
static void swap_byte(unsigned char *a, unsigned char *b);
void prepare_key(unsigned char *key_data_ptr, int key_data_len,
rc4_key *key)
{
     unsigned char swapByte;
     unsigned char index1;
     unsigned char index2;
     unsigned char* state;
     short counter;
     
     state = &key->state[0];
     for(counter = 0; counter < 256; counter++)
     state[counter] = counter;
     key->x = 0;
     key->y = 0;
     index1 = 0;
     index2 = 0;
     for(counter = 0; counter < 256; counter++)
     {
          index2 = (key_data_ptr[index1] + state[counter] +
index2) % 256;
          swap_byte(&state[counter], &state[index2]);

          index1 = (index1 + 1) % key_data_len;
     }
}

void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key
*key)
{
     unsigned char x;
     unsigned char y;
     unsigned char* state;
     unsigned char xorIndex;
     short counter;
     
     x = key->x;
     y = key->y;
     
     state = &key->state[0];
     for(counter = 0; counter < buffer_len; counter ++)
     {
          x = (x + 1) % 256;
          y = (state[x] + y) % 256;
          swap_byte(&state[x], &state[y]);
               
          xorIndex = state[x] + (state[y]) % 256;
               
          buffer_ptr[counter] ^= state[xorIndex];
      }
      key->x = x;
      key->y = y;
}

static void swap_byte(unsigned char *a, unsigned char *b)
{
     unsigned char swapByte;
     
     swapByte = *a;
     *a = *b;
     *b = swapByte;
}
[/code]
idk if this is the right encryption algorithm, but reverse engineering the one d2 uses is the 1st big step i spose. :P
June 14, 2006, 1:14 PM
Juniper
[quote author=Ringo link=topic=14507.msg154339#msg154339 date=1150281285]
[quote author=Juniper link=topic=14507.msg154291#msg154291 date=1150146238]
[code][DECODE] [DEBUG] Was passed array 'f2 05 04 60 c8 3f 07 02 8b 30 4c 6a 3e 1b 2d 35 0d c2 a6 08 5c 19 07 e0 e0 51 48 ac 35 ba b0 64 1f 83 81 44 c0 13 1a 8f 86 da 0c 2f 05 e1 e0 32 00 a2 c8 0b 1e 1c 1a 52 08 81 a0 65 2f b8 56 35 04 06 cf 4a 2c d8 2f 05 c7 0c 00 28 64 31 00 ce 1a 52 41 82 f1 dc 77 70 72 6a 09 cd 9e 94 59 b0 5e 0b 63 c0 5c 46 31 98 8f 30 07 1f 7f ff ff ff c0 19 52 08 81 a0 65 2f b8 53 35 03 c6 cf 4a 2c d8 2f 05 a7 0b 28 c6 23 13 ee 11 52 14 00 50 e6 5d 70 94 6a 0d 0d 9e 94 79 94 80 09 04 10 a0 02 87 32 e9 2c 67 44 b4 fa d4 0b a2 5a 7c 05 20 5d 12 d3 e5 c4 0b a4 70 d6 09 82 88 30 48 e1 a8 0c 03 41 71 23 86 71 40 77 04 c9 1c 31 83 40 5c 04 61 40 05 0e 65 d2 a3 86 53 50 6a 6c b4 8e 03 cf 9d 8f fc 89 01 a0 7c 5c 30 04 2e 14 00 50 e6 5d 0e 43 f1 15 6a 20 f9 21 1a 52 08 83 f0 dc 86 70 60 6a 05 4d 9e 94 59 b0 5e 0b 0e 44 00 a0 06 62 bb 80 10 52 08 81 a0 65 2f b9 10 6a 06 cd 9e 94 59 b0 0f 2e 83 20 0e 18 09 c3 a2 d1 28 79 09 0b e0 10 52 08 81 a0 65 2f b9 0e 6a 07 8d 9e 94 59 b0 10 52 41 82 f1 dc 77 70 74 6a 0a 8d 9e 94 59 b0 23 03 f0 a0 02 87 32 e9 a9 2c 36 1d 90 03 12 20 33 03 d2 28 e8 ba 0c 80 38 5c 27 0e 8b 44 a1 e4 24 2f 80 10 52 0d 8b ad 81 47 0a 86 a0 6c d9 e9 45 9b 00 34 02 b3 63 46 c1 68 5e 18 0d 0e c8 08 ca 64 25 8f 21 21 74 a2 1a 14 0a c8 30 5e 3b 8e e8 c1 d1 a8 2a 36 4a 94 d6 14 00 50 e6 1a 58 14 00 50 e6 5d 09 46 a0 d0 d9 69 74 19 80 70 c4 4e 1d 16 89 43 c8 48 5f 10 52 08 83 f0 dc 86 70 5e 6a 05 4d 9e 94 59 b0 10 52 0d 8b ad 81 47 0a 46 a0 70 d9 e9 45 9b 00 10 52 08 81 a0 65 2f b9 10 6a 08 4d 9e 94 59 b0 1f 52 14 00 50 e6 5d 72 18 d4 0f 1b 3d' for processing [/code][/quote]
I think your compression buffer is broken, because the message is only 106 bytes long, followed by a singlely compressed ping responce (07 1f 7f ff ff ff c0).
So i would say that F2 05 is part of a broken compressed packet. (check your recv buffer, that handles incoming data from the socket)

[EDIT]:
eh, i think your compressed data (quoted data), is currrupt through out.
[/quote]

You believe the data I'm giving the script is wrong/curropted?
Right now I'm passing onto the script the packets I get from tcpdump, I then strip them from their IP and TCP headers and process the data as mentioned above.

I've decided I'm going to post my original capture file.
The capture file can be found at: http://www.box.net/public/eg7dxlfbv6
If someone could decode/decompress this then I believe I'll be able to track down my problem and figure out why I'm not processing the input correctly.

Could someone *please* decode/decompress the capture file I'm posting and post/pm me back the result - I'll greatly appreciate it.

Thanks,
J
June 14, 2006, 3:25 PM
Juniper
Alright, I'm on the brink of despair.

I must have checked my input and decode functions a dozen times, I used both ethereal and tcpdump and I cannot see anything wrong with my input. As far as I know, I'm passing on the data correctly, as opposed to what Ringo suggested earlier. I'm not saying Ringo is wrong, I'm just saying that [u]I[/u] cannot see anything wrong with the data I'm handling.
I also read every possible post/thread relater to this subject of decompressing/parsing incoming packets.

Like I said in my previous post, I posted my capture file from tcpdump (it's filtered to only show S->C packets, because that's what I'm having problems with). It can be opened with ethereal too ofcourse.
I asked if someone could please grab the file and run it through thier decoder. No one did, so far.

Can someone please, pretty please (with a bit of sugar on top  :) ) decode that file for me and post here, or send me even a pm with the result?

Thanks,
J

EDIT: Ringo solved my problem! it seems my tcpdump snaplen was wrong and I wasn't capturing the entire packet, but only 68 bytes of it, which it tcpdump's default.
Thanks again Ringo!
June 21, 2006, 9:57 AM
Myndfyr
So, were you not debugging in a way that would make that clear to you?  Or was this problem entirely unrelated to actually programming a bot?
June 25, 2006, 10:21 PM
Juniper
I just didn't even consider the possibility that I wasn't capturing the entire packet. I was unaware of the snaplen variable and once Ringo pointed me in the direction that my input might be bad, well, I just focused on that and with some help saw the problem.

J
June 25, 2006, 11:32 PM

Search