Skip to content

Commit ee0fba1

Browse files
authored
Merge pull request #4 from miredirex/fix/EngineFixes-v7-support
Simplify `IsFormAllocateReplacedByEF` and `RehookFormAllocate`
2 parents 5a9a977 + 02bce8e commit ee0fba1

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

Code/client/Games/Memory.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,33 +67,37 @@ void Memory::Free(void* apData) noexcept
6767
TiltedPhoques::ThisCall(RealFormFree, GameHeap::Get(), apData, false);
6868
}
6969

70-
bool Memory::IsFormAllocateReplacedByEF() noexcept
70+
static bool IsFormAllocateReplacedByEF(TFormAllocate** appOutEngineFixesAlloc) noexcept
7171
{
7272
POINTER_SKYRIMSE(TFormAllocate, s_formAllocate, 68115);
7373
TFormAllocate* pFormAllocate = s_formAllocate.Get();
7474

75-
// 6-byte sequence of 'FF 25 00 00 00 00' comes before the virtual address we're after; so, +6
76-
auto possibleEfAllocAddr = *reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(*pFormAllocate) + 6);
75+
auto opcodeBytes = reinterpret_cast<uint16_t*>(*pFormAllocate);
76+
uint8_t shift = 0;
77+
78+
if (*opcodeBytes == 0x25FF) // 'jmp' opcode 'FF 25' and the 4-byte displacement bytes come before the virtual address we're after
79+
shift = 6;
80+
else if (*opcodeBytes == 0xB848) // 'mov' opcode '48 B8' comes before the virtual address we're after
81+
shift = 2;
82+
83+
auto possibleEfAllocAddress = *reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(*pFormAllocate) + shift);
7784

7885
MEMORY_BASIC_INFORMATION mbi;
79-
if (VirtualQuery((void*)possibleEfAllocAddr, &mbi, sizeof(mbi)) != 0)
86+
if (VirtualQuery((void*)possibleEfAllocAddress, &mbi, sizeof(mbi)) != 0)
8087
{
81-
return mbi.AllocationBase == GetModuleHandleW(L"EngineFixes.dll");
88+
if (mbi.AllocationBase == GetModuleHandleW(L"EngineFixes.dll"))
89+
{
90+
*appOutEngineFixesAlloc = reinterpret_cast<TFormAllocate*>(possibleEfAllocAddress);
91+
return true;
92+
}
8293
}
8394
return false;
8495
}
8596

86-
bool Memory::RehookMemoryFunctions() noexcept
97+
static void RehookFormAllocate(TFormAllocate* apEngineFixesAllocate) noexcept
8798
{
88-
POINTER_SKYRIMSE(TFormAllocate, s_formAllocate, 68115);
89-
TFormAllocate* pFormAllocate = s_formAllocate.Get();
90-
91-
uintptr_t efAllocAddr = *reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(*pFormAllocate) + 6);
92-
auto pEngineFixesAllocate = reinterpret_cast<decltype(&HookFormAllocate)>(efAllocAddr);
93-
94-
RealFormAllocate = pEngineFixesAllocate;
99+
RealFormAllocate = apEngineFixesAllocate;
95100
TP_HOOK_IMMEDIATE(&RealFormAllocate, HookFormAllocate);
96-
return true; // TODO when to return false?
97101
}
98102

99103
size_t Hook_msize(void* apData)
@@ -171,10 +175,10 @@ int __cdecl Hook_initterm_e(_PIFV* apFirst, _PIFV* apLast)
171175
// We want to run last, so pre-chain.
172176
auto retval = Real_initterm_e(apFirst, apLast);
173177

174-
// Check if anyone messed with STR's moddified allocator hook,
175-
// which changes the size of some allocations.
176-
if (GetModuleHandleW(L"EngineFixes.dll") && Memory::IsFormAllocateReplacedByEF())
177-
Memory::RehookMemoryFunctions();
178+
// Check if EngineFixes messed with STR's modified alloc hook; if it did, treat EF as truth and rehook
179+
TFormAllocate* pEngineFixesAllocate = nullptr;
180+
if (GetModuleHandleW(L"EngineFixes.dll") && IsFormAllocateReplacedByEF(&pEngineFixesAllocate))
181+
RehookFormAllocate(pEngineFixesAllocate);
178182

179183
return retval;
180184
}

Code/client/Games/Memory.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ struct Memory
55
[[nodiscard]] static void* Allocate(size_t aSize) noexcept;
66
static void Free(void* apData) noexcept;
77

8-
static bool IsFormAllocateReplacedByEF() noexcept;
9-
static bool RehookMemoryFunctions() noexcept;
10-
118
template <class T> static T* Allocate() noexcept
129
{
1310
auto pMemory = static_cast<T*>(Allocate(sizeof(T)));

0 commit comments

Comments
 (0)