Kod:
File > libthecore/src/buffer.c
Search for :
void buffer_realloc(LPBUFFER& buffer, int length);
Add this directly below it:
static void buffer_compact(LPBUFFER buffer)
{
if (!buffer || buffer->read_point == buffer->mem_data)
return;
if (buffer->length > 0)
memmove(buffer->mem_data, buffer->read_point, buffer->length);
buffer->read_point = buffer->mem_data;
buffer->write_point = buffer->mem_data + buffer->length;
buffer->write_point_pos = buffer->length;
}
Search inside both buffer_get_pool_index and buffer_get_exac_pool_index :
for (i = 0; i < 32; ++i) {
Replace both with:
for (i = 0; i < 31; ++i) {
Search for :
LPBUFFER buffer_new(int size)
Add this at the start of the function:
if (size < 0) {
return NULL;
}
Search for :
void buffer_write(LPBUFFER& buffer, const void *src, int length)
Replace the complete function with:
void buffer_write(LPBUFFER& buffer, const void *src, int length)
{
if (!buffer || !src || length <= 0)
{
if (length < 0)
sys_err("buffer_write: invalid length %d", length);
return;
}
if (buffer->write_point_pos > INT_MAX - length)
{
sys_err("buffer_write: size overflow (%d + %d)", buffer->write_point_pos, length);
return;
}
if (buffer_has_space(buffer) < length)
buffer_compact(buffer);
if (buffer_has_space(buffer) < length)
{
const int required = buffer->write_point_pos + length;
const int spare = MIN(10240, length);
buffer_realloc(buffer, required <= INT_MAX - spare ? required + spare : required);
}
thecore_memcpy(buffer->write_point, src, length);
buffer_write_proceed(buffer, length);
}
Search for :
void buffer_read(LPBUFFER buffer, void * buf, int bytes)
Replace the complete function with:
void buffer_read(LPBUFFER buffer, void * buf, int bytes)
{
if (!buffer || !buf || bytes <= 0)
{
if (bytes < 0)
sys_err("buffer_read: invalid length %d", bytes);
return;
}
if (bytes > buffer->length)
{
sys_err("buffer_read: requested %d bytes from %d-byte buffer", bytes, buffer->length);
return;
}
thecore_memcpy(buf, buffer->read_point, bytes);
buffer_read_proceed(buffer, bytes);
}
Search for these three complete functions :
buffer_byte
buffer_word
buffer_dword
Replace them with:
BYTE buffer_byte(LPBUFFER buffer)
{
if (!buffer || buffer->length < (int)sizeof(BYTE))
return 0;
BYTE val = *(BYTE *) buffer->read_point;
buffer_read_proceed(buffer, sizeof(BYTE));
return val;
}
WORD buffer_word(LPBUFFER buffer)
{
if (!buffer || buffer->length < (int)sizeof(WORD))
return 0;
WORD val = *(WORD *) buffer->read_point;
buffer_read_proceed(buffer, sizeof(WORD));
return val;
}
DWORD buffer_dword(LPBUFFER buffer)
{
if (!buffer || buffer->length < (int)sizeof(DWORD))
return 0;
DWORD val = *(DWORD *) buffer->read_point;
buffer_read_proceed(buffer, sizeof(DWORD));
return val;
}
Search for :
void buffer_read_proceed(LPBUFFER buffer, int length)
Make sure the function starts with:
if (length == 0)
return;
if (length < 0)
{
sys_err("buffer_proceed: length argument lower than zero (length: %d)", length);
return;
}
else if (length > buffer->length)
{
sys_err("buffer_proceed: length argument bigger than buffer (length: %d, buffer: %d)", length, buffer->length);
length = buffer->length;
}
Search for :
void buffer_write_proceed(LPBUFFER buffer, int length)
Replace the complete function with:
void buffer_write_proceed(LPBUFFER buffer, int length)
{
if (!buffer || length < 0 || length > buffer_has_space(buffer))
{
sys_err("buffer_write_proceed: invalid length %d (space %d)", length, buffer ? buffer_has_space(buffer) : 0);
return;
}
buffer->length += length;
buffer->write_point += length;
buffer->write_point_pos += length;
}
Search for :
void buffer_adjust_size(LPBUFFER& buffer, int add_size)
Replace the complete function with:
void buffer_adjust_size(LPBUFFER& buffer, int add_size)
{
if (!buffer || add_size <= 0)
return;
if (buffer_has_space(buffer) < add_size)
buffer_compact(buffer);
if (buffer_has_space(buffer) >= add_size)
return;
if (buffer->write_point_pos > INT_MAX - add_size)
{
sys_err("buffer_adjust_size: size overflow (%d + %d)", buffer->write_point_pos, add_size);
return;
}
sys_log(0, "buffer_adjust %d current %d/%d", add_size, buffer->length, buffer->mem_size);
const int required = buffer->write_point_pos + add_size;
const int target = buffer->mem_size <= INT_MAX - add_size ? buffer->mem_size + add_size : required;
buffer_realloc(buffer, target);
}
Search for :
void buffer_realloc(LPBUFFER& buffer, int length)
Replace the complete function definition with:
void buffer_realloc(LPBUFFER& buffer, int length)
{
int i, read_point_pos;
LPBUFFER temp;
if (!buffer || length < 0)
{
sys_err("buffer_realloc: invalid length %d", length);
return;
}
if (buffer->mem_size >= length)
return;
buffer_compact(buffer);
i = length - buffer->mem_size;
if (i <= 0)
return;
temp = buffer_new(length);
sys_log(0, "reallocating buffer to %d, current %d", temp->mem_size, buffer->mem_size);
thecore_memcpy(temp->mem_data, buffer->mem_data, buffer->length);
read_point_pos = buffer->read_point - buffer->mem_data;
temp->write_point = temp->mem_data + buffer->write_point_pos;
temp->write_point_pos = buffer->write_point_pos;
temp->read_point = temp->mem_data + read_point_pos;
temp->flag = buffer->flag;
temp->next = 0;
temp->length = buffer->length;
buffer_delete(buffer);
buffer = temp;
}
File > EterLib/NetStream.cpp
Search for :
void CNetworkStream::SetRecvBufferSize(int recvBufSize)
void CNetworkStream::ReleaseRecvBuffer()
Replace both complete functions with:
void CNetworkStream::SetRecvBufferSize(int recvBufSize)
{
if (recvBufSize <= 0)
{
ReleaseRecvBuffer();
return;
}
if (m_recvBuf && m_recvBufSize >= recvBufSize)
return;
ReleaseRecvBuffer();
m_recvBufSize = recvBufSize;
m_recvBuf = new char[m_recvBufSize];
m_recvTEABufSize = ((m_recvBufSize>>3)+1)<<3;
m_recvTEABuf = new char[m_recvTEABufSize];
}
void CNetworkStream::ReleaseRecvBuffer()
{
delete [] m_recvBuf;
m_recvBuf = NULL;
m_recvBufSize = 0;
m_recvBufInputPos = 0;
m_recvBufOutputPos = 0;
delete [] m_recvTEABuf;
m_recvTEABuf = NULL;
m_recvTEABufSize = 0;
m_recvTEABufInputPos = 0;
}
Search for :
void CNetworkStream::SetSendBufferSize(int sendBufSize)
Add this at the start of the function:
if (sendBufSize <= 0)
{
delete [] m_sendBuf;
m_sendBuf = NULL;
m_sendBufSize = 0;
m_sendBufInputPos = 0;
m_sendBufOutputPos = 0;
delete [] m_sendTEABuf;
m_sendTEABuf = NULL;
m_sendTEABufSize = 0;
m_sendTEABufInputPos = 0;
return;
}
Add this after the m_sendBuf and m_sendTEABuf allocations:
m_sendBufInputPos = 0;
m_sendBufOutputPos = 0;
m_sendTEABufInputPos = 0;
Search inside CNetworkStream::CNetworkStream :
m_sendTEABuf
Use these three initializers:
m_sendTEABuf = NULL;
m_sendTEABufSize = 0;
m_sendTEABufInputPos = 0;
Search for :
bool CNetworkStream::Peek(int size)
Add this at the start:
if (size < 0 || !m_recvBuf)
return false;
Search for :
bool CNetworkStream::Peek(int size, char * pDestBuf)
Add this at the start:
if (size < 0 || (size > 0 && !pDestBuf))
return false;
Search for :
bool CNetworkStream::Send(int size, const char * pSrcBuf)
Replace its validation/copy beginning with:
if (size <= 0 || !pSrcBuf || !m_sendBuf)
return false;
int sendBufRestSize = m_sendBufSize - m_sendBufInputPos;
if (sendBufRestSize <= 1 || size > sendBufRestSize - 1)
return false;
memcpy(m_sendBuf + m_sendBufInputPos, pSrcBuf, size);
m_sendBufInputPos += size;
Search for every "if (recvSize < 0)" inside :
__RecvInternalBuffer
Use this in all three receive branches:
if (recvSize < 0)
{
int error = WSAGetLastError();
if (error != WSAEWOULDBLOCK)
return false;
return true;
}
else if (recvSize == 0)
{
return false;
}
File > UserInterface/PythonNetworkStream.cpp
Search for :
TDynamicSizePacketHeader DynamicSizePacketHeader;
Add this directly after it:
if (DynamicSizePacketHeader.size < sizeof(TDynamicSizePacketHeader))
{
TraceError("CPythonNetworkStream::CheckPacket - Invalid dynamic packet size: header %d packet size: %u",
DynamicSizePacketHeader.header,
static_cast<unsigned int>(DynamicSizePacketHeader.size));
ClearRecvBuffer();
PostQuitMessage(0);
return false;
}
File > UserInterface/Packet.h
Search for :
SPacketGCHybridCryptKeys
SPacketGCHybridSDB
Use these instead:
SPacketGCHybridCryptKeys() : m_pStream(NULL) {}
explicit SPacketGCHybridCryptKeys(int iStreamSize) : iKeyStreamLen(iStreamSize), m_pStream(NULL)
{
if (iStreamSize > 0)
m_pStream = new BYTE[iStreamSize];
}
SPacketGCHybridSDB() : m_pStream(NULL) {}
explicit SPacketGCHybridSDB(int iStreamSize) : iSDBStreamLen(iStreamSize), m_pStream(NULL)
{
if (iStreamSize > 0)
m_pStream = new BYTE[iStreamSize];
}
File > UserInterface/PythonNetworkStreamPhaseHandShake.cpp
Search for :
bool CPythonNetworkStream::RecvHybridCryptKeyPacket()
Replace the complete function with:
bool CPythonNetworkStream::RecvHybridCryptKeyPacket()
{
const int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize();
TDynamicSizePacketHeader header;
if (!Peek(sizeof(header), &header))
return false;
if (header.size < iFixedHeaderSize)
{
TraceError("RecvHybridCryptKeyPacket: invalid packet size %u", static_cast<unsigned int>(header.size));
return false;
}
const int iPayloadSize = static_cast<int>(header.size) - iFixedHeaderSize;
TPacketGCHybridCryptKeys kPacket(iPayloadSize);
if (!Recv(iFixedHeaderSize, &kPacket))
return false;
if (kPacket.iKeyStreamLen != iPayloadSize)
{
TraceError("RecvHybridCryptKeyPacket: stream length %d does not match payload %d", kPacket.iKeyStreamLen, iPayloadSize);
return false;
}
if (!Recv(iPayloadSize, kPacket.m_pStream))
return false;
CEterPackManager::Instance().RetrieveHybridCryptPackKeys(kPacket.m_pStream);
return true;
}
Search for :
bool CPythonNetworkStream::RecvHybridCryptSDBPacket()
Replace the complete function with:
bool CPythonNetworkStream::RecvHybridCryptSDBPacket()
{
const int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize();
TDynamicSizePacketHeader header;
if (!Peek(sizeof(header), &header))
return false;
if (header.size < iFixedHeaderSize)
{
TraceError("RecvHybridCryptSDBPacket: invalid packet size %u", static_cast<unsigned int>(header.size));
return false;
}
const int iPayloadSize = static_cast<int>(header.size) - iFixedHeaderSize;
TPacketGCHybridSDB kPacket(iPayloadSize);
if (!Recv(iFixedHeaderSize, &kPacket))
return false;
if (kPacket.iSDBStreamLen != iPayloadSize)
{
TraceError("RecvHybridCryptSDBPacket: stream length %d does not match payload %d", kPacket.iSDBStreamLen, iPayloadSize);
return false;
}
if (!Recv(iPayloadSize, kPacket.m_pStream))
return false;
CEterPackManager::Instance().RetrieveHybridCryptPackSDB(kPacket.m_pStream);
return true;
}
File > UserInterface/AccountConnector.cpp
Search for :
bool CAccountConnector::__AuthState_RecvHybridCryptKeys(int iTotalSize)
Replace the complete function with:
bool CAccountConnector::__AuthState_RecvHybridCryptKeys(int iTotalSize)
{
const int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize();
if (iTotalSize < iFixedHeaderSize)
return false;
const int iPayloadSize = iTotalSize - iFixedHeaderSize;
TPacketGCHybridCryptKeys kPacket(iPayloadSize);
if (!Recv(iFixedHeaderSize, &kPacket))
return false;
if (kPacket.iKeyStreamLen != iPayloadSize)
return false;
if (!Recv(iPayloadSize, kPacket.m_pStream))
return false;
CEterPackManager::Instance().RetrieveHybridCryptPackKeys(kPacket.m_pStream);
return true;
}
Search for :
bool CAccountConnector::__AuthState_RecvHybridCryptSDB(int iTotalSize)
Replace the complete function with:
bool CAccountConnector::__AuthState_RecvHybridCryptSDB(int iTotalSize)
{
const int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize();
if (iTotalSize < iFixedHeaderSize)
return false;
const int iPayloadSize = iTotalSize - iFixedHeaderSize;
TPacketGCHybridSDB kPacket(iPayloadSize);
if (!Recv(iFixedHeaderSize, &kPacket))
return false;
if (kPacket.iSDBStreamLen != iPayloadSize)
return false;
if (!Recv(iPayloadSize, kPacket.m_pStream))
return false;
CEterPackManager::Instance().RetrieveHybridCryptPackSDB(kPacket.m_pStream);
return true;
}
Search inside CAccountConnector::__AnalyzeVarSizePacket :
TDynamicSizePacketHeader dynamicHeader;
if (!Peek(sizeof(dynamicHeader), &dynamicHeader))
return true;
Add this directly below it:
if (dynamicHeader.size < sizeof(dynamicHeader))
return false;
File > UserInterface/GuildMarkDownloader.cpp
Search for :
__LoginState_RecvMarkBlock
Add this after the initial fixed-header Peek:
if (kPacket.bufSize < sizeof(kPacket) || kPacket.bufSize > INT_MAX)
{
TraceError("RecvMarkBlock: invalid packet size %u", kPacket.bufSize);
return false;
}
if (!Peek(static_cast<int>(kPacket.bufSize)))
return false;
Add this before the block loop:
DWORD remainingSize = kPacket.bufSize - static_cast<DWORD>(sizeof(kPacket));
Validate each compressed block with:
const DWORD blockHeaderSize = sizeof(BYTE) + sizeof(DWORD);
if (remainingSize < blockHeaderSize ||
!Recv(sizeof(BYTE), &posBlock) || !Recv(sizeof(DWORD), &compSize))
return false;
remainingSize -= blockHeaderSize;
if (compSize > remainingSize || compSize > SGuildMarkBlock::MAX_COMP_SIZE)
return false;
if (!Recv(static_cast<int>(compSize), compBuf))
return false;
remainingSize -= compSize;
Add this after the loop:
if (remainingSize != 0)
return false;
Search for :
__LoginState_RecvSymbolData
Add this before subtracting the fixed header:
if (packet.size < sizeof(TPacketGCGuildSymbolData))
{
TraceError("RecvSymbolData: invalid packet size %u", static_cast<unsigned int>(packet.size));
return false
}