Add Methods to fetch Anal class attrs

This commit is contained in:
Florian Märkl 2019-01-31 17:45:58 +01:00
parent c7d582a893
commit 6087ab8016
8 changed files with 140 additions and 44 deletions

View File

@ -538,7 +538,7 @@ void CutterCore::setCurrentBits(int bits, RVA offset)
emit instructionChanged(offset); emit instructionChanged(offset);
} }
void CutterCore::setClassMethod(const QString &className, const ClassMethodDescription &meth) void CutterCore::setClassMethod(const QString &className, const BinClassMethodDescription &meth)
{ {
RAnalMethod analMeth; RAnalMethod analMeth;
analMeth.name = strdup (meth.name.toUtf8().constData()); analMeth.name = strdup (meth.name.toUtf8().constData());
@ -1891,7 +1891,7 @@ QList<BinClassDescription> CutterCore::getAllClassesFromBin()
for (const QJsonValue &value2 : classObject[RJsonKey::methods].toArray()) { for (const QJsonValue &value2 : classObject[RJsonKey::methods].toArray()) {
QJsonObject methObject = value2.toObject(); QJsonObject methObject = value2.toObject();
ClassMethodDescription meth; BinClassMethodDescription meth;
meth.name = methObject[RJsonKey::name].toString(); meth.name = methObject[RJsonKey::name].toString();
meth.addr = methObject[RJsonKey::addr].toVariant().toULongLong(); meth.addr = methObject[RJsonKey::addr].toVariant().toULongLong();
@ -1902,7 +1902,7 @@ QList<BinClassDescription> CutterCore::getAllClassesFromBin()
for (const QJsonValue &value2 : classObject[RJsonKey::fields].toArray()) { for (const QJsonValue &value2 : classObject[RJsonKey::fields].toArray()) {
QJsonObject fieldObject = value2.toObject(); QJsonObject fieldObject = value2.toObject();
ClassFieldDescription field; BinClassFieldDescription field;
field.name = fieldObject[RJsonKey::name].toString(); field.name = fieldObject[RJsonKey::name].toString();
field.addr = fieldObject[RJsonKey::addr].toVariant().toULongLong(); field.addr = fieldObject[RJsonKey::addr].toVariant().toULongLong();
@ -1967,7 +1967,7 @@ QList<BinClassDescription> CutterCore::getAllClassesFromFlags()
classDesc = it.value(); classDesc = it.value();
} }
ClassMethodDescription meth; BinClassMethodDescription meth;
meth.name = match.captured(2); meth.name = match.captured(2);
meth.addr = flagObject[RJsonKey::offset].toVariant().toULongLong(); meth.addr = flagObject[RJsonKey::offset].toVariant().toULongLong();
classDesc->methods << meth; classDesc->methods << meth;
@ -1977,7 +1977,7 @@ QList<BinClassDescription> CutterCore::getAllClassesFromFlags()
return ret; return ret;
} }
QList<QString> CutterCore::getAllClassesFromAnal() QList<QString> CutterCore::getAllAnalClasses()
{ {
QList<QString> ret; QList<QString> ret;
@ -1985,6 +1985,7 @@ QList<QString> CutterCore::getAllClassesFromAnal()
if (!l) { if (!l) {
return ret; return ret;
} }
ret.reserve(static_cast<int>(l->length));
SdbListIter *it; SdbListIter *it;
void *entry; void *entry;
@ -1997,6 +1998,72 @@ QList<QString> CutterCore::getAllClassesFromAnal()
return ret; return ret;
} }
QList<AnalMethodDescription> CutterCore::getAnalClassMethods(const QString &cls)
{
QList<AnalMethodDescription> ret;
RVector *meths = r_anal_class_method_get_all(core_->anal, cls.toUtf8().constData());
if (!meths) {
return ret;
}
ret.reserve(static_cast<int>(meths->len));
RAnalMethod *meth;
CutterRVectorForeach(meths, meth, RAnalMethod) {
AnalMethodDescription desc;
desc.name = QString::fromUtf8(meth->name);
desc.addr = meth->addr;
desc.vtableOffset = meth->vtable_offset;
}
r_vector_free(meths);
return ret;
}
QList<AnalBaseClassDescription> CutterCore::getAnalClassBaseClasses(const QString &cls)
{
QList<AnalBaseClassDescription> ret;
RVector *bases = r_anal_class_base_get_all(core_->anal, cls.toUtf8().constData());
if (!bases) {
return ret;
}
ret.reserve(static_cast<int>(bases->len));
RAnalBaseClass *base;
CutterRVectorForeach(bases, base, RAnalBaseClass) {
AnalBaseClassDescription desc;
desc.id = QString::fromUtf8(base->id);
desc.offset = base->offset;
desc.className = QString::fromUtf8(base->class_name);
}
r_vector_free(bases);
return ret;
}
QList<AnalVTableDescription> CutterCore::getAnalClassVTables(const QString &cls)
{
QList<AnalVTableDescription> ret;
RVector *vtables = r_anal_class_base_get_all(core_->anal, cls.toUtf8().constData());
if (!vtables) {
return ret;
}
ret.reserve(static_cast<int>(vtables->len));
RAnalVTable *vtable;
CutterRVectorForeach(vtables, vtable, RAnalVTable) {
AnalVTableDescription desc;
desc.id = QString::fromUtf8(vtable->id);
desc.offset = vtable->offset;
desc.addr = vtable->addr;
}
r_vector_free(vtables);
return ret;
}
QList<ResourcesDescription> CutterCore::getAllResources() QList<ResourcesDescription> CutterCore::getAllResources()
{ {
CORE_LOCK(); CORE_LOCK();
@ -2037,7 +2104,7 @@ QList<VTableDescription> CutterCore::getAllVTables()
for (const QJsonValue &methodValue : methodArray) { for (const QJsonValue &methodValue : methodArray) {
QJsonObject methodObject = methodValue.toObject(); QJsonObject methodObject = methodValue.toObject();
ClassMethodDescription method; BinClassMethodDescription method;
method.addr = methodObject[RJsonKey::offset].toVariant().toULongLong(); method.addr = methodObject[RJsonKey::offset].toVariant().toULongLong();
method.name = methodObject[RJsonKey::name].toString(); method.name = methodObject[RJsonKey::name].toString();

View File

@ -20,6 +20,10 @@
#define CutterRListForeach(list, it, type, x) \ #define CutterRListForeach(list, it, type, x) \
if (list) for (it = list->head; it && ((x=static_cast<type*>(it->data))); it = it->n) if (list) for (it = list->head; it && ((x=static_cast<type*>(it->data))); it = it->n)
#define CutterRVectorForeach(vec, it, type) \
if ((vec) && (vec)->a) \
for (it = (type *)(vec)->a; (char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); it = (type *)((char *)it + (vec)->elem_size))
#define APPNAME "Cutter" #define APPNAME "Cutter"
#define Core() (CutterCore::getInstance()) #define Core() (CutterCore::getInstance())
@ -251,18 +255,18 @@ struct DisassemblyLine {
QString text; QString text;
}; };
struct ClassBaseClassDescription { struct BinClassBaseClassDescription {
QString name; QString name;
RVA offset; RVA offset;
}; };
struct ClassMethodDescription { struct BinClassMethodDescription {
QString name; QString name;
RVA addr = RVA_INVALID; RVA addr = RVA_INVALID;
st64 vtableOffset = -1; st64 vtableOffset = -1;
}; };
struct ClassFieldDescription { struct BinClassFieldDescription {
QString name; QString name;
RVA addr = RVA_INVALID; RVA addr = RVA_INVALID;
}; };
@ -272,9 +276,27 @@ struct BinClassDescription {
RVA addr = RVA_INVALID; RVA addr = RVA_INVALID;
RVA vtableAddr = RVA_INVALID; RVA vtableAddr = RVA_INVALID;
ut64 index = 0; ut64 index = 0;
QList<ClassBaseClassDescription> baseClasses; QList<BinClassBaseClassDescription> baseClasses;
QList<ClassMethodDescription> methods; QList<BinClassMethodDescription> methods;
QList<ClassFieldDescription> fields; QList<BinClassFieldDescription> fields;
};
struct AnalMethodDescription {
QString name;
RVA addr;
st64 vtableOffset;
};
struct AnalBaseClassDescription {
QString id;
RVA offset;
QString className;
};
struct AnalVTableDescription {
QString id;
ut64 offset;
ut64 addr;
}; };
struct ResourcesDescription { struct ResourcesDescription {
@ -288,7 +310,7 @@ struct ResourcesDescription {
struct VTableDescription { struct VTableDescription {
RVA addr; RVA addr;
QList<ClassMethodDescription> methods; QList<BinClassMethodDescription> methods;
}; };
struct BlockDescription { struct BlockDescription {
@ -363,12 +385,12 @@ Q_DECLARE_METATYPE(RBinPluginDescription)
Q_DECLARE_METATYPE(RIOPluginDescription) Q_DECLARE_METATYPE(RIOPluginDescription)
Q_DECLARE_METATYPE(RCorePluginDescription) Q_DECLARE_METATYPE(RCorePluginDescription)
Q_DECLARE_METATYPE(RAsmPluginDescription) Q_DECLARE_METATYPE(RAsmPluginDescription)
Q_DECLARE_METATYPE(ClassMethodDescription) Q_DECLARE_METATYPE(BinClassMethodDescription)
Q_DECLARE_METATYPE(ClassFieldDescription) Q_DECLARE_METATYPE(BinClassFieldDescription)
Q_DECLARE_METATYPE(BinClassDescription) Q_DECLARE_METATYPE(BinClassDescription)
Q_DECLARE_METATYPE(const BinClassDescription *) Q_DECLARE_METATYPE(const BinClassDescription *)
Q_DECLARE_METATYPE(const ClassMethodDescription *) Q_DECLARE_METATYPE(const BinClassMethodDescription *)
Q_DECLARE_METATYPE(const ClassFieldDescription *) Q_DECLARE_METATYPE(const BinClassFieldDescription *)
Q_DECLARE_METATYPE(ResourcesDescription) Q_DECLARE_METATYPE(ResourcesDescription)
Q_DECLARE_METATYPE(VTableDescription) Q_DECLARE_METATYPE(VTableDescription)
Q_DECLARE_METATYPE(TypeDescription) Q_DECLARE_METATYPE(TypeDescription)
@ -455,7 +477,7 @@ 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 ClassMethodDescription &meth); void setClassMethod(const QString &className, const BinClassMethodDescription &meth);
void renameClassMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName); void renameClassMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName);
/* File related methods */ /* File related methods */
@ -619,7 +641,6 @@ public:
QList<EntrypointDescription> getAllEntrypoint(); QList<EntrypointDescription> getAllEntrypoint();
QList<BinClassDescription> getAllClassesFromBin(); QList<BinClassDescription> getAllClassesFromBin();
QList<BinClassDescription> getAllClassesFromFlags(); QList<BinClassDescription> getAllClassesFromFlags();
QList<QString> getAllClassesFromAnal();
QList<ResourcesDescription> getAllResources(); QList<ResourcesDescription> getAllResources();
QList<VTableDescription> getAllVTables(); QList<VTableDescription> getAllVTables();
@ -662,6 +683,11 @@ 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

@ -74,7 +74,7 @@ void EditMethodDialog::setClass(const QString &className)
validateInput(); validateInput();
} }
void EditMethodDialog::setMethod(const ClassMethodDescription &meth) void EditMethodDialog::setMethod(const BinClassMethodDescription &meth)
{ {
ui->nameEdit->setText(meth.name); ui->nameEdit->setText(meth.name);
ui->addressEdit->setText(meth.addr != RVA_INVALID ? RAddressString(meth.addr) : nullptr); ui->addressEdit->setText(meth.addr != RVA_INVALID ? RAddressString(meth.addr) : nullptr);
@ -100,9 +100,9 @@ QString EditMethodDialog::getClass()
return ui->classComboBox->itemData(index).value<BinClassDescription>().name; return ui->classComboBox->itemData(index).value<BinClassDescription>().name;
} }
ClassMethodDescription EditMethodDialog::getMethod() BinClassMethodDescription EditMethodDialog::getMethod()
{ {
ClassMethodDescription ret; BinClassMethodDescription 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,7 +113,7 @@ ClassMethodDescription EditMethodDialog::getMethod()
return ret; return ret;
} }
bool EditMethodDialog::showDialog(const QString &title, const QString &className, ClassMethodDescription *meth, QWidget *parent) bool EditMethodDialog::showDialog(const QString &title, const QString &className, BinClassMethodDescription *meth, QWidget *parent)
{ {
auto dialog = new EditMethodDialog(parent); auto dialog = new EditMethodDialog(parent);
dialog->setWindowTitle(title); dialog->setWindowTitle(title);
@ -124,7 +124,7 @@ bool EditMethodDialog::showDialog(const QString &title, const QString &className
return result == QDialog::DialogCode::Accepted; return result == QDialog::DialogCode::Accepted;
} }
void EditMethodDialog::newMethod(const QString &className, ClassMethodDescription meth) void EditMethodDialog::newMethod(const QString &className, BinClassMethodDescription meth)
{ {
if (!showDialog(tr("Create Method"), className, &meth)) { if (!showDialog(tr("Create Method"), className, &meth)) {
return; return;
@ -132,7 +132,7 @@ void EditMethodDialog::newMethod(const QString &className, ClassMethodDescriptio
Core()->setClassMethod(className, meth); Core()->setClassMethod(className, meth);
} }
void EditMethodDialog::editMethod(const QString &className, ClassMethodDescription meth) void EditMethodDialog::editMethod(const QString &className, BinClassMethodDescription meth)
{ {
QString oldName = meth.name; QString oldName = meth.name;
if (!showDialog(tr("Edit Method"), className, &meth)) { if (!showDialog(tr("Edit Method"), className, &meth)) {

View File

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

View File

@ -259,6 +259,8 @@ void InitialOptionsDialog::setupAndStartAnalysis(/*int level, QList<QString> adv
if (ui->scriptCheckBox->isChecked()) { if (ui->scriptCheckBox->isChecked()) {
options.script = ui->scriptLineEdit->text(); options.script = ui->scriptLineEdit->text();
} }
options.endian = getSelectedEndianness(); options.endian = getSelectedEndianness();
options.bbsize = getSelectedBBSize(); options.bbsize = getSelectedBBSize();

View File

@ -87,9 +87,9 @@ int BinClassesModel::columnCount(const QModelIndex &) const
QVariant BinClassesModel::data(const QModelIndex &index, int role) const QVariant BinClassesModel::data(const QModelIndex &index, int role) const
{ {
const BinClassDescription *cls; const BinClassDescription *cls;
const ClassMethodDescription *meth = nullptr; const BinClassMethodDescription *meth = nullptr;
const ClassFieldDescription *field = nullptr; const BinClassFieldDescription *field = nullptr;
const ClassBaseClassDescription *base = nullptr; const BinClassBaseClassDescription *base = nullptr;
if (index.internalId() == 0) { // class row if (index.internalId() == 0) { // class row
if (index.row() >= classes.count()) { if (index.row() >= classes.count()) {
return QVariant(); return QVariant();
@ -218,10 +218,10 @@ AnalClassesModel::AnalClassesModel(QObject *parent)
{ {
} }
void AnalClassesModel::setClasses(const QList<QString> &classes) void AnalClassesModel::refreshClasses()
{ {
beginResetModel(); beginResetModel();
this->classes = classes; classes = Core()->getAllAnalClasses();
endResetModel(); endResetModel();
} }
@ -273,9 +273,9 @@ int AnalClassesModel::columnCount(const QModelIndex &) const
QVariant AnalClassesModel::data(const QModelIndex &index, int role) const QVariant AnalClassesModel::data(const QModelIndex &index, int role) const
{ {
QString cls; QString cls;
const ClassMethodDescription *meth = nullptr; const BinClassMethodDescription *meth = nullptr;
const ClassFieldDescription *field = nullptr; const BinClassFieldDescription *field = nullptr;
const ClassBaseClassDescription *base = nullptr; const BinClassBaseClassDescription *base = nullptr;
if (index.internalId() == 0) { // class row if (index.internalId() == 0) { // class row
if (index.row() >= classes.count()) { if (index.row() >= classes.count()) {
return QVariant(); return QVariant();
@ -497,7 +497,7 @@ void ClassesWidget::refreshClasses()
ui->classesTreeView->setModel(anal_model); ui->classesTreeView->setModel(anal_model);
//proxy_model->setSourceModel(anal_model); //proxy_model->setSourceModel(anal_model);
} }
anal_model->setClasses(Core()->getAllClassesFromAnal()); anal_model->refreshClasses();
break; break;
} }
@ -561,7 +561,7 @@ void ClassesWidget::on_addMethodAction_triggered()
className = index.parent().data(ClassesModel::NameRole).toString(); className = index.parent().data(ClassesModel::NameRole).toString();
} }
ClassMethodDescription meth; BinClassMethodDescription meth;
meth.addr = Core()->getOffset(); meth.addr = Core()->getOffset();
EditMethodDialog::newMethod(className, meth); EditMethodDialog::newMethod(className, meth);
@ -575,6 +575,6 @@ void ClassesWidget::on_editMethodAction_triggered()
} }
QString className = index.parent().data(ClassesModel::NameRole).toString(); QString className = index.parent().data(ClassesModel::NameRole).toString();
ClassMethodDescription meth = index.data(ClassesModel::DataRole).value<ClassMethodDescription>(); BinClassMethodDescription meth = index.data(ClassesModel::DataRole).value<BinClassMethodDescription>();
EditMethodDialog::editMethod(className, meth); EditMethodDialog::editMethod(className, meth);
} }

View File

@ -77,7 +77,8 @@ private:
public: public:
explicit AnalClassesModel(QObject *parent = nullptr); explicit AnalClassesModel(QObject *parent = nullptr);
void setClasses(const QList<QString> &classes);
void refreshClasses();
}; };

View File

@ -39,7 +39,7 @@ QVariant VTableModel::data(const QModelIndex &index, int role) const
{ {
QModelIndex parent = index.parent(); QModelIndex parent = index.parent();
if (parent.isValid()) { if (parent.isValid()) {
const ClassMethodDescription &res = vtables->at(parent.row()).methods.at(index.row()); const BinClassMethodDescription &res = vtables->at(parent.row()).methods.at(index.row());
switch (role) { switch (role) {
case Qt::DisplayRole: case Qt::DisplayRole:
switch (index.column()) { switch (index.column()) {
@ -189,7 +189,7 @@ void VTablesWidget::on_vTableTreeView_doubleClicked(const QModelIndex &index)
QModelIndex parent = index.parent(); QModelIndex parent = index.parent();
if (parent.isValid()) { if (parent.isValid()) {
Core()->seek(index.data( Core()->seek(index.data(
VTableModel::VTableDescriptionRole).value<ClassMethodDescription>().addr); VTableModel::VTableDescriptionRole).value<BinClassMethodDescription>().addr);
} else { } else {
Core()->seek(index.data( Core()->seek(index.data(
VTableModel::VTableDescriptionRole).value<VTableDescription>().addr); VTableModel::VTableDescriptionRole).value<VTableDescription>().addr);