Skip to content

Commit 231debc

Browse files
committed
Log when hooks are installed, install hooks after libraries are loaded post-initial-install
1 parent d75865f commit 231debc

10 files changed

Lines changed: 363 additions & 200 deletions

File tree

LANCommander.Interposer/dll/src/borderless.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -207,25 +207,30 @@ static LONG WINAPI HookSetWindowLongA(HWND hwnd, int nIndex, LONG dwNewLong)
207207
// ---------------------------------------------------------------------------
208208
void InstallBorderlessHooks()
209209
{
210-
MH_CreateHookApi(L"user32", "CreateWindowExW",
211-
reinterpret_cast<LPVOID>(HookCreateWindowExW),
212-
reinterpret_cast<LPVOID*>(&g_origCreateWindowExW));
213-
214-
MH_CreateHookApi(L"user32", "CreateWindowExA",
215-
reinterpret_cast<LPVOID>(HookCreateWindowExA),
216-
reinterpret_cast<LPVOID*>(&g_origCreateWindowExA));
217-
218-
MH_CreateHookApi(L"user32", "SetWindowPos",
219-
reinterpret_cast<LPVOID>(HookSetWindowPos),
220-
reinterpret_cast<LPVOID*>(&g_origSetWindowPos));
221-
222-
MH_CreateHookApi(L"user32", "SetWindowLongW",
223-
reinterpret_cast<LPVOID>(HookSetWindowLongW),
224-
reinterpret_cast<LPVOID*>(&g_origSetWindowLongW));
225-
226-
MH_CreateHookApi(L"user32", "SetWindowLongA",
227-
reinterpret_cast<LPVOID>(HookSetWindowLongA),
228-
reinterpret_cast<LPVOID*>(&g_origSetWindowLongA));
210+
LogHookInit(L"user32", "CreateWindowExW",
211+
MH_CreateHookApi(L"user32", "CreateWindowExW",
212+
reinterpret_cast<LPVOID>(HookCreateWindowExW),
213+
reinterpret_cast<LPVOID*>(&g_origCreateWindowExW)));
214+
215+
LogHookInit(L"user32", "CreateWindowExA",
216+
MH_CreateHookApi(L"user32", "CreateWindowExA",
217+
reinterpret_cast<LPVOID>(HookCreateWindowExA),
218+
reinterpret_cast<LPVOID*>(&g_origCreateWindowExA)));
219+
220+
LogHookInit(L"user32", "SetWindowPos",
221+
MH_CreateHookApi(L"user32", "SetWindowPos",
222+
reinterpret_cast<LPVOID>(HookSetWindowPos),
223+
reinterpret_cast<LPVOID*>(&g_origSetWindowPos)));
224+
225+
LogHookInit(L"user32", "SetWindowLongW",
226+
MH_CreateHookApi(L"user32", "SetWindowLongW",
227+
reinterpret_cast<LPVOID>(HookSetWindowLongW),
228+
reinterpret_cast<LPVOID*>(&g_origSetWindowLongW)));
229+
230+
LogHookInit(L"user32", "SetWindowLongA",
231+
MH_CreateHookApi(L"user32", "SetWindowLongA",
232+
reinterpret_cast<LPVOID>(HookSetWindowLongA),
233+
reinterpret_cast<LPVOID*>(&g_origSetWindowLongA)));
229234
}
230235

231236
void ForceBorderless(HWND hwnd)

LANCommander.Interposer/dll/src/config.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,19 @@ void LogNetworkAccess(const wchar_t* verb, const wchar_t* address, const wchar_t
230230
WriteLogLine(verb, address, info);
231231
}
232232

