#pragma once #include "lua/lua_module.hpp" #include "lua/lua_patch.hpp" #include "lua/sol.hpp" #include "memory/byte_patch.hpp" namespace lua::memory { struct pointer { private: std::uint64_t m_address; public: explicit pointer(std::uint64_t address) : m_address(address) { } explicit pointer() : m_address(0) { } pointer add(uint64_t offset) { return pointer(m_address + offset); } pointer sub(uint64_t offset) { return pointer(m_address - offset); } pointer rip() { return add(*(std::int32_t*)m_address).add(4); } template T get() { return *(T*)m_address; } template void set(T value) { *(T*)m_address = value; } std::string get_string() { return std::string((char*)m_address); } void set_string(const std::string& string, int max_length) { strncpy((char*)m_address, string.data(), max_length); } template big::lua_patch* patch(T value, sol::this_state state) { auto module = sol::state_view(state)["!this"].get(); auto patch = std::make_shared(::memory::byte_patch::make((T*)m_address, value).get()); auto raw = patch.get(); module->m_registered_patches.push_back(std::move(patch)); return raw; } bool is_null() { return m_address == 0; } bool is_valid() { return !is_null(); } pointer deref() { return pointer(*(uint64_t*)m_address); } uint64_t get_address() const { return m_address; } }; pointer scan_pattern(const std::string& pattern); pointer handle_to_ptr(int entity); int ptr_to_handle(pointer mem_addr); pointer allocate(int size, sol::this_state state); void free(pointer ptr, sol::this_state state); static void bind(sol::state& state) { auto ns = state["memory"].get_or_create(); // clang-format off ns.new_usertype("pointer", sol::constructors(), "add", &pointer::add, "sub", &pointer::sub, "rip", &pointer::rip, "get_byte", &pointer::get, "get_word", &pointer::get, "get_dword", &pointer::get, "get_float", &pointer::get, "get_qword", &pointer::get, "get_string", &pointer::get_string, "set_byte", &pointer::set, "set_word", &pointer::set, "set_dword", &pointer::set, "set_float", &pointer::set, "set_qword", &pointer::set, "set_string", &pointer::set_string, "patch_byte", &pointer::patch, "patch_word", &pointer::patch, "patch_dword", &pointer::patch, "patch_qword", &pointer::patch, "is_null", &pointer::is_null, "is_valid", &pointer::is_valid, "deref", &pointer::deref, "get_address", &pointer::get_address ); ns.new_usertype("patch", sol::no_constructor, "apply", &big::lua_patch::apply, "restore", &big::lua_patch::restore ); // clang-format on ns["scan_pattern"] = scan_pattern; ns["handle_to_ptr"] = handle_to_ptr; ns["ptr_to_handle"] = ptr_to_handle; ns["allocate"] = allocate; ns["free"] = free; } }