Skip to content

Commit c865a80

Browse files
committed
replace minhook with eat hook
1 parent 4c4b4c8 commit c865a80

File tree

6 files changed

+105
-26
lines changed

6 files changed

+105
-26
lines changed

.gitmodules

Lines changed: 0 additions & 3 deletions
This file was deleted.

external/minhook

Lines changed: 0 additions & 1 deletion
This file was deleted.

proxy/CMakeLists.txt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,6 @@ add_compile_definitions(STEAM_API_NODLL)
4343

4444
add_executable(gc_proxy WIN32 ${PROXY_SRC})
4545

46-
# minhook...
47-
file(GLOB_RECURSE MINHOOK_SRC ${SRC_DIR}/external/minhook/*.c)
48-
source_group("MinHook" FILES ${MINHOOK_SRC})
49-
50-
target_sources(gc_proxy PRIVATE ${MINHOOK_SRC})
51-
target_include_directories(gc_proxy PRIVATE ${SRC_DIR}/external/minhook/include)
52-
5346
# for protobuf
5447
set_property(TARGET gc_proxy PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
5548

proxy/launcher_win.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ int main(int argc, char **argv)
5858
wchar_t szEngine2Path[MAX_PATH];
5959
char szBaseDirUTF8[MAX_PATH];
6060

61+
// do this first (schizo)
62+
InstallSteamProxy(szBaseDir);
63+
6164
if (!GetModuleFileNameW(NULL, szBaseDir, ARRAYSIZE(szBaseDir)))
6265
{
6366
MessageBoxW(NULL, L"GetModuleFileName failed", L"Launcher Error", MB_OK);
@@ -92,8 +95,6 @@ int main(int argc, char **argv)
9295
return 1;
9396
}
9497

95-
InstallSteamProxy(szBaseDir);
96-
9798
const char *szGameName = "csgo";
9899

99100
// the engine does have a check for -game, however it's only considered if we pass null as game name to Source2Main

proxy/plat_win.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ConColorMsg_t ConColorMsg;
66

77
void InitLog()
88
{
9-
HMODULE hTier0 = GetModuleHandleW(L"tier0.dll");
9+
HMODULE hTier0 = LoadLibraryExW(L"tier0.dll", NULL, 0);
1010
if (!hTier0)
1111
return;
1212

proxy/steam_proxy.cpp

Lines changed: 101 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#include "precompiled.h"
22
#include <windows.h>
33

4-
// remove eventually
5-
#include <MinHook.h>
6-
74
#if defined(_M_X64)
85
#define STEAM_API L"steam_api64.dll"
96
#else
@@ -205,18 +202,112 @@ void *Hk_SteamInternal_CreateInterface(const char *ver)
205202

206203
//-------------------------------------
207204

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+
209282
void InstallHookEAT(HMODULE hModule, const char *szFunction, void *pHook, void **ppOriginal)
210283
{
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);
213288
return;
289+
}
214290

215-
auto result = MH_CreateHook(pFunction, pHook, ppOriginal);
216-
assert(result == MH_OK);
291+
uintptr_t HookOffset = (uintptr_t)pHook - (uintptr_t)hModule;
217292

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);
220311
}
221312

222313
static HMODULE LoadSteam(const wchar_t *szBaseDir)
@@ -234,8 +325,6 @@ static HMODULE LoadSteam(const wchar_t *szBaseDir)
234325

235326
void InstallSteamProxy(const wchar_t *szBaseDir)
236327
{
237-
MH_Initialize();
238-
239328
HMODULE hSteam = LoadSteam(szBaseDir);
240329
if (!hSteam)
241330
HardError("Could not find Steam\n");

0 commit comments

Comments
 (0)