Fix crashes with bytepatches on specific hardware due to memory being marked non readable (#1364)

* Try to fix bytepatch crash

* Try some more potential fixes

* More changes
This commit is contained in:
LightCat 2021-02-28 11:50:08 +01:00 committed by GitHub
parent 8ab6615c3a
commit 57579cf2bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 4 deletions

View File

@ -29,21 +29,39 @@ public:
addr = static_cast<void *>(static_cast<char *>(addr) + offset);
size = patch.size();
original.resize(size);
memcpy(&original[0], addr, size);
Copy();
}
BytePatch(uintptr_t addr, std::vector<unsigned char> patch) : addr{ reinterpret_cast<void *>(addr) }, patch_bytes{ patch }
{
size = patch.size();
original.resize(size);
memcpy(&original[0], reinterpret_cast<void *>(addr), size);
Copy();
}
BytePatch(void *addr, std::vector<unsigned char> patch) : addr{ addr }, patch_bytes{ patch }
{
size = patch.size();
original.resize(size);
memcpy(&original[0], addr, size);
Copy();
}
static void mprotectAddr(unsigned addr, int size, int flags)
{
void *page = (void *) ((uint64_t) addr & ~0xFFF);
void *end_page = (void *) (((uint64_t)(addr) + size) & ~0xFFF);
uintptr_t mprot_len = (uint64_t) end_page - (uint64_t) page + 0xFFF;
mprotect(page, mprot_len, flags);
}
void Copy()
{
void *page = (void *) ((uint64_t) addr & ~0xFFF);
void *end_page = (void *) (((uint64_t)(addr) + size) & ~0xFFF);
uintptr_t mprot_len = (uint64_t) end_page - (uint64_t) page + 0xFFF;
mprotect(page, mprot_len, PROT_READ | PROT_WRITE | PROT_EXEC);
memcpy(&original[0], addr, size);
mprotect(page, mprot_len, PROT_EXEC);
}
void Patch()
{
if (!patched)

View File

@ -236,6 +236,12 @@ static InitRoutine init([]() {
static auto addr4 = gSignatures.GetClientSignature("E8 ? ? ? ? 8D 85 ? ? ? ? 89 7C 24 0C 89 44 24 10");
static auto addr5 = gSignatures.GetClientSignature("E8 ? ? ? ? 8D 65 F4 5B 5E 5F 5D C3 8D 76 00 8B 43 0C"); // FX_Tracer detour
BytePatch::mprotectAddr(addr1 + 1, 4, PROT_READ | PROT_WRITE | PROT_EXEC);
BytePatch::mprotectAddr(addr2 + 1, 4, PROT_READ | PROT_WRITE | PROT_EXEC);
BytePatch::mprotectAddr(addr3 + 1, 4, PROT_READ | PROT_WRITE | PROT_EXEC);
BytePatch::mprotectAddr(addr4 + 1, 4, PROT_READ | PROT_WRITE | PROT_EXEC);
BytePatch::mprotectAddr(addr5 + 1, 4, PROT_READ | PROT_WRITE | PROT_EXEC);
GetParticleSystemNameFromIndex_fn = GetParticleSystemNameFromIndex_t(e8call(addr1 + 7));
GetActiveTFWeapon_fn = GetActiveTFWeapon_t(e8call_direct(addr2));
DispatchEffect_fn = DispatchEffect_t(e8call_direct(addr3));

View File

@ -963,7 +963,13 @@ inline void force_wait_func(bool after)
{
// Enable the wait command
int **enable_wait = (int **) (enable_wait_signature + 3);
BytePatch::mprotectAddr((uintptr_t) enable_wait, 4, PROT_READ | PROT_WRITE | PROT_EXEC);
BytePatch::mprotectAddr((uintptr_t) *enable_wait, 4, PROT_READ | PROT_WRITE | PROT_EXEC);
**enable_wait = true;
BytePatch::mprotectAddr((uintptr_t) enable_wait, 4, PROT_EXEC);
patch_wait.Patch();
}
else