summaryrefslogtreecommitdiff
path: root/csgo-loader/csgo-client
diff options
context:
space:
mode:
authorboris <wzn@moneybot.cc>2019-01-03 16:51:40 +1300
committerboris <wzn@moneybot.cc>2019-01-03 16:51:40 +1300
commite1f048c8f922613aec1f63791c2191e55cbd5132 (patch)
tree887f57c58673e775bff8c1df3f23943ef8ddd6cd /csgo-loader/csgo-client
parentc0f1354a301ce2a2fc867a89fafdde4571c07c02 (diff)
ricardo milos :DDDD::D:D:D:
Diffstat (limited to 'csgo-loader/csgo-client')
-rw-r--r--csgo-loader/csgo-client/Client.cpp14
-rw-r--r--csgo-loader/csgo-client/Client.hpp2
-rw-r--r--csgo-loader/csgo-client/Login/RemoteLogin.cpp19
-rw-r--r--csgo-loader/csgo-client/Networking/TCPClient.cpp40
-rw-r--r--csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp63
-rw-r--r--csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp22
-rw-r--r--csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp57
-rw-r--r--csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp23
-rw-r--r--csgo-loader/csgo-client/Security/RuntimeSecurity.cpp106
-rw-r--r--csgo-loader/csgo-client/Security/RuntimeSecurity.hpp8
-rw-r--r--csgo-loader/csgo-client/loader.err1
11 files changed, 314 insertions, 41 deletions
diff --git a/csgo-loader/csgo-client/Client.cpp b/csgo-loader/csgo-client/Client.cpp
index 7285b6b..8972410 100644
--- a/csgo-loader/csgo-client/Client.cpp
+++ b/csgo-loader/csgo-client/Client.cpp
@@ -24,11 +24,13 @@
int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow)
{
- WRAP_IF_DEBUG(Utils::OpenConsole());
+ WRAP_IF_DEBUG(
+ Utils::OpenConsole();
+ );
///////////////////////////////////////////////////////////////
- VMProtectBeginMutation("EntryPoint");
+ //VMProtectBeginMutation("EntryPoint");
///////////////////////////////////////////////////////////////
@@ -49,10 +51,8 @@ int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow)
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(STR("[000F:00001A00] Failed to initialize. Please contact an administrator."));
- );
+ if(!Protection->Start())
+ ERROR_ASSERT(STR("[000F:00001A00] Failed to initialize. Please contact an administrator."));
// Wait for connection.
UserInterface->m_Data.m_ExecutionState = UserExperience::EXECUTION_WAITING;
@@ -90,7 +90,7 @@ int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow)
///////////////////////////////////////////////////////////////
- VMProtectEnd();
+ //VMProtectEnd();
///////////////////////////////////////////////////////////////
}
diff --git a/csgo-loader/csgo-client/Client.hpp b/csgo-loader/csgo-client/Client.hpp
index 0f89669..0f05a34 100644
--- a/csgo-loader/csgo-client/Client.hpp
+++ b/csgo-loader/csgo-client/Client.hpp
@@ -38,6 +38,6 @@ namespace Utils
// :^)
SetConsoleTitleA(STR("moneyclient $"));
- printf(STR("[DEBUG] Hello!\n"));
+ printf(STR("[DEBUG] Ready\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 7942c3b..4a46da3 100644
--- a/csgo-loader/csgo-client/Login/RemoteLogin.cpp
+++ b/csgo-loader/csgo-client/Login/RemoteLogin.cpp
@@ -21,10 +21,11 @@ namespace Login
Security::HardwareIdentifier HardwareId = Protection->GetHardwareId();
WRAP_IF_DEBUG(
- printf("[DEBUG] LoginTransactionStart\n");
+ printf("[DEBUG] RemoteLoginTransaction Start\n");
printf("[DEBUG] Processor count: %d\n", HardwareId.m_CpuCount);
printf("[DEBUG] Processor architecture: %d\n", HardwareId.m_CpuArchitecture);
printf("[DEBUG] Hard-drive Serial: %llx\n", HardwareId.m_HardDiskSerialHash);
+ printf("[DEBUG] Detail: %s\n", HardwareId.m_CustomDetail);
for(int i = 0; i < 4; ++i)
printf("[DEBUG] Safety check #%d: %s\n", i, HardwareId.m_SpecialMode[i] ? "TRUE" : "FALSE");
@@ -32,6 +33,10 @@ namespace Login
m_Header.m_HardwareId = fnv::hash_runtime_data((void *)(&HardwareId), sizeof Security::HardwareIdentifier);
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] Hardware-ID Hash: %llx\n", m_Header.m_HardwareId);
+ );
+
// TODO: Verify integrity of system.
// 0 for integrity passed, random bit for failure
m_Header.m_IntegrityBit1 = HardwareId.m_SpecialMode[Security::DEBUGGING_MODE];
@@ -52,6 +57,10 @@ namespace Login
{
RemoteLoginResponse ServerResponse = *(RemoteLoginResponse *)&RawResponse[0];
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] RemoteLoginTransaction Finish: %02x\n", ServerResponse);
+ );
+
switch(ServerResponse)
{
case RemoteLoginResponse::ACCESS_SPECIAL_USER:
@@ -60,16 +69,16 @@ namespace Login
case RemoteLoginResponse::ACCESS_AUTHORISED:
return true;
case RemoteLoginResponse::OUTDATED_CLIENT:
- INFO_ASSERT(STR("[000A:%llx] Your client is outdated.\nPlease download the latest client at 'moneybot.cc'."), m_Header.m_HardwareId ^ ServerResponse);
+ ERROR_ASSERT(STR("[000A:%llx] Your client is outdated.\nPlease download the latest client at 'moneybot.cc'."), m_Header.m_HardwareId ^ ServerResponse);
break;
case RemoteLoginResponse::USER_BANNED:
- INFO_ASSERT(STR("[000D:%llx] Your account is banned.\nPlease contact 'admin@moneybot.cc' for additional information."), m_Header.m_HardwareId ^ ServerResponse);
+ ERROR_ASSERT(STR("[000D:%llx] Your account is banned.\nPlease contact 'admin@moneybot.cc' for additional information."), m_Header.m_HardwareId ^ ServerResponse);
break;
case RemoteLoginResponse::INVALID_HARDWARE:
- INFO_ASSERT(STR("[000D:%llx] Your Hardware-ID is incorrect!\nPlease contact a staff member."), m_Header.m_HardwareId ^ ServerResponse);
+ ERROR_ASSERT(STR("[000D:%llx] Your Hardware-ID is incorrect!\nPlease contact a staff member."), m_Header.m_HardwareId ^ ServerResponse);
break;
case RemoteLoginResponse::INVALID_CREDENTIALS:
- INFO_ASSERT(STR("[000C:%llx] Your credentials are invalid. Please check your spelling and try again."), m_Header.m_HardwareId ^ ServerResponse);
+ ERROR_ASSERT(STR("[000C:%llx] 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:
diff --git a/csgo-loader/csgo-client/Networking/TCPClient.cpp b/csgo-loader/csgo-client/Networking/TCPClient.cpp
index c20c831..c974f88 100644
--- a/csgo-loader/csgo-client/Networking/TCPClient.cpp
+++ b/csgo-loader/csgo-client/Networking/TCPClient.cpp
@@ -13,6 +13,22 @@ namespace Networking
if(Result == -1)
INFO_ASSERT(STR("[000F:00002B00] Server closed the connection unexpectedly."));
+
+ WRAP_IF_DEBUG(
+ size_t BreakIndex = 0;
+
+ printf("[DEBUG] Sending data (%zd bytes):\n[DEBUG] ", Bytes.size());
+
+ for(auto &Byte : Bytes)
+ {
+ printf("%02x ", Byte);
+
+ if(BreakIndex++ % 8 == 0)
+ printf("\n[DEBUG] ");
+ }
+
+ printf("\n");
+ );
}
ByteArray TCPClient::ReceiveRawBytes()
@@ -40,6 +56,22 @@ namespace Networking
break;
}
+ WRAP_IF_DEBUG(
+ size_t BreakIndex = 0;
+
+ printf("[DEBUG] Receiving data (%zd bytes):\n[DEBUG] ", ReceivedBytes.size());
+
+ for(auto &Byte : ReceivedBytes)
+ {
+ printf("%02x ", Byte);
+
+ if(BreakIndex++ % 8 == 0)
+ printf("\n[DEBUG] ");
+ }
+
+ printf("\n");
+ );
+
return ReceivedBytes;
}
@@ -103,11 +135,19 @@ namespace Networking
return false;
// Initialise encryption wrapper.
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] Attempting to handshake with server...\n");
+ );
+
ByteArray EncryptionKey = ReceiveRawBytes();
if(EncryptionKey.empty())
return false;
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] Server handshake successful!\n");
+ )
+
std::memcpy(m_EncryptionKey, EncryptionKey.data(), EncryptionKey.size());
return true;
diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp b/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp
index 5a42b6c..21d7851 100644
--- a/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp
+++ b/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.cpp
@@ -2,5 +2,68 @@
namespace RemoteCode
{
+ uint8_t ShellcodeStub[] = {
+ 0x55,
+ 0x8B, 0xEC,
+ 0x56,
+ 0x8B, 0x75, 0x08,
+ 0x57,
+ 0x80, 0x3E, 0x00,
+ 0x74, 0x2F,
+ 0x8B, 0x7E, 0x14,
+ 0x8D, 0x45, 0x08,
+ 0x50,
+ 0x8B, 0x46, 0x18,
+ 0x81, 0xC7, 0xA8, 0x00, 0x00, 0x00,
+ 0x6A, 0x40,
+ 0x6A, 0x04,
+ 0x57,
+ 0xFF, 0xD0,
+ 0x84, 0xC0,
+ 0x74, 0x4D,
+ 0x8B, 0x46, 0x10,
+ 0x89, 0x07,
+ 0x8D, 0x45, 0x08,
+ 0x50,
+ 0xFF, 0x75, 0x08,
+ 0x8B, 0x46, 0x18,
+ 0x6A, 0x04,
+ 0x57,
+ 0xFF, 0xD0,
+
+ 0x8B, 0x46, 0x08,
+ 0x85, 0xC0,
+ 0x74, 0x09,
+ 0x6A, 0x00,
+ 0x6A, 0x01,
+ 0xFF, 0x76, 0x04,
+ 0xFF, 0xD0,
+ 0x53,
+ 0x8B, 0x5E, 0x0C,
+ 0x85, 0xDB,
+ 0x74, 0x20,
+ 0x8B, 0x5B, 0x0C,
+ 0x33, 0xFF,
+ 0x8B, 0x03,
+ 0x85, 0xC0,
+ 0x74, 0x15,
+ 0x90,
+
+ 0x6A, 0x00,
+ 0x6A, 0x01,
+ 0xFF, 0x76, 0x04,
+ 0xFF, 0xD0,
+ 0x8B, 0x44, 0xBB, 0x04,
+ 0x8D, 0x7F, 0x01,
+ 0x85, 0xC0,
+ 0x75, 0xEC,
+
+ 0x5B,
+
+ 0x5F,
+ 0x5E,
+ 0x5D,
+ 0xC2, 0x04, 0x00
+ };
} \ No newline at end of file
diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp b/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp
index 964d055..84021c6 100644
--- a/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp
+++ b/csgo-loader/csgo-client/RemoteCode/RemoteCodeClient.hpp
@@ -6,6 +6,28 @@ namespace RemoteCode
{
class RemoteCodeClient
{
+ using MemProtect = bool(__stdcall *)(void *, size_t, uint32_t, uint32_t *);
+ struct ShellcodeParameters
+ {
+ // Specifies whether or not the thread hijacking
+ // exploit will be used for code execution.
+ uint8_t m_ThreadExploit;
+
+ // Address of the module allocation base
+ uintptr_t m_AllocationBase;
+
+ // Specifies the entry-point / optional TLS directory
+ // to invoke.
+ uintptr_t m_EntryPoint;
+ uintptr_t m_TlsDirectory;
+
+ // Thread hijacking (original address & VMT)
+ uintptr_t m_ThreadOriginal;
+ uintptr_t m_ThreadVirtual;
+
+ // Function parameters that will be passed
+ MemProtect m_ProtectMemory;
+ };
};
} \ No newline at end of file
diff --git a/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp b/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp
index 6699a9e..2e5d216 100644
--- a/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp
+++ b/csgo-loader/csgo-client/RemoteCode/RemoteInjectionClient.hpp
@@ -5,8 +5,65 @@
namespace RemoteCode
{
+ // Used for TransactionStart
+ using ImportedModule = char[64];
+ using ImportList = std::vector<ImportedModule>;
+
+ // Used for TransactionContinue
+ struct ExportedFunction
+ {
+ // I've never seen modules / functions with names
+ // that were larger than 64 characters.
+ char m_Module[64];
+ char m_Function[64];
+
+ // Address of exported module / function
+ uintptr_t m_ModuleAddress;
+ uintptr_t m_FunctionAddress;
+ };
+
+ using ExportList = std::vector<ExportedFunction>;
+
+ // Used for TransactionCommit
+ struct RemoteInjectionHeader
+ {
+ // Used to decrypt the cheat header (first 1000 bytes of image sent back).
+ uint8_t m_HeaderKey;
+
+ // Used to call entrypoint/TLS callbacks.
+ uintptr_t m_EntryPoint;
+ uintptr_t m_TlsDirectory;
+ };
+
+ struct RemoteInjectionCode
+ {
+ RemoteInjectionHeader m_Header;
+
+ // Actual injection code.
+ ByteArray m_Code;
+ };
+
+ // Implementation of client mapping code
class RemoteInjectionClient
{
+ RemoteInjectionHeader m_Header;
+ RemoteProcess m_Process;
+
+ public:
+ // Receive hash of selected cheat.
+ // Reply with size of image to allocate.
+ ByteArray Start(ByteArray &Response);
+
+ // Receive client header, send over list of imported functions
+ ByteArray TransactionStart(ByteArray &Response);
+
+ // Receive list of modules & export addresses
+ ByteArray TransactionContinue(ByteArray &Response);
+
+ // Write the file to the
+ void TransactionCommit(ByteArray &Response);
+ RemoteProcess GetProcess() { return m_Process; }
+ RemoteInjectionHeader GetHeader() { return m_Header; }
};
} \ 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 abed829..1bbfed0 100644
--- a/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp
+++ b/csgo-loader/csgo-client/RemoteCode/RemoteProcess.cpp
@@ -29,6 +29,10 @@ namespace RemoteCode
m_ProcessId = ProcessEntry.th32ProcessID;
m_Process = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessEntry.th32ProcessID);
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] Found process \"%s\" -> %p", ProcessEntry.szExeFile, m_Process);
+ );
+
if(!m_Process)
ERROR_ASSERT(STR("[000G:%08x] There was an error with accessing a process."), GetLastError());
@@ -45,9 +49,13 @@ namespace RemoteCode
static auto ZwReadVirtualMemory = Syscalls->Find<long(__stdcall *)(void *, void *, void *, size_t, void *)>(FNV("ZwReadVirtualMemory"));
NTSTATUS Status = ZwReadVirtualMemory(m_Process, Address, Data, SizeOfData, nullptr);
-
+
if(NT_ERROR(Status))
ERROR_ASSERT(STR("[00DF:%08x] There was an error with accessing a process."), Status);
+
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] Read %zd bytes from process\n", SizeOfData);
+ );
}
void RemoteProcess::WriteMemoryWrapper_Internal(void *Address, void *Data, size_t SizeOfData)
@@ -58,6 +66,10 @@ namespace RemoteCode
if(NT_ERROR(Status))
ERROR_ASSERT(STR("[00DF:%08x] There was an error with accessing a process."), Status);
+
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] Wrote %zd bytes to process\n", SizeOfData);
+ );
}
void *RemoteProcess::Allocate(size_t AllocationSize)
@@ -78,6 +90,10 @@ namespace RemoteCode
if(NT_ERROR(Status))
ERROR_ASSERT(STR("[00DF:%08x] There was an error with accessing a process."), Status);
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] Allocated page at %p (%zd bytes)\n", AllocationAddress, AllocationSize);
+ );
+
return AllocationAddress;
}
@@ -101,6 +117,11 @@ namespace RemoteCode
ERROR_ASSERT(STR("[00DF:00001C00] An integrity check failed."));
CloseHandle(Toolhelp);
+
+ WRAP_IF_DEBUG(
+ printf("[DEBUG] Found module \"%s\" at %p\n", ModuleEntry.szModule, ModuleEntry.hModule);
+ );
+
return RemoteModule(ModuleEntry.hModule);
}
}
diff --git a/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp b/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp
index 7f528e3..6054790 100644
--- a/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp
+++ b/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp
@@ -44,6 +44,25 @@ namespace Security
return oOpenProcess(AccessLevel, Inherit, ProcessId);
}
+
+ decltype(&FindWindowA) oFindWindow;
+ HWND __stdcall Hooked_FindWindow(const char *Class, const char *Text)
+ {
+ // Determine where the return address of the function actually points.
+ void *Address = _ReturnAddress();
+ MEMORY_BASIC_INFORMATION Query = Protection->QueryMemory(Address);
+
+ // If the return address points outside of the loader module,
+ // fail the function.
+ HMODULE ReturnModule = (HMODULE)Query.AllocationBase;
+ HMODULE LoaderModule = GetModuleHandleA(NULL);
+
+ if(ReturnModule != LoaderModule)
+ return []() { Protection->SecurityCallback(STR("Malicious activity [Tampering].")); return HWND{}; }();
+
+ return oFindWindow(Class, Text);
+ }
+
decltype(&ExitProcess) oExitProcess;
void __stdcall Hooked_ExitProcess(DWORD ExitCode)
{
@@ -62,7 +81,6 @@ namespace Security
decltype(&recv) oWSARecv;
int __stdcall Hooked_WSARecv(SOCKET Socket, char *Buffer, int Length, int Flags)
{
-
// Determine where the return address of the function actually points.
void *Address = _ReturnAddress();
MEMORY_BASIC_INFORMATION Query = Protection->QueryMemory(Address);
@@ -86,7 +104,6 @@ namespace Security
decltype(&send) oWSASend;
int __stdcall Hooked_WSASend(SOCKET Socket, char *Buffer, int Length, int Flags)
{
-
// Determine where the return address of the function actually points.
void *Address = _ReturnAddress();
MEMORY_BASIC_INFORMATION Query = Protection->QueryMemory(Address);
@@ -129,6 +146,9 @@ namespace Security
// Apply any hooks.
SafeCallTo(MH_CreateHook(&OpenProcess, Hooked_OpenProcess, (void **)&oOpenProcess));
SafeCallTo(MH_EnableHook(&OpenProcess));
+
+ SafeCallTo(MH_CreateHook(&FindWindowA, Hooked_FindWindow, (void **)&oFindWindow));
+ SafeCallTo(MH_EnableHook(&FindWindowA));
SafeCallTo(MH_CreateHook(&ExitProcess, Hooked_ExitProcess, (void **)&oExitProcess));
SafeCallTo(MH_EnableHook(&ExitProcess));
@@ -148,7 +168,7 @@ namespace Security
void RuntimeSecurity::PatchDebugFunctions()
{
- HMODULE Module = GetModuleHandleA("ntdll.dll");
+ HMODULE Module = GetModuleHandleA(STR("ntdll.dll"));
if(!Module)
ERROR_ASSERT(STR("[000F:00001A00] Failed to initialize. Please contact an administrator."));
@@ -261,6 +281,8 @@ namespace Security
void RuntimeSecurity::CheckForDrivers()
{
+ VMProtectBeginMutation("DriverThread");
+
// TODO: Check for disallowed drivers
for(;;)
{
@@ -313,21 +335,41 @@ namespace Security
// Don't put too much stress on the CPU.
Sleep(1);
}
+
+ VMProtectEnd();
}
void RuntimeSecurity::CheckForTampering()
{
+ VMProtectBeginMutation("TamperThread");
+
for(;;)
{
- if(!VMProtectIsProtected())
- SecurityCallback(STR("Malicious activity [Tampering]."));
+ if(m_Identifier.m_SpecialMode[SAFE_MODE])
+ ERROR_ASSERT(STR("[000F:00003D00] This program cannot run under Safe Mode.\nPlease reboot your system and select 'Normal Mode'."));
+
+ if(m_Identifier.m_SpecialMode[TEST_SIGN_MODE])
+ ERROR_ASSERT(STR("[000F:00003D00] This program cannot run under Test Signing Mode.\nPlease reboot your system and select 'Normal Mode'."));
+
+ if(m_Identifier.m_SpecialMode[DEBUGGING_MODE])
+ SecurityCallback(STR("Malicious activity [Plausible]."));
+
+ if(m_Identifier.m_SpecialMode[TEST_BUILD_MODE])
+ SecurityCallback(STR("Malicious activity [Plausible]."));
- if(!VMProtectIsValidImageCRC())
- SecurityCallback(STR("Malicious activity [Tampering]."));
+ // Check if the file was unpacked.
+ //if(!VMProtectIsProtected())
+ // SecurityCallback(STR("Malicious activity [Tampering]."));
+
+ // Check if the image in memory was partially unpacked or patched.
+ //if(!VMProtectIsValidImageCRC())
+ // SecurityCallback(STR("Malicious activity [Tampering]."));
// Don't put too much stress on the CPU.
Sleep(1);
}
+
+ VMProtectEnd();
}
#pragma optimize("", on)
@@ -335,21 +377,6 @@ namespace Security
// The following functions are exposed publicly.
///////////////////////////////////////////////////////////
- bool RuntimeSecurity::Start()
- {
- // If hooking API functions fails, exit the program.
- if(!ApplyApiHooks())
- return false;
-
- // Dispatch threads before patching NtContinue & co.
- DispatchSecurityThreads();
-
- // Patch DbgUiRemoteBreakin, DbgBreakPoint, NtContinue
- // This also fucks up detours for some reason... only extra protection :-)
- PatchDebugFunctions();
-
- return true;
- }
constexpr uintptr_t KUSER_SHARED_DATA = 0x7FFE0000;
@@ -399,14 +426,14 @@ namespace Security
return 0;
}
- HardwareIdentifier RuntimeSecurity::GetHardwareId()
+ void RuntimeSecurity::SetupSystemIdentifier()
{
- VMProtectBeginMutation("HardwareIdentifier");
+ VMProtectBeginUltra("SetupHWID");
HardwareIdentifier Identifier{};
// CPU information
- Identifier.m_CpuCount = *(uint32_t *)(KUSER_SHARED_DATA + 0x3C0);
+ Identifier.m_CpuCount = *(uint32_t *)(KUSER_SHARED_DATA + 0x3C0);
Identifier.m_CpuArchitecture = *(uint16_t *)(KUSER_SHARED_DATA + 0x26A);
// HDD serial number
@@ -425,8 +452,11 @@ namespace Security
CodeIntegrityInformation Info{ sizeof CodeIntegrityInformation };
NTSTATUS Status = ZwQuerySystemInformation(0x67, &Info, sizeof Info, nullptr);
+ if(!VMProtectGetCurrentHWID(Identifier.m_CustomDetail, 256))
+ ERROR_ASSERT(STR("[000F:00001A00] Failed to initialize. Please contact an administrator."));
+
if(NT_ERROR(Status))
- ERROR_ASSERT(STR("[00CF:%08x] Critical execution error."), Status);
+ ERROR_ASSERT(STR("[000F:00001A00] Failed to initialize. Please contact an administrator."));
if(Info.m_Options & 0x02)
Identifier.m_SpecialMode[1] = true;
@@ -437,11 +467,33 @@ namespace Security
if(Info.m_Options & 0x40)
Identifier.m_SpecialMode[3] = true;
+ m_Identifier = Identifier;
+
VMProtectEnd();
+ }
+
+ bool RuntimeSecurity::Start()
+ {
+ WRAP_IF_RELEASE(
+ // If hooking API functions fails, exit the program.
+ if(!ApplyApiHooks())
+ return false;
- return Identifier;
+ // Dispatch threads before patching NtContinue & co.
+ DispatchSecurityThreads();
+
+ // Patch DbgUiRemoteBreakin, DbgBreakPoint, NtContinue
+ // This also fucks up detours for some reason... only extra protection :-)
+ PatchDebugFunctions();
+ );
+
+ SetupSystemIdentifier();
+
+ return true;
}
+ HardwareIdentifier RuntimeSecurity::GetHardwareId() { return m_Identifier; }
+
#pragma optimize("", off)
__declspec(noinline) MEMORY_BASIC_INFORMATION RuntimeSecurity::QueryMemory(void *Address)
diff --git a/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp b/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp
index 06df3bf..6446a08 100644
--- a/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp
+++ b/csgo-loader/csgo-client/Security/RuntimeSecurity.hpp
@@ -74,6 +74,9 @@ namespace Security
// Hash of the hard disk serial identifier.
uint64_t m_HardDiskSerialHash;
+ // VMP HWID
+ char m_CustomDetail[256];
+
// Safe-mode/Test-signing mode status
uint8_t m_SpecialMode[4];
};
@@ -87,6 +90,8 @@ namespace Security
// any potentially malicious actions from users.
class RuntimeSecurity
{
+ HardwareIdentifier m_Identifier;
+
protected:
// Applies necessary API hooks.
bool ApplyApiHooks();
@@ -97,6 +102,9 @@ namespace Security
// Dispatches security threads.
void DispatchSecurityThreads();
+ // Grabs all hardware data.
+ void SetupSystemIdentifier();
+
// The following functions are used in security threads to run checks.
void CheckForVirtualMachine();
diff --git a/csgo-loader/csgo-client/loader.err b/csgo-loader/csgo-client/loader.err
new file mode 100644
index 0000000..c3b6aec
--- /dev/null
+++ b/csgo-loader/csgo-client/loader.err
@@ -0,0 +1 @@
+Malicious activity [Debugging attempt]. \ No newline at end of file