-
Reverse Decompression.
Hi, I finally got the compression to work. It was just a simple port to C++ from C#.
I have no idea how decompression would work. Here as an example of the compression code by krrios ported by me to C++.
So how does decompression work?
Code:
void PacketDisplay(char *buf,int iBytesSent);
int main()
{
char m_OutputBuffer[0x40000];
int m_Table[514] =
{
0x2, 0x000, 0x5, 0x01F, 0x6, 0x022, 0x7, 0x034, 0x7, 0x075, 0x6, 0x028, 0x6, 0x03B, 0x7, 0x032,
0x8, 0x0E0, 0x8, 0x062, 0x7, 0x056, 0x8, 0x079, 0x9, 0x19D, 0x8, 0x097, 0x6, 0x02A, 0x7, 0x057,
0x8, 0x071, 0x8, 0x05B, 0x9, 0x1CC, 0x8, 0x0A7, 0x7, 0x025, 0x7, 0x04F, 0x8, 0x066, 0x8, 0x07D,
0x9, 0x191, 0x9, 0x1CE, 0x7, 0x03F, 0x9, 0x090, 0x8, 0x059, 0x8, 0x07B, 0x8, 0x091, 0x8, 0x0C6,
0x6, 0x02D, 0x9, 0x186, 0x8, 0x06F, 0x9, 0x093, 0xA, 0x1CC, 0x8, 0x05A, 0xA, 0x1AE, 0xA, 0x1C0,
0x9, 0x148, 0x9, 0x14A, 0x9, 0x082, 0xA, 0x19F, 0x9, 0x171, 0x9, 0x120, 0x9, 0x0E7, 0xA, 0x1F3,
0x9, 0x14B, 0x9, 0x100, 0x9, 0x190, 0x6, 0x013, 0x9, 0x161, 0x9, 0x125, 0x9, 0x133, 0x9, 0x195,
0x9, 0x173, 0x9, 0x1CA, 0x9, 0x086, 0x9, 0x1E9, 0x9, 0x0DB, 0x9, 0x1EC, 0x9, 0x08B, 0x9, 0x085,
0x5, 0x00A, 0x8, 0x096, 0x8, 0x09C, 0x9, 0x1C3, 0x9, 0x19C, 0x9, 0x08F, 0x9, 0x18F, 0x9, 0x091,
0x9, 0x087, 0x9, 0x0C6, 0x9, 0x177, 0x9, 0x089, 0x9, 0x0D6, 0x9, 0x08C, 0x9, 0x1EE, 0x9, 0x1EB,
0x9, 0x084, 0x9, 0x164, 0x9, 0x175, 0x9, 0x1CD, 0x8, 0x05E, 0x9, 0x088, 0x9, 0x12B, 0x9, 0x172,
0x9, 0x10A, 0x9, 0x08D, 0x9, 0x13A, 0x9, 0x11C, 0xA, 0x1E1, 0xA, 0x1E0, 0x9, 0x187, 0xA, 0x1DC,
0xA, 0x1DF, 0x7, 0x074, 0x9, 0x19F, 0x8, 0x08D, 0x8, 0x0E4, 0x7, 0x079, 0x9, 0x0EA, 0x9, 0x0E1,
0x8, 0x040, 0x7, 0x041, 0x9, 0x10B, 0x9, 0x0B0, 0x8, 0x06A, 0x8, 0x0C1, 0x7, 0x071, 0x7, 0x078,
0x8, 0x0B1, 0x9, 0x14C, 0x7, 0x043, 0x8, 0x076, 0x7, 0x066, 0x7, 0x04D, 0x9, 0x08A, 0x6, 0x02F,
0x8, 0x0C9, 0x9, 0x0CE, 0x9, 0x149, 0x9, 0x160, 0xA, 0x1BA, 0xA, 0x19E, 0xA, 0x39F, 0x9, 0x0E5,
0x9, 0x194, 0x9, 0x184, 0x9, 0x126, 0x7, 0x030, 0x8, 0x06C, 0x9, 0x121, 0x9, 0x1E8, 0xA, 0x1C1,
0xA, 0x11D, 0xA, 0x163, 0xA, 0x385, 0xA, 0x3DB, 0xA, 0x17D, 0xA, 0x106, 0xA, 0x397, 0xA, 0x24E,
0x7, 0x02E, 0x8, 0x098, 0xA, 0x33C, 0xA, 0x32E, 0xA, 0x1E9, 0x9, 0x0BF, 0xA, 0x3DF, 0xA, 0x1DD,
0xA, 0x32D, 0xA, 0x2ED, 0xA, 0x30B, 0xA, 0x107, 0xA, 0x2E8, 0xA, 0x3DE, 0xA, 0x125, 0xA, 0x1E8,
0x9, 0x0E9, 0xA, 0x1CD, 0xA, 0x1B5, 0x9, 0x165, 0xA, 0x232, 0xA, 0x2E1, 0xB, 0x3AE, 0xB, 0x3C6,
0xB, 0x3E2, 0xA, 0x205, 0xA, 0x29A, 0xA, 0x248, 0xA, 0x2CD, 0xA, 0x23B, 0xB, 0x3C5, 0xA, 0x251,
0xA, 0x2E9, 0xA, 0x252, 0x9, 0x1EA, 0xB, 0x3A0, 0xB, 0x391, 0xA, 0x23C, 0xB, 0x392, 0xB, 0x3D5,
0xA, 0x233, 0xA, 0x2CC, 0xB, 0x390, 0xA, 0x1BB, 0xB, 0x3A1, 0xB, 0x3C4, 0xA, 0x211, 0xA, 0x203,
0x9, 0x12A, 0xA, 0x231, 0xB, 0x3E0, 0xA, 0x29B, 0xB, 0x3D7, 0xA, 0x202, 0xB, 0x3AD, 0xA, 0x213,
0xA, 0x253, 0xA, 0x32C, 0xA, 0x23D, 0xA, 0x23F, 0xA, 0x32F, 0xA, 0x11C, 0xA, 0x384, 0xA, 0x31C,
0xA, 0x17C, 0xA, 0x30A, 0xA, 0x2E0, 0xA, 0x276, 0xA, 0x250, 0xB, 0x3E3, 0xA, 0x396, 0xA, 0x18F,
0xA, 0x204, 0xA, 0x206, 0xA, 0x230, 0xA, 0x265, 0xA, 0x212, 0xA, 0x23E, 0xB, 0x3AC, 0xB, 0x393,
0xB, 0x3E1, 0xA, 0x1DE, 0xB, 0x3D6, 0xA, 0x31D, 0xB, 0x3E5, 0xB, 0x3E4, 0xA, 0x207, 0xB, 0x3C7,
0xA, 0x277, 0xB, 0x3D4, 0x8, 0x0C0, 0xA, 0x162, 0xA, 0x3DA, 0xA, 0x124, 0xA, 0x1B4, 0xA, 0x264,
0xA, 0x33D, 0xA, 0x1D1, 0xA, 0x1AF, 0xA, 0x39E, 0xA, 0x24F, 0xB, 0x373, 0xA, 0x249, 0xB, 0x372,
0x9, 0x167, 0xA, 0x210, 0xA, 0x23A, 0xA, 0x1B8, 0xB, 0x3AF, 0xA, 0x18E, 0xA, 0x2EC, 0x7, 0x062,
0x4, 0x00D
};
/*
Packet Id: 78
a2 1c 18 9f 3f ae 6 b8 68 8f f7 22 b aa
3 3b 7 cb b0 00 00 00 00 00 00 87 3c 8d
43 51 e0 b4 b9 1e 8 63 51 c8 1a
*/
/*unsigned char WhatitShouldBe[72] = {0xAE ,0x00 ,0x48 ,0x00 ,0x00 ,0x09 ,0x2F ,0x01 ,0x90 ,0x00 ,0x00 ,0x26 ,0x00 ,0x03 ,0x45 ,0x4E,
0x55 ,0x00 ,0x52 ,0x68 ,0x79 ,0x6D ,0x65 ,0x73 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x48 ,0x00 ,0x65 ,0x00 ,0x6C ,0x00 ,0x6C ,0x00 ,0x6F ,0x00 ,0x20 ,0x00 ,0x57 ,0x00 ,0x6F,
0x00 ,0x72 ,0x00 ,0x6C ,0x00 ,0x64 ,0x00 ,0x00};*/
unsigned char input[40] = {0x78,0xa2 ,0x1c ,0x18 ,0x9f ,0x3f ,0xae ,0x06 ,0xb8 ,0x68 ,0x8f ,0xf7 ,0x22 ,0x0b ,0xaa,
0x03 ,0x3b ,0x07 ,0xcb ,0xb0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x87 ,0x3c ,0x8d,
0x43 ,0x51 ,0xe0 ,0xb4 ,0xb9 ,0x1e ,0x08 ,0x63 ,0x51 ,0xc8 ,0x1a};
//unsigned char input[8] = {0xBF ,0x00 ,0x06 ,0x00 ,0x08 ,0x00};
int length = 40;
int holdCount = 0;
int holdValue = 0;
int packCount = 0;
int packValue = 0;
int byteValue = 0;
int inputLength = length;
int inputIndex = 0;
int outputCount = 0;
int *pTable = m_Table;
char *pOutputBuffer = m_OutputBuffer;
while ( inputIndex < inputLength )
{
byteValue = input[inputIndex++] << 1;
packCount = pTable[byteValue];
packValue = pTable[byteValue | 1];
holdValue <<= packCount;
holdValue |= packValue;
holdCount += packCount;
while ( holdCount >= 8 )
{
holdCount -= 8;
pOutputBuffer[outputCount++] = (char)(holdValue >> holdCount);
}
}
packCount = pTable[0x200];
packValue = pTable[0x201];
holdValue <<= packCount;
holdValue |= packValue;
holdCount += packCount;
while ( holdCount <= 8 )
{
holdCount += 8;
pOutputBuffer[outputCount++] = (char)(holdValue >> holdCount);
}
if ( holdCount > 0 )
pOutputBuffer[outputCount++] = (char)(holdValue << (8 - holdCount));
cout << pOutputBuffer << endl;
cout << outputCount << endl;
PacketDisplay(pOutputBuffer,outputCount);
system("pause");
return EXIT_SUCCESS;
}
void PacketDisplay(char *buf,int iBytesSent)
{
int i;
int display;
if(int(buf[0])<0)
{
display = (255 + (int(buf[0])+1));
cout << " Packet Id: " << hex<<display << endl;
}
else
{
cout << " Packet Id: " << hex<<int(buf[0]) << endl;
}
for(i=1;i<iBytesSent;i++)
{
if(buf[i] == 0)
{
cout << "00" << " ";
}
else if(buf[i] < 0)
{
display = 255 + (int(buf[i])+1);
cout << display << " ";
}
else
{
cout << int(buf[i]) << " ";
}
}
cout << endl;
}
-
Bit shifting.
Without studying the code in detail, it looks like it uses bit shifting to pack two bytes (8-bits) into a 16-bit integer. It does this by sticking a byte into the (otherwise unused) upper 8 bits.
If you understand binary, hex, and bitwise operations, you should be able to write the code to unpack the bytes.
Note that hex is usually used (rather than decimal) when you're working with binary and/or bits. This is because it's easy to convert between hex an binary. (I did notice that the code uses decimal 255, rather than FF, as a constant.)
FYI- The Windows calculator can do hex, binary, and decimal conversions. START->PROGRAMS->ACCESSORIES->CALCULATOR.
-
Ok I researched what you said till I understood it, and I think I do.
so Here is what I came up with
Code:
unsigned char input[6] = {174,0x00,0x48 ,0x00 ,0x00 ,0x09};
int length = 6;
int holdCount = 0;
int holdValue = 0;
int packCount = 0;
int packValue = 0;
int byteValue = 0;
int inputLength = length;
int inputIndex = 0;
int outputCount = 0;
int *pTable = m_Table;
char *pOutputBuffer = m_OutputBuffer;
while (inputIndex < inputLength)
{
byteValue = input[inputIndex++];
byteValue = byteValue >> 8;
byteValue = input[inputIndex] >> 8;
pOutputBuffer[inputIndex] = (char)byteValue;
}
PacketDisplay(pOutputBuffer,inputLength*2);
system("pause");
return EXIT_SUCCESS;
}
void PacketDisplay(char *buf,int iBytesSent)
{
int i;
int display;
if(int(buf[0])<0)
{
display = (255 + (int(buf[0])+1));
cout << " Packet Id: " << hex<<display << endl;
}
else
{
cout << " Packet Id: " << hex<<int(buf[0]) << endl;
}
for(i=1;i<iBytesSent;i++)
{
if(buf[i] == 0)
{
cout << "00" << " ";
}
else if(buf[i] < 0)
{
display = 255 + (int(buf[i])+1);
cout << display << " ";
}
else
{
cout << int(buf[i]) << " ";
}
}
cout << endl;
}
But it just outputs cc. I puch a 1 byte value into a 4 byte int. Then move the 1 byte value over 8 bits.
then its just 0 or CC?
Im learning this slowly sorry.