fix style issues and use blank icons

This commit is contained in:
Akash Mozumdar 2021-06-05 16:29:51 -06:00
parent a1d3abb080
commit eb1421c143
11 changed files with 121 additions and 283 deletions

View File

@ -2,20 +2,15 @@ include(QtUtils)
msvc_registry_search() msvc_registry_search()
find_qt5(Core Widgets WinExtras) find_qt5(Core Widgets WinExtras)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
add_executable(Textractor WIN32 add_executable(Textractor WIN32
main.cpp main.cpp
mainwindow.cpp mainwindow.cpp
extenwindow.cpp extenwindow.cpp
attachtoprocessdialog.cpp attachprocessdialog.cpp
host/exception.cpp host/exception.cpp
host/host.cpp host/host.cpp
host/textthread.cpp host/textthread.cpp
host/hookcode.cpp host/hookcode.cpp
utils/windowshelpers.cpp
Textractor.rc Textractor.rc
Textractor.ico Textractor.ico
) )

View File

@ -0,0 +1,48 @@
#include "attachprocessdialog.h"
#include <QtWinExtras/QtWin>
extern const char* SELECT_PROCESS;
extern const char* ATTACH_INFO;
AttachProcessDialog::AttachProcessDialog(QWidget *parent, std::vector<std::pair<QString, HICON>> processIcons) :
QDialog(parent, Qt::WindowCloseButtonHint),
model(this)
{
ui.setupUi(this);
setWindowTitle(SELECT_PROCESS);
ui.label->setText(ATTACH_INFO);
ui.processIdEdit->setValidator(new QIntValidator(0, INT_MAX, this));
ui.processList->setModel(&model);
QPixmap transparent(100, 100);
transparent.fill(QColor::fromRgba(0));
for (const auto& [process, icon] : processIcons)
{
auto item = new QStandardItem(icon ? QIcon(QtWin::fromHICON(icon)) : transparent, process);
item->setEditable(false);
model.appendRow(item);
}
connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(ui.processList, &QListView::clicked, [this](QModelIndex index)
{
selectedProcess = model.item(index.row())->text();
});
connect(ui.processList, &QListView::doubleClicked, [this](QModelIndex index)
{
selectedProcess = model.item(index.row())->text();
accept();
});
connect(ui.processIdEdit, &QLineEdit::returnPressed, [this]
{
selectedProcess = ui.processIdEdit->text();
accept();
});
}
QString AttachProcessDialog::SelectedProcess()
{
return selectedProcess.isEmpty() ? ui.processIdEdit->text() : selectedProcess;
}

17
GUI/attachprocessdialog.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "qtcommon.h"
#include "ui_attachprocessdialog.h"
#include <QStandardItemModel>
class AttachProcessDialog : public QDialog
{
public:
explicit AttachProcessDialog(QWidget *parent, std::vector<std::pair<QString, HICON>> processIcons);
QString SelectedProcess();
private:
Ui::AttachProcessDialog ui;
QStandardItemModel model;
QString selectedProcess;
};

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AttachProcessDialog</class>
<widget class="QWidget" name="AttachProcessDialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>400</height>
</rect>
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="label"/>
</item>
<item>
<widget class="QLineEdit" name="processIdEdit">
<property name="placeholderText">
<string>Process id</string>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="processList"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,92 +0,0 @@
#include "attachtoprocessdialog.h"
#include "ui_attachtoprocessdialog.h"
#include "utils/windowshelpers.h"
#include <QStandardItemModel>
#include <algorithm>
#include <limits>
namespace
{
QString GetNameProcessFromIndex(const QModelIndex &index, const QVector<QPair<QString, HICON>>& data)
{
const int row = index.row();
return data[row].first;
}
}
AttachToProcessDialog::AttachToProcessDialog(QWidget *parent) :
QDialog(parent, Qt::WindowCloseButtonHint),
ui(new Ui::AttachToProcessDialog),
model(new QStandardItemModel(this))
{
ui->setupUi(this);
const QIntValidator* validator = new QIntValidator(0, INT_MAX, this);
ui->lineEdit->setValidator(validator);
}
AttachToProcessDialog::~AttachToProcessDialog()
{
delete ui;
}
void AttachToProcessDialog::setLabelText(const QString& text)
{
ui->label->setText(text);
}
void AttachToProcessDialog::setData(QVector<QPair<QString, HICON>>&& newData)
{
data = std::move(newData);
selectedProcess.clear();
std::sort(data.begin(), data.end(), [](const auto& left, const auto& right) {
return left.first < right.first;
});
model->clear();
for (const auto& [process, hIcon] : data)
{
QIcon icon = WindowsHepers::CreateQIconFromHIcon(hIcon);
auto* item = new QStandardItem(icon, process);
item->setEditable(false);
model->appendRow(item);
}
ui->listView->setModel(model);
}
QString AttachToProcessDialog::getSelectedData()
{
return selectedProcess.isEmpty() ? ui->lineEdit->text() : selectedProcess;
}
void AttachToProcessDialog::on_buttonBox_accepted()
{
accept();
}
void AttachToProcessDialog::on_buttonBox_rejected()
{
reject();
}
void AttachToProcessDialog::on_listView_doubleClicked(const QModelIndex& index)
{
selectedProcess = GetNameProcessFromIndex(index, data);
accept();
}
void AttachToProcessDialog::on_lineEdit_returnPressed()
{
selectedProcess = ui->lineEdit->text();
accept();
}
void AttachToProcessDialog::on_listView_clicked(const QModelIndex &index)
{
selectedProcess = GetNameProcessFromIndex(index, data);
}
void AttachToProcessDialog::on_lineEdit_editingFinished()
{
selectedProcess = ui->lineEdit->text();
}

