Last active
September 8, 2018 04:36
-
-
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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