From 180a61a147aaaaa92a7b27d12e11a87793322309 Mon Sep 17 00:00:00 2001 From: Ray Koopa Date: Sun, 12 Jul 2020 17:40:11 +0200 Subject: [PATCH] Extend fkNetcode with settings and better error handling. --- src/tool/FrontendKitWS/FrontendKitWS.vcxproj | 2 +- src/tool/FrontendKitWS/fk.h | 3 +- src/tool/fkNetcode/PEInfo.h | 1 - src/tool/fkNetcode/fkConfig.cpp | 38 +++++ src/tool/fkNetcode/fkConfig.h | 20 +++ src/tool/fkNetcode/fkNetcode.vcxproj | 15 +- src/tool/fkNetcode/fkPatch.cpp | 28 ++++ src/tool/fkNetcode/fkPatch.h | 24 ++++ src/tool/fkNetcode/fkPatch.inl | 10 ++ src/tool/fkNetcode/fkUtils.cpp | 89 ++++++++++++ src/tool/fkNetcode/fkUtils.h | 32 +++++ src/tool/fkNetcode/fkWinHandle.cpp | 20 +++ src/tool/fkNetcode/fkWinHandle.h | 19 +++ src/tool/fkNetcode/main.cpp | 140 +++++++++++-------- src/tool/fkNetcode/misc_tools.cpp | 92 ------------ src/tool/fkNetcode/misc_tools.h | 27 ---- 16 files changed, 378 insertions(+), 182 deletions(-) create mode 100644 src/tool/fkNetcode/fkConfig.cpp create mode 100644 src/tool/fkNetcode/fkConfig.h create mode 100644 src/tool/fkNetcode/fkPatch.cpp create mode 100644 src/tool/fkNetcode/fkPatch.h create mode 100644 src/tool/fkNetcode/fkPatch.inl create mode 100644 src/tool/fkNetcode/fkUtils.cpp create mode 100644 src/tool/fkNetcode/fkUtils.h create mode 100644 src/tool/fkNetcode/fkWinHandle.cpp create mode 100644 src/tool/fkNetcode/fkWinHandle.h delete mode 100644 src/tool/fkNetcode/misc_tools.cpp delete mode 100644 src/tool/fkNetcode/misc_tools.h diff --git a/src/tool/FrontendKitWS/FrontendKitWS.vcxproj b/src/tool/FrontendKitWS/FrontendKitWS.vcxproj index 08ed644..ebb4ffd 100644 --- a/src/tool/FrontendKitWS/FrontendKitWS.vcxproj +++ b/src/tool/FrontendKitWS/FrontendKitWS.vcxproj @@ -100,4 +100,4 @@ - + \ No newline at end of file diff --git a/src/tool/FrontendKitWS/fk.h b/src/tool/FrontendKitWS/fk.h index 55df0c1..35f7344 100644 --- a/src/tool/FrontendKitWS/fk.h +++ b/src/tool/FrontendKitWS/fk.h @@ -1,4 +1,3 @@ -#define WIN32_LEAN_AND_MEAN #include #include @@ -28,7 +27,7 @@ void fkAttach() } else { - sprintf_s(buffer, "Could not load module %s.", findFileData.cFileName); + sprintf_s(buffer, "Could not load module %s.", findFileData.cFileName); MessageBox(NULL, buffer, "FrontendKit", MB_ICONWARNING); } } while (FindNextFile(hFindFile, &findFileData)); diff --git a/src/tool/fkNetcode/PEInfo.h b/src/tool/fkNetcode/PEInfo.h index 5b9733b..c6dc61c 100644 --- a/src/tool/fkNetcode/PEInfo.h +++ b/src/tool/fkNetcode/PEInfo.h @@ -1,5 +1,4 @@ #pragma once -#define WIN32_LEAN_AND_MEAN #include typedef struct PEInfo diff --git a/src/tool/fkNetcode/fkConfig.cpp b/src/tool/fkNetcode/fkConfig.cpp new file mode 100644 index 0000000..0b5024e --- /dev/null +++ b/src/tool/fkNetcode/fkConfig.cpp @@ -0,0 +1,38 @@ +#include "fkConfig.h" +#include + +namespace fk +{ + Config::Config(LPCSTR fileName) + { + DWORD length = GetModuleFileName(NULL, _filePath, MAX_PATH); + strcpy_s(strrchr(_filePath, '\\') + 1, MAX_PATH, fileName); + } + + void Config::get(LPCSTR category, LPCSTR key, BOOL& result, UINT fallback) const + { + result = GetPrivateProfileInt(category, key, fallback, _filePath); + } + + void Config::get(LPCSTR category, LPCSTR key, UINT& result, UINT fallback) const + { + result = GetPrivateProfileInt(category, key, fallback, _filePath); + } + + void Config::get(LPCSTR category, LPCSTR key, LPSTR result, INT resultLength, LPCSTR fallback) const + { + GetPrivateProfileString(category, key, fallback, result, resultLength, _filePath); + } + + void Config::set(LPCSTR category, LPCSTR key, UINT value) const + { + CHAR buffer[32]; + sprintf_s(buffer, "%d", value); + WritePrivateProfileString(category, key, buffer, _filePath); + } + + void Config::set(LPCSTR category, LPCSTR key, LPCSTR value) const + { + WritePrivateProfileString(category, key, value, _filePath); + } +} \ No newline at end of file diff --git a/src/tool/fkNetcode/fkConfig.h b/src/tool/fkNetcode/fkConfig.h new file mode 100644 index 0000000..2113172 --- /dev/null +++ b/src/tool/fkNetcode/fkConfig.h @@ -0,0 +1,20 @@ +#pragma once +#include + +namespace fk +{ + class Config + { + public: + Config(LPCSTR fileName); + + void get(LPCSTR category, LPCSTR key, BOOL& result, UINT fallback) const; + void get(LPCSTR category, LPCSTR key, UINT& result, UINT fallback) const; + void get(LPCSTR category, LPCSTR key, LPSTR result, INT resultLength, LPCSTR fallback = NULL) const; + void set(LPCSTR category, LPCSTR key, UINT value) const; + void set(LPCSTR category, LPCSTR key, LPCSTR value) const; + + private: + CHAR _filePath[MAX_PATH]; + }; +} diff --git a/src/tool/fkNetcode/fkNetcode.vcxproj b/src/tool/fkNetcode/fkNetcode.vcxproj index 8e45033..27bf1b1 100644 --- a/src/tool/fkNetcode/fkNetcode.vcxproj +++ b/src/tool/fkNetcode/fkNetcode.vcxproj @@ -87,15 +87,24 @@ + + + + - - + + + + + + + - + \ No newline at end of file diff --git a/src/tool/fkNetcode/fkPatch.cpp b/src/tool/fkNetcode/fkPatch.cpp new file mode 100644 index 0000000..da00ad3 --- /dev/null +++ b/src/tool/fkNetcode/fkPatch.cpp @@ -0,0 +1,28 @@ +#include "fkPatch.h" +#include + +namespace fk +{ + Patch::Patch(LPVOID lpAddress, SIZE_T dwSize) + : _lpAddress(static_cast(lpAddress)) + , _dwSize(dwSize) + , dwPosition(0) + { + if (!_lpAddress || !_dwSize) + throw std::invalid_argument("Address and size must not be 0."); + if (!VirtualProtect(_lpAddress, _dwSize, PAGE_EXECUTE_READWRITE, &_flOldProtect)) + throw std::exception("VirtualProtect failed, call GetLastError for more info."); + } + + Patch::~Patch() + { + close(); + } + + void Patch::close() const + { + DWORD oldProtect; + if (!VirtualProtect(_lpAddress, _dwSize, _flOldProtect, &oldProtect)) + throw std::exception("VirtualProtect failed, call GetLastError for more info."); + } +}; diff --git a/src/tool/fkNetcode/fkPatch.h b/src/tool/fkNetcode/fkPatch.h new file mode 100644 index 0000000..2464f5c --- /dev/null +++ b/src/tool/fkNetcode/fkPatch.h @@ -0,0 +1,24 @@ +#pragma once +#include + +namespace fk +{ + struct Patch + { + public: + DWORD dwPosition; + + Patch(LPVOID lpAddress, SIZE_T dwSize); + ~Patch(); + + void close() const; + template void write(const T& value); + + private: + LPBYTE _lpAddress; + SIZE_T _dwSize; + DWORD _flOldProtect; + }; +} + +#include "fkPatch.inl" diff --git a/src/tool/fkNetcode/fkPatch.inl b/src/tool/fkNetcode/fkPatch.inl new file mode 100644 index 0000000..edbee9a --- /dev/null +++ b/src/tool/fkNetcode/fkPatch.inl @@ -0,0 +1,10 @@ +namespace fk +{ + template + void Patch::write(const T& value) + { + memcpy_s(_lpAddress + dwPosition, sizeof(T), &value, sizeof(T)); + dwPosition += sizeof(T); + } + +} diff --git a/src/tool/fkNetcode/fkUtils.cpp b/src/tool/fkNetcode/fkUtils.cpp new file mode 100644 index 0000000..bc935b1 --- /dev/null +++ b/src/tool/fkNetcode/fkUtils.cpp @@ -0,0 +1,89 @@ +#include "fkUtils.h" +#include "fkPatch.h" + +namespace fk +{ + int getGameVersion(DWORD timeDateStamp) + { + switch (timeDateStamp) + { + case 0x3528DAFA: return GAME_VERSION_BR; + case 0x3528DCB1: return GAME_VERSION_EN; + case 0x3528DB52: return GAME_VERSION_GE; + case 0x3528DA98: return GAME_VERSION_NA; + case 0x3528DBDA: return GAME_VERSION_SA; + case 0x3587BE19: return GAME_VERSION_TRY; + } + return GAME_VERSION_NONE; + } + + void throwLastError() + { + DWORD error = GetLastError(); + if (error == ERROR_SUCCESS) + return; + + LPTSTR buffer = NULL; + const DWORD cchMsg = FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, + error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buffer), 0, NULL); + if (cchMsg > 0) + { + std::string message(buffer); + LocalFree(buffer); + throw std::exception(message.c_str()); + } + else + { + CHAR buffer[32]; + sprintf_s(buffer, "Error code 0x%08X.", error); + throw std::exception(buffer); + } + } + + void patchNops(ULONG dwAddr, SIZE_T dwPatchSize) + { + fk::Patch patch(reinterpret_cast(dwAddr), dwPatchSize); + while (dwPatchSize--) + patch.write(0x90); + } + + void patchJump(PVOID pDest, SIZE_T dwPatchSize, PVOID pCallee, DWORD dwJumpType) + { + fk::Patch patch(pDest, dwPatchSize); + + if (dwPatchSize >= 5 && pDest) + { + BYTE OpSize, OpCode; + switch (dwJumpType) + { + case IJ_PUSHRET: OpSize = 6; OpCode = 0x68; break; + case IJ_FARJUMP: OpSize = 7; OpCode = 0xEA; break; + case IJ_FARCALL: OpSize = 7; OpCode = 0x9A; break; + case IJ_CALL: OpSize = 5; OpCode = 0xE8; break; + default: OpSize = 5; OpCode = 0xE9; break; + } + + if (dwPatchSize < OpSize) + throw std::exception("Not enough space to patch opcode."); + + patch.write(OpCode); + switch (OpSize) + { + case 7: + patch.write((ULONG)pCallee); + patch.write(0x23); + break; + case 6: + patch.write((ULONG)pCallee); + patch.write(0xC3); + break; + default: + patch.write((ULONG)pCallee - (ULONG)pDest - 5); + break; + } + for (DWORD i = OpSize; i < dwPatchSize; i++) + patch.write(0x90); + } + } +} \ No newline at end of file diff --git a/src/tool/fkNetcode/fkUtils.h b/src/tool/fkNetcode/fkUtils.h new file mode 100644 index 0000000..be1abe5 --- /dev/null +++ b/src/tool/fkNetcode/fkUtils.h @@ -0,0 +1,32 @@ +#pragma once +#include +#include + +namespace fk +{ + enum GameVersion + { + GAME_VERSION_NONE = -1, + GAME_VERSION_BR, // 1.05 Br + GAME_VERSION_EN, // 1.05 Du, En, Fr, It, Po, Sp, Sw + GAME_VERSION_GE, // 1.05 + GAME_VERSION_NA, // 1.05 + GAME_VERSION_SA, // 1.05 + GAME_VERSION_TRY // 1.07 Trymedia + }; + + enum InsertJump + { + IJ_JUMP, // Insert a jump (0xE9) with patchJump + IJ_CALL, // Insert a call (0xE8) with patchJump + IJ_FARJUMP, // Insert a farjump (0xEA) with patchJump + IJ_FARCALL, // Insert a farcall (0x9A) with patchJump + IJ_PUSHRET, // Insert a pushret with patchJump + }; + + int getGameVersion(DWORD timeDateStamp); + void throwLastError(); + + void patchNops(ULONG dwAddr, SIZE_T dwPatchSize); + void patchJump(PVOID pDest, SIZE_T dwPatchSize, PVOID pCallee, DWORD dwJumpType = IJ_JUMP); +} diff --git a/src/tool/fkNetcode/fkWinHandle.cpp b/src/tool/fkNetcode/fkWinHandle.cpp new file mode 100644 index 0000000..247c175 --- /dev/null +++ b/src/tool/fkNetcode/fkWinHandle.cpp @@ -0,0 +1,20 @@ +#include "fkWinHandle.h" +#include "fkUtils.h" +#include + +namespace fk +{ + WinHandle::WinHandle(HANDLE handle, BOOL(__stdcall* closeProc)(HANDLE)) + : _handle(handle) + , _closeProc(closeProc) + { + if (!_handle || _handle == INVALID_HANDLE_VALUE) + fk::throwLastError(); + } + + WinHandle::~WinHandle() + { + if (_handle) + _closeProc(_handle); + } +} \ No newline at end of file diff --git a/src/tool/fkNetcode/fkWinHandle.h b/src/tool/fkNetcode/fkWinHandle.h new file mode 100644 index 0000000..4258661 --- /dev/null +++ b/src/tool/fkNetcode/fkWinHandle.h @@ -0,0 +1,19 @@ +#pragma once +#include + +namespace fk +{ + struct WinHandle + { + public: + WinHandle(HANDLE handle, BOOL(__stdcall* closeProc)(HANDLE)); + ~WinHandle(); + + operator bool() { return _handle; } + operator HANDLE() { return _handle; } + + private: + HANDLE _handle; + BOOL(__stdcall* _closeProc)(HANDLE); + }; +} diff --git a/src/tool/fkNetcode/main.cpp b/src/tool/fkNetcode/main.cpp index 4762bac..7a5e4a7 100644 --- a/src/tool/fkNetcode/main.cpp +++ b/src/tool/fkNetcode/main.cpp @@ -1,77 +1,101 @@ #define WIN32_LEAN_AND_MEAN -#include -#include #include #include +#include "fkConfig.h" +#include "fkUtils.h" +#include "fkWinHandle.h" #include "PEInfo.h" -#include "misc_tools.h" +CHAR cfgFallbackIP[16]; +CHAR cfgServiceUrl[MAX_PATH]; +BOOL cfgShowErrors; PEInfo pe; -CHAR szFoundIP[16] = {}; +CHAR resolvedIP[16] = {}; -enum GameRegion +void configure() { - GAME_REGION_NONE = -1, - GAME_REGION_BR, - GAME_REGION_EN, // Du, En, Fr, It, Po, Sp, Sw have the same executable - GAME_REGION_GE, - GAME_REGION_NA, - GAME_REGION_SA -}; + fk::Config config("fkNetcode.ini"); -int getRegion() -{ - switch (pe.FH->TimeDateStamp) + // Load INI settings. + config.get("AddressResolval", "FallbackIP", cfgFallbackIP, 16); + config.get("AddressResolval", "ServiceUrl", cfgServiceUrl, MAX_PATH, "http://ip.syroot.com"); + config.get("AddressResolval", "ShowErrors", cfgShowErrors, TRUE); + + // Ensure INI file has been created with default setting. + config.set("AddressResolval", "FallbackIP", cfgFallbackIP); + config.set("AddressResolval", "ServiceUrl", cfgServiceUrl); + config.set("AddressResolval", "ShowErrors", cfgShowErrors); + + // Validate fallback IP. + BYTE b; + if (*cfgFallbackIP && sscanf_s(cfgFallbackIP, "%hhu.%hhu.%hhu.%hhu", &b, &b, &b, &b) != 4) { - case 0x3528DAFA: return GAME_REGION_BR; - case 0x3528DCB1: return GAME_REGION_EN; - case 0x3528DB52: return GAME_REGION_GE; - case 0x3528DA98: return GAME_REGION_NA; - case 0x3528DBDA: return GAME_REGION_SA; + *cfgFallbackIP = NULL; + MessageBox(NULL, "Invalid fallback IP setting in fkNetcode.ini has been ignored.", "fkNetcode", MB_ICONWARNING); } - return GAME_REGION_NONE; } -bool __stdcall getLabelIP(LPSTR buffer, int bufferLength) +void resolveIP(LPTSTR buffer) { - if (!szFoundIP[0]) + if (!*resolvedIP) { // Initially resolve the external IP through a web service. - HINTERNET hInternet = 0, hFile = 0; - DWORD bytesRead = 0; - CHAR buffer[16]; + fk::WinHandle hInternet(InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0), InternetCloseHandle); + fk::WinHandle hFile(InternetOpenUrl(hInternet, cfgServiceUrl, NULL, 0, + INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD, NULL), InternetCloseHandle); - if ((hInternet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0)) - && (hFile = InternetOpenUrl(hInternet, "http://ip.syroot.com", NULL, 0, - INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD, NULL)) - && InternetReadFile(hFile, buffer, 16, &bytesRead) && bytesRead >= 8) - { - buffer[bytesRead] = '\0'; - uint8_t temp; - if (sscanf_s(buffer, "%hhu.%hhu.%hhu.%hhu", &temp, &temp, &temp, &temp) == 4) - lstrcpy(szFoundIP, buffer); - } + DWORD responseLength = 0; + CHAR response[16]; + if (!InternetReadFile(hFile, response, 16, &responseLength)) + fk::throwLastError(); + if (responseLength < 8) + throw std::exception("Response was too short."); - if (hFile) InternetCloseHandle(hFile); - if (hInternet) InternetCloseHandle(hInternet); + response[responseLength] = '\0'; + BYTE temp; + if (sscanf_s(response, "%hhu.%hhu.%hhu.%hhu", &temp, &temp, &temp, &temp) != 4) + throw std::exception("Response could not be parsed."); + + lstrcpy(resolvedIP, response); } - - // Return the detected IP. - lstrcpy(buffer, szFoundIP); - return buffer[0]; + lstrcpy(buffer, resolvedIP); } -void applyPatches() +bool __stdcall patchResolveIP(LPSTR buffer, int bufferLength) { - // Replace NAT IP detection with web service. - InsertJump((PVOID)pe.Offset(0x00001799), 5, &getLabelIP, IJ_JUMP); + try + { + resolveIP(buffer); + } + catch (std::exception& ex) + { + lstrcpy(buffer, *cfgFallbackIP ? cfgFallbackIP : "0.0.0.0"); + if (cfgShowErrors) + { + CHAR message[512]; + sprintf_s(message, "Could not resolve your IP address. %s", ex.what()); + MessageBox(NULL, message, "fkNetcode", MB_ICONWARNING); + } + } + return true; // not used +} - // Prevent overriding the resolved IP when connecting to server. - PatchMemNop(pe.Offset(0x00053E96), 5); // writes user name - PatchMemNop(pe.Offset(0x00054993), 5); // writes NAT IP +void patch(int gameVersion) +{ + fk::patchJump((PVOID)pe.Offset(0x00001799), 5, &patchResolveIP, fk::IJ_JUMP); // replace IP resolve with web service - // Remove useless sleeps. - PatchMemNop(pe.Offset(0x00054935), 11); + if (gameVersion == fk::GAME_VERSION_TRY) + { + fk::patchNops(pe.Offset(0x00053B96), 5); // prevent overriding IP with user name + fk::patchNops(pe.Offset(0x00054693), 5); // prevent overriding IP with NAT IP + fk::patchNops(pe.Offset(0x00054635), 11); // useless sleep when connecting to server + } + else + { + fk::patchNops(pe.Offset(0x00053E96), 5); // prevent overriding IP with user name + fk::patchNops(pe.Offset(0x00054935), 11); // useless sleep when connecting to server + fk::patchNops(pe.Offset(0x00054993), 5); // prevent overriding IP with NAT IP + } } BOOL WINAPI DllMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) @@ -79,17 +103,21 @@ BOOL WINAPI DllMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { case DLL_PROCESS_ATTACH: - if (getRegion() == GAME_REGION_NONE) + { + int version = fk::getGameVersion(pe.FH->TimeDateStamp); + if (version == fk::GAME_VERSION_NONE) { - MessageBox(NULL, "fkNetcode is incompatible with your game version or region and will not be able to " - "resolve your external IP address. Please install the Worms 2 1.05 patch or delete this module to " - "remove this warning.", "fkNetcode", MB_ICONWARNING); + MessageBox(NULL, "fkNetcode is incompatible with your game version. Please run the 1.05 patch or " + "1.07 release of Worms 2. Otherwise, you can delete the module to remove this warning.", + "fkNetcode", MB_ICONWARNING); } else { - applyPatches(); + configure(); + patch(version); } - break; + } + break; case DLL_PROCESS_DETACH: break; diff --git a/src/tool/fkNetcode/misc_tools.cpp b/src/tool/fkNetcode/misc_tools.cpp deleted file mode 100644 index 431545c..0000000 --- a/src/tool/fkNetcode/misc_tools.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include "misc_tools.h" - -BOOL WritePrivateProfileIntA(LPCSTR lpAppName, LPCSTR lpKeyName, int nInteger, LPCSTR lpFileName) -{ - CHAR lpString[32]; - sprintf_s(lpString, "%d", nInteger); - return WritePrivateProfileStringA(lpAppName, lpKeyName, lpString, lpFileName); -} - -LPSTR GetPathUnderModuleA(HMODULE hModule, LPSTR OutBuf, LPCSTR FileName) -{ - GetModuleFileNameA(hModule, OutBuf, MAX_PATH); - CHAR* dirend = strrchr(OutBuf, '\\') + 1; - strcpy_s(dirend, MAX_PATH, FileName); - return OutBuf; -} - -BOOL __stdcall PatchMemData(ULONG dwAddr, ULONG dwBufLen, PVOID pNewData, ULONG dwDataLen) -{ - if (!dwDataLen || !pNewData || !dwAddr) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - DWORD dwLastProtection; - if (!VirtualProtect((void*)dwAddr, dwDataLen, PAGE_EXECUTE_READWRITE, &dwLastProtection)) - return 0; - - memcpy_s((PVOID)dwAddr, dwBufLen, pNewData, dwDataLen); - - return VirtualProtect((void*)dwAddr, dwDataLen, dwLastProtection, &dwLastProtection); -} - -BOOL __stdcall PatchMemQword(ULONG dwAddr, QWORD qNewValue) { return PatchMemData(dwAddr, 8, &qNewValue, 8); } -BOOL __stdcall PatchMemDword(ULONG dwAddr, DWORD dwNewValue) { return PatchMemData(dwAddr, 4, &dwNewValue, 4); } -BOOL __stdcall PatchMemWord(ULONG dwAddr, WORD wNewValue) { return PatchMemData(dwAddr, 2, &wNewValue, 2); } -BOOL __stdcall PatchMemByte(ULONG dwAddr, BYTE bNewValue) { return PatchMemData(dwAddr, 1, &bNewValue, 1); } -BOOL __stdcall PatchMemFloat(ULONG dwAddr, FLOAT fNewValue) -{ - DWORD dwLastProtection; - if (!VirtualProtect((void*)dwAddr, sizeof(FLOAT), PAGE_EXECUTE_READWRITE, &dwLastProtection)) - return 0; - *(FLOAT*)dwAddr = fNewValue; - return VirtualProtect((void*)dwAddr, sizeof(FLOAT), dwLastProtection, &dwLastProtection); -} - -BOOL __stdcall PatchMemNop(ULONG dwAddr, DWORD dwPatchSize) -{ - while (dwPatchSize-- && PatchMemByte(dwAddr++, 0x90)); - return dwPatchSize == 0; -} -BOOL __stdcall InsertJump(PVOID pDest, DWORD dwPatchSize, PVOID pCallee, DWORD dwJumpType) -{ - if (dwPatchSize >= 5 && pDest) - { - DWORD OpSize, OpCode; - switch (dwJumpType) - { - case IJ_PUSHRET: OpSize = 6; OpCode = 0x68; break; - case IJ_FARJUMP: OpSize = 7; OpCode = 0xEA; break; - case IJ_FARCALL: OpSize = 7; OpCode = 0x9A; break; - case IJ_CALL: OpSize = 5; OpCode = 0xE8; break; - default: OpSize = 5; OpCode = 0xE9; break; - } - - if (dwPatchSize < OpSize) - return 0; - - PatchMemByte((ULONG)pDest, (BYTE)OpCode); - - switch (OpSize) - { - case 7: - PatchMemDword((ULONG)pDest + 1, (ULONG)pCallee); - PatchMemWord((ULONG)pDest + 5, 0x23); - break; - case 6: - PatchMemDword((ULONG)pDest + 1, (ULONG)pCallee); - PatchMemByte((ULONG)pDest + 5, 0xC3); - break; - default: - PatchMemDword((ULONG)pDest + 1, (ULONG)pCallee - (ULONG)pDest - 5); - break; - } - - for (ULONG i = OpSize; i < dwPatchSize; i++) - PatchMemByte((ULONG)pDest + i, 0x90); - } - return 0; -} diff --git a/src/tool/fkNetcode/misc_tools.h b/src/tool/fkNetcode/misc_tools.h deleted file mode 100644 index a84f3d8..0000000 --- a/src/tool/fkNetcode/misc_tools.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -typedef unsigned long long QWORD; -typedef QWORD *PQWORD, *LPQWORD; - -extern "C" IMAGE_DOS_HEADER __ImageBase; -#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) - -#define IJ_JUMP 0 //Insert a jump (0xE9) with InsertJump -#define IJ_CALL 1 //Insert a call (0xE8) with InsertJump -#define IJ_FARJUMP 2 //Insert a farjump (0xEA) with InsertJump -#define IJ_FARCALL 3 //Insert a farcall (0x9A) with InsertJump -#define IJ_PUSHRET 4 //Insert a pushret with InsertJump - -BOOL WritePrivateProfileIntA(LPCSTR lpAppName, LPCSTR lpKeyName, int nInteger, LPCSTR lpFileName); -LPSTR GetPathUnderModuleA(HMODULE hModule, LPSTR OutBuf, LPCSTR FileName); - -BOOL __stdcall PatchMemData(ULONG dwAddr, ULONG dwBufLen, PVOID pNewData, ULONG dwDataLen); -BOOL __stdcall PatchMemQword(ULONG dwAddr, QWORD qNewValue); -BOOL __stdcall PatchMemDword(ULONG dwAddr, DWORD dwNewValue); -BOOL __stdcall PatchMemWord(ULONG dwAddr, WORD wNewValue); -BOOL __stdcall PatchMemByte(ULONG dwAddr, BYTE bNewValue); -BOOL __stdcall PatchMemFloat(ULONG dwAddr, FLOAT fNewValue); - -BOOL __stdcall PatchMemNop(ULONG dwAddr, DWORD dwPatchSize); - -BOOL __stdcall InsertJump(PVOID pDest, DWORD dwPatchSize, PVOID pCallee, DWORD dwJumpType = IJ_JUMP);