mirror of
https://github.com/Artikash/Textractor.git
synced 2024-12-23 17:04:12 +08:00
cleaning things up
This commit is contained in:
parent
c7a79e6064
commit
290ef57490
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ 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}};
|
||||||
|
|
||||||
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &processToken);
|
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &processToken);
|
||||||
AdjustTokenPrivileges(processToken, FALSE, &Privileges, 0, nullptr, nullptr);
|
AdjustTokenPrivileges(processToken, FALSE, &Privileges, 0, nullptr, nullptr);
|
||||||
@ -79,7 +79,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID unused)
|
|||||||
IthInitSystemService();
|
IthInitSystemService();
|
||||||
GetDebugPrivileges();
|
GetDebugPrivileges();
|
||||||
// jichi 12/20/2013: Since I already have a GUI, I don't have to InitCommonControls()
|
// jichi 12/20/2013: Since I already have a GUI, I don't have to InitCommonControls()
|
||||||
//Used by timers.
|
// Used by timers.
|
||||||
InitCommonControls();
|
InitCommonControls();
|
||||||
// jichi 8/24/2013: Create hidden window so that ITH can access timer and events
|
// jichi 8/24/2013: Create hidden window so that ITH can access timer and events
|
||||||
dummyWindow = CreateWindowW(L"Button", L"InternalWindow", 0, 0, 0, 0, 0, 0, 0, hinstDLL, 0);
|
dummyWindow = CreateWindowW(L"Button", L"InternalWindow", 0, 0, 0, 0, 0, 0, 0, hinstDLL, 0);
|
||||||
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
|
@ -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,57 +19,57 @@
|
|||||||
|
|
||||||
//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;
|
// jichi 10/27/2013
|
||||||
bool detach = false;
|
// 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 = 0x19 };
|
||||||
|
inline bool HasLeadingSpace(const BYTE *text, int len)
|
||||||
|
{
|
||||||
|
return len == 1 ? *text <= FILTER_LIMIT : // 1 byte
|
||||||
|
*(WORD*)text <= FILTER_LIMIT; // 2 bytes
|
||||||
|
}
|
||||||
|
|
||||||
// jichi 10/27/2013
|
// jichi 9/28/2013: Skip leading garbage
|
||||||
// Check if text has leading space
|
// Note:
|
||||||
enum { _filter_limit = 0x20 }; // The same as the orignal ITH filter. So, I don't have to check \u3000
|
// - Modifying limit will break manual translation. The orignal one is 0x20
|
||||||
//enum { _filter_limit = 0x19 };
|
// - Eliminating 0x20 will break English-translated games
|
||||||
inline bool has_leading_space(const BYTE *text, int len)
|
const BYTE* Filter(const BYTE *str, int len)
|
||||||
{
|
{
|
||||||
return len == 1 ? *text <= _filter_limit : // 1 byte
|
|
||||||
*reinterpret_cast<const WORD *>(text) <= _filter_limit; // 2 bytes
|
|
||||||
}
|
|
||||||
|
|
||||||
// jichi 9/28/2013: Skip leading garbage
|
|
||||||
// Note:
|
|
||||||
// - Modifying limit will break manual translation. The orignal one is 0x20
|
|
||||||
// - Eliminating 0x20 will break English-translated games
|
|
||||||
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
|
while (true)
|
||||||
// return nullptr;
|
{
|
||||||
//enum { limit = 0x19 };
|
if (len >= 2)
|
||||||
while (true)
|
{
|
||||||
if (len >= 2) {
|
if (*(WORD*)str <= FILTER_LIMIT)
|
||||||
if (*(const WORD *)str <= _filter_limit) { // jichi 10/27/2013: two bytes
|
{ // jichi 10/27/2013: two bytes
|
||||||
str += 2;
|
str += 2;
|
||||||
len -= 2;
|
len -= 2;
|
||||||
} else
|
}
|
||||||
break;
|
else
|
||||||
} else if (*str <= _filter_limit) { // jichi 10/27/2013: 1 byte
|
{
|
||||||
str++;
|
break;
|
||||||
len--;
|
}
|
||||||
} else
|
|
||||||
break;
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
} // unnamed namespace
|
|
||||||
|
|
||||||
//WCHAR recv_pipe[] = L"\\??\\pipe\\ITH_PIPE";
|
}
|
||||||
//WCHAR command_pipe[] = L"\\??\\pipe\\ITH_COMMAND";
|
else if (*str <= FILTER_LIMIT)
|
||||||
wchar_t recv_pipe[] = ITH_TEXT_PIPE;
|
{ // jichi 10/27/2013: 1 byte
|
||||||
wchar_t command_pipe[] = ITH_COMMAND_PIPE;
|
str++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
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,204 +77,106 @@ 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
|
// jichi 9/27/2013: why recursion?
|
||||||
//void OutputDWORD(DWORD d)
|
// Artikash 5/20/2018: To create a new pipe for another process
|
||||||
//{
|
CreateNewPipe();
|
||||||
// WCHAR str[0x20];
|
|
||||||
// swprintf(str, L"%.8X", d);
|
|
||||||
// ConsoleOutput(str);
|
|
||||||
//}
|
|
||||||
|
|
||||||
DWORD WINAPI RecvThread(LPVOID lpThreadParameter)
|
while (::running)
|
||||||
{
|
{
|
||||||
HANDLE hTextPipe = (HANDLE)lpThreadParameter;
|
if (!ReadFile(hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
IO_STATUS_BLOCK ios;
|
enum { DATA_OFFSET = 0xc }; // jichi 10/27/2013: Seem to be the data offset in the pipe
|
||||||
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;
|
if (bytesRead < DATA_OFFSET)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
enum { PipeBufferSize = 0x1000 };
|
union { DWORD retn; DWORD commandType; };
|
||||||
buff = new BYTE[PipeBufferSize];
|
DWORD hook = *(DWORD *)buffer;
|
||||||
::memset(buff, 0, PipeBufferSize); // jichi 8/27/2013: zero memory, or it will crash wine on start up
|
retn = *(DWORD *)(buffer + 4);
|
||||||
|
DWORD split = *(DWORD *)(buffer + 8);
|
||||||
|
|
||||||
// 10/19/2014 jichi: there are totally three words received
|
buffer[bytesRead] = 0;
|
||||||
// See: hook/rpc/pipe.cc
|
buffer[bytesRead + 1] = 0;
|
||||||
// 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
|
if (hook == HOST_NOTIFICATION)
|
||||||
DWORD pid = *(DWORD *)buff,
|
{
|
||||||
module = *(DWORD *)(buff + 0x8),
|
switch (commandType)
|
||||||
hookman = *(DWORD *)(buff + 0x4);
|
{
|
||||||
//engine = *(DWORD *)(buff + 0xc);
|
case HOST_NOTIFICATION_NEWHOOK:
|
||||||
man->RegisterProcess(pid, hookman, module);
|
{
|
||||||
|
static long lock;
|
||||||
|
while (InterlockedExchange(&lock, 1) == 1);
|
||||||
|
man->ProcessNewHook()(processId);
|
||||||
|
lock = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HOST_NOTIFICATION_TEXT:
|
||||||
|
USES_CONVERSION;
|
||||||
|
man->AddConsoleOutput(A2W((LPCSTR)(buffer + 8)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// jichi 9/28/2013: Debug raw data
|
||||||
|
//ITH_DEBUG_DWORD9(RecvLen - 0xc,
|
||||||
|
// buffer[0xc], buffer[0xd], buffer[0xe], buffer[0xf],
|
||||||
|
// buffer[0x10], buffer[0x11], buffer[0x12], buffer[0x13]);
|
||||||
|
|
||||||
// jichi 9/27/2013: why recursion?
|
const BYTE *data = buffer + DATA_OFFSET; // th
|
||||||
CreateNewPipe();
|
int dataLength = bytesRead - DATA_OFFSET;
|
||||||
|
bool space = ::HasLeadingSpace(data, dataLength);
|
||||||
|
if (space)
|
||||||
|
{
|
||||||
|
const BYTE *it = ::Filter(data, dataLength);
|
||||||
|
dataLength -= it - data;
|
||||||
|
data = it;
|
||||||
|
}
|
||||||
|
man->DispatchText(processId, data, hook, retn, split, dataLength, space);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//NtClose(IthCreateThread(UpdateWindows,0));
|
EnterCriticalSection(&detachCs);
|
||||||
while (::running) {
|
|
||||||
if (!NT_SUCCESS(NtReadFile(hTextPipe,
|
|
||||||
0, 0, 0,
|
|
||||||
&ios,
|
|
||||||
buff,
|
|
||||||
0xf80,
|
|
||||||
0, 0)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
enum { data_offset = 0xc }; // jichi 10/27/2013: Seem to be the data offset in the pipe
|
DisconnectNamedPipe(hookPipe);
|
||||||
|
DisconnectNamedPipe(man->GetCmdHandleByPID(processId));
|
||||||
|
man->UnRegisterProcess(processId);
|
||||||
|
|
||||||
DWORD RecvLen = ios.uInformation;
|
LeaveCriticalSection(&detachCs);
|
||||||
if (RecvLen < data_offset)
|
delete[] buffer;
|
||||||
break;
|
|
||||||
DWORD hook = *(DWORD *)buff;
|
|
||||||
|
|
||||||
union { DWORD retn; DWORD cmd_type; };
|
return 0;
|
||||||
union { DWORD split; DWORD new_engine_type; };
|
|
||||||
|
|
||||||
retn = *(DWORD *)(buff + 4);
|
|
||||||
split = *(DWORD *)(buff + 8);
|
|
||||||
|
|
||||||
buff[RecvLen] = 0;
|
|
||||||
buff[RecvLen + 1] = 0;
|
|
||||||
|
|
||||||
if (hook == HOST_NOTIFICATION) {
|
|
||||||
switch (cmd_type) {
|
|
||||||
case HOST_NOTIFICATION_NEWHOOK:
|
|
||||||
{
|
|
||||||
static long lock;
|
|
||||||
while (InterlockedExchange(&lock, 1) == 1);
|
|
||||||
ProcessEventCallback new_hook = man->ProcessNewHook();
|
|
||||||
if (new_hook)
|
|
||||||
new_hook(pid);
|
|
||||||
lock = 0;
|
|
||||||
} break;
|
|
||||||
case HOST_NOTIFICATION_TEXT:
|
|
||||||
//qDebug() << ((LPCSTR)(buff + 8));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// jichi 9/28/2013: Debug raw data
|
|
||||||
//ITH_DEBUG_DWORD9(RecvLen - 0xc,
|
|
||||||
// buff[0xc], buff[0xd], buff[0xe], buff[0xf],
|
|
||||||
// buff[0x10], buff[0x11], buff[0x12], buff[0x13]);
|
|
||||||
|
|
||||||
const BYTE *data = buff + data_offset; // th
|
|
||||||
int len = RecvLen - data_offset;
|
|
||||||
bool space = ::has_leading_space(data, len);
|
|
||||||
if (space) {
|
|
||||||
const BYTE *it = ::Filter(data, len);
|
|
||||||
len -= it - data;
|
|
||||||
data = it;
|
|
||||||
}
|
|
||||||
if (len >> 31) // jichi 10/27/2013: len is too large, which seldom happens
|
|
||||||
len = 0;
|
|
||||||
//man->DispatchText(pid, len ? data : nullptr, hook, retn, split, len, space);
|
|
||||||
man->DispatchText(pid, data, hook, retn, split, len, space);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EnterCriticalSection(&detachCs);
|
|
||||||
|
|
||||||
HANDLE hDisconnect = IthCreateEvent(nullptr);
|
|
||||||
|
|
||||||
if (STATUS_PENDING == NtFsControlFile(
|
|
||||||
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);
|
|
||||||
delete[] buff;
|
|
||||||
|
|
||||||
if (::running)
|
|
||||||
DOUT("detached");
|
|
||||||
|
|
||||||
//if (::running) {
|
|
||||||
// swprintf((LPWSTR)buff, FormatDetach, pid);
|
|
||||||
// ConsoleOutput((LPWSTR)buff);
|
|
||||||
// NtClose(IthCreateThread(UpdateWindows, 0));
|
|
||||||
//}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user