From 7bdc28d07d4ecc1bf5fc063fddf598fb48b8010c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Fri, 1 Feb 2019 21:40:34 +0100 Subject: [PATCH] Make EditMethodDialog Method Loading work --- src/Cutter.cpp | 47 +++++++++++++++--------- src/Cutter.h | 14 ++++---- src/dialogs/EditMethodDialog.cpp | 62 +++++++++++++++++++------------- src/dialogs/EditMethodDialog.h | 10 +++--- src/widgets/ClassesWidget.cpp | 12 +++---- 5 files changed, 84 insertions(+), 61 deletions(-) diff --git a/src/Cutter.cpp b/src/Cutter.cpp index 1d1ec7dc..6a3e6f7f 100644 --- a/src/Cutter.cpp +++ b/src/Cutter.cpp @@ -538,23 +538,6 @@ void CutterCore::setCurrentBits(int bits, RVA offset) emit instructionChanged(offset); } -void CutterCore::setClassMethod(const QString &className, const BinClassMethodDescription &meth) -{ - RAnalMethod analMeth; - analMeth.name = strdup (meth.name.toUtf8().constData()); - analMeth.addr = meth.addr; - analMeth.vtable_offset = meth.vtableOffset; - r_anal_class_method_set(core_->anal, className.toUtf8().constData(), &analMeth); - r_anal_class_method_fini(&analMeth); - emit classesChanged(); -} - -void CutterCore::renameClassMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName) -{ - r_anal_class_method_rename(core_->anal, className.toUtf8().constData(), oldMethodName.toUtf8().constData(), newMethodName.toUtf8().constData()); - emit classesChanged(); -} - void CutterCore::seek(ut64 offset) { // Slower than using the API, but the API is not complete @@ -2067,6 +2050,36 @@ QList CutterCore::getAnalClassVTables(const QString &cls) return ret; } +bool CutterCore::getAnalMethod(const QString &cls, const QString &meth, AnalMethodDescription *desc) +{ + RAnalMethod analMeth; + if (r_anal_class_method_get(core_->anal, cls.toUtf8().constData(), meth.toUtf8().constData(), &analMeth) != R_ANAL_CLASS_ERR_SUCCESS) { + return false; + } + desc->name = QString::fromUtf8(analMeth.name); + desc->addr = analMeth.addr; + desc->vtableOffset = analMeth.vtable_offset; + r_anal_class_method_fini(&analMeth); + return true; +} + +void CutterCore::setAnalMethod(const QString &className, const AnalMethodDescription &meth) +{ + RAnalMethod analMeth; + analMeth.name = strdup (meth.name.toUtf8().constData()); + analMeth.addr = meth.addr; + analMeth.vtable_offset = meth.vtableOffset; + r_anal_class_method_set(core_->anal, className.toUtf8().constData(), &analMeth); + r_anal_class_method_fini(&analMeth); + emit classesChanged(); +} + +void CutterCore::renameAnalMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName) +{ + r_anal_class_method_rename(core_->anal, className.toUtf8().constData(), oldMethodName.toUtf8().constData(), newMethodName.toUtf8().constData()); + emit classesChanged(); +} + QList CutterCore::getAllResources() { CORE_LOCK(); diff --git a/src/Cutter.h b/src/Cutter.h index 4aec0654..f4dbb885 100644 --- a/src/Cutter.h +++ b/src/Cutter.h @@ -480,8 +480,13 @@ public: void setCurrentBits(int bits, RVA offset = RVA_INVALID); /* Classes */ - void setClassMethod(const QString &className, const BinClassMethodDescription &meth); - void renameClassMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName); + QList getAllAnalClasses(); + QList getAnalClassMethods(const QString &cls); + QList getAnalClassBaseClasses(const QString &cls); + QList getAnalClassVTables(const QString &cls); + bool getAnalMethod(const QString &cls, const QString &meth, AnalMethodDescription *desc); + void renameAnalMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName); + void setAnalMethod(const QString &cls, const AnalMethodDescription &meth); /* File related methods */ bool loadFile(QString path, ut64 baddr = 0LL, ut64 mapaddr = 0LL, int perms = R_PERM_R, @@ -686,11 +691,6 @@ public: QJsonObject getRegisterJson(); QList getVariables(RVA at); - QList getAllAnalClasses(); - QList getAnalClassMethods(const QString &cls); - QList getAnalClassBaseClasses(const QString &cls); - QList getAnalClassVTables(const QString &cls); - QList getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType = QString::null); diff --git a/src/dialogs/EditMethodDialog.cpp b/src/dialogs/EditMethodDialog.cpp index a08c786d..db67d877 100644 --- a/src/dialogs/EditMethodDialog.cpp +++ b/src/dialogs/EditMethodDialog.cpp @@ -9,9 +9,9 @@ EditMethodDialog::EditMethodDialog(QWidget *parent) : setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); ui->classComboBox->clear(); - /* TODO for (auto &cls : Core()->getAllClassesFromAnal()) { - ui->classComboBox->addItem(cls.name, QVariant::fromValue(cls)); - }*/ + for (auto &cls : Core()->getAllAnalClasses()) { + ui->classComboBox->addItem(cls, cls); + } updateVirtualUI(); validateInput(); @@ -64,8 +64,8 @@ void EditMethodDialog::setClass(const QString &className) } for (int i=0; iclassComboBox->count(); i++) { - BinClassDescription cls = ui->classComboBox->itemData(i).value(); - if (cls.name == className) { + QString cls = ui->classComboBox->itemData(i).toString(); + if (cls == className) { ui->classComboBox->setCurrentIndex(i); break; } @@ -74,14 +74,14 @@ void EditMethodDialog::setClass(const QString &className) validateInput(); } -void EditMethodDialog::setMethod(const BinClassMethodDescription &meth) +void EditMethodDialog::setMethod(const AnalMethodDescription &desc) { - ui->nameEdit->setText(meth.name); - ui->addressEdit->setText(meth.addr != RVA_INVALID ? RAddressString(meth.addr) : nullptr); + ui->nameEdit->setText(desc.name); + ui->addressEdit->setText(desc.addr != RVA_INVALID ? RAddressString(desc.addr) : nullptr); - if (meth.vtableOffset >= 0) { + if (desc.vtableOffset >= 0) { ui->virtualCheckBox->setChecked(true); - ui->vtableOffsetEdit->setText(QString::number(meth.vtableOffset)); + ui->vtableOffsetEdit->setText(QString::number(desc.vtableOffset)); } else { ui->virtualCheckBox->setChecked(false); ui->vtableOffsetEdit->setText(nullptr); @@ -100,9 +100,9 @@ QString EditMethodDialog::getClass() return ui->classComboBox->itemData(index).value().name; } -BinClassMethodDescription EditMethodDialog::getMethod() +AnalMethodDescription EditMethodDialog::getMethod() { - BinClassMethodDescription ret; + AnalMethodDescription ret; ret.name = ui->nameEdit->text(); ret.addr = Core()->num(ui->addressEdit->text()); if (ui->virtualCheckBox->isChecked()) { @@ -113,33 +113,45 @@ BinClassMethodDescription EditMethodDialog::getMethod() return ret; } -bool EditMethodDialog::showDialog(const QString &title, const QString &className, BinClassMethodDescription *meth, QWidget *parent) +bool EditMethodDialog::showDialog(const QString &title, QString *className, AnalMethodDescription *desc, QWidget *parent) { auto dialog = new EditMethodDialog(parent); dialog->setWindowTitle(title); - dialog->setClass(className); - dialog->setMethod(*meth); + dialog->setClass(*className); + dialog->setMethod(*desc); int result = dialog->exec(); - *meth = dialog->getMethod(); + *className = dialog->getClass(); + *desc = dialog->getMethod(); return result == QDialog::DialogCode::Accepted; } -void EditMethodDialog::newMethod(const QString &className, BinClassMethodDescription meth) +void EditMethodDialog::newMethod(QString className, const QString &meth, QWidget *parent) { - if (!showDialog(tr("Create Method"), className, &meth)) { + AnalMethodDescription desc; + desc.name = meth; + desc.vtableOffset = -1; + desc.addr = Core()->getOffset(); + + if (!showDialog(tr("Create Method"), &className, &desc, parent)) { return; } - Core()->setClassMethod(className, meth); + + Core()->setAnalMethod(className, desc); } -void EditMethodDialog::editMethod(const QString &className, BinClassMethodDescription meth) +void EditMethodDialog::editMethod(const QString &className, const QString &meth, QWidget *parent) { - QString oldName = meth.name; - if (!showDialog(tr("Edit Method"), className, &meth)) { + AnalMethodDescription desc; + if (!Core()->getAnalMethod(className, meth, &desc)) { return; } - if (meth.name != oldName) { - Core()->renameClassMethod(className, oldName, meth.name); + + QString classNameCopy = className; + if (!showDialog(tr("Edit Method"), &classNameCopy, &desc, parent)) { + return; } - Core()->setClassMethod(className, meth); + if (desc.name != meth) { + Core()->renameAnalMethod(className, meth, desc.name); + } + Core()->setAnalMethod(className, desc); } \ No newline at end of file diff --git a/src/dialogs/EditMethodDialog.h b/src/dialogs/EditMethodDialog.h index aee65a01..5a6bbd59 100644 --- a/src/dialogs/EditMethodDialog.h +++ b/src/dialogs/EditMethodDialog.h @@ -19,14 +19,14 @@ public: ~EditMethodDialog(); void setClass(const QString &className); - void setMethod(const BinClassMethodDescription &meth); + void setMethod(const AnalMethodDescription &desc); QString getClass(); - BinClassMethodDescription getMethod(); + AnalMethodDescription getMethod(); - static bool showDialog(const QString &title, const QString &className, BinClassMethodDescription *meth, QWidget *parent = nullptr); - static void newMethod(const QString &className = nullptr, BinClassMethodDescription meth = BinClassMethodDescription()); - static void editMethod(const QString &className, BinClassMethodDescription meth); + static bool showDialog(const QString &title, QString *className, AnalMethodDescription *desc, QWidget *parent = nullptr); + static void newMethod(QString className = nullptr, const QString &meth = QString(), QWidget *parent = nullptr); + static void editMethod(const QString &className, const QString &meth, QWidget *parent = nullptr); private slots: void on_buttonBox_accepted(); diff --git a/src/widgets/ClassesWidget.cpp b/src/widgets/ClassesWidget.cpp index de452969..6c7a94d2 100644 --- a/src/widgets/ClassesWidget.cpp +++ b/src/widgets/ClassesWidget.cpp @@ -321,6 +321,8 @@ QVariant AnalClassesModel::data(const QModelIndex &index, int role) const } case TypeRole: return QVariant::fromValue(RowType::Class); + case NameRole: + return cls; default: return QVariant(); } @@ -596,10 +598,7 @@ void ClassesWidget::on_addMethodAction_triggered() className = index.parent().data(ClassesModel::NameRole).toString(); } - BinClassMethodDescription meth; - meth.addr = Core()->getOffset(); - - EditMethodDialog::newMethod(className, meth); + EditMethodDialog::newMethod(className, QString(), this); } void ClassesWidget::on_editMethodAction_triggered() @@ -608,8 +607,7 @@ void ClassesWidget::on_editMethodAction_triggered() if (!index.isValid() || index.data(ClassesModel::TypeRole).toInt() != static_cast(ClassesModel::RowType::Method)) { return; } - QString className = index.parent().data(ClassesModel::NameRole).toString(); - BinClassMethodDescription meth = index.data(ClassesModel::DataRole).value(); - EditMethodDialog::editMethod(className, meth); + QString methName = index.data(ClassesModel::NameRole).toString(); + EditMethodDialog::editMethod(className, methName, this); }