233+
void LogHookInit(const wchar_t* module, const char* fn, MH_STATUS status)
234+
{
235+
if (status == MH_ERROR_ALREADY_CREATED)
236+
return; // Hook was already installed (e.g. late-install called twice); not an error.
237+
238+
wchar_t msg[128]{};
239+
if (status == MH_OK)
240+
wsprintfW(msg, L"%s!%S", module, fn);
241+
else
242+
wsprintfW(msg, L"%s!%S %S", module, fn, MH_StatusToString(status));
243+
WriteLogLine(L"HOOK INIT", msg, nullptr);
244+
}
245+
233246
void CloseLog()
234247
{
235248
std::lock_guard<std::mutex> lk(g_logMutex);

LANCommander.Interposer/dll/src/config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define WIN32_LEAN_AND_MEAN
33
#define NOMINMAX
44
#include <windows.h>
5+
#include <MinHook.h>
56
#include <string>
67
#include <vector>
78
#include <regex>
@@ -57,6 +58,10 @@ void LogRegistryAccess(const wchar_t* verb, const wchar_t* keyPath, const wchar_
5758
void LogFastDLAccess(const wchar_t* verb, const wchar_t* url, const wchar_t* localPath);
5859
void LogNetworkAccess(const wchar_t* verb, const wchar_t* address, const wchar_t* info = nullptr);
5960

61+
// Log a MinHook hook installation result. Always written regardless of other logging flags.
62+
// Pass the MH_STATUS value returned by MH_CreateHookApi.
63+
void LogHookInit(const wchar_t* module, const char* fn, MH_STATUS status);
64+
6065
// ---------------------------------------------------------------------------
6166
// Plugin API — exported by name, resolved by plugins via GetProcAddress.
6267
// ---------------------------------------------------------------------------

LANCommander.Interposer/dll/src/files.cpp

Lines changed: 82 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "files.h"
22
#include "config.h"
33
#include "fastdl.h"
4+
#include "hooks.h"
45

56
#include <windows.h>
67
#include <MinHook.h>
@@ -301,7 +302,9 @@ static HMODULE WINAPI HookLoadLibraryW(LPCWSTR lpLibFileName)
301302
else
302303
LogFileAccess(L"DLL LOAD", path.c_str());
303304

304-
return g_origLoadLibraryW(redirected.c_str());
305+
HMODULE hMod = g_origLoadLibraryW(redirected.c_str());
306+
OnLibraryLoaded(hMod);
307+
return hMod;
305308
}
306309

307310
static HMODULE WINAPI HookLoadLibraryA(LPCSTR lpLibFileName)
@@ -318,15 +321,20 @@ static HMODULE WINAPI HookLoadLibraryA(LPCSTR lpLibFileName)
318321

319322
std::wstring redirected = ApplyFileRedirects(widePath);
320323

324+
HMODULE hMod;
321325
if (redirected != widePath)
322326
{
323327
LogFileAccess(L"FILE REDIRECT", widePath.c_str(), redirected.c_str());
324328
// Use the W trampoline since we already have a wide redirected path
325-
return g_origLoadLibraryW(redirected.c_str());
329+
hMod = g_origLoadLibraryW(redirected.c_str());
326330
}
327-
328-
LogFileAccess(L"DLL LOAD", widePath.c_str());
329-
return g_origLoadLibraryA(lpLibFileName);
331+
else
332+
{
333+
LogFileAccess(L"DLL LOAD", widePath.c_str());
334+
hMod = g_origLoadLibraryA(lpLibFileName);
335+
}
336+
OnLibraryLoaded(hMod);
337+
return hMod;
330338
}
331339

332340
static HMODULE WINAPI HookLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
@@ -342,7 +350,13 @@ static HMODULE WINAPI HookLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DW
342350
else
343351
LogFileAccess(L"DLL LOAD", path.c_str());
344352

345-
return g_origLoadLibraryExW(redirected.c_str(), hFile, dwFlags);
353+
HMODULE hMod = g_origLoadLibraryExW(redirected.c_str(), hFile, dwFlags);
354+
constexpr DWORD dataFlags = LOAD_LIBRARY_AS_DATAFILE
355+
| LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
356+
| LOAD_LIBRARY_AS_IMAGE_RESOURCE;
357+
if (!(dwFlags & dataFlags))
358+
OnLibraryLoaded(hMod);
359+
return hMod;
346360
}
347361

348362
static HMODULE WINAPI HookLoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
@@ -359,58 +373,77 @@ static HMODULE WINAPI HookLoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWO
359373

360374
std::wstring redirected = ApplyFileRedirects(widePath);
361375

376+
HMODULE hMod;
362377
if (redirected != widePath)
363378
{
364379
LogFileAccess(L"FILE REDIRECT", widePath.c_str(), redirected.c_str());
365-
return g_origLoadLibraryExW(redirected.c_str(), hFile, dwFlags);
380+
hMod = g_origLoadLibraryExW(redirected.c_str(), hFile, dwFlags);
366381
}
367-
368-
LogFileAccess(L"DLL LOAD", widePath.c_str());
369-
return g_origLoadLibraryExA(lpLibFileName, hFile, dwFlags);
382+
else
383+
{
384+
LogFileAccess(L"DLL LOAD", widePath.c_str());
385+
hMod = g_origLoadLibraryExA(lpLibFileName, hFile, dwFlags);
386+
}
387+
constexpr DWORD dataFlags = LOAD_LIBRARY_AS_DATAFILE
388+
| LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
389+
| LOAD_LIBRARY_AS_IMAGE_RESOURCE;
390+
if (!(dwFlags & dataFlags))
391+
OnLibraryLoaded(hMod);
392+
return hMod;
370393
}
371394

