From 3c7b3d728cbbe367a4ea5e1bbced3e3023d9cc15 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Sat, 16 Feb 2019 00:33:38 -0500 Subject: [PATCH] remove some other race conditions --- GUI/host/host.cpp | 56 ++++++++++++++++++++++------------------------- GUI/host/host.h | 2 +- GUI/host/util.cpp | 3 +-- GUI/host/util.h | 2 +- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/GUI/host/host.cpp b/GUI/host/host.cpp index 1eeb34a..44dad6b 100644 --- a/GUI/host/host.cpp +++ b/GUI/host/host.cpp @@ -148,53 +148,49 @@ namespace Host CreatePipe(); + static AutoHandle<> clipboardUpdate = CreateEventW(nullptr, FALSE, TRUE, NULL); SetWindowsHookExW(WH_GETMESSAGE, [](int statusCode, WPARAM wParam, LPARAM lParam) { - if (statusCode == HC_ACTION && wParam == PM_REMOVE && ((MSG*)lParam)->message == WM_CLIPBOARDUPDATE) - if (auto text = Util::GetClipboardText()) GetThread(clipboard).AddSentence(std::move(text.value())); + if (statusCode == HC_ACTION && wParam == PM_REMOVE && ((MSG*)lParam)->message == WM_CLIPBOARDUPDATE) SetEvent(clipboardUpdate); return CallNextHookEx(NULL, statusCode, wParam, lParam); }, NULL, GetCurrentThreadId()); + std::thread([] + { + while (WaitForSingleObject(clipboardUpdate, INFINITE) == WAIT_OBJECT_0) + if (auto text = Util::GetClipboardText()) GetThread(clipboard).AddSentence(std::move(text.value())); + throw; + }).detach(); } - bool InjectProcess(DWORD processId, DWORD timeout) + void InjectProcess(DWORD processId) { - if (processId == GetCurrentProcessId()) return false; - - WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId)); - if (GetLastError() == ERROR_ALREADY_EXISTS) + std::thread([processId] { - AddConsoleOutput(ALREADY_INJECTED); - return false; - } + if (processId == GetCurrentProcessId()) return; - static std::wstring location = Util::GetModuleFilename(LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES)).value(); + WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId)); + if (GetLastError() == ERROR_ALREADY_EXISTS) return AddConsoleOutput(ALREADY_INJECTED); - if (AutoHandle<> process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId)) - { + static std::wstring location = Util::GetModuleFilename(LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES)).value(); + + if (AutoHandle<> process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId)) + { #ifdef _WIN64 - BOOL invalidProcess = FALSE; - IsWow64Process(process, &invalidProcess); - if (invalidProcess) - { - AddConsoleOutput(ARCHITECTURE_MISMATCH); - return false; - } + BOOL invalidProcess = FALSE; + IsWow64Process(process, &invalidProcess); + if (invalidProcess) return AddConsoleOutput(ARCHITECTURE_MISMATCH); #endif - if (LPVOID remoteData = VirtualAllocEx(process, nullptr, (location.size() + 1) * sizeof(wchar_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) - { - WriteProcessMemory(process, remoteData, location.c_str(), (location.size() + 1) * sizeof(wchar_t), nullptr); - if (AutoHandle<> thread = CreateRemoteThread(process, nullptr, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, remoteData, 0, nullptr)) + if (LPVOID remoteData = VirtualAllocEx(process, nullptr, (location.size() + 1) * sizeof(wchar_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) { - WaitForSingleObject(thread, timeout); + WriteProcessMemory(process, remoteData, location.c_str(), (location.size() + 1) * sizeof(wchar_t), nullptr); + if (AutoHandle<> thread = CreateRemoteThread(process, nullptr, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, remoteData, 0, nullptr)) WaitForSingleObject(thread, INFINITE); VirtualFreeEx(process, remoteData, 0, MEM_RELEASE); - return true; + return; } - VirtualFreeEx(process, remoteData, 0, MEM_RELEASE); } - } - AddConsoleOutput(INJECT_FAILED); - return false; + AddConsoleOutput(INJECT_FAILED); + }).detach(); } void DetachProcess(DWORD processId) diff --git a/GUI/host/host.h b/GUI/host/host.h index e9b58c2..6c990b6 100644 --- a/GUI/host/host.h +++ b/GUI/host/host.h @@ -9,7 +9,7 @@ namespace Host using ThreadEventHandler = std::function; void Start(ProcessEventHandler Connect, ProcessEventHandler Disconnect, ThreadEventHandler Create, ThreadEventHandler Destroy, TextThread::OutputCallback Output); - bool InjectProcess(DWORD processId, DWORD timeout = 5000); + void InjectProcess(DWORD processId); void DetachProcess(DWORD processId); void InsertHook(DWORD processId, HookParam hp); diff --git a/GUI/host/util.cpp b/GUI/host/util.cpp index 330ca61..69dec83 100644 --- a/GUI/host/util.cpp +++ b/GUI/host/util.cpp @@ -267,7 +267,6 @@ namespace Util std::optional GetClipboardText() { - Sleep(10); // for some reason this function sometimes fails if I don't wait a little if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) return {}; if (!OpenClipboard(NULL)) return {}; @@ -277,7 +276,7 @@ namespace Util return text; } - std::optional StringToWideString(std::string text, UINT encoding) + std::optional StringToWideString(const std::string& text, UINT encoding) { std::vector buffer(text.size() + 1); if (MultiByteToWideChar(encoding, 0, text.c_str(), -1, buffer.data(), buffer.size())) return buffer.data(); diff --git a/GUI/host/util.h b/GUI/host/util.h index 5133339..b4ef1e2 100644 --- a/GUI/host/util.h +++ b/GUI/host/util.h @@ -8,7 +8,7 @@ namespace Util std::optional GetModuleFilename(DWORD processId, HMODULE module = NULL); std::optional GetModuleFilename(HMODULE module = NULL); std::optional GetClipboardText(); - std::optional StringToWideString(std::string text, UINT encoding = CP_UTF8); + std::optional StringToWideString(const std::string& text, UINT encoding = CP_UTF8); // return true if repetition found (see https://github.com/Artikash/Textractor/issues/40) bool RemoveRepetition(std::wstring& text); std::optional ParseCode(std::wstring code);