From 41566e68c10852865ecf480a76878f5d275814a3 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Thu, 26 Jul 2018 22:42:21 -0700 Subject: [PATCH] start implementing extensions --- GUI/GUI.pro | 9 ++++---- GUI/extensions.cpp | 32 +++++++++++++++++++++++++++ GUI/extensions.h | 15 +++++++++++++ GUI/hostsignaller.cpp | 3 ++- GUI/mainwindow.cpp | 50 +++++++++++++++++++++++++++++++++++++++---- GUI/mainwindow.h | 13 ++++++----- GUI/mainwindow.ui | 7 ++++-- GUI/misc.cpp | 15 +++++++++---- GUI/misc.h | 3 ++- 9 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 GUI/extensions.cpp create mode 100644 GUI/extensions.h diff --git a/GUI/GUI.pro b/GUI/GUI.pro index 24d7523..b06d853 100644 --- a/GUI/GUI.pro +++ b/GUI/GUI.pro @@ -26,12 +26,14 @@ SOURCES += \ main.cpp \ mainwindow.cpp \ hostsignaller.cpp \ - misc.cpp + misc.cpp \ + extensions.cpp HEADERS += \ mainwindow.h \ hostsignaller.h \ - misc.h + misc.h \ + extensions.h FORMS += \ mainwindow.ui @@ -39,9 +41,6 @@ FORMS += \ win32: LIBS += \ -L$$PWD/../Builds/Debug/Debug/ -lvnrhost -QMAKE_CXXFLAGS_RELEASE += \ - /MT - # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin diff --git a/GUI/extensions.cpp b/GUI/extensions.cpp new file mode 100644 index 0000000..0f96764 --- /dev/null +++ b/GUI/extensions.cpp @@ -0,0 +1,32 @@ +#include "extensions.h" +#include + +std::map extensions; + +std::map LoadExtensions() +{ + std::map extensionNames; + wchar_t path[MAX_PATH]; + wchar_t* end = path + GetModuleFileNameW(nullptr, path, MAX_PATH); + while (*(--end) != L'\\'); + *(end + 1) = L'*'; + *(end + 2) = L'\0'; + WIN32_FIND_DATAW fileData; + HANDLE file = FindFirstFileW(path, &fileData); + do + if (!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + if (wcsstr(fileData.cFileName, L"_nexthooker_extension.dll")) + if (GetProcAddress(LoadLibraryW(fileData.cFileName), "OnNewSentence")) + { + extensions[std::wcstol(fileData.cFileName, nullptr, 10)] = (ExtensionFunction)GetProcAddress(LoadLibraryW(fileData.cFileName), "OnNewSentence"); + extensionNames[std::wcstol(fileData.cFileName, nullptr, 10)] = fileData.cFileName; + } + while (FindNextFileW(file, &fileData) != 0); + return extensionNames; +} + +std::wstring DispatchSentenceToExtensions(std::wstring sentence, std::unordered_map miscInfo) +{ + for (auto extension : extensions) sentence = extension.second(sentence, miscInfo); + return sentence; +} diff --git a/GUI/extensions.h b/GUI/extensions.h new file mode 100644 index 0000000..df0ce6a --- /dev/null +++ b/GUI/extensions.h @@ -0,0 +1,15 @@ +#ifndef EXTENSIONS_H +#define EXTENSIONS_H + +#include +#include +#include +#include +#include + +std::map LoadExtensions(); +std::wstring DispatchSentenceToExtensions(std::wstring sentence, std::unordered_map miscInfo); + +typedef std::wstring(*ExtensionFunction)(std::wstring, std::unordered_map&); + +#endif // EXTENSIONS_H diff --git a/GUI/hostsignaller.cpp b/GUI/hostsignaller.cpp index 3bc7413..6d89421 100644 --- a/GUI/hostsignaller.cpp +++ b/GUI/hostsignaller.cpp @@ -1,4 +1,5 @@ #include "hostsignaller.h" +#include "extensions.h" void HostSignaller::Initialize() { @@ -9,7 +10,7 @@ void HostSignaller::Initialize() emit AddThread(thread); thread->RegisterOutputCallBack([&](TextThread* thread, std::wstring output) { - //output = DispatchToExtensions(output); + output = DispatchSentenceToExtensions(output, {}); emit ThreadOutput(thread, QString::fromWCharArray(output.c_str())); return output; }); diff --git a/GUI/mainwindow.cpp b/GUI/mainwindow.cpp index 7dc1912..b4799c3 100644 --- a/GUI/mainwindow.cpp +++ b/GUI/mainwindow.cpp @@ -8,16 +8,24 @@ #include "QInputDialog" #include #include +#include +#include +#include #include +#include +#include #include #include #include +#include "extensions.h" +#include "../vnrhook/include/const.h" #include "misc.h" QMainWindow* mainWindow; QComboBox* processCombo; QComboBox* ttCombo; -QTextBrowser* textOutput; +QComboBox* extenCombo; +QPlainTextEdit* textOutput; QString ProcessString(DWORD processId) { @@ -45,7 +53,8 @@ MainWindow::MainWindow(QWidget *parent) : mainWindow = this; processCombo = mainWindow->findChild("processCombo"); ttCombo = mainWindow->findChild("ttCombo"); - textOutput = mainWindow->findChild("textOutput"); + extenCombo = mainWindow->findChild("extenCombo"); + textOutput = mainWindow->findChild("textOutput"); hostSignaller->Initialize(); connect(hostSignaller, &HostSignaller::AddProcess, this, &MainWindow::AddProcess); @@ -53,6 +62,8 @@ MainWindow::MainWindow(QWidget *parent) : connect(hostSignaller, &HostSignaller::AddThread, this, &MainWindow::AddThread); connect(hostSignaller, &HostSignaller::RemoveThread, this, &MainWindow::RemoveThread); connect(hostSignaller, &HostSignaller::ThreadOutput, this, &MainWindow::ThreadOutput); + std::map extensions = LoadExtensions(); + for (auto i : extensions) extenCombo->addItem(QString::number(i.first) + ":" + QString::fromWCharArray(i.second.c_str())); Host::Open(); } @@ -64,6 +75,19 @@ MainWindow::~MainWindow() void MainWindow::AddProcess(unsigned int processId) { processCombo->addItem(ProcessString(processId)); + QFile file("SavedHooks.txt"); + if (!file.open(QIODevice::ReadOnly)) return; + QString processName = GetFullModuleName(processId); + QString allData = file.readAll(); + QStringList allProcesses = allData.split("\r", QString::SkipEmptyParts); + for (int i = allProcesses.length() - 1; i >= 0; --i) + if (allProcesses.at(i).contains(processName)) + { + Sleep(50); + QStringList hooks = allProcesses.at(i).split(" , "); + for (int j = 1; j < hooks.length(); ++j) Host::InsertHook(processId, ParseHCode(hooks.at(j))); + return; + } } void MainWindow::RemoveProcess(unsigned int processId) @@ -136,7 +160,7 @@ void MainWindow::on_hookButton_clicked() "Enter hook code\r\n/H{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:module]", QLineEdit::Normal, "/H", &ok ); - if (ok) Host::InsertHook(processCombo->currentText().split(":")[0].toInt(), ParseHCode(hookCode, processCombo->currentText().split(":")[0].toInt())); + if (ok) Host::InsertHook(processCombo->currentText().split(":")[0].toInt(), ParseHCode(hookCode)); } void MainWindow::on_unhookButton_clicked() @@ -153,8 +177,26 @@ void MainWindow::on_unhookButton_clicked() if (ok) Host::RemoveHook(processCombo->currentText().split(":")[0].toInt(), hooks.at(hookList.indexOf(hook)).address); } +void MainWindow::on_saveButton_clicked() +{ + QVector hooks = GetAllHooks(processCombo->currentText().split(":")[0].toInt()); + QString hookList = GetFullModuleName(processCombo->currentText().split(":")[0].toInt());; + for (auto i : hooks) + if (!(i.type & HOOK_ENGINE)) + hookList += " , " + GenerateHCode(i, processCombo->currentText().split(":")[0].toInt()); + QFile file("SavedHooks.txt"); + if (!file.open(QIODevice::Append | QIODevice::Text)) return; + file.write((hookList + "\r\n").toUtf8()); +} + void MainWindow::on_ttCombo_activated(int index) { - textOutput->setText(QString::fromWCharArray(Host::GetThread(ttCombo->itemText(index).split(":")[0].toInt())->GetStore().c_str())); + textOutput->setPlainText(QString::fromWCharArray(Host::GetThread(ttCombo->itemText(index).split(":")[0].toInt())->GetStore().c_str())); textOutput->moveCursor(QTextCursor::End); } + +void MainWindow::on_addExtenButton_clicked() +{ + QFileDialog extenSelector; + +} diff --git a/GUI/mainwindow.h b/GUI/mainwindow.h index ccecda6..9743bb9 100644 --- a/GUI/mainwindow.h +++ b/GUI/mainwindow.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "../texthook/host.h" #include "hostsignaller.h" @@ -21,17 +23,18 @@ public: ~MainWindow(); private slots: - void on_attachButton_clicked(); - void on_detachButton_clicked(); - void on_ttCombo_activated(int index); - void on_unhookButton_clicked(); void AddProcess(unsigned int processId); void RemoveProcess(unsigned int processId); void AddThread(TextThread* thread); void RemoveThread(TextThread* thread); void ThreadOutput(TextThread* thread, QString output); - + void on_attachButton_clicked(); + void on_detachButton_clicked(); + void on_ttCombo_activated(int index); + void on_unhookButton_clicked(); void on_hookButton_clicked(); + void on_saveButton_clicked(); + void on_addExtenButton_clicked(); private: QVector GetAllHooks(DWORD processId); diff --git a/GUI/mainwindow.ui b/GUI/mainwindow.ui index 53df71d..7b6955e 100644 --- a/GUI/mainwindow.ui +++ b/GUI/mainwindow.ui @@ -241,7 +241,7 @@ - + 5 @@ -253,6 +253,9 @@ 12 + + true + @@ -266,7 +269,7 @@ 0 0 949 - 21 + 20 diff --git a/GUI/misc.cpp b/GUI/misc.cpp index 1c6cc0e..9e96e31 100644 --- a/GUI/misc.cpp +++ b/GUI/misc.cpp @@ -3,23 +3,30 @@ #include #include -QString GetModuleName(DWORD processId, HMODULE module) +QString GetFullModuleName(DWORD processId, HMODULE module) { HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); wchar_t buffer[MAX_PATH]; GetModuleFileNameExW(handle, module, buffer, MAX_PATH); CloseHandle(handle); - return QString::fromWCharArray(wcsrchr(buffer, L'\\') + 1); + return QString::fromWCharArray(buffer); +} + +QString GetModuleName(DWORD processId, HMODULE module) +{ + QString fullName = GetFullModuleName(processId, module); + return fullName.remove(0, fullName.lastIndexOf("\\") + 1); } DWORD Hash(QString module) { + module = module.toLower(); DWORD hash = 0; for (auto i : module) hash = _rotr(hash, 7) + i.unicode(); return hash; } -HookParam ParseHCode(QString HCode, DWORD processId) +HookParam ParseHCode(QString HCode) { HookParam hp = {}; HCode = HCode.toUpper(); @@ -87,7 +94,7 @@ HookParam ParseHCode(QString HCode, DWORD processId) if (HCode.length()) { hp.type |= MODULE_OFFSET; - hp.module = Hash(HCode.toLower()); + hp.module = Hash(HCode); } if (hp.offset & 0x80000000) hp.offset -= 4; diff --git a/GUI/misc.h b/GUI/misc.h index 96e1938..802b50f 100644 --- a/GUI/misc.h +++ b/GUI/misc.h @@ -5,8 +5,9 @@ #include #include "../texthook/host.h" +QString GetFullModuleName(DWORD processId, HMODULE module = NULL); QString GetModuleName(DWORD processId, HMODULE module = NULL); -HookParam ParseHCode(QString HCode, DWORD processId); +HookParam ParseHCode(QString HCode); QString GenerateHCode(HookParam hp, DWORD processId); #endif // MISC_H