Asynchronous pattern scanning using std::async. (#770)

* feat(pattern): add support for double ? IDA sigs

Co-authored-by: Yimura <24669514+Yimura@users.noreply.github.com>
This commit is contained in:
Marcezsa 2023-01-18 19:02:23 +00:00 committed by GitHub
parent 23b016f4c8
commit fd0b4ebd55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 29 deletions

View File

@ -29,6 +29,8 @@ namespace big
void detour_hook::create_hook()
{
if (!m_target) return;
fix_hook_address();
if (auto status = MH_CreateHook(m_target, m_detour, &m_original); status != MH_OK)
throw std::runtime_error(std::format("Failed to create hook '{}' at 0x{:X} (error: {})", m_name, uintptr_t(m_target), MH_StatusToString(status)));
@ -36,18 +38,24 @@ namespace big
detour_hook::~detour_hook() noexcept
{
if (!m_target) return;
if (auto status = MH_RemoveHook(m_target); status != MH_OK)
LOG(FATAL) << "Failed to remove hook '" << m_name << "' at 0x" << HEX_TO_UPPER(uintptr_t(m_target)) << "(error: " << m_name << ")";
}
void detour_hook::enable()
{
if (!m_target) return;
if (auto status = MH_QueueEnableHook(m_target); status != MH_OK)
throw std::runtime_error(std::format("Failed to enable hook 0x{:X} ({})", uintptr_t(m_target), MH_StatusToString(status)));
}
void detour_hook::disable()
{
if (!m_target) return;
if (auto status = MH_QueueDisableHook(m_target); status != MH_OK)
LOG(WARNING) << "Failed to disable hook '" << m_name << "'.";
}

View File

@ -3,6 +3,11 @@
#include "batch.hpp"
#include "range.hpp"
#include <future> //std::async
static std::mutex s_entry_mutex;
static std::vector<std::future<bool>> g_futures;
namespace memory
{
void batch::add(std::string name, pattern pattern, std::function<void(handle)> callback)
@ -10,38 +15,46 @@ namespace memory
m_entries.emplace_back(std::move(name), std::move(pattern), std::move(callback));
}
void batch::run(range region)
bool scan_pattern_and_execute_callback(range region, memory::batch::entry entry)
{
if (auto result = region.scan(entry.m_pattern))
{
if (entry.m_callback)
{
std::lock_guard<std::mutex> lock(s_entry_mutex); // Acquire a lock on the mutex to synchronize access.
std::invoke(std::move(entry.m_callback), result);
LOG(INFO) << "Found '" << entry.m_name << "' GTA5.exe+" << HEX_TO_UPPER(result.as<DWORD64>() - region.begin().as<DWORD64>());
return true;
}
}
LOG(WARNING) << "Failed to find '" << entry.m_name << "'.";
return false;
}
bool batch::run(range region)
{
bool all_found = true;
for (auto& entry : m_entries)
{
if (auto result = region.scan(entry.m_pattern))
{
if (entry.m_callback)
{
std::invoke(std::move(entry.m_callback), result);
std::stringstream file_out{}; //I hate this, but not logging it except on fail really helps on speed.
file_out << "Found '" << entry.m_name << "' GTA5.exe+" << HEX_TO_UPPER(result.as<DWORD64>() - region.begin().as<DWORD64>());
big::g_log->file_out(file_out);
file_out.clear();
}
else
{
all_found = false;
LOG(WARNING) << "Failed to find '" << entry.m_name << "'.";
}
}
else
{
all_found = false;
LOG(WARNING) << "Failed to find '" << entry.m_name << "'.";
}
g_futures.emplace_back(
std::async(&scan_pattern_and_execute_callback, region, entry));
}
bool found_all_patterns = true;
for (auto& future : g_futures)
{
future.wait();
if (!future.get())
found_all_patterns = false;
}
m_entries.clear();
if (!all_found)
{
throw std::runtime_error("Failed to find some patterns.");
}
g_futures.clear();
return found_all_patterns;
}
}

View File

@ -12,7 +12,7 @@ namespace memory
~batch() noexcept = default;
void add(std::string name, pattern pattern, std::function<void(memory::handle)> callback);
void run(range region);
bool run(range region);
struct entry
{

View File

@ -79,6 +79,12 @@ namespace memory
else
{
m_bytes.push_back({});
// add support for double question mark sigs
if (ida_sig[i + 1] == '?')
{
++i;
}
}
}
}

View File

@ -811,7 +811,10 @@ namespace big
});
auto mem_region = memory::module("GTA5.exe");
main_batch.run(mem_region);
if (!main_batch.run(mem_region))
{
throw std::runtime_error("Failed to find some patterns.");
}
memory::batch socialclub_batch;