start implementing extensions

This commit is contained in:
Akash Mozumdar 2018-07-26 22:42:21 -07:00
parent f3c4884660
commit 41566e68c1
9 changed files with 125 additions and 22 deletions

View File

@ -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
View 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
View 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

View File

@ -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;
}); });

View File

@ -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;
}

View File

@ -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);

View File

@ -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">

View File

@ -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;

View File

@ -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