refactor: Soundbank runtime hooking improvement
> change default behaviour to pattern based patch for hooks::soundbank, see #13 > fix broken check for hooks::soundbank unsupported game version
This commit is contained in:
@@ -249,3 +249,52 @@ bool get_pe_identifier(const std::filesystem::path& dll_path, uint32_t* time_dat
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// search cstr
|
||||
const unsigned char *cstr_addr = std::search(
|
||||
modbegp,
|
||||
modendp,
|
||||
reinterpret_cast<const unsigned char *>(cstr),
|
||||
reinterpret_cast<const unsigned char *>(cstr) + strlen(cstr)
|
||||
);
|
||||
if (cstr_addr == modendp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
// find LEA REG, [abs32]
|
||||
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);
|
||||
return reinterpret_cast<intptr_t>(std::search(
|
||||
modbegp,
|
||||
modendp,
|
||||
asmop,
|
||||
asmop + sizeof(asmop)
|
||||
));
|
||||
#elif defined(__x86_64__)
|
||||
// find LEA REG, [RIP + rel32]
|
||||
unsigned char rex = reg.t == GPR_EXT ? 0x4C : 0x48;
|
||||
unsigned char asmop[7] = {rex, 0x8D, reg.v, 0x00, 0x00, 0x00, 0x00};
|
||||
for (const unsigned char *addr = modbegp; addr < modendp - sizeof(asmop); addr++)
|
||||
{
|
||||
auto dist32 = static_cast<int32_t>(reinterpret_cast<intptr_t>(cstr_addr) - reinterpret_cast<intptr_t>(addr + sizeof(asmop)));
|
||||
memcpy(asmop + (sizeof(asmop) - 4), &dist32, 4);
|
||||
if (memcmp(addr, asmop, sizeof(asmop)) == 0) return reinterpret_cast<intptr_t>(addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+51
-1
@@ -89,4 +89,54 @@ intptr_t replace_pattern_from(
|
||||
intptr_t usage,
|
||||
intptr_t start_from);
|
||||
|
||||
bool get_pe_identifier(const std::filesystem::path& dll_path, uint32_t* time_date_stamp, uint32_t* address_of_entry_point);
|
||||
bool get_pe_identifier(const std::filesystem::path& dll_path, uint32_t* time_date_stamp, uint32_t* address_of_entry_point);
|
||||
|
||||
union reg_t{
|
||||
struct{
|
||||
unsigned char t;
|
||||
unsigned char v;
|
||||
};
|
||||
unsigned short s;
|
||||
constexpr reg_t(unsigned char t, unsigned char v) : s(v << 8 | t) {}
|
||||
constexpr reg_t(unsigned short s) : s(s) {}
|
||||
};
|
||||
|
||||
enum REGTYPE : unsigned char
|
||||
{
|
||||
GPR_32,
|
||||
GPR_64,
|
||||
GPR_EXT
|
||||
};
|
||||
|
||||
enum REG : unsigned short
|
||||
{
|
||||
EAX = reg_t(GPR_32, 0x05).s,
|
||||
ECX = reg_t(GPR_32, 0x0D).s,
|
||||
EDX = reg_t(GPR_32, 0x15).s,
|
||||
EBX = reg_t(GPR_32, 0x1D).s,
|
||||
ESP = reg_t(GPR_32, 0x25).s,
|
||||
EBP = reg_t(GPR_32, 0x2D).s,
|
||||
ESI = reg_t(GPR_32, 0x35).s,
|
||||
EDI = reg_t(GPR_32, 0x3D).s,
|
||||
RAX = reg_t(GPR_64, 0x05).s,
|
||||
RCX = reg_t(GPR_64, 0x0D).s,
|
||||
RDX = reg_t(GPR_64, 0x15).s,
|
||||
RBX = reg_t(GPR_64, 0x1D).s,
|
||||
RSP = reg_t(GPR_64, 0x25).s,
|
||||
RBP = reg_t(GPR_64, 0x2D).s,
|
||||
RSI = reg_t(GPR_64, 0x35).s,
|
||||
RDI = reg_t(GPR_64, 0x3D).s,
|
||||
R8 = reg_t(GPR_EXT, 0x05).s,
|
||||
R9 = reg_t(GPR_EXT, 0x0D).s,
|
||||
R10 = reg_t(GPR_EXT, 0x15).s,
|
||||
R11 = reg_t(GPR_EXT, 0x1D).s,
|
||||
R12 = reg_t(GPR_EXT, 0x25).s,
|
||||
R13 = reg_t(GPR_EXT, 0x2D).s,
|
||||
R14 = reg_t(GPR_EXT, 0x35).s,
|
||||
R15 = reg_t(GPR_EXT, 0x3D).s
|
||||
};
|
||||
|
||||
intptr_t find_asm_leacstr_from(
|
||||
HMODULE module,
|
||||
reg_t reg,
|
||||
const char *cstr);
|
||||
Reference in New Issue
Block a user