210 lines
5.2 KiB
C++
Raw Normal View History

// 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"
#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;
2018-05-20 13:11:55 -04:00
DWORD WINAPI PipeManager(LPVOID unused)
{
enum { STANDARD_WAIT = 1000 };
while (::running)
{
DWORD count;
2018-05-21 04:05:09 -04:00
BYTE* buffer = new BYTE[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();
WriteFile(::hookPipe, buffer, sizeof(DWORD), nullptr, 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;
}
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);
WriteFile(::hookPipe, buffer, dataSize, nullptr, nullptr);
}
//if (str) {
// int t, len, sum;
// BYTE buffer[0x80];
// BYTE *buff;
// len = wcslen(str) << 1;
2018-05-20 17:07:42 -04:00
// t = swprintf((LPWSTR)(buffer + 8),L"%d: ",current_process_id) << 1;
// sum = len + t + 8;
// if (sum > 0x80) {
// buff = new BYTE[sum];
// memset(buff, 0, sum); // jichi 9/25/2013: zero memory
// memcpy(buff + 8, buffer + 8, t);
// }
// else
// buff = buffer;
// *(DWORD *)buff = HOST_NOTIFICATION; //cmd
// *(DWORD *)(buff + 4) = HOST_NOTIFICATION_TEXT; //console
// memcpy(buff + t + 8, str, len);
// IO_STATUS_BLOCK ios;
2018-05-20 13:11:55 -04:00
// NtWriteFile(hookPipe,0,0,0,&ios,buff,sum,0,0);
// if (buff != buffer)
// delete[] buff;
// return len;
//}
//DWORD IOutputDWORD(DWORD d)
//{
// WCHAR str[0x10];
// swprintf(str,L"%.8X",d);
// ConsoleOutput(str);
// return 0;
//}
//DWORD IOutputRegister(DWORD *base)
//{
// WCHAR str[0x40];
// swprintf(str,L"EAX:%.8X",base[0]);
// ConsoleOutput(str);
// swprintf(str,L"ECX:%.8X",base[-1]);
// ConsoleOutput(str);
// swprintf(str,L"EDX:%.8X",base[-2]);
// ConsoleOutput(str);
// swprintf(str,L"EBX:%.8X",base[-3]);
// ConsoleOutput(str);
// swprintf(str,L"ESP:%.8X",base[-4]);
// ConsoleOutput(str);
// swprintf(str,L"EBP:%.8X",base[-5]);
// ConsoleOutput(str);
// swprintf(str,L"ESI:%.8X",base[-6]);
// ConsoleOutput(str);
// swprintf(str,L"EDI:%.8X",base[-7]);
// ConsoleOutput(str);
// return 0;
//}
//DWORD IRegisterEngineModule(DWORD idEngine, DWORD dnHook)
//{
// ::IdentifyEngine = (IdentifyEngineFun)idEngine;
// ::InsertDynamicHook = (InsertDynamicHookFun)dnHook;
// ::engine_registered = true;
// return 0;
//}
2018-05-20 16:10:07 -04:00
void NotifyHookInsert(DWORD addr)
{
2018-05-20 16:10:07 -04:00
if (!::live)
{
return;
}
BYTE buffer[0xc];
*(DWORD*)buffer = HOST_NOTIFICATION;
*(DWORD*)(buffer + 4) = HOST_NOTIFICATION_NEWHOOK;
*(DWORD*)(buffer + 8) = addr;
WriteFile(::hookPipe, buffer, 0xc, nullptr, nullptr);
return;
}
// EOF