#ifndef _L2EX_ #include "L2Ex.h" #endif L2Ex::L2Ex() { dwProcessID = GetCurrentProcessId(); L2Server = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_READ | PROCESS_VM_WRITE, false, dwProcessID); if (!L2Server) { MessageBox(NULL, "Unable to open L2Server's Process! Please restart the server.", "Error", MB_OK); ExitProcess(1); } } L2Ex *L2Ex::Instance() { static L2Ex Ex; return &Ex; } void L2Ex::WriteServerMemory(DWORD *pAddress, LPCVOID pData, SIZE_T nSize) { DWORD dwOldProtect; char szErrorBuf[32]; if (!VirtualProtectEx(L2Server, (LPVOID)(pAddress), nSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { sprintf_s(szErrorBuf, 32, "VirtualProtectEx Failed! Error: %d", GetLastError()); MessageBox(NULL, szErrorBuf, "L2Ex[Interlude]", MB_OK); } if (!WriteProcessMemory(L2Server, (LPVOID)(pAddress), pData, nSize, NULL)) { sprintf_s(szErrorBuf, 32, "WriteProcessMemory Failed! Error: %d", GetLastError()); MessageBox(NULL, szErrorBuf, "L2Ex[Interlude]", MB_OK); return; } if (!VirtualProtectEx(L2Server, (LPVOID)(pAddress), nSize, dwOldProtect, &dwOldProtect)) { sprintf_s(szErrorBuf, 32, "VirtualProtectEx Failed! Error: %d", GetLastError()); MessageBox(NULL, szErrorBuf, "L2Ex[Interlude]", MB_OK); } } void L2Ex::WriteServerHook(BYTE *pAddress, DWORD *pFunction, BYTE bNops) { BYTE Call = 0xE9; BYTE Nop = 0x90; WriteServerMemory((DWORD *)(pAddress), &Call, 1); DWORD pFuncAddress = (DWORD)pFunction - (DWORD)(pAddress + 5); WriteServerMemory((DWORD *)(pAddress + 1), (LPVOID)&pFuncAddress, sizeof(pFuncAddress)); for (int i = 6; i < bNops + 6; i++) { WriteServerMemory((DWORD *)(pAddress + i), &Nop, 1); } } void L2Ex::SetProtocolRevision(const char *szRevision) { WriteServerMemory((DWORD *)0x9BA9B3, (LPVOID)szRevision, 3); } void L2Ex::IncreaseMaxNpcId() { DWORD dwMaxNpcId = 0x10C8DF; WriteServerMemory((DWORD *)0x95F5A4, (LPVOID)&dwMaxNpcId, sizeof(dwMaxNpcId)); } void L2Ex::IncreaseMaxItemId() { DWORD dwMaxItemId = 0x1869F; WriteServerMemory((DWORD *)0x95F574, (LPVOID)&dwMaxItemId, sizeof(dwMaxItemId)); } void L2Ex::FixVersionPacket() { BYTE Fix1[] = {0x90, 0x90, 0x90, 0x90, 0x90}; BYTE Fix2[] = {0xB8, 0x00, 0x00, 0x00, 0x00, 0x90}; WriteServerMemory((DWORD *)0x87872C, Fix1, 5); WriteServerMemory((DWORD *)0x8786F2, Fix2, 6); } void L2Ex::FixCharSelectInfo() { DWORD pFuncAddress = (DWORD)CharSelectInfoFix - (DWORD)(0x574C32 + 4); WriteServerMemory((DWORD *)(0x574C32), (LPVOID)&pFuncAddress, sizeof(pFuncAddress)); } void L2Ex::FixUserInfo() { BYTE Four = 0x04; WriteServerMemory((DWORD *)(0x85712A), (LPVOID)&Four, 1); DWORD pFuncAddress = (DWORD)UserInfoFix - (DWORD)(0x85768F + 4); WriteServerMemory((DWORD *)(0x85768F), (LPVOID)&pFuncAddress, sizeof(pFuncAddress)); } void L2Ex::HookEnterWorld() { WriteServerHook((BYTE *)0x84D222, (DWORD *)EWHandler, 0); } void L2Ex::FixAve() { WriteServerHook((BYTE *)0x8F0E36, (DWORD *)NewAve,2); } void L2Ex::FixCharInfo() { WriteServerHook((BYTE *)0x858A7B, (DWORD *)CharInfoFix, 2); } L2Ex::~L2Ex() { }