forked from Public-Mirror/Textractor
small refactor. rename and extract exception handling
This commit is contained in:
parent
507e0bc1e6
commit
1c391e3a4b
@ -9,6 +9,7 @@ set(gui_SRCS
|
|||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
misc.cpp
|
misc.cpp
|
||||||
|
exception.cpp
|
||||||
extenwindow.cpp
|
extenwindow.cpp
|
||||||
tests.cpp
|
tests.cpp
|
||||||
host/host.cpp
|
host/host.cpp
|
||||||
|
51
GUI/exception.cpp
Normal file
51
GUI/exception.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "host/util.h"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
char* GetCppExceptionInfo(EXCEPTION_POINTERS* exception)
|
||||||
|
{
|
||||||
|
// See https://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273
|
||||||
|
// Not very reliable so use __try
|
||||||
|
__try { return ((char****)exception->ExceptionRecord->ExceptionInformation[2])[3][1][1] + 8; }
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER) { return "Could not find"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
thread_local static auto _ = std::invoke(std::set_terminate, Terminate);
|
||||||
|
|
||||||
|
MEMORY_BASIC_INFORMATION info = {};
|
||||||
|
VirtualQuery(exception->ExceptionRecord->ExceptionAddress, &info, sizeof(info));
|
||||||
|
|
||||||
|
std::wstringstream errorMsg;
|
||||||
|
errorMsg << std::uppercase << std::hex <<
|
||||||
|
L"Error code: " << exception->ExceptionRecord->ExceptionCode << std::endl <<
|
||||||
|
L"Error address: " << exception->ExceptionRecord->ExceptionAddress << std::endl <<
|
||||||
|
L"Error in module: " << Util::GetModuleFilename((HMODULE)info.AllocationBase).value_or(L"Could not find") << std::endl <<
|
||||||
|
L"Additional info: " << info.AllocationBase << std::endl;
|
||||||
|
|
||||||
|
if (exception->ExceptionRecord->ExceptionCode == 0xE06D7363)
|
||||||
|
errorMsg << L"Additional info: " << GetCppExceptionInfo(exception) << std::endl;
|
||||||
|
|
||||||
|
for (int i = 0; i < exception->ExceptionRecord->NumberParameters; ++i)
|
||||||
|
errorMsg << L"Additional info: " << exception->ExceptionRecord->ExceptionInformation[i] << std::endl;
|
||||||
|
|
||||||
|
lastError = errorMsg.str();
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto _ = std::invoke([]
|
||||||
|
{
|
||||||
|
AddVectoredExceptionHandler(FALSE, ExceptionLogger);
|
||||||
|
return SetUnhandledExceptionFilter([](auto) -> LONG { Terminate(); });
|
||||||
|
});
|
||||||
|
}
|
@ -155,7 +155,7 @@ namespace Host
|
|||||||
}
|
}
|
||||||
|
|
||||||
static HMODULE vnrhook = LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES);
|
static HMODULE vnrhook = LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES);
|
||||||
static std::wstring location = Util::GetModuleFileName(vnrhook).value();
|
static std::wstring location = Util::GetModuleFilename(vnrhook).value();
|
||||||
|
|
||||||
if (AutoHandle<> process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId))
|
if (AutoHandle<> process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId))
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace Util
|
namespace Util
|
||||||
{
|
{
|
||||||
std::optional<std::wstring> GetModuleFileName(DWORD processId, HMODULE module)
|
std::optional<std::wstring> GetModuleFilename(DWORD processId, HMODULE module)
|
||||||
{
|
{
|
||||||
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
||||||
{
|
{
|
||||||
@ -15,7 +15,7 @@ namespace Util
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::wstring> GetModuleFileName(HMODULE module)
|
std::optional<std::wstring> GetModuleFilename(HMODULE module)
|
||||||
{
|
{
|
||||||
std::vector<wchar_t> buffer(MAX_PATH);
|
std::vector<wchar_t> buffer(MAX_PATH);
|
||||||
if (::GetModuleFileNameW(module, buffer.data(), MAX_PATH)) return buffer.data();
|
if (::GetModuleFileNameW(module, buffer.data(), MAX_PATH)) return buffer.data();
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
namespace Util
|
namespace Util
|
||||||
{
|
{
|
||||||
std::optional<std::wstring> GetModuleFileName(DWORD processId, HMODULE module = NULL);
|
std::optional<std::wstring> GetModuleFilename(DWORD processId, HMODULE module = NULL);
|
||||||
std::optional<std::wstring> GetModuleFileName(HMODULE module = NULL);
|
std::optional<std::wstring> GetModuleFilename(HMODULE module = NULL);
|
||||||
std::optional<std::wstring> GetClipboardText();
|
std::optional<std::wstring> GetClipboardText();
|
||||||
std::optional<std::wstring> StringToWideString(std::string text, UINT encoding = CP_UTF8);
|
std::optional<std::wstring> StringToWideString(std::string text, UINT encoding = CP_UTF8);
|
||||||
// return true if repetition found (see https://github.com/Artikash/Textractor/issues/40)
|
// return true if repetition found (see https://github.com/Artikash/Textractor/issues/40)
|
||||||
|
49
GUI/main.cpp
49
GUI/main.cpp
@ -1,59 +1,12 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "host/util.h"
|
#include "host/util.h"
|
||||||
#include <sstream>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
char* GetCppExceptionInfo(EXCEPTION_POINTERS* exception)
|
|
||||||
{
|
|
||||||
// See https://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273
|
|
||||||
// Not very reliable so use __try
|
|
||||||
__try { return ((char****)exception->ExceptionRecord->ExceptionInformation[2])[3][1][1] + 8; }
|
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER) { return "Could not find"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
thread_local static auto terminateSetter = std::invoke(std::set_terminate, Terminate);
|
|
||||||
|
|
||||||
MEMORY_BASIC_INFORMATION info = {};
|
|
||||||
VirtualQuery(exception->ExceptionRecord->ExceptionAddress, &info, sizeof(info));
|
|
||||||
|
|
||||||
std::wstringstream errorMsg;
|
|
||||||
errorMsg << std::uppercase << std::hex <<
|
|
||||||
L"Error code: " << exception->ExceptionRecord->ExceptionCode << std::endl <<
|
|
||||||
L"Error address: " << exception->ExceptionRecord->ExceptionAddress << std::endl <<
|
|
||||||
L"Error in module: " << Util::GetModuleFileName((HMODULE)info.AllocationBase).value_or(L"Could not find") << std::endl <<
|
|
||||||
L"Additional info: " << info.AllocationBase << std::endl;
|
|
||||||
|
|
||||||
if (exception->ExceptionRecord->ExceptionCode == 0xE06D7363)
|
|
||||||
errorMsg << L"Additional info: " << GetCppExceptionInfo(exception) << std::endl;
|
|
||||||
|
|
||||||
for (int i = 0; i < exception->ExceptionRecord->NumberParameters; ++i)
|
|
||||||
errorMsg << L"Additional info: " << exception->ExceptionRecord->ExceptionInformation[i] << std::endl;
|
|
||||||
|
|
||||||
lastError = errorMsg.str();
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
AddVectoredExceptionHandler(FALSE, ExceptionLogger);
|
QDir::setCurrent(QFileInfo(S(Util::GetModuleFilename().value())).absolutePath());
|
||||||
SetUnhandledExceptionFilter([](auto) -> LONG { Terminate(); });
|
|
||||||
|
|
||||||
QDir::setCurrent(QFileInfo(S(Util::GetModuleFileName().value())).absolutePath());
|
|
||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
|
@ -75,7 +75,6 @@ MainWindow::~MainWindow()
|
|||||||
QSettings settings(CONFIG_FILE, QSettings::IniFormat);
|
QSettings settings(CONFIG_FILE, QSettings::IniFormat);
|
||||||
settings.setValue(WINDOW, geometry());
|
settings.setValue(WINDOW, geometry());
|
||||||
settings.sync();
|
settings.sync();
|
||||||
delete ui;
|
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +88,7 @@ void MainWindow::ProcessConnected(DWORD processId)
|
|||||||
if (processId == 0) return;
|
if (processId == 0) return;
|
||||||
QMetaObject::invokeMethod(this, [this, processId]
|
QMetaObject::invokeMethod(this, [this, processId]
|
||||||
{
|
{
|
||||||
QString process = S(Util::GetModuleFileName(processId).value());
|
QString process = S(Util::GetModuleFilename(processId).value());
|
||||||
ui->processCombo->addItem(QString::number(processId, 16).toUpper() + ": " + QFileInfo(process).fileName());
|
ui->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);
|
||||||
@ -189,7 +188,7 @@ void MainWindow::AttachProcess()
|
|||||||
DWORD allProcessIds[5000] = {}, spaceUsed = 0;
|
DWORD allProcessIds[5000] = {}, spaceUsed = 0;
|
||||||
EnumProcesses(allProcessIds, sizeof(allProcessIds), &spaceUsed);
|
EnumProcesses(allProcessIds, sizeof(allProcessIds), &spaceUsed);
|
||||||
for (int i = 0; i < spaceUsed / sizeof(DWORD); ++i)
|
for (int i = 0; i < spaceUsed / sizeof(DWORD); ++i)
|
||||||
if (auto processName = Util::GetModuleFileName(allProcessIds[i])) allProcesses.insert(QFileInfo(S(processName.value())).fileName(), allProcessIds[i]);
|
if (auto processName = Util::GetModuleFilename(allProcessIds[i])) allProcesses.insert(QFileInfo(S(processName.value())).fileName(), allProcessIds[i]);
|
||||||
|
|
||||||
QStringList processList(allProcesses.uniqueKeys());
|
QStringList processList(allProcesses.uniqueKeys());
|
||||||
processList.sort(Qt::CaseInsensitive);
|
processList.sort(Qt::CaseInsensitive);
|
||||||
@ -216,7 +215,7 @@ void MainWindow::AddHook()
|
|||||||
|
|
||||||
void MainWindow::SaveHooks()
|
void MainWindow::SaveHooks()
|
||||||
{
|
{
|
||||||
if (auto processName = Util::GetModuleFileName(GetSelectedProcessId()))
|
if (auto processName = Util::GetModuleFilename(GetSelectedProcessId()))
|
||||||
{
|
{
|
||||||
QHash<uint64_t, QString> hookCodes;
|
QHash<uint64_t, QString> hookCodes;
|
||||||
for (int i = 0; i < ui->ttCombo->count(); ++i)
|
for (int i = 0; i < ui->ttCombo->count(); ++i)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user