Hello,
I'd like to share some code i wrote which hooks the "Encrypt" function that encrypts packet data before it is sent off. Via this hook you can monitor/modify all unencrypted packet data being sent from client->server. This is not exactly a hack of its own but i believe this will shed some light on the packet protocol of PoE. Maybe even help some people to possibly create something amazing in the future via packet manipulation.
Code:
0139DDC0 | 8B 86 C8 00 00 00 | mov eax,dword ptr ds:[esi+C8] |
0139DDC6 | 8B 11 | mov edx,dword ptr ds:[ecx] |
0139DDC8 | 03 C3 | add eax,ebx |
0139DDCA | 57 | push edi |
0139DDCB | 50 | push eax |
0139DDCC | FF 52 04 | call dword ptr ds:[edx+4] |
0139DDCF | 8B 86 B4 00 00 00 | mov eax,dword ptr ds:[esi+B4] |
0139DDD5 | 33 FF | xor edi,edi |
0139DDD7 | 89 86 B8 00 00 00 | mov dword ptr ds:[esi+B8],eax |
0139DDDD | 85 C0 | test eax,eax |
0139DDDF | 74 43 | je pathofexile.139DE24 |
0139DDE1 | 8B 1D CC 15 94 01 | mov ebx,dword ptr ds:[<&send>] |
0139DDE7 | 66 0F 1F 84 00 00 00 00 | nop word ptr ds:[eax+eax] |
0139DDF0 | 8B 8E C8 00 00 00 | mov ecx,dword ptr ds:[esi+C8] |
0139DDF6 | 8B 86 B4 00 00 00 | mov eax,dword ptr ds:[esi+B4] |
0139DDFC | 6A 00 | push 0 |
0139DDFE | 2B C7 | sub eax,edi |
0139DE00 | 50 | push eax |
0139DE01 | 8D 04 39 | lea eax,dword ptr ds:[ecx+edi] |
0139DE04 | 50 | push eax |
0139DE05 | FF 36 | push dword ptr ds:[esi] |
0139DE07 | FF D3 | call ebx |
call dword ptr ds:[edx+4] <---- this is the encrypt function, it takes two parameters pData and size
after breakpointing on that line I could see that edx points to hBase + 0xA3B2D4 which is in the PoE.rdata section so rather then doing a .TEXT modification hook i decided to be sneaky about it and did a vtable hook.
Here is the final code
Code:
#include <Windows.h>
#include <stdio.h>
typedef DWORD(__thiscall * pEncryptT)(DWORD ecx, BYTE* pData, DWORD dwSize);
pEncryptT pEncrypt = (pEncryptT)NULL;
DWORD __fastcall EncryptHook(DWORD ecx, DWORD edx, BYTE* pData, DWORD dwSize)
{
BYTE CmdID = *(BYTE*)(pData+1);
//if (CmdID != 0xC)
//{
for (int i = 0; i < dwSize; i++)
{
printf("%.2x ", pData[i]);
if ( (i+1) % 15 == 0)
printf("\n");
}
printf("\n\n");
//}
return pEncrypt(ecx, pData, dwSize);
}
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReason)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
AllocConsole();
freopen("CONOUT$", "w", stdout);
/*freopen("CONIN$", "r", stdin);*/
DWORD dwOld;
DWORD hBase = (DWORD)GetModuleHandle(NULL);
DWORD dwEncryptAddr = (DWORD)(hBase + 0xA3B2D4);
VirtualProtect((LPVOID)(dwEncryptAddr+4), 4, PAGE_EXECUTE_READWRITE, &dwOld);
pEncrypt = (pEncryptT)*(DWORD*)(dwEncryptAddr+4);
*(DWORD*)(dwEncryptAddr+4) = (DWORD)EncryptHook;
VirtualProtect((LPVOID)(dwEncryptAddr+4), 4, dwOld, NULL);
}
return TRUE;
}
Heres a screenshot of what it looks like

Btw if you want to just straight drop a packet you will have to be witty with it because the game will disconnect you if you just send some random data.
Like u could modify the return address of your EncryptHook in [esp+4] or wherever its stored to jump straight to here after its called-->
Code:
0139DE81 | 5F | pop edi |
0139DE82 | 8B C6 | mov eax,esi |
0139DE84 | 5E | pop esi |
0139DE85 | 5B | pop ebx |
0139DE86 | 8B 4D F4 | mov ecx,dword ptr ss:[ebp-C] |
0139DE89 | 64 89 0D 00 00 00 00 | mov dword ptr fs:[0],ecx |
0139DE90 | 8D 65 38 | lea esp,dword ptr ss:[ebp+38] |
0139DE93 | 5D | pop ebp |
0139DE94 | C2 04 00 | retn 4 |
this would prevent the game from calling WS2_32.send after the encrypt function.