small refactor. rename and extract exception handling

This commit is contained in:
Akash Mozumdar 2018-12-22 13:05:01 -05:00
parent 507e0bc1e6
commit 1c391e3a4b
7 changed files with 61 additions and 57 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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