Textractor_test/vnrhook/main.cc

171 lines
4.5 KiB
C++
Raw 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
#ifdef _MSC_VER
# pragma warning (disable:4100) // C4100: unreference formal parameter
//# pragma warning (disable:4733) // C4733: Inline asm assigning to 'FS:0' : handler not registered as safe handler
#endif // _MSC_VER
#include "main.h"
#include "defs.h"
2018-11-11 13:34:42 +08:00
#include "text.h"
2018-08-26 03:45:25 +08:00
#include "MinHook.h"
2018-08-23 23:53:23 +08:00
#include "engine/engine.h"
#include "engine/match.h"
2018-11-11 12:29:12 +08:00
#include "texthook.h"
2018-08-23 23:53:23 +08:00
#include "util/growl.h"
std::unique_ptr<WinMutex> sectionMutex;
2018-08-25 00:50:20 +08:00
2018-11-11 13:34:42 +08:00
namespace
{
HANDLE hSection, hookPipe;
TextHook* hooks;
bool running;
int currentHook = 0, userhookCount = 0;
DWORD DUMMY;
}
2018-11-11 12:29:12 +08:00
DWORD WINAPI Pipe(LPVOID)
{
while (running)
{
DWORD count = 0;
BYTE buffer[PIPE_BUFFER_SIZE] = {};
HANDLE hostPipe = hookPipe = INVALID_HANDLE_VALUE;
while (hookPipe == INVALID_HANDLE_VALUE || hostPipe == INVALID_HANDLE_VALUE)
{
if (hookPipe == INVALID_HANDLE_VALUE)
{
hookPipe = CreateFileW(HOOK_PIPE, GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
}
if (hookPipe != INVALID_HANDLE_VALUE && hostPipe == INVALID_HANDLE_VALUE)
{
hostPipe = CreateFileW(HOST_PIPE, GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
DWORD mode = PIPE_READMODE_MESSAGE;
SetNamedPipeHandleState(hostPipe, &mode, NULL, NULL);
continue;
}
Sleep(50);
}
*(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
#ifdef _WIN64
2018-11-11 13:34:42 +08:00
ConsoleOutput(DISABLE_HOOKS);
2018-11-11 12:29:12 +08:00
#else
Engine::Hijack();
#endif
while (running && ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE, &count, nullptr))
switch (*(HostCommandType*)buffer)
{
case HOST_COMMAND_NEW_HOOK:
{
auto info = *(InsertHookCmd*)buffer;
NewHook(info.hp, info.name, 0);
}
break;
case HOST_COMMAND_DETACH:
{
running = false;
}
break;
}
CloseHandle(hostPipe);
CloseHandle(hookPipe);
}
FreeLibraryAndExitThread(GetModuleHandleW(ITH_DLL), 0);
return 0;
}
void TextOutput(ThreadParam tp, BYTE* text, int len)
{
if (len < 0) return;
2018-11-28 04:56:28 +08:00
if (len > PIPE_BUFFER_SIZE - sizeof(ThreadParam)) len = PIPE_BUFFER_SIZE - sizeof(ThreadParam);
2018-11-11 12:29:12 +08:00
BYTE buffer[PIPE_BUFFER_SIZE] = {};
*(ThreadParam*)buffer = tp;
2018-11-28 04:56:28 +08:00
memcpy(buffer + sizeof(ThreadParam), text, len);
2018-11-11 12:29:12 +08:00
WriteFile(hookPipe, buffer, sizeof(ThreadParam) + len, &DUMMY, nullptr);
}
void ConsoleOutput(LPCSTR text)
{
ConsoleOutputNotif buffer(text);
WriteFile(hookPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
}
void ConsoleOutput(std::string text)
{
ConsoleOutput(text.c_str());
}
void NotifyHookRemove(uint64_t addr)
{
HookRemovedNotif buffer(addr);
WriteFile(hookPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
}
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:
{
sectionMutex = std::make_unique<WinMutex>(ITH_HOOKMAN_MUTEX_ + std::to_wstring(GetCurrentProcessId()));
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.
hSection = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_EXECUTE_READWRITE, 0, HOOK_SECTION_SIZE, (ITH_SECTION_ + std::to_wstring(GetCurrentProcessId())).c_str());
2018-11-11 12:29:12 +08:00
hooks = (TextHook*)MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, HOOK_BUFFER_SIZE);
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-11-11 12:29:12 +08:00
running = true;
2018-08-23 23:53:23 +08:00
2018-11-11 13:34:42 +08:00
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 12:29:12 +08:00
running = false;
for (int i = 0; i < MAX_HOOK; ++i) if (hooks[i].hp.insertion_address) hooks[i].ClearHook();
UnmapViewOfFile(hooks);
2018-11-11 13:34:42 +08:00
MH_Uninitialize();
2018-08-23 23:53:23 +08:00
CloseHandle(hSection);
}
break;
}
return TRUE;
}
//extern "C" {
2018-11-11 12:29:12 +08:00
void NewHook(HookParam hp, LPCSTR lpname, DWORD flag)
2018-08-23 23:53:23 +08:00
{
std::string name = lpname;
2018-11-28 04:56:28 +08:00
if (++currentHook < MAX_HOOK)
2018-08-26 03:45:25 +08:00
{
2018-11-28 04:56:28 +08:00
if (name.empty()) name = "UserHook " + std::to_string(userhookCount++);
2018-11-11 13:34:42 +08:00
ConsoleOutput(INSERTING_HOOK + name);
2018-08-23 23:53:23 +08:00
// jichi 7/13/2014: This function would raise when too many hooks added
2018-11-11 12:29:12 +08:00
hooks[currentHook].InitHook(hp, name.c_str(), flag);
2018-11-11 13:34:42 +08:00
if (!hooks[currentHook].InsertHook()) ConsoleOutput(HOOK_FAILED);
2018-08-23 23:53:23 +08:00
}
2018-11-11 13:34:42 +08:00
else ConsoleOutput(TOO_MANY_HOOKS);
2018-08-23 23:53:23 +08:00
}
2018-08-26 03:45:25 +08:00
2018-09-21 09:59:07 +08:00
void RemoveHook(uint64_t addr)
2018-08-23 23:53:23 +08:00
{
for (int i = 0; i < MAX_HOOK; i++)
2018-11-11 12:29:12 +08:00
if (abs((long long)(hooks[i].hp.insertion_address - addr)) < 9) return hooks[i].ClearHook();
2018-08-23 23:53:23 +08:00
}
// EOF