Clan x86

Technical (Development, Security, etc.) => General Programming => Botdev => Topic started by: Lance on November 29, 2009, 11:46:51 pm

Title: Information on W3GS data
Post by: Lance on November 29, 2009, 11:46:51 pm
I am trying to figure out how to decode a buffer. In the thread in the quote below, the posters seem to decode the buffer somehow. How are they decoding the buffer? (which in the first code block seems to be enc1_raw)

Thanks :)

Quote from: http://forum.valhallalegends.com/index.php?topic=14994.msg152623#msg152623
i have some comments on the gameInfo packet.
about the encoded part.
i am very certain, as i stated in the other thread, that the encoded part starts after the 0x00 after the gamename. why?
1) in replays it starts there
2) some values tagged unknown by you do vanish...

example:
Code: [Select]
i let my encoded data start with 01034907... not with 997d01...

static const char enc1_raw[] =
{
0x01,0x03,0x49,0x07,0x01,0x01,0x7d,0x01,
0x99,0x7d,0x01,0xa3,0xdf,0x1d,0x43,0x4d,0x8b,0x61,
0x71,0x73,0x5d,0x29,0x35,0x29,0xcd,0x4d,0x6f,0x73,
0x75,0x55,0x65,0x6d,0xe9,0x71,0x6d,0x65,0x2f,0x77,
0x33,0x6d,0x89,0x01,0x47,0x6f,0x73,0x2f,0x53,0x65,
0x03,0x73,0x75,0x01,0x01
};
if we decode that, we get
Code: [Select]
02 48 06 00 00 7c 00 7c
.  H  .  .  .  |  .  |  
00 a3 df 1c 42 4d 61 70
.  .  .  .  B  M  a  p  
73 5c 28 34 29 4c 6f 73
s  \  (  4  )  L  o  s  
74 54 65 6d 70 6c 65 2e
t  T  e  m  p  l  e  .  
77 33 6d 00 46 6f 72 2e
w  3  m  .  F  o  r  .  
52 65 73 74 00 00
r  e  s  t
...
Title: Re: Decoding SID_GETADVLIST Data
Post by: rabbit on November 30, 2009, 07:52:03 am
I wonder why you haven't asked over at vL?  Anyway, the answer is invariably a variant of Grok's DebugOuput routine.  Search "DebugOutput" at vL and you'll find billions of copies.
Title: Re: Decoding SID_GETADVLIST Data
Post by: Lance on November 30, 2009, 10:38:17 am
I wonder why you haven't asked over at vL?  Anyway, the answer is invariably a variant of Grok's DebugOuput routine.  Search "DebugOutput" at vL and you'll find billions of copies.

I don't want to stretch myself too thin; barely have a post count here :P

By decode, I mean how 0x01 becomes 02, 0x03 becomes 48 etc. I have a variant of DebugOutput provided in the JavaOP util.Buffer class which I use to view the raw buffer, but it does not show similar contents (map location and player name) though the rest of the buffer shows what I expect. I guess this specific segment of the buffer needs special decoding  :'(

The mysterious segment:
Code: [Select]
01 03 49 07 01 01 77 01 89 79 01 cb 31 57 17 4d ..I...w..y..1W.M
cb 61 71 73 5d 45 6f 77 19 6f 6d 6f 61 65 5d 45 .aqs]Eow.omoae]E
2b 6f 75 41 21 41 6d 6d 2b 73 75 61 73 73 21 77 +ouA!Amm+suass!w
c1 37 2f 37 35 2f 77 33 51 79 01 45 6f 75 41 51 .7/75/w3Qy.EouAQ
d3 75 63 2f 41 51 45 4d 99 01 01 f3 35 89 1f 71 .uc/AQEM....5..q
b9 d5 c9 41 4d 29 43 39 67 6f 6b 59 af a3 cd 9b ...AM)C9gokY....
03 6f                                            .o
Length: 98

May DebugOutput be completely different from the method in JavaOp2?  :o
Title: Re: Decoding SID_GETADVLIST Data
Post by: MyndFyre on November 30, 2009, 12:09:12 pm
To clarify for everyone else, the title of this thread is misleading.  Sarcastic is looking for information about W3GS data.  The header leads one to think that you might be able to just find the info on BnetDocs....
Title: Re: Decoding SID_GETADVLIST Data
Post by: Lance on November 30, 2009, 01:02:30 pm
To clarify for everyone else, the title of this thread is misleading.  Sarcastic is looking for information about W3GS data.  The header leads one to think that you might be able to just find the info on BnetDocs....
Changed the title  :P
Title: Re: Information on W3GS data
Post by: rabbit on November 30, 2009, 01:52:21 pm
It seems that whatever is transcoding the raw to the output is doing it...weird.  The first byte is dropped, and the rest have 1 either added or subtracted from them and are then output.  Without code, it'll be hard to tell why your output is completely wrong.
Title: Re: Information on W3GS data
Post by: Lance on November 30, 2009, 02:01:56 pm
It seems that whatever is transcoding the raw to the output is doing it...weird.  The first byte is dropped, and the rest have 1 either added or subtracted from them and are then output.  Without code, it'll be hard to tell why your output is completely wrong.

