Lineage 2 Game Protocol: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
| Zeile 1: | Zeile 1: | ||
| + | == Protocol dumps (GoD) == | ||
| + | |||
| + | [[Goddess of Destruction - Login]] | ||
| + | |||
== Initialisation == | == Initialisation == | ||
Version vom 20. Februar 2012, 18:41 Uhr
Inhaltsverzeichnis
Protocol dumps (GoD)
Goddess of Destruction - Login
Initialisation
- C->S
- SYN
- S->C
- SYN-ACK
- C->S
- ACK
Some packets:
- C->S Login
- 0x2b (UnicodeString: LoginName) (Bytes x4 from sessionKey2+4) (Bytes x4 from sessionKey2) (Bytes x8 from sessionKey1) 0x00000001
- C->S ProtocolVersion
- 0x0e (UInt: Protocol) 0x09, 0x07, 0x54, 0x56, 0x03, 0x09, 0x0B, 0x01, 0x07, 0x02, 0x54, 0x54, 0x56, 0x07, 0x00, 0x02,
0x55, 0x56, 0x00, 0x51, 0x00, 0x53, 0x57, 0x04, 0x07, 0x55, 0x08, 0x54, 0x01, 0x07, 0x01, 0x53,
0x00, 0x56, 0x55, 0x56, 0x01, 0x06, 0x05, 0x04, 0x51, 0x03, 0x08, 0x51, 0x08, 0x51, 0x56, 0x04,
0x54, 0x06, 0x55, 0x08, 0x02, 0x09, 0x51, 0x56, 0x01, 0x53, 0x06, 0x55, 0x04, 0x53, 0x00, 0x56,
0x56, 0x53, 0x01, 0x09, 0x02, 0x09, 0x01, 0x51, 0x54, 0x51, 0x09, 0x55, 0x56, 0x09, 0x03, 0x04,
0x07, 0x05, 0x55, 0x04, 0x06, 0x55, 0x04, 0x06, 0x09, 0x04, 0x51, 0x01, 0x08, 0x08, 0x06, 0x05,
0x52, 0x06, 0x04, 0x01, 0x07, 0x54, 0x03, 0x06, 0x52, 0x55, 0x06, 0x55, 0x55, 0x51, 0x01, 0x02,
0x04, 0x54, 0x03, 0x55, 0x54, 0x01, 0x57, 0x51, 0x55, 0x05, 0x52, 0x05, 0x54, 0x07, 0x51, 0x51,
0x55, 0x07, 0x02, 0x53, 0x53, 0x00, 0x52, 0x05, 0x52, 0x07, 0x01, 0x54, 0x00, 0x03, 0x05, 0x05,
0x08, 0x06, 0x05, 0x05, 0x06, 0x03, 0x00, 0x0D, 0x08, 0x01, 0x07, 0x09, 0x03, 0x51, 0x03, 0x07,
0x53, 0x09, 0x51, 0x06, 0x07, 0x54, 0x0A, 0x50, 0x56, 0x02, 0x52, 0x04, 0x05, 0x55, 0x51, 0x02,
0x53, 0x00, 0x08, 0x54, 0x04, 0x52, 0x56, 0x06, 0x02, 0x09, 0x00, 0x08, 0x03, 0x53, 0x56, 0x01,
0x05, 0x00, 0x55, 0x06, 0x08, 0x56, 0x04, 0x0D, 0x06, 0x07, 0x52, 0x06, 0x07, 0x04, 0x0A, 0x06,
0x01, 0x04, 0x54, 0x04, 0x00, 0x05, 0x02, 0x04, 0x54, 0x00, 0x09, 0x52, 0x53, 0x05, 0x04, 0x01,
0x04, 0x05, 0x05, 0x01, 0x52, 0x51, 0x52, 0x0D, 0x06, 0x51, 0x08, 0x09, 0x54, 0x53, 0x00, 0x0D,
0x01, 0x02, 0x03, 0x54, 0x53, 0x01, 0x05, 0x03, 0x08, 0x56, 0x54, 0x07, 0x02, 0x54, 0x0B, 0x06,
0xFB, 0x87, 0xB9, 0x4A }; // these last 4 bytes may differ
- C->S EnterWorld
- 0x11
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
C9 BC F2 A7 66 5A 0B 98 36 A5 BD 89 ED 7F E4 D7
6B 49 E2 9F EF 76 EB CE A3 FA F4 BF 0C 64 A3 B4
A4 CE DC C6 08 3E 6E EA 45 CA D3 FE 88 13 87 B8
06 2C 96 F0 9B 1E 8E BC C6 9B 98 C8 63 16 CF D0
29 00 00 00 0A E1 74 17 0A 08 00 08 5C 32 BD E1
5C 32 BE 22 5E 19 03 41
- C->S CharacterSelect
- 0x12 (UInt: Character Slot) 0x0000 0x00000000 0x00000000 0x00000000
- S->C KeyPacket
- (Packet type: 0x2E) (Byte: Protocol ok? 0x01: OK, 0x00: Not OK) (Byte x8: First 8 bytes of Crypto XOR key) 0x00000001 (Byte: ServerID) 0x00000000 (UInt: Opcode Obfuscator Seed)
- S->C CharSelectionInfo
- 0x09 (UInt: Number of characters) (UInt: Max number of characters allowed on this server) 0x00 (((UnicodeString: Name) (UInt: CharID) (UnicodeString: AccountName) (UInt: SessionID) (UInt: ClanID) 0x00000000 (UInt: Sex) (UInt: Race) (UInt: BaseClassID) (UInt: IsActive) (UInt: X) (UInt: Y) (UInt: Z) (Double: HP_Current) (Double: MP_Current) (UInt: SP) (UInt64: XP) (UInt: Level) (UInt: Karma) (UInt: PKs) (0x00000000 x8) (UInt x19: Equipment worn) (0x00000000 x6) (UInt: HairStyle) (UInt: HairColor) (UInt: Face) (Double: HP_Max) (Double: MP_Max) (UInt: DeleteDays) (UInt: ClassID) (UInt: LastUsedChar) (UChar: EnchantEffect) (UShort: AugumentID) (UShort: AugumentSmth) (UInt: TransformID)) x number of Characters)
Additional data fields in Freya: (UInt: PetID) (UInt: Level) 0x00000000 (UInt: Food) (Double: MaxHP) (Double: CurHP)
Additional data fields in High Five:(UInt: Vitality)
Crypto XOR key set to:
[Bytes 3-10 of the KeyPacket packet] 0xc8 0x27 0x93 0x01 0xa1 0x6c 0x31 0x97
OpCode Obfuscation
Pseudo-Randomisation function
unsigned int pseudo_rand()
{
unsigned int a;
a = ( m_seed * 0x343fd + 0x269EC3 ) & 0xFFFFFFFF;
m_seed = a;
unsigned int result = ( m_seed >> 0x10 ) & 0x7FFF;
return result;
}
Table initialisation
void init_tables( unsigned int seed )
{
unsigned int i = 0;
unsigned char tmp = 0;
unsigned int pos;
unsigned int cpos;
m_s1 = 0xD0;
m_s2 = 0x58; // Gracia, Part 2 (amount of opcodes, depends on the protocol version)
m_DecodeTable1 = (unsigned char *)malloc( sizeof(unsigned char) * (m_s1 + 1) );
m_DecodeTable2 = (unsigned char *)malloc( sizeof(unsigned char) * (m_s2 + 1) );
for( i = 0; i <= m_s1; i++ ) m_DecodeTable1[i] = (unsigned char)i;
for( i = 0; i <= m_s2; i++ ) m_DecodeTable2[i] = (unsigned char)i;
this->pseudo_srand( seed );
for( i = 1; i <= m_s1; i++ )
{
pos = this->pseudo_rand() % (i + 1);
// swap bytes [pos] and [i] in DecodeTable1
tmp = m_DecodeTable1[pos];
m_DecodeTable1[pos] = m_DecodeTable1[i];
m_DecodeTable1[i] = tmp;
}
for( i = 1; i <= m_s2; i++ )
{
pos = this->pseudo_rand() % (i + 1);
// swap bytes [pos] and [i] in DecodeTable2
tmp = m_DecodeTable2[pos];
m_DecodeTable2[pos] = m_DecodeTable2[i];
m_DecodeTable2[i] = tmp;
}
// 0x12 (CharacterSelect) isn't obfuscated
cpos = 0;
while( m_DecodeTable1[cpos] != 0x12 ) cpos++;
tmp = m_DecodeTable1[0x12];
m_DecodeTable1[0x12] = 0x12;
m_DecodeTable1[cpos] = tmp;
// 0xb1 (NetPing) isn't obfuscated either
cpos = 0;
while( m_DecodeTable1[cpos] != 0xB1 ) cpos++;
tmp = m_DecodeTable1[0xB1];
m_DecodeTable1[0xB1] = 0xB1;
m_DecodeTable1[cpos] = tmp;
// EncodeTables are just the reverse of DecodeTables
m_EncodeTable1 = (unsigned char *)malloc( sizeof(unsigned char) * (m_s1 + 1) );
m_EncodeTable2 = (unsigned char *)malloc( sizeof(unsigned char) * (m_s2 + 1) );
for( i = 0; i <= m_s1; i++ ) m_EncodeTable1[ m_DecodeTable1[i] ] = (unsigned char)i;
for( i = 0; i <= m_s2; i++ ) m_EncodeTable2[ m_DecodeTable2[i] ] = (unsigned char)i;
}
Decode IDs
int decodeIDs( unsigned char *packet_data_raw )
{
if( !packet_data_raw ) return 0;
unsigned char *data = packet_data_raw;
int ofs = 2; // offset of packet ID in raw data
int ret_val = 0;
if( m_DecodeTable1 )
{
if( data[ofs] >= m_s1 ) return -1;
else data[ofs] = m_DecodeTable1[ data[ofs] ];
ret_val = 1;
if( data[ofs] == 0xD0 ) // double-byte packet
{
ret_val = 2;
if( data[ofs + 1] >= m_s2 ) return -2;
else data[ofs + 1] = m_DecodeTable2[ data[ofs + 1] ];
}
}
return ret_val;
}
Encode IDs
int encodeIDs( unsigned char *packet_data_raw )
{
if( !packet_data_raw ) return 0;
unsigned char *data = packet_data_raw;
int ofs = 2; // offset of packet ID in raw data
int ret_val = 0;
if( m_EncodeTable1 )
{
if( data[ofs] >= m_s1 ) return -1;
else data[ofs] = m_EncodeTable1[ data[ofs] ];
ret_val = 1;
if( data[ofs] == 0xD0 ) // double-byte packet
{
ret_val = 2;
if( data[ofs + 1] >= m_s2 ) return -2;
else data[ofs + 1] = m_EncodeTable2[ data[ofs + 1] ];
}
}
return ret_val;
}