• Welcome to Valhalla Legends Archive.
 

In-Game Packet Decompression

Started by Brand.X, February 13, 2003, 11:02 AM

Previous topic - Next topic

Brand.X

This code is based on a disassembly from fog.dll.

Quote//----------------------------------------------------------------------
// Packet Decompression Tables
//----------------------------------------------------------------------

unsigned int CharIndex[] = {
    0x0247, 0x0236, 0x0225, 0x0214, 0x0203, 0x01F2, 0x01E1, 0x01D0,
    0x01BF, 0x01AE, 0x019D, 0x018C, 0x017B, 0x016A, 0x0161, 0x0158,
    0x014F, 0x0146, 0x013D, 0x0134, 0x012B, 0x0122, 0x0119, 0x0110,
    0x0107, 0x00FE, 0x00F5, 0x00EC, 0x00E3, 0x00DA, 0x00D1, 0x00C8,
    0x00BF, 0x00B6, 0x00AD, 0x00A8, 0x00A3, 0x009E, 0x0099, 0x0094,
    0x008F, 0x008A, 0x0085, 0x0080, 0x007B, 0x0076, 0x0071, 0x006C,
    0x0069, 0x0066, 0x0063, 0x0060, 0x005D, 0x005A, 0x0057, 0x0054,
    0x0051, 0x004E, 0x004B, 0x0048, 0x0045, 0x0042, 0x003F, 0x003F,
    0x003C, 0x003C, 0x0039, 0x0039, 0x0036, 0x0036, 0x0033, 0x0033,
    0x0030, 0x0030, 0x002D, 0x002D, 0x002A, 0x002A, 0x0027, 0x0027,
    0x0024, 0x0024, 0x0021, 0x0021, 0x001E, 0x001E, 0x001B, 0x001B,
    0x0018, 0x0018, 0x0015, 0x0015, 0x0012, 0x0012, 0x0012, 0x0012,
    0x000F, 0x000F, 0x000F, 0x000F, 0x000C, 0x000C, 0x000C, 0x000C,
    0x0009, 0x0009, 0x0009, 0x0009, 0x0006, 0x0006, 0x0006, 0x0006,
    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};


