From c0f1354a301ce2a2fc867a89fafdde4571c07c02 Mon Sep 17 00:00:00 2001 From: boris Date: Wed, 2 Jan 2019 21:11:03 +1300 Subject: 6IX9INE "Billy" (WSHH Exclusive - Official Music Video) --- csgo-loader/csgo-client/Security/Encryption.cpp | 17 ++- .../csgo-client/Security/RuntimeSecurity.cpp | 124 ++++++++++++++++----- .../csgo-client/Security/RuntimeSecurity.hpp | 25 ++++- 3 files changed, 121 insertions(+), 45 deletions(-) (limited to 'csgo-loader/csgo-client/Security') diff --git a/csgo-loader/csgo-client/Security/Encryption.cpp b/csgo-loader/csgo-client/Security/Encryption.cpp index 00b0fee..083460a 100644 --- a/csgo-loader/csgo-client/Security/Encryption.cpp +++ b/csgo-loader/csgo-client/Security/Encryption.cpp @@ -80,7 +80,7 @@ namespace Wrapper }; // Implementation of the AES256 encryption algorithm. - unsigned char rj_xtime(unsigned char x); + uint8_t rj_xtime(uint8_t x); Aes256::Aes256(const ByteArray& key) : m_key(ByteArray(key.size() > KEY_SIZE ? KEY_SIZE : key.size(), 0)) @@ -144,7 +144,7 @@ namespace Wrapper ByteArray::size_type Aes256::encrypt_start(const ByteArray::size_type plain_length, ByteArray& encrypted) { - VMProtectBegin("AESEncryptStart"); + VMProtectBeginUltra("AESEncryptStart"); m_remainingLength = plain_length; @@ -265,7 +265,7 @@ namespace Wrapper { unsigned char j; - VMProtectBegin("AESDecryptStart"); + VMProtectBeginUltra("AESDecryptStart"); m_remainingLength = encrypted_length; @@ -314,7 +314,7 @@ namespace Wrapper void Aes256::check_and_decrypt_buffer(ByteArray& plain) { - VMProtectBegin("AESDecryptBuffer"); + VMProtectBeginUltra("AESDecryptBuffer"); if(!m_decryptInitialized && m_buffer_pos == m_salt.size() + 1) { @@ -384,7 +384,7 @@ namespace Wrapper { unsigned char i; - VMProtectBegin("AESExpandKey"); + VMProtectBeginUltra("AESExpandKey"); m_rkey[0] = m_rkey[0] ^ sbox[m_rkey[29]] ^ (*rc); m_rkey[1] = m_rkey[1] ^ sbox[m_rkey[30]]; @@ -419,7 +419,7 @@ namespace Wrapper { unsigned char i; - VMProtectBegin("AESExpandKey"); + VMProtectBeginUltra("AESExpandKey"); for(i = 28; i > 16; i -= 4) { @@ -585,10 +585,7 @@ namespace Wrapper VMProtectEnd(); } - inline unsigned char rj_xtime(unsigned char x) - { - return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1); - } + inline uint8_t rj_xtime(uint8_t x) { return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1); } // Wrapper for the AES256 encryption algorithm. void Encryption::Start() diff --git a/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp b/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp index 572c9b1..7f528e3 100644 --- a/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp +++ b/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp @@ -209,6 +209,9 @@ namespace Security for(;;) { + if(VMProtectIsVirtualMachinePresent()) + SecurityCallback(STR("Malicious activity [Virtualized environment].")); + // Don't put too much stress on the CPU. Sleep(1); } @@ -227,36 +230,18 @@ namespace Security // Offset for x64 is 0x60 ; mov ..., qword ptr gs:[0x60] PEB *ProcessEnvBlock = (PEB *)__readgsqword(0x60); - //if(ProcessEnvBlock->BeingDebugged) - // SecurityCallback(__FUNCSIG__); + if(ProcessEnvBlock->BeingDebugged) + SecurityCallback(STR("Malicious activity [Debugging attempt].")); // TODO: Check for x64dbg window? - /* - ------------------------------ - HWND: 000305A4 - HWND->m_Class = "ID" - HWND->m_Text = "Immunity - ------------------------------ - HWND: 00060574 - HWND->m_Class = || NON CONSTANT || - HWND->m_Text = "x64dbg" - ------------------------------ - HWND: 002C0680 - HWND->m_Class = || NON CONSTANT || - HWND->m_Text = "Progress Telerik Fiddler Web Debugger" - ------------------------------ - HWND: 000406E4 - HWND->m_Class = "OLLYDBG" - HWND->m_Text = "OllyDbg" - ------------------------------ - */ using WindowParams = std::pair; static std::vector BlackListedWindows = { {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 + {STR("Qt5QWindowIcon"), STR("x64dbg")}, // x64dbg + {STR("Qt5QWindowIcon"), STR("x32dbg")}, // x32dbg + {STR("Qt5QWindowIcon"), STR("The Wireshark Network Analyzer")}, // x32dbg + {STR("OLLYDBG"), STR("OllyDbg")}, // OllyDbg + {nullptr, STR("Progress Telerik Fiddler Web Debugger")}, // Telerik Fiddler }; for(auto &It : BlackListedWindows) @@ -284,7 +269,7 @@ namespace Security STR("NPF"), // WireShark / WinPCAP STR("acker"), // Process Hacker STR("CEDRI"), // Cheat Engine - //STR("VBox") // VirtualBox + //STR("VBox") // VirtualBox }; static const char *BlackListReasons[] = { @@ -303,7 +288,11 @@ namespace Security if(K32EnumDeviceDrivers(DriverList, sizeof DriverList, &Needed)) { if(Needed > sizeof DriverList) - ERROR_ASSERT(STR("[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]; @@ -330,6 +319,12 @@ namespace Security { for(;;) { + if(!VMProtectIsProtected()) + SecurityCallback(STR("Malicious activity [Tampering].")); + + if(!VMProtectIsValidImageCRC()) + SecurityCallback(STR("Malicious activity [Tampering].")); + // Don't put too much stress on the CPU. Sleep(1); } @@ -358,22 +353,93 @@ namespace Security constexpr uintptr_t KUSER_SHARED_DATA = 0x7FFE0000; + __forceinline uint64_t get_hdd_hash() { + STORAGE_PROPERTY_QUERY query{ }; + STORAGE_DESCRIPTOR_HEADER desc_header{ }; + STORAGE_DEVICE_DESCRIPTOR* device_descriptor{ }; + HANDLE device; + DWORD bytes_returned; + uint8_t* out_buffer; + + const wchar_t* device_path = L"\\??\\PhysicalDrive0"; + device = CreateFileA("\\\\.\\PhysicalDrive0", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if(!device) return uint64_t{ }; + + query.PropertyId = StorageDeviceProperty; + query.QueryType = PropertyStandardQuery; + + if(!DeviceIoControl(device, IOCTL_STORAGE_QUERY_PROPERTY, + &query, sizeof(STORAGE_PROPERTY_QUERY), + &desc_header, sizeof(STORAGE_DESCRIPTOR_HEADER), + &bytes_returned, 0)) { + return uint64_t{ }; + } + + out_buffer = new uint8_t[desc_header.Size]; + memset(out_buffer, 0, desc_header.Size); + + if(!DeviceIoControl(device, IOCTL_STORAGE_QUERY_PROPERTY, + &query, sizeof(STORAGE_PROPERTY_QUERY), + out_buffer, desc_header.Size, + &bytes_returned, 0)) { + delete[] out_buffer; + return uint64_t{ }; + } + + device_descriptor = (STORAGE_DEVICE_DESCRIPTOR*)out_buffer; + if(device_descriptor->SerialNumberOffset) { + std::string serial_num = reinterpret_cast( + out_buffer + device_descriptor->SerialNumberOffset); + + delete[] out_buffer; + CloseHandle(device); + return fnv::hash_runtime(serial_num.c_str()); + } + + return 0; + } + HardwareIdentifier RuntimeSecurity::GetHardwareId() { + VMProtectBeginMutation("HardwareIdentifier"); + HardwareIdentifier Identifier{}; // CPU information Identifier.m_CpuCount = *(uint32_t *)(KUSER_SHARED_DATA + 0x3C0); Identifier.m_CpuArchitecture = *(uint16_t *)(KUSER_SHARED_DATA + 0x26A); - // CPU features + // HDD serial number + Identifier.m_HardDiskSerialHash = get_hdd_hash(); // Safe-mode Identifier.m_SpecialMode[0] = *(uint8_t *)(KUSER_SHARED_DATA + 0x2EC); // Test-signing mode + static auto ZwQuerySystemInformation = Syscalls->Find(FNV("ZwQuerySystemInformation")); + + // 0x02 CODEINTEGRITY_OPTION_TESTSIGN + // 0x20 CODEINTEGRITY_OPTION_TEST_BUILD + // 0x80 CODEINTEGRITY_OPTION_DEBUGMODE_ENABLED + + CodeIntegrityInformation Info{ sizeof CodeIntegrityInformation }; + NTSTATUS Status = ZwQuerySystemInformation(0x67, &Info, sizeof Info, nullptr); + + if(NT_ERROR(Status)) + ERROR_ASSERT(STR("[00CF:%08x] Critical execution error."), Status); + + if(Info.m_Options & 0x02) + Identifier.m_SpecialMode[1] = true; + + if(Info.m_Options & 0x20) + Identifier.m_SpecialMode[2] = true; + + if(Info.m_Options & 0x40) + Identifier.m_SpecialMode[3] = true; + + VMProtectEnd(); - return HardwareIdentifier{}; + return Identifier; } #pragma optimize("", off) diff --git a/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp b/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp index 08e6490..06df3bf 100644 --- a/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp +++ b/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp @@ -10,6 +10,9 @@ #include #include +// IOCTL +#include + // EnumDeviceDrivers #include @@ -47,6 +50,19 @@ namespace Security { + // Sigh.. + struct CodeIntegrityInformation { + uint32_t m_Size; + uint32_t m_Options; + }; + + enum SpecialMode { + SAFE_MODE, + TEST_SIGN_MODE, + TEST_BUILD_MODE, + DEBUGGING_MODE + }; + // Hardware ID structure (this is hashed and sent to server, but it's easier to use it // this way internally) struct HardwareIdentifier @@ -54,15 +70,12 @@ namespace Security // Generic CPU information. uint16_t m_CpuArchitecture; uint32_t m_CpuCount; - - // Contains list of CPU features. - char m_CpuFeatures[64]; - + // Hash of the hard disk serial identifier. - uint32_t m_HardDiskSerialHash; + uint64_t m_HardDiskSerialHash; // Safe-mode/Test-signing mode status - uint8_t m_SpecialMode[2]; + uint8_t m_SpecialMode[4]; }; // This class implements the runtime security system. -- cgit v1.2.3