Make EditMethodDialog Method Loading work

This commit is contained in:
Florian Märkl 2019-02-01 21:40:34 +01:00
parent 159d04e4c5
commit 7bdc28d07d
5 changed files with 84 additions and 61 deletions

View File

@ -538,23 +538,6 @@ void CutterCore::setCurrentBits(int bits, RVA offset)
emit instructionChanged(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) void CutterCore::seek(ut64 offset)
{ {
// Slower than using the API, but the API is not complete // Slower than using the API, but the API is not complete
@ -2067,6 +2050,36 @@ QList<AnalVTableDescription> CutterCore::getAnalClassVTables(const QString &cls)
return ret; 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<ResourcesDescription> CutterCore::getAllResources() QList<ResourcesDescription> CutterCore::getAllResources()
{ {
CORE_LOCK(); CORE_LOCK();

View File

@ -480,8 +480,13 @@ public:
void setCurrentBits(int bits, RVA offset = RVA_INVALID); void setCurrentBits(int bits, RVA offset = RVA_INVALID);
/* Classes */ /* Classes */
void setClassMethod(const QString &className, const BinClassMethodDescription &meth); QList<QString> getAllAnalClasses();
void renameClassMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName); QList<AnalMethodDescription> getAnalClassMethods(const QString &cls);
QList<AnalBaseClassDescription> getAnalClassBaseClasses(const QString &cls);
QList<AnalVTableDescription> 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 */ /* File related methods */
bool loadFile(QString path, ut64 baddr = 0LL, ut64 mapaddr = 0LL, int perms = R_PERM_R, bool loadFile(QString path, ut64 baddr = 0LL, ut64 mapaddr = 0LL, int perms = R_PERM_R,
@ -686,11 +691,6 @@ public:
QJsonObject getRegisterJson(); QJsonObject getRegisterJson();
QList<VariableDescription> getVariables(RVA at); QList<VariableDescription> getVariables(RVA at);
QList<QString> getAllAnalClasses();
QList<AnalMethodDescription> getAnalClassMethods(const QString &cls);
QList<AnalBaseClassDescription> getAnalClassBaseClasses(const QString &cls);
QList<AnalVTableDescription> getAnalClassVTables(const QString &cls);
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function,
const QString &filterType = QString::null); const QString &filterType = QString::null);

View File

@ -9,9 +9,9 @@ EditMethodDialog::EditMethodDialog(QWidget *parent) :
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
ui->classComboBox->clear(); ui->classComboBox->clear();
/* TODO for (auto &cls : Core()->getAllClassesFromAnal()) { for (auto &cls : Core()->getAllAnalClasses()) {
ui->classComboBox->addItem(cls.name, QVariant::fromValue<BinClassDescription>(cls)); ui->classComboBox->addItem(cls, cls);
}*/ }
updateVirtualUI(); updateVirtualUI();
validateInput(); validateInput();
@ -64,8 +64,8 @@ void EditMethodDialog::setClass(const QString &className)
} }
for (int i=0; i<ui->classComboBox->count(); i++) { for (int i=0; i<ui->classComboBox->count(); i++) {
BinClassDescription cls = ui->classComboBox->itemData(i).value<BinClassDescription>(); QString cls = ui->classComboBox->itemData(i).toString();
if (cls.name == className) { if (cls == className) {
ui->classComboBox->setCurrentIndex(i); ui->classComboBox->setCurrentIndex(i);
break; break;
} }
@ -74,14 +74,14 @@ void EditMethodDialog::setClass(const QString &className)
validateInput(); validateInput();
} }
void EditMethodDialog::setMethod(const BinClassMethodDescription &meth) void EditMethodDialog::setMethod(const AnalMethodDescription &desc)
{ {
ui->nameEdit->setText(meth.name); ui->nameEdit->setText(desc.name);
ui->addressEdit->setText(meth.addr != RVA_INVALID ? RAddressString(meth.addr) : nullptr); ui->addressEdit->setText(desc.addr != RVA_INVALID ? RAddressString(desc.addr) : nullptr);
if (meth.vtableOffset >= 0) { if (desc.vtableOffset >= 0) {
ui->virtualCheckBox->setChecked(true); ui->virtualCheckBox->setChecked(true);
ui->vtableOffsetEdit->setText(QString::number(meth.vtableOffset)); ui->vtableOffsetEdit->setText(QString::number(desc.vtableOffset));
} else { } else {
ui->virtualCheckBox->setChecked(false); ui->virtualCheckBox->setChecked(false);
ui->vtableOffsetEdit->setText(nullptr); ui->vtableOffsetEdit->setText(nullptr);
@ -100,9 +100,9 @@ QString EditMethodDialog::getClass()
return ui->classComboBox->itemData(index).value<BinClassDescription>().name; return ui->classComboBox->itemData(index).value<BinClassDescription>().name;
} }
BinClassMethodDescription EditMethodDialog::getMethod() AnalMethodDescription EditMethodDialog::getMethod()
{ {
BinClassMethodDescription ret; AnalMethodDescription ret;
ret.name = ui->nameEdit->text(); ret.name = ui->nameEdit->text();
ret.addr = Core()->num(ui->addressEdit->text()); ret.addr = Core()->num(ui->addressEdit->text());
if (ui->virtualCheckBox->isChecked()) { if (ui->virtualCheckBox->isChecked()) {
@ -113,33 +113,45 @@ BinClassMethodDescription EditMethodDialog::getMethod()
return ret; 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); auto dialog = new EditMethodDialog(parent);
dialog->setWindowTitle(title); dialog->setWindowTitle(title);
dialog->setClass(className); dialog->setClass(*className);
dialog->setMethod(*meth); dialog->setMethod(*desc);
int result = dialog->exec(); int result = dialog->exec();
*meth = dialog->getMethod(); *className = dialog->getClass();
*desc = dialog->getMethod();
return result == QDialog::DialogCode::Accepted; 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; return;
} }
Core()->setClassMethod(className, meth);
}
void EditMethodDialog::editMethod(const QString &className, BinClassMethodDescription meth) Core()->setAnalMethod(className, desc);
}
void EditMethodDialog::editMethod(const QString &className, const QString &meth, QWidget *parent)
{ {
QString oldName = meth.name; AnalMethodDescription desc;
if (!showDialog(tr("Edit Method"), className, &meth)) { if (!Core()->getAnalMethod(className, meth, &desc)) {
return; 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);
} }

View File

@ -19,14 +19,14 @@ public:
~EditMethodDialog(); ~EditMethodDialog();
void setClass(const QString &className); void setClass(const QString &className);
void setMethod(const BinClassMethodDescription &meth); void setMethod(const AnalMethodDescription &desc);
QString getClass(); QString getClass();
BinClassMethodDescription getMethod(); AnalMethodDescription getMethod();
static bool showDialog(const QString &title, const QString &className, BinClassMethodDescription *meth, QWidget *parent = nullptr); static bool showDialog(const QString &title, QString *className, AnalMethodDescription *desc, QWidget *parent = nullptr);
static void newMethod(const QString &className = nullptr, BinClassMethodDescription meth = BinClassMethodDescription()); static void newMethod(QString className = nullptr, const QString &meth = QString(), QWidget *parent = nullptr);
static void editMethod(const QString &className, BinClassMethodDescription meth); static void editMethod(const QString &className, const QString &meth, QWidget *parent = nullptr);
private slots: private slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();

View File

@ -321,6 +321,8 @@ QVariant AnalClassesModel::data(const QModelIndex &index, int role) const
} }
case TypeRole: case TypeRole:
return QVariant::fromValue(RowType::Class); return QVariant::fromValue(RowType::Class);
case NameRole:
return cls;
default: default:
return QVariant(); return QVariant();
} }
@ -596,10 +598,7 @@ void ClassesWidget::on_addMethodAction_triggered()
className = index.parent().data(ClassesModel::NameRole).toString(); className = index.parent().data(ClassesModel::NameRole).toString();
} }
BinClassMethodDescription meth; EditMethodDialog::newMethod(className, QString(), this);
meth.addr = Core()->getOffset();
EditMethodDialog::newMethod(className, meth);
} }
void ClassesWidget::on_editMethodAction_triggered() void ClassesWidget::on_editMethodAction_triggered()
@ -608,8 +607,7 @@ void ClassesWidget::on_editMethodAction_triggered()
if (!index.isValid() || index.data(ClassesModel::TypeRole).toInt() != static_cast<int>(ClassesModel::RowType::Method)) { if (!index.isValid() || index.data(ClassesModel::TypeRole).toInt() != static_cast<int>(ClassesModel::RowType::Method)) {
return; return;
} }
QString className = index.parent().data(ClassesModel::NameRole).toString(); QString className = index.parent().data(ClassesModel::NameRole).toString();
BinClassMethodDescription meth = index.data(ClassesModel::DataRole).value<BinClassMethodDescription>(); QString methName = index.data(ClassesModel::NameRole).toString();
EditMethodDialog::editMethod(className, meth); EditMethodDialog::editMethod(className, methName, this);
} }