cleaning things up

This commit is contained in:
Akash Mozumdar 2018-05-20 13:11:55 -04:00
parent c7a79e6064
commit 290ef57490
12 changed files with 269 additions and 303 deletions

View File

@ -129,7 +129,7 @@ size_t IthGetCurrentModulePath(wchar_t *buf, size_t len)
HANDLE hHeap; // used in ith/common/memory.h HANDLE hHeap; // used in ith/common/memory.h
#endif // ITH_HAS_HEAP #endif // ITH_HAS_HEAP
DWORD current_process_id; DWORD currentProcessId;
DWORD debug; DWORD debug;
BYTE launch_time[0x10]; BYTE launch_time[0x10];
LPVOID page; LPVOID page;
@ -238,7 +238,7 @@ public:
AcquireLock(); AcquireLock();
DWORD pid,addr,len; DWORD pid,addr,len;
if (hProc == NtCurrentProcess()) if (hProc == NtCurrentProcess())
pid = ::current_process_id; pid = ::currentProcessId;
else { else {
PROCESS_BASIC_INFORMATION info; PROCESS_BASIC_INFORMATION info;
NtQueryInformationProcess(hProc, ProcessBasicInformation, &info, sizeof(info), &len); NtQueryInformationProcess(hProc, ProcessBasicInformation, &info, sizeof(info), &len);
@ -287,7 +287,7 @@ public:
DWORD pid,addr,len; DWORD pid,addr,len;
AcquireLock(); AcquireLock();
if (hProc==NtCurrentProcess()) if (hProc==NtCurrentProcess())
pid = ::current_process_id; pid = ::currentProcessId;
else { else {
PROCESS_BASIC_INFORMATION info; PROCESS_BASIC_INFORMATION info;
NtQueryInformationProcess(hProc,ProcessBasicInformation,&info,sizeof(info),&len); NtQueryInformationProcess(hProc,ProcessBasicInformation,&info,sizeof(info),&len);
@ -733,7 +733,7 @@ BOOL IthInitSystemService()
mov ecx,[eax+0x20] mov ecx,[eax+0x20]
mov eax,[eax+0x30] mov eax,[eax+0x30]
mov peb,eax mov peb,eax
mov current_process_id,ecx mov currentProcessId,ecx
} }
debug = peb->BeingDebugged; debug = peb->BeingDebugged;
LowFragmentHeap = 2; LowFragmentHeap = 2;

View File

@ -63,7 +63,7 @@ void CheckThreadStart();
extern HANDLE hHeap; // used in ith/common/memory.h extern HANDLE hHeap; // used in ith/common/memory.h
#endif // ITH_HAS_HEAP #endif // ITH_HAS_HEAP
extern DWORD current_process_id; extern DWORD currentProcessId;
extern DWORD debug; extern DWORD debug;
extern BYTE LeadByteTable[]; extern BYTE LeadByteTable[];
extern LPVOID page; extern LPVOID page;

View File

@ -485,7 +485,7 @@ void HookManager::RegisterPipe(HANDLE text, HANDLE cmd, HANDLE thread)
else else
NtClearEvent(destroy_event); NtClearEvent(destroy_event);
} }
void HookManager::RegisterProcess(DWORD pid, DWORD hookman, DWORD module) void HookManager::RegisterProcess(DWORD pid)
{ {
HM_LOCK; HM_LOCK;
wchar_t str[0x40], wchar_t str[0x40],
@ -494,8 +494,6 @@ void HookManager::RegisterProcess(DWORD pid, DWORD hookman, DWORD module)
//ConsoleOutput("vnrhost:RegisterProcess: lock"); //ConsoleOutput("vnrhost:RegisterProcess: lock");
//EnterCriticalSection(&hmcs); //EnterCriticalSection(&hmcs);
record[register_count - 1].pid_register = pid; record[register_count - 1].pid_register = pid;
record[register_count - 1].hookman_register = hookman;
record[register_count - 1].module_register = module;
//record[register_count - 1].engine_register = engine; //record[register_count - 1].engine_register = engine;
swprintf(str, ITH_SECTION_ L"%d", pid); swprintf(str, ITH_SECTION_ L"%d", pid);
HANDLE hSection = IthCreateSection(str, HOOK_SECTION_SIZE, PAGE_READONLY); HANDLE hSection = IthCreateSection(str, HOOK_SECTION_SIZE, PAGE_READONLY);

View File

@ -71,7 +71,7 @@ public:
void RemoveSingleHook(DWORD pid, DWORD addr); void RemoveSingleHook(DWORD pid, DWORD addr);
void RegisterThread(TextThread*, DWORD); // private void RegisterThread(TextThread*, DWORD); // private
void RegisterPipe(HANDLE text, HANDLE cmd, HANDLE thread); void RegisterPipe(HANDLE text, HANDLE cmd, HANDLE thread);
void RegisterProcess(DWORD pid, DWORD hookman, DWORD module); void RegisterProcess(DWORD pid);
void UnRegisterProcess(DWORD pid); void UnRegisterProcess(DWORD pid);
//void SetName(DWORD); //void SetName(DWORD);

View File

@ -56,7 +56,7 @@ namespace
{ // unnamed { // unnamed
void GetDebugPrivileges() void GetDebugPrivileges()
{ { // Artikash 5/19/2018: Is it just me or is this function 100% superfluous?
HANDLE processToken; HANDLE processToken;
TOKEN_PRIVILEGES Privileges = {1, {0x14, 0, SE_PRIVILEGE_ENABLED}}; TOKEN_PRIVILEGES Privileges = {1, {0x14, 0, SE_PRIVILEGE_ENABLED}};
@ -133,7 +133,6 @@ IHFSERVICE bool IHFAPI OpenHost()
IHFSERVICE void IHFAPI StartHost() IHFSERVICE void IHFAPI StartHost()
{ {
CreateNewPipe(); CreateNewPipe();
::pipeExistsEvent = CreateEventW(nullptr, TRUE, TRUE, ITH_PIPEEXISTS_EVENT);
} }
IHFSERVICE void IHFAPI CloseHost() IHFSERVICE void IHFAPI CloseHost()
@ -142,12 +141,10 @@ IHFSERVICE void IHFAPI CloseHost()
if (::running) if (::running)
{ {
::running = FALSE; ::running = FALSE;
ResetEvent(::pipeExistsEvent);
delete man; delete man;
delete settings; delete settings;
CloseHandle(::hookMutex); CloseHandle(::hookMutex);
CloseHandle(preventDuplicationMutex); CloseHandle(preventDuplicationMutex);
CloseHandle(::pipeExistsEvent);
DeleteCriticalSection(&detachCs); DeleteCriticalSection(&detachCs);
} }
LeaveCriticalSection(&::hostCs); LeaveCriticalSection(&::hostCs);
@ -169,7 +166,7 @@ IHFSERVICE bool IHFAPI InjectProcessById(DWORD processId, DWORD timeout)
success = false; success = false;
} }
HMODULE textHooker = LoadLibraryExW(L"vnrhook", nullptr, DONT_RESOLVE_DLL_REFERENCES); HMODULE textHooker = LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES);
if (textHooker == nullptr) if (textHooker == nullptr)
{ {
success = false; success = false;
@ -184,7 +181,7 @@ IHFSERVICE bool IHFAPI InjectProcessById(DWORD processId, DWORD timeout)
success = false; success = false;
} }
void* loadLibraryStartRoutine = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW"); LPTHREAD_START_ROUTINE loadLibraryStartRoutine = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW");
if (success) if (success)
{ {
@ -192,7 +189,7 @@ IHFSERVICE bool IHFAPI InjectProcessById(DWORD processId, DWORD timeout)
{ {
if (WriteProcessMemory(processHandle, remoteData, textHookerPath, textHookerPathSize, nullptr)) if (WriteProcessMemory(processHandle, remoteData, textHookerPath, textHookerPathSize, nullptr))
{ {
if (HANDLE thread = CreateRemoteThread(processHandle, nullptr, 0, (LPTHREAD_START_ROUTINE)loadLibraryStartRoutine, remoteData, 0, nullptr)) if (HANDLE thread = CreateRemoteThread(processHandle, nullptr, 0, loadLibraryStartRoutine, remoteData, 0, nullptr))
{ {
WaitForSingleObject(thread, timeout); WaitForSingleObject(thread, timeout);
CloseHandle(thread); CloseHandle(thread);
@ -247,7 +244,7 @@ IHFSERVICE void IHFAPI GetHostSettings(Settings **p)
} }
} }
// I don't understand the following operations, so I'm making minimal changes in cleanup -Artikash 11 May 2018 // Artikash 5/11/2018: I don't understand the following operations, so I'm making minimal changes in cleanup
IHFSERVICE DWORD IHFAPI Host_InsertHook(DWORD pid, HookParam *hp, LPCSTR name) IHFSERVICE DWORD IHFAPI Host_InsertHook(DWORD pid, HookParam *hp, LPCSTR name)
{ {

View File

@ -31,7 +31,7 @@ GLOBAL DWORD split_time,
global_filter; global_filter;
GLOBAL CRITICAL_SECTION detachCs; GLOBAL CRITICAL_SECTION detachCs;
DWORD WINAPI RecvThread(LPVOID lpThreadParameter); DWORD WINAPI TextReceiver(LPVOID lpThreadParameter);
DWORD WINAPI CmdThread(LPVOID lpThreadParameter); DWORD WINAPI CmdThread(LPVOID lpThreadParameter);
DWORD GetCurrentPID(); DWORD GetCurrentPID();

View File

@ -9,6 +9,8 @@
#include "vnrhook/include/const.h" #include "vnrhook/include/const.h"
#include "ithsys/ithsys.h" #include "ithsys/ithsys.h"
#include <stdio.h> #include <stdio.h>
#include "growl.h"
#include <atlbase.h>
//#include "CommandQueue.h" //#include "CommandQueue.h"
//#include <QtCore/QDebug> //#include <QtCore/QDebug>
@ -17,23 +19,17 @@
//DWORD WINAPI UpdateWindows(LPVOID lpThreadParameter); //DWORD WINAPI UpdateWindows(LPVOID lpThreadParameter);
namespace { // unnamed namespace
enum NamedPipeCommand { { // unnamed
NAMED_PIPE_DISCONNECT = 1
, NAMED_PIPE_CONNECT = 2
};
bool newline = false;
bool detach = false;
// jichi 10/27/2013 // jichi 10/27/2013
// Check if text has leading space // Check if text has leading space
enum { _filter_limit = 0x20 }; // The same as the orignal ITH filter. So, I don't have to check \u3000 enum { FILTER_LIMIT = 0x20 }; // The same as the orignal ITH filter. So, I don't have to check \u3000
//enum { _filter_limit = 0x19 }; //enum { FILTER_LIMIT = 0x19 };
inline bool has_leading_space(const BYTE *text, int len) inline bool HasLeadingSpace(const BYTE *text, int len)
{ {
return len == 1 ? *text <= _filter_limit : // 1 byte return len == 1 ? *text <= FILTER_LIMIT : // 1 byte
*reinterpret_cast<const WORD *>(text) <= _filter_limit; // 2 bytes *(WORD*)text <= FILTER_LIMIT; // 2 bytes
} }
// jichi 9/28/2013: Skip leading garbage // jichi 9/28/2013: Skip leading garbage
@ -44,30 +40,36 @@ const BYTE *Filter(const BYTE *str, int len)
{ {
#ifdef ITH_DISABLE_FILTER // jichi 9/28/2013: only for debugging purpose #ifdef ITH_DISABLE_FILTER // jichi 9/28/2013: only for debugging purpose
return str; return str;
#endif // ITH_DISABLE_FILTER #endif
// if (len && *str == 0x10) // jichi 9/28/2013: garbage on wine, data link escape, or ^P
// return nullptr;
//enum { limit = 0x19 };
while (true) while (true)
if (len >= 2) { {
if (*(const WORD *)str <= _filter_limit) { // jichi 10/27/2013: two bytes if (len >= 2)
{
if (*(WORD*)str <= FILTER_LIMIT)
{ // jichi 10/27/2013: two bytes
str += 2; str += 2;
len -= 2; len -= 2;
} else }
else
{
break; break;
} else if (*str <= _filter_limit) { // jichi 10/27/2013: 1 byte }
}
else if (*str <= FILTER_LIMIT)
{ // jichi 10/27/2013: 1 byte
str++; str++;
len--; len--;
} else }
else
{
break; break;
}
}
return str; return str;
} }
} // unnamed namespace
//WCHAR recv_pipe[] = L"\\??\\pipe\\ITH_PIPE"; } // unnamed namespace
//WCHAR command_pipe[] = L"\\??\\pipe\\ITH_COMMAND";
wchar_t recv_pipe[] = ITH_TEXT_PIPE;
wchar_t command_pipe[] = ITH_COMMAND_PIPE;
CRITICAL_SECTION detachCs; // jichi 9/27/2013: also used in main CRITICAL_SECTION detachCs; // jichi 9/27/2013: also used in main
//HANDLE hDetachEvent; //HANDLE hDetachEvent;
@ -75,203 +77,105 @@ extern HANDLE pipeExistsEvent;
void CreateNewPipe() void CreateNewPipe()
{ {
HANDLE hTextPipe, hCmdPipe, hThread; HANDLE hookPipe, hostPipe, TextReceivingThread;
hTextPipe = CreateNamedPipeW(ITH_TEXT_PIPE, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, 0x1000, 0x1000, MAXDWORD, NULL); hookPipe = CreateNamedPipeW(ITH_TEXT_PIPE, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, 0x1000, 0x1000, MAXDWORD, NULL);
hCmdPipe = CreateNamedPipeW(ITH_COMMAND_PIPE, PIPE_ACCESS_OUTBOUND, 0, PIPE_UNLIMITED_INSTANCES, 0x1000, 0x1000, MAXDWORD, NULL); hostPipe = CreateNamedPipeW(ITH_COMMAND_PIPE, PIPE_ACCESS_OUTBOUND, 0, PIPE_UNLIMITED_INSTANCES, 0x1000, 0x1000, MAXDWORD, NULL);
hThread = CreateThread(nullptr, 0, RecvThread, hTextPipe, 0, nullptr); TextReceivingThread = CreateThread(nullptr, 0, TextReceiver, hookPipe, 0, nullptr);
man->RegisterPipe(hTextPipe, hCmdPipe, hThread); man->RegisterPipe(hookPipe, hostPipe, TextReceivingThread);
} }
void DetachFromProcess(DWORD pid) DWORD WINAPI TextReceiver(LPVOID lpThreadParameter)
{ {
HANDLE hMutex = INVALID_HANDLE_VALUE, HANDLE hookPipe = (HANDLE)lpThreadParameter;
hEvent = INVALID_HANDLE_VALUE; ConnectNamedPipe(hookPipe, nullptr);
//try {
IO_STATUS_BLOCK ios;
ProcessRecord *pr = man->GetProcessRecord(pid);
if (!pr)
return;
//IthBreak();
hEvent = IthCreateEvent(nullptr);
if (STATUS_PENDING == NtFsControlFile(
man->GetCmdHandleByPID(pid),
hEvent,
0,0,
&ios,
CTL_CODE(FILE_DEVICE_NAMED_PIPE, NAMED_PIPE_DISCONNECT, 0, 0),
0,0,0,0))
NtWaitForSingleObject(hEvent, 0, 0);
NtClose(hEvent);
//hEvent = INVALID_HANDLE_VALUE;
WCHAR mutex[0x20]; enum { PIPE_BUFFER_SIZE = 0x1000 };
swprintf(mutex, ITH_DETACH_MUTEX_ L"%d", pid); BYTE* buffer = new BYTE[PIPE_BUFFER_SIZE];
hMutex = IthOpenMutex(mutex); DWORD bytesRead, processId;
if (hMutex != INVALID_HANDLE_VALUE) {
NtWaitForSingleObject(hMutex, 0, 0);
NtReleaseMutant(hMutex, 0);
NtClose(hMutex);
//hMutex = INVALID_HANDLE_VALUE;
}
//} catch (...) { // Artikash 5/20/2018: Shouldn't Windows automatically close the handles when the host process stops running?
// if (hEvent != INVALID_HANDLE_VALUE) //if (!::running) {
// NtClose(hEvent); // NtClose(hookPipe);
// else if (hMutex != INVALID_HANDLE_VALUE) { // return 0;
// NtWaitForSingleObject(hMutex, 0, 0);
// NtReleaseMutant(hMutex, 0);
// NtClose(hMutex);
// }
//} //}
//NtSetEvent(hDetachEvent, 0); ReadFile(hookPipe, &processId, sizeof(processId), &bytesRead, nullptr);
if (::running) man->RegisterProcess(processId);
NtSetEvent(pipeExistsEvent, 0);
}
// jichi 9/27/2013: I don't need this
//void OutputDWORD(DWORD d)
//{
// WCHAR str[0x20];
// swprintf(str, L"%.8X", d);
// ConsoleOutput(str);
//}
DWORD WINAPI RecvThread(LPVOID lpThreadParameter)
{
HANDLE hTextPipe = (HANDLE)lpThreadParameter;
IO_STATUS_BLOCK ios;
NtFsControlFile(hTextPipe,
0, 0, 0,
&ios,
CTL_CODE(FILE_DEVICE_NAMED_PIPE, NAMED_PIPE_CONNECT, 0, 0),
0, 0, 0, 0);
if (!::running) {
NtClose(hTextPipe);
return 0;
}
BYTE *buff;
enum { PipeBufferSize = 0x1000 };
buff = new BYTE[PipeBufferSize];
::memset(buff, 0, PipeBufferSize); // jichi 8/27/2013: zero memory, or it will crash wine on start up
// 10/19/2014 jichi: there are totally three words received
// See: hook/rpc/pipe.cc
// struct {
// DWORD pid;
// TextHook *man;
// DWORD module;
// //DWORD engine;
// } u;
enum { module_struct_size = 12 };
NtReadFile(hTextPipe, 0, 0, 0, &ios, buff, module_struct_size, 0, 0);
// jichi 7/2/2015: This must be consistent with the struct declared in vnrhook/pipe.cc
DWORD pid = *(DWORD *)buff,
module = *(DWORD *)(buff + 0x8),
hookman = *(DWORD *)(buff + 0x4);
//engine = *(DWORD *)(buff + 0xc);
man->RegisterProcess(pid, hookman, module);
// jichi 9/27/2013: why recursion? // jichi 9/27/2013: why recursion?
// Artikash 5/20/2018: To create a new pipe for another process
CreateNewPipe(); CreateNewPipe();
//NtClose(IthCreateThread(UpdateWindows,0)); while (::running)
while (::running) { {
if (!NT_SUCCESS(NtReadFile(hTextPipe, if (!ReadFile(hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr))
0, 0, 0, {
&ios,
buff,
0xf80,
0, 0)))
break; break;
}
enum { data_offset = 0xc }; // jichi 10/27/2013: Seem to be the data offset in the pipe enum { DATA_OFFSET = 0xc }; // jichi 10/27/2013: Seem to be the data offset in the pipe
DWORD RecvLen = ios.uInformation; if (bytesRead < DATA_OFFSET)
if (RecvLen < data_offset) {
break; break;
DWORD hook = *(DWORD *)buff; }
union { DWORD retn; DWORD cmd_type; }; union { DWORD retn; DWORD commandType; };
union { DWORD split; DWORD new_engine_type; }; DWORD hook = *(DWORD *)buffer;
retn = *(DWORD *)(buffer + 4);
DWORD split = *(DWORD *)(buffer + 8);
retn = *(DWORD *)(buff + 4); buffer[bytesRead] = 0;
split = *(DWORD *)(buff + 8); buffer[bytesRead + 1] = 0;
buff[RecvLen] = 0; if (hook == HOST_NOTIFICATION)
buff[RecvLen + 1] = 0; {
switch (commandType)
if (hook == HOST_NOTIFICATION) { {
switch (cmd_type) {
case HOST_NOTIFICATION_NEWHOOK: case HOST_NOTIFICATION_NEWHOOK:
{ {
static long lock; static long lock;
while (InterlockedExchange(&lock, 1) == 1); while (InterlockedExchange(&lock, 1) == 1);
ProcessEventCallback new_hook = man->ProcessNewHook(); man->ProcessNewHook()(processId);
if (new_hook)
new_hook(pid);
lock = 0; lock = 0;
} break; }
break;
case HOST_NOTIFICATION_TEXT: case HOST_NOTIFICATION_TEXT:
//qDebug() << ((LPCSTR)(buff + 8)); USES_CONVERSION;
man->AddConsoleOutput(A2W((LPCSTR)(buffer + 8)));
break; break;
} }
} else { }
else
{
// jichi 9/28/2013: Debug raw data // jichi 9/28/2013: Debug raw data
//ITH_DEBUG_DWORD9(RecvLen - 0xc, //ITH_DEBUG_DWORD9(RecvLen - 0xc,
// buff[0xc], buff[0xd], buff[0xe], buff[0xf], // buffer[0xc], buffer[0xd], buffer[0xe], buffer[0xf],
// buff[0x10], buff[0x11], buff[0x12], buff[0x13]); // buffer[0x10], buffer[0x11], buffer[0x12], buffer[0x13]);
const BYTE *data = buff + data_offset; // th const BYTE *data = buffer + DATA_OFFSET; // th
int len = RecvLen - data_offset; int dataLength = bytesRead - DATA_OFFSET;
bool space = ::has_leading_space(data, len); bool space = ::HasLeadingSpace(data, dataLength);
if (space) { if (space)
const BYTE *it = ::Filter(data, len); {
len -= it - data; const BYTE *it = ::Filter(data, dataLength);
dataLength -= it - data;
data = it; data = it;
} }
if (len >> 31) // jichi 10/27/2013: len is too large, which seldom happens man->DispatchText(processId, data, hook, retn, split, dataLength, space);
len = 0;
//man->DispatchText(pid, len ? data : nullptr, hook, retn, split, len, space);
man->DispatchText(pid, data, hook, retn, split, len, space);
} }
} }
EnterCriticalSection(&detachCs); EnterCriticalSection(&detachCs);
HANDLE hDisconnect = IthCreateEvent(nullptr); DisconnectNamedPipe(hookPipe);
DisconnectNamedPipe(man->GetCmdHandleByPID(processId));
if (STATUS_PENDING == NtFsControlFile( man->UnRegisterProcess(processId);
hTextPipe,
hDisconnect,
0, 0,
&ios,
CTL_CODE(FILE_DEVICE_NAMED_PIPE, NAMED_PIPE_DISCONNECT, 0, 0),
0, 0, 0, 0))
NtWaitForSingleObject(hDisconnect, 0, 0);
NtClose(hDisconnect);
DetachFromProcess(pid);
man->UnRegisterProcess(pid);
//NtClearEvent(hDetachEvent);
LeaveCriticalSection(&detachCs); LeaveCriticalSection(&detachCs);
delete[] buff; delete[] buffer;
if (::running)
DOUT("detached");
//if (::running) {
// swprintf((LPWSTR)buff, FormatDetach, pid);
// ConsoleOutput((LPWSTR)buff);
// NtClose(IthCreateThread(UpdateWindows, 0));
//}
return 0; return 0;
} }

View File

@ -234,7 +234,7 @@ DWORD GetModuleBase()
// *(DWORD*)buffer=-1; // *(DWORD*)buffer=-1;
// *(DWORD*)(buffer+4)=1; // *(DWORD*)(buffer+4)=1;
// IO_STATUS_BLOCK ios; // IO_STATUS_BLOCK ios;
// NtWriteFile(hPipe,0,0,0,&ios,buffer,0x10,0,0); // NtWriteFile(hookPipe,0,0,0,&ios,buffer,0x10,0,0);
// } // }
//} //}
@ -488,9 +488,9 @@ DWORD TextHook::UnsafeSend(DWORD dwDataBase, DWORD dwRetn)
IthCoolDown(); // jichi 9/28/2013: cool down to prevent parallelization in wine IthCoolDown(); // jichi 9/28/2013: cool down to prevent parallelization in wine
//CliLockPipe(); //CliLockPipe();
if (STATUS_PENDING == NtWriteFile(::hPipe, 0, 0, 0, &ios, pbData, dwCount + HEADER_SIZE, 0, 0)) { if (STATUS_PENDING == NtWriteFile(::hookPipe, 0, 0, 0, &ios, pbData, dwCount + HEADER_SIZE, 0, 0)) {
NtWaitForSingleObject(::hPipe, 0, 0); NtWaitForSingleObject(::hookPipe, 0, 0);
NtFlushBuffersFile(::hPipe, &ios); NtFlushBuffersFile(::hookPipe, &ios);
} }
//CliUnlockPipe(); //CliUnlockPipe();
} }
@ -550,7 +550,7 @@ int TextHook::UnsafeInsertHookCode()
if (base) if (base)
hp.address += base; hp.address += base;
else { else {
current_hook--; currentHook--;
ConsoleOutput("vnrcli:UnsafeInsertHookCode: FAILED: function not found in the export table"); ConsoleOutput("vnrcli:UnsafeInsertHookCode: FAILED: function not found in the export table");
return no; return no;
} }
@ -561,7 +561,7 @@ int TextHook::UnsafeInsertHookCode()
hp.type &= ~(MODULE_OFFSET | FUNCTION_OFFSET); hp.type &= ~(MODULE_OFFSET | FUNCTION_OFFSET);
} }
else { else {
current_hook--; currentHook--;
ConsoleOutput("vnrcli:UnsafeInsertHookCode: FAILED: module not present"); ConsoleOutput("vnrcli:UnsafeInsertHookCode: FAILED: module not present");
return no; return no;
} }
@ -569,7 +569,7 @@ int TextHook::UnsafeInsertHookCode()
{ {
TextHook *it = hookman; TextHook *it = hookman;
for (int i = 0; (i < current_hook) && it; it++) { // Check if there is a collision. for (int i = 0; (i < currentHook) && it; it++) { // Check if there is a collision.
if (it->Address()) if (it->Address())
i++; i++;
//it = hookman + i; //it = hookman + i;
@ -640,7 +640,7 @@ int TextHook::UnsafeInsertHookCode()
//Check if the new hook range conflict with existing ones. Clear older if conflict. //Check if the new hook range conflict with existing ones. Clear older if conflict.
{ {
TextHook *it = hookman; TextHook *it = hookman;
for (int i = 0; i < current_hook; it++) { for (int i = 0; i < currentHook; it++) {
if (it->Address()) if (it->Address())
i++; i++;
if (it == this) if (it == this)
@ -686,7 +686,7 @@ int TextHook::InitHook(LPVOID addr, DWORD data, DWORD data_ind,
hp.hook_len = 0; hp.hook_len = 0;
hp.module = 0; hp.module = 0;
hp.length_offset = len_off & 0xffff; hp.length_offset = len_off & 0xffff;
current_hook++; currentHook++;
if (current_available >= this) if (current_available >= this)
for (current_available = this + 1; current_available->Address(); current_available++); for (current_available = this + 1; current_available->Address(); current_available++);
IthReleaseMutex(hmMutex); IthReleaseMutex(hmMutex);
@ -701,7 +701,7 @@ int TextHook::InitHook(const HookParam &h, LPCSTR name, WORD set_flag)
if (name && name != hook_name) { if (name && name != hook_name) {
SetHookName(name); SetHookName(name);
} }
current_hook++; currentHook++;
current_available = this+1; current_available = this+1;
while (current_available->Address()) while (current_available->Address())
current_available++; current_available++;
@ -742,7 +742,7 @@ int TextHook::ClearHook()
memset(this, 0, sizeof(TextHook)); // jichi 11/30/2013: This is the original code of ITH memset(this, 0, sizeof(TextHook)); // jichi 11/30/2013: This is the original code of ITH
//if (current_available>this) //if (current_available>this)
// current_available = this; // current_available = this;
current_hook--; currentHook--;
IthReleaseMutex(hmMutex); IthReleaseMutex(hmMutex);
return err; return err;
} }

View File

@ -19,11 +19,11 @@
// - 0x8 dwSplit split value // - 0x8 dwSplit split value
#define HEADER_SIZE 0xc #define HEADER_SIZE 0xc
extern int current_hook; extern int currentHook;
extern WCHAR dll_mutex[]; extern WCHAR dll_mutex[];
//extern WCHAR dll_name[]; //extern WCHAR dll_name[];
extern DWORD trigger; extern DWORD trigger;
//extern DWORD current_process_id; //extern DWORD currentProcessId;
// jichi 6/3/2014: Get memory range of the current module // jichi 6/3/2014: Get memory range of the current module
extern DWORD processStartAddress, extern DWORD processStartAddress,
@ -77,11 +77,12 @@ extern FilterRange *filter;
extern bool running, extern bool running,
live; live;
extern HANDLE hPipe, extern HANDLE hookPipe,
hmMutex; hmMutex;
DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter); DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter);
DWORD WINAPI CommandPipe(LPVOID lpThreadParameter); DWORD WINAPI CommandPipe(LPVOID lpThreadParameter);
DWORD WINAPI PipeManager(LPVOID unused);
//void RequestRefreshProfile(); //void RequestRefreshProfile();

View File

@ -62,14 +62,14 @@ HINSTANCE hDLL;
HANDLE hSection; HANDLE hSection;
bool running, bool running,
live = false; live = false;
int current_hook = 0, int currentHook = 0,
user_hook_count = 0; user_hook_count = 0;
DWORD trigger = 0; DWORD trigger = 0;
HANDLE HANDLE
hFile, hFile,
hMutex, hMutex,
hmMutex; hmMutex;
//DWORD current_process_id; //DWORD currentProcessId;
extern DWORD enter_count; extern DWORD enter_count;
//extern LPWSTR current_dir; //extern LPWSTR current_dir;
extern DWORD engine_type; extern DWORD engine_type;
@ -133,7 +133,7 @@ void RequestRefreshProfile()
*(DWORD *)(buffer + 8) = 0; *(DWORD *)(buffer + 8) = 0;
IO_STATUS_BLOCK ios; IO_STATUS_BLOCK ios;
CliLockPipe(); CliLockPipe();
NtWriteFile(hPipe, 0, 0, 0, &ios, buffer, HEADER_SIZE, 0, 0); NtWriteFile(hookPipe, 0, 0, 0, &ios, buffer, HEADER_SIZE, 0, 0);
CliUnlockPipe(); CliUnlockPipe();
} }
} }
@ -156,7 +156,7 @@ DWORD GetFunctionAddr(const char *name, DWORD *addr, DWORD *base, DWORD *size, L
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved) BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
{ {
static HANDLE hSendThread, static HANDLE pipeThread,
hCmdThread; hCmdThread;
CC_UNUSED(lpReserved); CC_UNUSED(lpReserved);
@ -189,7 +189,7 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
// No longer checking if SystemService fails, which could happen on non-Japanese OS // No longer checking if SystemService fails, which could happen on non-Japanese OS
IthInitSystemService(); IthInitSystemService();
swprintf(hm_section, ITH_SECTION_ L"%d", current_process_id); swprintf(hm_section, ITH_SECTION_ L"%d", currentProcessId);
// jichi 9/25/2013: Interprocedural communication with vnrsrv. // jichi 9/25/2013: Interprocedural communication with vnrsrv.
hSection = IthCreateSection(hm_section, HOOK_SECTION_SIZE, PAGE_EXECUTE_READWRITE); hSection = IthCreateSection(hm_section, HOOK_SECTION_SIZE, PAGE_EXECUTE_READWRITE);
@ -211,12 +211,12 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
{ {
wchar_t hm_mutex[0x100]; wchar_t hm_mutex[0x100];
swprintf(hm_mutex, ITH_HOOKMAN_MUTEX_ L"%d", current_process_id); swprintf(hm_mutex, ITH_HOOKMAN_MUTEX_ L"%d", currentProcessId);
::hmMutex = IthCreateMutex(hm_mutex, FALSE); ::hmMutex = IthCreateMutex(hm_mutex, FALSE);
} }
{ {
wchar_t dll_mutex[0x100]; wchar_t dll_mutex[0x100];
swprintf(dll_mutex, ITH_PROCESS_MUTEX_ L"%d", current_process_id); swprintf(dll_mutex, ITH_PROCESS_MUTEX_ L"%d", currentProcessId);
DWORD exists; DWORD exists;
::hMutex = IthCreateMutex(dll_mutex, TRUE, &exists); // jichi 9/18/2013: own is true, make sure the injected dll is singleton ::hMutex = IthCreateMutex(dll_mutex, TRUE, &exists); // jichi 9/18/2013: own is true, make sure the injected dll is singleton
if (exists) if (exists)
@ -231,8 +231,7 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
AddAllModules(); AddAllModules();
InitFilterTable(); InitFilterTable();
hSendThread = IthCreateThread(WaitForPipe, 0); pipeThread = IthCreateThread(PipeManager, 0);
hCmdThread = IthCreateThread(CommandPipe, 0);
} break; } break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
{ {
@ -250,9 +249,9 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
Engine::terminate(); Engine::terminate();
if (hSendThread) { if (pipeThread) {
NtWaitForSingleObject(hSendThread, 0, (PLARGE_INTEGER)&timeout); NtWaitForSingleObject(pipeThread, 0, (PLARGE_INTEGER)&timeout);
NtClose(hSendThread); NtClose(pipeThread);
} }
if (hCmdThread) { if (hCmdThread) {

View File

@ -12,7 +12,7 @@
#include "src/util/util.h" #include "src/util/util.h"
#include "src/main.h" #include "src/main.h"
#include "include/defs.h" #include "include/defs.h"
//#include "src/util/growl.h" #include "src/util/growl.h"
#include "ithsys/ithsys.h" #include "ithsys/ithsys.h"
#include "ccutil/ccmacro.h" #include "ccutil/ccmacro.h"
#include <cstdio> // for swprintf #include <cstdio> // for swprintf
@ -34,7 +34,7 @@ LARGE_INTEGER sleep_time = {-20*10000, -1};
DWORD engine_type; DWORD engine_type;
DWORD module_base; DWORD module_base;
HANDLE hPipe, HANDLE hookPipe,
hCommand, hCommand,
hDetach; //,hLose; hDetach; //,hLose;
//InsertHookFun InsertHook; //InsertHookFun InsertHook;
@ -71,20 +71,88 @@ HANDLE IthOpenPipe(LPWSTR name, ACCESS_MASK direction)
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
DWORD WINAPI PipeManager(LPVOID unused)
{
enum { STANDARD_WAIT = 1000 };
while (::running)
{
DWORD count;
BYTE* buffer = new BYTE[0x1000];
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);
}
}
WriteFile(::hookPipe, &::currentProcessId, sizeof(::currentProcessId), &count, nullptr);
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);
if (!ReadFile(hostPipe, buffer, 0x800, &count, nullptr))
{
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;
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);
}
Util::unloadCurrentModule();
return 0;
}
DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter) // Dynamically detect ITH main module status. DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter) // Dynamically detect ITH main module status.
{ {
CC_UNUSED(lpThreadParameter); CC_UNUSED(lpThreadParameter);
// jichi 7/2/2015:This must be consistent with the struct declared in vnrhost/pipe.cc
struct {
DWORD pid;
DWORD module;
TextHook *man;
//DWORD engine;
} u;
//swprintf(engine_event,L"ITH_ENGINE_%d",current_process_id); //swprintf(engine_event,L"ITH_ENGINE_%d",currentProcessId);
swprintf(::detach_mutex, ITH_DETACH_MUTEX_ L"%d", current_process_id); swprintf(::detach_mutex, ITH_DETACH_MUTEX_ L"%d", currentProcessId);
//swprintf(lose_event,L"ITH_LOSEPIPE_%d",current_process_id); //swprintf(lose_event,L"ITH_LOSEPIPE_%d",currentProcessId);
//hEngine=IthCreateEvent(engine_event); //hEngine=IthCreateEvent(engine_event);
//NtWaitForSingleObject(hEngine,0,0); //NtWaitForSingleObject(hEngine,0,0);
//NtClose(hEngine); //NtClose(hEngine);
@ -93,35 +161,33 @@ DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter) // Dynamically detect ITH mai
// NtDelayExecution(0, &wait_time); // NtDelayExecution(0, &wait_time);
//LoadEngine(L"ITH_Engine.dll"); //LoadEngine(L"ITH_Engine.dll");
u.module = module_base;
u.pid = current_process_id;
u.man = hookman;
//u.engine = engine_base; // jichi 10/19/2014: disable the second dll //u.engine = engine_base; // jichi 10/19/2014: disable the second dll
HANDLE hPipeExist = IthOpenEvent(ITH_PIPEEXISTS_EVENT); HANDLE hPipeExist = IthOpenEvent(ITH_PIPEEXISTS_EVENT);
IO_STATUS_BLOCK ios; IO_STATUS_BLOCK ios;
//hLose=IthCreateEvent(lose_event,0,0); //hLose=IthCreateEvent(lose_event,0,0);
if (hPipeExist != INVALID_HANDLE_VALUE) if (hPipeExist != INVALID_HANDLE_VALUE)
while (::running) { while (::running) {
::hPipe = INVALID_HANDLE_VALUE; ::hookPipe = INVALID_HANDLE_VALUE;
hCommand = INVALID_HANDLE_VALUE; hCommand = INVALID_HANDLE_VALUE;
while (NtWaitForSingleObject(hPipeExist, 0, &wait_time) == WAIT_TIMEOUT) while (NtWaitForSingleObject(hPipeExist, 0, &wait_time) == WAIT_TIMEOUT)
if (!::running) if (!::running)
goto _release; goto _release;
GROWL_MSG(L"Pipe connected");
HANDLE hMutex = IthCreateMutex(ITH_GRANTPIPE_MUTEX, 0); HANDLE hMutex = IthCreateMutex(ITH_GRANTPIPE_MUTEX, 0);
NtWaitForSingleObject(hMutex, 0, 0); NtWaitForSingleObject(hMutex, 0, 0);
while (::hPipe == INVALID_HANDLE_VALUE|| while (::hookPipe == INVALID_HANDLE_VALUE||
hCommand == INVALID_HANDLE_VALUE) { hCommand == INVALID_HANDLE_VALUE) {
NtDelayExecution(0, &sleep_time); NtDelayExecution(0, &sleep_time);
if (::hPipe == INVALID_HANDLE_VALUE) if (::hookPipe == INVALID_HANDLE_VALUE)
::hPipe = IthOpenPipe(recv_pipe, GENERIC_WRITE); ::hookPipe = IthOpenPipe(recv_pipe, GENERIC_WRITE);
if (hCommand == INVALID_HANDLE_VALUE) if (hCommand == INVALID_HANDLE_VALUE)
hCommand = IthOpenPipe(command, GENERIC_READ); hCommand = IthOpenPipe(command, GENERIC_READ);
} }
//NtClearEvent(hLose); //NtClearEvent(hLose);
CliLockPipe(); CliLockPipe();
NtWriteFile(::hPipe, 0, 0, 0, &ios, &u, sizeof(u), 0, 0); NtWriteFile(::hookPipe, 0, 0, 0, &ios, &::currentProcessId, sizeof(::currentProcessId), 0, 0);
CliUnlockPipe(); CliUnlockPipe();
for (int i = 0, count = 0; count < ::current_hook; i++) 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 if (hookman[i].RecoverHook()) // jichi 9/27/2013: This is the place where built-in hooks like TextOutA are inserted
count++; count++;
//ConsoleOutput(dll_name); //ConsoleOutput(dll_name);
@ -141,19 +207,19 @@ DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter) // Dynamically detect ITH mai
NtDelayExecution(0, &sleep_time); NtDelayExecution(0, &sleep_time);
::live = false; ::live = false;
for (int i = 0, count = 0; count < ::current_hook; i++) for (int i = 0, count = 0; count < ::currentHook; i++)
if (hookman[i].RemoveHook()) if (hookman[i].RemoveHook())
count++; count++;
if (!::running) { if (!::running) {
IthCoolDown(); // jichi 9/28/2013: Use cooldown instead of lock pipe to prevent from hanging on exit IthCoolDown(); // jichi 9/28/2013: Use cooldown instead of lock pipe to prevent from hanging on exit
//CliLockPipe(); //CliLockPipe();
//NtWriteFile(::hPipe, 0, 0, 0, &ios, man, 4, 0, 0); //NtWriteFile(::hookPipe, 0, 0, 0, &ios, man, 4, 0, 0);
NtWriteFile(::hPipe, 0, 0, 0, &ios, hookman, 4, 0, 0); NtWriteFile(::hookPipe, 0, 0, 0, &ios, hookman, 4, 0, 0);
//CliUnlockPipe(); //CliUnlockPipe();
IthReleaseMutex(::hDetach); IthReleaseMutex(::hDetach);
} }
NtClose(::hDetach); NtClose(::hDetach);
NtClose(::hPipe); NtClose(::hookPipe);
} }
_release: _release:
//NtClose(hLose); //NtClose(hLose);
@ -211,7 +277,7 @@ DWORD WINAPI CommandPipe(LPVOID lpThreadParameter)
HANDLE hRemoved = IthOpenEvent(ITH_REMOVEHOOK_EVENT); HANDLE hRemoved = IthOpenEvent(ITH_REMOVEHOOK_EVENT);
TextHook *in = hookman; TextHook *in = hookman;
for (int i = 0; i < current_hook; in++) { for (int i = 0; i < currentHook; in++) {
if (in->Address()) i++; if (in->Address()) i++;
if (in->Address() == rm_addr) break; if (in->Address() == rm_addr) break;
} }
@ -226,7 +292,7 @@ DWORD WINAPI CommandPipe(LPVOID lpThreadParameter)
DWORD rm_addr = *(DWORD *)(buff + 4); DWORD rm_addr = *(DWORD *)(buff + 4);
HANDLE hModify = IthOpenEvent(ITH_MODIFYHOOK_EVENT); HANDLE hModify = IthOpenEvent(ITH_MODIFYHOOK_EVENT);
TextHook *in = hookman; TextHook *in = hookman;
for (int i = 0; i < current_hook; in++) { for (int i = 0; i < currentHook; in++) {
if (in->Address()) if (in->Address())
i++; i++;
if (in->Address() == rm_addr) if (in->Address() == rm_addr)
@ -270,7 +336,7 @@ void ConsoleOutput(LPCSTR text)
memcpy(data + 8, text, text_size); memcpy(data + 8, text, text_size);
IO_STATUS_BLOCK ios; IO_STATUS_BLOCK ios;
NtWriteFile(hPipe, 0, 0, 0, &ios, data, data_size, 0, 0); NtWriteFile(hookPipe, 0, 0, 0, &ios, data, data_size, 0, 0);
if (data != buf) if (data != buf)
delete[] data; delete[] data;
} }
@ -279,7 +345,7 @@ void ConsoleOutput(LPCSTR text)
// BYTE buffer[0x80]; // BYTE buffer[0x80];
// BYTE *buff; // BYTE *buff;
// len = wcslen(str) << 1; // len = wcslen(str) << 1;
// t = swprintf((LPWSTR)(buffer + 8),L"%d: ",current_process_id) << 1; // t = swprintf((LPWSTR)(buffer + 8),L"%d: ",currentProcessId) << 1;
// sum = len + t + 8; // sum = len + t + 8;
// if (sum > 0x80) { // if (sum > 0x80) {
// buff = new BYTE[sum]; // buff = new BYTE[sum];
@ -292,7 +358,7 @@ void ConsoleOutput(LPCSTR text)
// *(DWORD *)(buff + 4) = HOST_NOTIFICATION_TEXT; //console // *(DWORD *)(buff + 4) = HOST_NOTIFICATION_TEXT; //console
// memcpy(buff + t + 8, str, len); // memcpy(buff + t + 8, str, len);
// IO_STATUS_BLOCK ios; // IO_STATUS_BLOCK ios;
// NtWriteFile(hPipe,0,0,0,&ios,buff,sum,0,0); // NtWriteFile(hookPipe,0,0,0,&ios,buff,sum,0,0);
// if (buff != buffer) // if (buff != buffer)
// delete[] buff; // delete[] buff;
// return len; // return len;
@ -343,7 +409,7 @@ DWORD NotifyHookInsert(DWORD addr)
*(DWORD *)(buffer + 0xc) = 0; *(DWORD *)(buffer + 0xc) = 0;
IO_STATUS_BLOCK ios; IO_STATUS_BLOCK ios;
CliLockPipe(); CliLockPipe();
NtWriteFile(hPipe,0,0,0,&ios,buffer,0x10,0,0); NtWriteFile(hookPipe,0,0,0,&ios,buffer,0x10,0,0);
CliUnlockPipe(); CliUnlockPipe();
} }
return 0; return 0;

View File

@ -304,6 +304,7 @@ termin:
EXTERN_C IMAGE_DOS_HEADER __ImageBase; EXTERN_C IMAGE_DOS_HEADER __ImageBase;
// See: http://stackoverflow.com/questions/3410130/dll-unloading-itself // See: http://stackoverflow.com/questions/3410130/dll-unloading-itself
// TODO: This doesn't always work. Fix it.
bool Util::unloadCurrentModule() bool Util::unloadCurrentModule()
{ {
auto fun = ::FreeLibrary; auto fun = ::FreeLibrary;