start implementing extensions
This commit is contained in:
parent
f3c4884660
commit
41566e68c1
@ -26,12 +26,14 @@ SOURCES += \
|
|||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
hostsignaller.cpp \
|
hostsignaller.cpp \
|
||||||
misc.cpp
|
misc.cpp \
|
||||||
|
extensions.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
hostsignaller.h \
|
hostsignaller.h \
|
||||||
misc.h
|
misc.h \
|
||||||
|
extensions.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
@ -39,9 +41,6 @@ FORMS += \
|
|||||||
win32: LIBS += \
|
win32: LIBS += \
|
||||||
-L$$PWD/../Builds/Debug/Debug/ -lvnrhost
|
-L$$PWD/../Builds/Debug/Debug/ -lvnrhost
|
||||||
|
|
||||||
QMAKE_CXXFLAGS_RELEASE += \
|
|
||||||
/MT
|
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
qnx: target.path = /tmp/$${TARGET}/bin
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
32
GUI/extensions.cpp
Normal file
32
GUI/extensions.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "extensions.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
std::map<int, ExtensionFunction> extensions;
|
||||||
|
|
||||||
|
std::map<int, std::wstring> LoadExtensions()
|
||||||
|
{
|
||||||
|
std::map<int, std::wstring> 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<std::string, int> miscInfo)
|
||||||
|
{
|
||||||
|
for (auto extension : extensions) sentence = extension.second(sentence, miscInfo);
|
||||||
|
return sentence;
|
||||||
|
}
|
15
GUI/extensions.h
Normal file
15
GUI/extensions.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef EXTENSIONS_H
|
||||||
|
#define EXTENSIONS_H
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
std::map<int, std::wstring> LoadExtensions();
|
||||||
|
std::wstring DispatchSentenceToExtensions(std::wstring sentence, std::unordered_map<std::string, int> miscInfo);
|
||||||
|
|
||||||
|
typedef std::wstring(*ExtensionFunction)(std::wstring, std::unordered_map<std::string, int>&);
|
||||||
|
|
||||||
|
#endif // EXTENSIONS_H
|
@ -1,4 +1,5 @@
|
|||||||
#include "hostsignaller.h"
|
#include "hostsignaller.h"
|
||||||
|
#include "extensions.h"
|
||||||
|
|
||||||
void HostSignaller::Initialize()
|
void HostSignaller::Initialize()
|
||||||
{
|
{
|
||||||
@ -9,7 +10,7 @@ void HostSignaller::Initialize()
|
|||||||
emit AddThread(thread);
|
emit AddThread(thread);
|
||||||
thread->RegisterOutputCallBack([&](TextThread* thread, std::wstring output)
|
thread->RegisterOutputCallBack([&](TextThread* thread, std::wstring output)
|
||||||
{
|
{
|
||||||
//output = DispatchToExtensions(output);
|
output = DispatchSentenceToExtensions(output, {});
|
||||||
emit ThreadOutput(thread, QString::fromWCharArray(output.c_str()));
|
emit ThreadOutput(thread, QString::fromWCharArray(output.c_str()));
|
||||||
return output;
|
return output;
|
||||||
});
|
});
|
||||||
|
@ -8,16 +8,24 @@
|
|||||||
#include "QInputDialog"
|
#include "QInputDialog"
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
#include <Qt>
|
#include <Qt>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QFileDialog>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <Psapi.h>
|
#include <Psapi.h>
|
||||||
|
#include "extensions.h"
|
||||||
|
#include "../vnrhook/include/const.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
QMainWindow* mainWindow;
|
QMainWindow* mainWindow;
|
||||||
QComboBox* processCombo;
|
QComboBox* processCombo;
|
||||||
QComboBox* ttCombo;
|
QComboBox* ttCombo;
|
||||||
QTextBrowser* textOutput;
|
QComboBox* extenCombo;
|
||||||
|
QPlainTextEdit* textOutput;
|
||||||
|
|
||||||
QString ProcessString(DWORD processId)
|
QString ProcessString(DWORD processId)
|
||||||
{
|
{
|
||||||
@ -45,7 +53,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
mainWindow = this;
|
mainWindow = this;
|
||||||
processCombo = mainWindow->findChild<QComboBox*>("processCombo");
|
processCombo = mainWindow->findChild<QComboBox*>("processCombo");
|
||||||
ttCombo = mainWindow->findChild<QComboBox*>("ttCombo");
|
ttCombo = mainWindow->findChild<QComboBox*>("ttCombo");
|
||||||
textOutput = mainWindow->findChild<QTextBrowser*>("textOutput");
|
extenCombo = mainWindow->findChild<QComboBox*>("extenCombo");
|
||||||
|
textOutput = mainWindow->findChild<QPlainTextEdit*>("textOutput");
|
||||||
|
|
||||||
hostSignaller->Initialize();
|
hostSignaller->Initialize();
|
||||||
connect(hostSignaller, &HostSignaller::AddProcess, this, &MainWindow::AddProcess);
|
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::AddThread, this, &MainWindow::AddThread);
|
||||||
connect(hostSignaller, &HostSignaller::RemoveThread, this, &MainWindow::RemoveThread);
|
connect(hostSignaller, &HostSignaller::RemoveThread, this, &MainWindow::RemoveThread);
|
||||||
connect(hostSignaller, &HostSignaller::ThreadOutput, this, &MainWindow::ThreadOutput);
|
connect(hostSignaller, &HostSignaller::ThreadOutput, this, &MainWindow::ThreadOutput);
|
||||||
|
std::map<int, std::wstring> extensions = LoadExtensions();
|
||||||
|
for (auto i : extensions) extenCombo->addItem(QString::number(i.first) + ":" + QString::fromWCharArray(i.second.c_str()));
|
||||||
Host::Open();
|
Host::Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +75,19 @@ MainWindow::~MainWindow()
|
|||||||
void MainWindow::AddProcess(unsigned int processId)
|
void MainWindow::AddProcess(unsigned int processId)
|
||||||
{
|
{
|
||||||
processCombo->addItem(ProcessString(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)
|
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]",
|
"Enter hook code\r\n/H{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:module]",
|
||||||
QLineEdit::Normal, "/H", &ok
|
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()
|
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);
|
if (ok) Host::RemoveHook(processCombo->currentText().split(":")[0].toInt(), hooks.at(hookList.indexOf(hook)).address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_saveButton_clicked()
|
||||||
|
{
|
||||||
|
QVector<HookParam> 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)
|
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);
|
textOutput->moveCursor(QTextCursor::End);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_addExtenButton_clicked()
|
||||||
|
{
|
||||||
|
QFileDialog extenSelector;
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
#include "../texthook/host.h"
|
#include "../texthook/host.h"
|
||||||
#include "hostsignaller.h"
|
#include "hostsignaller.h"
|
||||||
|
|
||||||
@ -21,17 +23,18 @@ public:
|
|||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
private slots:
|
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 AddProcess(unsigned int processId);
|
||||||
void RemoveProcess(unsigned int processId);
|
void RemoveProcess(unsigned int processId);
|
||||||
void AddThread(TextThread* thread);
|
void AddThread(TextThread* thread);
|
||||||
void RemoveThread(TextThread* thread);
|
void RemoveThread(TextThread* thread);
|
||||||
void ThreadOutput(TextThread* thread, QString output);
|
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_hookButton_clicked();
|
||||||
|
void on_saveButton_clicked();
|
||||||
|
void on_addExtenButton_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<HookParam> GetAllHooks(DWORD processId);
|
QVector<HookParam> GetAllHooks(DWORD processId);
|
||||||
|
@ -241,7 +241,7 @@
|
|||||||
<widget class="QComboBox" name="ttCombo"/>
|
<widget class="QComboBox" name="ttCombo"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTextBrowser" name="textOutput">
|
<widget class="QPlainTextEdit" name="textOutput">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<horstretch>5</horstretch>
|
<horstretch>5</horstretch>
|
||||||
@ -253,6 +253,9 @@
|
|||||||
<pointsize>12</pointsize>
|
<pointsize>12</pointsize>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -266,7 +269,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>949</width>
|
<width>949</width>
|
||||||
<height>21</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuOptions">
|
<widget class="QMenu" name="menuOptions">
|
||||||
|
15
GUI/misc.cpp
15
GUI/misc.cpp
@ -3,23 +3,30 @@
|
|||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <Psapi.h>
|
#include <Psapi.h>
|
||||||
|
|
||||||
QString GetModuleName(DWORD processId, HMODULE module)
|
QString GetFullModuleName(DWORD processId, HMODULE module)
|
||||||
{
|
{
|
||||||
HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
|
HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
|
||||||
wchar_t buffer[MAX_PATH];
|
wchar_t buffer[MAX_PATH];
|
||||||
GetModuleFileNameExW(handle, module, buffer, MAX_PATH);
|
GetModuleFileNameExW(handle, module, buffer, MAX_PATH);
|
||||||
CloseHandle(handle);
|
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)
|
DWORD Hash(QString module)
|
||||||
{
|
{
|
||||||
|
module = module.toLower();
|
||||||
DWORD hash = 0;
|
DWORD hash = 0;
|
||||||
for (auto i : module) hash = _rotr(hash, 7) + i.unicode();
|
for (auto i : module) hash = _rotr(hash, 7) + i.unicode();
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
HookParam ParseHCode(QString HCode, DWORD processId)
|
HookParam ParseHCode(QString HCode)
|
||||||
{
|
{
|
||||||
HookParam hp = {};
|
HookParam hp = {};
|
||||||
HCode = HCode.toUpper();
|
HCode = HCode.toUpper();
|
||||||
@ -87,7 +94,7 @@ HookParam ParseHCode(QString HCode, DWORD processId)
|
|||||||
if (HCode.length())
|
if (HCode.length())
|
||||||
{
|
{
|
||||||
hp.type |= MODULE_OFFSET;
|
hp.type |= MODULE_OFFSET;
|
||||||
hp.module = Hash(HCode.toLower());
|
hp.module = Hash(HCode);
|
||||||
}
|
}
|
||||||
if (hp.offset & 0x80000000)
|
if (hp.offset & 0x80000000)
|
||||||
hp.offset -= 4;
|
hp.offset -= 4;
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include "../texthook/host.h"
|
#include "../texthook/host.h"
|
||||||
|
|
||||||
|
QString GetFullModuleName(DWORD processId, HMODULE module = NULL);
|
||||||
QString GetModuleName(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);
|
QString GenerateHCode(HookParam hp, DWORD processId);
|
||||||
|
|
||||||
#endif // MISC_H
|
#endif // MISC_H
|
||||||
|
Loading…
Reference in New Issue
Block a user