123 lines
3.9 KiB
C++
123 lines
3.9 KiB
C++
#include "stdafx.h"
|
|
#include "L2Game_KeyPacket.h"
|
|
|
|
/**
|
|
* ==========================================
|
|
Retail NCSoft
|
|
19 00 // p.len 25
|
|
2E // pcode
|
|
01 // always const
|
|
42 55 77 8F C3 05 69 87 // xorkey first part
|
|
01 00 00 00 // always const
|
|
01 // possible Game Server ID - depends on game server ID
|
|
00 00 00 00 // always NULLs
|
|
XX XX XX XX // always different, non-nulls: opcode obfuscator
|
|
*/
|
|
|
|
L2Game_KeyPacket::L2Game_KeyPacket()
|
|
{
|
|
this->_initNull();
|
|
}
|
|
|
|
L2Game_KeyPacket::L2Game_KeyPacket( const unsigned char *bytes, unsigned int length )
|
|
{
|
|
this->_initNull();
|
|
this->setBytes( bytes, length );
|
|
}
|
|
|
|
// key must point to buffer large enough to hold 8 bytes
|
|
bool L2Game_KeyPacket::read_key( unsigned char *key )
|
|
{
|
|
if( !key ) return false;
|
|
this->readReset();
|
|
if( this->canReadBytes(10) )
|
|
{
|
|
this->readUChar(); // packet type (0x0e in hellbound, 0x00 - interlude)
|
|
this->readUChar(); // 0x01 ?
|
|
return this->readBytes( key, 8 );
|
|
}
|
|
else return false;
|
|
}
|
|
|
|
unsigned char L2Game_KeyPacket::read_GameServerID()
|
|
{
|
|
if( !this->canReadBytes(5) ) return 0x00;
|
|
this->readUInt(); // 01 00 00 00 // always const
|
|
return this->readUChar(); // 01 // possible Game Server ID
|
|
}
|
|
|
|
unsigned int L2Game_KeyPacket::read_OpcodeObfuscator()
|
|
{
|
|
if( !this->canReadBytes(4) ) return 0x00000000;
|
|
this->readUInt(); // 00 00 00 00 // always 0x00000000, read 4 NULLs
|
|
return this->readUInt(); // XX XX XX XX // always different, opcode obfuscator
|
|
}
|
|
|
|
// keyPacket array points to key bytes received from KeyPacket (8 bytes)
|
|
// keyResult will hold resultig key (16 bytes)
|
|
void L2Game_KeyPacket::createInitialHellboundKey(
|
|
const unsigned char *keyPacket,
|
|
unsigned char *keyResult )
|
|
{
|
|
if( !keyPacket || !keyResult ) return;
|
|
// first 8 bytes of key are from KeyPacket
|
|
keyResult[0] = keyPacket[0];
|
|
keyResult[1] = keyPacket[1];
|
|
keyResult[2] = keyPacket[2];
|
|
keyResult[3] = keyPacket[3];
|
|
keyResult[4] = keyPacket[4];
|
|
keyResult[5] = keyPacket[5];
|
|
keyResult[6] = keyPacket[6];
|
|
keyResult[7] = keyPacket[7];
|
|
// last 8 bytes are constant in T1/T1.5/T2/T2.2/T2.3...
|
|
keyResult[8] = (unsigned char)0xc8;
|
|
keyResult[9] = (unsigned char)0x27;
|
|
keyResult[10] = (unsigned char)0x93;
|
|
keyResult[11] = (unsigned char)0x01;
|
|
keyResult[12] = (unsigned char)0xa1;
|
|
keyResult[13] = (unsigned char)0x6c;
|
|
keyResult[14] = (unsigned char)0x31;
|
|
keyResult[15] = (unsigned char)0x97;
|
|
}
|
|
|
|
/*** Format:
|
|
19 00 // plen = 25
|
|
2E // pcode
|
|
01 // 00 - wrong proto, 01 - proto OK
|
|
B6 4D 20 15 CE 0E BC 7A // 1st 8 bytes of crypto key
|
|
01 00 00 00 // 0x01
|
|
09 // game serverID
|
|
00 00 00 00 // wtf?
|
|
E3 D1 10 2F // obfuscation key ***/
|
|
bool L2Game_KeyPacket::parse( L2_VERSION ver /*= L2_VERSION_T1*/ )
|
|
{
|
|
UNREFERENCED_PARAMETER( ver );
|
|
readReset();
|
|
if( !canReadBytes( 19 ) ) return false; // packet size is at least 19 bytes O_o
|
|
getPacketType();
|
|
this->p_protocolIsOK = readUChar(); // 0x01 - proto OK, 0x00 - proto not supported
|
|
readBytes( this->p_initialKey, 8 ); // first 8 bytes of XOR key
|
|
readD(); // 0x00000001
|
|
this->p_serverId = readUChar(); // server ID
|
|
readD(); // 0x00000000;
|
|
this->p_obfuscatorSeed = readUInt(); // obfuscator seed
|
|
// add last 8 bytes of XOR key - they are constant
|
|
createInitialHellboundKey( p_initialKey, p_initialKey );
|
|
//
|
|
return true;
|
|
}
|
|
|
|
bool L2Game_KeyPacket::create( L2_VERSION ver )
|
|
{
|
|
UNREFERENCED_PARAMETER( ver );
|
|
writeReset();
|
|
setPacketType( 0x2E );
|
|
writeUChar( p_protocolIsOK );
|
|
writeBytes( p_initialKey, 8 );
|
|
writeD( 1 );
|
|
writeUChar( p_serverId );
|
|
writeD( 0 );
|
|
writeUInt( p_obfuscatorSeed );
|
|
return true;
|
|
}
|