372395
// ---------------------------------------------------------------------------
373396
// Public API
374397
// ---------------------------------------------------------------------------
375398
void InstallFileHooks()
376399
{
377-
MH_CreateHookApi(L"kernel32", "CreateFileW",
378-
reinterpret_cast<LPVOID>(HookCreateFileW),
379-
reinterpret_cast<LPVOID*>(&g_origCreateFileW));
380-
381-
MH_CreateHookApi(L"kernel32", "CreateFileA",
382-
reinterpret_cast<LPVOID>(HookCreateFileA),
383-
reinterpret_cast<LPVOID*>(&g_origCreateFileA));
384-
385-
MH_CreateHookApi(L"kernel32", "GetFileAttributesW",
386-
reinterpret_cast<LPVOID>(HookGetFileAttributesW),
387-
reinterpret_cast<LPVOID*>(&g_origGetFileAttributesW));
388-
389-
MH_CreateHookApi(L"kernel32", "GetFileAttributesA",
390-
reinterpret_cast<LPVOID>(HookGetFileAttributesA),
391-
reinterpret_cast<LPVOID*>(&g_origGetFileAttributesA));
392-
393-
MH_CreateHookApi(L"kernel32", "FindFirstFileW",
394-
reinterpret_cast<LPVOID>(HookFindFirstFileW),
395-
reinterpret_cast<LPVOID*>(&g_origFindFirstFileW));
396-
397-
MH_CreateHookApi(L"kernel32", "FindFirstFileA",
398-
reinterpret_cast<LPVOID>(HookFindFirstFileA),
399-
reinterpret_cast<LPVOID*>(&g_origFindFirstFileA));
400-
401-
MH_CreateHookApi(L"kernel32", "LoadLibraryW",
402-
reinterpret_cast<LPVOID>(HookLoadLibraryW),
403-
reinterpret_cast<LPVOID*>(&g_origLoadLibraryW));
404-
405-
MH_CreateHookApi(L"kernel32", "LoadLibraryA",
406-
reinterpret_cast<LPVOID>(HookLoadLibraryA),
407-
reinterpret_cast<LPVOID*>(&g_origLoadLibraryA));
408-
409-
MH_CreateHookApi(L"kernel32", "LoadLibraryExW",
410-
reinterpret_cast<LPVOID>(HookLoadLibraryExW),
411-
reinterpret_cast<LPVOID*>(&g_origLoadLibraryExW));
412-
413-
MH_CreateHookApi(L"kernel32", "LoadLibraryExA",
414-
reinterpret_cast<LPVOID>(HookLoadLibraryExA),
415-
reinterpret_cast<LPVOID*>(&g_origLoadLibraryExA));
400+
LogHookInit(L"kernel32", "CreateFileW",
401+
MH_CreateHookApi(L"kernel32", "CreateFileW",
402+
reinterpret_cast<LPVOID>(HookCreateFileW),
403+
reinterpret_cast<LPVOID*>(&g_origCreateFileW)));
404+
405+
LogHookInit(L"kernel32", "CreateFileA",
406+
MH_CreateHookApi(L"kernel32", "CreateFileA",
407+
reinterpret_cast<LPVOID>(HookCreateFileA),
408+
reinterpret_cast<LPVOID*>(&g_origCreateFileA)));
409+
410+
LogHookInit(L"kernel32", "GetFileAttributesW",
411+
MH_CreateHookApi(L"kernel32", "GetFileAttributesW",
412+
reinterpret_cast<LPVOID>(HookGetFileAttributesW),
413+
reinterpret_cast<LPVOID*>(&g_origGetFileAttributesW)));
414+
415+
LogHookInit(L"kernel32", "GetFileAttributesA",
416+
MH_CreateHookApi(L"kernel32", "GetFileAttributesA",
417+
reinterpret_cast<LPVOID>(HookGetFileAttributesA),
418+
reinterpret_cast<LPVOID*>(&g_origGetFileAttributesA)));
419+
420+
LogHookInit(L"kernel32", "FindFirstFileW",
421+
MH_CreateHookApi(L"kernel32", "FindFirstFileW",
422+
reinterpret_cast<LPVOID>(HookFindFirstFileW),
423+
reinterpret_cast<LPVOID*>(&g_origFindFirstFileW)));
424+
425+
LogHookInit(L"kernel32", "FindFirstFileA",
426+
MH_CreateHookApi(L"kernel32", "FindFirstFileA",
427+
reinterpret_cast<LPVOID>(HookFindFirstFileA),
428+
reinterpret_cast<LPVOID*>(&g_origFindFirstFileA)));
429+
430+
LogHookInit(L"kernel32", "LoadLibraryW",
431+
MH_CreateHookApi(L"kernel32", "LoadLibraryW",
432+
reinterpret_cast<LPVOID>(HookLoadLibraryW),
433+
reinterpret_cast<LPVOID*>(&g_origLoadLibraryW)));
434+
435+
LogHookInit(L"kernel32", "LoadLibraryA",
436+
MH_CreateHookApi(L"kernel32", "LoadLibraryA",
437+
reinterpret_cast<LPVOID>(HookLoadLibraryA),
438+
reinterpret_cast<LPVOID*>(&g_origLoadLibraryA)));
439+
440+
LogHookInit(L"kernel32", "LoadLibraryExW",
441+
MH_CreateHookApi(L"kernel32", "LoadLibraryExW",
442+
reinterpret_cast<LPVOID>(HookLoadLibraryExW),
443+
reinterpret_cast<LPVOID*>(&g_origLoadLibraryExW)));
444+
445+
LogHookInit(L"kernel32", "LoadLibraryExA",
446+
MH_CreateHookApi(L"kernel32", "LoadLibraryExA",
447+
reinterpret_cast<LPVOID>(HookLoadLibraryExA),
448+
reinterpret_cast<LPVOID*>(&g_origLoadLibraryExA)));
416449
}

