diff options
author | GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> | 2022-03-28 23:48:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-28 23:48:05 +0200 |
commit | b8a7feabea6456f7fa5e8403c8d9bd2630401045 (patch) | |
tree | d6fa62ef39eb4fcfac1c1711f49ad86b2b6c59d3 /NorthstarDedicatedTest/NSMem.h | |
parent | 379cbc8bc251307777a14b901e5617e834398485 (diff) | |
download | NorthstarLauncher-b8a7feabea6456f7fa5e8403c8d9bd2630401045.tar.gz NorthstarLauncher-b8a7feabea6456f7fa5e8403c8d9bd2630401045.zip |
More exploit fixes by KIttenPopo (#126)
* Quick fix for a bug I caused
* Typo
* Update kitten-fixes branch to my repo (#122)
* Added string hash macro
* Added convenient vtfunc macro
* Made lil ConCommand creation macro
* Fixed multiple NET_SetConVar exploits
* Quick fixerino
* Fix convar struct (and other things)
* Revive clang-format (but good, i think)
* Update .clang-format
* Reformatted code to meet .clang-format requirements
* Minor formatting fixes
* Fixed Northstar "crashing" when console is closed
* Update .clang-format
* Quick fix for a bug I caused
* Typo
* NSMem Update
* ExplotFixes: Only block excessive convar counts if server
* Update ExploitFixes.cpp
* Update ExploitFixes.cpp
* Updated bytepatch format
* reformatted all code for clang-format
* Updated my clang-format to v13.0.0
* 3 fixes in 1
- ANTITAMPER fixed
- NSMem simplification update
- Fixed bad byte string in serverauthentication.cpp
* Improved ExploitFixes logging and NET_SetConVar patch
* clang-format unironically sabotaged my code
* Made ns_exploitfixes_log on by default
* Fixed IsMemoryReadable (oops)
Co-authored-by: KittenPopo <Pokeberry123@gmail.com>
Diffstat (limited to 'NorthstarDedicatedTest/NSMem.h')
-rw-r--r-- | NorthstarDedicatedTest/NSMem.h | 200 |
1 files changed, 114 insertions, 86 deletions
diff --git a/NorthstarDedicatedTest/NSMem.h b/NorthstarDedicatedTest/NSMem.h index a5bbd42f..50928dd2 100644 --- a/NorthstarDedicatedTest/NSMem.h +++ b/NorthstarDedicatedTest/NSMem.h @@ -6,119 +6,147 @@ #pragma region Pattern Scanning namespace NSMem { - inline void* PatternScan(void* module, const int* pattern, int patternSize, int offset) +inline std::vector<int> HexBytesToString(const char* str) +{ + std::vector<int> patternNums; + int size = strlen(str); + for (int i = 0; i < size; i++) { - if (!module) - return NULL; - - auto dosHeader = (PIMAGE_DOS_HEADER)module; - auto ntHeaders = (PIMAGE_NT_HEADERS)((BYTE*)module + dosHeader->e_lfanew); - - auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage; + char c = str[i]; - auto scanBytes = (BYTE*)module; + // If this is a space character, ignore it + if (c == ' ' || c == '\t') + continue; - for (auto i = 0; i < sizeOfImage - patternSize; ++i) + if (c == '?') { - bool found = true; - for (auto j = 0; j < patternSize; ++j) + // Add a wildcard (-1) + patternNums.push_back(-1); + } + else if (i < size - 1) + { + BYTE result = 0; + for (int j = 0; j < 2; j++) { - if (scanBytes[i + j] != pattern[j] && pattern[j] != -1) + int val = 0; + char c = *(str + i + j); + if (c >= 'a') { - found = false; - break; + val = c - 'a' + 0xA; + } + else if (c >= 'A') + { + val = c - 'A' + 0xA; + } + else if (isdigit(c)) + { + val = c - '0'; + } + else + { + assert(false, "Failed to parse invalid hex string."); + val = -1; } - } - if (found) - { - uintptr_t addressInt = (uintptr_t)(&scanBytes[i]) + offset; - return (uint8_t*)addressInt; + result += (j == 0) ? val * 16 : val; } + patternNums.push_back(result); } - return nullptr; + i++; } - inline void* PatternScan(const char* moduleName, const char* pattern, int offset = 0) - { - std::vector<int> patternNums; + return patternNums; +} - bool lastChar = 0; - int size = strlen(pattern); - for (int i = 0; i < size; i++) - { - char c = pattern[i]; +inline void* PatternScan(void* module, const int* pattern, int patternSize, int offset) +{ + if (!module) + return NULL; - // If this is a space character, ignore it - if (c == ' ' || c == '\t') - continue; + auto dosHeader = (PIMAGE_DOS_HEADER)module; + auto ntHeaders = (PIMAGE_NT_HEADERS)((BYTE*)module + dosHeader->e_lfanew); - if (c == '?') - { - // Add a wildcard (-1) - patternNums.push_back(-1); - } - else if (i < size - 1) + auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage; + + auto scanBytes = (BYTE*)module; + + for (auto i = 0; i < sizeOfImage - patternSize; ++i) + { + bool found = true; + for (auto j = 0; j < patternSize; ++j) + { + if (scanBytes[i + j] != pattern[j] && pattern[j] != -1) { - BYTE result = 0; - for (int j = 0; j < 2; j++) - { - int val = 0; - char c = (pattern + i + j)[0]; - if (c >= 'a') - { - val = c - 'a' + 0xA; - } - else if (c >= 'A') - { - val = c - 'A' + 0xA; - } - else - { - val = c - '0'; - } - - result += (j == 0) ? val * 16 : val; - } - patternNums.push_back(result); + found = false; + break; } + } - i++; + if (found) + { + uintptr_t addressInt = (uintptr_t)(&scanBytes[i]) + offset; + return (uint8_t*)addressInt; } - return PatternScan(GetModuleHandleA(moduleName), &patternNums[0], patternNums.size(), offset); } - inline void BytePatch(uintptr_t address, const BYTE* vals, int size) - { - WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, vals, size, NULL); - } + return nullptr; +} - inline void BytePatch(uintptr_t address, std::initializer_list<BYTE> vals) - { - std::vector<BYTE> bytes = vals; - if (!bytes.empty()) - BytePatch(address, &bytes[0], bytes.size()); - } +inline void* PatternScan(const char* moduleName, const char* pattern, int offset = 0) +{ + std::vector<int> patternNums = HexBytesToString(pattern); - inline void NOP(uintptr_t address, int size) - { - BYTE* buf = (BYTE*)malloc(size); - memset(buf, 0x90, size); - BytePatch(address, buf, size); - free(buf); - } + return PatternScan(GetModuleHandleA(moduleName), &patternNums[0], patternNums.size(), offset); +} - inline bool IsMemoryReadable(void* ptr, size_t size) - { - BYTE* buffer = (BYTE*)malloc(size); +inline void BytePatch(uintptr_t address, const BYTE* vals, int size) +{ + WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, vals, size, NULL); +} - size_t numWritten = 0; - ReadProcessMemory(GetCurrentProcess(), ptr, buffer, size, &numWritten); - free(buffer); +inline void BytePatch(uintptr_t address, std::initializer_list<BYTE> vals) +{ + std::vector<BYTE> bytes = vals; + if (!bytes.empty()) + BytePatch(address, &bytes[0], bytes.size()); +} - return numWritten == size; - } +inline void BytePatch(uintptr_t address, const char* bytesStr) +{ + std::vector<int> byteInts = HexBytesToString(bytesStr); + std::vector<BYTE> bytes; + for (int v : byteInts) + bytes.push_back(v); + + if (!bytes.empty()) + BytePatch(address, &bytes[0], bytes.size()); +} + +inline void NOP(uintptr_t address, int size) +{ + BYTE* buf = (BYTE*)malloc(size); + memset(buf, 0x90, size); + BytePatch(address, buf, size); + free(buf); +} + +inline bool IsMemoryReadable(void* ptr, size_t size) +{ + static SYSTEM_INFO sysInfo; + if (!sysInfo.dwPageSize) + GetSystemInfo(&sysInfo); // This should always be 4096 unless ur playing on NES or some shit but whatever + + MEMORY_BASIC_INFORMATION memInfo; + + if (!VirtualQuery(ptr, &memInfo, sizeof(memInfo))) + return false; + + if (memInfo.RegionSize < size) + return false; + + return (memInfo.State & MEM_COMMIT) && !(memInfo.Protect & PAGE_NOACCESS); +} } // namespace NSMem #pragma region KHOOK |