diff options
Diffstat (limited to 'csgo-loader/csgo-client/Security')
| -rw-r--r-- | csgo-loader/csgo-client/Security/Encryption.cpp | 17 | ||||
| -rw-r--r-- | csgo-loader/csgo-client/Security/RuntimeSecurity.cpp | 124 | ||||
| -rw-r--r-- | csgo-loader/csgo-client/Security/RuntimeSecurity.hpp | 25 |
3 files changed, 121 insertions, 45 deletions
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<const char *, const char *>;
static std::vector<WindowParams> 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<const char*>( + 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<long(__stdcall *)(uint32_t, void *, uint32_t, uint32_t *)>(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 <windows.h>
#include <winternl.h>
+// IOCTL
+#include <winioctl.h>
+
// EnumDeviceDrivers
#include <psapi.h>
@@ -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.
|
