Textractor_test/texthook/main.cc

168 lines
4.7 KiB
C++
Raw Permalink Normal View History

2018-08-23 23:53:23 +08:00
// main.cc
// 8/24/2013 jichi
// Branch: ITH_DLL/main.cpp, rev 128
// 8/24/2013 TODO: Clean up this file
#include "main.h"
#include "defs.h"
#include "engine/match.h"
2018-11-11 12:29:12 +08:00
#include "texthook.h"
2019-06-02 14:09:17 +08:00
#include "hookfinder.h"
2019-01-04 06:52:16 +08:00
#include "util.h"
#include "MinHook.h"
2018-08-23 23:53:23 +08:00
2019-02-28 00:33:17 +08:00
extern const char* PIPE_CONNECTED;
extern const char* INSERTING_HOOK;
extern const char* REMOVING_HOOK;
extern const char* HOOK_FAILED;
extern const char* TOO_MANY_HOOKS;
WinMutex viewMutex;
2018-08-25 00:50:20 +08:00
2018-11-11 13:34:42 +08:00
namespace
{
2018-12-02 04:52:52 +08:00
AutoHandle<> hookPipe = INVALID_HANDLE_VALUE, mappedFile = INVALID_HANDLE_VALUE;
TextHook (*hooks)[MAX_HOOK];
2018-12-02 04:52:52 +08:00
int currentHook = 0;
2018-11-11 13:34:42 +08:00
}
2018-11-11 12:29:12 +08:00
DWORD WINAPI Pipe(LPVOID)
{
2019-10-04 04:00:19 +08:00
for (bool running = true; running; hookPipe = INVALID_HANDLE_VALUE)
2018-11-11 12:29:12 +08:00
{
DWORD count = 0;
BYTE buffer[PIPE_BUFFER_SIZE] = {};
2018-12-02 04:52:52 +08:00
AutoHandle<> hostPipe = INVALID_HANDLE_VALUE;
2018-11-11 12:29:12 +08:00
while (!hostPipe || !hookPipe)
2018-11-11 12:29:12 +08:00
{
WinMutex connectionMutex(CONNECTING_MUTEX, &allAccess);
std::scoped_lock lock(connectionMutex);
WaitForSingleObject(AutoHandle<>(CreateEventW(&allAccess, FALSE, FALSE, PIPE_AVAILABLE_EVENT)), INFINITE);
hostPipe = CreateFileW(HOST_PIPE, GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
hookPipe = CreateFileW(HOOK_PIPE, GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
2018-11-11 12:29:12 +08:00
}
DWORD mode = PIPE_READMODE_MESSAGE;
SetNamedPipeHandleState(hostPipe, &mode, NULL, NULL);
2018-11-11 12:29:12 +08:00
*(DWORD*)buffer = GetCurrentProcessId();
WriteFile(hookPipe, buffer, sizeof(DWORD), &count, nullptr);
2018-11-11 13:34:42 +08:00
ConsoleOutput(PIPE_CONNECTED);
2018-11-11 12:29:12 +08:00
Engine::Hijack();
while (running && ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE, &count, nullptr))
switch (*(HostCommandType*)buffer)
{
case HOST_COMMAND_NEW_HOOK:
{
auto info = *(InsertHookCmd*)buffer;
2019-06-10 13:49:11 +08:00
static int userHooks = 0;
NewHook(info.hp, ("UserHook" + std::to_string(userHooks += 1)).c_str(), 0);
}
break;
case HOST_COMMAND_REMOVE_HOOK:
{
auto info = *(RemoveHookCmd*)buffer;
2019-06-11 03:06:43 +08:00
RemoveHook(info.address, 0);
2018-11-11 12:29:12 +08:00
}
break;
2019-06-02 14:09:17 +08:00
case HOST_COMMAND_FIND_HOOK:
{
auto info = *(FindHookCmd*)buffer;
if (*info.sp.text) SearchForText(info.sp.text, info.sp.codepage);
else SearchForHooks(info.sp);
2019-06-02 14:09:17 +08:00
}
break;
2018-11-11 12:29:12 +08:00
case HOST_COMMAND_DETACH:
{
running = false;
}
break;
}
}
2019-10-04 04:00:19 +08:00
MH_Uninitialize();
for (auto& hook : *hooks) hook.Clear();
2018-11-11 12:29:12 +08:00
FreeLibraryAndExitThread(GetModuleHandleW(ITH_DLL), 0);
}
2020-03-24 09:37:11 +08:00
void TextOutput(ThreadParam tp, BYTE (*buffer)[PIPE_BUFFER_SIZE], int len)
2018-11-11 12:29:12 +08:00
{
2020-03-24 09:37:11 +08:00
if (len < 0 || len > PIPE_BUFFER_SIZE - sizeof(tp)) ConsoleOutput("Textractor: something went very wrong (invalid length %d at hook address %I64d)", len, tp.addr);
2018-11-11 12:29:12 +08:00
*(ThreadParam*)buffer = tp;
2019-06-04 05:58:30 +08:00
WriteFile(hookPipe, buffer, sizeof(tp) + len, DUMMY, nullptr);
2018-11-11 12:29:12 +08:00
}
2018-12-02 04:52:52 +08:00
void ConsoleOutput(LPCSTR text, ...)
2018-11-11 12:29:12 +08:00
{
2018-12-02 04:52:52 +08:00
ConsoleOutputNotif buffer;
va_list args;
va_start(args, text);
2019-06-02 14:09:17 +08:00
vsnprintf(buffer.message, MESSAGE_SIZE, text, args);
2019-06-04 05:58:30 +08:00
WriteFile(hookPipe, &buffer, sizeof(buffer), DUMMY, nullptr);
2019-06-02 14:09:17 +08:00
}
void NotifyHookFound(HookParam hp, wchar_t* text)
2019-06-02 14:09:17 +08:00
{
HookFoundNotif buffer(hp, text);
2019-06-04 05:58:30 +08:00
WriteFile(hookPipe, &buffer, sizeof(buffer), DUMMY, nullptr);
2018-11-11 12:29:12 +08:00
}
2019-02-28 00:33:17 +08:00
void NotifyHookRemove(uint64_t addr, LPCSTR name)
2018-11-11 12:29:12 +08:00
{
2019-02-28 00:33:17 +08:00
if (name) ConsoleOutput(REMOVING_HOOK, name);
2018-11-11 12:29:12 +08:00
HookRemovedNotif buffer(addr);
2019-06-04 05:58:30 +08:00
WriteFile(hookPipe, &buffer, sizeof(buffer), DUMMY, nullptr);
2018-11-11 12:29:12 +08:00
}
2018-09-21 10:42:15 +08:00
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
2018-08-23 23:53:23 +08:00
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
viewMutex = WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(GetCurrentProcessId()), &allAccess);
2018-08-23 23:53:23 +08:00
if (GetLastError() == ERROR_ALREADY_EXISTS) return FALSE;
DisableThreadLibraryCalls(hModule);
// jichi 9/25/2013: Interprocedural communication with vnrsrv.
mappedFile = CreateFileMappingW(INVALID_HANDLE_VALUE, &allAccess, PAGE_EXECUTE_READWRITE, 0, HOOK_SECTION_SIZE, (ITH_SECTION_ + std::to_wstring(GetCurrentProcessId())).c_str());
hooks = (TextHook(*)[MAX_HOOK])MapViewOfFile(mappedFile, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, HOOK_BUFFER_SIZE);
2018-11-11 12:29:12 +08:00
memset(hooks, 0, HOOK_BUFFER_SIZE);
2018-08-23 23:53:23 +08:00
2018-08-26 03:45:25 +08:00
MH_Initialize();
2018-08-23 23:53:23 +08:00
CloseHandle(CreateThread(nullptr, 0, Pipe, nullptr, 0, nullptr)); // Using std::thread here = deadlock
2018-08-23 23:53:23 +08:00
}
break;
case DLL_PROCESS_DETACH:
{
2018-11-11 13:34:42 +08:00
MH_Uninitialize();
2019-10-04 04:00:19 +08:00
UnmapViewOfFile(hooks);
2018-08-23 23:53:23 +08:00
}
break;
}
return TRUE;
}
2018-11-11 12:29:12 +08:00
void NewHook(HookParam hp, LPCSTR lpname, DWORD flag)
2018-08-23 23:53:23 +08:00
{
if (++currentHook >= MAX_HOOK) return ConsoleOutput(TOO_MANY_HOOKS);
if (lpname && *lpname) strncpy_s(hp.name, lpname, HOOK_NAME_SIZE - 1);
ConsoleOutput(INSERTING_HOOK, hp.name);
RemoveHook(hp.address, 0);
if (!(*hooks)[currentHook].Insert(hp, flag))
2019-01-04 06:52:16 +08:00
{
ConsoleOutput(HOOK_FAILED);
(*hooks)[currentHook].Clear();
2019-01-04 06:52:16 +08:00
}
2018-08-23 23:53:23 +08:00
}
2018-08-26 03:45:25 +08:00
2019-06-11 03:06:43 +08:00
void RemoveHook(uint64_t addr, int maxOffset)
2018-08-23 23:53:23 +08:00
{
2019-06-11 03:06:43 +08:00
for (auto& hook : *hooks) if (abs((long long)(hook.address - addr)) <= maxOffset) return hook.Clear();
2018-08-23 23:53:23 +08:00
}
2018-12-21 23:10:51 +08:00
// EOF