From d120e7b489adc42a4489c63305413dfe52ed8bbf Mon Sep 17 00:00:00 2001 From: auth12 <67507608+auth12@users.noreply.github.com> Date: Thu, 6 Aug 2020 15:33:18 +0100 Subject: Improved CPU usage drastically. Switched to directx9. Reduced RAM usage by only remapping modules from a blacklist. --- client/src/security/security.cpp | 110 ++++++++++++++++++++------------------- client/src/security/security.h | 58 ++++++++++++++++++++- 2 files changed, 114 insertions(+), 54 deletions(-) (limited to 'client/src/security') diff --git a/client/src/security/security.cpp b/client/src/security/security.cpp index f0adfe9..b1e2b93 100644 --- a/client/src/security/security.cpp +++ b/client/src/security/security.cpp @@ -6,71 +6,36 @@ #include "../util/syscalls.h" #include "security.h" -#define SEC_NO_CHANGE 0x00400000 - std::unordered_map> security::parsed_images; void security::thread(tcp::client& client) { - std::list whitelist = { "d3dcompiler_43.dll", "xinput1_3.dll" }; - - std::unordered_map images; - std::unordered_map> raw_images; - pe::get_all_modules(images); - - for (auto& [name, vi] : images) { - auto it = std::find(whitelist.begin(), whitelist.end(), name); - if (it != whitelist.end()) { - continue; - } - - std::vector raw; - char path[MAX_PATH]; - GetModuleFileNameA(GetModuleHandleA(name.c_str()), path, MAX_PATH); - - if (!io::read_file(path, raw)) { - io::log("failed to read {}.", name); - continue; - } - - raw_images[name] = pe::image(raw); - } + if (!init()) { + io::log_error("failed to init security thread."); - for (auto& [name, image] : raw_images) { - std::vector mem; + client.shutdown(); - image.copy(mem); - image.relocate(mem, uintptr_t(GetModuleHandleA(name.c_str()))); - - for (auto& [mod, funcs] : image.imports()) { - std::string mod_name{ mod }; - g_apiset.find(mod_name); - - for (auto& func : funcs) { - *reinterpret_cast(&mem[func.rva]) = uintptr_t(GetProcAddress(GetModuleHandleA(mod_name.c_str()), func.name.c_str())); - } - } - - parsed_images[name] = mem; + return; } - raw_images.clear(); - images.clear(); - while (client) { if (client.session_id.empty()) { continue; } + bool ret = check(); + io::log("check returned {}.", ret); + std::unordered_map loaded_images; - pe::get_all_modules(loaded_images); + if (!pe::get_all_modules(loaded_images)) { + io::log_error("failed to get loaded modules."); + + client.shutdown(); + + break; + } std::vector patches; for (auto& [name, limage] : loaded_images) { - auto it = std::find(whitelist.begin(), whitelist.end(), name); - if (it != whitelist.end()) { - continue; - } - auto& parsed = parsed_images[name]; if (parsed.empty()) { continue; @@ -85,12 +50,12 @@ void security::thread(tcp::client& client) { continue; } - /*int ret = std::memcmp(&parsed[sec.va], reinterpret_cast(start + sec.va), sec.size); + int ret = std::memcmp(&parsed[sec.va], reinterpret_cast(start + sec.va), sec.size); if (ret != 0) { io::log("found patch in {}.", name); - }*/ + } - auto sec_start = reinterpret_cast(start + sec.va); + /*auto sec_start = reinterpret_cast(start + sec.va); auto sec_len = sec.size; for (size_t i = 0; i < sec_len; ++i) { @@ -107,7 +72,7 @@ void security::thread(tcp::client& client) { patches.emplace_back(patch); } - } + }*/ } } nlohmann::json j; @@ -125,4 +90,43 @@ void security::thread(tcp::client& client) { std::this_thread::sleep_for(std::chrono::seconds(5)); } +} + +__forceinline bool security::check() { + static auto peb = util::peb(); + auto being_debugged = static_cast(peb->BeingDebugged); + if (being_debugged) { + return true; + } + + io::log("being debugged {}", being_debugged); + + static auto query_info = g_syscalls.get("NtQueryInformationProcess"); + + uint32_t debug_inherit = 0; + auto status = query_info(INVALID_HANDLE_VALUE, native::ProcessDebugFlags, &debug_inherit, sizeof(debug_inherit), 0); + if (!NT_SUCCESS(status)) { + io::log_error("failed to get local process debug flags, status {:#X}.", (status & 0xFFFFFFFF)); + return true; + } + + io::log("debug inherit {}", debug_inherit); + + if (debug_inherit == 0) { + return true; + } + + uint64_t remote_debug = 0; + status = query_info(INVALID_HANDLE_VALUE, native::ProcessDebugPort, &remote_debug, sizeof(remote_debug), 0); + if (!NT_SUCCESS(status)) { + io::log_error("failed to get local process debug port, status {:#X}.", (status & 0xFFFFFFFF)); + return true; + } + + io::log("remote debug {}", remote_debug); + if (remote_debug != 0) { + return true; + } + + return false; } \ No newline at end of file diff --git a/client/src/security/security.h b/client/src/security/security.h index 009622a..fd2a5f3 100644 --- a/client/src/security/security.h +++ b/client/src/security/security.h @@ -4,6 +4,8 @@ namespace security { extern std::unordered_map> parsed_images; + + struct patch_t { uintptr_t va; uint8_t original_op; @@ -11,5 +13,59 @@ namespace security { std::string module; }; - void thread(tcp::client &client); + void thread(tcp::client& client); + + __forceinline bool check(); + + __forceinline bool init() { + std::list blacklist = { "ntdll.dll", "kernel32.dll" }; + + std::unordered_map memory_modules; + std::unordered_map> disk_modules; + if (!pe::get_all_modules(memory_modules)) { + io::log_error("failed to get loaded modules."); + return false; + } + + for (auto& [name, vi] : memory_modules) { + auto it = std::find(blacklist.begin(), blacklist.end(), name); + if (it == blacklist.end()) { + continue; + } + + std::vector raw; + char path[MAX_PATH]; + GetModuleFileNameA(GetModuleHandleA(name.c_str()), path, MAX_PATH); + + if (!io::read_file(path, raw)) { + io::log("failed to read {}.", name); + continue; + } + + disk_modules[name] = pe::image(raw); + } + + for (auto& [name, image] : disk_modules) { + std::vector mem; + + image.copy(mem); + image.relocate(mem, uintptr_t(GetModuleHandleA(name.c_str()))); + + for (auto& [mod, funcs] : image.imports()) { + std::string mod_name{ mod }; + g_apiset.find(mod_name); + + for (auto& func : funcs) { + *reinterpret_cast(&mem[func.rva]) = uintptr_t(GetProcAddress(GetModuleHandleA(mod_name.c_str()), func.name.c_str())); + } + } + + parsed_images[name] = mem; + } + + disk_modules.clear(); + memory_modules.clear(); + + return !parsed_images.empty(); + } }; \ No newline at end of file -- cgit v1.2.3