diff --git a/src/common/BugReporting.cpp b/src/common/BugReporting.cpp index 7d5ec919..18aa36ef 100644 --- a/src/common/BugReporting.cpp +++ b/src/common/BugReporting.cpp @@ -8,26 +8,18 @@ void openIssue() { + RzCoreLocked core(Core()); + RzBinFile *bf = rz_bin_cur(core->bin); + RzBinInfo *info = rz_bin_get_info(core->bin); + RzBinPlugin *plugin = rz_bin_file_cur_plugin(bf); + QString url, osInfo, format, arch, type; // Pull in info needed for git issue osInfo = QSysInfo::productType() + " " + (QSysInfo::productVersion() == "unknown" ? "" : QSysInfo::productVersion()); - CutterJson docu = Core()->getFileInfo(); - CutterJson coreObj = docu["core"]; - CutterJson binObj = docu["bin"]; - if (binObj.size()) { - format = coreObj["format"].toString(); - arch = binObj["arch"].toString(); - if (binObj["type"].valid()) { - type = coreObj["type"].toString(); - } else { - type = "N/A"; - } - } else { - format = coreObj["format"].toString(); - arch = "N/A"; - type = "N/A"; - } + format = plugin && RZ_STR_ISNOTEMPTY(plugin->name) ? plugin->name : "N/A"; + arch = info && RZ_STR_ISNOTEMPTY(info->arch) ? info->arch : "N/A"; + type = info && RZ_STR_ISNOTEMPTY(info->type) ? info->type : "N/A"; url = "https://github.com/rizinorg/cutter/issues/new?&body=**Environment information**\n* " "Operating System: " + osInfo + "\n* Cutter version: " + CUTTER_VERSION_FULL + "\n* Obtained from:\n" diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index 61882cfc..f3c0f0de 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -681,7 +681,7 @@ bool CutterCore::mapFile(QString path, RVA mapaddr) { CORE_LOCK(); RVA addr = mapaddr != RVA_INVALID ? mapaddr : 0; - ut64 baddr = Core()->getFileInfo()["bin"]["baddr"].toUt64(); + ut64 baddr = rz_bin_get_baddr(core->bin); if (rz_core_file_open(core, path.toUtf8().constData(), RZ_PERM_RX, addr)) { rz_core_bin_load(core, path.toUtf8().constData(), baddr); } else { @@ -1434,16 +1434,6 @@ bool CutterCore::registerDecompiler(Decompiler *decompiler) return true; } -CutterJson CutterCore::getFileInfo() -{ - return cmdj("ij"); -} - -CutterJson CutterCore::getFileVersionInfo() -{ - return cmdj("iVj"); -} - QString CutterCore::getSignatureInfo() { CORE_LOCK(); @@ -1456,9 +1446,23 @@ QString CutterCore::getSignatureInfo() if (!signature) { return {}; } + auto sig = parseJson(signature, nullptr); + if (sig.size() == 0) { + return {}; + } return fromOwnedCharPtr(signature); } +bool CutterCore::existsFileInfo() +{ + CORE_LOCK(); + const RzBinInfo *info = rz_bin_get_info(core->bin); + if (!(info && info->rclass)) { + return false; + } + return strncmp("pe", info->rclass, 2) == 0 || strncmp("elf", info->rclass, 3) == 0; +} + // Utility function to check if a telescoped item exists and add it with prefixes to the desc static inline const QString appendVar(QString &dst, const QString val, const QString prepend_val, const QString append_val) @@ -2133,9 +2137,15 @@ void CutterCore::attachDebug(int pid) offsetPriorDebugging = getOffset(); } - QString attach_command = currentlyOpenFile.isEmpty() ? "o" : "oodf"; - // attach to process with dbg plugin - asyncCmd("e cfg.debug=true;" + attach_command + " dbg://" + QString::number(pid), debugTask); + CORE_LOCK(); + setConfig("cfg.debug", true); + auto uri = rz_str_newf("dbg://%d", pid); + if (currentlyOpenFile.isEmpty()) { + rz_core_file_open_load(core, uri, 0, RZ_PERM_R, false); + } else { + rz_core_file_reopen_remote_debug(core, uri, 0); + } + free(uri); emit debugTaskStateChanged(); @@ -2189,7 +2199,8 @@ void CutterCore::stopDebug() CORE_LOCK(); if (currentlyEmulating) { - cmdEsil("aeim- ; aei-"); + rz_core_analysis_esil_init_mem_del(core, NULL, UT64_MAX, UT32_MAX); + rz_core_analysis_esil_deinit(core); resetWriteCache(); rz_core_debug_clear_register_flags(core); rz_core_analysis_esil_trace_stop(core); @@ -3173,21 +3184,38 @@ QList CutterCore::getAllImports() QList CutterCore::getAllExports() { CORE_LOCK(); - QList ret; - - for (CutterJson exportObject : cmdj("iEj")) { - ExportDescription exp; - - exp.vaddr = exportObject[RJsonKey::vaddr].toRVA(); - exp.paddr = exportObject[RJsonKey::paddr].toRVA(); - exp.size = exportObject[RJsonKey::size].toRVA(); - exp.type = exportObject[RJsonKey::type].toString(); - exp.name = exportObject[RJsonKey::name].toString(); - exp.flag_name = exportObject[RJsonKey::flagname].toString(); - - ret << exp; + RzBinFile *bf = rz_bin_cur(core->bin); + if (!bf) { + return {}; + } + const RzList *symbols = rz_bin_object_get_symbols(bf->o); + if (!symbols) { + return {}; } + QString lang = getConfigi("bin.demangle") ? getConfig("bin.lang") : ""; + bool va = core->io->va || core->bin->is_debugger; + + QList ret; + for (const auto &symbol : CutterRzList(symbols)) { + if (!(symbol->name && rz_core_sym_is_export(symbol))) { + continue; + } + + RzBinSymNames sn = {}; + rz_core_sym_name_init(core, &sn, symbol, lang.isEmpty() ? NULL : lang.toUtf8().constData()); + + ExportDescription exportDescription; + exportDescription.vaddr = rva(bf->o, symbol->paddr, symbol->vaddr, va); + exportDescription.paddr = symbol->paddr; + exportDescription.size = symbol->size; + exportDescription.type = symbol->type; + exportDescription.name = sn.symbolname; + exportDescription.flag_name = sn.nameflag; + ret << exportDescription; + + rz_core_sym_name_fini(&sn); + } return ret; } @@ -3343,22 +3371,37 @@ QList CutterCore::getAllRelocs() QList CutterCore::getAllStrings() { - return parseStringsJson(cmdjTask("izzj")); -} + CORE_LOCK(); + RzBinFile *bf = rz_bin_cur(core->bin); + if (!bf) { + return {}; + } + RzBinObject *obj = rz_bin_cur_object(core->bin); + if (!obj) { + return {}; + } + RzList *l = rz_core_bin_whole_strings(core, bf); + if (!l) { + return {}; + } + + int va = core->io->va || core->bin->is_debugger; + RzStrEscOptions opt = {}; + opt.show_asciidot = false; + opt.esc_bslash = true; + opt.esc_double_quotes = true; -QList CutterCore::parseStringsJson(const CutterJson &doc) -{ QList ret; + for (const auto &str : CutterRzList(l)) { + auto section = obj ? rz_bin_get_section_at(obj, str->paddr, 0) : NULL; - for (CutterJson value : doc) { StringDescription string; - - string.string = value[RJsonKey::string].toString(); - string.vaddr = value[RJsonKey::vaddr].toRVA(); - string.type = value[RJsonKey::type].toString(); - string.size = value[RJsonKey::size].toUt64(); - string.length = value[RJsonKey::length].toUt64(); - string.section = value[RJsonKey::section].toString(); + string.string = rz_str_escape_utf8_keep_printable(str->string, &opt); + string.vaddr = obj ? rva(obj, str->paddr, str->vaddr, va) : str->paddr; + string.type = str->type; + string.size = str->size; + string.length = str->length; + string.section = section ? section->name : ""; ret << string; } @@ -3917,8 +3960,7 @@ QString CutterCore::getTypeAsC(QString name) return output; } char *earg = rz_cmd_escape_arg(name.toUtf8().constData(), RZ_CMD_ESCAPE_ONE_ARG); - // TODO: use API for `tc` command once available - QString result = cmd(QString("tc %1").arg(earg)); + QString result = fromOwnedCharPtr(rz_core_types_as_c(core, earg, true)); free(earg); return result; } @@ -4495,19 +4537,15 @@ QByteArray CutterCore::ioRead(RVA addr, int len) QStringList CutterCore::getConfigVariableSpaces(const QString &key) { CORE_LOCK(); - QStringList stringList; - for (const auto &node : CutterRzList(core->config->nodes)) { - stringList.push_back(node->name); + RzList *list = rz_core_config_in_space(core, key.toUtf8().constData()); + if (!list) { + return {}; } - 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(); }); + QStringList stringList; + for (const auto &x : CutterRzList(list)) { + stringList << x; } - stringList.removeDuplicates(); + rz_list_free(list); return stringList; } diff --git a/src/core/Cutter.h b/src/core/Cutter.h index b5be0ff8..9aa90b18 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -569,9 +569,8 @@ public: bool registerDecompiler(Decompiler *decompiler); RVA getOffsetJump(RVA addr); - CutterJson getFileInfo(); QString getSignatureInfo(); - CutterJson getFileVersionInfo(); + bool existsFileInfo(); void setGraphEmpty(bool empty); bool isGraphEmpty(); @@ -688,8 +687,6 @@ public: QList getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType = QString()); - QList parseStringsJson(const CutterJson &doc); - void handleREvent(int type, void *data); /* Signals related */ diff --git a/src/dialogs/VersionInfoDialog.cpp b/src/dialogs/VersionInfoDialog.cpp index 7e67d594..dd43f23e 100644 --- a/src/dialogs/VersionInfoDialog.cpp +++ b/src/dialogs/VersionInfoDialog.cpp @@ -23,145 +23,213 @@ VersionInfoDialog::~VersionInfoDialog() {} void VersionInfoDialog::fillVersionInfo() { - - CutterJson doc = Core()->getFileVersionInfo(); - + RzCoreLocked core(Core()); + const RzBinInfo *info = rz_bin_get_info(core->bin); + if (!info || !info->rclass) { + return; + } // Case ELF - if (doc["verneed"].valid()) { - CutterJson verneed = doc["verneed"].first(); - CutterJson versym = doc["versym"].first(); - + if (strncmp("elf", info->rclass, 3) == 0) { // Set labels ui->leftLabel->setText("Version symbols"); ui->rightLabel->setText("Version need"); - // Left tree - QTreeWidgetItem *secNameItemL = new QTreeWidgetItem(); - secNameItemL->setText(0, "Section name:"); - secNameItemL->setText(1, versym["section_name"].toString()); - ui->leftTreeWidget->addTopLevelItem(secNameItemL); + Sdb *sdb = sdb_ns_path(core->sdb, "bin/cur/info/versioninfo/versym", 0); + if (!sdb) { + return; + } + // Left tree QTreeWidgetItem *addrItemL = new QTreeWidgetItem(); addrItemL->setText(0, "Address:"); - addrItemL->setText(1, RzAddressString(versym["address"].toRVA())); + addrItemL->setText(1, RzAddressString(sdb_num_get(sdb, "addr", 0))); ui->leftTreeWidget->addTopLevelItem(addrItemL); QTreeWidgetItem *offItemL = new QTreeWidgetItem(); offItemL->setText(0, "Offset:"); - offItemL->setText(1, RzAddressString(versym["offset"].toRVA())); + offItemL->setText(1, RzAddressString(sdb_num_get(sdb, "offset", 0))); ui->leftTreeWidget->addTopLevelItem(offItemL); - QTreeWidgetItem *linkItemL = new QTreeWidgetItem(); - linkItemL->setText(0, "Link:"); - linkItemL->setText(1, QString::number(versym["link"].toRVA())); - ui->leftTreeWidget->addTopLevelItem(linkItemL); - - QTreeWidgetItem *linkNameItemL = new QTreeWidgetItem(); - linkNameItemL->setText(0, "Link section name:"); - linkNameItemL->setText(1, versym["link_section_name"].toString()); - ui->leftTreeWidget->addTopLevelItem(linkNameItemL); - QTreeWidgetItem *entriesItemL = new QTreeWidgetItem(); entriesItemL->setText(0, "Entries:"); - for (CutterJson obj : versym["entries"]) { - QTreeWidgetItem *tempItem = new QTreeWidgetItem(); - tempItem->setText(0, RzAddressString(obj["idx"].toRVA())); - tempItem->setText(1, obj["value"].toString()); - entriesItemL->addChild(tempItem); + const ut64 num_entries = sdb_num_get(sdb, "num_entries", 0); + for (size_t i = 0; i < num_entries; ++i) { + auto key = QString("entry%0").arg(i); + const char *const value = sdb_const_get(sdb, key.toStdString().c_str(), 0); + if (!value) { + continue; + } + auto item = new QTreeWidgetItem(); + item->setText(0, RzAddressString(i)); + item->setText(1, value); + entriesItemL->addChild(item); } ui->leftTreeWidget->addTopLevelItem(entriesItemL); // Adjust columns to content qhelpers::adjustColumns(ui->leftTreeWidget, 0); + sdb = sdb_ns_path(core->sdb, "bin/cur/info/versioninfo/verneed", 0); // Right tree - QTreeWidgetItem *secNameItemR = new QTreeWidgetItem(); - secNameItemR->setText(0, "Section name:"); - secNameItemR->setText(1, verneed["section_name"].toString()); - ui->rightTreeWidget->addTopLevelItem(secNameItemR); - QTreeWidgetItem *addrItemR = new QTreeWidgetItem(); addrItemR->setText(0, "Address:"); - addrItemR->setText(1, RzAddressString(verneed["address"].toRVA())); + addrItemR->setText(1, RzAddressString(sdb_num_get(sdb, "addr", 0))); ui->rightTreeWidget->addTopLevelItem(addrItemR); QTreeWidgetItem *offItemR = new QTreeWidgetItem(); offItemR->setText(0, "Offset:"); - offItemR->setText(1, RzAddressString(verneed["offset"].toRVA())); + offItemR->setText(1, RzAddressString(sdb_num_get(sdb, "offset", 0))); ui->rightTreeWidget->addTopLevelItem(offItemR); - QTreeWidgetItem *linkItemR = new QTreeWidgetItem(); - linkItemR->setText(0, "Link:"); - linkItemR->setText(1, QString::number(verneed["link"].toSt64())); - ui->rightTreeWidget->addTopLevelItem(linkItemR); - - QTreeWidgetItem *linkNameItemR = new QTreeWidgetItem(); - linkNameItemR->setText(0, "Link section name:"); - linkNameItemR->setText(1, verneed["link_section_name"].toString()); - ui->rightTreeWidget->addTopLevelItem(linkNameItemR); - QTreeWidgetItem *entriesItemR = new QTreeWidgetItem(); entriesItemR->setText(0, "Entries:"); - for (CutterJson parentObj : verneed["entries"]) { - QTreeWidgetItem *parentItem = new QTreeWidgetItem(); - QString parentString; - parentItem->setText(0, RzAddressString(parentObj["idx"].toRVA())); - parentString.append("Version: " + QString::number(parentObj["vn_version"].toSt64()) - + "\t"); - parentString.append("File: " + parentObj["file_name"].toString()); - parentItem->setText(1, parentString); + for (size_t num_version = 0;; num_version++) { + auto path_version = + QString("bin/cur/info/versioninfo/verneed/version%0").arg(num_version); + sdb = sdb_ns_path(core->sdb, path_version.toStdString().c_str(), 0); + if (!sdb) { + break; + } + const char *filename = sdb_const_get(sdb, "file_name", 0); + auto *parentItem = new QTreeWidgetItem(); + parentItem->setText(0, RzAddressString(sdb_num_get(sdb, "idx", 0))); + parentItem->setText(1, + QString("Version: %0\t" + "File: %1") + .arg(QString::number(sdb_num_get(sdb, "vn_version", 0)), + QString(filename))); - for (CutterJson childObj : parentObj["vernaux"]) { - QTreeWidgetItem *childItem = new QTreeWidgetItem(); - QString childString; - childItem->setText(0, RzAddressString(childObj["idx"].toRVA())); - childString.append("Name: " + childObj["name"].toString() + "\t"); - childString.append("Flags: " + childObj["flags"].toString() + "\t"); - childString.append("Version: " + QString::number(childObj["version"].toSt64())); + int num_vernaux = 0; + while (true) { + auto path_vernaux = + QString("%0/vernaux%1").arg(path_version, QString::number(num_vernaux++)); + sdb = sdb_ns_path(core->sdb, path_vernaux.toStdString().c_str(), 0); + if (!sdb) { + break; + } + + auto *childItem = new QTreeWidgetItem(); + childItem->setText(0, RzAddressString(sdb_num_get(sdb, "idx", 0))); + QString childString = + QString("Name: %0\t" + "Flags: %1\t" + "Version: %2\t") + .arg(sdb_const_get(sdb, "name", 0), sdb_const_get(sdb, "flags", 0), + QString::number(sdb_num_get(sdb, "version", 0))); childItem->setText(1, childString); parentItem->addChild(childItem); } entriesItemR->addChild(parentItem); } - ui->rightTreeWidget->addTopLevelItem(entriesItemR); + ui->rightTreeWidget->addTopLevelItem(entriesItemR); // Adjust columns to content qhelpers::adjustColumns(ui->rightTreeWidget, 0); - } - // Case PE - else if (doc["VS_FIXEDFILEINFO"].valid()) { - CutterJson vs = doc["VS_FIXEDFILEINFO"]; - CutterJson strings = doc["StringTable"]; - + else if (strncmp("pe", info->rclass, 2) == 0) { // Set labels ui->leftLabel->setText("VS Fixed file info"); ui->rightLabel->setText("String table"); + Sdb *sdb = NULL; // Left tree - for (CutterJson property : vs) { - QTreeWidgetItem *tempItem = new QTreeWidgetItem(); - tempItem->setText(0, property.key()); - if (property.type() == RZ_JSON_INTEGER) - tempItem->setText(1, RzHexString(property.toRVA())); - else - tempItem->setText(1, property.toString()); - ui->leftTreeWidget->addTopLevelItem(tempItem); - - // Adjust columns to content - qhelpers::adjustColumns(ui->leftTreeWidget, 0); + auto path_version = QString("bin/cur/info/vs_version_info/VS_VERSIONINFO%0").arg(0); + auto path_fixedfileinfo = QString("%0/fixed_file_info").arg(path_version); + sdb = sdb_ns_path(core->sdb, path_fixedfileinfo.toStdString().c_str(), 0); + if (!sdb) { + return; } + ut32 file_version_ms = sdb_num_get(sdb, "FileVersionMS", 0); + ut32 file_version_ls = sdb_num_get(sdb, "FileVersionLS", 0); + auto file_version = QString("%0.%1.%2.%3") + .arg(file_version_ms >> 16) + .arg(file_version_ms & 0xFFFF) + .arg(file_version_ls >> 16) + .arg(file_version_ls & 0xFFFF); + ut32 product_version_ms = sdb_num_get(sdb, "ProductVersionMS", 0); + ut32 product_version_ls = sdb_num_get(sdb, "ProductVersionLS", 0); + auto product_version = QString("%0.%1.%2.%3") + .arg(product_version_ms >> 16) + .arg(product_version_ms & 0xFFFF) + .arg(product_version_ls >> 16) + .arg(product_version_ls & 0xFFFF); + + auto item = new QTreeWidgetItem(); + item->setText(0, "Signature"); + item->setText(1, RzHexString(sdb_num_get(sdb, "Signature", 0))); + ui->leftTreeWidget->addTopLevelItem(item); + + item = new QTreeWidgetItem(); + item->setText(0, "StrucVersion"); + item->setText(1, RzHexString(sdb_num_get(sdb, "StrucVersion", 0))); + ui->leftTreeWidget->addTopLevelItem(item); + + item = new QTreeWidgetItem(); + item->setText(0, "FileVersion"); + item->setText(1, file_version); + ui->leftTreeWidget->addTopLevelItem(item); + + item = new QTreeWidgetItem(); + item->setText(0, "ProductVersion"); + item->setText(1, product_version); + ui->leftTreeWidget->addTopLevelItem(item); + + item = new QTreeWidgetItem(); + item->setText(0, "FileFlagsMask"); + item->setText(1, RzHexString(sdb_num_get(sdb, "FileFlagsMask", 0))); + ui->leftTreeWidget->addTopLevelItem(item); + + item = new QTreeWidgetItem(); + item->setText(0, "FileFlags"); + item->setText(1, RzHexString(sdb_num_get(sdb, "FileFlags", 0))); + ui->leftTreeWidget->addTopLevelItem(item); + + item = new QTreeWidgetItem(); + item->setText(0, "FileOS"); + item->setText(1, RzHexString(sdb_num_get(sdb, "FileOS", 0))); + ui->leftTreeWidget->addTopLevelItem(item); + + item = new QTreeWidgetItem(); + item->setText(0, "FileType"); + item->setText(1, RzHexString(sdb_num_get(sdb, "FileType", 0))); + ui->leftTreeWidget->addTopLevelItem(item); + + item = new QTreeWidgetItem(); + item->setText(0, "FileSubType"); + item->setText(1, RzHexString(sdb_num_get(sdb, "FileSubType", 0))); + ui->leftTreeWidget->addTopLevelItem(item); + + // Adjust columns to content + qhelpers::adjustColumns(ui->leftTreeWidget, 0); // Right tree - for (CutterJson property : strings) { - QTreeWidgetItem *tempItem = new QTreeWidgetItem(); - tempItem->setText(0, property.key()); - tempItem->setText(1, property.toString()); - ui->rightTreeWidget->addTopLevelItem(tempItem); - - // Adjust columns to content - qhelpers::adjustColumns(ui->rightTreeWidget, 0); + for (int num_stringtable = 0;; num_stringtable++) { + auto path_stringtable = QString("%0/string_file_info/stringtable%1") + .arg(path_version) + .arg(num_stringtable); + sdb = sdb_ns_path(core->sdb, path_stringtable.toStdString().c_str(), 0); + if (!sdb) { + break; + } + for (int num_string = 0; sdb; num_string++) { + auto path_string = QString("%0/string%1").arg(path_stringtable).arg(num_string); + sdb = sdb_ns_path(core->sdb, path_string.toStdString().c_str(), 0); + if (!sdb) { + continue; + } + int lenkey = 0; + int lenval = 0; + ut8 *key_utf16 = sdb_decode(sdb_const_get(sdb, "key", 0), &lenkey); + ut8 *val_utf16 = sdb_decode(sdb_const_get(sdb, "value", 0), &lenval); + item = new QTreeWidgetItem(); + item->setText(0, QString::fromUtf16(reinterpret_cast(key_utf16))); + item->setText(1, QString::fromUtf16(reinterpret_cast(val_utf16))); + ui->rightTreeWidget->addTopLevelItem(item); + free(key_utf16); + free(val_utf16); + } } + qhelpers::adjustColumns(ui->rightTreeWidget, 0); } } diff --git a/src/widgets/Dashboard.cpp b/src/widgets/Dashboard.cpp index 66265d43..3715bc36 100644 --- a/src/widgets/Dashboard.cpp +++ b/src/widgets/Dashboard.cpp @@ -32,24 +32,27 @@ Dashboard::~Dashboard() {} void Dashboard::updateContents() { - CutterJson docu = Core()->getFileInfo(); - CutterJson item = docu["core"]; - CutterJson item2 = docu["bin"]; + RzCoreLocked core(Core()); + int fd = rz_io_fd_get_current(core->io); + RzIODesc *desc = rz_io_desc_get(core->io, fd); + setPlainText(this->ui->modeEdit, desc ? rz_str_rwx_i(desc->perm & RZ_PERM_RWX) : ""); - setPlainText(this->ui->modeEdit, item["mode"].toString()); - setPlainText(this->ui->compilationDateEdit, item2["compiled"].toString()); - - if (!item2["relro"].toString().isEmpty()) { - QString relro = item2["relro"].toString().section(QLatin1Char(' '), 0, 0); - relro[0] = relro[0].toUpper(); - setPlainText(this->ui->relroEdit, relro); - } else { - setPlainText(this->ui->relroEdit, "N/A"); + RzBinFile *bf = rz_bin_cur(core->bin); + if (bf) { + setPlainText(this->ui->compilationDateEdit, rz_core_bin_get_compile_time(bf)); + if (bf->o) { + char *relco_buf = sdb_get(bf->o->kv, "elf.relro", 0); + if (RZ_STR_ISNOTEMPTY(relco_buf)) { + QString relro = QString(relco_buf).section(QLatin1Char(' '), 0, 0); + relro[0] = relro[0].toUpper(); + setPlainText(this->ui->relroEdit, relro); + } else { + setPlainText(this->ui->relroEdit, "N/A"); + } + } } // Add file hashes, analysis info and libraries - RzCoreLocked core(Core()); - RzBinFile *bf = rz_bin_cur(core->bin); RzBinInfo *binInfo = rz_bin_get_info(core->bin); setPlainText(ui->fileEdit, binInfo ? binInfo->file : ""); @@ -111,16 +114,25 @@ void Dashboard::updateContents() hashesLayout->addRow(new QLabel(label), hashLineEdit); } - CutterJson analinfo = Core()->cmdj("aaij"); - setPlainText(ui->functionsLineEdit, QString::number(analinfo["fcns"].toSt64())); - setPlainText(ui->xRefsLineEdit, QString::number(analinfo["xrefs"].toSt64())); - setPlainText(ui->callsLineEdit, QString::number(analinfo["calls"].toSt64())); - setPlainText(ui->stringsLineEdit, QString::number(analinfo["strings"].toSt64())); - setPlainText(ui->symbolsLineEdit, QString::number(analinfo["symbols"].toSt64())); - setPlainText(ui->importsLineEdit, QString::number(analinfo["imports"].toSt64())); - setPlainText(ui->coverageLineEdit, QString::number(analinfo["covrage"].toSt64()) + " bytes"); - setPlainText(ui->codeSizeLineEdit, QString::number(analinfo["codesz"].toSt64()) + " bytes"); - setPlainText(ui->percentageLineEdit, QString::number(analinfo["percent"].toSt64()) + "%"); + st64 fcns = rz_list_length(core->analysis->fcns); + st64 strs = rz_flag_count(core->flags, "str.*"); + st64 syms = rz_flag_count(core->flags, "sym.*"); + st64 imps = rz_flag_count(core->flags, "sym.imp.*"); + st64 code = rz_core_analysis_code_count(core); + st64 covr = rz_core_analysis_coverage_count(core); + st64 call = rz_core_analysis_calls_count(core); + ut64 xrfs = rz_analysis_xrefs_count(core->analysis); + double precentage = (code > 0) ? (covr * 100.0 / code) : 0; + + setPlainText(ui->functionsLineEdit, QString::number(fcns)); + setPlainText(ui->xRefsLineEdit, QString::number(xrfs)); + setPlainText(ui->callsLineEdit, QString::number(call)); + setPlainText(ui->stringsLineEdit, QString::number(strs)); + setPlainText(ui->symbolsLineEdit, QString::number(syms)); + setPlainText(ui->importsLineEdit, QString::number(imps)); + setPlainText(ui->coverageLineEdit, QString::number(covr) + " bytes"); + setPlainText(ui->codeSizeLineEdit, QString::number(code) + " bytes"); + setPlainText(ui->percentageLineEdit, QString::number(precentage) + "%"); // dunno: why not label->setText(lines.join("\n")? while (ui->verticalLayout_2->count() > 0) { @@ -153,9 +165,7 @@ void Dashboard::updateContents() if (Core()->getSignatureInfo().isEmpty()) { ui->certificateButton->setEnabled(false); } - if (!Core()->getFileVersionInfo().size()) { - ui->versioninfoButton->setEnabled(false); - } + ui->versioninfoButton->setEnabled(Core()->existsFileInfo()); } void Dashboard::on_certificateButton_clicked() diff --git a/src/widgets/FunctionsWidget.cpp b/src/widgets/FunctionsWidget.cpp index 6324467b..b59cfb34 100644 --- a/src/widgets/FunctionsWidget.cpp +++ b/src/widgets/FunctionsWidget.cpp @@ -564,7 +564,18 @@ void FunctionsWidget::refreshTree() importAddresses.insert(import.plt); } - mainAdress = (ut64)Core()->cmdj("iMj")["vaddr"].toUt64(); + mainAdress = RVA_INVALID; + RzCoreLocked core(Core()); + RzBinFile *bf = rz_bin_cur(core->bin); + if (bf) { + const RzBinAddr *binmain = + rz_bin_object_get_special_symbol(bf->o, RZ_BIN_SPECIAL_SYMBOL_MAIN); + if (binmain) { + int va = core->io->va || core->bin->is_debugger; + mainAdress = va ? rz_bin_object_addr_with_base(bf->o, binmain->vaddr) + : binmain->paddr; + } + } functionModel->updateCurrentIndex(); functionModel->endResetModel(); diff --git a/src/widgets/TypesWidget.cpp b/src/widgets/TypesWidget.cpp index 8e7a0e6e..ebdeace1 100644 --- a/src/widgets/TypesWidget.cpp +++ b/src/widgets/TypesWidget.cpp @@ -259,6 +259,10 @@ void TypesWidget::showTypesContextMenu(const QPoint &pt) void TypesWidget::on_actionExport_Types_triggered() { + char *str = rz_core_types_as_c_all(Core()->core(), true); + if (!str) { + return; + } QString filename = QFileDialog::getSaveFileName(this, tr("Save File"), Config()->getRecentFolder()); if (filename.isEmpty()) { @@ -272,8 +276,8 @@ void TypesWidget::on_actionExport_Types_triggered() return; } QTextStream fileOut(&file); - // TODO: use API for `tc` command once available - fileOut << Core()->cmd("tc"); + fileOut << str; + free(str); file.close(); }