unsigned char CharTable[] = {
    0x00,0x00,0x01,0x00,0x01,0x04,0x00,0xFF,0x06,0x00,0x14,0x06,
    0x00,0x13,0x06,0x00,0x05,0x06,0x00,0x02,0x06,0x00,0x80,0x07,
    0x00,0x6D,0x07,0x00,0x69,0x07,0x00,0x68,0x07,0x00,0x67,0x07,
    0x00,0x1E,0x07,0x00,0x15,0x07,0x00,0x12,0x07,0x00,0x0D,0x07,
    0x00,0x0A,0x07,0x00,0x08,0x07,0x00,0x07,0x07,0x00,0x06,0x07,
    0x00,0x04,0x07,0x00,0x03,0x07,0x00,0x6C,0x08,0x00,0x51,0x08,
    0x00,0x20,0x08,0x00,0x1F,0x08,0x00,0x1D,0x08,0x00,0x18,0x08,
    0x00,0x17,0x08,0x00,0x16,0x08,0x00,0x11,0x08,0x00,0x10,0x08,
    0x00,0x0F,0x08,0x00,0x0C,0x08,0x00,0x0B,0x08,0x00,0x09,0x08,
    0x01,0x96,0x09,0x97,0x09,0x01,0x90,0x09,0x95,0x09,0x01,0x64,
    0x09,0x6B,0x09,0x01,0x62,0x09,0x63,0x09,0x01,0x56,0x09,0x58,
    0x09,0x01,0x52,0x09,0x55,0x09,0x01,0x4D,0x09,0x50,0x09,0x01,
    0x45,0x09,0x4C,0x09,0x01,0x40,0x09,0x43,0x09,0x01,0x31,0x09,
    0x3B,0x09,0x01,0x28,0x09,0x30,0x09,0x01,0x1A,0x09,0x25,0x09,
    0x01,0x0E,0x09,0x19,0x09,0x02,0xE2,0x0A,0xE8,0x0A,0xF0,0x0A,
    0xF8,0x0A,0x02,0xC0,0x0A,0xC2,0x0A,0xCE,0x0A,0xE0,0x0A,0x02,
    0xA0,0x0A,0xA2,0x0A,0xB0,0x0A,0xB8,0x0A,0x02,0x8A,0x0A,0x8F,
    0x0A,0x93,0x0A,0x98,0x0A,0x02,0x81,0x0A,0x82,0x0A,0x83,0x0A,
    0x89,0x0A,0x02,0x7C,0x0A,0x7D,0x0A,0x7E,0x0A,0x7F,0x0A,0x02,
    0x77,0x0A,0x78,0x0A,0x79,0x0A,0x7A,0x0A,0x02,0x73,0x0A,0x74,
    0x0A,0x75,0x0A,0x76,0x0A,0x02,0x6E,0x0A,0x6F,0x0A,0x70,0x0A,
    0x72,0x0A,0x02,0x61,0x0A,0x65,0x0A,0x66,0x0A,0x6A,0x0A,0x02,
    0x5D,0x0A,0x5E,0x0A,0x5F,0x0A,0x60,0x0A,0x02,0x57,0x0A,0x59,
    0x0A,0x5A,0x0A,0x5B,0x0A,0x02,0x4A,0x0A,0x4B,0x0A,0x4E,0x0A,
    0x53,0x0A,0x02,0x46,0x0A,0x47,0x0A,0x48,0x0A,0x49,0x0A,0x02,
    0x3F,0x0A,0x41,0x0A,0x42,0x0A,0x44,0x0A,0x02,0x3A,0x0A,0x3C,
    0x0A,0x3D,0x0A,0x3E,0x0A,0x02,0x36,0x0A,0x37,0x0A,0x38,0x0A,
    0x39,0x0A,0x02,0x32,0x0A,0x33,0x0A,0x34,0x0A,0x35,0x0A,0x02,
    0x2B,0x0A,0x2C,0x0A,0x2D,0x0A,0x2E,0x0A,0x02,0x26,0x0A,0x27,
    0x0A,0x29,0x0A,0x2A,0x0A,0x02,0x21,0x0A,0x22,0x0A,0x23,0x0A,
    0x24,0x0A,0x03,0xFB,0x0B,0xFC,0x0B,0xFD,0x0B,0xFE,0x0B,0x1B,
    0x0A,0x1B,0x0A,0x1C,0x0A,0x1C,0x0A,0x03,0xF2,0x0B,0xF3,0x0B,
    0xF4,0x0B,0xF5,0x0B,0xF6,0x0B,0xF7,0x0B,0xF9,0x0B,0xFA,0x0B,
    0x03,0xE9,0x0B,0xEA,0x0B,0xEB,0x0B,0xEC,0x0B,0xED,0x0B,0xEE,
    0x0B,0xEF,0x0B,0xF1,0x0B,0x03,0xDE,0x0B,0xDF,0x0B,0xE1,0x0B,
    0xE3,0x0B,0xE4,0x0B,0xE5,0x0B,0xE6,0x0B,0xE7,0x0B,0x03,0xD6,
    0x0B,0xD7,0x0B,0xD8,0x0B,0xD9,0x0B,0xDA,0x0B,0xDB,0x0B,0xDC,
    0x0B,0xDD,0x0B,0x03,0xCD,0x0B,0xCF,0x0B,0xD0,0x0B,0xD1,0x0B,
    0xD2,0x0B,0xD3,0x0B,0xD4,0x0B,0xD5,0x0B,0x03,0xC5,0x0B,0xC6,
    0x0B,0xC7,0x0B,0xC8,0x0B,0xC9,0x0B,0xCA,0x0B,0xCB,0x0B,0xCC,
    0x0B,0x03,0xBB,0x0B,0xBC,0x0B,0xBD,0x0B,0xBE,0x0B,0xBF,0x0B,
    0xC1,0x0B,0xC3,0x0B,0xC4,0x0B,0x03,0xB2,0x0B,0xB3,0x0B,0xB4,
    0x0B,0xB5,0x0B,0xB6,0x0B,0xB7,0x0B,0xB9,0x0B,0xBA,0x0B,0x03,
    0xA9,0x0B,0xAA,0x0B,0xAB,0x0B,0xAC,0x0B,0xAD,0x0B,0xAE,0x0B,
    0xAF,0x0B,0xB1,0x0B,0x03,0x9F,0x0B,0xA1,0x0B,0xA3,0x0B,0xA4,
    0x0B,0xA5,0x0B,0xA6,0x0B,0xA7,0x0B,0xA8,0x0B,0x03,0x92,0x0B,
    0x94,0x0B,0x99,0x0B,0x9A,0x0B,0x9B,0x0B,0x9C,0x0B,0x9D,0x0B,
    0x9E,0x0B,0x03,0x86,0x0B,0x87,0x0B,0x88,0x0B,0x8B,0x0B,0x8C,
    0x0B,0x8D,0x0B,0x8E,0x0B,0x91,0x0B,0x03,0x2F,0x0B,0x4F,0x0B,
    0x54,0x0B,0x5C,0x0B,0x71,0x0B,0x7B,0x0B,0x84,0x0B,0x85,0x0B
};

unsigned int BitMasks[] = {
    0x0000,0x0001,0x0003,0x0007,0x000F,0x001F,0x003F,0x007F,
    0x00FF,0x01FF,0x03FF,0x07FF,0x0FFF,0x1FFF,0x3FFF,0x7FFF
};

//----------------------------------------------------------------------
// GamePacketSize
//   Calculates the size of a compressed game packet.
//  
// data: [in] pointer to received packet
// size: [out] pointer to size
// returns: the offset to the data.
//----------------------------------------------------------------------

unsigned char *GamePacketSize(unsigned char *data, unsigned int *size,
                              unsigned int *offset)
{
    unsigned int a;

    if (data[0] < 0xF0) {
        *size = data[0] - 1;
        *offset = 1;
        return &data[1];
    }

    a = (data[0] & 0xF) << 8;
    *size = a + data[1] - 2;
    *offset = 2;
    return &data[2];
}

