Skip to content

Instantly share code, notes, and snippets.

@requeijaum
Last active September 8, 2018 04:36
Show Gist options
  • Save requeijaum/17fb076ce4cb1d6c0370ae7dc608271d to your computer and use it in GitHub Desktop.
Save requeijaum/17fb076ce4cb1d6c0370ae7dc608271d to your computer and use it in GitHub Desktop.
Análise do algoritmo de encriptação e decriptação de um pacote de rede (Winsock) para o MMORPG With Your Destiny (2003).
//WYD2BOT, by Shepher (Kevin Kouketsu)
//https://github.com/kevinkouketsu/WYD2Bot/blob/master/WYD2Bot/Socket.cpp
//Análise do algoritmo de encriptação e decriptação de um pacote de rede (Winsock)
BOOL Server::AddMessage(char *pMsg, int Size)
{
char temp[256];
PacketHeader *pSMsg = (PacketHeader *)pMsg; //???
if(nSendPosition + Size >= SEND_BUFFER_SIZE)
return FALSE;
if(KeyTable[0]){ // 004251CA
INT32 hashIncrement = GetHashIncrement();
if(hashIncrement > 15){ // checagem desnecessária: 0042524C }
}
// check socket valid
unsigned char iKeyWord = rand()%256;
unsigned char KeyWord = KeyTable[iKeyWord * 2];
unsigned char CheckSum = 0;
//???
pSMsg->Size = Size;
pSMsg->Key = iKeyWord;
pSMsg->CheckSum = CheckSum;
pSMsg->TimeStamp = GetCurrenttime();
TimePacket = GetCurrentTime(); //???
unsigned char Sum1 = 0;
unsigned char Sum2 = 0;
int pos = KeyWord; //???
for (int i = 4; i < Size; i++, pos++){
Sum1 += pMsg[i]; //não seria pSMsg???
int rst = pos % 256; //reset ou resto?
//aritmetica relacionada a KeyTable:
unsigned char Trans = KeyTable[(rst & 255) * 2 + 1];
int mod = i & 0x3;
if (mod == 0)
pSendBuffer[nSendPosition + i] = pMsg[i] + (Trans << 1);
if (mod == 1)
pSendBuffer[nSendPosition + i] = pMsg[i] - (Trans >> 3);
if (mod == 2)
pSendBuffer[nSendPosition + i] = pMsg[i] + (Trans << 2);
if (mod == 3)
pSendBuffer[nSendPosition + i] = pMsg[i] - (Trans >> 5);
Sum2 += pSendBuffer[nSendPosition + i]; //???
//muita doideira
}
//assim que gera checksum? haha
CheckSum = Sum2 - Sum1;
pSMsg->CheckSum = CheckSum; //manda pro packet que está sendo construído...
memcpy(pSendBuffer + nSendPosition, pMsg, 4); //???
nSendPosition = nSendPosition + Size;
return SendMessageA(); //formatacao??? fazer referencia a essa função depois...
}
/*
SendMessageA(){
(...)
}
*/
char* Server::ReadMessage(int *ErrorCode, int* ErrorType)
{
*ErrorCode = 0;
//algo pra capturar posição do Recv e recolher dados - que nem ~seek file~ do GNU DD?
//e condicionais (1) e (2) pra Recv válido
//(1)
if(nProcPosition >= nRecvPosition)
{
nRecvPosition = 0;
nProcPosition = 0;
return NULL;
}
//(2)
if((nRecvPosition - nProcPosition) < 12)
return NULL;
//reconstrução do pacote agora:
//captura size e checksum a partir do buffer do Recv recebido
unsigned short Size = *((unsigned short*)(pRecvBuffer + nProcPosition));
unsigned short CheckSum = *((unsigned char*)(pRecvBuffer + nProcPosition + 2));
//uma condicional que acusa erro caso o tamanho do pacote seja invalido
//se comparado ao tamanho declarado OU (sei lá esse sizeof())
if(Size > MAX_MESSAGE_SIZE || Size < sizeof(PacketHeader))
{
nRecvPosition = 0;
nProcPosition = 0;
*ErrorCode = 2;
*ErrorType = Size;
return NULL;
}
//rest = restante? resto?
//serve pra contar os bytes do que vem depois... e saber se vai quebrar o tamanho declarado
unsigned short Rest = nRecvPosition - nProcPosition;
if(Size > Rest)
return NULL;
//captura pMsg de acordo com parte do buffer Recv recebido, em determinada posição
char*pMsg = (char*)&(pRecvBuffer[nProcPosition]);
nProcPosition = nProcPosition + Size; //soma com tamanho... pra saber o tamanho do pacote completo?
//condicional pra saber se o pacote esta ainda dentro dos limites de tamanho
//serve pra resetar aqueles ~seeks~ e começar do inicio...
if(nRecvPosition <= nProcPosition)
{
nRecvPosition = 0;
nProcPosition = 0;
}
//começa a mágica do Keytable ... olha as variaveis iguais as da primeira função!
unsigned int i;
int pos, Key;
int sum1 = 0, sum2 = 0;
pos = KeyTable[CheckSum * 2];
//mesmo algoritmo... ordem inversa de operacoes
for(i = 4; i < Size; i++, pos++) //começar do quarto (ou quinto?) byte
//iterar i e pos a cada execução desse loop
{
//sei lá:
sum1 += pMsg[i];
Key = KeyTable[((pos & 0xFF) * 2) + 1]; //meh...
//se i for igual a 3 ?
//é uma operação AND bytewise ou mask?
switch(i & 3)
{
case 0:
Key <<= 1;
Key &= 255;
pMsg[i] -= Key;
break;
case 1:
Key >>= 3;
Key &= 255;
pMsg[i] += Key;
break;
case 2:
Key <<= 2;
Key &= 255;
pMsg[i] -= Key;
break;
case 3: default:
Key >>= 5;
Key &= 255;
pMsg[i] += Key;
break;
} //porra, tem mask com shifting...
sum2 += pMsg[i];
}
//mais truques...
sum2 &= 255;
sum1 &= 255;
//precisa ser igual???
//pra descobrir o tamanho?
if(sum2 != sum1)
{
*ErrorCode = 1;
*ErrorType = Size; //é... tamanho mesmo
}
return pMsg; //hmm...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment