Да у меня просто не так много опыта. Анализировал пакеты одной любительской игры, там был HEX наоборот, а тут чего-то каждый раз все разное.Quote:
Нагибатор
вообще то, шифрование - стандартная вещь для ммо
Да, я нашел информацию, некто Vort тут (и еще на олчитс) выкладывал исходный код декриптора на слил ру (не остался ли у кого?), но файл удален уже. Есть только функции на си без комментариев.Quote:
уже два года назад все расшифровали
MD5, SHA2_256, HMAC_MD5, RC4 (каждый используется в определенных ситуациях)
Не могли бы вы, пожалуйста, объяснить, как ими пользоваться и что на входе и выходе? Я не силен в си, можно в ПМ.
Code:
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// PWEncDec.h
#pragma once
#include "Defs.h"
// ----------------------------------------------------------------------------
class CPacketEncDec
{
public:
CPacketEncDec()
{
for (dword i = 0; i < 256; i++)
m_Table[i] = i;
m_Shift1 = 0;
m_Shift2 = 0;
}
void Shuffle(byte* Key)
{
byte Shift = 0;
for (dword i = 0; i < 256; i++)
{
byte A = Key[i % 16];
Shift += A + m_Table[i];
byte B = m_Table[i];
m_Table[i] = m_Table[Shift];
m_Table[Shift] = B;
}
}
void Encode(byte* InPacket, dword PacketSize, byte* OutPacket)
{
for (dword i = 0; i < PacketSize; i++)
{
m_Shift1++;
byte A = m_Table[m_Shift1];
m_Shift2 += A;
byte B = m_Table[m_Shift2];
m_Table[m_Shift2] = A;
m_Table[m_Shift1] = B;
byte C = A + B;
byte D = m_Table[C];
OutPacket[i] = InPacket[i] ^ D;
}
}
private:
byte m_Shift1;
byte m_Shift2;
byte m_Table[256];
};
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// PWUnpack.h
#pragma once
#include "Defs.h"
#include "Array2.h"
#include <windows.h>
// ----------------------------------------------------------------------------
class CUnpack
{
public:
CUnpack()
{
m_PackedOffset = 0;
m_Stage = 0;
}
CArray<byte> AddByte(byte InB)
{
m_Packed.PushBack(InB);
CArray<byte> UnpackedChunk;
for (;;)
{
if (m_Stage == 0)
{
if (HasBits(4))
{
if (GetPackedBits(1) == 0)
{
// 0-xxxxxxx
m_Code1 = 1;
m_Stage = 1;
continue;
}
else
{
if (GetPackedBits(1) == 0)
{
// 10-xxxxxxx
m_Code1 = 2;
m_Stage = 1;
continue;
}
else
{
if (GetPackedBits(1) == 0)
{
// 110-xxxxxxxxxxxxx-*
m_Code1 = 3;
m_Stage = 1;
continue;
}
else
{
if (GetPackedBits(1) == 0)
{
// 1110-xxxxxxxx-*
m_Code1 = 4;
m_Stage = 1;
continue;
}
else
{
// 1111-xxxxxx-*
m_Code1 = 5;
m_Stage = 1;
continue;
}
}
}
}
}
else
break;
}
else if (m_Stage == 1)
{
if (m_Code1 == 1)
{
if (HasBits(7))
{
byte OutB = byte(GetPackedBits(7));
UnpackedChunk.PushBack(OutB);
m_Unpacked.PushBack(OutB);
m_Stage = 0;
continue;
}
else
break;
}
else if (m_Code1 == 2)
{
if (HasBits(7))
{
byte OutB = byte(GetPackedBits(7)) | 0x80;
UnpackedChunk.PushBack(OutB);
m_Unpacked.PushBack(OutB);
m_Stage = 0;
continue;
}
else
break;
}
else if (m_Code1 == 3)
{
if (HasBits(13))
{
m_Shift = GetPackedBits(13) + 0x140;
m_Stage = 2;
continue;
}
else
break;
}
else if (m_Code1 == 4)
{
if (HasBits(8))
{
m_Shift = GetPackedBits(8) + 0x40;
m_Stage = 2;
continue;
}
else
break;
}
else if (m_Code1 == 5)
{
if (HasBits(6))
{
m_Shift = GetPackedBits(6);
m_Stage = 2;
continue;
}
else
break;
}
}
else if (m_Stage == 2)
{
if (m_Shift == 0)
{
// Guess !!!
if (m_PackedOffset)
{
m_PackedOffset = 0;
m_Packed.PopFront();
}
m_Stage = 0;
continue;
}
m_Code2 = 0;
m_Stage = 3;
continue;
}
else if (m_Stage == 3)
{
if (HasBits(1))
{
if (GetPackedBits(1) == 0)
{
m_Stage = 4;
continue;
}
else
{
m_Code2++;
continue;
}
}
else
break;
}
else if (m_Stage == 4)
{
dword CopySize = 0;
if (m_Code2 == 0)
CopySize = 3;
else
{
dword Sz = m_Code2 + 1;
if (HasBits(Sz))
CopySize = GetPackedBits(Sz) + (1 << Sz);
else
break;
}
Copy(m_Shift, CopySize, UnpackedChunk);
m_Stage = 0;
continue;
}
}
return UnpackedChunk;
}
private:
void Notify(char* Msg)
{
MessageBoxA(0, Msg, "", 0);
}
void Copy(dword Shift, dword Size, CArray<byte>& UnpackedChunk)
{
for (dword i = 0; i < Size; i++)
{
int PIndex = m_Unpacked.Size() - Shift;
if (PIndex < 0)
Notify("Unpack error");
else
{
byte B = m_Unpacked[PIndex];
m_Unpacked.PushBack(B);
UnpackedChunk.PushBack(B);
}
}
}
dword GetPackedBits(dword BitCount)
{
if (BitCount > 16)
return 0;
if (!HasBits(BitCount))
Notify("Unpack bit stream overflow");
dword AlBitCount = BitCount + m_PackedOffset;
dword AlByteCount = (AlBitCount + 7) / 8;
dword V = 0;
for (dword i = 0; i < AlByteCount; i++)
V |= dword(m_Packed[i]) << (24 - i * 8);
V <<= m_PackedOffset;
V >>= 32 - BitCount;
m_PackedOffset += BitCount;
dword FreeBytes = m_PackedOffset / 8;
if (FreeBytes)
m_Packed.PopFront(FreeBytes);
m_PackedOffset %= 8;
return V;
}
bool HasBits(dword Count)
{
return (m_Packed.Size() * 8 - m_PackedOffset) >= Count;
}
private:
dword m_Code1;
dword m_Code2;
dword m_Stage;
dword m_Shift;
byte m_PackedOffset;
CArray<byte> m_Packed;
CArray<byte> m_Unpacked;
};
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=