From a5acd4c9a3b24c9d5af3a8f504e5af053fa7fa09 Mon Sep 17 00:00:00 2001 From: boris Date: Thu, 20 Dec 2018 21:38:04 +1300 Subject: yo is this loss --- csgo-loader/csgo-client/Client.cpp | 27 ++-- csgo-loader/csgo-client/Login/RemoteLogin.cpp | 34 ++-- csgo-loader/csgo-client/Login/RemoteLogin.hpp | 23 +-- csgo-loader/csgo-client/Networking/TCPClient.cpp | 33 ++-- csgo-loader/csgo-client/Networking/TCPClient.hpp | 8 +- .../csgo-client/RemoteCode/RemoteCodeClient.cpp | 1 + .../csgo-client/RemoteCode/RemoteCodeClient.hpp | 6 + .../RemoteCode/RemoteInjectionClient.cpp | 1 + .../RemoteCode/RemoteInjectionClient.hpp | 6 + .../csgo-client/RemoteCode/RemoteProcess.cpp | 118 ++++++++++---- .../csgo-client/RemoteCode/RemoteProcess.hpp | 49 +++--- csgo-loader/csgo-client/Security/Encryption.cpp | 174 ++++++++++++++------- csgo-loader/csgo-client/Security/Encryption.hpp | 12 +- csgo-loader/csgo-client/Security/FnvHash.hpp | 24 ++- .../csgo-client/Security/SyscallManager.cpp | 40 +++-- .../csgo-client/Security/SyscallManager.hpp | 15 +- .../csgo-client/UserExperience/UserInterface.cpp | 32 ++-- .../csgo-client/UserExperience/UserInterface.hpp | 17 +- csgo-loader/csgo-client/csgo-client.vcxproj | 4 + .../csgo-client/csgo-client.vcxproj.filters | 12 ++ 20 files changed, 424 insertions(+), 212 deletions(-) create mode 100644 csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp create mode 100644 csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp create mode 100644 csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.cpp create mode 100644 csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp (limited to 'csgo-loader/csgo-client') diff --git a/csgo-loader/csgo-client/Client.cpp b/csgo-loader/csgo-client/Client.cpp index 077b14b..d2dbd7a 100644 --- a/csgo-loader/csgo-client/Client.cpp +++ b/csgo-loader/csgo-client/Client.cpp @@ -3,37 +3,42 @@ #include #include #include +#include #define LOCAL_IP 0x0100007F // '127.0.0.1' #define SERVER_IP 0xE53CA523 // Hexadecimal representation of the server IP, obtained by inet_addr() #define SERVER_PORT 0xF2C // Hexadecimal representation of the server port. -int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow) { +int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow) +{ + AllocConsole(); + FILE *file; + freopen_s(&file, "CONOUT$", "w", stdout); + + RemoteCode::RemoteProcess Process; + if(!Syscalls->Start()) ERROR_ASSERT("[000F:00001A00] Failed to initialize. Please contact an administrator."); UserInterface->m_Data.m_ExecutionState = UserExperience::EXECUTION_WAITING; - std::thread WindowThread([] { + std::thread WindowThread([] + { if(!UserInterface->Start()) ERROR_ASSERT("[000F:00001B00] Failed to initialize. Please contact an administrator."); UserInterface->RunUiFrame(); }); WindowThread.detach(); - // Allow the window to start, etc. - Sleep(2000); - Networking::TCPClient Client; if(!Client.Start(LOCAL_IP, SERVER_PORT)) ERROR_ASSERT("[000F:0002A000] Server did not accept the connection."); UserInterface->m_Data.m_ExecutionState = UserExperience::EXECUTION_LOG_IN; - - while(UserInterface->m_Data.m_ExecutionState != UserExperience::EXECUTION_WAITING) { + + while(UserInterface->m_Data.m_ExecutionState != UserExperience::EXECUTION_WAITING) Sleep(1); - } Login::RemoteLoginTransaction Transaction; Transaction.Start(UserInterface->m_Data.m_Username, UserInterface->m_Data.m_Password); @@ -42,10 +47,12 @@ int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow) { Client.SendBytes(RawLoginHeader); ByteArray RawServerResponse = Client.ReceiveBytes(); - if(!Transaction.TranslateResponse(RawServerResponse)) { + if(!Transaction.TranslateResponse(RawServerResponse)) + { UserInterface->m_Data.m_ExecutionState = UserExperience::EXECUTION_ERROR; } - else { + else + { UserInterface->m_Data.m_ExecutionState = UserExperience::EXECUTION_CHOOSE; } diff --git a/csgo-loader/csgo-client/Login/RemoteLogin.cpp b/csgo-loader/csgo-client/Login/RemoteLogin.cpp index 45f7953..2f82744 100644 --- a/csgo-loader/csgo-client/Login/RemoteLogin.cpp +++ b/csgo-loader/csgo-client/Login/RemoteLogin.cpp @@ -5,8 +5,10 @@ // NOTE: You must change this on the server as well. #define CURRENT_CLIENT_HEADER 0xDEADBEEF -namespace Login { - void RemoteLoginTransaction::Start(const char *Username, const char *Password) { +namespace Login +{ + void RemoteLoginTransaction::Start(const char *Username, const char *Password) + { // Initialise the header with the client header. m_Header.m_ClientHeader = CURRENT_CLIENT_HEADER; @@ -23,26 +25,30 @@ namespace Login { m_Header.m_IntegrityBit3 = 0; // The checksum bit, the server will check this first to detect possible tampering. - m_Header.m_IntegrityBit4 = m_Header.m_IntegrityBit1 - | m_Header.m_IntegrityBit2 - | m_Header.m_IntegrityBit3; + m_Header.m_IntegrityBit4 = m_Header.m_IntegrityBit1 + | m_Header.m_IntegrityBit2 + | m_Header.m_IntegrityBit3; } // TODO: Hardware ID check. - ByteArray RemoteLoginTransaction::DoWmiQuery(const char *Query) { + ByteArray RemoteLoginTransaction::DoWmiQuery(const char *Query) + { ByteArray Response{}; - + return Response; } - uint32_t RemoteLoginTransaction::GetHardwareId() { + uint32_t RemoteLoginTransaction::GetHardwareId() + { return 123456789; } - bool RemoteLoginTransaction::TranslateResponse(ByteArray &RawResponse) { + bool RemoteLoginTransaction::TranslateResponse(ByteArray &RawResponse) + { RemoteLoginResponse ServerResponse = *reinterpret_cast(&RawResponse[0]); - switch(ServerResponse) { + switch(ServerResponse) + { case RemoteLoginResponse::ACCESS_SPECIAL_USER: // Allow the user to load special access cheats. UserInterface->m_Data.m_SpecialAccess = true; @@ -52,21 +58,19 @@ namespace Login { INFO_ASSERT("[000A:%08x] Your client is outdated.\nPlease download the latest client at 'moneybot.cc'.", m_Header.m_HardwareId); break; case RemoteLoginResponse::INTEGRITY_FAILURE: - INFO_ASSERT("[000F:%08x] Failed to verify session.\nPlease contact an administrator.", m_Header.m_HardwareId); + UserInterface->m_Data.m_Error = UserExperience::ERROR_SHADOW_BAN; 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); break; case RemoteLoginResponse::INVALID_HARDWARE: UserInterface->m_Data.m_Error = UserExperience::ERROR_INVALID_HWID; - //INFO_ASSERT("[000C:%08x] Hardware ID mismatch.\nPlease contact an administrator to request a hardware ID reset.", m_Header.m_HardwareId); break; case RemoteLoginResponse::INVALID_CREDENTIALS: - UserInterface->m_Data.m_Error = UserExperience::ERROR_SHADOW_BAN; - //INFO_ASSERT("[000C:%08x] Your credentials are invalid. Please check your spelling and try again.", m_Header.m_HardwareId ^ RemoteLoginResponse::INVALID_CREDENTIALS); + INFO_ASSERT("[000C:%08x] Your credentials are invalid. Please check your spelling and try again.", m_Header.m_HardwareId); break; case RemoteLoginResponse::NO_SUBSCRIPTION: - INFO_ASSERT("[000G:%08x] No active subscription found.", m_Header.m_HardwareId ^ RemoteLoginResponse::NO_SUBSCRIPTION); + INFO_ASSERT("[000G:%08x] No active subscription found.", m_Header.m_HardwareId); break; } diff --git a/csgo-loader/csgo-client/Login/RemoteLogin.hpp b/csgo-loader/csgo-client/Login/RemoteLogin.hpp index e543d27..31649c6 100644 --- a/csgo-loader/csgo-client/Login/RemoteLogin.hpp +++ b/csgo-loader/csgo-client/Login/RemoteLogin.hpp @@ -6,9 +6,11 @@ using ByteArray = std::vector; -namespace Login { +namespace Login +{ // Login header that is sent over to the server - struct RemoteLoginHeader { + struct RemoteLoginHeader + { // The first four bytes are encoded by the client. // This will carry the client version which can be checked. uint32_t m_ClientHeader; @@ -32,9 +34,10 @@ namespace Login { // Possible server responses // The hardware ID is encoded (XORed with the message ID) within the message for // shadow ban/forum ban purposes. :) - enum RemoteLoginResponse : uint8_t { - OUTDATED_CLIENT = 'A', // '[000A:{HWID}] Your client is outdated. Please download the latest client at 'moneybot.cc'.' - ACCESS_AUTHORISED = 'B', // Allows the user to continue with injection. + enum RemoteLoginResponse : uint8_t + { + OUTDATED_CLIENT = 'A', // '[000A:{HWID}] Your client is outdated. Please download the latest client at 'moneybot.cc'.' + ACCESS_AUTHORISED = 'B', // Allows the user to continue with injection. INVALID_CREDENTIALS = 'C', // '[000C:{HWID}] Your credentials are invalid. Please check your spelling and try again.' USER_BANNED = 'D', // '[000D:{HWID}] Your account is banned. Please contact 'admin@moneybot.cc' for additional information.' INVALID_HARDWARE = 'E', // '[000E:{HWID}] Please contact an administrator to request a hardware ID reset.' @@ -44,9 +47,10 @@ namespace Login { }; // Runs the security checks and creates the login header to send to the server. - class RemoteLoginTransaction { + class RemoteLoginTransaction + { RemoteLoginHeader m_Header; - + public: // Initialises the header. void Start(const char *Username, const char *Password); @@ -62,9 +66,10 @@ namespace Login { // the response is not ACCESS_AUTHORISED. bool TranslateResponse(ByteArray &RawResponse); - ByteArray GetHeader() { + ByteArray GetHeader() + { ByteArray Header; - + // Copy header to the ByteArray. Header.insert( Header.begin(), diff --git a/csgo-loader/csgo-client/Networking/TCPClient.cpp b/csgo-loader/csgo-client/Networking/TCPClient.cpp index 3bdea21..8065c50 100644 --- a/csgo-loader/csgo-client/Networking/TCPClient.cpp +++ b/csgo-loader/csgo-client/Networking/TCPClient.cpp @@ -1,11 +1,13 @@ #include #include -namespace Networking { +namespace Networking +{ // We will only receive up to 256 bytes per cycle. constexpr int BufferSize = 256; - void TCPClient::SendRawBytes(ByteArray &Bytes) { + void TCPClient::SendRawBytes(ByteArray &Bytes) + { // Send data. int32_t Result = send(m_Socket, (char *)Bytes.data(), (int)Bytes.size(), 0); @@ -13,12 +15,14 @@ namespace Networking { INFO_ASSERT("[000F:00002B00] Server closed the connection suddenly."); } - ByteArray TCPClient::ReceiveRawBytes() { + ByteArray TCPClient::ReceiveRawBytes() + { ByteArray ReceivedBytes; uint8_t RecvBuffer[BufferSize]; // Attempt to receive a packet. - while(true) { + while(true) + { int32_t Received = recv(m_Socket, (char*)RecvBuffer, BufferSize, 0); // No more bytes left to receive. @@ -26,7 +30,8 @@ namespace Networking { break; // Emplace all received bytes. - for(int n = 0; n < Received; ++n) { + for(int n = 0; n < Received; ++n) + { ReceivedBytes.push_back(RecvBuffer[n]); } @@ -38,14 +43,16 @@ namespace Networking { return ReceivedBytes; } - void TCPClient::SendBytes(ByteArray &Bytes) { + void TCPClient::SendBytes(ByteArray &Bytes) + { // Encrypt outgoing data. ByteArray Encrypted = m_Encryption.Encrypt(Bytes); SendRawBytes(Encrypted); } - ByteArray TCPClient::ReceiveBytes() { + ByteArray TCPClient::ReceiveBytes() + { ByteArray ReceivedBytes = ReceiveRawBytes(); // Decrypt incoming data. @@ -54,7 +61,8 @@ namespace Networking { return Decrypted; } - bool TCPClient::Start(uint32_t ServerAddress, uint16_t ServerPort) { + bool TCPClient::Start(uint32_t ServerAddress, uint16_t ServerPort) + { const int32_t version = 0x101; // Initialise WinSocks. @@ -69,8 +77,8 @@ namespace Networking { // Set up client context. m_Context.sin_addr.s_addr = ServerAddress; - m_Context.sin_family = AF_INET; - m_Context.sin_port = htons(ServerPort); + m_Context.sin_family = AF_INET; + m_Context.sin_port = htons(ServerPort); // Attempt connection. if(connect(m_Socket, (sockaddr *)&m_Context, sizeof m_Context)) @@ -93,10 +101,11 @@ namespace Networking { return true; } - void TCPClient::Kill() { + void TCPClient::Kill() + { if(m_Socket) closesocket(m_Socket); - + WSACleanup(); } } \ No newline at end of file diff --git a/csgo-loader/csgo-client/Networking/TCPClient.hpp b/csgo-loader/csgo-client/Networking/TCPClient.hpp index f057cdc..4e3e089 100644 --- a/csgo-loader/csgo-client/Networking/TCPClient.hpp +++ b/csgo-loader/csgo-client/Networking/TCPClient.hpp @@ -10,10 +10,12 @@ // std::min #include -namespace Networking { +namespace Networking +{ // A TCPClient is essentially the same as the TCPConnection counterpart on the server, // however, it independently handles connection. - class TCPClient { + class TCPClient + { WSADATA m_WinSocks; SOCKET m_Socket; sockaddr_in m_Context; @@ -25,7 +27,7 @@ namespace Networking { // Connects to a remote server. // Also handles the initial handshake between server and client. bool Start(uint32_t ServerAddress, uint16_t ServerPort); - + // Kills the client. void Kill(); diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp b/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp new file mode 100644 index 0000000..7e6575b --- /dev/null +++ b/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp @@ -0,0 +1 @@ +#include diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp b/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp new file mode 100644 index 0000000..57f1499 --- /dev/null +++ b/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace RemoteCode +{ + +} \ No newline at end of file diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.cpp b/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.cpp new file mode 100644 index 0000000..d142264 --- /dev/null +++ b/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.cpp @@ -0,0 +1 @@ +#include diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp b/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp new file mode 100644 index 0000000..57f1499 --- /dev/null +++ b/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace RemoteCode +{ + +} \ No newline at end of file diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp b/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp index 7397c7d..969f907 100644 --- a/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp +++ b/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp @@ -1,47 +1,99 @@ #include -namespace RemoteCode { +namespace RemoteCode +{ // RemoteModule implementation - RemoteModule::RemoteModule(HANDLE Module, RemoteProcess &Process) : - m_Module(Module) { - // Read information about module. - MODULEINFO ModuleInfo{}; - if(!K32GetModuleInformation(Process, (HMODULE)Module, &ModuleInfo, sizeof ModuleInfo)) - return; - - // Read module data. - m_ModuleData.reserve(ModuleInfo.SizeOfImage); - Process.Read(ModuleInfo.lpBaseOfDll, m_ModuleData.data(), m_ModuleData.size()); - } + RemoteModule::RemoteModule(HANDLE Module) : + m_Module(Module) {} - uintptr_t RemoteModule::Scan(ByteArray &Data) { - if(m_ModuleData.empty()) - return uintptr_t{}; + // RemoteProcess implementation + bool RemoteProcess::Start(const char *ProcessName) + { + void *Toolhelp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - // We have a valid file (?) - uint8_t *Buffer = m_ModuleData.data(); + if(!Toolhelp) + return false; - if(!Buffer || *(uint16_t *)Buffer != IMAGE_DOS_SIGNATURE) - return uintptr_t{}; + PROCESSENTRY32 ProcessEntry{}; + ProcessEntry.dwSize = sizeof PROCESSENTRY32; - // Read PE information. - IMAGE_DOS_HEADER *DosHeader = (IMAGE_DOS_HEADER *)Buffer; - IMAGE_NT_HEADERS *NtHeaders = (IMAGE_NT_HEADERS *)(Buffer + DosHeader->e_lfanew); + if(!Process32First(Toolhelp, &ProcessEntry)) + return false; - if(NtHeaders->Signature != IMAGE_NT_SIGNATURE) - return uintptr_t{}; + while(Process32Next(Toolhelp, &ProcessEntry)) + { + if(strstr(ProcessName, ProcessEntry.szExeFile)) + { + CloseHandle(Toolhelp); - // Find signature. - ByteArray::iterator Iterator = std::search( - m_ModuleData.begin(), - m_ModuleData.end(), - Data.begin(), - Data.end() - ); + // swoo + m_ProcessId = ProcessEntry.th32ProcessID; + m_Process = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessEntry.th32ProcessID); + return true; + } + } - return (uintptr_t)std::distance(m_ModuleData.begin(), Iterator); + CloseHandle(Toolhelp); + return false; } - // RemoteProcess implementation + void RemoteProcess::ReadMemoryWrapper_Internal(void *Address, void *Data, size_t SizeOfData) + { + static auto ZwReadVirtualMemory = Syscalls->Find(FNV("ZwReadVirtualMemory")); + ZwReadVirtualMemory(m_Process, Address, Data, SizeOfData, nullptr); + } + + void RemoteProcess::WriteMemoryWrapper_Internal(void *Address, void *Data, size_t SizeOfData) + { + static auto ZwWriteVirtualMemory = Syscalls->Find(FNV("ZwWriteVirtualMemory")); + ZwWriteVirtualMemory(m_Process, Address, Data, SizeOfData, nullptr); + } + void *RemoteProcess::Allocate(size_t AllocationSize) + { + void *AllocationAddress = nullptr; + static auto ZwAllocateVirtualMemory = Syscalls->Find(FNV("ZwAllocateVirtualMemory")); + + // :b:invoke the :b:unction :b:oi + NTSTATUS Status = ZwAllocateVirtualMemory( + m_Process, + &AllocationAddress, + 0, + &AllocationSize, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE + ); + + if(!NT_SUCCESS(Status)) + return nullptr; + + return AllocationAddress; + } + + RemoteModule RemoteProcess::FindModule(const char *ModuleName) + { + void *Toolhelp = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, m_ProcessId); + + if(!Toolhelp) + return RemoteModule{}; + + MODULEENTRY32 ModuleEntry{}; + ModuleEntry.dwSize = sizeof MODULEENTRY32; + + if(!Module32First(Toolhelp, &ModuleEntry)) + return RemoteModule{}; + + while(Module32Next(Toolhelp, &ModuleEntry)) + { + printf("%s\n", ModuleEntry.szModule); + if(strstr(ModuleEntry.szModule, ModuleName)) + { + CloseHandle(Toolhelp); + return RemoteModule(ModuleEntry.hModule); + } + } + + CloseHandle(Toolhelp); + return RemoteModule{}; + } } \ No newline at end of file diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteProcess.hpp b/csgo-loader/csgo-client/RemoteCode/RemoteProcess.hpp index b1c716b..d86ecfa 100644 --- a/csgo-loader/csgo-client/RemoteCode/RemoteProcess.hpp +++ b/csgo-loader/csgo-client/RemoteCode/RemoteProcess.hpp @@ -2,35 +2,32 @@ #include #include +#include #include #include -namespace RemoteCode { +namespace RemoteCode +{ // The module wrapper. class RemoteProcess; - class RemoteModule { + class RemoteModule + { HANDLE m_Module; - int32_t m_SizeOfModule; - - // All the module data will be read upon class initialisation. - ByteArray m_ModuleData; public: - // The constructor (reads all module data into m_ModuleData). - RemoteModule(HANDLE Module, RemoteProcess &Process); - - // TODO: Add support for wild-cards (not currently implemented) - uintptr_t Scan(ByteArray &Pattern); + RemoteModule() = default; + RemoteModule(HANDLE Module); + ~RemoteModule() { CloseHandle(m_Module); } // Allow us to access the module by just passing the // handle as a parameter. operator HANDLE() { return m_Module; } - operator HINSTANCE() { return (HINSTANCE)m_Module; } }; // The process wrapper. - class RemoteProcess { + class RemoteProcess + { HANDLE m_Process; int32_t m_ProcessId; @@ -42,12 +39,14 @@ namespace RemoteCode { RemoteProcess() = default; // For portability, will ignore exceptions. - RemoteProcess(const char *ProcessName) { + RemoteProcess(const char *ProcessName) + { Start(ProcessName); } // Release the handle when the process goes out of scope. - ~RemoteProcess() { + ~RemoteProcess() + { if(m_Process) CloseHandle(m_Process); } @@ -57,25 +56,29 @@ namespace RemoteCode { // Writes to the process memory. template - void Write(void *Address, T Data) { + void Write(void *Address, T Data) + { WriteMemoryWrapper_Internal(Address, (void *)&Data, sizeof T); } - void Write(void *Address, uint8_t *Data, size_t SizeOfData) { - WriteMemoryWrapper_Internal(Address, (void *)Data, SizeOfData); + void Write(void *Address, uint8_t *Data, size_t SizeOfData) + { + WriteMemoryWrapper_Internal(Address, (void *)&Data, SizeOfData); } - + // Reads from the process memory. template - T Read(void *Address) { + T Read(void *Address) + { T Buffer{}; ReadMemoryWrapper_Internal(Address, (void *)&Buffer, sizeof T); - + return Buffer; } - void Read(void *Address, uint8_t *Data, size_t SizeOfData) { - ReadMemoryWrapper_Internal(Address, (void *)Data, SizeOfData); + void Read(void *Address, uint8_t *Data, size_t SizeOfData) + { + ReadMemoryWrapper_Internal(Address, &Data, SizeOfData); } // Allocates a memory region in the process. diff --git a/csgo-loader/csgo-client/Security/Encryption.cpp b/csgo-loader/csgo-client/Security/Encryption.cpp index 7d4fd05..4d42ee7 100644 --- a/csgo-loader/csgo-client/Security/Encryption.cpp +++ b/csgo-loader/csgo-client/Security/Encryption.cpp @@ -6,7 +6,8 @@ #define KEY_SIZE 32 #define NUM_ROUNDS 14 -namespace Wrapper { +namespace Wrapper +{ // Constants used for the AES256 algorithm. uint8_t sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, @@ -87,15 +88,18 @@ namespace Wrapper { , m_rkey(ByteArray(KEY_SIZE, 0)) , m_buffer_pos(0) , m_remainingLength(0) - , m_decryptInitialized(false) { + , m_decryptInitialized(false) + { for(ByteArray::size_type i = 0; i < m_key.size(); ++i) m_key[i] = key[i]; } - Aes256::~Aes256() { + Aes256::~Aes256() + { } - ByteArray::size_type Aes256::encrypt(const ByteArray& key, const ByteArray& plain, ByteArray& encrypted) { + ByteArray::size_type Aes256::encrypt(const ByteArray& key, const ByteArray& plain, ByteArray& encrypted) + { Aes256 aes(key); aes.encrypt_start(plain.size(), encrypted); @@ -105,7 +109,8 @@ namespace Wrapper { return encrypted.size(); } - ByteArray::size_type Aes256::encrypt(const ByteArray& key, const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted) { + ByteArray::size_type Aes256::encrypt(const ByteArray& key, const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted) + { Aes256 aes(key); aes.encrypt_start(plain_length, encrypted); @@ -115,7 +120,8 @@ namespace Wrapper { return encrypted.size(); } - ByteArray::size_type Aes256::decrypt(const ByteArray& key, const ByteArray& encrypted, ByteArray& plain) { + ByteArray::size_type Aes256::decrypt(const ByteArray& key, const ByteArray& encrypted, ByteArray& plain) + { Aes256 aes(key); aes.decrypt_start(encrypted.size()); @@ -125,7 +131,8 @@ namespace Wrapper { return plain.size(); } - ByteArray::size_type Aes256::decrypt(const ByteArray& key, const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain) { + ByteArray::size_type Aes256::decrypt(const ByteArray& key, const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain) + { Aes256 aes(key); aes.decrypt_start(encrypted_length); @@ -135,7 +142,8 @@ namespace Wrapper { return plain.size(); } - ByteArray::size_type Aes256::encrypt_start(const ByteArray::size_type plain_length, ByteArray& encrypted) { + ByteArray::size_type Aes256::encrypt_start(const ByteArray::size_type plain_length, ByteArray& encrypted) + { m_remainingLength = plain_length; // Generate salt @@ -163,10 +171,12 @@ namespace Wrapper { return encrypted.size(); } - ByteArray::size_type Aes256::encrypt_continue(const ByteArray& plain, ByteArray& encrypted) { + ByteArray::size_type Aes256::encrypt_continue(const ByteArray& plain, ByteArray& encrypted) + { ByteArray::const_iterator it = plain.begin(), itEnd = plain.end(); - while(it != itEnd) { + while(it != itEnd) + { m_buffer[m_buffer_pos++] = *(it++); check_and_encrypt_buffer(encrypted); @@ -175,10 +185,12 @@ namespace Wrapper { return encrypted.size(); } - ByteArray::size_type Aes256::encrypt_continue(const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted) { + ByteArray::size_type Aes256::encrypt_continue(const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted) + { ByteArray::size_type i = 0; - while(i < plain_length) { + while(i < plain_length) + { m_buffer[m_buffer_pos++] = plain[i++]; check_and_encrypt_buffer(encrypted); @@ -187,11 +199,14 @@ namespace Wrapper { return encrypted.size(); } - void Aes256::check_and_encrypt_buffer(ByteArray& encrypted) { - if(m_buffer_pos == BLOCK_SIZE) { + void Aes256::check_and_encrypt_buffer(ByteArray& encrypted) + { + if(m_buffer_pos == BLOCK_SIZE) + { encrypt(m_buffer); - for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos) { + for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos) + { encrypted.push_back(m_buffer[m_buffer_pos]); --m_remainingLength; } @@ -200,14 +215,17 @@ namespace Wrapper { } } - ByteArray::size_type Aes256::encrypt_end(ByteArray& encrypted) { - if(m_buffer_pos > 0) { + ByteArray::size_type Aes256::encrypt_end(ByteArray& encrypted) + { + if(m_buffer_pos > 0) + { while(m_buffer_pos < BLOCK_SIZE) m_buffer[m_buffer_pos++] = 0; encrypt(m_buffer); - for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos) { + for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos) + { encrypted.push_back(m_buffer[m_buffer_pos]); --m_remainingLength; } @@ -218,12 +236,14 @@ namespace Wrapper { return encrypted.size(); } - void Aes256::encrypt(unsigned char* buffer) { + void Aes256::encrypt(unsigned char* buffer) + { unsigned char i, rcon; copy_key(); add_round_key(buffer, 0); - for(i = 1, rcon = 1; i < NUM_ROUNDS; ++i) { + for(i = 1, rcon = 1; i < NUM_ROUNDS; ++i) + { sub_bytes(buffer); shift_rows(buffer); mix_columns(buffer); @@ -237,7 +257,8 @@ namespace Wrapper { add_round_key(buffer, i); } - ByteArray::size_type Aes256::decrypt_start(const ByteArray::size_type encrypted_length) { + ByteArray::size_type Aes256::decrypt_start(const ByteArray::size_type encrypted_length) + { unsigned char j; m_remainingLength = encrypted_length; @@ -255,10 +276,12 @@ namespace Wrapper { return m_remainingLength; } - ByteArray::size_type Aes256::decrypt_continue(const ByteArray& encrypted, ByteArray& plain) { + ByteArray::size_type Aes256::decrypt_continue(const ByteArray& encrypted, ByteArray& plain) + { ByteArray::const_iterator it = encrypted.begin(), itEnd = encrypted.end(); - while(it != itEnd) { + while(it != itEnd) + { m_buffer[m_buffer_pos++] = *(it++); check_and_decrypt_buffer(plain); @@ -267,10 +290,12 @@ namespace Wrapper { return plain.size(); } - ByteArray::size_type Aes256::decrypt_continue(const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain) { + ByteArray::size_type Aes256::decrypt_continue(const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain) + { ByteArray::size_type i = 0; - while(i < encrypted_length) { + while(i < encrypted_length) + { m_buffer[m_buffer_pos++] = encrypted[i++]; check_and_decrypt_buffer(plain); @@ -279,8 +304,10 @@ namespace Wrapper { return plain.size(); } - void Aes256::check_and_decrypt_buffer(ByteArray& plain) { - if(!m_decryptInitialized && m_buffer_pos == m_salt.size() + 1) { + void Aes256::check_and_decrypt_buffer(ByteArray& plain) + { + if(!m_decryptInitialized && m_buffer_pos == m_salt.size() + 1) + { unsigned char j; ByteArray::size_type padding; @@ -297,11 +324,13 @@ namespace Wrapper { m_decryptInitialized = true; } - else if(m_decryptInitialized && m_buffer_pos == BLOCK_SIZE) { + else if(m_decryptInitialized && m_buffer_pos == BLOCK_SIZE) + { decrypt(m_buffer); for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos) - if(m_remainingLength > 0) { + if(m_remainingLength > 0) + { plain.push_back(m_buffer[m_buffer_pos]); --m_remainingLength; } @@ -310,11 +339,13 @@ namespace Wrapper { } } - ByteArray::size_type Aes256::decrypt_end(ByteArray& plain) { + ByteArray::size_type Aes256::decrypt_end(ByteArray& plain) + { return plain.size(); } - void Aes256::decrypt(unsigned char* buffer) { + void Aes256::decrypt(unsigned char* buffer) + { unsigned char i, rcon = 1; copy_key(); @@ -325,7 +356,8 @@ namespace Wrapper { shift_rows_inv(buffer); sub_bytes_inv(buffer); - for(i = NUM_ROUNDS, rcon = 0x80; --i;) { + for(i = NUM_ROUNDS, rcon = 0x80; --i;) + { if((i & 1)) expand_dec_key(&rcon); add_round_key(buffer, i); @@ -336,7 +368,8 @@ namespace Wrapper { add_round_key(buffer, i); } - void Aes256::expand_enc_key(unsigned char* rc) { + void Aes256::expand_enc_key(unsigned char* rc) + { unsigned char i; m_rkey[0] = m_rkey[0] ^ sbox[m_rkey[29]] ^ (*rc); @@ -345,7 +378,8 @@ namespace Wrapper { m_rkey[3] = m_rkey[3] ^ sbox[m_rkey[28]]; *rc = FE(*rc); - for(i = 4; i < 16; i += 4) { + for(i = 4; i < 16; i += 4) + { m_rkey[i] = m_rkey[i] ^ m_rkey[i - 4]; m_rkey[i + 1] = m_rkey[i + 1] ^ m_rkey[i - 3]; m_rkey[i + 2] = m_rkey[i + 2] ^ m_rkey[i - 2]; @@ -356,7 +390,8 @@ namespace Wrapper { m_rkey[18] = m_rkey[18] ^ sbox[m_rkey[14]]; m_rkey[19] = m_rkey[19] ^ sbox[m_rkey[15]]; - for(i = 20; i < 32; i += 4) { + for(i = 20; i < 32; i += 4) + { m_rkey[i] = m_rkey[i] ^ m_rkey[i - 4]; m_rkey[i + 1] = m_rkey[i + 1] ^ m_rkey[i - 3]; m_rkey[i + 2] = m_rkey[i + 2] ^ m_rkey[i - 2]; @@ -364,10 +399,12 @@ namespace Wrapper { } } - void Aes256::expand_dec_key(unsigned char* rc) { + void Aes256::expand_dec_key(unsigned char* rc) + { unsigned char i; - for(i = 28; i > 16; i -= 4) { + for(i = 28; i > 16; i -= 4) + { m_rkey[i + 0] = m_rkey[i + 0] ^ m_rkey[i - 4]; m_rkey[i + 1] = m_rkey[i + 1] ^ m_rkey[i - 3]; m_rkey[i + 2] = m_rkey[i + 2] ^ m_rkey[i - 2]; @@ -379,7 +416,8 @@ namespace Wrapper { m_rkey[18] = m_rkey[18] ^ sbox[m_rkey[14]]; m_rkey[19] = m_rkey[19] ^ sbox[m_rkey[15]]; - for(i = 12; i > 0; i -= 4) { + for(i = 12; i > 0; i -= 4) + { m_rkey[i + 0] = m_rkey[i + 0] ^ m_rkey[i - 4]; m_rkey[i + 1] = m_rkey[i + 1] ^ m_rkey[i - 3]; m_rkey[i + 2] = m_rkey[i + 2] ^ m_rkey[i - 2]; @@ -393,21 +431,24 @@ namespace Wrapper { m_rkey[3] = m_rkey[3] ^ sbox[m_rkey[28]]; } - void Aes256::sub_bytes(unsigned char* buffer) { + void Aes256::sub_bytes(unsigned char* buffer) + { unsigned char i = KEY_SIZE / 2; while(i--) buffer[i] = sbox[buffer[i]]; } - void Aes256::sub_bytes_inv(unsigned char* buffer) { + void Aes256::sub_bytes_inv(unsigned char* buffer) + { unsigned char i = KEY_SIZE / 2; while(i--) buffer[i] = sboxinv[buffer[i]]; } - void Aes256::copy_key() { + void Aes256::copy_key() + { ByteArray::size_type i; for(i = 0; i < m_key.size(); ++i) @@ -416,14 +457,16 @@ namespace Wrapper { m_rkey[i + m_key.size()] = m_salt[i]; } - void Aes256::add_round_key(unsigned char* buffer, const unsigned char round) { + void Aes256::add_round_key(unsigned char* buffer, const unsigned char round) + { unsigned char i = KEY_SIZE / 2; while(i--) buffer[i] ^= m_rkey[(round & 1) ? i + 16 : i]; } - void Aes256::shift_rows(unsigned char* buffer) { + void Aes256::shift_rows(unsigned char* buffer) + { unsigned char i, j, k, l; /* to make it potentially parallelable :) */ i = buffer[1]; @@ -447,7 +490,8 @@ namespace Wrapper { buffer[6] = l; } - void Aes256::shift_rows_inv(unsigned char* buffer) { + void Aes256::shift_rows_inv(unsigned char* buffer) + { unsigned char i, j, k, l; /* same as above :) */ i = buffer[1]; @@ -471,10 +515,12 @@ namespace Wrapper { buffer[14] = l; } - void Aes256::mix_columns(unsigned char* buffer) { + void Aes256::mix_columns(unsigned char* buffer) + { unsigned char i, a, b, c, d, e; - for(i = 0; i < 16; i += 4) { + for(i = 0; i < 16; i += 4) + { a = buffer[i]; b = buffer[i + 1]; c = buffer[i + 2]; @@ -489,10 +535,12 @@ namespace Wrapper { } } - void Aes256::mix_columns_inv(unsigned char* buffer) { + void Aes256::mix_columns_inv(unsigned char* buffer) + { unsigned char i, a, b, c, d, e, x, y, z; - for(i = 0; i < 16; i += 4) { + for(i = 0; i < 16; i += 4) + { a = buffer[i]; b = buffer[i + 1]; c = buffer[i + 2]; @@ -509,15 +557,19 @@ namespace Wrapper { } } - inline unsigned char rj_xtime(unsigned char x) { + inline unsigned char rj_xtime(unsigned char x) + { return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1); } // Wrapper for the AES256 encryption algorithm. - void Encryption::Start() { + void Encryption::Start() + { // Create cryptographic context. - if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, 0)) { - if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, CRYPT_NEWKEYSET)) { + if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, 0)) + { + if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, CRYPT_NEWKEYSET)) + { printf("Failed to initialise encryption provider.\n"); return; } @@ -527,7 +579,8 @@ namespace Wrapper { uint32_t RandomBytesCount = sizeof RandomBytes; // Generate random bytes to use as encryption key. - if(CryptGenRandom(m_CryptProvider, RandomBytesCount, RandomBytes)) { + if(CryptGenRandom(m_CryptProvider, RandomBytesCount, RandomBytes)) + { m_EncryptionKey.reserve(RandomBytesCount); m_EncryptionKey.insert( m_EncryptionKey.begin(), @@ -541,19 +594,23 @@ namespace Wrapper { CryptReleaseContext(m_CryptProvider, 0); } - void Encryption::Start(ByteArray &EncryptionKey) { + void Encryption::Start(ByteArray &EncryptionKey) + { // If an encryption key is provided, initialise the wrapper with // the passed parameter. - if(!EncryptionKey.empty()) { + if(!EncryptionKey.empty()) + { m_EncryptionKey.reserve(EncryptionKey.size()); std::copy(EncryptionKey.begin(), EncryptionKey.end(), m_EncryptionKey.begin()); } - else { + else + { Start(); } } - ByteArray Encryption::Encrypt(ByteArray &Data) { + ByteArray Encryption::Encrypt(ByteArray &Data) + { // Encrypt outgoing data. ByteArray Encrypted; @@ -566,7 +623,8 @@ namespace Wrapper { return Encrypted; } - ByteArray Encryption::Decrypt(ByteArray &Data) { + ByteArray Encryption::Decrypt(ByteArray &Data) + { // Decrypt incoming data. ByteArray Decrypted; diff --git a/csgo-loader/csgo-client/Security/Encryption.hpp b/csgo-loader/csgo-client/Security/Encryption.hpp index d55608f..b1c49dc 100644 --- a/csgo-loader/csgo-client/Security/Encryption.hpp +++ b/csgo-loader/csgo-client/Security/Encryption.hpp @@ -9,9 +9,11 @@ using ByteArray = std::vector; #define BLOCK_SIZE 16 -namespace Wrapper { +namespace Wrapper +{ // AES256 implementation. - class Aes256 { + class Aes256 + { public: Aes256(const ByteArray& key); @@ -67,7 +69,8 @@ namespace Wrapper { }; // Encryption wrapper. - class Encryption { + class Encryption + { ByteArray m_EncryptionKey; HCRYPTPROV m_CryptProvider; @@ -82,7 +85,8 @@ namespace Wrapper { ByteArray Decrypt(ByteArray &Data); // Exposes the encryption key. - ByteArray GetKey() { + ByteArray GetKey() + { return m_EncryptionKey; } }; diff --git a/csgo-loader/csgo-client/Security/FnvHash.hpp b/csgo-loader/csgo-client/Security/FnvHash.hpp index da7e80d..35c9ad0 100644 --- a/csgo-loader/csgo-client/Security/FnvHash.hpp +++ b/csgo-loader/csgo-client/Security/FnvHash.hpp @@ -4,9 +4,11 @@ // Credits: namazso // Implements FNV-1a hash algorithm -namespace detail { +namespace detail +{ template - struct SizeDependantData { + struct SizeDependantData + { using type = Type; constexpr static auto k_offset_basis = OffsetBasis; @@ -23,7 +25,8 @@ namespace detail { struct SizeSelector<64> : SizeDependantData {}; template - class FnvHash { + class FnvHash + { private: using data_t = SizeSelector; @@ -36,14 +39,16 @@ namespace detail { public: static __forceinline constexpr auto hash_init( - ) -> hash { + ) -> hash + { return k_offset_basis; } static __forceinline constexpr auto hash_byte( hash current, std::uint8_t byte - ) -> hash { + ) -> hash + { return (current ^ byte) * k_prime; } @@ -51,7 +56,8 @@ namespace detail { static __forceinline constexpr auto hash_constexpr( const char(&str)[N], const std::size_t size = N - 1 /* do not hash the null */ - ) -> hash { + ) -> hash + { const auto prev_hash = size == 1 ? hash_init() : hash_constexpr(str, size - 1); const auto cur_hash = hash_byte(prev_hash, str[size - 1]); return cur_hash; @@ -60,7 +66,8 @@ namespace detail { static auto __forceinline hash_runtime_data( const void* data, const std::size_t sz - ) -> hash { + ) -> hash + { const auto bytes = static_cast(data); const auto end = bytes + sz; auto result = hash_init(); @@ -72,7 +79,8 @@ namespace detail { static auto __forceinline hash_runtime( const char* str - ) -> hash { + ) -> hash + { auto result = hash_init(); do result = hash_byte(result, *str++); diff --git a/csgo-loader/csgo-client/Security/SyscallManager.cpp b/csgo-loader/csgo-client/Security/SyscallManager.cpp index 55d68a3..9de2459 100644 --- a/csgo-loader/csgo-client/Security/SyscallManager.cpp +++ b/csgo-loader/csgo-client/Security/SyscallManager.cpp @@ -4,17 +4,21 @@ // Global accessor for SyscallManager. Wrapper::SyscallManagerPtr Syscalls = std::make_unique(); -namespace Wrapper { - void SyscallStub::SetIndex(uint32_t Index) { +namespace Wrapper +{ + void SyscallStub::SetIndex(uint32_t Index) + { unsigned long OldProtection{}; - + // Make the code executable and set the index. - if(VirtualProtect(m_Shellcode, sizeof m_Shellcode, PAGE_EXECUTE_READWRITE, &OldProtection)) { + if(VirtualProtect(m_Shellcode, sizeof m_Shellcode, PAGE_EXECUTE_READWRITE, &OldProtection)) + { *(uint32_t *)(&m_Shellcode[4]) = Index; } } - ByteArray SyscallManager::GetNtdllFromDisk() { + ByteArray SyscallManager::GetNtdllFromDisk() + { char SystemPath[MAX_PATH]; GetSystemDirectoryA(SystemPath, MAX_PATH); @@ -42,7 +46,8 @@ namespace Wrapper { } // Stolen :-) - uint64_t SyscallManager::GetRawOffsetByRva(IMAGE_SECTION_HEADER *SectionHeader, uint64_t Sections, uint64_t FileSize, uint64_t Rva) { + uint64_t SyscallManager::GetRawOffsetByRva(IMAGE_SECTION_HEADER *SectionHeader, uint64_t Sections, uint64_t FileSize, uint64_t Rva) + { IMAGE_SECTION_HEADER *Header = GetSectionByRva(SectionHeader, Sections, Rva); if(!Header) @@ -59,10 +64,12 @@ namespace Wrapper { return Offset; } - IMAGE_SECTION_HEADER *SyscallManager::GetSectionByRva(IMAGE_SECTION_HEADER *SectionHeader, uint64_t Sections, uint64_t Rva) { + IMAGE_SECTION_HEADER *SyscallManager::GetSectionByRva(IMAGE_SECTION_HEADER *SectionHeader, uint64_t Sections, uint64_t Rva) + { IMAGE_SECTION_HEADER *Header = SectionHeader; - for(size_t i{}; i < Sections; ++i, ++Header) { + for(size_t i{}; i < Sections; ++i, ++Header) + { uint64_t VirtualAddress = Header->VirtualAddress; uint64_t AddressBounds = VirtualAddress + Header->SizeOfRawData; @@ -74,9 +81,10 @@ namespace Wrapper { } // Sick macros, retard. - #define GetRvaPointer(Rva) (Buffer + GetRawOffsetByRva(SectionHeader, SectionCount, FileSize, Rva)) +#define GetRvaPointer(Rva) (Buffer + GetRawOffsetByRva(SectionHeader, SectionCount, FileSize, Rva)) - bool SyscallManager::Start() { + bool SyscallManager::Start() + { // Read contents of NTDLL. ByteArray Ntdll = GetNtdllFromDisk(); @@ -101,7 +109,7 @@ namespace Wrapper { if(!SectionHeader) return false; - + uint64_t ExportRva = NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; uint64_t ExportSize = NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; uint64_t ExportRaw = GetRawOffsetByRva(SectionHeader, SectionCount, FileSize, ExportRva); @@ -120,7 +128,8 @@ namespace Wrapper { return false; // Loop each exported symbol. - for(uint32_t n{}; n < ExportDirectory->NumberOfNames; ++n) { + for(uint32_t n{}; n < ExportDirectory->NumberOfNames; ++n) + { uint32_t NameRva = Names[n]; uint32_t FunctionRva = Functions[Ordinals[n]]; @@ -129,10 +138,11 @@ 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, "\x4C\x8B\xD1\xB8", 4)) + { uint32_t SyscallIndex = *(uint32_t *)(Buffer + FunctionRawOffset + 4); - + char *SyscallName = (char *)(Buffer + NameRawOffset); uint64_t SyscallNameHash = fnv::hash_runtime(SyscallName); diff --git a/csgo-loader/csgo-client/Security/SyscallManager.hpp b/csgo-loader/csgo-client/Security/SyscallManager.hpp index e154625..a9c67aa 100644 --- a/csgo-loader/csgo-client/Security/SyscallManager.hpp +++ b/csgo-loader/csgo-client/Security/SyscallManager.hpp @@ -11,9 +11,11 @@ using ByteArray = std::vector; -namespace Wrapper { +namespace Wrapper +{ // A stub used for our syscalls. - class SyscallStub { + class SyscallStub + { // The shellcode which executes a low latency system call. uint8_t m_Shellcode[11] = { 0x4C, 0x8B, 0xD1, // mov r10, rcx @@ -28,14 +30,16 @@ namespace Wrapper { // Sets the syscall index. void SetIndex(uint32_t Index); - __forceinline uintptr_t Get() { + __forceinline uintptr_t Get() + { return (uintptr_t)m_Shellcode; } }; // Manager for system calls. Used to iterate NTDLL for all syscall indices. // Read: https://www.evilsocket.net/2014/02/11/on-windows-syscall-mechanism-and-syscall-numbers-extraction-methods/ - class SyscallManager { + class SyscallManager + { // Reading NTDLL from disk because it cannot be modified // due to restrictions put in place by PatchGuard. ByteArray GetNtdllFromDisk(); @@ -54,7 +58,8 @@ namespace Wrapper { // Finds a syscall by hash. template < typename T > - T Find(uint64_t Hash) { + T Find(uint64_t Hash) + { return (T)m_Syscalls[Hash].Get(); } }; diff --git a/csgo-loader/csgo-client/UserExperience/UserInterface.cpp b/csgo-loader/csgo-client/UserExperience/UserInterface.cpp index f8f465f..af1b384 100644 --- a/csgo-loader/csgo-client/UserExperience/UserInterface.cpp +++ b/csgo-loader/csgo-client/UserExperience/UserInterface.cpp @@ -7,11 +7,15 @@ // Global accessor for the user interface. UserExperience::UserInterfacePtr UserInterface = std::make_unique(); -namespace UserExperience { - void OnDirectXFrame() { - if(g_d3d.run_frame(g_window.m_d3d_device)) { +namespace UserExperience +{ + void OnDirectXFrame() + { + if(g_d3d.run_frame(g_window.m_d3d_device)) + { g_d3d.begin(); - for(auto& it : d3d::sprites) { + for(auto& it : d3d::sprites) + { it->begin(g_window.m_d3d_device); } @@ -25,10 +29,12 @@ namespace UserExperience { constexpr float anim_step = 1.0f / 15.f; static float anim_time = 0.f; static bool flip = false; - if(anim_time == 1.0f) { + if(anim_time == 1.0f) + { flip = true; } - if(anim_time == 0.f) { + if(anim_time == 0.f) + { flip = false; } @@ -42,16 +48,19 @@ namespace UserExperience { GetWindowRect(g_window.get_hwnd(), &cur_rect); g_d3d.end(); - for(auto& it : d3d::sprites) { + for(auto& it : d3d::sprites) + { it->end(); } } } - bool UserInterface::Start() { + bool UserInterface::Start() + { bool result = g_window.create(); - - if(result) { + + if(result) + { std::this_thread::sleep_for(std::chrono::milliseconds(100)); g_window.add_on_frame(&OnDirectXFrame); } @@ -59,7 +68,8 @@ namespace UserExperience { return result; } - void UserInterface::RunUiFrame() { + void UserInterface::RunUiFrame() + { g_window.on_frame(); } } \ No newline at end of file diff --git a/csgo-loader/csgo-client/UserExperience/UserInterface.hpp b/csgo-loader/csgo-client/UserExperience/UserInterface.hpp index 332b042..bea8b45 100644 --- a/csgo-loader/csgo-client/UserExperience/UserInterface.hpp +++ b/csgo-loader/csgo-client/UserExperience/UserInterface.hpp @@ -5,24 +5,28 @@ #include #include -namespace UserExperience { +namespace UserExperience +{ // Execution states define a moment in the execution of the loader. // These may be changed externally by other threads. - enum ExecutionState : uint16_t { + enum ExecutionState : uint16_t + { EXECUTION_WAITING, // Displays the message 'please wait...'. EXECUTION_ERROR, // Displays an error. EXECUTION_LOG_IN, // Displays the log-in dialog. EXECUTION_CHOOSE // Displays the game selection dialog. }; - enum ErrorReason : uint16_t { + enum ErrorReason : uint16_t + { ERROR_GENERIC_ERROR, ERROR_INVALID_HWID, ERROR_SHADOW_BAN }; // Structure that holds global data that will be used by the UI. - struct UserExperienceData { + struct UserExperienceData + { // Holds the current execution state of the loader. ExecutionState m_ExecutionState = EXECUTION_WAITING; @@ -41,7 +45,8 @@ namespace UserExperience { }; // User experience handler. - class UserInterface { + class UserInterface + { public: UserExperienceData m_Data; @@ -51,7 +56,7 @@ namespace UserExperience { // Creates an UI thread, call only once. void RunUiFrame(); }; - + using UserInterfacePtr = std::unique_ptr; } diff --git a/csgo-loader/csgo-client/csgo-client.vcxproj b/csgo-loader/csgo-client/csgo-client.vcxproj index 9dc8b61..5c839dc 100644 --- a/csgo-loader/csgo-client/csgo-client.vcxproj +++ b/csgo-loader/csgo-client/csgo-client.vcxproj @@ -22,6 +22,8 @@ + + @@ -35,6 +37,8 @@ + + diff --git a/csgo-loader/csgo-client/csgo-client.vcxproj.filters b/csgo-loader/csgo-client/csgo-client.vcxproj.filters index 2040b2b..049be28 100644 --- a/csgo-loader/csgo-client/csgo-client.vcxproj.filters +++ b/csgo-loader/csgo-client/csgo-client.vcxproj.filters @@ -55,6 +55,12 @@ RemoteCode + + RemoteCode + + + RemoteCode + @@ -150,5 +156,11 @@ RemoteCode + + RemoteCode + + + RemoteCode + \ No newline at end of file -- cgit v1.2.3