Update to capture unhandled packets that can desync client (orig credit: theFoof)
Based on DM conversation, extracted GetProtocolPacket -> IsProtocolPacket https://github.com/Jabantiz/EQ2Emulator-Rewrite/blob/master/trunk/source/common/Packets/ProtocolPacket.cpp ProtocolPacket* subPacket = ProtocolPacket::GetProtocolPacket(p->buffer + processed + offset, subpacket_length, false); if (subPacket) { //I've seen some garbage packets get sent with wrong protocol opcodes but the rest of the combine is still correct //So don't break if GetProtocolPacket fails ProcessPacket(subPacket); delete subPacket; } else if (ntohs(*reinterpret_cast<uint16_t*>(p->buffer + processed + offset)) > 0x1e) { //Garbage packet? crypto.RC4Decrypt(p->buffer + processed + offset, subpacket_length); LogError(LOG_PACKET, 0, "Garbage packet?!:"); DumpBytes(p->buffer + processed + offset, subpacket_length); }
This commit is contained in:
parent
bf4bf5ec4d
commit
ae6f55fd12
3 changed files with 45 additions and 7 deletions
|
@ -555,6 +555,31 @@ void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQProtocolPacket::IsProtocolPacket(const unsigned char* in_buff, uint32_t len, bool bTrimCRC) {
|
||||||
|
bool ret = false;
|
||||||
|
uint16_t opcode = ntohs(*(uint16_t*)in_buff);
|
||||||
|
uint32_t offset = 2;
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
case OP_SessionRequest:
|
||||||
|
case OP_SessionDisconnect:
|
||||||
|
case OP_KeepAlive:
|
||||||
|
case OP_SessionStatResponse:
|
||||||
|
case OP_Packet:
|
||||||
|
case OP_Combined:
|
||||||
|
case OP_Fragment:
|
||||||
|
case OP_Ack:
|
||||||
|
case OP_OutOfOrderAck:
|
||||||
|
case OP_OutOfSession:
|
||||||
|
{
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DumpPacketHex(const EQApplicationPacket* app)
|
void DumpPacketHex(const EQApplicationPacket* app)
|
||||||
|
|
|
@ -104,6 +104,8 @@ public:
|
||||||
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
||||||
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
|
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
|
||||||
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
|
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
|
||||||
|
static bool IsProtocolPacket(const unsigned char* in_buff, uint32_t len, bool bTrimCRC);
|
||||||
|
|
||||||
EQProtocolPacket *Copy() {
|
EQProtocolPacket *Copy() {
|
||||||
EQProtocolPacket* new_packet = new EQProtocolPacket(opcode,pBuffer,size);
|
EQProtocolPacket* new_packet = new EQProtocolPacket(opcode,pBuffer,size);
|
||||||
new_packet->eq2_compressed = this->eq2_compressed;
|
new_packet->eq2_compressed = this->eq2_compressed;
|
||||||
|
|
|
@ -239,17 +239,28 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||||
#ifdef LE_DEBUG
|
#ifdef LE_DEBUG
|
||||||
LogWrite(PACKET__DEBUG, 0, "Packet", "OP_Combined Packet %i (%u) (%u): ", count, subpacket_length, processed);
|
LogWrite(PACKET__DEBUG, 0, "Packet", "OP_Combined Packet %i (%u) (%u): ", count, subpacket_length, processed);
|
||||||
#endif
|
#endif
|
||||||
EQProtocolPacket *subp=new EQProtocolPacket(p->pBuffer+processed+offset,subpacket_length);
|
bool isSubPacket = EQProtocolPacket::IsProtocolPacket(p->pBuffer + processed + offset, subpacket_length, false);
|
||||||
subp->copyInfo(p);
|
if (isSubPacket) {
|
||||||
|
EQProtocolPacket* subp = new EQProtocolPacket(p->pBuffer + processed + offset, subpacket_length);
|
||||||
|
subp->copyInfo(p);
|
||||||
|
//I've seen some garbage packets get sent with wrong protocol opcodes but the rest of the combine is still correct
|
||||||
|
//So don't break if GetProtocolPacket fails
|
||||||
#ifdef LE_DEBUG
|
#ifdef LE_DEBUG
|
||||||
LogWrite(PACKET__DEBUG, 0, "Packet", "Opcode %i:", subp->opcode);
|
LogWrite(PACKET__DEBUG, 0, "Packet", "Opcode %i:", subp->opcode);
|
||||||
DumpPacket(subp);
|
DumpPacket(subp);
|
||||||
#endif
|
#endif
|
||||||
ProcessPacket(subp);
|
ProcessPacket(subp);
|
||||||
#ifdef LE_DEBUG
|
#ifdef LE_DEBUG
|
||||||
DumpPacket(subp);
|
DumpPacket(subp);
|
||||||
#endif
|
#endif
|
||||||
delete subp;
|
delete subp;
|
||||||
|
}
|
||||||
|
else if (ntohs(*reinterpret_cast<uint16_t*>(p->pBuffer + processed + offset)) > 0x1e) {
|
||||||
|
//Garbage packet?
|
||||||
|
crypto->RC4Decrypt(p->pBuffer + processed + offset, subpacket_length);
|
||||||
|
LogWrite(PACKET__ERROR, 0, "Packet", "Garbage packet?!:");
|
||||||
|
DumpPacket(p->pBuffer + processed + offset, subpacket_length);
|
||||||
|
}
|
||||||
processed+=subpacket_length+offset;
|
processed+=subpacket_length+offset;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue