From ed91d14f61c9456a8bd0be6258ba7de2cbe508c7 Mon Sep 17 00:00:00 2001 From: Anonymous275 Date: Wed, 17 Jun 2020 22:44:46 +0300 Subject: [PATCH] Security tweaks --- CMakeLists.txt | 3 +- src/CoreNetwork.cpp | 11 +- src/GameStart.cpp | 4 +- src/Memory/Memory.cpp | 237 ++++++++++++++++++++++++++++++++++++++++++ src/Memory/Memory.hpp | 33 ++++++ src/Memory/Reader.cpp | 43 ++++++++ src/Resources.cpp | 8 +- src/Security.cpp | 14 ++- src/main.cpp | 5 +- 9 files changed, 339 insertions(+), 19 deletions(-) create mode 100644 src/Memory/Memory.cpp create mode 100644 src/Memory/Memory.hpp create mode 100644 src/Memory/Reader.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a9aef51..582bba4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,8 @@ set(CMAKE_CXX_STANDARD 17) file(GLOB source_files "src/*.cpp" "src/include/*.h" "src/include/*.hpp" "src/curl/*.h" - "src/Network 2.0/*.cpp" "src/Network 2.0/*.h") + "src/Network 2.0/*.cpp" "src/Network 2.0/*.h" + "src/Memory/*.hpp" "src/Memory/*.cpp") add_executable(BeamMP-Launcher ${source_files}) diff --git a/src/CoreNetwork.cpp b/src/CoreNetwork.cpp index fecd9ae..1b85452 100644 --- a/src/CoreNetwork.cpp +++ b/src/CoreNetwork.cpp @@ -54,8 +54,8 @@ std::string Parse(const std::string& Data){ return ""; } } - - +bool once = false; +[[noreturn]] void MemoryInit(); [[noreturn]] void CoreNetworkThread(){ std::cout << "Ready!" << std::endl; do{ @@ -123,10 +123,13 @@ std::string Parse(const std::string& Data){ WSACleanup(); } closesocket(ListenSocket); - + if(!once){ + std::thread Memory(MemoryInit); + Memory.detach(); + once = true; + } do { std::string Response; - iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); if (iResult > 0) { std::string data = recvbuf; diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 59c303f..b31b5fd 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -31,6 +31,8 @@ void RollBack(const std::string&Val,int T){ if(!Val.empty())Write(Val); else DeleteKey(); } + +void SetPID(DWORD PID); void StartGame(const std::string&ExeDir,const std::string&Current){ BOOL bSuccess = FALSE; PROCESS_INFORMATION pi; @@ -41,7 +43,7 @@ void StartGame(const std::string&ExeDir,const std::string&Current){ if (bSuccess) { std::cout << "Game Launched!\n"; - DWORD dwPid = pi.dwProcessId; //Gets the PID + SetPID(pi.dwProcessId); std::thread RB(RollBack,Write(Current),7); RB.detach(); WaitForSingleObject(pi.hProcess, INFINITE); diff --git a/src/Memory/Memory.cpp b/src/Memory/Memory.cpp new file mode 100644 index 0000000..7194369 --- /dev/null +++ b/src/Memory/Memory.cpp @@ -0,0 +1,237 @@ +/// +/// Created by Anonymous275 on 5/5/2020 +/// + +#include "Memory.hpp" +#include +#include + + +int Memory::GetProcessId(const std::string& processName) { + SetLastError(0); + PROCESSENTRY32 pe32; + HANDLE hSnapshot = nullptr; + GetLastError(); + pe32.dwSize = sizeof(PROCESSENTRY32); + hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if(Process32First(hSnapshot,&pe32)) { + do { + if(processName == pe32.szExeFile) + break; + } while(Process32Next(hSnapshot, &pe32)); + } + + if(hSnapshot != INVALID_HANDLE_VALUE) + CloseHandle(hSnapshot); + int err = GetLastError(); + + if (err != 0) + return 0; + return pe32.th32ProcessID; +} + +long long Memory::GetModuleBase(HANDLE processHandle, const std::string &sModuleName) +{ + HMODULE *hModules = nullptr; + char szBuf[50]; + DWORD cModules; + long long dwBase = -1; + + EnumProcessModulesEx(processHandle, hModules, 0, &cModules,LIST_MODULES_ALL); + hModules = new HMODULE[cModules/sizeof(HMODULE)]; + + if(EnumProcessModulesEx(processHandle, hModules, cModules/sizeof(HMODULE), &cModules,LIST_MODULES_ALL)) { + for(size_t i = 0; i < cModules/sizeof(HMODULE); i++) { + if(GetModuleBaseName(processHandle, hModules[i], szBuf, sizeof(szBuf))) { + if(sModuleName == szBuf) { + dwBase = (long long)hModules[i]; + break; + } + } + } + } + + delete[] hModules; + return dwBase; +} + +void PrintAllBases(HANDLE processHandle){ + HMODULE *hModules = nullptr; + char szBuf[50]; + DWORD cModules; + EnumProcessModulesEx(processHandle, hModules, 0, &cModules,LIST_MODULES_ALL); + hModules = new HMODULE[cModules/sizeof(HMODULE)]; + if(EnumProcessModulesEx(processHandle, hModules, cModules/sizeof(HMODULE), &cModules,LIST_MODULES_ALL)) { + for(size_t i = 0; i < cModules/sizeof(HMODULE); i++) { + if(GetModuleBaseName(processHandle, hModules[i], szBuf, sizeof(szBuf))) { + if(hModules[i] != nullptr){ + std::cout << szBuf << " : " << hModules[i] << std::endl; + } + } + } + } + delete[] hModules; +} + +BOOL Memory::SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) +{ + TOKEN_PRIVILEGES tp; + LUID luid; + + if (!LookupPrivilegeValue(nullptr, lpszPrivilege, &luid)) { + //printf("LookupPrivilegeValue error: %u\n", GetLastError() ); + return FALSE; + } + + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + if (bEnablePrivilege) + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + else + tp.Privileges[0].Attributes = 0; + + if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) nullptr, (PDWORD) nullptr)) { + //printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); + return FALSE; + } + + if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { + //printf("The token does not have the specified privilege. \n"); + return FALSE; + } + + return TRUE; +} +BOOL Memory::GetDebugPrivileges() { + HANDLE hToken = nullptr; + if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) + return FALSE; //std::cout << "OpenProcessToken() failed, error\n>> " << GetLastError() << std::endl; + //else std::cout << "OpenProcessToken() is OK, got the handle!" << std::endl; + + if(!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)) + return FALSE; //std::cout << "Failed to enable privilege, error:\n>> " << GetLastError() << std::endl; + + return TRUE; +} +int Memory::ReadInt(HANDLE processHandle, long long address) { + if (address == -1) + return -1; + int buffer = 0; + SIZE_T NumberOfBytesToRead = sizeof(buffer); //this is equal to 4 + SIZE_T NumberOfBytesActuallyRead; + BOOL success = ReadProcessMemory(processHandle, (LPCVOID)address, &buffer, NumberOfBytesToRead, &NumberOfBytesActuallyRead); + if (!success || NumberOfBytesActuallyRead != NumberOfBytesToRead) { + //std::cout << "Memory Error!" << std::endl; + return -1; + } + return buffer; +} +long long Memory::ReadLong(HANDLE processHandle, long long address) { + if (address == -1) + return -1; + long long buffer = 0; + SIZE_T NumberOfBytesToRead = sizeof(buffer); + SIZE_T NumberOfBytesActuallyRead; + BOOL success = ReadProcessMemory(processHandle, (LPCVOID)address, &buffer, NumberOfBytesToRead, &NumberOfBytesActuallyRead); + if (!success || NumberOfBytesActuallyRead != NumberOfBytesToRead) { + //std::cout << "Memory Error!" << std::endl; + return -1; + } + return buffer; +} +int Memory::GetPointerAddress(HANDLE processHandle, long long startAddress, int offsets[], int offsetCount) { + if (startAddress == -1) + return -1; + int ptr = ReadInt(processHandle, startAddress); + for (int i=0; i offsets) { + if (startAddress == -1) + return -1; + long long ptr = ReadLong(processHandle, startAddress); + for (int i=0; i< offsets.size()-1; i++) { + ptr+=offsets[i]; + ptr = ReadLong(processHandle, ptr); + } + ptr+=offsets[offsets.size()-1]; + return ptr; +} +int Memory::ReadPointerInt(HANDLE processHandle, long long startAddress, std::vector offsets) { + if (startAddress == -1) + return -1; + return ReadInt(processHandle, GetPointerAddressLong(processHandle, startAddress, std::move(offsets))); +} +long long Memory::ReadPointerLong(HANDLE processHandle, long long startAddress, std::vector offsets) { + if (startAddress == -1) + return -1; + return ReadLong(processHandle, GetPointerAddressLong(processHandle, startAddress, std::move(offsets))); +} + +float Memory::ReadFloat(HANDLE processHandle, long long address) { + if (address == -1) + return -1; + float buffer = 0.0; + SIZE_T NumberOfBytesToRead = sizeof(buffer); //this is equal to 4 + SIZE_T NumberOfBytesActuallyRead; + BOOL success = ReadProcessMemory(processHandle, (LPCVOID)address, &buffer, NumberOfBytesToRead, &NumberOfBytesActuallyRead); + if (!success || NumberOfBytesActuallyRead != NumberOfBytesToRead) + return -1; + return buffer; +} +void Memory::WriteFloat(HANDLE processHandle, long long address,float Value) { + if (address == -1) + return; + SIZE_T NumberOfBytesToWrite = sizeof(Value); //this is equal to 4 + SIZE_T NumberOfBytesWritten; + BOOL Write = WriteProcessMemory(processHandle, LPVOID(address), &Value, NumberOfBytesToWrite, &NumberOfBytesWritten); +} +double Memory::ReadDouble(HANDLE processHandle, long long address) { + if (address == -1) + return -1; + double buffer = 0.0; + SIZE_T NumberOfBytesToRead = sizeof(buffer); //this is equal to 8 + SIZE_T NumberOfBytesActuallyRead; + BOOL success = ReadProcessMemory(processHandle, (LPCVOID)address, &buffer, NumberOfBytesToRead, &NumberOfBytesActuallyRead); + if (!success || NumberOfBytesActuallyRead != NumberOfBytesToRead) + return -1; + return buffer; +} +float Memory::ReadPointerFloat(HANDLE processHandle, long long startAddress, std::vector offsets) { + if (startAddress == -1) + return -1; + return ReadFloat(processHandle, GetPointerAddressLong(processHandle, startAddress, std::move(offsets))); +} +double Memory::ReadPointerDouble(HANDLE processHandle, long long startAddress, int offsets[], int offsetCount) { + if (startAddress == -1) + return -1; + return ReadDouble(processHandle, GetPointerAddress(processHandle, startAddress, offsets, offsetCount)); +} +std::string Memory::ReadText(HANDLE processHandle, long long address) { + if (address == -1) + return "-1"; + char buffer = !0; + char* stringToRead = new char[128]; + SIZE_T NumberOfBytesToRead = sizeof(buffer); + SIZE_T NumberOfBytesActuallyRead; + int i = 0; + while (buffer != 0) { + BOOL success = ReadProcessMemory(processHandle, (LPCVOID)address, &buffer, NumberOfBytesToRead, &NumberOfBytesActuallyRead); + if (!success || NumberOfBytesActuallyRead != NumberOfBytesToRead) + return "-1"; + stringToRead[i] = buffer; + i++; + address++; + } + return stringToRead; +} +std::string Memory::ReadPointerText(HANDLE processHandle, long long startAddress, std::vector offsets) { + if (startAddress == -1) + return "-1"; + return ReadText(processHandle, GetPointerAddressLong(processHandle, startAddress, std::move(offsets))); +} \ No newline at end of file diff --git a/src/Memory/Memory.hpp b/src/Memory/Memory.hpp new file mode 100644 index 0000000..d942a4c --- /dev/null +++ b/src/Memory/Memory.hpp @@ -0,0 +1,33 @@ +/// +/// Created by Anonymous275 on 5/5/2020 +/// + +#pragma once +#include +#include +#include +#include +#include + +class Memory +{ +public: + DWORD PID = 0; + int GetProcessId(const std::string& processName); + long long ReadLong(HANDLE processHandle, long long address); + long long ReadPointerLong(HANDLE processHandle, long long startAddress, std::vector offsets); + long long GetPointerAddressLong(HANDLE processHandle, long long startAddress, std::vector offsets); + long long GetModuleBase(HANDLE processHandle, const std::string&sModuleName); + BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege); + BOOL GetDebugPrivileges(); + int ReadInt(HANDLE processHandle, long long address); + int GetPointerAddress(HANDLE processHandle, long long startAddress, int offsets[], int offsetCount); + int ReadPointerInt(HANDLE processHandle, long long startAddress, std::vector offsets); + float ReadFloat(HANDLE processHandle, long long address); + void WriteFloat(HANDLE processHandle, long long address,float Value); + double ReadDouble(HANDLE processHandle, long long address); + float ReadPointerFloat(HANDLE processHandle, long long startAddress, std::vector offsets); + double ReadPointerDouble(HANDLE processHandle, long long startAddress, int offsets[], int offsetCount); + std::string ReadText(HANDLE processHandle, long long address); + std::string ReadPointerText(HANDLE processHandle, long long startAddress, std::vector offsets); +}; \ No newline at end of file diff --git a/src/Memory/Reader.cpp b/src/Memory/Reader.cpp new file mode 100644 index 0000000..7f81951 --- /dev/null +++ b/src/Memory/Reader.cpp @@ -0,0 +1,43 @@ +/// +/// Created by Anonymous275 on 6/17/2020 +/// +#include "Memory.hpp" +#include +#include +extern bool MPDEV; +Memory Game; +std::string GameVer(HANDLE processHandle, long long Address){ + //lib_Beam + Address += 0x1B0688; + std::vector Off = {0x0,0xBF0}; + return Game.ReadPointerText(processHandle,Address,Off); +} +std::string LoadedMap(HANDLE processHandle, long long Address){ + //lib_Beam + Address += 0x1B0688; + std::vector Off = {0x2F8,0x0}; + return Game.ReadPointerText(processHandle,Address,Off); +} +void SetPID(DWORD PID){ + Game.PID = PID; +} +[[noreturn]] void MemoryInit(){ + if(Game.PID == 0 && !MPDEV)exit(4); + HANDLE processHandle; + long long ExeBase; //BeamNG.drive.x64.exe + long long Lib1 = 0x180000000; //libbeamng.x64.dll Contains Vehicle Data + Game.GetDebugPrivileges(); + processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, Game.PID); + ExeBase = Game.GetModuleBase(processHandle, "BeamNG.drive.x64.exe"); + + std::string Map,Temp; + while(true){ + Map = LoadedMap(processHandle,Lib1); + if(!Map.empty() && Map != "-1" && Map.find("/info.json") != std::string::npos && Map != Temp){ + std::cout << "You just loaded: " << Map << std::endl; + Temp = Map; + } + Map.clear(); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } +} \ No newline at end of file diff --git a/src/Resources.cpp b/src/Resources.cpp index 453824b..0fbdeae 100644 --- a/src/Resources.cpp +++ b/src/Resources.cpp @@ -12,7 +12,7 @@ extern std::vector GlobalInfo; void Exit(const std::string& Msg); -namespace fs = std::filesystem; +namespace fs = std::experimental::filesystem; extern std::string UlStatus; extern bool Terminate; extern bool MPDEV; @@ -124,6 +124,10 @@ void SyncResources(SOCKET Sock){ } while (LFS.tellp() != std::stoi(*FS)); LFS.close(); } - STCPSend(Sock,"Done"); + if(!FNames.empty()){ + STCPSend(Sock,"Done"); + } + FNames.clear(); + FSizes.clear(); std::cout << "Done!" << std::endl; } \ No newline at end of file diff --git a/src/Security.cpp b/src/Security.cpp index 8d7b8f8..1412f16 100644 --- a/src/Security.cpp +++ b/src/Security.cpp @@ -124,7 +124,7 @@ std::string QueryKey(HKEY hKey,int ID) delete [] buffer; return ""; } -namespace fs = std::filesystem; +namespace fs = std::experimental::filesystem; void FileList(std::vector&a,const std::string& Path){ for (const auto &entry : fs::directory_iterator(Path)) { int pos = entry.path().filename().string().find('.'); @@ -135,18 +135,17 @@ void FileList(std::vector&a,const std::string& Path){ } bool Continue = false; void Find(const std::string& FName,const std::string& Path){ - auto *FS = new std::vector; - FileList(*FS,Path); - for(const std::string&a : *FS){ + std::vector FS; + FileList(FS,Path); + for(const std::string&a : FS){ if(a.find(FName)!=std::string::npos)Continue = true; } - delete FS; + FS.clear(); } void ExitError(){ std::string MSG2 = HTA("4572726f722120506c6561736520436f6e7461637420537570706f7274"); Exit(MSG2 + " Code 2"); } - void Check(){ /*.HKEY_CURRENT_USER\Software\Valve\Steam HKEY_CURRENT_USER\\Software\Valve\Steam\Apps\284160 @@ -161,7 +160,6 @@ void Check(){ std::string MSG3 = HTA("596f7520646f206e6f74206f776e207468652067616d65206f6e2074686973206d616368696e6521"); //You do not own the game on this machine! //std::string MSG = HTA("5761726e696e672120796f75206f776e207468652067616d6520627574206120637261636b65642067616d652077617320666f756e64206f6e20796f7572206d616368696e6521"); //not used : Warning! you own the game but a cracked game was found on your machine! - HKEY hKey; LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey); if(dwRegOPenKey == ERROR_SUCCESS) { @@ -170,7 +168,7 @@ void Check(){ SData.push_back(Result); Result += HTA("2f7573657264617461"); struct stat buffer{}; - if(stat (Result.c_str(), &buffer) == 0){ + if(stat(Result.c_str(), &buffer) == 0){ auto *F = new std::thread(Find,HTA("3238343136302e6a736f6e"),Result); F->join(); delete F; diff --git a/src/main.cpp b/src/main.cpp index 4fe54db..32842ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,7 +84,7 @@ int main(int argc, char* argv[]){ const unsigned long long NPos = std::string::npos; struct stat info{}; system("cls"); - std::string ver = "1.31", link, HTTP_Result; + std::string ver = "1.4", link, HTTP_Result; SetWindowTextA(GetConsoleWindow(),("BeamMP Launcher v" + ver).c_str()); std::thread t1(Discord_Main); t1.detach(); @@ -103,7 +103,7 @@ int main(int argc, char* argv[]){ exit(-1); } } - }else MPDEV = true; + }else MPDEV = false; std::string Path = CheckDir(argv[0]); std::thread CFU(CheckForUpdates,ver); CFU.join(); @@ -121,7 +121,6 @@ int main(int argc, char* argv[]){ Sec->join(); delete Sec; if(SData.size() != 3)ExitError(); - std::string GamePath = SData.at(2); if(MPDEV)std::cout << "You own BeamNG on this machine!" << std::endl; std::cout << "Game Version : " << CheckVer(GamePath) << std::endl;