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);
}
void CutterCore::setClassMethod(const QString &className, const ClassMethodDescription &meth)
void CutterCore::setClassMethod(const QString &className, const BinClassMethodDescription &meth)
{
RAnalMethod analMeth;
analMeth.name = strdup (meth.name.toUtf8().constData());
@ -1891,7 +1891,7 @@ QList<BinClassDescription> CutterCore::getAllClassesFromBin()
for (const QJsonValue &value2 : classObject[RJsonKey::methods].toArray()) {
QJsonObject methObject = value2.toObject();
ClassMethodDescription meth;
BinClassMethodDescription meth;
meth.name = methObject[RJsonKey::name].toString();
meth.addr = methObject[RJsonKey::addr].toVariant().toULongLong();
@ -1902,7 +1902,7 @@ QList<BinClassDescription> CutterCore::getAllClassesFromBin()
for (const QJsonValue &value2 : classObject[RJsonKey::fields].toArray()) {
QJsonObject fieldObject = value2.toObject();
ClassFieldDescription field;
BinClassFieldDescription field;
field.name = fieldObject[RJsonKey::name].toString();
field.addr = fieldObject[RJsonKey::addr].toVariant().toULongLong();
@ -1967,7 +1967,7 @@ QList<BinClassDescription> CutterCore::getAllClassesFromFlags()
classDesc = it.value();
}
ClassMethodDescription meth;
BinClassMethodDescription meth;
meth.name = match.captured(2);
meth.addr = flagObject[RJsonKey::offset].toVariant().toULongLong();
classDesc->methods << meth;
@ -1977,7 +1977,7 @@ QList<BinClassDescription> CutterCore::getAllClassesFromFlags()
return ret;
}
QList<QString> CutterCore::getAllClassesFromAnal()
QList<QString> CutterCore::getAllAnalClasses()
{
QList<QString> ret;
@ -1985,6 +1985,7 @@ QList<QString> CutterCore::getAllClassesFromAnal()
if (!l) {
return ret;
}
ret.reserve(static_cast<int>(l->length));
SdbListIter *it;
void *entry;
@ -1997,6 +1998,72 @@ QList<QString> CutterCore::getAllClassesFromAnal()
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()
{
CORE_LOCK();
@ -2037,7 +2104,7 @@ QList<VTableDescription> CutterCore::getAllVTables()
for (const QJsonValue &methodValue : methodArray) {
QJsonObject methodObject = methodValue.toObject();
ClassMethodDescription method;
BinClassMethodDescription method;
method.addr = methodObject[RJsonKey::offset].toVariant().toULongLong();
method.name = methodObject[RJsonKey::name].toString();

View File

@ -20,6 +20,10 @@
#define CutterRListForeach(list, it, type, x) \
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 Core() (CutterCore::getInstance())
@ -251,18 +255,18 @@ struct DisassemblyLine {
QString text;
};
struct ClassBaseClassDescription {
struct BinClassBaseClassDescription {
QString name;
RVA offset;
};
struct ClassMethodDescription {
struct BinClassMethodDescription {
QString name;
RVA addr = RVA_INVALID;
st64 vtableOffset = -1;
};
struct ClassFieldDescription {
struct BinClassFieldDescription {
QString name;
RVA addr = RVA_INVALID;
};
@ -272,9 +276,27 @@ struct BinClassDescription {
RVA addr = RVA_INVALID;
RVA vtableAddr = RVA_INVALID;
ut64 index = 0;
QList<ClassBaseClassDescription> baseClasses;
QList<ClassMethodDescription> methods;
QList<ClassFieldDescription> fields;
QList<BinClassBaseClassDescription> baseClasses;
QList<BinClassMethodDescription> methods;
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 {
@ -288,7 +310,7 @@ struct ResourcesDescription {
struct VTableDescription {
RVA addr;
QList<ClassMethodDescription> methods;
QList<BinClassMethodDescription> methods;
};
struct BlockDescription {
@ -363,12 +385,12 @@ Q_DECLARE_METATYPE(RBinPluginDescription)
Q_DECLARE_METATYPE(RIOPluginDescription)
Q_DECLARE_METATYPE(RCorePluginDescription)
Q_DECLARE_METATYPE(RAsmPluginDescription)
Q_DECLARE_METATYPE(ClassMethodDescription)
Q_DECLARE_METATYPE(ClassFieldDescription)
Q_DECLARE_METATYPE(BinClassMethodDescription)
Q_DECLARE_METATYPE(BinClassFieldDescription)
Q_DECLARE_METATYPE(BinClassDescription)
Q_DECLARE_METATYPE(const BinClassDescription *)
Q_DECLARE_METATYPE(const ClassMethodDescription *)
Q_DECLARE_METATYPE(const ClassFieldDescription *)
Q_DECLARE_METATYPE(const BinClassMethodDescription *)
Q_DECLARE_METATYPE(const BinClassFieldDescription *)
Q_DECLARE_METATYPE(ResourcesDescription)
Q_DECLARE_METATYPE(VTableDescription)
Q_DECLARE_METATYPE(TypeDescription)
@ -455,7 +477,7 @@ public:
void setCurrentBits(int bits, RVA offset = RVA_INVALID);
/* 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);
/* File related methods */
@ -619,7 +641,6 @@ public:
QList<EntrypointDescription> getAllEntrypoint();
QList<BinClassDescription> getAllClassesFromBin();
QList<BinClassDescription> getAllClassesFromFlags();
QList<QString> getAllClassesFromAnal();
QList<ResourcesDescription> getAllResources();
QList<VTableDescription> getAllVTables();
@ -662,6 +683,11 @@ public:
QJsonObject getRegisterJson();
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,
const QString &filterType = QString::null);

View File

@ -74,7 +74,7 @@ void EditMethodDialog::setClass(const QString &className)
validateInput();
}
void EditMethodDialog::setMethod(const ClassMethodDescription &meth)
void EditMethodDialog::setMethod(const BinClassMethodDescription &meth)
{
ui->nameEdit->setText(meth.name);
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;
}
ClassMethodDescription EditMethodDialog::getMethod()
BinClassMethodDescription EditMethodDialog::getMethod()
{
ClassMethodDescription ret;
BinClassMethodDescription ret;
ret.name = ui->nameEdit->text();
ret.addr = Core()->num(ui->addressEdit->text());
if (ui->virtualCheckBox->isChecked()) {
@ -113,7 +113,7 @@ ClassMethodDescription EditMethodDialog::getMethod()
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);
dialog->setWindowTitle(title);
@ -124,7 +124,7 @@ bool EditMethodDialog::showDialog(const QString &title, const QString &className
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)) {
return;
@ -132,7 +132,7 @@ void EditMethodDialog::newMethod(const QString &className, ClassMethodDescriptio
Core()->setClassMethod(className, meth);
}
void EditMethodDialog::editMethod(const QString &className, ClassMethodDescription meth)
void EditMethodDialog::editMethod(const QString &className, BinClassMethodDescription meth)
{
QString oldName = meth.name;
if (!showDialog(tr("Edit Method"), className, &meth)) {

View File

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

View File

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

View File

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

View File

@ -77,7 +77,8 @@ private:
public:
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();
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) {
case Qt::DisplayRole:
switch (index.column()) {
@ -189,7 +189,7 @@ void VTablesWidget::on_vTableTreeView_doubleClicked(const QModelIndex &index)
QModelIndex parent = index.parent();
if (parent.isValid()) {
Core()->seek(index.data(
VTableModel::VTableDescriptionRole).value<ClassMethodDescription>().addr);
VTableModel::VTableDescriptionRole).value<BinClassMethodDescription>().addr);
} else {
Core()->seek(index.data(
VTableModel::VTableDescriptionRole).value<VTableDescription>().addr);