refactor/feat: Further signature scan changes

> funcionality cleanup, API compatibility should be the same
> improve patching performance by skipping vector copy (replaced with span)
> chain call wrapper (fixes soudbank hook breaking 32-bit styles)
This commit is contained in:
[ ]
2026-02-20 18:36:42 +09:00
parent a7723148bc
commit ce0344742e
4 changed files with 91 additions and 48 deletions
+47 -41
View File
@@ -9,12 +9,18 @@
#include "util/memutils.h"
#include "util/utils.h"
intptr_t find_pattern(std::vector<uint8_t> &data, intptr_t base, const uint8_t *pattern,
intptr_t find_pattern(std::span<const unsigned char> data, intptr_t base, const uint8_t *pattern,
const char *mask, intptr_t offset, intptr_t usage, bool reverse)
{
return find_pattern_from(data, base, pattern, mask, offset, usage, 0, reverse);
}
intptr_t find_pattern(const std::vector<uint8_t> &data, intptr_t base, const uint8_t *pattern,
const char *mask, intptr_t offset, intptr_t usage, bool reverse)
{
return find_pattern_from(std::span<const unsigned char>(data), base, pattern, mask, offset, usage, 0, reverse);
}
intptr_t find_pattern(HMODULE module, const uint8_t *pattern, const char *mask,
intptr_t offset, intptr_t result_usage, bool reverse)
{
@@ -29,12 +35,9 @@ intptr_t find_pattern(HMODULE module, const std::string &pattern, const char *ma
///
intptr_t find_pattern_from(std::vector<uint8_t> &data, intptr_t base, const uint8_t *pattern,
intptr_t find_pattern_from(std::span<const unsigned char> data, intptr_t base, const uint8_t *pattern,
const char *mask, intptr_t offset, intptr_t usage, intptr_t start_from, bool reverse)
{
// boundary check (mainly for result passthrough without validating)
if (start_from < 0 || usage < 0 || base < 0) return 0;
// build pattern
std::vector<std::pair<uint8_t, bool>> pattern_vector;
size_t mask_size = strlen(mask);
@@ -104,37 +107,26 @@ intptr_t find_pattern_from(std::vector<uint8_t> &data, intptr_t base, const uint
return 0;
}
intptr_t find_pattern_from(const std::vector<uint8_t> &data, intptr_t base, const uint8_t *pattern,
const char *mask, intptr_t offset, intptr_t usage, intptr_t start_from, bool reverse)
{
return find_pattern_from(std::span<const unsigned char>(data), base, pattern, mask, offset, usage, start_from, reverse);
}
intptr_t find_pattern_from(HMODULE module, const uint8_t *pattern, const char *mask,
intptr_t offset, intptr_t result_usage, intptr_t start_from, bool reverse)
{
// get module information
MODULEINFO module_info {};
if (!GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(module_info))) {
return 0;
}
auto size = static_cast<size_t>(module_info.SizeOfImage);
try {
// copy data
std::vector<uint8_t> data(size);
memcpy(data.data(), module_info.lpBaseOfDll, size);
// find pattern
return find_pattern_from(
data,
reinterpret_cast<intptr_t>(module_info.lpBaseOfDll),
pattern,
mask,
offset,
result_usage,
start_from,
reverse);
} catch (const std::bad_alloc &e) {
log_warning("sigscan", "failed to allocate buffer of size {} for image data", size);
return false;
}
intptr_t base;
auto data = get_module_data(module, &base);
return find_pattern_from(
data,
base,
pattern,
mask,
offset,
result_usage,
start_from,
reverse);
}
intptr_t find_pattern_from(HMODULE module, const std::string &pattern, const char *mask,
@@ -286,13 +278,10 @@ bool get_pe_identifier(const std::filesystem::path& dll_path, uint32_t* time_dat
intptr_t find_asm_leacstr_from(HMODULE module, reg_t reg, const char *cstr)
{
// get module information
MODULEINFO module_info{};
if (!GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(module_info)))
{
return 0;
}
const unsigned char *modbegp = reinterpret_cast<unsigned char *>(module);
const unsigned char *modendp = reinterpret_cast<unsigned char *>(module) + static_cast<size_t>(module_info.SizeOfImage);
intptr_t base;
auto data = get_module_data(module, &base);
const unsigned char *modbegp = data.data();
const unsigned char *modendp = data.data() + data.size();
// search cstr
const unsigned char *cstr_addr = std::search(
@@ -308,6 +297,7 @@ intptr_t find_asm_leacstr_from(HMODULE module, reg_t reg, const char *cstr)
#if defined(__i386__)
// find LEA REG, [abs32]
if (reg.t != GPR_32) return 0;
unsigned char asmop[6] = { 0x8D, reg.v, 0x00, 0x00, 0x00, 0x00};
int32_t dist32 = reinterpret_cast<int32_t>(cstr_addr);
memcpy(asmop + (sizeof(asmop) - 4), &dist32, 4);
@@ -316,7 +306,7 @@ intptr_t find_asm_leacstr_from(HMODULE module, reg_t reg, const char *cstr)
modendp,
asmop,
asmop + sizeof(asmop)
));
)) % reinterpret_cast<intptr_t>(modendp);
#elif defined(__x86_64__)
// find LEA REG, [RIP + rel32]
unsigned char rex = reg.t == GPR_EXT ? 0x4C : 0x48;
@@ -331,3 +321,19 @@ intptr_t find_asm_leacstr_from(HMODULE module, reg_t reg, const char *cstr)
return 0;
}
std::span<const unsigned char> get_module_data(HMODULE module, intptr_t *base)
{
// get module information
size_t sz = 0;
MODULEINFO module_info {};
if (GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(module_info))) {
sz = static_cast<size_t>(module_info.SizeOfImage);
}
// wrap data
std::span<const unsigned char> data(static_cast<const unsigned char*>(module_info.lpBaseOfDll), sz);
*base = reinterpret_cast<intptr_t>(module_info.lpBaseOfDll);
return data;
}