remove some other race conditions

This commit is contained in:
Akash Mozumdar 2019-02-16 00:33:38 -05:00
parent c7ff5f637a
commit 3c7b3d728c
4 changed files with 29 additions and 34 deletions

View File

@ -148,24 +148,28 @@ namespace Host
CreatePipe(); CreatePipe();
static AutoHandle<> clipboardUpdate = CreateEventW(nullptr, FALSE, TRUE, NULL);
SetWindowsHookExW(WH_GETMESSAGE, [](int statusCode, WPARAM wParam, LPARAM lParam) SetWindowsHookExW(WH_GETMESSAGE, [](int statusCode, WPARAM wParam, LPARAM lParam)
{ {
if (statusCode == HC_ACTION && wParam == PM_REMOVE && ((MSG*)lParam)->message == WM_CLIPBOARDUPDATE) if (statusCode == HC_ACTION && wParam == PM_REMOVE && ((MSG*)lParam)->message == WM_CLIPBOARDUPDATE) SetEvent(clipboardUpdate);
if (auto text = Util::GetClipboardText()) GetThread(clipboard).AddSentence(std::move(text.value()));
return CallNextHookEx(NULL, statusCode, wParam, lParam); return CallNextHookEx(NULL, statusCode, wParam, lParam);
}, NULL, GetCurrentThreadId()); }, 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; std::thread([processId]
{
if (processId == GetCurrentProcessId()) return;
WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId)); WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId));
if (GetLastError() == ERROR_ALREADY_EXISTS) if (GetLastError() == ERROR_ALREADY_EXISTS) return AddConsoleOutput(ALREADY_INJECTED);
{
AddConsoleOutput(ALREADY_INJECTED);
return false;
}
static std::wstring location = Util::GetModuleFilename(LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES)).value(); static std::wstring location = Util::GetModuleFilename(LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES)).value();
@ -174,27 +178,19 @@ namespace Host
#ifdef _WIN64 #ifdef _WIN64
BOOL invalidProcess = FALSE; BOOL invalidProcess = FALSE;
IsWow64Process(process, &invalidProcess); IsWow64Process(process, &invalidProcess);
if (invalidProcess) if (invalidProcess) return AddConsoleOutput(ARCHITECTURE_MISMATCH);
{
AddConsoleOutput(ARCHITECTURE_MISMATCH);
return false;
}
#endif #endif
if (LPVOID remoteData = VirtualAllocEx(process, nullptr, (location.size() + 1) * sizeof(wchar_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) 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); 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 (AutoHandle<> thread = CreateRemoteThread(process, nullptr, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, remoteData, 0, nullptr)) WaitForSingleObject(thread, INFINITE);
{
WaitForSingleObject(thread, timeout);
VirtualFreeEx(process, remoteData, 0, MEM_RELEASE);
return true;
}
VirtualFreeEx(process, remoteData, 0, MEM_RELEASE); VirtualFreeEx(process, remoteData, 0, MEM_RELEASE);
return;
} }
} }
AddConsoleOutput(INJECT_FAILED); AddConsoleOutput(INJECT_FAILED);
return false; }).detach();
} }
void DetachProcess(DWORD processId) void DetachProcess(DWORD processId)

View File

@ -9,7 +9,7 @@ namespace Host
using ThreadEventHandler = std::function<void(TextThread&)>; using ThreadEventHandler = std::function<void(TextThread&)>;
void Start(ProcessEventHandler Connect, ProcessEventHandler Disconnect, ThreadEventHandler Create, ThreadEventHandler Destroy, TextThread::OutputCallback Output); 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 DetachProcess(DWORD processId);
void InsertHook(DWORD processId, HookParam hp); void InsertHook(DWORD processId, HookParam hp);

View File

@ -267,7 +267,6 @@ namespace Util
std::optional<std::wstring> GetClipboardText() std::optional<std::wstring> GetClipboardText()
{ {
Sleep(10); // for some reason this function sometimes fails if I don't wait a little
if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) return {}; if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) return {};
if (!OpenClipboard(NULL)) return {}; if (!OpenClipboard(NULL)) return {};
@ -277,7 +276,7 @@ namespace Util
return text; return text;
} }
std::optional<std::wstring> StringToWideString(std::string text, UINT encoding) std::optional<std::wstring> StringToWideString(const std::string& text, UINT encoding)
{ {
std::vector<wchar_t> buffer(text.size() + 1); std::vector<wchar_t> buffer(text.size() + 1);
if (MultiByteToWideChar(encoding, 0, text.c_str(), -1, buffer.data(), buffer.size())) return buffer.data(); if (MultiByteToWideChar(encoding, 0, text.c_str(), -1, buffer.data(), buffer.size())) return buffer.data();

View File

@ -8,7 +8,7 @@ namespace Util
std::optional<std::wstring> GetModuleFilename(DWORD processId, HMODULE module = NULL); std::optional<std::wstring> GetModuleFilename(DWORD processId, HMODULE module = NULL);
std::optional<std::wstring> GetModuleFilename(HMODULE module = NULL); std::optional<std::wstring> GetModuleFilename(HMODULE module = NULL);
std::optional<std::wstring> GetClipboardText(); std::optional<std::wstring> GetClipboardText();
std::optional<std::wstring> StringToWideString(std::string text, UINT encoding = CP_UTF8); std::optional<std::wstring> StringToWideString(const std::string& text, UINT encoding = CP_UTF8);
// return true if repetition found (see https://github.com/Artikash/Textractor/issues/40) // return true if repetition found (see https://github.com/Artikash/Textractor/issues/40)
bool RemoveRepetition(std::wstring& text); bool RemoveRepetition(std::wstring& text);
std::optional<HookParam> ParseCode(std::wstring code); std::optional<HookParam> ParseCode(std::wstring code);