mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 10:56:11 +00:00
Convert Rizin command calls to the API (#2968)
* `es` * `il` * `wcr` * `.ar-` * `aets-` * `drp` * `ahts` * `e <val>=?` * `fo`
This commit is contained in:
parent
aa222b53df
commit
06c8f15ce0
@ -92,7 +92,7 @@ JSDecDecompiler::JSDecDecompiler(QObject *parent) : Decompiler("jsdec", "jsdec",
|
||||
|
||||
bool JSDecDecompiler::isAvailable()
|
||||
{
|
||||
return Core()->cmdList("es").contains("jsdec");
|
||||
return Core()->getConfigVariableSpaces().contains("jsdec");
|
||||
}
|
||||
|
||||
void JSDecDecompiler::decompileAt(RVA addr)
|
||||
|
@ -1199,7 +1199,21 @@ void CutterCore::message(const QString &msg, bool debug)
|
||||
QString CutterCore::getConfig(const char *k)
|
||||
{
|
||||
CORE_LOCK();
|
||||
return QString(rz_config_get(core->config, k));
|
||||
return { rz_config_get(core->config, k) };
|
||||
}
|
||||
|
||||
QStringList CutterCore::getConfigOptions(const char *k)
|
||||
{
|
||||
CORE_LOCK();
|
||||
RzConfigNode *node = rz_config_node_get(core->config, k);
|
||||
if (!(node && node->options)) {
|
||||
return {};
|
||||
}
|
||||
QStringList list;
|
||||
for (const auto &s : CutterRzList<char>(node->options)) {
|
||||
list << s;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void CutterCore::setConfig(const char *k, const QVariant &v)
|
||||
@ -2146,11 +2160,15 @@ void CutterCore::stopDebug()
|
||||
currentlyRemoteDebugging = false;
|
||||
emit debugTaskStateChanged();
|
||||
|
||||
CORE_LOCK();
|
||||
if (currentlyEmulating) {
|
||||
cmdEsil("aeim-; aei-; wcr; .ar-; aets-");
|
||||
cmdEsil("aeim- ; aei-");
|
||||
resetWriteCache();
|
||||
rz_core_debug_clear_register_flags(core);
|
||||
rz_core_analysis_esil_trace_stop(core);
|
||||
currentlyEmulating = false;
|
||||
} else {
|
||||
rz_core_debug_process_close(core());
|
||||
rz_core_debug_process_close(core);
|
||||
currentlyAttachedToPID = -1;
|
||||
}
|
||||
|
||||
@ -2870,8 +2888,17 @@ bool CutterCore::isGraphEmpty()
|
||||
|
||||
void CutterCore::getOpcodes()
|
||||
{
|
||||
CORE_LOCK();
|
||||
this->opcodes = cmdList("?O");
|
||||
this->regs = cmdList("drp~[1]");
|
||||
|
||||
this->regs = {};
|
||||
const RzList *rs = rz_reg_get_list(core->dbg->reg, RZ_REG_TYPE_ANY);
|
||||
if (!rs) {
|
||||
return;
|
||||
}
|
||||
for (const auto &r : CutterRzList<RzRegItem>(rs)) {
|
||||
this->regs.push_back(r->name);
|
||||
}
|
||||
}
|
||||
|
||||
void CutterCore::setSettings()
|
||||
@ -4430,3 +4457,23 @@ QByteArray CutterCore::ioRead(RVA addr, int len)
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
QStringList CutterCore::getConfigVariableSpaces(const QString &key)
|
||||
{
|
||||
CORE_LOCK();
|
||||
QStringList stringList;
|
||||
for (const auto &node : CutterRzList<RzConfigNode>(core->config->nodes)) {
|
||||
stringList.push_back(node->name);
|
||||
}
|
||||
|
||||
if (!key.isEmpty()) {
|
||||
stringList = stringList.filter(QRegularExpression(QString("^%0\\..*").arg(key)));
|
||||
std::transform(stringList.begin(), stringList.end(), stringList.begin(),
|
||||
[](const QString &x) { return x.split('.').last(); });
|
||||
} else {
|
||||
std::transform(stringList.begin(), stringList.end(), stringList.begin(),
|
||||
[](const QString &x) { return x.split('.').first(); });
|
||||
}
|
||||
stringList.removeDuplicates();
|
||||
return stringList;
|
||||
}
|
||||
|
@ -393,10 +393,12 @@ public:
|
||||
QString getConfig(const char *k);
|
||||
QString getConfig(const QString &k) { return getConfig(k.toUtf8().constData()); }
|
||||
QString getConfigDescription(const char *k);
|
||||
QStringList getConfigOptions(const char *k);
|
||||
QStringList getColorThemes();
|
||||
QHash<QString, QColor> getTheme();
|
||||
QStringList getThemeKeys();
|
||||
bool setColor(const QString &key, const QString &color);
|
||||
QStringList getConfigVariableSpaces(const QString &key = "");
|
||||
|
||||
/* Assembly\Hexdump related methods */
|
||||
QByteArray assemble(const QString &code);
|
||||
|
@ -15,20 +15,21 @@
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
// Rizin list iteration macros
|
||||
#define CutterRzListForeach(list, it, type, x) \
|
||||
#define CutterRzListForeach(list, it, type, x) \
|
||||
if (list) \
|
||||
for (it = list->head; it && ((x = static_cast<type *>(it->data))); it = it->n)
|
||||
|
||||
#define CutterRzVectorForeach(vec, it, type) \
|
||||
#define CutterRzVectorForeach(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))
|
||||
|
||||
template<typename T> class CutterPVector
|
||||
template<typename T>
|
||||
class CutterPVector
|
||||
{
|
||||
private:
|
||||
const RzPVector * const vec;
|
||||
const RzPVector *const vec;
|
||||
|
||||
public:
|
||||
class iterator : public std::iterator<std::input_iterator_tag, T *>
|
||||
@ -39,10 +40,19 @@ public:
|
||||
public:
|
||||
iterator(T **p) : p(p) {}
|
||||
iterator(const iterator &o) : p(o.p) {}
|
||||
iterator &operator++() { p++; return *this; }
|
||||
iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
|
||||
bool operator==(const iterator &rhs) const {return p == rhs.p;}
|
||||
bool operator!=(const iterator &rhs) const {return p != rhs.p;}
|
||||
iterator &operator++()
|
||||
{
|
||||
p++;
|
||||
return *this;
|
||||
}
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
bool operator==(const iterator &rhs) const { return p == rhs.p; }
|
||||
bool operator!=(const iterator &rhs) const { return p != rhs.p; }
|
||||
T *operator*() { return *p; }
|
||||
};
|
||||
|
||||
@ -51,6 +61,57 @@ public:
|
||||
iterator end() const { return iterator(reinterpret_cast<T **>(vec->v.a) + vec->v.len); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CutterRzList
|
||||
{
|
||||
private:
|
||||
const RzList *const list;
|
||||
|
||||
public:
|
||||
class iterator : public std::iterator<std::input_iterator_tag, T *>
|
||||
{
|
||||
private:
|
||||
RzListIter *iter;
|
||||
|
||||
public:
|
||||
explicit iterator(RzListIter *iter) : iter(iter) {}
|
||||
iterator(const iterator &o) : iter(o.iter) {}
|
||||
iterator &operator++()
|
||||
{
|
||||
if (!iter) {
|
||||
return *this;
|
||||
}
|
||||
iter = iter->n;
|
||||
return *this;
|
||||
}
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
bool operator==(const iterator &rhs) const { return iter == rhs.iter; }
|
||||
bool operator!=(const iterator &rhs) const { return iter != rhs.iter; }
|
||||
T *operator*()
|
||||
{
|
||||
if (!iter) {
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<T *>(iter->data);
|
||||
}
|
||||
};
|
||||
|
||||
explicit CutterRzList(const RzList *l) : list(l) {}
|
||||
iterator begin() const
|
||||
{
|
||||
if (!list) {
|
||||
return iterator(nullptr);
|
||||
}
|
||||
return iterator(list->head);
|
||||
}
|
||||
iterator end() const { return iterator(nullptr); }
|
||||
};
|
||||
|
||||
// Global information for Cutter
|
||||
#define APPNAME "Cutter"
|
||||
|
||||
|
@ -641,7 +641,11 @@ void MainWindow::finalizeOpen()
|
||||
core->updateSeek();
|
||||
refreshAll();
|
||||
// Add fortune message
|
||||
core->message("\n" + core->cmdRaw("fo"));
|
||||
char *fortune = rz_core_fortune_get_random(core->core());
|
||||
if (fortune) {
|
||||
core->message("\n" + QString(fortune));
|
||||
free(fortune);
|
||||
}
|
||||
|
||||
// hide all docks before showing window to avoid false positive for refreshDeferrer
|
||||
for (auto dockWidget : dockWidgets) {
|
||||
|
@ -40,7 +40,7 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main)
|
||||
updateCPUComboBox();
|
||||
|
||||
// os combo box
|
||||
for (const auto &plugin : core->cmdList("e asm.os=?")) {
|
||||
for (const auto &plugin : Core()->getConfigOptions("asm.os")) {
|
||||
ui->kernelComboBox->addItem(plugin, plugin);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog *dialog)
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->syntaxComboBox->blockSignals(true);
|
||||
for (const auto &syntax : Core()->cmdList("e asm.syntax=?"))
|
||||
for (const auto &syntax : Core()->getConfigOptions("asm.syntax"))
|
||||
ui->syntaxComboBox->addItem(syntax, syntax);
|
||||
ui->syntaxComboBox->blockSignals(false);
|
||||
|
||||
|
@ -524,15 +524,19 @@ void DisassemblyContextMenu::aboutToShowSlot()
|
||||
structureOffsetMenu->menuAction()->setVisible(true);
|
||||
structureOffsetMenu->clear();
|
||||
|
||||
// Get the possible offsets using the "ahts" command
|
||||
// TODO: add ahtj command to Rizin and then use it here
|
||||
QStringList ret = Core()->cmdList("ahts " + QString::number(memDisp));
|
||||
for (const QString &val : ret) {
|
||||
if (val.isEmpty()) {
|
||||
continue;
|
||||
RzCoreLocked core(Core());
|
||||
RzList *typeoffs = rz_type_db_get_by_offset(core->analysis->typedb, memDisp);
|
||||
if (typeoffs) {
|
||||
for (const auto &ty : CutterRzList<RzTypePath>(typeoffs)) {
|
||||
if (RZ_STR_ISEMPTY(ty->path)) {
|
||||
continue;
|
||||
}
|
||||
structureOffsetMenu->addAction("[" + memBaseReg + " + " + ty->path + "]")
|
||||
->setData(ty->path);
|
||||
}
|
||||
structureOffsetMenu->addAction("[" + memBaseReg + " + " + val + "]")->setData(val);
|
||||
rz_list_free(typeoffs);
|
||||
}
|
||||
|
||||
if (structureOffsetMenu->isEmpty()) {
|
||||
// No possible offset was found so hide the menu
|
||||
structureOffsetMenu->menuAction()->setVisible(false);
|
||||
|
@ -220,8 +220,7 @@ bool CommentsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &ri
|
||||
case CommentsModel::OffsetColumn:
|
||||
return leftComment.offset < rightComment.offset;
|
||||
case CommentsModel::FunctionColumn:
|
||||
return Core()->flagAt(leftComment.offset)
|
||||
< Core()->flagAt(rightComment.offset);
|
||||
return Core()->flagAt(leftComment.offset) < Core()->flagAt(rightComment.offset);
|
||||
case CommentsModel::CommentColumn:
|
||||
return leftComment.name < rightComment.name;
|
||||
default:
|
||||
|
@ -122,12 +122,6 @@ void Dashboard::updateContents()
|
||||
setPlainText(ui->codeSizeLineEdit, QString::number(analinfo["codesz"].toSt64()) + " bytes");
|
||||
setPlainText(ui->percentageLineEdit, QString::number(analinfo["percent"].toSt64()) + "%");
|
||||
|
||||
QStringList libs = Core()->cmdList("il");
|
||||
if (!libs.isEmpty()) {
|
||||
libs.removeFirst();
|
||||
libs.removeLast();
|
||||
}
|
||||
|
||||
// dunno: why not label->setText(lines.join("\n")?
|
||||
while (ui->verticalLayout_2->count() > 0) {
|
||||
QLayoutItem *item = ui->verticalLayout_2->takeAt(0);
|
||||
@ -141,12 +135,15 @@ void Dashboard::updateContents()
|
||||
}
|
||||
}
|
||||
|
||||
for (const QString &lib : libs) {
|
||||
QLabel *label = new QLabel(this);
|
||||
label->setText(lib);
|
||||
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
label->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
ui->verticalLayout_2->addWidget(label);
|
||||
const RzList *libs = rz_bin_object_get_libs(bf->o);
|
||||
if (libs) {
|
||||
for (const auto &lib : CutterRzList<char>(libs)) {
|
||||
auto *label = new QLabel(this);
|
||||
label->setText(lib);
|
||||
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
label->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
ui->verticalLayout_2->addWidget(label);
|
||||
}
|
||||
}
|
||||
|
||||
QSpacerItem *spacer = new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
|
Loading…
Reference in New Issue
Block a user