diff --git a/gui/ProcessWindow.cpp b/gui/ProcessWindow.cpp index 84c3f3e..4845dd5 100644 --- a/gui/ProcessWindow.cpp +++ b/gui/ProcessWindow.cpp @@ -76,9 +76,9 @@ void ProcessWindow::AttachProcess() { DWORD pid = GetSelectedPID(); if (InjectProcessById(pid)) - { RefreshThreadWithPID(pid, true); - } + else + ConsoleOutput(L"NextHooker: could not inject"); } void ProcessWindow::DetachProcess() diff --git a/gui/main.cpp b/gui/main.cpp index 08e87d9..040e505 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -18,7 +18,6 @@ #include "ITH.h" #include "host/host.h" #include "host/hookman.h" -#include "host/settings.h" #include "profile/Profile.h" #include "ProfileManager.h" @@ -30,7 +29,6 @@ extern HWND hMainWnd; // windows.cpp extern ProfileManager* pfman; // ProfileManager.cpp HookManager* man; -Settings* setman; LONG split_time; std::map setting; @@ -148,17 +146,15 @@ LONG WINAPI UnhandledExcept(_EXCEPTION_POINTERS *ExceptionInfo) int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { InitCommonControls(); - if (OpenHost()) + if (StartHost()) { SetUnhandledExceptionFilter(UnhandledExcept); GetHostHookManager(&man); - GetHostSettings(&setman); - setman->splittingInterval = 200; pfman = new ProfileManager(); DefaultSettings(); LoadSettings(); InitializeSettings(); - setman->splittingInterval = split_time; + man->SetSplitInterval(split_time); hIns = hInstance; MyRegisterClass(hIns); InitInstance(hIns, FALSE, &window); diff --git a/gui/window.cpp b/gui/window.cpp index 8db3c94..c03ec99 100644 --- a/gui/window.cpp +++ b/gui/window.cpp @@ -23,7 +23,6 @@ #include "vnrhook/include/const.h" #include "version.h" #include "ProfileManager.h" -#include "host/settings.h" #include "profile/Profile.h" #include "TextBuffer.h" #include "profile/misc.h" @@ -44,7 +43,6 @@ ProcessWindow* pswnd; TextBuffer* texts; extern ProfileManager* pfman; // ProfileManager.cpp extern HookManager* man; // main.cpp -extern Settings* setman; // main.cpp #define COMMENT_BUFFER_LENGTH 512 static WCHAR comment_buffer[COMMENT_BUFFER_LENGTH]; @@ -108,7 +106,7 @@ BOOL CALLBACK OptionDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) GetWindowText(GetDlgItem(hDlg, IDC_EDIT1), str, 0x80); DWORD st = std::stoul(str); split_time = st > 100 ? st : 100; - setman->splittingInterval = split_time; + man->SetSplitInterval(split_time); } case IDCANCEL: EndDialog(hDlg, 0); @@ -602,7 +600,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) man->RegisterProcessDetachCallback(RemoveProcessList); //man->RegisterProcessNewHookCallback(RefreshProfileOnNewHook); Artikash 5/30/2018 TODO: Finish implementing this. man->RegisterAddRemoveLinkCallback(AddRemoveLink); - StartHost(); + OpenHost(); { static const WCHAR program_name[] = L"NextHooker beta v"; //static const WCHAR program_version[] = L"3.0"; diff --git a/vnr/ithsys/ithsys.cc b/vnr/ithsys/ithsys.cc index e9e530f..d671feb 100644 --- a/vnr/ithsys/ithsys.cc +++ b/vnr/ithsys/ithsys.cc @@ -67,6 +67,15 @@ DWORD IthGetMemoryRange(LPCVOID mem, DWORD *base, DWORD *size) return (info.Type&PAGE_NOACCESS) == 0; } +inline DWORD GetHash(LPSTR str) +{ + DWORD hash = 0; + //for (; *str; str++) + while (*str) + hash = ((hash >> 7) | (hash << 25)) + *str++; + return hash; +} + //Query module export table. Return function address if found. //Similar to GetProcAddress DWORD GetExportAddress(DWORD hModule,DWORD hash) diff --git a/vnr/ithsys/ithsys.h b/vnr/ithsys/ithsys.h index 2266c16..381f01b 100644 --- a/vnr/ithsys/ithsys.h +++ b/vnr/ithsys/ithsys.h @@ -21,13 +21,4 @@ DWORD GetExportAddress(DWORD hModule,DWORD hash); extern BYTE LeadByteTable[]; -inline DWORD GetHash(LPSTR str) -{ - DWORD hash = 0; - //for (; *str; str++) - while (*str) - hash = ((hash>>7) | (hash<<25)) + *str++; - return hash; -} - // EOF diff --git a/vnr/texthook/host/CMakeLists.txt b/vnr/texthook/host/CMakeLists.txt index 22375ea..97b0ec3 100644 --- a/vnr/texthook/host/CMakeLists.txt +++ b/vnr/texthook/host/CMakeLists.txt @@ -11,7 +11,6 @@ set(vnrhost_src hookman.h host.h host_p.h - settings.h textthread.h textthread_p.h hookman.cc diff --git a/vnr/texthook/host/config.h b/vnr/texthook/host/config.h index 7e1d50a..fa322ea 100644 --- a/vnr/texthook/host/config.h +++ b/vnr/texthook/host/config.h @@ -5,10 +5,6 @@ // The first header file that are included by all source files. #define IHF // for dll import -//#include "ith/dllconfig.h" -#define IHFAPI __stdcall -#ifdef IHF -# define IHFSERVICE __declspec(dllexport) -#endif +#define DLLEXPORT __declspec(dllexport) // EOF diff --git a/vnr/texthook/host/hookman.cc b/vnr/texthook/host/hookman.cc index 4ff1397..1685c6a 100644 --- a/vnr/texthook/host/hookman.cc +++ b/vnr/texthook/host/hookman.cc @@ -12,88 +12,27 @@ #include "vnrhook/include/const.h" #include "vnrhook/include/defs.h" #include "vnrhook/include/types.h" -#include "ithsys/ithsys.h" #include //#include #include "profile/Profile.h" #include "profile/pugixml.h" #include "profile/misc.h" -#define DEBUG "vnrhost/hookman.cc" - -namespace { // unnamed -//enum { MAX_ENTRY = 0x40 }; - #define HM_LOCK CriticalSectionLocker d_locker(hmcs) // Synchronized scope for accessing private data - -} // unnamed namespace - -HookManager *man; // jichi 9/22/2013: initialized in main -//BitMap* pid_map; -DWORD clipboard_flag, - split_time, - repeat_count, - global_filter, - cyclic_remove; - -DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max) -{ - if (!pid) - return 0; - - DWORD len = 0; - max--; //for '\0' magic marker. - - //if (pid == 0) { - // len = wcslen(HookNameInitTable[0]); - // if (len >= max) - // len = max; - // memcpy(str, HookNameInitTable[0], len << 1); - // str[len] = 0; - // return len; - //} - - //::man->LockProcessHookman(pid); - ProcessRecord *pr = ::man->GetProcessRecord(pid); - if (!pr) - return 0; - WaitForSingleObject(pr->hookman_mutex, 0); - const Hook *hks = (const Hook *)pr->hookman_map; - for (int i = 0; i < MAX_HOOK; i++) - if (hks[i].Address() == hook_addr) { - len = hks[i].NameLength(); - if (len >= max) - len = max; - ReadProcessMemory(pr->process_handle, hks[i].Name(), str, len, &len); - if (str[len - 1] == 0) - len--; - else - str[len] = 0; - break; - } - - ReleaseMutex(pr->hookman_mutex); - //::man->UnlockProcessHookman(pid); - return len; -} - -//Class member of HookManger HookManager::HookManager() : - // jichi 9/21/2013: Zero memory - //CRITICAL_SECTION hmcs; - current(nullptr) - , create(nullptr) - , remove(nullptr) - , reset(nullptr) - , attach(nullptr) - , detach(nullptr) - , hook(nullptr) - , new_thread_number(0) - , threadTable() - , processRecordsByIds() + current(nullptr), + create(nullptr), + remove(nullptr), + reset(nullptr), + attach(nullptr), + detach(nullptr), + hook(nullptr), + new_thread_number(0), + threadTable(), + processRecordsByIds() { - TextThread* consoleTextThread = threadTable[{0, -1UL, -1UL, -1UL}] = new TextThread({ 0, -1UL, -1UL, -1UL }, new_thread_number++); + TextThread* consoleTextThread = threadTable[{0, -1UL, -1UL, -1UL}] = new TextThread({ 0, -1UL, -1UL, -1UL }, new_thread_number++, splitDelay); consoleTextThread->Status() |= USING_UNICODE; SetCurrent(consoleTextThread); @@ -102,17 +41,7 @@ HookManager::HookManager() : HookManager::~HookManager() { - // Artikash 5/31/2018: This is called when the program terminates, so Windows should automatically free all these resources.....right? - //LeaveCriticalSection(&hmcs); - //LARGE_INTEGER timeout={-1000*1000,-1}; - //IthBreak(); - //NtWaitForSingleObject(destroy_event, 0, 0); - //CloseHandle(destroy_event); - //CloseHandle(cmd_pipes[0]); - //CloseHandle(recv_threads[0]); - //delete thread_table; - //delete head.key; - //DeleteCriticalSection(&hmcs); + DeleteCriticalSection(&hmcs); } TextThread *HookManager::FindSingle(DWORD number) @@ -232,7 +161,7 @@ void HookManager::DispatchText(DWORD pid, const BYTE *text, DWORD hook, DWORD re TextThread *it; if (!(it = threadTable[tp])) { - it = threadTable[tp] = new TextThread(tp, new_thread_number++); + it = threadTable[tp] = new TextThread(tp, new_thread_number++, splitDelay); if (create) { create(it); @@ -267,15 +196,12 @@ ProcessRecord *HookManager::GetProcessRecord(DWORD pid) return processRecordsByIds[pid]; } -HANDLE HookManager::GetCommandPipe(DWORD pid) +HANDLE HookManager::GetHostPipe(DWORD pid) { HM_LOCK; return processRecordsByIds[pid] ? processRecordsByIds[pid]->hostPipe : nullptr; } -MK_BASIC_TYPE(DWORD) -MK_BASIC_TYPE(LPVOID) - void AddHooksToProfile(Profile& pf, const ProcessRecord& pr); DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread* thread); void MakeHookRelative(const ProcessRecord& pr, HookParam& hp); diff --git a/vnr/texthook/host/hookman.h b/vnr/texthook/host/hookman.h index 93defbb..78e63b0 100644 --- a/vnr/texthook/host/hookman.h +++ b/vnr/texthook/host/hookman.h @@ -18,15 +18,12 @@ enum { MAX_REGISTER = 0xf }; enum { MAX_PREV_REPEAT_LENGTH = 0x20 }; struct ProcessRecord { - DWORD pid_register; - DWORD hookman_register; - DWORD module_register; - //DWORD engine_register; // jichi 10/19/2014: removed HANDLE process_handle; HANDLE hookman_mutex; HANDLE hookman_section; LPVOID hookman_map; HANDLE hostPipe; + //std::unordered_map hooksByAddress; }; typedef DWORD (*ProcessEventCallback)(DWORD pid); @@ -39,7 +36,7 @@ struct ThreadParameterHasher } }; -class IHFSERVICE HookManager +class DLLEXPORT HookManager { public: HookManager(); @@ -62,7 +59,7 @@ public: void UnRegisterProcess(DWORD pid); //void SetName(DWORD); - HANDLE GetCommandPipe(DWORD pid); + HANDLE GetHostPipe(DWORD pid); ThreadEventCallback RegisterThreadCreateCallback(ThreadEventCallback cf) { return (ThreadEventCallback)_InterlockedExchange((long*)&create,(long)cf); } @@ -82,6 +79,8 @@ public: ProcessEventCallback RegisterProcessDetachCallback(ProcessEventCallback cf) { return (ProcessEventCallback)_InterlockedExchange((long*)&detach,(long)cf); } + void SetSplitInterval(unsigned int splitDelay) { this->splitDelay = splitDelay; } + void OnThreadCreate(pugi::xml_node profile_node, TextThread* thread); void GetProfile(DWORD pid, pugi::xml_node profile_node); @@ -102,6 +101,8 @@ private: WORD register_count, new_thread_number; + unsigned int splitDelay; + void HookManager::AddThreadsToProfile(Profile& pf, const ProcessRecord& pr, DWORD pid); }; diff --git a/vnr/texthook/host/host.cc b/vnr/texthook/host/host.cc index a1fb258..5ab07ab 100644 --- a/vnr/texthook/host/host.cc +++ b/vnr/texthook/host/host.cc @@ -10,34 +10,20 @@ //#include "customfilter.h" #include "growl.h" #include "host.h" -#include "host_p.h" -#include "settings.h" #include "vnrhook/include/const.h" #include "vnrhook/include/defs.h" #include "vnrhook/include/types.h" -#include "ithsys/ithsys.h" #include #include #include "extensions/Extensions.h" #define DEBUG "vnrhost/host.cc" -namespace -{ // unnamed +HANDLE preventDuplicationMutex; - CRITICAL_SECTION hostCs; - HANDLE preventDuplicationMutex; // jichi 9/28/2013: used to guard pipe - HANDLE hookMutex; // jichi 9/28/2013: used to guard hook modification -} // unnamed namespace - -//extern LPWSTR current_dir; -extern CRITICAL_SECTION detachCs; - -Settings *settings; +HookManager* man; HWND dummyWindow; -BOOL running; - -#define ITH_SYNC_HOOK MutexLocker locker(::hookMutex) +bool running; namespace { // unnamed @@ -62,7 +48,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID unused) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); - InitializeCriticalSection(&::hostCs); GetDebugPrivileges(); // jichi 12/20/2013: Since I already have a GUI, I don't have to InitCommonControls() // Used by timers. @@ -73,7 +58,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID unused) case DLL_PROCESS_DETACH: if (::running) CloseHost(); - DeleteCriticalSection(&::hostCs); DestroyWindow(dummyWindow); break; default: @@ -82,129 +66,83 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID unused) return true; } -IHFSERVICE bool IHFAPI OpenHost() +DLLEXPORT bool StartHost() { - bool success; - EnterCriticalSection(&::hostCs); preventDuplicationMutex = CreateMutexW(nullptr, TRUE, ITH_SERVER_MUTEX); if (GetLastError() == ERROR_ALREADY_EXISTS || ::running) { GROWL_WARN(L"I am sorry that this game is attached by some other VNR ><\nPlease restart the game and try again!"); - success = false; + return false; } else { LoadExtensions(); ::running = true; - ::settings = new Settings; ::man = new HookManager; - InitializeCriticalSection(&detachCs); - ::hookMutex = CreateMutexW(nullptr, FALSE, ITH_SERVER_HOOK_MUTEX); - success = true; + return true; } - LeaveCriticalSection(&::hostCs); - return success; } -IHFSERVICE void IHFAPI StartHost() +DLLEXPORT void OpenHost() { CreateNewPipe(); } -IHFSERVICE void IHFAPI CloseHost() +DLLEXPORT void CloseHost() { - EnterCriticalSection(&::hostCs); if (::running) { ::running = false; delete man; - delete settings; - CloseHandle(::hookMutex); CloseHandle(preventDuplicationMutex); - DeleteCriticalSection(&detachCs); } - LeaveCriticalSection(&::hostCs); } -IHFSERVICE bool IHFAPI InjectProcessById(DWORD processId, DWORD timeout) +DLLEXPORT bool InjectProcessById(DWORD processId, DWORD timeout) { - bool success = true; if (processId == GetCurrentProcessId()) { - success = false; + return false; } CloseHandle(CreateMutexW(nullptr, FALSE, (ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId)).c_str())); if (GetLastError() == ERROR_ALREADY_EXISTS) { man->AddConsoleOutput(L"already locked"); - success = false; + return false; } HMODULE textHooker = LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES); - if (textHooker == nullptr) - { - success = false; - } wchar_t textHookerPath[MAX_PATH]; unsigned int textHookerPathSize = GetModuleFileNameW(textHooker, textHookerPath, MAX_PATH) * 2 + 2; FreeLibrary(textHooker); - HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId); - if (processHandle == INVALID_HANDLE_VALUE || processHandle == nullptr) - { - success = false; - } - - LPTHREAD_START_ROUTINE loadLibraryStartRoutine = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW"); - - if (success) - { + if (HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId)) if (LPVOID remoteData = VirtualAllocEx(processHandle, nullptr, textHookerPathSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) - { if (WriteProcessMemory(processHandle, remoteData, textHookerPath, textHookerPathSize, nullptr)) - { - if (HANDLE thread = CreateRemoteThread(processHandle, nullptr, 0, loadLibraryStartRoutine, remoteData, 0, nullptr)) + if (HANDLE thread = CreateRemoteThread(processHandle, nullptr, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, remoteData, 0, nullptr)) { WaitForSingleObject(thread, timeout); CloseHandle(thread); + VirtualFreeEx(processHandle, remoteData, textHookerPathSize, MEM_RELEASE); + CloseHandle(processHandle); + return true; } - else - { - success = false; - } - } - else - { - success = false; - } - VirtualFreeEx(processHandle, remoteData, textHookerPathSize, MEM_RELEASE); - } - else - { - success = false; - } - } - - if (!success) - { - man->AddConsoleOutput(L"error: could not inject"); - } - - CloseHandle(processHandle); - return success; + + man->AddConsoleOutput(L"couldn't inject dll"); + return false; } -IHFSERVICE bool IHFAPI DetachProcessById(DWORD processId) +DLLEXPORT bool DetachProcessById(DWORD processId) { DWORD command = HOST_COMMAND_DETACH; DWORD unused; - return WriteFile(man->GetCommandPipe(processId), &command, sizeof(command), &unused, nullptr); + return WriteFile(man->GetHostPipe(processId), &command, sizeof(command), &unused, nullptr); } -IHFSERVICE void IHFAPI GetHostHookManager(HookManager** hookman) +DLLEXPORT void GetHostHookManager(HookManager** hookman) { if (::running) { @@ -212,17 +150,9 @@ IHFSERVICE void IHFAPI GetHostHookManager(HookManager** hookman) } } -IHFSERVICE void IHFAPI GetHostSettings(Settings **p) +DLLEXPORT DWORD InsertHook(DWORD pid, const HookParam *hp, std::string name) { - if (::running) - { - *p = settings; - } -} - -IHFSERVICE DWORD IHFAPI InsertHook(DWORD pid, const HookParam *hp, std::string name) -{ - HANDLE commandPipe = man->GetCommandPipe(pid); + HANDLE commandPipe = man->GetHostPipe(pid); if (commandPipe == nullptr) return -1; @@ -236,9 +166,9 @@ IHFSERVICE DWORD IHFAPI InsertHook(DWORD pid, const HookParam *hp, std::string n return 0; } -IHFSERVICE DWORD IHFAPI RemoveHook(DWORD pid, DWORD addr) +DLLEXPORT DWORD RemoveHook(DWORD pid, DWORD addr) { - HANDLE commandPipe = man->GetCommandPipe(pid); + HANDLE commandPipe = man->GetHostPipe(pid); if (commandPipe == nullptr) return -1; diff --git a/vnr/texthook/host/host.h b/vnr/texthook/host/host.h index 3570d17..d47879f 100644 --- a/vnr/texthook/host/host.h +++ b/vnr/texthook/host/host.h @@ -9,26 +9,15 @@ #include "host/hookman.h" #include -struct Settings; struct HookParam; -IHFSERVICE void IHFAPI Host_Init(); -IHFSERVICE void IHFAPI Host_Destroy(); - -IHFSERVICE void IHFAPI StartHost(); -IHFSERVICE bool IHFAPI OpenHost(); -IHFSERVICE void IHFAPI CloseHost(); -IHFSERVICE void IHFAPI GetHostHookManager(HookManager **hookman); -IHFSERVICE void IHFAPI GetHostSettings(Settings **settings); -IHFSERVICE DWORD IHFAPI Host_GetPIDByName(LPCWSTR pwcTarget); -IHFSERVICE bool IHFAPI InjectProcessById(DWORD pid, DWORD timeout = 5000); -IHFSERVICE bool IHFAPI DetachProcessById(DWORD pid); -IHFSERVICE bool IHFAPI Host_HijackProcess(DWORD pid); -IHFSERVICE DWORD IHFAPI InsertHook(DWORD pid, const HookParam *hp, std::string name = ""); -IHFSERVICE DWORD IHFAPI Host_ModifyHook(DWORD pid, HookParam *hp); -IHFSERVICE DWORD IHFAPI RemoveHook(DWORD pid, DWORD addr); -IHFSERVICE DWORD IHFAPI Host_AddLink(DWORD from, DWORD to); -IHFSERVICE DWORD IHFAPI Host_UnLink(DWORD from); -IHFSERVICE DWORD IHFAPI Host_UnLinkAll(DWORD from); +DLLEXPORT void OpenHost(); +DLLEXPORT bool StartHost(); +DLLEXPORT void CloseHost(); +DLLEXPORT void GetHostHookManager(HookManager **hookman); +DLLEXPORT bool InjectProcessById(DWORD pid, DWORD timeout = 5000); +DLLEXPORT bool DetachProcessById(DWORD pid); +DLLEXPORT DWORD InsertHook(DWORD pid, const HookParam *hp, std::string name = ""); +DLLEXPORT DWORD RemoveHook(DWORD pid, DWORD addr); // EOF diff --git a/vnr/texthook/host/host_p.h b/vnr/texthook/host/host_p.h deleted file mode 100644 index 1dbdf20..0000000 --- a/vnr/texthook/host/host_p.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -// host_p.h -// 8/24/2013 jichi -// Branch IHF/main.h, rev 111 -#include -#include - -#define GLOBAL extern -#define SHIFT_JIS 0x3A4 -class HookManager; -//class CommandQueue; -class SettingManager; -class TextHook; -//class BitMap; -//class CustomFilterMultiByte; -//class CustomFilterUnicode; -//#define TextHook Hook -GLOBAL BOOL running; -//GLOBAL BitMap *pid_map; -//GLOBAL CustomFilterMultiByte *mb_filter; -//GLOBAL CustomFilterUnicode *uni_filter; -GLOBAL HookManager *man; -//GLOBAL CommandQueue *cmdq; -GLOBAL SettingManager *setman; -GLOBAL WCHAR recv_pipe[]; -GLOBAL WCHAR command[]; -GLOBAL HANDLE pipeExistsEvent; -GLOBAL DWORD split_time, - cyclic_remove, - clipboard_flag, - global_filter; -GLOBAL CRITICAL_SECTION detachCs; - -DWORD WINAPI TextReceiver(LPVOID lpThreadParameter); -DWORD WINAPI CmdThread(LPVOID lpThreadParameter); - -DWORD GetCurrentPID(); -//DWORD GetProcessIDByPath(LPWSTR str); -HANDLE GetCommandPipe(DWORD pid); -//DWORD Inject(HANDLE hProc); -//DWORD InjectByPID(DWORD pid); -//DWORD PIDByName(LPWSTR target); -//DWORD Hash(LPCWSTR module, int length=-1); - -// EOF diff --git a/vnr/texthook/host/pipe.cc b/vnr/texthook/host/pipe.cc index 0b24f96..57d737b 100644 --- a/vnr/texthook/host/pipe.cc +++ b/vnr/texthook/host/pipe.cc @@ -3,22 +3,15 @@ // Branch IHF/pipe.cpp, rev 93 // 8/24/2013 TODO: Clean up this file -#include "host_p.h" +#include "host.h" #include "hookman.h" #include "vnrhook/include/defs.h" #include "vnrhook/include/const.h" -#include "ithsys/ithsys.h" #include #include "growl.h" #include -//#include "CommandQueue.h" -//#include -#define DEBUG "vnrhost/pipe.cc" - -CRITICAL_SECTION detachCs; // jichi 9/27/2013: also used in main -//HANDLE hDetachEvent; -extern HANDLE pipeExistsEvent; +extern HookManager* man; struct Pipes { @@ -26,14 +19,16 @@ struct Pipes HANDLE hostPipe; }; +DWORD WINAPI TextReceiver(LPVOID lpThreadParameter); + void CreateNewPipe() { - CreateThread(nullptr, 0, TextReceiver, new Pipes + CloseHandle(CreateThread(nullptr, 0, TextReceiver, new Pipes { CreateNamedPipeW(ITH_TEXT_PIPE, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, MAXDWORD, NULL), CreateNamedPipeW(ITH_COMMAND_PIPE, PIPE_ACCESS_OUTBOUND, 0, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, MAXDWORD, NULL) }, - 0, nullptr); + 0, nullptr)); } DWORD WINAPI TextReceiver(LPVOID lpThreadParameter) @@ -57,34 +52,22 @@ DWORD WINAPI TextReceiver(LPVOID lpThreadParameter) // Artikash 5/20/2018: To create a new pipe for another process CreateNewPipe(); - while (::running) + while (true) { - if (!ReadFile(pipes->hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr)) - { - break; - } - - enum { DATA_OFFSET = 0xc }; // jichi 10/27/2013: Seem to be the data offset in the pipe - - if (bytesRead < DATA_OFFSET) - { - break; - } - - union { DWORD retn; DWORD commandType; }; - DWORD hook = *(DWORD *)buffer; - retn = *(DWORD *)(buffer + 4); - DWORD split = *(DWORD *)(buffer + 8); + if (!ReadFile(pipes->hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr)) break; buffer[bytesRead] = 0; buffer[bytesRead + 1] = 0; - if (hook == HOST_NOTIFICATION) + if (*(DWORD*)buffer == HOST_NOTIFICATION) { - switch (commandType) + switch (*(DWORD*)(buffer + 4)) // Artikash 7/17/2018: Notification type { - case HOST_NOTIFICATION_NEWHOOK: // Artikash 5/30/2018: Useless for now, but could be handy to implement something later + case HOST_NOTIFICATION_NEWHOOK: + { + break; + } case HOST_NOTIFICATION_TEXT: USES_CONVERSION; man->AddConsoleOutput(A2W((LPCSTR)(buffer + 8))); @@ -93,24 +76,26 @@ DWORD WINAPI TextReceiver(LPVOID lpThreadParameter) } else { + DWORD hook = *(DWORD*)buffer; + DWORD retn = *(DWORD*)(buffer + 4); + DWORD split = *(DWORD*)(buffer + 8); // 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]); - const BYTE *data = buffer + DATA_OFFSET; // th - int dataLength = bytesRead - DATA_OFFSET; + const BYTE *data = buffer + HEADER_SIZE; // th + int dataLength = bytesRead - HEADER_SIZE; man->DispatchText(processId, data, hook, retn, split, dataLength); } } - EnterCriticalSection(&detachCs); - DisconnectNamedPipe(pipes->hookPipe); DisconnectNamedPipe(pipes->hostPipe); man->UnRegisterProcess(processId); + CloseHandle(pipes->hookPipe); + CloseHandle(pipes->hostPipe); - LeaveCriticalSection(&detachCs); delete pipes; return 0; diff --git a/vnr/texthook/host/settings.h b/vnr/texthook/host/settings.h deleted file mode 100644 index c6919ee..0000000 --- a/vnr/texthook/host/settings.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -// settings.h -// 8/24/2013 jichi - -struct Settings { - //bool debug; // whether output debug messages using pipes - int splittingInterval;// time to split text into sentences - bool clipboardFlag; - - Settings() : splittingInterval(200), - clipboardFlag(false) - {} - -}; - -// EOF diff --git a/vnr/texthook/host/textthread.cc b/vnr/texthook/host/textthread.cc index a925deb..347b537 100644 --- a/vnr/texthook/host/textthread.cc +++ b/vnr/texthook/host/textthread.cc @@ -7,41 +7,66 @@ # pragma warning (disable:4100) // C4100: unreference formal parameter #endif // _MSC_VER -#include "settings.h" +#include "host.h" #include "textthread.h" //#include "wintimer/wintimer.h" #include "vnrhook/include/const.h" -#include "ithsys/ithsys.h" +#include "vnrhook/include/types.h" #include #include "extensions/Extensions.h" -MK_BASIC_TYPE(BYTE) -MK_BASIC_TYPE(ThreadParameter) +extern HookManager* man; -static DWORD MIN_DETECT = 0x20; -static DWORD MIN_REDETECT = 0x80; -//#define MIN_DETECT 0x20 -//#define MIN_REDETECT 0x80 -#ifndef CURRENT_SELECT -# define CURRENT_SELECT 0x1000 -#endif -#ifndef REPEAT_NUMBER_DECIDED -# define REPEAT_NUMBER_DECIDED 0x2000 -#endif +DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max) +{ + if (!pid) + return 0; -DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr,DWORD max); + DWORD len = 0; + max--; //for '\0' magic marker. + + //if (pid == 0) { + // len = wcslen(HookNameInitTable[0]); + // if (len >= max) + // len = max; + // memcpy(str, HookNameInitTable[0], len << 1); + // str[len] = 0; + // return len; + //} + + //::man->LockProcessHookman(pid); + ProcessRecord *pr = ::man->GetProcessRecord(pid); + if (!pr) + return 0; + WaitForSingleObject(pr->hookman_mutex, 0); + const Hook *hks = (const Hook *)pr->hookman_map; + for (int i = 0; i < MAX_HOOK; i++) + if (hks[i].Address() == hook_addr) { + len = hks[i].NameLength(); + if (len >= max) + len = max; + ReadProcessMemory(pr->process_handle, hks[i].Name(), str, len, &len); + if (str[len - 1] == 0) + len--; + else + str[len] = 0; + break; + } + + ReleaseMutex(pr->hookman_mutex); + //::man->UnlockProcessHookman(pid); + return len; +} -extern Settings *settings; extern HWND dummyWindow; -TextThread::TextThread(ThreadParameter tp, WORD num) : - //,tp - thread_number(num) - , output(nullptr) - //, comment(nullptr) - , status(0) - , tp(tp) - , sentenceBuffer() +TextThread::TextThread(ThreadParameter tp, unsigned int threadNumber, unsigned int splitDelay) : + thread_number(threadNumber), + splitDelay(splitDelay), + output(nullptr), + status(0), + tp(tp), + sentenceBuffer() { } @@ -77,7 +102,7 @@ void TextThread::AddSentence(std::wstring sentence) void TextThread::AddText(const BYTE *con, int len) { sentenceBuffer.insert(sentenceBuffer.end(), con, con+len); - SetTimer(dummyWindow, (UINT_PTR)this, settings->splittingInterval, + SetTimer(dummyWindow, (UINT_PTR)this, splitDelay, [](HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { KillTimer(hWnd, idEvent); diff --git a/vnr/texthook/host/textthread.h b/vnr/texthook/host/textthread.h index 423d6d4..064d3b6 100644 --- a/vnr/texthook/host/textthread.h +++ b/vnr/texthook/host/textthread.h @@ -23,13 +23,6 @@ struct ThreadParameter { }; #define CURRENT_SELECT 0x1000 -#define REPEAT_NUMBER_DECIDED 0x2000 -#define BUFF_NEWLINE 0x4000 -#define CYCLIC_REPEAT 0x8000 -#define COUNT_PER_FOWARD 0x200 -#define REPEAT_DETECT 0x10000 -#define REPEAT_SUPPRESS 0x20000 -#define REPEAT_NEWLINE 0x40000 class TextThread; typedef DWORD (* ThreadOutputFilterCallback)(TextThread *,const BYTE *, DWORD, DWORD); @@ -40,7 +33,7 @@ typedef DWORD (* ThreadEventCallback)(TextThread *); class TextThread : public MyVector { public: - TextThread(ThreadParameter tp, WORD num); + TextThread(ThreadParameter tp, unsigned int threadNumber, unsigned int splitDelay); virtual void GetEntryString(LPSTR buffer, DWORD max); @@ -64,10 +57,10 @@ public: private: ThreadParameter tp; - + ThreadOutputFilterCallback output; std::vector sentenceBuffer; unsigned int thread_number; - ThreadOutputFilterCallback output; + unsigned int splitDelay; DWORD status; }; diff --git a/vnr/texthook/host/textthread_p.h b/vnr/texthook/host/textthread_p.h index bdfc21c..f1512a0 100644 --- a/vnr/texthook/host/textthread_p.h +++ b/vnr/texthook/host/textthread_p.h @@ -5,15 +5,6 @@ #include -template -void Release(const T &p) { delete p; } - -// Prevent memory release. -// Used when T is basic types and will be automatically released (on stack). -#define MK_BASIC_TYPE(T) \ - template<> \ - void Release(const T &p) {} - template class MyVector { @@ -42,7 +33,7 @@ protected: { EnterCriticalSection(&cs_store); for (int i = 0; i < used; i++) { - Release(storage[i]); + //Release(storage[i]); storage[i] = T(); } used = 0; @@ -52,7 +43,7 @@ protected: { if (index>=used) return; - Release(storage[index]); + //Release(storage[index]); for (int i = index; i < used; i++) storage[i] = storage[i+1]; used--; diff --git a/vnr/vnrhook/include/const.h b/vnr/vnrhook/include/const.h index 23a3cee..336fa32 100644 --- a/vnr/vnrhook/include/const.h +++ b/vnr/vnrhook/include/const.h @@ -248,6 +248,13 @@ enum { , IHF_FILTER_CAPACITY = IHF_FILTER_COUNT + 1 // one more than the dll count }; +// jichi 12/25/2013: Header in each message sent to vnrsrv +// There are totally three elements +// - 0x0 dwAddr hook address +// - 0x4 dwRetn return address +// - 0x8 dwSplit split value +#define HEADER_SIZE 0xc + #define TIMEOUT 5000 // 5 seconds // EOF diff --git a/vnr/vnrhook/src/hijack/texthook.h b/vnr/vnrhook/src/hijack/texthook.h index bcacf09..bdfe3ac 100644 --- a/vnr/vnrhook/src/hijack/texthook.h +++ b/vnr/vnrhook/src/hijack/texthook.h @@ -12,13 +12,6 @@ #include "include/types.h" #include -// jichi 12/25/2013: Header in each message sent to vnrsrv -// There are totally three elements -// - 0x0 dwAddr hook address -// - 0x4 dwRetn return address -// - 0x8 dwSplit split value -#define HEADER_SIZE 0xc - extern int currentHook; extern WCHAR dll_mutex[]; //extern WCHAR dll_name[];