forked from Public-Mirror/Textractor
remove some other race conditions
This commit is contained in:
parent
c7ff5f637a
commit
3c7b3d728c
@ -148,53 +148,49 @@ 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]
|
||||||
|
|
||||||
WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId));
|
|
||||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
|
||||||
{
|
{
|
||||||
AddConsoleOutput(ALREADY_INJECTED);
|
if (processId == GetCurrentProcessId()) return;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
#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);
|
|
||||||
if (AutoHandle<> thread = CreateRemoteThread(process, nullptr, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, remoteData, 0, nullptr))
|
|
||||||
{
|
{
|
||||||
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);
|
VirtualFreeEx(process, remoteData, 0, MEM_RELEASE);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
VirtualFreeEx(process, remoteData, 0, MEM_RELEASE);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
AddConsoleOutput(INJECT_FAILED);
|
AddConsoleOutput(INJECT_FAILED);
|
||||||
return false;
|
}).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetachProcess(DWORD processId)
|
void DetachProcess(DWORD processId)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user