forked from Public-Mirror/Textractor
using raii for processrecords and qfileinfo for files and other refactors
This commit is contained in:
parent
0f903940bc
commit
5ef1ff6352
@ -105,12 +105,11 @@ void ExtenWindow::Sync()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtenWindow::Add(QString fileName)
|
void ExtenWindow::Add(QFileInfo extenFile)
|
||||||
{
|
{
|
||||||
if (!fileName.endsWith(".dll")) return;
|
if (extenFile.suffix() != "dll") return;
|
||||||
QString extenName = fileName.mid(fileName.lastIndexOf("/") + 1);
|
QFile::copy(extenFile.fileName(), extenFile.absoluteFilePath());
|
||||||
QFile::copy(fileName, extenName);
|
Load(extenFile.completeBaseName());
|
||||||
Load(extenName.split(".dll")[0]);
|
|
||||||
Sync();
|
Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ private slots:
|
|||||||
void on_rmvButton_clicked();
|
void on_rmvButton_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Add(QString fileName);
|
void Add(QFileInfo extenFile);
|
||||||
void Sync();
|
void Sync();
|
||||||
bool eventFilter(QObject* target, QEvent* event);
|
bool eventFilter(QObject* target, QEvent* event);
|
||||||
void dragEnterEvent(QDragEnterEvent* event);
|
void dragEnterEvent(QDragEnterEvent* event);
|
||||||
|
@ -15,9 +15,9 @@ namespace
|
|||||||
ProcessRecord(DWORD processId, HANDLE pipe) :
|
ProcessRecord(DWORD processId, HANDLE pipe) :
|
||||||
processId(processId),
|
processId(processId),
|
||||||
pipe(pipe),
|
pipe(pipe),
|
||||||
fileMapping(OpenFileMappingW(FILE_MAP_READ, FALSE, (ITH_SECTION_ + std::to_wstring(processId)).c_str())),
|
mappedFile(OpenFileMappingW(FILE_MAP_READ, FALSE, (ITH_SECTION_ + std::to_wstring(processId)).c_str())),
|
||||||
mappedView(MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, HOOK_SECTION_SIZE / 2)), // jichi 1/16/2015: Changed to half to hook section size
|
view(MapViewOfFile(mappedFile, FILE_MAP_READ, 0, 0, HOOK_SECTION_SIZE / 2)), // jichi 1/16/2015: Changed to half to hook section size
|
||||||
sectionMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId))
|
viewMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId))
|
||||||
{
|
{
|
||||||
OnConnect(processId);
|
OnConnect(processId);
|
||||||
}
|
}
|
||||||
@ -25,14 +25,14 @@ namespace
|
|||||||
~ProcessRecord()
|
~ProcessRecord()
|
||||||
{
|
{
|
||||||
OnDisconnect(processId);
|
OnDisconnect(processId);
|
||||||
UnmapViewOfFile(mappedView);
|
UnmapViewOfFile(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextHook GetHook(uint64_t addr)
|
TextHook GetHook(uint64_t addr)
|
||||||
{
|
{
|
||||||
if (mappedView == nullptr) return {};
|
if (view == nullptr) return {};
|
||||||
LOCK(sectionMutex);
|
LOCK(viewMutex);
|
||||||
auto hooks = (const TextHook*)mappedView;
|
auto hooks = (const TextHook*)view;
|
||||||
for (int i = 0; i < MAX_HOOK; ++i)
|
for (int i = 0; i < MAX_HOOK; ++i)
|
||||||
if (hooks[i].hp.insertion_address == addr) return hooks[i];
|
if (hooks[i].hp.insertion_address == addr) return hooks[i];
|
||||||
return {};
|
return {};
|
||||||
@ -41,16 +41,16 @@ namespace
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void Send(T data)
|
void Send(T data)
|
||||||
{
|
{
|
||||||
DWORD DUMMY;
|
std::enable_if_t<sizeof(data) < PIPE_BUFFER_SIZE, DWORD> DUMMY;
|
||||||
WriteFile(pipe, &data, sizeof(data), &DUMMY, nullptr);
|
WriteFile(pipe, &data, sizeof(data), &DUMMY, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DWORD processId;
|
DWORD processId;
|
||||||
HANDLE pipe;
|
HANDLE pipe;
|
||||||
AutoHandle<> fileMapping;
|
AutoHandle<> mappedFile;
|
||||||
LPCVOID mappedView;
|
LPCVOID view;
|
||||||
WinMutex sectionMutex;
|
WinMutex viewMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
ThreadSafePtr<std::unordered_map<ThreadParam, std::shared_ptr<TextThread>>> textThreadsByParams;
|
ThreadSafePtr<std::unordered_map<ThreadParam, std::shared_ptr<TextThread>>> textThreadsByParams;
|
||||||
@ -60,8 +60,8 @@ namespace
|
|||||||
|
|
||||||
void RemoveThreads(std::function<bool(ThreadParam)> removeIf)
|
void RemoveThreads(std::function<bool(ThreadParam)> removeIf)
|
||||||
{
|
{
|
||||||
auto lockedTextThreadsByParams = textThreadsByParams.operator->();
|
auto[lock, textThreadsByParams] = ::textThreadsByParams.operator->();
|
||||||
for (auto it = lockedTextThreadsByParams->begin(); it != lockedTextThreadsByParams->end(); removeIf(it->first) ? it = lockedTextThreadsByParams->erase(it) : ++it);
|
for (auto it = textThreadsByParams->begin(); it != textThreadsByParams->end(); removeIf(it->first) ? it = textThreadsByParams->erase(it) : ++it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatePipe()
|
void CreatePipe()
|
||||||
@ -104,9 +104,9 @@ namespace
|
|||||||
auto tp = *(ThreadParam*)buffer;
|
auto tp = *(ThreadParam*)buffer;
|
||||||
if (textThreadsByParams->count(tp) == 0)
|
if (textThreadsByParams->count(tp) == 0)
|
||||||
{
|
{
|
||||||
auto textThread = textThreadsByParams->insert({ tp, std::make_shared<TextThread>(tp, Host::GetHookParam(tp), Host::GetHookName(tp)) }).first->second;
|
auto textThread = textThreadsByParams->insert({ tp, std::make_shared<TextThread>(tp, Host::GetHookParam(tp)) }).first->second;
|
||||||
if (textThreadsByParams->size() > MAX_THREAD_COUNT) Host::AddConsoleOutput(TOO_MANY_THREADS);
|
if (textThreadsByParams->size() < MAX_THREAD_COUNT) textThread->Start();
|
||||||
else textThread->Start();
|
else Host::AddConsoleOutput(TOO_MANY_THREADS);
|
||||||
}
|
}
|
||||||
textThreadsByParams->at(tp)->Push(buffer + sizeof(tp), bytesRead - sizeof(tp));
|
textThreadsByParams->at(tp)->Push(buffer + sizeof(tp), bytesRead - sizeof(tp));
|
||||||
}
|
}
|
||||||
@ -146,6 +146,16 @@ namespace Host
|
|||||||
CreatePipe();
|
CreatePipe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shutdown()
|
||||||
|
{
|
||||||
|
auto NOP = [](auto... args) { return NULL; };
|
||||||
|
ProcessRecord::OnConnect = NOP;
|
||||||
|
ProcessRecord::OnDisconnect = NOP;
|
||||||
|
TextThread::OnCreate = NOP;
|
||||||
|
TextThread::OnDestroy = NOP;
|
||||||
|
TextThread::Output = NOP;
|
||||||
|
}
|
||||||
|
|
||||||
bool InjectProcess(DWORD processId, DWORD timeout)
|
bool InjectProcess(DWORD processId, DWORD timeout)
|
||||||
{
|
{
|
||||||
if (processId == GetCurrentProcessId()) return false;
|
if (processId == GetCurrentProcessId()) return false;
|
||||||
@ -193,19 +203,14 @@ namespace Host
|
|||||||
processRecordsByIds->at(processId)->Send(HostCommandType(HOST_COMMAND_DETACH));
|
processRecordsByIds->at(processId)->Send(HostCommandType(HOST_COMMAND_DETACH));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertHook(DWORD processId, HookParam hp, std::string name)
|
void InsertHook(DWORD processId, HookParam hp)
|
||||||
{
|
{
|
||||||
processRecordsByIds->at(processId)->Send(InsertHookCmd(hp, name));
|
processRecordsByIds->at(processId)->Send(InsertHookCmd(hp));
|
||||||
}
|
}
|
||||||
|
|
||||||
HookParam GetHookParam(DWORD processId, uint64_t addr)
|
HookParam GetHookParam(ThreadParam tp)
|
||||||
{
|
{
|
||||||
return processRecordsByIds->at(processId)->GetHook(addr).hp;
|
return processRecordsByIds->at(tp.processId)->GetHook(tp.addr).hp;
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring GetHookName(DWORD processId, uint64_t addr)
|
|
||||||
{
|
|
||||||
return Util::StringToWideString(processRecordsByIds->at(processId)->GetHook(addr).hookName).value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TextThread> GetThread(ThreadParam tp)
|
std::shared_ptr<TextThread> GetThread(ThreadParam tp)
|
||||||
|
@ -5,17 +5,15 @@
|
|||||||
|
|
||||||
namespace Host
|
namespace Host
|
||||||
{
|
{
|
||||||
typedef std::function<void(DWORD)> ProcessEventCallback;
|
using ProcessEventCallback = std::function<void(DWORD)>;
|
||||||
void Start(ProcessEventCallback OnConnect, ProcessEventCallback OnDisconnect, TextThread::EventCallback OnCreate, TextThread::EventCallback OnDestroy, TextThread::OutputCallback Output);
|
void Start(ProcessEventCallback OnConnect, ProcessEventCallback OnDisconnect, TextThread::EventCallback OnCreate, TextThread::EventCallback OnDestroy, TextThread::OutputCallback Output);
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
bool InjectProcess(DWORD processId, DWORD timeout = 5000);
|
bool InjectProcess(DWORD processId, DWORD timeout = 5000);
|
||||||
void DetachProcess(DWORD processId);
|
void DetachProcess(DWORD processId);
|
||||||
void InsertHook(DWORD processId, HookParam hp, std::string name = "");
|
void InsertHook(DWORD processId, HookParam hp);
|
||||||
|
|
||||||
HookParam GetHookParam(DWORD processId, uint64_t addr);
|
HookParam GetHookParam(ThreadParam tp);
|
||||||
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.processId, tp.addr); }
|
|
||||||
|
|
||||||
std::shared_ptr<TextThread> GetThread(ThreadParam tp);
|
std::shared_ptr<TextThread> GetThread(ThreadParam tp);
|
||||||
void AddConsoleOutput(std::wstring text);
|
void AddConsoleOutput(std::wstring text);
|
||||||
|
@ -4,16 +4,23 @@
|
|||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
TextThread::TextThread(ThreadParam tp, HookParam hp, std::wstring name) : handle(threadCounter++), name(name), tp(tp), hp(hp)
|
TextThread::TextThread(ThreadParam tp, HookParam hp, std::optional<std::wstring> name) :
|
||||||
|
handle(threadCounter++),
|
||||||
|
name(name.value_or(Util::StringToWideString(hp.name).value())),
|
||||||
|
tp(tp),
|
||||||
|
hp(hp)
|
||||||
{
|
{
|
||||||
OnCreate(this);
|
OnCreate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextThread::~TextThread()
|
TextThread::~TextThread()
|
||||||
{
|
{
|
||||||
SetEvent(deletionEvent);
|
if (flushThread.joinable())
|
||||||
flushThread.join();
|
{
|
||||||
OnDestroy(this);
|
SetEvent(deletionEvent);
|
||||||
|
flushThread.join();
|
||||||
|
OnDestroy(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring TextThread::GetStorage()
|
std::wstring TextThread::GetStorage()
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
class TextThread
|
class TextThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<void(TextThread*)> EventCallback;
|
using EventCallback = std::function<void(TextThread*)>;
|
||||||
typedef std::function<bool(TextThread*, std::wstring&)> OutputCallback;
|
using OutputCallback = std::function<bool(TextThread*, std::wstring&)>;
|
||||||
inline static EventCallback OnCreate, OnDestroy;
|
inline static EventCallback OnCreate, OnDestroy;
|
||||||
inline static OutputCallback Output;
|
inline static OutputCallback Output;
|
||||||
|
|
||||||
@ -16,9 +16,7 @@ public:
|
|||||||
inline static int defaultCodepage = SHIFT_JIS;
|
inline static int defaultCodepage = SHIFT_JIS;
|
||||||
inline static int threadCounter = 0;
|
inline static int threadCounter = 0;
|
||||||
|
|
||||||
TextThread(ThreadParam tp, HookParam hp, std::wstring name);
|
TextThread(ThreadParam tp, HookParam hp, std::optional<std::wstring> name = {});
|
||||||
TextThread(TextThread&) = delete;
|
|
||||||
TextThread& operator=(TextThread) = delete;
|
|
||||||
~TextThread();
|
~TextThread();
|
||||||
|
|
||||||
std::wstring GetStorage();
|
std::wstring GetStorage();
|
||||||
|
21
GUI/main.cpp
21
GUI/main.cpp
@ -2,6 +2,7 @@
|
|||||||
#include "host/util.h"
|
#include "host/util.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -15,8 +16,16 @@ namespace
|
|||||||
|
|
||||||
thread_local std::wstring lastError = L"Unknown error";
|
thread_local std::wstring lastError = L"Unknown error";
|
||||||
|
|
||||||
|
__declspec(noreturn) void Terminate()
|
||||||
|
{
|
||||||
|
MessageBoxW(NULL, lastError.c_str(), L"Textractor ERROR", MB_ICONERROR);
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
LONG WINAPI ExceptionLogger(EXCEPTION_POINTERS* exception)
|
LONG WINAPI ExceptionLogger(EXCEPTION_POINTERS* exception)
|
||||||
{
|
{
|
||||||
|
thread_local static auto terminateSetter = std::invoke(std::set_terminate, Terminate);
|
||||||
|
|
||||||
MEMORY_BASIC_INFORMATION info = {};
|
MEMORY_BASIC_INFORMATION info = {};
|
||||||
VirtualQuery(exception->ExceptionRecord->ExceptionAddress, &info, sizeof(info));
|
VirtualQuery(exception->ExceptionRecord->ExceptionAddress, &info, sizeof(info));
|
||||||
|
|
||||||
@ -36,14 +45,6 @@ namespace
|
|||||||
lastError = errorMsg.str();
|
lastError = errorMsg.str();
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(noreturn) void Terminate()
|
|
||||||
{
|
|
||||||
MessageBoxW(NULL, lastError.c_str(), L"Textractor ERROR", MB_ICONERROR);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local auto _ = [] { return std::set_terminate(Terminate); }();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -51,9 +52,7 @@ int main(int argc, char *argv[])
|
|||||||
AddVectoredExceptionHandler(FALSE, ExceptionLogger);
|
AddVectoredExceptionHandler(FALSE, ExceptionLogger);
|
||||||
SetUnhandledExceptionFilter([](auto) -> LONG { Terminate(); });
|
SetUnhandledExceptionFilter([](auto) -> LONG { Terminate(); });
|
||||||
|
|
||||||
std::wstring exe = Util::GetModuleFileName().value();
|
QDir::setCurrent(QFileInfo().absolutePath());
|
||||||
while (exe.back() != L'\\') exe.pop_back();
|
|
||||||
SetCurrentDirectoryW(exe.c_str());
|
|
||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "extenwindow.h"
|
#include "extenwindow.h"
|
||||||
#include "setdialog.h"
|
#include "setdialog.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "host/util.h"
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
|
Host::Shutdown();
|
||||||
settings.setValue(WINDOW, geometry());
|
settings.setValue(WINDOW, geometry());
|
||||||
settings.sync();
|
settings.sync();
|
||||||
delete ui;
|
delete ui;
|
||||||
@ -46,7 +48,7 @@ void MainWindow::closeEvent(QCloseEvent*)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::InvokeOnMainThread(std::function<void()>&& f)
|
void MainWindow::InvokeOnMainThread(std::function<void()> f)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(this, f);
|
QMetaObject::invokeMethod(this, f);
|
||||||
}
|
}
|
||||||
@ -56,16 +58,15 @@ void MainWindow::ProcessConnected(DWORD processId)
|
|||||||
if (processId == 0) return;
|
if (processId == 0) return;
|
||||||
InvokeOnMainThread([&, processId]
|
InvokeOnMainThread([&, processId]
|
||||||
{
|
{
|
||||||
processCombo->addItem(QString::number(processId, 16).toUpper() + ": " + GetModuleName(processId));
|
QString process = QString::fromStdWString(Util::GetModuleFileName(processId).value());
|
||||||
QString processName = GetFullModuleName(processId);
|
processCombo->addItem(QString::number(processId, 16).toUpper() + ": " + QFileInfo(process).fileName());
|
||||||
|
|
||||||
QStringList allProcesses = QString(QAutoFile(HOOK_SAVE_FILE, QIODevice::ReadOnly)->readAll()).split("\r", QString::SkipEmptyParts);
|
QStringList allProcesses = QString(QAutoFile(HOOK_SAVE_FILE, QIODevice::ReadOnly)->readAll()).split("\r", QString::SkipEmptyParts);
|
||||||
for (auto hooks = allProcesses.rbegin(); hooks != allProcesses.rend(); ++hooks)
|
// Can't use QFileInfo::absoluteFilePath since hook save file has '\\' as path separator
|
||||||
if (hooks->contains(processName))
|
auto hookList = std::find_if(allProcesses.rbegin(), allProcesses.rend(), [&](QString hookList) { return hookList.contains(process); });
|
||||||
{
|
if (hookList != allProcesses.rend())
|
||||||
for (auto hook : hooks->split(" , "))
|
for (auto hookCode : hookList->split(" , "))
|
||||||
if (auto hp = ParseCode(hook)) Host::InsertHook(processId, hp.value());
|
if (auto hp = ParseCode(hookCode)) Host::InsertHook(processId, hp.value());
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +186,7 @@ void MainWindow::on_saveButton_clicked()
|
|||||||
ThreadParam tp = ParseTextThreadString(ttCombo->itemText(i));
|
ThreadParam tp = ParseTextThreadString(ttCombo->itemText(i));
|
||||||
if (tp.processId == GetSelectedProcessId() && !(Host::GetHookParam(tp).type & HOOK_ENGINE)) hookCodes[tp.addr] = GenerateCode(Host::GetHookParam(tp), tp.processId);
|
if (tp.processId == GetSelectedProcessId() && !(Host::GetHookParam(tp).type & HOOK_ENGINE)) hookCodes[tp.addr] = GenerateCode(Host::GetHookParam(tp), tp.processId);
|
||||||
}
|
}
|
||||||
QString hookList = GetFullModuleName(GetSelectedProcessId());
|
QString hookList = QString::fromStdWString(Util::GetModuleFileName(GetSelectedProcessId()).value());
|
||||||
for (auto hookCode : hookCodes) hookList += " , " + hookCode;
|
for (auto hookCode : hookCodes) hookList += " , " + hookCode;
|
||||||
QAutoFile(HOOK_SAVE_FILE, QIODevice::Append)->write((hookList + "\r\n").toUtf8());
|
QAutoFile(HOOK_SAVE_FILE, QIODevice::Append)->write((hookList + "\r\n").toUtf8());
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void closeEvent(QCloseEvent*);
|
void closeEvent(QCloseEvent*);
|
||||||
void InvokeOnMainThread(std::function<void()>&& f);
|
void InvokeOnMainThread(std::function<void()> f);
|
||||||
void ProcessConnected(DWORD processId);
|
void ProcessConnected(DWORD processId);
|
||||||
void ProcessDisconnected(DWORD processId);
|
void ProcessDisconnected(DWORD processId);
|
||||||
void ThreadAdded(TextThread* thread);
|
void ThreadAdded(TextThread* thread);
|
||||||
|
44
GUI/misc.cpp
44
GUI/misc.cpp
@ -1,32 +1,16 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
|
#include "host/util.h"
|
||||||
#include <Psapi.h>
|
#include <Psapi.h>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
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(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GetModuleName(DWORD processId, HMODULE module)
|
|
||||||
{
|
|
||||||
QString fullName = GetFullModuleName(processId, module);
|
|
||||||
return fullName.remove(0, fullName.lastIndexOf("\\") + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
QMultiHash<QString, DWORD> GetAllProcesses()
|
QMultiHash<QString, DWORD> GetAllProcesses()
|
||||||
{
|
{
|
||||||
DWORD allProcessIds[0x1000];
|
DWORD allProcessIds[5000] = {}, spaceUsed = 0;
|
||||||
DWORD spaceUsed;
|
EnumProcesses(allProcessIds, sizeof(allProcessIds), &spaceUsed);
|
||||||
QMultiHash<QString, DWORD> ret;
|
QMultiHash<QString, DWORD> ret;
|
||||||
if (!EnumProcesses(allProcessIds, sizeof(allProcessIds), &spaceUsed)) return ret;
|
|
||||||
for (int i = 0; i < spaceUsed / sizeof(DWORD); ++i)
|
for (int i = 0; i < spaceUsed / sizeof(DWORD); ++i)
|
||||||
if (GetModuleName(allProcessIds[i]).size())
|
if (auto processName = Util::GetModuleFileName(allProcessIds[i])) ret.insert(QFileInfo(QString::fromStdWString(processName.value())).fileName(), allProcessIds[i]);
|
||||||
ret.insert(GetModuleName(allProcessIds[i]), allProcessIds[i]);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,19 +219,15 @@ namespace
|
|||||||
|
|
||||||
// Attempt to make the address relative
|
// Attempt to make the address relative
|
||||||
if (!(hp.type & MODULE_OFFSET))
|
if (!(hp.type & MODULE_OFFSET))
|
||||||
{
|
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
||||||
HANDLE processHandle;
|
if (MEMORY_BASIC_INFORMATION info = {}; VirtualQueryEx(process, (LPCVOID)hp.address, &info, sizeof(info)))
|
||||||
if (!(processHandle = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))) goto fin;
|
if (auto moduleName = Util::GetModuleFileName(processId, (HMODULE)info.AllocationBase))
|
||||||
MEMORY_BASIC_INFORMATION info;
|
{
|
||||||
if (!VirtualQueryEx(processHandle, (LPCVOID)hp.address, &info, sizeof(info))) goto fin;
|
hp.type |= MODULE_OFFSET;
|
||||||
QString moduleName = GetModuleName(processId, (HMODULE)info.AllocationBase);
|
hp.address -= (uint64_t)info.AllocationBase;
|
||||||
if (moduleName == "") goto fin;
|
wcscpy_s<MAX_MODULE_SIZE>(hp.module, moduleName->c_str() + moduleName->rfind(L'\\') + 1);
|
||||||
hp.type |= MODULE_OFFSET;
|
}
|
||||||
hp.address -= (uint64_t)info.AllocationBase;
|
|
||||||
wcscpy_s<MAX_MODULE_SIZE>(hp.module, moduleName.toStdWString().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
fin:
|
|
||||||
codeBuilder << "@" << hp.address;
|
codeBuilder << "@" << hp.address;
|
||||||
if (hp.type & MODULE_OFFSET) codeBuilder << ":" << QString::fromWCharArray(hp.module);
|
if (hp.type & MODULE_OFFSET) codeBuilder << ":" << QString::fromWCharArray(hp.module);
|
||||||
if (hp.type & FUNCTION_OFFSET) codeBuilder << ":" << hp.function;
|
if (hp.type & FUNCTION_OFFSET) codeBuilder << ":" << hp.function;
|
||||||
|
@ -13,8 +13,6 @@ private:
|
|||||||
QFile f;
|
QFile f;
|
||||||
};
|
};
|
||||||
|
|
||||||
QString GetFullModuleName(DWORD processId, HMODULE module = NULL);
|
|
||||||
QString GetModuleName(DWORD processId, HMODULE module = NULL);
|
|
||||||
QMultiHash<QString, DWORD> GetAllProcesses();
|
QMultiHash<QString, DWORD> GetAllProcesses();
|
||||||
std::optional<HookParam> ParseCode(QString HCode);
|
std::optional<HookParam> ParseCode(QString HCode);
|
||||||
QString GenerateCode(HookParam hp, DWORD processId);
|
QString GenerateCode(HookParam hp, DWORD processId);
|
||||||
|
@ -7,4 +7,5 @@
|
|||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user