From d2e2bcd6b6bd938ff85aca45a7de4b111d31a144 Mon Sep 17 00:00:00 2001 From: billow Date: Fri, 10 Jun 2022 19:05:25 +0800 Subject: [PATCH] Convert more commands to rizin APIs (#2964) `fdj?`, `iRj`, `om.`, `psx`, `p8`, `fj` --- src/core/Cutter.cpp | 115 +++++++++++++++++---------------- src/core/Cutter.h | 4 +- src/widgets/CommentsWidget.cpp | 6 +- src/widgets/HexWidget.cpp | 14 ++-- 4 files changed, 68 insertions(+), 71 deletions(-) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index 80e41699..59306d39 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -845,15 +845,19 @@ void CutterCore::removeString(RVA addr) QString CutterCore::getString(RVA addr) { CORE_LOCK(); - char *s = (char *)returnAtSeek( - [&]() { - RzStrStringifyOpt opt = { 0 }; - opt.buffer = core->block; - opt.length = core->blocksize; - opt.encoding = rz_str_guess_encoding_from_buffer(core->block, core->blocksize); - return rz_str_stringify_raw_buffer(&opt, NULL); - }, - addr); + return getString(addr, core->blocksize, + rz_str_guess_encoding_from_buffer(core->block, core->blocksize)); +} + +QString CutterCore::getString(RVA addr, uint64_t len, RzStrEnc encoding, bool escape_nl) +{ + CORE_LOCK(); + RzStrStringifyOpt opt = {}; + opt.buffer = core->block; + opt.length = len; + opt.encoding = encoding; + opt.escape_nl = escape_nl; + char *s = (char *)returnAtSeek([&]() { return rz_str_stringify_raw_buffer(&opt, NULL); }, addr); return fromOwnedCharPtr(s); } @@ -1023,9 +1027,7 @@ void CutterCore::updateSeek() RVA CutterCore::prevOpAddr(RVA startAddr, int count) { CORE_LOCK(); - bool ok; - RVA offset = cmdRawAt(QString("/O %1").arg(count), startAddr).toULongLong(&ok, 16); - return ok ? offset : startAddr - count; + return rz_core_prevop_addr_force(core, startAddr, count); } RVA CutterCore::nextOpAddr(RVA startAddr, int count) @@ -1322,17 +1324,14 @@ RVA CutterCore::getLastFunctionInstruction(RVA addr) return lastBB ? rz_analysis_block_get_op_addr(lastBB, lastBB->ninstr - 1) : RVA_INVALID; } -QString CutterCore::cmdFunctionAt(QString addr) +QString CutterCore::flagAt(RVA addr) { - QString ret; - // Use cmd because cmdRaw would not work with grep - ret = cmd(QString("fd @ %1~[0]").arg(addr)); - return ret.trimmed(); -} - -QString CutterCore::cmdFunctionAt(RVA addr) -{ - return cmdFunctionAt(QString::number(addr)); + CORE_LOCK(); + RzFlagItem *f = rz_flag_get_at(core->flags, addr, true); + if (!f) { + return {}; + } + return core->flags->realnames && f->realname ? f->realname : f->name; } void CutterCore::cmdEsil(const char *command) @@ -2035,7 +2034,7 @@ void CutterCore::attachRemote(const QString &uri) [&](RzCore *core) { setConfig("cfg.debug", true); rz_core_file_reopen_remote_debug(core, uri.toStdString().c_str(), 0); - return (void *)NULL; + return nullptr; }, debugTask)) { return; @@ -2043,9 +2042,7 @@ void CutterCore::attachRemote(const QString &uri) emit debugTaskStateChanged(); connect(debugTask.data(), &RizinTask::finished, this, [this, uri]() { - if (debugTaskDialog) { - delete debugTaskDialog; - } + delete debugTaskDialog; debugTask.clear(); // Check if we actually connected bool connected = false; @@ -3536,10 +3533,8 @@ QList CutterCore::getAllClassesFromFlags() QList ret; QMap classesCache; - for (const CutterJson flagObject : cmdj("fj@F:classes")) { - QString flagName = flagObject[RJsonKey::name].toString(); - - QRegularExpressionMatch match = classFlagRegExp.match(flagName); + for (const auto &item : getAllFlags("classes")) { + QRegularExpressionMatch match = classFlagRegExp.match(item.name); if (match.hasMatch()) { QString className = match.captured(1); BinClassDescription *desc = nullptr; @@ -3553,12 +3548,12 @@ QList CutterCore::getAllClassesFromFlags() desc = it.value(); } desc->name = match.captured(1); - desc->addr = flagObject[RJsonKey::offset].toRVA(); + desc->addr = item.offset; desc->index = RVA_INVALID; continue; } - match = methodFlagRegExp.match(flagName); + match = methodFlagRegExp.match(item.name); if (match.hasMatch()) { QString className = match.captured(1); BinClassDescription *classDesc = nullptr; @@ -3578,7 +3573,7 @@ QList CutterCore::getAllClassesFromFlags() BinClassMethodDescription meth; meth.name = match.captured(2); - meth.addr = flagObject[RJsonKey::offset].toRVA(); + meth.addr = item.offset; classDesc->methods << meth; continue; } @@ -3745,21 +3740,27 @@ void CutterCore::renameAnalysisMethod(const QString &className, const QString &o QList CutterCore::getAllResources() { CORE_LOCK(); - QList resources; - - for (CutterJson resourceObject : cmdj("iRj")) { - ResourcesDescription res; - - res.name = resourceObject[RJsonKey::name].toString(); - res.vaddr = resourceObject[RJsonKey::vaddr].toRVA(); - res.index = resourceObject[RJsonKey::index].toUt64(); - res.type = resourceObject[RJsonKey::type].toString(); - res.size = resourceObject[RJsonKey::size].toUt64(); - res.lang = resourceObject[RJsonKey::lang].toString(); - - resources << res; + RzBinFile *bf = rz_bin_cur(core->bin); + if (!bf) { + return {}; } - return resources; + const RzList *resources = rz_bin_object_get_resources(bf->o); + QList resourcesDescriptions; + + RzBinResource *r; + RzListIter *it; + CutterRzListForeach (resources, it, RzBinResource, r) { + ResourcesDescription description; + description.name = r->name; + description.vaddr = r->vaddr; + description.index = r->index; + description.type = r->type; + description.size = r->size; + description.lang = r->language; + resourcesDescriptions << description; + } + + return resourcesDescriptions; } QList CutterCore::getAllVTables() @@ -3867,8 +3868,8 @@ QString CutterCore::getTypeAsC(QString name) bool CutterCore::isAddressMapped(RVA addr) { - // If value returned by "om. @ addr" is empty means that address is not mapped - return !Core()->cmdRawAt(QString("om."), addr).isEmpty(); + CORE_LOCK(); + return rz_io_map_get(core->io, addr); } QList CutterCore::getAllSearch(QString searchFor, QString space, QString in) @@ -3966,7 +3967,7 @@ QList CutterCore::getXRefs(RVA addr, bool to, bool whole_functi } xd.from_str = RzAddressString(xd.from); - xd.to_str = Core()->cmdRaw(QString("fd %1").arg(xd.to)).trimmed(); + xd.to_str = Core()->flagAt(xd.to); xrefList << xd; } @@ -3997,13 +3998,15 @@ QString CutterCore::listFlagsAsStringAt(RVA addr) QString CutterCore::nearestFlag(RVA offset, RVA *flagOffsetOut) { - auto r = cmdj(QString("fdj @ ") + QString::number(offset)); - QString name = r["name"].toString(); - if (flagOffsetOut) { - auto offsetValue = r["offset"]; - *flagOffsetOut = offsetValue.valid() ? offsetValue.toRVA() : offset; + CORE_LOCK(); + auto r = rz_flag_get_at(core->flags, offset, true); + if (!r) { + return {}; } - return name; + if (flagOffsetOut) { + *flagOffsetOut = r->offset; + } + return r->name; } void CutterCore::handleREvent(int type, void *data) diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 45cde76d..607fb7b2 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -237,8 +237,7 @@ public: RVA getFunctionStart(RVA addr); RVA getFunctionEnd(RVA addr); RVA getLastFunctionInstruction(RVA addr); - QString cmdFunctionAt(QString addr); - QString cmdFunctionAt(RVA addr); + QString flagAt(RVA addr); void createFunctionAt(RVA addr); void createFunctionAt(RVA addr, QString name); QStringList getDisassemblyPreview(RVA address, int num_of_lines); @@ -297,6 +296,7 @@ public: * @return string at requested address */ QString getString(RVA addr); + QString getString(RVA addr, uint64_t len, RzStrEnc encoding, bool escape_nl = false); void setToData(RVA addr, int size, int repeat = 1); int sizeofDataMeta(RVA addr); diff --git a/src/widgets/CommentsWidget.cpp b/src/widgets/CommentsWidget.cpp index ddb4bbb9..cf7bea12 100644 --- a/src/widgets/CommentsWidget.cpp +++ b/src/widgets/CommentsWidget.cpp @@ -128,7 +128,7 @@ QVariant CommentsModel::data(const QModelIndex &index, int role) const case CommentsModel::OffsetColumn: return RzAddressString(comment.offset); case CommentsModel::FunctionColumn: - return Core()->cmdFunctionAt(comment.offset); + return Core()->flagAt(comment.offset); case CommentsModel::CommentColumn: return comment.name; default: @@ -220,8 +220,8 @@ bool CommentsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &ri case CommentsModel::OffsetColumn: return leftComment.offset < rightComment.offset; case CommentsModel::FunctionColumn: - return Core()->cmdFunctionAt(leftComment.offset) - < Core()->cmdFunctionAt(rightComment.offset); + return Core()->flagAt(leftComment.offset) + < Core()->flagAt(rightComment.offset); case CommentsModel::CommentColumn: return leftComment.name < rightComment.name; default: diff --git a/src/widgets/HexWidget.cpp b/src/widgets/HexWidget.cpp index 76cc586a..39f63186 100644 --- a/src/widgets/HexWidget.cpp +++ b/src/widgets/HexWidget.cpp @@ -692,16 +692,10 @@ void HexWidget::copy() if (selection.isEmpty() || selection.size() > MAX_COPY_SIZE) return; - QClipboard *clipboard = QApplication::clipboard(); - if (cursorOnAscii) { - clipboard->setText( - Core()->cmdRawAt(QString("psx %1").arg(selection.size()), selection.start()) - .trimmed()); - } else { - clipboard->setText(Core()->cmdRawAt(QString("p8 %1").arg(selection.size()), - selection.start()) - .trimmed()); // TODO: copy in the format shown - } + auto x = cursorOnAscii + ? Core()->getString(selection.start(), selection.size(), RZ_STRING_ENC_8BIT, true) + : Core()->ioRead(selection.start(), (int)selection.size()).toHex(); + QApplication::clipboard()->setText(x); } void HexWidget::copyAddress()