LANCommander.Interposer/dll/src/hooks.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ void InstallHooks()
3232
LoadPlugins();
3333
}
3434

35+
void OnLibraryLoaded(HMODULE hModule)
36+
{
37+
if (!hModule) return;
38+
39+
wchar_t path[MAX_PATH]{};
40+
GetModuleFileNameW(hModule, path, MAX_PATH);
41+
42+
const wchar_t* slash = wcsrchr(path, L'\\');
43+
const wchar_t* name = slash ? slash + 1 : path;
44+
45+
LateInstallNetworkHooks(name);
46+
}
47+
3548
void RemoveHooks()
3649
{
3750
UnloadPlugins();

LANCommander.Interposer/dll/src/hooks.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@ void InstallHooks();
88

99
// Remove all hooks and uninitialize MinHook. Called from DllMain on DLL_PROCESS_DETACH.
1010
void RemoveHooks();
11+
12+
// Called from LoadLibrary hooks after a DLL is successfully loaded.
13+
// Checks whether any hooks that failed at startup (module not yet loaded) can
14+
// now be installed for the newly loaded module and enables them.
15+
void OnLibraryLoaded(HMODULE hModule);

LANCommander.Interposer/dll/src/identity.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -208,23 +208,27 @@ void InstallIdentityHooks()
208208

209209
if (!g_username.empty())
210210
{
211-
MH_CreateHookApi(L"advapi32", "GetUserNameW",
212-
reinterpret_cast<LPVOID>(HookGetUserNameW),
213-
reinterpret_cast<LPVOID*>(&g_origGetUserNameW));
214-
215-
MH_CreateHookApi(L"advapi32", "GetUserNameA",
216-
reinterpret_cast<LPVOID>(HookGetUserNameA),
217-
reinterpret_cast<LPVOID*>(&g_origGetUserNameA));
211+
LogHookInit(L"advapi32", "GetUserNameW",
212+
MH_CreateHookApi(L"advapi32", "GetUserNameW",
213+
reinterpret_cast<LPVOID>(HookGetUserNameW),
214+
reinterpret_cast<LPVOID*>(&g_origGetUserNameW)));
215+
216+
LogHookInit(L"advapi32", "GetUserNameA",
217+
MH_CreateHookApi(L"advapi32", "GetUserNameA",
218+
reinterpret_cast<LPVOID>(HookGetUserNameA),
219+
reinterpret_cast<LPVOID*>(&g_origGetUserNameA)));
218220
}
219221

220222
if (!g_computername.empty())
221223
{
222-
MH_CreateHookApi(L"kernel32", "GetComputerNameW",
223-
reinterpret_cast<LPVOID>(HookGetComputerNameW),
224-
reinterpret_cast<LPVOID*>(&g_origGetComputerNameW));
225-
226-
MH_CreateHookApi(L"kernel32", "GetComputerNameA",
227-
reinterpret_cast<LPVOID>(HookGetComputerNameA),
228-
reinterpret_cast<LPVOID*>(&g_origGetComputerNameA));
224+
LogHookInit(L"kernel32", "GetComputerNameW",
225+
MH_CreateHookApi(L"kernel32", "GetComputerNameW",
226+
reinterpret_cast<LPVOID>(HookGetComputerNameW),
227+
reinterpret_cast<LPVOID*>(&g_origGetComputerNameW)));
228+
229+
LogHookInit(L"kernel32", "GetComputerNameA",
230+
MH_CreateHookApi(L"kernel32", "GetComputerNameA",
231+
reinterpret_cast<LPVOID>(HookGetComputerNameA),
232+
reinterpret_cast<LPVOID*>(&g_origGetComputerNameA)));
229233
}
230234
}

0 commit comments

Comments
 (0)