From 00b271f265450850336c8bcfdacc8671dbc8406a Mon Sep 17 00:00:00 2001 From: boris Date: Tue, 1 Jan 2019 20:53:10 +1300 Subject: yah --- csgo-loader/csgo-client/Client.cpp | 10 +-- csgo-loader/csgo-client/Client.hpp | 6 +- csgo-loader/csgo-client/Login/RemoteLogin.cpp | 13 ++-- csgo-loader/csgo-client/Login/RemoteLogin.hpp | 3 + csgo-loader/csgo-client/Networking/TCPClient.cpp | 2 +- .../csgo-client/RemoteCode/RemoteProcess.cpp | 10 +-- csgo-loader/csgo-client/Security/Encryption.cpp | 2 +- csgo-loader/csgo-client/Security/Encryption.hpp | 1 + .../csgo-client/Security/RuntimeSecurity.cpp | 72 +++++++++++++--------- .../csgo-client/Security/RuntimeSecurity.hpp | 6 +- .../csgo-client/Security/SyscallManager.cpp | 5 +- .../csgo-client/Security/SyscallManager.hpp | 5 +- 12 files changed, 82 insertions(+), 53 deletions(-) (limited to 'csgo-loader/csgo-client') diff --git a/csgo-loader/csgo-client/Client.cpp b/csgo-loader/csgo-client/Client.cpp index d752732..10e8012 100644 --- a/csgo-loader/csgo-client/Client.cpp +++ b/csgo-loader/csgo-client/Client.cpp @@ -32,7 +32,7 @@ int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow) { - /*WRAP_IF_DEBUG*/(Utils::OpenConsole()); + WRAP_IF_DEBUG(Utils::OpenConsole()); /////////////////////////////////////////////////////////////// @@ -43,7 +43,7 @@ int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow) { // Create a window, initialise DirectX context. if(!UserInterface->Start()) - ERROR_ASSERT("[000F:00001C00] Failed to initialize. Please contact an administrator."); + ERROR_ASSERT(STR("[000F:00001C00] Failed to initialize. Please contact an administrator.")); UserInterface->RunUiFrame(); }); WindowThread.detach(); @@ -52,12 +52,12 @@ int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow) // Initialize the syscall manager. if(!Syscalls->Start()) - ERROR_ASSERT("[000F:00001B00] Failed to initialize. Please contact an administrator."); + ERROR_ASSERT(STR("[000F:00001B00] Failed to initialize. Please contact an administrator.")); // Initialize the runtime protection system. WRAP_IF_RELEASE( if(!Protection->Start()) - ERROR_ASSERT("[000F:00001A00] Failed to initialize. Please contact an administrator."); + ERROR_ASSERT(STR("[000F:00001A00] Failed to initialize. Please contact an administrator.")); ); // Wait for connection. @@ -67,7 +67,7 @@ int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow) Networking::TCPClientPtr Client = std::make_unique(); if(!Client->Start(LOCAL_IP, SERVER_PORT)) - ERROR_ASSERT("[000F:0002A000] Server closed the connection unexpectedly."); + ERROR_ASSERT(STR("[000F:0002A000] Server closed the connection unexpectedly.")); // Allow the user to input their log-in data. UserInterface->m_Data.m_ExecutionState = UserExperience::EXECUTION_LOG_IN; diff --git a/csgo-loader/csgo-client/Client.hpp b/csgo-loader/csgo-client/Client.hpp index 016e3d3..0f89669 100644 --- a/csgo-loader/csgo-client/Client.hpp +++ b/csgo-loader/csgo-client/Client.hpp @@ -33,11 +33,11 @@ namespace Utils // Allow console to access output stream. FILE *file; - freopen_s(&file, "CONOUT$", "w", stdout); + freopen_s(&file, STR("CONOUT$"), STR("w"), stdout); // :^) - SetConsoleTitleA("moneyclient $"); + SetConsoleTitleA(STR("moneyclient $")); - printf("[DEBUG] Hello!\n"); + printf(STR("[DEBUG] Hello!\n")); } } \ No newline at end of file diff --git a/csgo-loader/csgo-client/Login/RemoteLogin.cpp b/csgo-loader/csgo-client/Login/RemoteLogin.cpp index 9362162..6e70f86 100644 --- a/csgo-loader/csgo-client/Login/RemoteLogin.cpp +++ b/csgo-loader/csgo-client/Login/RemoteLogin.cpp @@ -1,5 +1,4 @@ #include -#include // Change this whenever a major client update is made. // NOTE: You must change this on the server as well. @@ -9,6 +8,8 @@ namespace Login { void RemoteLoginTransaction::Start(const char *Username, const char *Password) { + VMProtectBeginUltra("LoginTransactionStart"); + // Initialise the header with the client header. m_Header.m_ClientHeader = CURRENT_CLIENT_HEADER; @@ -29,6 +30,8 @@ namespace Login m_Header.m_IntegrityBit4 = m_Header.m_IntegrityBit1 | m_Header.m_IntegrityBit2 | m_Header.m_IntegrityBit3; + + VMProtectEnd(); } // TODO: Hardware ID check. @@ -45,20 +48,20 @@ namespace Login case RemoteLoginResponse::ACCESS_AUTHORISED: return true; case RemoteLoginResponse::OUTDATED_CLIENT: - INFO_ASSERT("[000A:%08x] Your client is outdated.\nPlease download the latest client at 'moneybot.cc'.", m_Header.m_HardwareId ^ ServerResponse); + INFO_ASSERT(STR("[000A:%08x] Your client is outdated.\nPlease download the latest client at 'moneybot.cc'."), m_Header.m_HardwareId ^ ServerResponse); break; case RemoteLoginResponse::USER_BANNED: - INFO_ASSERT("[000D:%08x] Your account is banned.\nPlease contact 'admin@moneybot.cc' for additional information.", m_Header.m_HardwareId ^ ServerResponse); + INFO_ASSERT(STR("[000D:%08x] Your account is banned.\nPlease contact 'admin@moneybot.cc' for additional information."), m_Header.m_HardwareId ^ ServerResponse); break; case RemoteLoginResponse::INVALID_HARDWARE: UserInterface->m_Data.m_Error = UserExperience::ERROR_INVALID_HWID; break; case RemoteLoginResponse::INVALID_CREDENTIALS: - INFO_ASSERT("[000C:%08x] Your credentials are invalid. Please check your spelling and try again.", m_Header.m_HardwareId ^ ServerResponse); + INFO_ASSERT(STR("[000C:%08x] Your credentials are invalid. Please check your spelling and try again."), m_Header.m_HardwareId ^ ServerResponse); break; case RemoteLoginResponse::INTEGRITY_FAILURE: case RemoteLoginResponse::NO_SUBSCRIPTION: - INFO_ASSERT("[0005:%08x] No active subscription found.", m_Header.m_HardwareId ^ ServerResponse); + INFO_ASSERT(STR("[0005:%08x] No active subscription found."), m_Header.m_HardwareId ^ ServerResponse); break; } diff --git a/csgo-loader/csgo-client/Login/RemoteLogin.hpp b/csgo-loader/csgo-client/Login/RemoteLogin.hpp index 8e819fe..071bb13 100644 --- a/csgo-loader/csgo-client/Login/RemoteLogin.hpp +++ b/csgo-loader/csgo-client/Login/RemoteLogin.hpp @@ -4,6 +4,9 @@ #include #include +#include +#include + using ByteArray = std::vector; namespace Login diff --git a/csgo-loader/csgo-client/Networking/TCPClient.cpp b/csgo-loader/csgo-client/Networking/TCPClient.cpp index 9ac3c3e..0611d89 100644 --- a/csgo-loader/csgo-client/Networking/TCPClient.cpp +++ b/csgo-loader/csgo-client/Networking/TCPClient.cpp @@ -12,7 +12,7 @@ namespace Networking int32_t Result = send(m_Socket, (char *)Bytes.data(), (int)Bytes.size(), 0); if(Result == -1) - INFO_ASSERT("[000F:00002B00] Server closed the connection unexpectedly."); + INFO_ASSERT(STR("[000F:00002B00] Server closed the connection unexpectedly.")); } ByteArray TCPClient::ReceiveRawBytes() diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp b/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp index 571f3cb..abed829 100644 --- a/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp +++ b/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp @@ -30,7 +30,7 @@ namespace RemoteCode m_Process = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessEntry.th32ProcessID); if(!m_Process) - ERROR_ASSERT("[000G:%08x] There was an error with accessing a process.", GetLastError()); + ERROR_ASSERT(STR("[000G:%08x] There was an error with accessing a process."), GetLastError()); return true; } @@ -47,7 +47,7 @@ namespace RemoteCode NTSTATUS Status = ZwReadVirtualMemory(m_Process, Address, Data, SizeOfData, nullptr); if(NT_ERROR(Status)) - ERROR_ASSERT("[00DF:%08x] There was an error with accessing a process.", Status); + ERROR_ASSERT(STR("[00DF:%08x] There was an error with accessing a process."), Status); } void RemoteProcess::WriteMemoryWrapper_Internal(void *Address, void *Data, size_t SizeOfData) @@ -57,7 +57,7 @@ namespace RemoteCode NTSTATUS Status = ZwWriteVirtualMemory(m_Process, Address, Data, SizeOfData, nullptr); if(NT_ERROR(Status)) - ERROR_ASSERT("[00DF:%08x] There was an error with accessing a process.", Status); + ERROR_ASSERT(STR("[00DF:%08x] There was an error with accessing a process."), Status); } void *RemoteProcess::Allocate(size_t AllocationSize) @@ -76,7 +76,7 @@ namespace RemoteCode ); if(NT_ERROR(Status)) - ERROR_ASSERT("[00DF:%08x] There was an error with accessing a process.", Status); + ERROR_ASSERT(STR("[00DF:%08x] There was an error with accessing a process."), Status); return AllocationAddress; } @@ -98,7 +98,7 @@ namespace RemoteCode if(strstr(ModuleEntry.szModule, ModuleName)) { if(!ModuleEntry.hModule) - ERROR_ASSERT("[00DF:00001C00] An integrity check failed."); + ERROR_ASSERT(STR("[00DF:00001C00] An integrity check failed.")); CloseHandle(Toolhelp); return RemoteModule(ModuleEntry.hModule); diff --git a/csgo-loader/csgo-client/Security/Encryption.cpp b/csgo-loader/csgo-client/Security/Encryption.cpp index d361d1c..6cf2f7f 100644 --- a/csgo-loader/csgo-client/Security/Encryption.cpp +++ b/csgo-loader/csgo-client/Security/Encryption.cpp @@ -569,7 +569,7 @@ namespace Wrapper if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, 0)) { if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, CRYPT_NEWKEYSET)) - INFO_ASSERT("Critical failure\nContact an admin with the following code: %08x", GetLastError()); + INFO_ASSERT(STR("Critical failure\nContact an admin with the following code: %08x"), GetLastError()); } uint8_t RandomBytes[32]; diff --git a/csgo-loader/csgo-client/Security/Encryption.hpp b/csgo-loader/csgo-client/Security/Encryption.hpp index bf1346e..79ae604 100644 --- a/csgo-loader/csgo-client/Security/Encryption.hpp +++ b/csgo-loader/csgo-client/Security/Encryption.hpp @@ -6,6 +6,7 @@ #include #include +#include using ByteArray = std::vector; diff --git a/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp b/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp index 6a5ce20..f7c1cc2 100644 --- a/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp +++ b/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp @@ -30,7 +30,7 @@ namespace Security if(ReturnModule != LoaderModule) { - Protection->SecurityCallback("Malicious activity [Tampering]."); + Protection->SecurityCallback(STR("Malicious activity [Tampering].")); [&](decltype(&OpenProcess) A) { @@ -75,7 +75,7 @@ namespace Security // Let's meme anyone who tries to reverse this. if(ReturnModule != LoaderModule) { - return []() { Protection->SecurityCallback("Malicious activity [Tampering]."); return -1; }(); + return []() { Protection->SecurityCallback(STR("Malicious activity [Tampering].")); return -1; }(); } // Call original function @@ -99,7 +99,7 @@ namespace Security // Let's meme anyone who tries to reverse this. if(ReturnModule != LoaderModule) { - return []() { Protection->SecurityCallback("Malicious activity [Tampering]."); return -1; }(); + return []() { Protection->SecurityCallback(STR("Malicious activity [Tampering].")); return -1; }(); } // Call original function @@ -120,6 +120,8 @@ namespace Security bool RuntimeSecurity::ApplyApiHooks() { + VMProtectBeginMutation("ApplyHooks"); + // Make sure that MinHook is initialized properly. CreateMinHook(); CheckStatus(); @@ -138,6 +140,8 @@ namespace Security SafeCallTo(MH_EnableHook(&send)); return true; + + VMProtectEnd(); } #pragma optimize("", on) @@ -147,17 +151,17 @@ namespace Security HMODULE Module = GetModuleHandleA("ntdll.dll"); if(!Module) - ERROR_ASSERT("[000F:00001A00] Failed to initialize. Please contact an administrator."); + ERROR_ASSERT(STR("[000F:00001A00] Failed to initialize. Please contact an administrator.")); // Grab exports from ntdll.dll - uintptr_t Export_DbgUiRemoteBreakin = (uintptr_t)GetProcAddress(Module, "DbgUiRemoteBreakin"); - uintptr_t Export_DbgBreakPoint = (uintptr_t)GetProcAddress(Module, "DbgBreakPoint"); + uintptr_t Export_DbgUiRemoteBreakin = (uintptr_t)GetProcAddress(Module, STR("DbgUiRemoteBreakin")); + uintptr_t Export_DbgBreakPoint = (uintptr_t)GetProcAddress(Module, STR("DbgBreakPoint")); // Most plugins for OllyDBG / IDA only fix DbgUiRemoteBreakin/DbgBreakPoint, // however, NtContinue is never touched although it is used. // This should prevent any such plugins from effectively attaching the debugger. // NOTE: This does not work on x64dbg for whatever reason.. - uintptr_t Export_NtContinue = (uintptr_t)GetProcAddress(Module, "NtContinue"); + uintptr_t Export_NtContinue = (uintptr_t)GetProcAddress(Module, STR("NtContinue")); // Ensure that the program gets closed if a debugger is attached. uintptr_t Exports[] = { @@ -170,7 +174,7 @@ namespace Security { DWORD OldProtection; if(!VirtualProtect((void *)It, sizeof uintptr_t + 1, PAGE_EXECUTE_READWRITE, &OldProtection)) - ERROR_ASSERT("[000F:00001A00] Failed to initialize. Please contact an administrator."); + ERROR_ASSERT(STR("[000F:00001A00] Failed to initialize. Please contact an administrator.")); // Patch to __asm { jmp oExitProcess; }; *(uint8_t *)It = 0xE9; @@ -182,10 +186,14 @@ namespace Security void RuntimeSecurity::DispatchSecurityThreads() { + VMProtectBeginMutation("DispatchThreads"); + std::thread DebugThread (&RuntimeSecurity::CheckForDebugger, this); DebugThread.detach(); std::thread VMThread (&RuntimeSecurity::CheckForVirtualMachine, this); VMThread.detach(); std::thread DriverThread(&RuntimeSecurity::CheckForDrivers, this); DriverThread.detach(); std::thread TamperThread(&RuntimeSecurity::CheckForTampering, this); TamperThread.detach(); + + VMProtectEnd(); } // The following functions are only called internally. @@ -197,15 +205,21 @@ namespace Security void RuntimeSecurity::CheckForVirtualMachine() { + VMProtectBeginVirtualization("VMThread"); + for(;;) { // Don't put too much stress on the CPU. Sleep(1); } + + VMProtectEnd(); } void RuntimeSecurity::CheckForDebugger() { + VMProtectBeginVirtualization("DebuggerThread"); + for(;;) { // Read the PEB from the TIB. @@ -238,11 +252,11 @@ namespace Security */ using WindowParams = std::pair; static std::vector BlackListedWindows = { - {"ID", "Immunity"}, // Immunity Debugger - {"Qt5QWindowIcon", "x64dbg"}, // x64dbg - {"Qt5QWindowIcon", "x32dbg"}, // x32dbg - {"OLLYDBG", "OllyDbg"}, // OllyDbg - {nullptr, "Progress Telerik Fiddler Web Debugger"}, // Telerik Fiddler + {STR("ID"), STR("Immunity")}, // Immunity Debugger + {STR("Qt5QWindowIcon"), STR("x64dbg")}, // x64dbg + {STR("Qt5QWindowIcon"), STR("x32dbg")}, // x32dbg + {STR("OLLYDBG"), STR("OllyDbg")}, // OllyDbg + {nullptr, STR("Progress Telerik Fiddler Web Debugger")}, // Telerik Fiddler }; for(auto &It : BlackListedWindows) @@ -250,12 +264,14 @@ namespace Security // size_t Index = std::distance(...); if(FindWindowA(It.first, It.second)) - SecurityCallback("Malicious activity [Debugging attempt]."); + SecurityCallback(STR("Malicious activity [Debugging attempt].")); } // Don't put too much stress on the CPU. Sleep(1); } + + VMProtectEnd(); } void RuntimeSecurity::CheckForDrivers() @@ -264,19 +280,19 @@ namespace Security for(;;) { static const char *BlackListedDrivers[] = { - "Sbie", // Sandboxie - "NPF", // WireShark / WinPCAP - "acker", // Process Hacker - "CEDRI" // Cheat Engine - "VBox", // VirtualBox + STR("Sbie"), // Sandboxie + STR("NPF"), // WireShark / WinPCAP + STR("acker"), // Process Hacker + STR("CEDRI"), // Cheat Engine + //STR("VBox") // VirtualBox }; static const char *BlackListReasons[] = { - "Please uninstall Sandboxie.", - "Please uninstall WireShark.", - "Please close Process Hacker.", - "Please close Cheat Engine.", - "Please uninstall VirtualBox." + STR("Please uninstall Sandboxie."), + STR("Please uninstall WireShark."), + STR("Please close Process Hacker."), + STR("Please close Cheat Engine."), + STR("Please uninstall VirtualBox.") }; uint16_t Length = sizeof BlackListedDrivers / sizeof(BlackListedDrivers[0]); @@ -287,7 +303,7 @@ namespace Security if(K32EnumDeviceDrivers(DriverList, sizeof DriverList, &Needed)) { if(Needed > sizeof DriverList) - ERROR_ASSERT("[00DF:00001CFF] A security thread has failed. Contact an administrator."); + ERROR_ASSERT(STR("[00DF:00001CFF] A security thread has failed. Contact an administrator.")); char DriverName[1024]; uint32_t DriverCount = Needed / sizeof DriverList[0]; @@ -375,7 +391,7 @@ namespace Security char ReasonParameter[64]; uint32_t Status = GetLastError(); - sprintf_s(ReasonParameter, "[00DF:%08x] There was an error with accessing a process.", Status); + sprintf_s(ReasonParameter, STR("[00DF:%08x] There was an error with accessing a process."), Status); ERROR_ASSERT(ReasonParameter); } @@ -392,9 +408,9 @@ namespace Security // You can use the reason parameters to debug the security in case // something weird starts going on with it. char Buffer[2048]; - sprintf_s(Buffer, "Security callback was called. Reason parameter: \"%s\"\n", Reason); + sprintf_s(Buffer, STR("Security callback was called. Reason parameter: \"%s\"\n"), Reason); - MessageBoxA(0, Buffer, "Information", MB_ICONINFORMATION | MB_OK); + MessageBoxA(0, Buffer, "", MB_ICONINFORMATION | MB_OK); // The process will straight up die on Release mode. diff --git a/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp b/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp index 9fe5c51..08e6490 100644 --- a/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp +++ b/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp @@ -20,7 +20,7 @@ // Required for the SDK from VMP which offers // virtual machines and string encryption, as // well as debug/VM checks. - +#include // Required for MinHook. #include @@ -35,10 +35,14 @@ // Sick macros, retard. #define WRAP_IF_RELEASE( s ) #define WRAP_IF_DEBUG( s ) { s; } + + #define STR( s ) s #else // Sick macros, retard. #define WRAP_IF_RELEASE( s ) { s; } #define WRAP_IF_DEBUG( s ) + + #define STR( s ) VMProtectDecryptStringA( s ) #endif namespace Security diff --git a/csgo-loader/csgo-client/Security/SyscallManager.cpp b/csgo-loader/csgo-client/Security/SyscallManager.cpp index 871b593..9bb1302 100644 --- a/csgo-loader/csgo-client/Security/SyscallManager.cpp +++ b/csgo-loader/csgo-client/Security/SyscallManager.cpp @@ -1,5 +1,4 @@ #include -#include // Global accessor for SyscallManager. Wrapper::SyscallManagerPtr Syscalls = std::make_unique(); @@ -23,7 +22,7 @@ namespace Wrapper GetSystemDirectoryA(SystemPath, MAX_PATH); // Append 'ntdll.dll' to path. - strcat_s(SystemPath, "\\ntdll.dll"); + strcat_s(SystemPath, STR("\\ntdll.dll")); // Open handle to 'ntdll.dll'. std::ifstream FileHandle(SystemPath, std::ios::in | std::ios::binary); @@ -139,7 +138,7 @@ namespace Wrapper // We've found a syscall. uint8_t *Opcodes = (uint8_t *)(Buffer + FunctionRawOffset); - if(!memcmp(Opcodes, "\x4C\x8B\xD1\xB8", 4)) + if(!memcmp(Opcodes, STR("\x4C\x8B\xD1\xB8"), 4)) { uint32_t SyscallIndex = *(uint32_t *)(Buffer + FunctionRawOffset + 4); diff --git a/csgo-loader/csgo-client/Security/SyscallManager.hpp b/csgo-loader/csgo-client/Security/SyscallManager.hpp index 615b646..df3a077 100644 --- a/csgo-loader/csgo-client/Security/SyscallManager.hpp +++ b/csgo-loader/csgo-client/Security/SyscallManager.hpp @@ -11,6 +11,9 @@ #include +#include +#include + using ByteArray = std::vector; namespace Wrapper @@ -65,7 +68,7 @@ namespace Wrapper uint64_t Syscall = m_Syscalls[Hash].Get(); if(!Syscall) - ERROR_ASSERT("[000F:00001B00] Internal software error. Please contact an administrator."); + ERROR_ASSERT(STR("[000F:00001B00] Internal software error. Please contact an administrator.")); return (T)m_Syscalls[Hash].Get(); } -- cgit v1.2.3