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:
+5
-2
@@ -927,8 +927,11 @@ void init(HINSTANCE hmodule, const char *model, const char *ext)
|
||||
}
|
||||
|
||||
// Override .text (pattern match)
|
||||
offset_.TX_EnumValidSoundbanks = find_pattern_from(hmodule, "CCCCCCCCCCCCCCCC", "XXXXXXXX", 8, 0,
|
||||
find_asm_leacstr_from(hmodule, R8, "%05d/%05d.2dx") - reinterpret_cast<intptr_t>(hmodule), true);
|
||||
offset_.TX_EnumValidSoundbanks = patch_pipeline(
|
||||
hmodule,
|
||||
[](HMODULE hmodule, intptr_t addr) { return find_asm_leacstr_from(hmodule, R8, "%05d/%05d.2dx"); },
|
||||
[](HMODULE hmodule, intptr_t addr) { return find_pattern_from(hmodule, "CCCCCCCCCCCCCCCC", "XXXXXXXX", 8, 0, addr, true); }
|
||||
);
|
||||
snd_bank::resampler_ = avcodec::BmswTranscoderResampler() == avcodec::bmswac_resampler_none ? snd_bank::resampler_ : avcodec::BmswTranscoderResampler();
|
||||
offset_.TX_EnumValidSoundbanks = avcodec::BmswTranscoderEnumValidSoundbanksAddr() == 0x0 ? offset_.TX_EnumValidSoundbanks : (intptr_t) hmodule + (int64_t) avcodec::BmswTranscoderEnumValidSoundbanksAddr();
|
||||
if (!offset_.TX_EnumValidSoundbanks)
|
||||
|
||||
+5
-2
@@ -92,8 +92,11 @@ bool on_thum_exists_(void *titleUTF_getter, int32_t id, char flag)
|
||||
void attach(HINSTANCE hmodule)
|
||||
{
|
||||
// Reverse lookup function head (PUSH RDI) for ThumExists() specific signature, quietly fail if invalid
|
||||
intptr_t TX_ThumExists = find_pattern_from(hmodule, "4057", "XX", 0, 0,
|
||||
find_pattern_from(hmodule, "83f801750c4084ff750732c0", "XXXXXXXXXXXX", 0, 0, 0) - reinterpret_cast<intptr_t>(hmodule), true);
|
||||
intptr_t TX_ThumExists = patch_pipeline(
|
||||
hmodule,
|
||||
[](HMODULE hmodule, intptr_t addr) { return find_pattern_from(hmodule, "83f801750c4084ff750732c0", "XXXXXXXXXXXX", 0, 0, 0); },
|
||||
[](HMODULE hmodule, intptr_t addr) { return find_pattern_from(hmodule, "4057", "XX", 0, 0, addr, true); }
|
||||
);
|
||||
log_info("hooks::wmisc::thumbnail", "Hooking ThumExists({})", reinterpret_cast<void *>(TX_ThumExists));
|
||||
detour::trampoline_try(reinterpret_cast<void *>(TX_ThumExists), reinterpret_cast<void *>(on_thum_exists_), reinterpret_cast<void **>(&ThumExists));
|
||||
}
|
||||
|
||||
+47
-41
@@ -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;
|
||||
}
|
||||
|
||||
+34
-3
@@ -5,11 +5,21 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <span>
|
||||
#include "windows.h"
|
||||
#include "psapi.h"
|
||||
|
||||
intptr_t find_pattern(
|
||||
std::vector<unsigned char> &data,
|
||||
std::span<const unsigned char> data,
|
||||
intptr_t base,
|
||||
const unsigned char *pattern,
|
||||
const char *mask,
|
||||
intptr_t offset,
|
||||
intptr_t usage,
|
||||
bool reverse = false);
|
||||
|
||||
intptr_t find_pattern(
|
||||
const std::vector<unsigned char> &data,
|
||||
intptr_t base,
|
||||
const unsigned char *pattern,
|
||||
const char *mask,
|
||||
@@ -34,7 +44,17 @@ intptr_t find_pattern(
|
||||
bool reverse = false);
|
||||
|
||||
intptr_t find_pattern_from(
|
||||
std::vector<unsigned char> &data,
|
||||
std::span<const unsigned char> data,
|
||||
intptr_t base,
|
||||
const unsigned char *pattern,
|
||||
const char *mask,
|
||||
intptr_t offset,
|
||||
intptr_t usage,
|
||||
intptr_t start_from,
|
||||
bool reverse = false);
|
||||
|
||||
intptr_t find_pattern_from(
|
||||
const std::vector<unsigned char> &data,
|
||||
intptr_t base,
|
||||
const unsigned char *pattern,
|
||||
const char *mask,
|
||||
@@ -149,4 +169,15 @@ enum REG : unsigned short
|
||||
intptr_t find_asm_leacstr_from(
|
||||
HMODULE module,
|
||||
reg_t reg,
|
||||
const char *cstr);
|
||||
const char *cstr);
|
||||
|
||||
std::span<const unsigned char> get_module_data(HMODULE hmodule, intptr_t *base);
|
||||
|
||||
template <typename... Funcs>
|
||||
intptr_t patch_pipeline(HMODULE module, Funcs&&... cbs) {
|
||||
intptr_t base;
|
||||
if(!get_module_data(module, &base).size()) return 0;
|
||||
intptr_t addr = base; //_REV: needs implementing module updating logic in case of traversing between libraries
|
||||
((addr && (addr = std::forward<Funcs>(cbs)(module, addr - base))), ...); // stop on first mismatch
|
||||
return addr;
|
||||
}
|
||||
Reference in New Issue
Block a user