1
1
#include " precompiled.h"
2
2
#include < windows.h>
3
3
4
- // remove eventually
5
- #include < MinHook.h>
6
-
7
4
#if defined(_M_X64)
8
5
#define STEAM_API L" steam_api64.dll"
9
6
#else
@@ -205,18 +202,112 @@ void *Hk_SteamInternal_CreateInterface(const char *ver)
205
202
206
203
// -------------------------------------
207
204
208
- // i lied, there's no eat hook (broken on x64 so temporarily using minhook)
205
+ #define MAX_ADDRESS_OFFSET ((DWORD)~0 )
206
+
207
+ void *AllocateNear (void *pOrigin, size_t nSize)
208
+ {
209
+ SYSTEM_INFO SystemInfo;
210
+ GetSystemInfo (&SystemInfo);
211
+
212
+ UINT_PTR Address = (UINT_PTR)pOrigin;
213
+ UINT_PTR MaxAddress = (UINT_PTR)pOrigin + MAX_ADDRESS_OFFSET;
214
+
215
+ Address -= Address % SystemInfo.dwAllocationGranularity ;
216
+ Address += SystemInfo.dwAllocationGranularity ;
217
+
218
+ while (Address <= MaxAddress)
219
+ {
220
+ MEMORY_BASIC_INFORMATION MemoryInfo;
221
+ if (!VirtualQuery ((void *)Address, &MemoryInfo, sizeof (MemoryInfo)))
222
+ break ;
223
+
224
+ if (MemoryInfo.State == MEM_FREE)
225
+ {
226
+ void *pBlock = VirtualAlloc ((void *)Address, nSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
227
+ if (pBlock)
228
+ return pBlock;
229
+ }
230
+
231
+ Address = (UINT_PTR)MemoryInfo.BaseAddress + MemoryInfo.RegionSize ;
232
+
233
+ Address += SystemInfo.dwAllocationGranularity - 1 ;
234
+ Address -= Address % SystemInfo.dwAllocationGranularity ;
235
+ }
236
+
237
+ return NULL ;
238
+ }
239
+
240
+ void *TrampolineNear (void *pAddress, void *pDestination)
241
+ {
242
+ UINT8 Payload[] =
243
+ {
244
+ 0x50 , // push rax
245
+ 0x48 , 0xb8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , // movabs rax, pDestination
246
+ 0x48 , 0x87 , 0x04 , 0x24 , // xchg QWORD PTR [rsp], rax
247
+ 0xc3 // ret
248
+ };
249
+
250
+ void * pTrampoline = AllocateNear (pAddress, sizeof (Payload));
251
+ if (!pTrampoline)
252
+ return NULL ;
253
+
254
+ memcpy (&Payload[3 ], &pDestination, sizeof (pDestination));
255
+ memcpy (pTrampoline, Payload, sizeof (Payload));
256
+
257
+ return pTrampoline;
258
+ }
259
+
260
+ DWORD *FindFromEAT (uintptr_t hModule, const char *szFunction)
261
+ {
262
+ IMAGE_DOS_HEADER *DosHeader = (IMAGE_DOS_HEADER *)(hModule);
263
+ IMAGE_NT_HEADERS *NtHeader = (IMAGE_NT_HEADERS *)(hModule + DosHeader->e_lfanew );
264
+ IMAGE_DATA_DIRECTORY *DataDirectory = &NtHeader->OptionalHeader .DataDirectory [IMAGE_DIRECTORY_ENTRY_EXPORT];
265
+ IMAGE_EXPORT_DIRECTORY *ExportDirectory = (IMAGE_EXPORT_DIRECTORY *)(hModule + DataDirectory->VirtualAddress );
266
+
267
+ DWORD *AddressOfFunctions = (DWORD *)(hModule + ExportDirectory->AddressOfFunctions );
268
+ DWORD *AddressOfNames = (DWORD *)(hModule + ExportDirectory->AddressOfNames );
269
+ WORD *AddressOfNameOrdinals = (WORD *)(hModule + ExportDirectory->AddressOfNameOrdinals );
270
+
271
+ for (DWORD i = 0 ; i < ExportDirectory->NumberOfFunctions ; i++)
272
+ {
273
+ char *szName = (char *)(hModule + AddressOfNames[i]);
274
+
275
+ if (!strcmp (szFunction, szName))
276
+ return AddressOfFunctions + AddressOfNameOrdinals[i];
277
+ }
278
+
279
+ return NULL ;
280
+ }
281
+
209
282
void InstallHookEAT (HMODULE hModule, const char *szFunction, void *pHook, void **ppOriginal)
210
283
{
211
- void *pFunction = GetProcAddress (hModule, szFunction);
212
- if (!pFunction)
284
+ DWORD *Offset = FindFromEAT ((uintptr_t )hModule, szFunction);
285
+ if (!Offset)
286
+ {
287
+ HardError (" Could not hook %s" , szFunction);
213
288
return ;
289
+ }
214
290
215
- auto result = MH_CreateHook (pFunction, pHook, ppOriginal);
216
- assert (result == MH_OK);
291
+ uintptr_t HookOffset = (uintptr_t )pHook - (uintptr_t )hModule;
217
292
218
- result = MH_EnableHook (pFunction);
219
- assert (result == MH_OK);
293
+ if (HookOffset > MAX_ADDRESS_OFFSET)
294
+ {
295
+ void *pTrampoline = TrampolineNear (hModule, pHook);
296
+ if (!pTrampoline)
297
+ {
298
+ HardError (" Could not hook %s" , szFunction);
299
+ return ;
300
+ }
301
+
302
+ HookOffset = (uintptr_t )pTrampoline - (uintptr_t )hModule;
303
+ }
304
+
305
+ *ppOriginal = (void *)(*Offset + (uintptr_t )hModule);
306
+
307
+ DWORD flOldProtect;
308
+ VirtualProtect (Offset, sizeof (DWORD), PAGE_READWRITE, &flOldProtect);
309
+ *Offset = HookOffset;
310
+ VirtualProtect (Offset, sizeof (DWORD), flOldProtect, &flOldProtect);
220
311
}
221
312
222
313
static HMODULE LoadSteam (const wchar_t *szBaseDir)
@@ -234,8 +325,6 @@ static HMODULE LoadSteam(const wchar_t *szBaseDir)
234
325
235
326
void InstallSteamProxy (const wchar_t *szBaseDir)
236
327
{
237
- MH_Initialize ();
238
-
239
328
HMODULE hSteam = LoadSteam (szBaseDir);
240
329
if (!hSteam)
241
330
HardError (" Could not find Steam\n " );
0 commit comments