View File

@ -1,51 +0,0 @@
#ifndef ATTACHTOPROCESSDIALOG_H
#define ATTACHTOPROCESSDIALOG_H
#include <QDialog>
#include <QString>
#include <QPair>
#include <QStyledItemDelegate>
#include <QVector>
#include <QtWinExtras/QtWin>
QT_BEGIN_NAMESPACE
namespace Ui {
class AttachToProcessDialog;
}
QT_END_NAMESPACE
class QStandardItemModel;
class QModelIndex;
class AttachToProcessDialog : public QDialog
{
Q_OBJECT
public:
explicit AttachToProcessDialog(QWidget *parent = nullptr);
void setData(QVector<QPair<QString, HICON>>&& newData);
void setLabelText(const QString& text);
QString getSelectedData();
~AttachToProcessDialog();
private slots:
void on_buttonBox_accepted();
void on_buttonBox_rejected();
void on_listView_doubleClicked(const QModelIndex &index);
void on_lineEdit_returnPressed();
void on_listView_clicked(const QModelIndex &index);
void on_lineEdit_editingFinished();
private:
Ui::AttachToProcessDialog* ui;
QStandardItemModel* model;
QString selectedProcess;
QVector<QPair<QString, HICON>> data;
};
#endif // ATTACHTOPROCESSDIALOG_H

