refactor!: Modified memory::module class (#597)

This commit is contained in:
Yimura 2022-11-14 22:59:02 +01:00 committed by GitHub
parent ed903528f4
commit 1986dee1b5
5 changed files with 103 additions and 35 deletions

View File

@ -35,7 +35,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
g_main_thread = CreateThread(nullptr, 0, [](PVOID) -> DWORD
{
while (!FindWindow("grcWindow", "Grand Theft Auto V"))
std::this_thread::sleep_for(1s);
std::this_thread::sleep_for(100ms);
std::filesystem::path base_dir = std::getenv("appdata");
base_dir /= "BigBaseV2";

View File

@ -3,31 +3,75 @@
namespace memory
{
module::module(HMODULE mod) :
range(mod, 0)
{
auto dosHeader = m_base.as<IMAGE_DOS_HEADER*>();
auto ntHeader = m_base.add(dosHeader->e_lfanew).as<IMAGE_NT_HEADERS*>();
m_size = ntHeader->OptionalHeader.SizeOfImage;
}
module::module(std::nullptr_t) :
module(GetModuleHandle(nullptr))
{
}
module::module(std::string_view name) :
module(GetModuleHandleA(name.data()))
{
}
module::module(std::wstring_view name) :
module(GetModuleHandleW(name.data()))
module::module(const std::string_view name) :
range(nullptr, 0),
m_name(name),
m_loaded(false)
{
try_get_module();
}
handle module::get_export(std::string_view symbol_name)
{
return GetProcAddress(m_base.as<HMODULE>(), symbol_name.data());
if (!m_loaded)
return nullptr;
const auto dosHeader = m_base.as<IMAGE_DOS_HEADER*>();
const auto ntHeader = m_base.add(dosHeader->e_lfanew).as<IMAGE_NT_HEADERS*>();
const auto imageDataDirectory = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
const auto exportDirectory = m_base.add(imageDataDirectory.VirtualAddress).as<IMAGE_EXPORT_DIRECTORY*>();
const auto nameOffsetArray = m_base.add(exportDirectory->AddressOfNames).as<DWORD*>();
const auto ordinalArray = m_base.add(exportDirectory->AddressOfNameOrdinals).as<DWORD*>();
const auto functionOffsetArray = m_base.add(exportDirectory->AddressOfFunctions).as<DWORD*>();
for (std::size_t i = 0; i < exportDirectory->NumberOfFunctions; i++)
{
const auto functionName = m_base.add(nameOffsetArray[i]).as<const char*>();
if (strcmp(functionName, symbol_name.data()))
continue;
return functionOffsetArray + ordinalArray[i];
}
return nullptr;
}
bool module::loaded() const
{
return m_loaded;
}
bool module::wait_for_module(std::optional<std::chrono::high_resolution_clock::duration> time)
{
const auto giveup_time = time.has_value()
? std::make_optional(std::chrono::high_resolution_clock::now() + time.value())
: std::nullopt;
LOG(G3LOG_DEBUG) << "Waiting for " << m_name << "...";
while (!try_get_module())
{
if (giveup_time.has_value() && giveup_time <= std::chrono::high_resolution_clock::now())
break;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return m_loaded;
}
bool module::try_get_module()
{
if (m_loaded)
return m_loaded;
const auto mod = GetModuleHandleA(m_name.data());
if (!mod)
return false;
m_loaded = true;
m_base = mod;
const auto dosHeader = m_base.as<IMAGE_DOS_HEADER*>();
const auto ntHeader = m_base.add(dosHeader->e_lfanew).as<IMAGE_NT_HEADERS*>();
m_size = ntHeader->OptionalHeader.SizeOfImage;
return m_loaded;
}
}

View File

@ -6,11 +6,32 @@ namespace memory
class module : public range
{
public:
module(HMODULE mod);
explicit module(std::nullptr_t);
explicit module(std::string_view name);
explicit module(std::wstring_view name);
explicit module(const std::string_view name);
/**
* @brief Get the export address of the current module given a symbol name
*
* @param symbol_name
* @return memory::handle
*/
memory::handle get_export(std::string_view symbol_name);
bool loaded() const;
/**
* @brief Waits till the given module is loaded.
*
* @param time Time to wait before giving up.
* @return true
* @return false
*/
bool wait_for_module(std::optional<std::chrono::high_resolution_clock::duration> time = std::nullopt);
protected:
bool try_get_module();
private:
const std::string_view m_name;
bool m_loaded;
};
}

View File

@ -482,7 +482,7 @@ namespace big
m_communications = ptr.add(3).rip().as<CCommunications**>();
});
auto mem_region = memory::module(nullptr);
auto mem_region = memory::module("GTA5.exe");
main_batch.run(mem_region);
memory::batch socialclub_batch;
@ -495,7 +495,12 @@ namespace big
m_update_presence_attribute_string = presence_data_vft[3];
});
socialclub_batch.run(memory::module("socialclub.dll"));
auto sc_module = memory::module("socialclub.dll");
if (sc_module.wait_for_module())
{
socialclub_batch.run(sc_module);
}
else LOG(WARNING) << "socialclub.dll module was not loaded within the time limit.";
if (auto pat = mem_region.scan("41 80 78 28 ? 0F 85 F5 01 00 00"))
{

View File

@ -1,5 +1,6 @@
#pragma once
#include "crossmap.hpp"
#include "file_manager.hpp"
#include "pointers.hpp"
#include "memory/module.hpp"
@ -7,13 +8,10 @@ namespace big::system
{
inline void dump_entry_points()
{
DWORD64 base_address = memory::module(nullptr).begin().as<DWORD64>();
DWORD64 base_address = memory::module("GTA5.exe").begin().as<DWORD64>();
std::string path = std::getenv("appdata");
path += "\\BigBaseV2\\entrypoints.txt";
std::ofstream file;
file.open(path, std::ios::out |std::ios::trunc);
const auto file_path = g_file_manager->get_project_file("./entrypoints.txt");
auto file = std::ofstream(file_path.get_path(), std::ios::out | std::ios::trunc);
for (auto &map : g_crossmap)
{
@ -27,7 +25,7 @@ namespace big::system
inline uintptr_t get_relative_address(void* ptr)
{
uintptr_t base_address = memory::module(nullptr).begin().as<uintptr_t>();
uintptr_t base_address = memory::module("GTA5.exe").begin().as<uintptr_t>();
return (uintptr_t)ptr - base_address;
}