@@ -67,6 +67,35 @@ void Memory::Free(void* apData) noexcept
6767 TiltedPhoques::ThisCall (RealFormFree, GameHeap::Get (), apData, false );
6868}
6969
70+ bool Memory::IsFormAllocateReplacedByEF () noexcept
71+ {
72+ POINTER_SKYRIMSE (TFormAllocate, s_formAllocate, 68115 );
73+ TFormAllocate* pFormAllocate = s_formAllocate.Get ();
74+
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 );
77+
78+ MEMORY_BASIC_INFORMATION mbi;
79+ if (VirtualQuery ((void *)possibleEfAllocAddr, &mbi, sizeof (mbi)) != 0 )
80+ {
81+ return mbi.AllocationBase == GetModuleHandleW (L" EngineFixes.dll" );
82+ }
83+ return false ;
84+ }
85+
86+ bool Memory::RehookMemoryFunctions () noexcept
87+ {
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;
95+ TP_HOOK_IMMEDIATE (&RealFormAllocate, HookFormAllocate);
96+ return true ; // TODO when to return false?
97+ }
98+
7099size_t Hook_msize (void * apData)
71100{
72101 return mi_malloc_size (apData);
@@ -137,23 +166,15 @@ T_initterm_e Real_initterm_e = nullptr;
137166
138167// If EngineFixes loaded, and it changed our FormAllocate hook,
139168// reset it. Our hook works just fine chaining to theirs.
140- int __cdecl Hook_initterm_e (_PIFV* pFirst , _PIFV* pLast )
169+ int __cdecl Hook_initterm_e (_PIFV* apFirst , _PIFV* apLast )
141170{
142171 // We want to run last, so pre-chain.
143- auto retval = Real_initterm_e (pFirst, pLast );
172+ auto retval = Real_initterm_e (apFirst, apLast );
144173
145- // Check if anyone messed with our modified form-allocator hook.
146- POINTER_SKYRIMSE (TFormAllocate, s_formAllocate, 68115 );
147- auto CurrentRealFormAllocate = s_formAllocate.Get ();
148- HMODULE h = GetModuleHandleW (L" EngineFixes.dll" ); // Debug
149- if (h && CurrentRealFormAllocate != RealFormAllocate)
150- {
151- uintptr_t efAllocateAddress = *reinterpret_cast <uintptr_t *>((reinterpret_cast <uint8_t *>(*CurrentRealFormAllocate) + 6 ));
152- auto pEngineFixesAllocate = reinterpret_cast <decltype (&HookFormAllocate)>(efAllocateAddress);
153- RealFormAllocate = pEngineFixesAllocate;
154-
155- TP_HOOK_IMMEDIATE (&RealFormAllocate, HookFormAllocate);
156- }
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 ();
157178
158179 return retval;
159180}
0 commit comments