mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 19:06:10 +00:00
Add Methods to fetch Anal class attrs
This commit is contained in:
parent
c7d582a893
commit
6087ab8016
@ -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();
|
||||
|
52
src/Cutter.h
52
src/Cutter.h
@ -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);
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -77,7 +77,8 @@ private:
|
||||
|
||||
public:
|
||||
explicit AnalClassesModel(QObject *parent = nullptr);
|
||||
void setClasses(const QList<QString> &classes);
|
||||
|
||||
void refreshClasses();
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user