// Function for outputting the buffer to the console
void print(const char* buffer, unsigned int length, bool sending)
{
if (sending)
{
cout << "[Client > Server] ";
}
else
{
cout << "[Server > Client] ";
}
for (unsigned int i = 0; i < length; i++)
{
printf("%02X ", buffer[i]);
}
cout << endl;
}
/*
VarInt read function
https://wiki.vg/index.php?title=Protocol#VarInt_and_VarLong
*/
int readVarInt(char* buffer, unsigned int& offset)
{
int numRead = 0;
int result = 0;
do
{
int value = (buffer[offset] & 0b01111111);
result |= (value << (7 * numRead));
}
while ((buffer[offset++] & 0b10000000) != 0);
return result;
}
// Intercepted WSARecv function
int WSAAPI __WSARecv(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
// Calling the original WSARecv function to fill the buffer
int result = _WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
for (unsigned int i = 0; i < dwBufferCount; i++)
{
unsigned int offset = 0;
unsigned int length = readVarInt(lpBuffers[i].buf, offset);
print(lpBuffers[i].buf, lpBuffers[i].len, false);
print(lpBuffers[i].buf, length, false);
cout << "Length: " << length << endl << endl;
}
return result;
}
// Intercepted WSASend function
int WSAAPI __WSASend(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
for (unsigned int i = 0; i < dwBufferCount; i++)
{
unsigned int offset = 0;
unsigned int length = readVarInt(lpBuffers[i].buf, offset);
print(lpBuffers[i].buf, lpBuffers[i].len, true);
print(lpBuffers[i].buf, length, true);
cout << "Length: " << length << endl << endl;
}
// Calling the original WSASend function
return _WSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
}
Output https://pastebin.com/2VqYP7ZU (Sorry, there are many symbols)
As you can see, in the first two requests the length obtained by reading VarInt truncated only 1 byte (only one byte was not displayed) But in the third request (Encryption Request) a very large part was cut off. Why is that? Where is my mistake?
What does FFFFFF mean which is sometimes displayed?
Encryption and compression are not enabled yet, as this is the moment of authorization.