2016-01-06 00:01:17 +09:00
|
|
|
// pipe.cc
|
|
|
|
// 8/24/2013 jichi
|
|
|
|
// Branch: ITH_DLL/pipe.cpp, rev 66
|
|
|
|
// 8/24/2013 TODO: Clean up this file
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
# pragma warning (disable:4100) // C4100: unreference formal parameter
|
|
|
|
#endif // _MSC_VER
|
|
|
|
|
|
|
|
#include "src/hijack/texthook.h"
|
|
|
|
#include "src/engine/match.h"
|
|
|
|
#include "src/util/util.h"
|
|
|
|
#include "src/main.h"
|
|
|
|
#include "include/defs.h"
|
2018-05-20 13:11:55 -04:00
|
|
|
#include "src/util/growl.h"
|
2016-01-06 00:01:17 +09:00
|
|
|
#include "ithsys/ithsys.h"
|
|
|
|
#include <cstdio> // for swprintf
|
|
|
|
|
2018-05-20 16:10:07 -04:00
|
|
|
HANDLE hookPipe;
|
2018-06-13 21:52:45 -04:00
|
|
|
extern HMODULE currentModule;
|
2016-01-06 00:01:17 +09:00
|
|
|
|
2018-05-20 13:11:55 -04:00
|
|
|
DWORD WINAPI PipeManager(LPVOID unused)
|
|
|
|
{
|
2018-07-16 14:04:21 -04:00
|
|
|
enum { STANDARD_WAIT = 50 };
|
2018-05-20 13:11:55 -04:00
|
|
|
while (::running)
|
|
|
|
{
|
|
|
|
DWORD count;
|
2018-07-12 13:59:05 -04:00
|
|
|
BYTE buffer[PIPE_BUFFER_SIZE];
|
2018-05-20 13:11:55 -04:00
|
|
|
HANDLE hostPipe = ::hookPipe = INVALID_HANDLE_VALUE,
|
|
|
|
pipeAcquisitionMutex = CreateMutexW(nullptr, TRUE, ITH_GRANTPIPE_MUTEX);
|
|
|
|
|
|
|
|
while (::hookPipe == INVALID_HANDLE_VALUE || hostPipe == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
Sleep(STANDARD_WAIT);
|
|
|
|
if (::hookPipe == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
::hookPipe = CreateFileW(ITH_TEXT_PIPE, GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
|
|
|
}
|
|
|
|
if (hostPipe == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
hostPipe = CreateFileW(ITH_COMMAND_PIPE, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-13 21:52:45 -04:00
|
|
|
*(DWORD*)buffer = GetCurrentProcessId();
|
2018-07-13 20:51:09 -04:00
|
|
|
WriteFile(::hookPipe, buffer, sizeof(DWORD), &count, nullptr);
|
2018-05-20 13:11:55 -04:00
|
|
|
|
|
|
|
for (int i = 0, count = 0; count < ::currentHook; i++)
|
|
|
|
{
|
|
|
|
if (hookman[i].RecoverHook()) // jichi 9/27/2013: This is the place where built-in hooks like TextOutA are inserted
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReleaseMutex(pipeAcquisitionMutex);
|
|
|
|
CloseHandle(pipeAcquisitionMutex);
|
|
|
|
|
|
|
|
::live = true;
|
|
|
|
Engine::hijack();
|
|
|
|
ConsoleOutput("vnrcli:WaitForPipe: pipe connected");
|
|
|
|
|
|
|
|
while (::running)
|
|
|
|
{
|
|
|
|
Sleep(STANDARD_WAIT);
|
2018-05-21 04:05:09 -04:00
|
|
|
if (!ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE / 2, &count, nullptr)) // Artikash 5/21/2018: why / 2? wchar_t?
|
2018-05-20 13:11:55 -04:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
DWORD command = *(DWORD*)buffer;
|
|
|
|
switch (command)
|
|
|
|
{
|
|
|
|
case HOST_COMMAND_NEW_HOOK:
|
|
|
|
buffer[count] = 0;
|
|
|
|
NewHook(*(HookParam *)(buffer + 4), (LPSTR)(buffer + 4 + sizeof(HookParam)), 0);
|
|
|
|
break;
|
2018-05-20 16:10:07 -04:00
|
|
|
case HOST_COMMAND_REMOVE_HOOK:
|
|
|
|
{
|
|
|
|
DWORD removalAddress = *(DWORD *)(buffer + 4);
|
|
|
|
HANDLE hookRemovalEvent = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, ITH_REMOVEHOOK_EVENT);
|
|
|
|
|
|
|
|
TextHook *in = hookman;
|
|
|
|
for (int i = 0; i < currentHook; in++)
|
|
|
|
{
|
|
|
|
if (in->Address()) i++;
|
|
|
|
if (in->Address() == removalAddress)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (in->Address())
|
|
|
|
{
|
|
|
|
in->ClearHook();
|
|
|
|
}
|
|
|
|
|
|
|
|
SetEvent(hookRemovalEvent);
|
|
|
|
CloseHandle(hookRemovalEvent);
|
|
|
|
}
|
|
|
|
break;
|
2018-05-20 13:11:55 -04:00
|
|
|
case HOST_COMMAND_DETACH:
|
|
|
|
::running = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
::live = false;
|
|
|
|
for (int i = 0, count = 0; count < ::currentHook; i++)
|
|
|
|
{
|
|
|
|
if (hookman[i].RemoveHook())
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CloseHandle(::hookPipe);
|
|
|
|
CloseHandle(hostPipe);
|
|
|
|
}
|
2018-06-13 21:52:45 -04:00
|
|
|
FreeLibraryAndExitThread(::currentModule, 0);
|
2018-05-20 13:11:55 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-01-06 00:01:17 +09:00
|
|
|
void ConsoleOutput(LPCSTR text)
|
|
|
|
{ // jichi 12/25/2013: Rewrite the implementation
|
2018-05-20 16:10:07 -04:00
|
|
|
if (!::live)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD textSize = strlen(text) + 1;
|
|
|
|
DWORD dataSize = textSize + 8;
|
|
|
|
BYTE *buffer = new BYTE[dataSize];
|
|
|
|
*(DWORD*)buffer = HOST_NOTIFICATION; //cmd
|
|
|
|
*(DWORD*)(buffer + 4) = HOST_NOTIFICATION_TEXT; //console
|
|
|
|
memcpy(buffer + 8, text, textSize);
|
2018-07-13 20:51:09 -04:00
|
|
|
DWORD unused;
|
|
|
|
WriteFile(::hookPipe, buffer, dataSize, &unused, nullptr);
|
2016-01-06 00:01:17 +09:00
|
|
|
}
|
2018-07-03 07:38:46 -04:00
|
|
|
|
|
|
|
// Artikash 7/3/2018: TODO: Finish using this in vnrhost instead of section to deliver hook name
|
2018-07-04 23:17:40 -04:00
|
|
|
void NotifyHookInsert(HookParam hp, LPCSTR name)
|
2016-01-06 00:01:17 +09:00
|
|
|
{
|
2018-05-20 16:10:07 -04:00
|
|
|
if (!::live)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2018-07-03 07:38:46 -04:00
|
|
|
BYTE buffer[PIPE_BUFFER_SIZE];
|
2018-05-20 16:10:07 -04:00
|
|
|
*(DWORD*)buffer = HOST_NOTIFICATION;
|
|
|
|
*(DWORD*)(buffer + 4) = HOST_NOTIFICATION_NEWHOOK;
|
2018-07-04 23:17:40 -04:00
|
|
|
*(HookParam*)(buffer + 8) = hp;
|
|
|
|
strcpy((char*)buffer + 8 + sizeof(HookParam), name);
|
2018-07-13 20:51:09 -04:00
|
|
|
DWORD unused;
|
|
|
|
WriteFile(::hookPipe, buffer, strlen(name) + 8 + sizeof(HookParam), &unused, nullptr);
|
2018-05-20 16:10:07 -04:00
|
|
|
return;
|
2016-01-06 00:01:17 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
// EOF
|