aboutsummaryrefslogtreecommitdiff
path: root/VMProtect/function_dialog.cc
diff options
context:
space:
mode:
authorjmpoep <OriginalEntryPoint@qq.com>2023-12-07 16:51:07 +0800
committerjmpoep <OriginalEntryPoint@qq.com>2023-12-07 16:51:07 +0800
commit28008a746a31abb7909dd86cb0cd413ac8943b0b (patch)
treea30b74b8cad548048c3c1551d652828ab76fa9bd /VMProtect/function_dialog.cc
downloadvmprotect-3.5.1-master.tar
vmprotect-3.5.1-master.tar.gz
vmprotect-3.5.1-master.tar.bz2
vmprotect-3.5.1-master.zip
first commitHEADmaster
Diffstat (limited to 'VMProtect/function_dialog.cc')
-rw-r--r--VMProtect/function_dialog.cc265
1 files changed, 265 insertions, 0 deletions
diff --git a/VMProtect/function_dialog.cc b/VMProtect/function_dialog.cc
new file mode 100644
index 0000000..3e67212
--- /dev/null
+++ b/VMProtect/function_dialog.cc
@@ -0,0 +1,265 @@
+#include "../core/objects.h"
+#include "../core/core.h"
+#include "../core/lang.h"
+#include "../core/files.h"
+#include "../core/processors.h"
+
+#include "widgets.h"
+#include "models.h"
+#include "property_editor.h"
+#include "function_dialog.h"
+#include "message_dialog.h"
+#include "help_browser.h"
+#include "moc/moc_function_dialog.cc"
+#include "application.h"
+
+/**
+ * FunctionDialog
+ */
+
+FunctionDialog::FunctionDialog(IFile *file, IArchitecture *file_arch, ShowMode mode, QWidget *parent)
+ : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint), file_(file), mode_(mode), defaultArch_(NULL)
+{
+ setWindowTitle(QString::fromUtf8(language[mode_ == smAddFunction ? lsAddFunction : lsGoTo].c_str()));
+
+ if (file_arch) {
+ functionListModel_.reset(new MapFunctionListModel(*file_arch, (mode_ == smAddFunction), this));
+ defaultArch_ = file_arch;
+ } else {
+ functionBundleListModel_.reset(new MapFunctionBundleListModel(*file, (mode_ == smAddFunction), this));
+ if (!file_->map_function_list()->show_arch_name()) {
+ for (size_t i = 0; i < file_->count(); i++) {
+ IArchitecture *arch = file_->item(i);
+ if (!arch->visible())
+ continue;
+
+ defaultArch_ = arch;
+ break;
+ }
+ }
+ }
+
+ QLabel *addressLabel = new QLabel(QString::fromUtf8(language[lsAddress].c_str()), this);
+ addressEdit_ = new LineEdit(this);
+ tabBar_ = new TabWidget(this);
+ tabBar_->setIconSize(QSize(18, 18));
+
+ QFrame *panel;
+ QLayout *panelLayout;
+
+ functionsTree_ = new TreeView(this);
+ functionsTree_->setObjectName("grid");
+ functionsTree_->setIconSize(QSize(18, 18));
+ functionsTree_->setRootIsDecorated(false);
+ functionsTree_->setUniformRowHeights(true);
+ if (functionBundleListModel_.get())
+ functionsTree_->setModel(functionBundleListModel_.get());
+ else
+ functionsTree_->setModel(functionListModel_.get());
+ if (mode_ == smAddFunction)
+ functionsTree_->setSelectionMode(QTreeView::ExtendedSelection);
+ functionsTree_->setSelectionBehavior(QTreeView::SelectRows);
+ functionsTree_->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ functionsTree_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ functionsTree_->header()->setSectionsMovable(false);
+ functionsTree_->header()->setSectionsClickable(true);
+ connect(functionsTree_->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
+ this, SLOT(functionsTreeSelectionChanged(QItemSelection, QItemSelection)));
+ connect(functionsTree_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(okButtonClicked()));
+ connect(functionsTree_->header(), SIGNAL(sectionClicked(int)), this, SLOT(sectionClicked(int)));
+
+ functionsFilter_ = new SearchLineEdit(this);
+ functionsFilter_->setPlaceholderText(QString::fromUtf8(language[lsSearch].c_str()));
+ connect(functionsFilter_, SIGNAL(textChanged(const QString &)), this, SLOT(functionsFilterChanged()));
+ connect(functionsFilter_, SIGNAL(returnPressed()), this, SLOT(functionsFilterChanged()));
+
+ panel = new QFrame(this);
+ panelLayout = new QVBoxLayout();
+ panelLayout->setContentsMargins(0, 10, 0, 0);
+ panelLayout->setSpacing(10);
+ panelLayout->addWidget(functionsFilter_);
+ panelLayout->addWidget(functionsTree_);
+ panel->setLayout(panelLayout);
+ tabBar_->addTab(panel, QIcon(":/images/star_gray.png"), QString::fromUtf8(language[lsFunctions].c_str()));
+
+ if (mode_ == smAddFunction) {
+ PropertyManager *propertyManager = new PropertyManager(this);
+ GroupProperty *protection = propertyManager->addGroupProperty(NULL, QString::fromUtf8(language[lsProtection].c_str()));
+ compilationType_ = propertyManager->addEnumProperty(protection, QString::fromUtf8(language[lsCompilationType].c_str()),
+ QStringList() << QString::fromUtf8(language[lsVirtualization].c_str())
+ << QString::fromUtf8(language[lsMutation].c_str())
+ << QString("%1 (%2 + %3)").arg(QString::fromUtf8(language[lsUltra].c_str())).arg(QString::fromUtf8(language[lsMutation].c_str())).arg(QString::fromUtf8(language[lsVirtualization].c_str())), 0);
+ lockToKey_ = propertyManager->addBoolProperty(protection, QString::fromUtf8(language[lsLockToSerialNumber].c_str()), false);
+
+ TreePropertyEditor *optionsTree = new TreePropertyEditor(this);
+ optionsTree->setFrameShape(QFrame::Box);
+ optionsTree->setModel(propertyManager);
+ optionsTree->expandToDepth(0);
+ optionsTree->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ optionsTree->header()->setSectionsMovable(false);
+
+ panel = new QFrame(this);
+ panelLayout = new QVBoxLayout();
+ panelLayout->setContentsMargins(0, 10, 0, 0);
+ panelLayout->addWidget(optionsTree);
+ panel->setLayout(panelLayout);
+ tabBar_->addTab(panel, QIcon(":/images/gear.png"), QString::fromUtf8(language[lsOptions].c_str()));
+ }
+
+ QToolButton *helpButton = new QToolButton(this);
+ helpButton->setShortcut(HelpContentsKeySequence());
+ helpButton->setIconSize(QSize(20, 20));
+ helpButton->setIcon(QIcon(":/images/help_gray.png"));
+ helpButton->setToolTip(QString::fromUtf8(language[lsHelp].c_str()));
+ connect(helpButton, SIGNAL(clicked(bool)), this, SLOT(helpClicked()));
+
+ QPushButton *okButton = new PushButton(windowTitle(), this);
+ connect(okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked()));
+
+ QPushButton *cancelButton = new PushButton(QString::fromUtf8(language[lsCancel].c_str()), this);
+ connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->setContentsMargins(0, 0, 0, 0);
+ buttonLayout->setSpacing(10);
+ buttonLayout->addWidget(helpButton);
+ buttonLayout->addStretch();
+#ifdef __APPLE__
+ buttonLayout->addWidget(cancelButton);
+ buttonLayout->addWidget(okButton);
+#else
+ buttonLayout->addWidget(okButton);
+ buttonLayout->addWidget(cancelButton);
+#endif
+
+ QGridLayout *layout = new QGridLayout();
+ layout->setContentsMargins(10, 10, 10, 10);
+ layout->setSpacing(10);
+ layout->addWidget(addressLabel, 0, 0);
+ layout->addWidget(addressEdit_, 0, 1);
+ layout->addWidget(tabBar_, 1, 0, 1, 2);
+ layout->addLayout(buttonLayout, 2, 0, 1, 2);
+ setLayout(layout);
+
+ setMinimumSize(480 * Application::stylesheetScaleFactor(), 300 * Application::stylesheetScaleFactor());
+}
+
+bool FunctionDialog::checkAddress(const AddressInfo &info)
+{
+ if (!info.arch)
+ return false;
+
+ if (mode_ == smAddFunction) {
+ if (info.arch->segment_list()->GetMemoryTypeByAddress(info.address) & mtExecutable) {
+ return true;
+ } else {
+ MapFunction *func = info.arch->map_function_list()->GetFunctionByAddress(info.address);
+ if (func && func->type() == otString)
+ return true;
+ }
+ } else {
+ if (info.arch->segment_list()->GetSectionByAddress(info.address))
+ return true;
+ }
+ return false;
+}
+
+void FunctionDialog::okButtonClicked()
+{
+ addresses_.clear();
+
+ bool show_arch_name = file_->map_function_list()->show_arch_name();
+
+ QStringList address_list = addressEdit_->text().split(',');
+ if (address_list.isEmpty())
+ address_list.append("0");
+
+ QString address_str;
+ AddressInfo info;
+ info.arch = NULL;
+ int p = 0;
+ for (int i = 0; i < address_list.size(); i++) {
+ address_str = address_list[i].trimmed();
+ info.arch = defaultArch_;
+ if (show_arch_name) {
+ int dot_pos = address_str.indexOf('.');
+ if (dot_pos > -1) {
+ info.arch = file_->GetArchitectureByName(address_str.left(dot_pos).toUtf8().constData());
+ address_str.remove(0, dot_pos + 1);
+ }
+ }
+ bool is_valid;
+ info.address = address_str.toULongLong(&is_valid, 16);
+
+ if (!is_valid || !checkAddress(info)) {
+ MessageDialog::critical(this, "Invalid address", QMessageBox::Ok);
+ addressEdit_->setFocus();
+ addressEdit_->setCursorPosition(p);
+ addressEdit_->cursorForward(true, address_list[i].size());
+ return;
+ }
+ addresses_.append(info);
+ p += address_list[i].size() + 1;
+ }
+
+ accept();
+}
+
+void FunctionDialog::functionsTreeSelectionChanged(const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/)
+{
+ QModelIndexList list;
+
+ list = functionsTree_->selectionModel()->selectedIndexes();
+
+ QString address;
+ for (int i = 0; i < list.size(); i++) {
+ QModelIndex index = list.at(i);
+ if (index.column() != 0)
+ continue;
+
+ if (!address.isEmpty())
+ address.append(", ");
+ if (functionBundleListModel_.get()) {
+ MapFunctionBundle *func = static_cast<MapFunctionBundle *>(index.internalPointer());
+ address.append(QString::fromLatin1(func->display_address().c_str()));
+ } else {
+ MapFunction *func = static_cast<MapFunction *>(index.internalPointer());
+ address.append(QString::fromLatin1(func->display_address("").c_str()));
+ }
+ }
+ addressEdit_->setText(address);
+}
+
+CompilationType FunctionDialog::compilationType() const
+{
+ return static_cast<CompilationType>(compilationType_->value());
+}
+
+uint32_t FunctionDialog::compilationOptions() const
+{
+ uint32_t res = 0;
+ if (lockToKey_->value())
+ res |= coLockToKey;
+ return res;
+}
+
+void FunctionDialog::functionsFilterChanged()
+{
+ if (functionBundleListModel_.get())
+ functionBundleListModel_->search(functionsFilter_->text());
+ else
+ functionListModel_->search(functionsFilter_->text());
+}
+
+void FunctionDialog::helpClicked()
+{
+ HelpBrowser::showTopic(tabBar_->currentIndex() == 0 ? "functions::search" : "functions::setup");
+}
+
+void FunctionDialog::sectionClicked(int index)
+{
+ auto mdl = functionsTree_->model();
+ assert(mdl);
+ if (mdl)
+ mdl->sort(index);
+} \ No newline at end of file