I don't know what to make of this:
Quote from: Dota.For.Rest
                 |last Zero is not Coded - it used only for detect end of Coded data
                  |Decode is simple: all Coded data splited by 8 bytes blocks
                  |First byte of each block is first bits of 7 bytes data bit0 always 1
                  |Bit1 represents bit0 of byte1, bit2 represents bit0 of byte2 ...
                  |Left 7 bytes bit0 set to 1 for coded data

I'm new to Java and application programming in general, so sorry if it's obvious, but I just don't get it.
Title: Re: Information on W3GS data
Post by: Chavo on November 30, 2009, 02:33:46 pm
This code makes some assumptions that you won't want to make if you are implementing this.  It's purely part of a proof-of-concept that I eventually determined was impossible and thus, abandoned.

Code: [Select]
/*
 * @author: Chavo
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Chavoland.vHost.API.Util;

namespace Chavoland.vHost.Plugin.Util
{
    class Statstring
    {
        private static short mapWidth = 0x0074;
        private static short mapHeight = 0x0074;

        public static byte[] CreateStatString(string hostName, string mapPath, uint mapCRC)
        {
            DataBuffer data = new DataBuffer();
            try
            {
                if (mapPath.Length > 0 && hostName.Length > 0)
                {
                    data.InsertByte(0x02);  // game speed = fast
                    data.InsertByte(0x48);  // teams together, visibility = map default
                    data.InsertByte(0x06);  // lock teams
                    data.InsertByte(0x40);  // refs
                    data.InsertByte(0x00);  // unknown
                    //data.InsertByteArray(UNKNOWN);
                    data.InsertInt16(mapWidth);
                    data.InsertInt16(mapHeight);
                    data.InsertUInt32(mapCRC);
                    data.InsertCString(mapPath);
                    data.InsertCString(hostName);
                    data.InsertByte(0);

                    return EncodeStatString(data.GetData());
                }
            }
            catch (Exception ex){}

            return new byte[0];
        }

        public static byte[] EncodeStatString(byte[] data)
        {
            int i;
            byte mask;
            List<byte> list;

            try
            {
                mask = 1;
                list = new List<byte>();
                for (i = 0; i < data.Length; i++)
                {
                    if (data[i] % 2 == 0) // even
                        list.Add((byte) (data[i] + 1));
                    else                  // odd
                    {
                        list.Add(data[i]);
                        mask = (byte)(mask | (1 << (i % 7) + 1));
                    }

                    if ((i % 7) == 6 || i == (data.Length - 1))
                    {
                        list.Insert(list.Count - 1 - (i % 7), mask);
                        mask = 1;
                    }
                }
                return list.ToArray();
            }
            catch (Exception ex)
            {
                return new byte[0];
            }
        }

        public static byte[] DecodeStatString(byte[] code)
        {
            int i;
            byte mask;
            List<byte> list;
            
            try
            {
                i = 0;
                list = new List<byte>();
                if (code == null || code.Length == 0)
                {
                    return new byte[0];
                }

                mask = code[0];
                while (i < code.Length && code[i] != 0)
                {
                    if ((i % 8) == 0)
                    {
                        mask = code[i];
                    }
                    else
                    {
                        if ((mask & (1 << (i % 8))) == 0)
                        {
                            list.Add((byte) (code[i] - 1));
                        }
                        else
                        {
                            list.Add(code[i]);
                        }
                    }
                    i++;
                }
                return list.ToArray();
            }
            catch (Exception ex)
            {
                return new byte[0];
            }
        }
    }
}

But ya, I'm not sure I can explain it much more simply than for.rest's quote.  The encoding just takes 7 byte chunks of existing data, increments the even bytes and marks those increments those in a corresponding 1-byte bitfield that is appended to that modified 7-byte chunk to make a 8-byte chunk.  Decoding is just as straightfoward.
   
Title: Re: Information on W3GS data
Post by: Camel on November 30, 2009, 02:45:50 pm
I don't know what to make of this:
Quote from: Dota.For.Rest
                 |last Zero is not Coded - it used only for detect end of Coded data
                  |Decode is simple: all Coded data splited by 8 bytes blocks
                  |First byte of each block is first bits of 7 bytes data bit0 always 1
                  |Bit1 represents bit0 of byte1, bit2 represents bit0 of byte2 ...
                  |Left 7 bytes bit0 set to 1 for coded data

I'm new to Java and application programming in general, so sorry if it's obvious, but I just don't get it.
A byte is 8 bits, thus its value can be between 0 and 2^8-1. Read about bitwise operations - and/or/xor, shifts, etc. Don't confuse bitwise operations with boolean operations; they behave differently, but share the names. It should make more sense after you've mastered that.
Title: Re: Information on W3GS data
Post by: Lance on November 30, 2009, 04:00:30 pm
Chavo: That decode method worked like a charm ;D

Camel: I have re-read about bitwise operations, and it is starting to make some sense.

Thanks guys! :)