diff --git a/GUI/host/host.cc b/GUI/host/host.cc index a24e1f1..27da486 100644 --- a/GUI/host/host.cc +++ b/GUI/host/host.cc @@ -89,7 +89,7 @@ namespace OnDetach(processId); LOCK(hostMutex); processRecordsByIds.erase(processId); - RemoveThreads([&](ThreadParam tp) { return tp.pid == processId; }); + RemoveThreads([&](ThreadParam tp) { return tp.processId == processId; }); } void CreatePipe() @@ -117,7 +117,7 @@ namespace case HOST_NOTIFICATION_RMVHOOK: { auto info = *(HookRemovedNotif*)buffer; - RemoveThreads([&](ThreadParam tp) { return tp.pid == processId && tp.hook == info.address; }); + RemoveThreads([&](ThreadParam tp) { return tp.processId == processId && tp.addr == info.address; }); } break; case HOST_NOTIFICATION_TEXT: @@ -175,7 +175,7 @@ namespace Host void Start(ProcessEventCallback onAttach, ProcessEventCallback onDetach, ThreadEventCallback onCreate, ThreadEventCallback onDestroy, TextThread::OutputCallback output) { OnAttach = onAttach; OnDetach = onDetach; OnCreate = onCreate; OnDestroy = onDestroy; TextThread::Output = output; - RegisterProcess(CONSOLE.pid, INVALID_HANDLE_VALUE); + RegisterProcess(CONSOLE.processId, INVALID_HANDLE_VALUE); OnCreate(textThreadsByParams[CONSOLE] = std::make_shared(CONSOLE, HookParam{}, L"Console")); OnCreate(textThreadsByParams[CLIPBOARD] = std::make_shared(CLIPBOARD, HookParam{}, L"Clipboard")); StartCapturingClipboard(); diff --git a/GUI/host/host.h b/GUI/host/host.h index 5a4cd5b..27dd65d 100644 --- a/GUI/host/host.h +++ b/GUI/host/host.h @@ -22,9 +22,9 @@ namespace Host void RemoveHook(DWORD processId, uint64_t addr); HookParam GetHookParam(DWORD processId, uint64_t addr); - inline HookParam GetHookParam(ThreadParam tp) { return GetHookParam(tp.pid, tp.hook); } + inline HookParam GetHookParam(ThreadParam tp) { return GetHookParam(tp.processId, tp.addr); } std::wstring GetHookName(DWORD processId, uint64_t addr); - inline std::wstring GetHookName(ThreadParam tp) { return GetHookName(tp.pid, tp.hook); } + inline std::wstring GetHookName(ThreadParam tp) { return GetHookName(tp.processId, tp.addr); } std::shared_ptr GetThread(ThreadParam tp); void AddConsoleOutput(std::wstring text); diff --git a/GUI/mainwindow.cpp b/GUI/mainwindow.cpp index 7fc777d..129f10c 100644 --- a/GUI/mainwindow.cpp +++ b/GUI/mainwindow.cpp @@ -59,6 +59,7 @@ void MainWindow::closeEvent(QCloseEvent*) void MainWindow::AddProcess(unsigned processId) { + if (processId == 0) return; processCombo->addItem(QString::number(processId, 16).toUpper() + ": " + GetModuleName(processId)); QFile file(HOOK_SAVE_FILE); file.open(QIODevice::ReadOnly); @@ -84,7 +85,7 @@ void MainWindow::AddThread(std::shared_ptr thread) TextThreadString(thread.get()) + QString::fromStdWString(thread->name) + " (" + - GenerateCode(thread->hp, thread->tp.pid) + + GenerateCode(thread->hp, thread->tp.processId) + ")" ); } @@ -126,10 +127,10 @@ QString MainWindow::TextThreadString(TextThread* thread) ThreadParam tp = thread->tp; return QString("%1:%2:%3:%4:%5: ").arg( QString::number(thread->handle, 16), - QString::number(tp.pid, 16), - QString::number(tp.hook, 16), - QString::number(tp.retn, 16), - QString::number(tp.spl, 16) + QString::number(tp.processId, 16), + QString::number(tp.addr, 16), + QString::number(tp.ctx, 16), + QString::number(tp.ctx2, 16) ).toUpper(); } @@ -150,8 +151,8 @@ std::unordered_map MainWindow::GetMiscInfo(TextThread* thr { { "current select", ttCombo->currentText().startsWith(TextThreadString(thread)) }, { "text number", thread->handle }, - { "process id", thread->tp.pid }, - { "hook address", thread->tp.hook }, + { "process id", thread->tp.processId }, + { "hook address", thread->tp.addr }, { "text handle", thread->handle }, { "text name", (int64_t)thread->name.c_str() } }; @@ -164,9 +165,9 @@ QVector MainWindow::GetAllHooks(DWORD processId) for (int i = 0; i < ttCombo->count(); ++i) { ThreadParam tp = ParseTextThreadString(ttCombo->itemText(i)); - if (tp.pid == processId && !addresses.contains(tp.hook)) + if (tp.processId == processId && !addresses.contains(tp.addr)) { - addresses.insert(tp.hook); + addresses.insert(tp.addr); hooks.push_back(Host::GetHookParam(tp)); } } @@ -204,11 +205,11 @@ void MainWindow::on_unhookButton_clicked() auto hooks = GetAllHooks(GetSelectedProcessId()); if (hooks.empty()) return Host::AddConsoleOutput(NO_HOOKS); QStringList hookList; - for (auto hook : hooks) + for (auto hp : hooks) hookList.push_back( - QString::fromStdWString(Host::GetHookName(GetSelectedProcessId(), hook.insertion_address)) + + QString::fromStdWString(Host::GetHookName(GetSelectedProcessId(), hp.insertion_address)) + ": " + - GenerateCode(hook, GetSelectedProcessId()) + GenerateCode(hp, GetSelectedProcessId()) ); bool ok; QString hook = QInputDialog::getItem(this, UNHOOK, REMOVE_HOOK, hookList, 0, false, &ok, Qt::WindowCloseButtonHint); @@ -219,9 +220,9 @@ void MainWindow::on_saveButton_clicked() { auto hooks = GetAllHooks(GetSelectedProcessId()); QString hookList = GetFullModuleName(GetSelectedProcessId()); - for (auto hook : hooks) - if (!(hook.type & HOOK_ENGINE)) - hookList += " , " + GenerateCode(hook, GetSelectedProcessId()); + for (auto hp : hooks) + if (!(hp.type & HOOK_ENGINE)) + hookList += " , " + GenerateCode(hp, GetSelectedProcessId()); QFile file(HOOK_SAVE_FILE); file.open(QIODevice::Append); file.write((hookList + "\r\n").toUtf8()); diff --git a/include/types.h b/include/types.h index 2f36375..c9a7c7b 100644 --- a/include/types.h +++ b/include/types.h @@ -29,16 +29,16 @@ struct HookParam hook_fun_t hook_fun; }; -struct ThreadParam // From hook, used internally by host as well +struct ThreadParam { - DWORD pid; // jichi: 5/11/2014: The process ID - uint64_t hook; // Artikash 6/6/2018: The insertion address of the hook - uint64_t retn; // jichi 5/11/2014: The return address of the hook - uint64_t spl; // jichi 5/11/2014: the processed split value of the hook paramete + DWORD processId; + uint64_t addr; + uint64_t ctx; // The context of the hook: by default the first value on stack, usually the return address + uint64_t ctx2; // The subcontext of the hook: 0 by default, generated in a method specific to the hook }; // Artikash 5/31/2018: required for unordered_map to work with struct key -template <> struct std::hash { size_t operator()(const ThreadParam& tp) const { return std::hash()((tp.pid + tp.hook) ^ (tp.retn + tp.spl)); } }; -static bool operator==(const ThreadParam& one, const ThreadParam& two) { return one.pid == two.pid && one.hook == two.hook && one.retn == two.retn && one.spl == two.spl; } +template <> struct std::hash { size_t operator()(const ThreadParam& tp) const { return std::hash()((tp.processId + tp.addr) ^ (tp.ctx + tp.ctx2)); } }; +static bool operator==(const ThreadParam& one, const ThreadParam& two) { return one.processId == two.processId && one.addr == two.addr && one.ctx == two.ctx && one.ctx2 == two.ctx2; } class WinMutex {