Hooking send/recv + decrypt - GoliaX - Jul 16, 2018
Hello everybody,
I've hooked send and recv calls from a game.exe, here is my source:
Code // General
#include <stdio.h>
#include <WinSock2.h>
#include <Windows.h>
#include <sstream>
#include <string>
#include <iomanip>
#include <xhacking/xHacking.h>
#include <xhacking/Utilities/Utilities.h>
#include <xhacking/Loader/Loader.h>
#include <xhacking/Detour/Detour.h>
using namespace xHacking;
Detour<int, SOCKET, char*, int, int>* recvDetour = NULL;
Detour<int, SOCKET, const char*, int, int>* sendDetour = NULL;
int WINAPI nuestro_recv(SOCKET s, char *buf, int len, int flags)
{
// LLAMAR ORIGINAL
int ret = (*recvDetour)(s, buf, len, flags);
__asm PUSHAD;
__asm PUSHFD;
std::ostringstream info;
// Server message
info << "**----------[[SERVIDOR]] >>>> CLIENTE]----------**\n\n- HEX:\n\n";
info << std::hex << std::uppercase;
for (int i = 0; i < ret; i++)
{
info << std::setw(2) << std::setfill('0') << (int)buf[i];
}
info << std::dec << std::nouppercase;
printf("%s\n\n", info.str().c_str());
printf("- Chars:\n\n");
printf("%s\n", buf);
printf("----------------------------------------------------\n\n\n");
__asm POPFD;
__asm POPAD;
return ret;
}
int WINAPI nuestro_send(SOCKET s, const char *buf, int len, int flags)
{
// CALL ORIGINAL
int ret = (*sendDetour)(s, buf, len, flags);
__asm PUSHAD;
__asm PUSHFD;
// Client message
std::ostringstream info;
info << "**----------[[CLIENTE]] >>>> SERVIDOR]----------**\n\n- HEX:\n\n";
info << std::hex << std::uppercase;
// si no funciona, cambiar ret por len
for (int i = 0; i < len; i++)
{
info << std::setw(2) << std::setfill('0') << (int)buf[i];
}
info << std::dec << std::nouppercase;
printf("%s\n\n", info.str().c_str());
printf("- Chars:\n\n");
printf("%s\n", buf);
printf("----------------------------------------------------\n\n\n");
__asm POPFD;
__asm POPAD;
return ret;
}
void Hooks()
{
recvDetour = new Detour<int, SOCKET, char*, int, int>();
recvDetour->Wait((char*)"ws2_32.dll", (char*)"recv", (BYTE*)nuestro_recv);
sendDetour = new Detour<int, SOCKET, const char*, int, int>();
sendDetour->Wait((char*)"ws2_32.dll", (char*)"send", (BYTE*)nuestro_send);
}
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, DWORD reserved)
{
if (reason == DLL_PROCESS_ATTACH)
{
// We are in the game
CreateConsole();
Hooks();
}
return true;
}
As you may know, packets are encrypted, and I have its cryption and decryption method:
Code bool Decryption(char * pData, const USHORT usDataLen, const u_char key )
{
// Get key string
char * cValKey ;
UINT * uiValKey ;
cValKey = "83kck3ks92 82drd";
uiValKey = (UINT*)cValKey ;
try {
int x, i,j,k,l ;
UINT * puiData = (UINT *) pData ; // 'int *' Convert to type data
j = 0 ; // line step
k = usDataLen / 16 ; // line count
l = usDataLen % 16 ; // char count
// line data block Encrypto
for( i = 0, x = 0, j = 0 ; i < k ; i++, x += 4, j += 16 ) { // Transpose Key and pData.
puiData[x+0] = uiValKey[0] ^ puiData[x+0] ;
puiData[x+1] = ~(uiValKey[2] ^ puiData[x+1]) ;
puiData[x+2] = uiValKey[1] ^ puiData[x+2] ;
puiData[x+3] = ~(uiValKey[3] ^ puiData[x+3]) ;
}
// char data Encrypto
//j += KEYVALLENTH ;
for(int h = 0 ; h < l ; h++ ) {
pData[j+h] = ~(cValKey[h] ^ pData[j+h]) ;
}
}// try
catch (...) {
return false ;
}
return true ;
}
My question is, How can I implement this decryption method into my hook packets project to make it print in console packets decrypted?
It may not be that dificult but I really cannot sort it out, I hope someone can help.
Thank you in advance
RE: Hooking send/recv + decrypt - Auriana - Jul 16, 2018
In your recv hook, you would just call Decryption by passing your buffer and the length into it.
The Decryption function seems to have a redundant argument of u_char key, I suppose that can be ignored and the key is just "83kck3ks92 82drd"
Inside the recv hook after int ret = (*recvDetour)(s, buf, len, flags);
Check the return length to make sure the function succeeded then call Decryption(buf,len,0);
RE: Hooking send/recv + decrypt - GoliaX - Jul 16, 2018
(Jul 16, 2018 08:04 AM)Auriana Wrote: In your recv hook, you would just call Decryption by passing your buffer and the length into it.
The Decryption function seems to have a redundant argument of u_char key, I suppose that can be ignored and the key is just "83kck3ks92 82drd"
Inside the recv hook after int ret = (*recvDetour)(s, buf, len, flags);
Check the return length to make sure the function succeeded then call Decryption(buf,len,0);
You are right, the key should be this one "83kck3ks92 82drd", but the game's key encryption should go changing when client updates version and is located in a binary file .dat packet in a data folder's game. The code should have acces to it and open to read the key. So tell to the code: go to this file .dat open in binary and read the key. How would I be able to code it?
Thank you for the answer, today I won't have time to apply your answer but I will get my hands on it tomorrow and will let you know the feedback, I may need more help with the .dat file.
Thank you
PD the original code for getting the key string is this:
Code // Get key string
char * cValKey ;
UINT * uiValKey ;
cValKey = GetKey( key ) ;
uiValKey = (UINT*)cValKey ;
On the crypto.h header file has this defined:
Code #define KEYBOX_FILE "crypto.dat" // Key box File
#define KEYVALLENTH 16 // Maximum lenght of random generation key
#define KEY_RANGE 0xff // Number of keys ..
RE: Hooking send/recv + decrypt - Auriana - Jul 16, 2018
Why would a game store the decryption key inside the client's installed folder? Seems silly and insecure to me.
Regardless if you wanted to read the key from the crypto.dat file, you would do it inside your recv hook.
Code char Key[16] = {0};
FILE* crypto = fopen("crypto.dat","rb");
if(crypto)
{
fread(Key,sizeof(char),sizeof(Key),crypto);
fclose(crypto);
}
Then you should be able to call Decryption with that key.
|