diff options
Diffstat (limited to 'client/src/util')
| -rw-r--r-- | client/src/util/native.h | 53 | ||||
| -rw-r--r-- | client/src/util/pe.h | 8 | ||||
| -rw-r--r-- | client/src/util/syscalls.cpp | 3 | ||||
| -rw-r--r-- | client/src/util/util.cpp | 51 | ||||
| -rw-r--r-- | client/src/util/util.h | 11 |
5 files changed, 109 insertions, 17 deletions
diff --git a/client/src/util/native.h b/client/src/util/native.h index bb80bd1..735a6cb 100644 --- a/client/src/util/native.h +++ b/client/src/util/native.h @@ -206,10 +206,57 @@ namespace native { uint32_t ReferenceCount; }; - using NtQuerySystemInformation = NTSTATUS(__stdcall*)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); + template<class P> + struct peb_t { + std::uint8_t _ignored[4]; + P _ignored2[2]; + P Ldr; + }; + + template<class P> + struct list_entry_t { + P Flink; + P Blink; + }; + + template<class P> + struct peb_ldr_data_t { + unsigned long Length; + bool Initialized; + P SsHandle; + list_entry_t<P> InLoadOrderModuleList; + }; + + template<class P> + struct unicode_string_t { + std::uint16_t Length; + std::uint16_t MaximumLength; + P Buffer; + }; + + template<class P> + struct ldr_data_table_entry_t { + list_entry_t<P> InLoadOrderLinks; + list_entry_t<P> InMemoryOrderLinks; + union { + list_entry_t<P> InInitializationOrderLinks; + list_entry_t<P> InProgressLinks; + }; + P DllBase; + P EntryPoint; + unsigned long SizeOfImage; + unicode_string_t<P> FullDllName; + }; + + using NtQuerySystemInformation = NTSTATUS(__stdcall*)(SYSTEM_INFORMATION_CLASS, PVOID, SIZE_T, PULONG); using NtOpenProcess = NTSTATUS(__stdcall*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, CLIENT_ID*); - using NtReadVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID, PVOID, ULONG, PULONG); - using NtAllocateVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID*, ULONG, PULONG, ULONG, ULONG); + using NtReadVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID, PVOID, SIZE_T, PULONG); + using NtAllocateVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID*, ULONG_PTR, PSIZE_T, ULONG, ULONG); using NtWiteVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID, PVOID, ULONG, PULONG); + using NtClose = NTSTATUS(__stdcall*)(HANDLE); + using NtFreeVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID*, PSIZE_T, ULONG); + using NtQueryInformationProcess = NTSTATUS(__stdcall*)(HANDLE, PROCESSINFOCLASS, PVOID, SIZE_T, PULONG); + using NtWaitForSingleObject = NTSTATUS(__stdcall*)(HANDLE, BOOLEAN, PLARGE_INTEGER); + using NtCreateThreadEx = NTSTATUS(__stdcall*)(PHANDLE, ACCESS_MASK, PVOID, HANDLE, LPTHREAD_START_ROUTINE, PVOID, ULONG, ULONG_PTR, SIZE_T, SIZE_T, PVOID); }; // namespace native
\ No newline at end of file diff --git a/client/src/util/pe.h b/client/src/util/pe.h index 56ba8ea..4ae4326 100644 --- a/client/src/util/pe.h +++ b/client/src/util/pe.h @@ -1,8 +1,10 @@ #pragma once +#include <linux-pe/linuxpe> + namespace pe { - class image { + class virtual_image { std::unordered_map<std::string, uintptr_t> m_exports; IMAGE_NT_HEADERS64* m_nt; @@ -10,8 +12,8 @@ namespace pe { bool m_valid; public: - image() {}; - image(const uintptr_t base) : m_valid{ false }, m_base{ base }, m_nt{ nullptr } { + virtual_image() {}; + virtual_image(const uintptr_t base) : m_valid{ false }, m_base{ base }, m_nt{ nullptr } { auto dos = reinterpret_cast<IMAGE_DOS_HEADER*>(base); if (!dos || dos->e_magic != IMAGE_DOS_SIGNATURE) { return; diff --git a/client/src/util/syscalls.cpp b/client/src/util/syscalls.cpp index 279a936..f1d9261 100644 --- a/client/src/util/syscalls.cpp +++ b/client/src/util/syscalls.cpp @@ -6,8 +6,7 @@ syscalls g_syscalls; syscalls::syscalls() { - m_call_table = VirtualAlloc(0, 0x100000, MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE); + m_call_table = VirtualAlloc(0, 0x100000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); std::memset(m_call_table, 0x90, 0x100000); } diff --git a/client/src/util/util.cpp b/client/src/util/util.cpp index dbee015..3dba550 100644 --- a/client/src/util/util.cpp +++ b/client/src/util/util.cpp @@ -1,8 +1,9 @@ #include "../include.h" -#include "io.h" #include "util.h" +#include "io.h" +#include "syscalls.h" -std::unordered_map<std::string, pe::image> util::loaded_modules; +std::unordered_map<std::string, pe::virtual_image> util::loaded_modules; std::string util::wide_to_multibyte(const std::wstring& str) { std::string ret; @@ -24,13 +25,36 @@ std::string util::wide_to_multibyte(const std::wstring& str) { return ret; } +std::wstring util::multibyte_to_wide(const std::string &str) { + std::wstring ret; + int32_t size; + wchar_t *wstr; + const char *buf = str.c_str(); + + // get size + size = MultiByteToWideChar(CP_UTF8, 0, buf, int32_t(strlen(buf) + 1), 0, 0); + + // alloc new wchars + wstr = new wchar_t[size]; + + // finally convert + MultiByteToWideChar(CP_UTF8, 0, buf, int32_t(strlen(buf) + 1), wstr, size); + + // construct return string + ret = std::wstring(wstr); + + // cleanup + delete[] wstr; + return ret; +} + -native::_PEB* util::get_peb() { +native::_PEB* util::cur_peb() { return reinterpret_cast<native::_PEB*>(__readgsqword(0x60)); } bool util::init() { - auto peb = get_peb(); + auto peb = cur_peb(); if (!peb) return false; if (!peb->Ldr->InMemoryOrderModuleList.Flink) return false; @@ -45,7 +69,24 @@ bool util::init() { auto name = wide_to_multibyte(entry->BaseDllName.Buffer); std::transform(name.begin(), name.end(), name.begin(), ::tolower); - loaded_modules[name] = pe::image(entry->DllBase); + loaded_modules[name] = pe::virtual_image(entry->DllBase); + } + + return true; +} + +bool util::close_handle(HANDLE handle) { + if (!handle) { + io::logger->error("invalid handle specified to close."); + return false; + } + + static auto nt_close = g_syscalls.get<native::NtClose>("NtClose"); + + auto status = nt_close(handle); + if (!NT_SUCCESS(status)) { + io::logger->error("failed to close {}, status {:#X}.", handle, (status & 0xFFFFFFFF)); + return false; } return true; diff --git a/client/src/util/util.h b/client/src/util/util.h index 8658ce6..a4ff8c9 100644 --- a/client/src/util/util.h +++ b/client/src/util/util.h @@ -5,16 +5,17 @@ namespace util { - extern std::unordered_map<std::string, pe::image> loaded_modules; + extern std::unordered_map<std::string, pe::virtual_image> loaded_modules; std::string wide_to_multibyte(const std::wstring& str); + std::wstring multibyte_to_wide(const std::string &str); - native::_PEB* get_peb(); + native::_PEB* cur_peb(); bool init(); - static pe::image& ntdll() { - static pe::image nt{}; + static pe::virtual_image& ntdll() { + static pe::virtual_image nt{}; if (!nt) { nt = loaded_modules["ntdll.dll"]; nt.parse_exports(); @@ -22,5 +23,7 @@ namespace util { return nt; } + bool close_handle(HANDLE handle); + }; // namespace util |