#include "pch.h" #include "memory.h" memory::allocator memory::mem_allocator_; memory::allocator::~allocator() { this->clear(); } void memory::allocator::clear() { std::lock_guard _(this->mutex_); for (auto& data : this->pool_) { memory::free(data); } this->pool_.clear(); } void memory::allocator::free(void* data) { std::lock_guard _(this->mutex_); const auto j = std::find(this->pool_.begin(), this->pool_.end(), data); if (j != this->pool_.end()) { memory::free(data); this->pool_.erase(j); } } void memory::allocator::free(const void* data) { this->free(const_cast(data)); } void* memory::allocator::allocate(const size_t length) { std::lock_guard _(this->mutex_); const auto data = memory::allocate(length); this->pool_.push_back(data); return data; } bool memory::allocator::empty() const { return this->pool_.empty(); } void* memory::allocate(const size_t length) { return calloc(length, 1); } void memory::free(void* data) { if (data) { ::free(data); } } void memory::free(const void* data) { free(const_cast(data)); } bool memory::is_set(const void* mem, const char chr, const size_t length) { const auto mem_arr = static_cast(mem); for (size_t i = 0; i < length; ++i) { if (mem_arr[i] != chr) { return false; } } return true; } memory::allocator* memory::get_allocator() { return &memory::mem_allocator_; } std::uint8_t* find_sig(LPCSTR module_name, const std::string& byte_array) { HMODULE module = GetModuleHandleA(module_name); if (!module) return nullptr; static const auto pattern_to_byte = [](const char* pattern) { auto bytes = std::vector{}; const auto start = const_cast(pattern); const auto end = const_cast(pattern) + std::strlen(pattern); for (auto current = start; current < end; ++current) { if (*current == '?') { ++current; if (*current == '?') ++current; bytes.push_back(-1); } else { bytes.push_back(std::strtoul(current, ¤t, 16)); } } return bytes; }; const auto dos_header = reinterpret_cast(module); const auto nt_headers = reinterpret_cast(reinterpret_cast(module) + dos_header->e_lfanew); const auto size_of_image = nt_headers->OptionalHeader.SizeOfImage; const auto pattern_bytes = pattern_to_byte(byte_array.c_str()); const auto scan_bytes = reinterpret_cast(module); const auto pattern_size = pattern_bytes.size(); const auto pattern_data = pattern_bytes.data(); for (auto i = 0ul; i < size_of_image - pattern_size; ++i) { auto found = true; for (auto j = 0ul; j < pattern_size; ++j) { if (scan_bytes[i + j] == pattern_data[j] || pattern_data[j] == -1) continue; found = false; break; } if (!found) continue; return &scan_bytes[i]; } return nullptr; } signature::signature(const std::string& sig) { this->imported = false; this->sig = sig; } signature signature::import(const std::string& module_name) { this->imported = true; this->module_name = module_name; this->pointer = (uint64_t)find_sig(this->module_name.data(), this->sig); return *this; } signature signature::add(uint32_t value) { if (!this->imported) *this = this->import(); this->pointer += value; return *this; } signature signature::sub(uint32_t value) { if (!this->imported) *this = this->import(); this->pointer -= value; return *this; } signature signature::dump(const std::string& func_name) { if (!this->imported) *this = this->import(); return *this; } signature signature::instruction(uint32_t offset) { if (!this->imported) *this = this->import(); this->pointer = *(int*)(this->pointer + offset) + this->pointer; return *this; } #ifdef _WIN64 uint64_t signature::GetPointer() { if (!this->imported) *this = this->import(); return this->pointer; } #else uint32_t signature::GetPointer() { if (!this->imported) *this = this->import(); return this->pointer; } #endif static inline void memcpy_(void* _Dst, void const* _Src, size_t _Size) { auto csrc = (char*)_Src; auto cdest = (char*)_Dst; for (int i = 0; i < _Size; i++) { cdest[i] = csrc[i]; } } void swap_virtual_table(void* obj, uint32_t index, void* func) { auto currVt = *(void**)(obj); auto vtable = *(void***)(obj); int i = 0; for (; vtable[i]; i++) __noop(); auto newVt = new uintptr_t[i]; memcpy_(newVt, currVt, i * 0x8); newVt[index] = (uintptr_t)func; *(uintptr_t**)(obj) = newVt; } bool get_key_state(int key, int flag) { clock_t c = clock(); static BYTE btKeyState[0x100] = { 0 }; static clock_t clockKeyState[0x100] = { c }; bool r = false; BYTE btState = (GetAsyncKeyState(key) & 0x8000U) >> 0xF; short wDelay = btKeyState[key] & 2 ? 0x50 : 0x200; if (btState) { if (flag & 1) { if (!(btKeyState[key] & 1) || c - clockKeyState[key] > wDelay) { if ((btKeyState[key] & 3) == 1) btKeyState[key] |= 2; r = true; clockKeyState[key] = c; } } else r = true; } else btKeyState[key] &= ~(2); btKeyState[key] ^= (-btState ^ btKeyState[key]) & 1; return r; }