View File

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AttachToProcessDialog</class>
<widget class="QWidget" name="AttachToProcessDialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>813</width>
<height>426</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="placeholderText">
<string>PID</string>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="listView"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -2,11 +2,6 @@
#include "qtcommon.h" #include "qtcommon.h"
namespace Ui
{
class ExtenWindow;
}
struct InfoForExtension struct InfoForExtension
{ {
const char* name; const char* name;

View File

@ -5,9 +5,7 @@
#include "extenwindow.h" #include "extenwindow.h"
#include "host/host.h" #include "host/host.h"
#include "host/hookcode.h" #include "host/hookcode.h"
#include "attachtoprocessdialog.h" #include "attachprocessdialog.h"
#include "utils/windowshelpers.h"
#include <shellapi.h> #include <shellapi.h>
#include <process.h> #include <process.h>
#include <QRegularExpression> #include <QRegularExpression>
@ -32,7 +30,6 @@ extern const char* SETTINGS;
extern const char* EXTENSIONS; extern const char* EXTENSIONS;
extern const char* FONT; extern const char* FONT;
extern const char* SELECT_PROCESS; extern const char* SELECT_PROCESS;
extern const char* ATTACH_INFO;
extern const char* SELECT_PROCESS_INFO; extern const char* SELECT_PROCESS_INFO;
extern const char* FROM_COMPUTER; extern const char* FROM_COMPUTER;
extern const char* PROCESSES; extern const char* PROCESSES;
@ -83,7 +80,6 @@ namespace
Ui::MainWindow ui; Ui::MainWindow ui;
std::atomic<DWORD> selectedProcessId = 0; std::atomic<DWORD> selectedProcessId = 0;
ExtenWindow* extenWindow = nullptr; ExtenWindow* extenWindow = nullptr;
AttachToProcessDialog* attachDialog = nullptr;
std::unordered_set<DWORD> alreadyAttached; std::unordered_set<DWORD> alreadyAttached;
bool autoAttach = false, autoAttachSavedOnly = true; bool autoAttach = false, autoAttachSavedOnly = true;
bool showSystemProcesses = false; bool showSystemProcesses = false;
@ -158,49 +154,30 @@ namespace
void AttachProcess() void AttachProcess()
{ {
auto processes = GetAllProcesses();
QMultiHash<QString, DWORD> processesMap; QMultiHash<QString, DWORD> processesMap;
QVector<QPair<QString, HICON>> dialogData; std::vector<std::pair<QString, HICON>> processIcons;
dialogData.reserve(processes.size()); for (auto [processId, processName] : GetAllProcesses())
for (auto [processId, processName] : processes)
{ {
if (processName && (showSystemProcesses || processName->find(L":\\Windows\\") == std::string::npos)) if (processName && (showSystemProcesses || processName->find(L":\\Windows\\") == std::string::npos))
{ {
const auto& value = processName.value(); QString fileName = QFileInfo(S(processName.value())).fileName();
const QFileInfo& fileInfo = QFileInfo(S(value));
const QString& fileName = fileInfo.fileName();
if (!processesMap.contains(fileName)) if (!processesMap.contains(fileName))
{ {
const auto icon = WindowsHepers::GetIconHandlerFromExe(value.c_str()); HICON bigIcon, smallIcon;
dialogData.push_back({fileName, icon}); ExtractIconExW(processName->c_str(), 0, &bigIcon, &smallIcon, 1);
processIcons.push_back({ fileName, bigIcon ? bigIcon : smallIcon });
} }
processesMap.insert(fileName, processId); processesMap.insert(fileName, processId);
} }
} }
dialogData.shrink_to_fit(); std::sort(processIcons.begin(), processIcons.end());
processes.clear();
attachDialog->setWindowTitle(SELECT_PROCESS); AttachProcessDialog attachProcessDialog(This, processIcons);
attachDialog->setLabelText(ATTACH_INFO); if (attachProcessDialog.exec())
attachDialog->setData(std::move(dialogData));
const bool hasChosenData = attachDialog->exec() != 0;
if (hasChosenData)
{ {
const QString& process = attachDialog->getSelectedData(); QString process = attachProcessDialog.SelectedProcess();
const int pid = process.toInt(nullptr, 0); if (int processId = process.toInt(nullptr, 0)) Host::InjectProcess(processId);
if (pid) else for (int processId : processesMap.values(process)) Host::InjectProcess(processId);
{
Host::InjectProcess(pid);
}
else
{
for (const auto& processId : processesMap.values(process))
{
Host::InjectProcess(processId);
}
}
} }
} }
@ -636,7 +613,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
This = this; This = this;
ui.setupUi(this); ui.setupUi(this);
extenWindow = new ExtenWindow(this); extenWindow = new ExtenWindow(this);
attachDialog = new AttachToProcessDialog(this);
for (auto [text, slot] : Array<const char*, void(&)()>{ for (auto [text, slot] : Array<const char*, void(&)()>{
{ ATTACH, AttachProcess }, { ATTACH, AttachProcess },
{ LAUNCH, LaunchProcess }, { LAUNCH, LaunchProcess },

View File

@ -1,30 +0,0 @@
#include "windowshelpers.h"
#include <QApplication>
#include <QIcon>
#include <QStyle>
#include <QPixmap>
#include <QtWinExtras/QtWin>
#include <shellapi.h>
namespace WindowsHepers {
HICON GetIconHandlerFromExe(const wchar_t* const filePath)
{
HICON bigIcon;
HICON smallIcon;
ExtractIconEx(filePath, 0, &bigIcon, &smallIcon, 1);
return bigIcon != 0 ? bigIcon : smallIcon;
}
QIcon CreateQIconFromHIcon(const HICON hIcon)
{
if (hIcon)
{
const QPixmap& pixmap = QtWin::fromHICON(hIcon);
return QIcon(pixmap);
}
const QStyle* style = QApplication::style();
return style->standardIcon(QStyle::SP_ComputerIcon);
}
}

View File

@ -1,9 +0,0 @@
#pragma once
#include <QtWinExtras/QtWin>
class QIcon;
namespace WindowsHepers
{
HICON GetIconHandlerFromExe(const wchar_t* const filePath);
QIcon CreateQIconFromHIcon(const HICON hIcon);
}