//----------------------------------------------------------------------
// GamePacketDecode
//   Decompress a d2gs packet into data.
//   Note: packets come in clumps. A single compressed packet may have
//   several game packets, and its up to you to figure it out.
//
// indata: [in] compressed packet (without size byte)
// insize: [in] length of indata
// outdata: [out] output buffer
// outmax: [in] size of output buffer
// outsize: [out] location to store size of decoded data
// returns: 1 on successf decode, 0 if not enough room
//----------------------------------------------------------------------

int GamePacketDecode(unsigned char *indata, unsigned int insize,
                     unsigned char *outdata, unsigned int outmax,
                     unsigned int *outsize)
{
    unsigned int a, b, c, d;
    unsigned int maxcnt, index, cnt;
    unsigned char *outptr, *inptr;
    int size;

    b = 0;

    size = insize;
    inptr = indata;

    maxcnt = outmax;
    outptr = outdata;
    cnt = 0x20;

    while (1) {

        if (cnt >= 0x8) {
            while (size > 0 && cnt >= 8) {
                cnt -= 0x8;
                size--;
                a = *inptr++ << cnt;
                b |= a;
            };
        }

        index = CharIndex[b >> 0x18];
        a = CharTable[index];
        d = (b >> (0x18 - a)) & BitMasks[a];
        c = CharTable[index + 2*d + 2];

        cnt += c;
        if (cnt > 0x20) {
            *outsize = outmax - maxcnt;
            return 1;
        }

        if (maxcnt-- == 0)
            return 0;

        a = CharTable[index + 2*d + 1];
        *outptr++ = (unsigned char)a;

        b <<= (c & 0xFF);
    }

    assert(0);
    return 0;
}


dxoigmn

#1
Ahh...nice.  I was looking into this but my skill at converting ASM to C++ is horrible.  Thanks ;).

talon60k

#2
nice!

Brand.X

#3
The work was mostly stepping through function calls with SoftICE trying to find where decompression was happening. And the dumping of the memory which contained the tables. It was a lot easier than I expected; thanks to Blizzard's clean code.

People had this information before but kept it private. Not mentioning any names, but I hope it will speed up bot development in general.

l)ragon

QuoteThe work was mostly stepping through function calls with SoftICE trying to find where decompression was happening. And the dumping of the memory which contained the tables. It was a lot easier than I expected; thanks to Blizzard's clean code.

People had this information before but kept it private. Not mentioning any names, but I hope it will speed up bot development in general.

it was not private it is in the hackit source code if i remember correctly.

*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

l)ragon

in any case maybe someone will sticky this thread due to the point lots of people were looking for this.

maybe we will see some d2gs talk now ^^
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

Noodlez

#6
now im not special anymore :(

dragon it was private, d2hackit intercepted packets after they were decompressed. oh well, atleast my gamebots done :P

l)ragon

#7
Quotenow im not special anymore :(

dragon it was private, d2hackit intercepted packets after they were decompressed. oh well, atleast my gamebots done :P

you'll get over it. :P

to anyone that can see the decompressed data, PM me.

kthx
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

talon60k

#8
Quotenow im not special anymore :(

dragon it was private, d2hackit intercepted packets after they were decompressed. oh well, atleast my gamebots done :P

when u gonna release it tho ?

yeah, that decompression was private, i figured out my own version also. my bots pretty much done tho also, so hopefully there wont be too many bots!

Noodlez

and maybe when your communist ass dies ill spit on your grave

talon60k

#10
Quoteand maybe when your communist ass dies ill spit on your grave

lmao, me or dragon ?

c0ke

#11
Quotenow im not special anymore :(

dragon it was private, d2hackit intercepted packets after they were decompressed. oh well, atleast my gamebots done :P

Noodlez; special because you were given first Yobguls', then Talon's decompression source?

(sorry in advance, this is for flaming me on blizzhackers)

Noodlez

talon, was talking to warz  not you :p
but he removed his post, guess he didn't want people to see it.

l)ragon

#13
* dRAgoN kicks topic back to the top of the list

This is a rather usefull topic.
Would someone Pin it or some thing along with the .BNI tut. Kain posted this way there both up at the top and noone asks + then theres also no need to search it out 8p

Quote from: laurion on May 31, 2003, 06:14 AM
Quote from: dRAgoN on May 31, 2003, 02:44 AM
* dRAgoN kicks topic back to the top of the list

This is a rather usefull topic.
Would someone Pin it or some thing along with the .BNI tut. Kain posted this way there both up at the top and noone asks + then theres also no need to search it out 8p
the BNI tut is on http://botdev.valhallalegends.com/

forgot about that
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

Tazo

Quote from: dRAgoN on May 31, 2003, 02:44 AM
* dRAgoN kicks topic back to the top of the list

This is a rather usefull topic.
Would someone Pin it or some thing along with the .BNI tut. Kain posted this way there both up at the top and noone asks + then theres also no need to search it out 8p
the BNI tut is on http://botdev.valhallalegends.com/