diff --git a/.appveyor.yml b/.appveyor.yml index 49221f5c..ef25be60 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: '2.3.2-git-{build}' +version: '2.2.0-git-{build}' image: 'Visual Studio 2017' clone_depth: 1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b07860e..771bddf1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,8 @@ if(NOT CUTTER_ENABLE_PYTHON) endif() set(CUTTER_VERSION_MAJOR 2) -set(CUTTER_VERSION_MINOR 3) -set(CUTTER_VERSION_PATCH 2) +set(CUTTER_VERSION_MINOR 2) +set(CUTTER_VERSION_PATCH 0) set(CUTTER_VERSION "${CUTTER_VERSION_MAJOR}.${CUTTER_VERSION_MINOR}.${CUTTER_VERSION_PATCH}") diff --git a/cmake/BundledRizin.cmake b/cmake/BundledRizin.cmake index 10816039..1c030690 100644 --- a/cmake/BundledRizin.cmake +++ b/cmake/BundledRizin.cmake @@ -57,7 +57,7 @@ endif() # TODO: This version number should be fetched automatically # instead of being hardcoded. -set (Rizin_VERSION 0.6) +set (Rizin_VERSION 0.7) set (RZ_LIBS rz_core rz_config rz_cons rz_io rz_util rz_flag rz_asm rz_debug rz_hash rz_bin rz_lang rz_il rz_analysis rz_parse rz_bp rz_egg rz_reg diff --git a/cmake/Translations.cmake b/cmake/Translations.cmake index c8e5dfce..a57a8797 100644 --- a/cmake/Translations.cmake +++ b/cmake/Translations.cmake @@ -1,5 +1,6 @@ set(TS_FILES translations/ar/cutter_ar.ts + translations/bn/cutter_bn.ts translations/ca/cutter_ca.ts translations/de/cutter_de.ts translations/es-ES/cutter_es.ts @@ -8,6 +9,7 @@ set(TS_FILES translations/he/cutter_he.ts translations/hi/cutter_hi.ts translations/it/cutter_it.ts + translations/ko/cutter_ko.ts translations/ja/cutter_ja.ts translations/nl/cutter_nl.ts translations/pt-PT/cutter_pt.ts @@ -15,9 +17,10 @@ set(TS_FILES translations/ru/cutter_ru.ts translations/tr/cutter_tr.ts translations/uk/cutter_uk.ts + translations/ur-PK/cutter_ur.ts translations/zh-CN/cutter_zh.ts + translations/vi/cutter_vi.ts ) -# translations/ko/cutter_ko.ts problems with fonts # translations/pt-BR/cutter_pt.ts #2321 handling multiple versions of a language set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/translations) diff --git a/dist/CMakeLists.txt b/dist/CMakeLists.txt index acae42d6..2fe5b671 100644 --- a/dist/CMakeLists.txt +++ b/dist/CMakeLists.txt @@ -188,9 +188,9 @@ if(CUTTER_PACKAGE_RZ_GHIDRA) # installed Cutter. ExternalProject_Add(rz-ghidra GIT_REPOSITORY https://github.com/rizinorg/rz-ghidra - GIT_TAG v0.6.0 + #GIT_TAG v0.3.0 #GIT_TAG c7a50a2e7c0a95cd52b167c9ee0fa1805223f08e - #GIT_TAG dev + GIT_TAG dev #GIT_SHALLOW ON # disable this line when using commit hash CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/dist/bundle_jsdec.ps1 b/dist/bundle_jsdec.ps1 index a25d6ae6..64466a7c 100644 --- a/dist/bundle_jsdec.ps1 +++ b/dist/bundle_jsdec.ps1 @@ -2,10 +2,10 @@ $dist = $args[0] $python = Split-Path((Get-Command python.exe).Path) if (-not (Test-Path -Path 'jsdec' -PathType Container)) { - git clone https://github.com/rizinorg/jsdec.git --depth 1 --branch "v0.6.0" + git clone https://github.com/rizinorg/jsdec.git --depth 1 --branch "v0.7.0" } cd jsdec -& meson.exe --buildtype=release -Dc_args=-DDUK_USE_DATE_NOW_WINDOWS -Djsc_folder=".." --prefix="$dist" p build +& meson.exe --buildtype=release --prefix="$dist" build ninja -C build install $ErrorActionPreference = 'Stop' $pathdll = "$dist\lib\rizin\plugins\core_pdd.dll" diff --git a/docs/source/building.rst b/docs/source/building.rst index 762cdd31..7520fd96 100644 --- a/docs/source/building.rst +++ b/docs/source/building.rst @@ -85,8 +85,14 @@ On Arch-based Linux distributions: :: + # When building with CUTTER_ENABLE_KSYNTAXHIGHLIGHTING (Default) + sudo pacman -Syu --needed syntax-highlighting + # When building with CUTTER_ENABLE_GRAPHVIZ (Default) + sudo pacman -Syu --needed graphviz + sudo pacman -Syu --needed base-devel cmake meson qt5-base qt5-svg qt5-tools + On dnf/yum based distributions: :: diff --git a/docs/source/conf.py b/docs/source/conf.py index 043c6d6f..34af39b1 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -24,9 +24,9 @@ copyright = '2020, The Cutter Developers' author = 'The Cutter Developers' # The short X.Y version -version = '2.3' +version = '2.2' # The full version, including a2lpha/beta/rc tags -release = '2.3.2' +release = '2.2.0' # -- General configuration --------------------------------------------------- diff --git a/rizin b/rizin index 18b12434..78d4043a 160000 --- a/rizin +++ b/rizin @@ -1 +1 @@ -Subproject commit 18b1243435df428b58bcefc4ec37aef558aab96e +Subproject commit 78d4043afb39a56fe91ea7ab03c83da613319cc3 diff --git a/scripts/jsdec.sh b/scripts/jsdec.sh index 966c605a..c084133c 100755 --- a/scripts/jsdec.sh +++ b/scripts/jsdec.sh @@ -6,14 +6,15 @@ SCRIPTPATH=$(realpath "$(dirname "${BASH_SOURCE[0]}")") cd "$SCRIPTPATH/.." -if [[ ! -d jsdec ]]; then - git clone https://github.com/rizinorg/jsdec.git --depth 1 --branch "v0.6.0" +if [ ! -d jsdec ]; then + git clone https://github.com/rizinorg/jsdec.git --depth 1 --branch "v0.7.0" fi cd jsdec -rm -rf build -mkdir build && cd build -meson --buildtype=release -Djsc_folder="../" "$@" ../p -ninja -ninja install +if [ -d build ]; then + rm -rf build +fi +meson --buildtype=release "$@" build +ninja -C build +ninja -C build install diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a753548..ad69522e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -429,33 +429,7 @@ if(CUTTER_ENABLE_PYTHON_BINDINGS) include_directories("${BINDINGS_BUILD_DIR}/CutterBindings") - set(SHIBOKEN_INCLUDE_DIRS "") - if(APPLE AND _qt6Core_install_prefix) - list(APPEND BINDINGS_INCLUDE_DIRS "${_qt6Core_install_prefix}/include") - list(APPEND BINDINGS_INCLUDE_DIRS "${_qt6Core_install_prefix}/include/QtCore") - list(APPEND BINDINGS_INCLUDE_DIRS "${_qt6Core_install_prefix}/include/QtGui") - list(APPEND BINDINGS_INCLUDE_DIRS "${_qt6Core_install_prefix}/include/QtWidgets") - endif() - - if (CUTTER_QT6) - list(APPEND SHIBOKEN_INCLUDE_DIRS ${Qt6Core_INCLUDE_DIRS} ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Gui_INCLUDE_DIRS}) - else() - list(APPEND SHIBOKEN_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS}) - endif() - - foreach(_dir ${CUTTER_INCLUDE_DIRECTORIES}) - list(APPEND SHIBOKEN_INCLUDE_DIRS - $ - $ - ) - endforeach() - list(APPEND SHIBOKEN_INCLUDE_DIRS ${Rizin_INCLUDE_DIRS}) - if (NOT WIN32) - string(REPLACE ";" ":" SHIBOKEN_INCLUDE_DIRS "${SHIBOKEN_INCLUDE_DIRS}") - endif() - set(SHIBOKEN_OPTIONS) - list(APPEND SHIBOKEN_OPTIONS --include-paths="${SHIBOKEN_INCLUDE_DIRS}") if (WIN32) list(APPEND SHIBOKEN_OPTIONS --avoid-protected-hack) endif() @@ -558,11 +532,16 @@ if(CUTTER_ENABLE_PYTHON) endif() endforeach() - if(APPLE AND _qt5Core_install_prefix) - list(APPEND BINDINGS_INCLUDE_DIRS "${_qt5Core_install_prefix}/include") - list(APPEND BINDINGS_INCLUDE_DIRS "${_qt5Core_install_prefix}/include/QtCore") - list(APPEND BINDINGS_INCLUDE_DIRS "${_qt5Core_install_prefix}/include/QtGui") - list(APPEND BINDINGS_INCLUDE_DIRS "${_qt5Core_install_prefix}/include/QtWidgets") + set(BINDINGS_INCLUDE_DIR_LINES "") + if(APPLE) + if (_qt5Core_install_prefix) + list(APPEND BINDINGS_INCLUDE_DIRS "${_qt5Core_install_prefix}/include") + list(APPEND BINDINGS_INCLUDE_DIRS "${_qt5Core_install_prefix}/include/QtCore") + list(APPEND BINDINGS_INCLUDE_DIRS "${_qt5Core_install_prefix}/include/QtGui") + list(APPEND BINDINGS_INCLUDE_DIRS "${_qt5Core_install_prefix}/include/QtWidgets") + elseif(CUTTER_QT6) + string(APPEND BINDINGS_INCLUDE_DIR_LINES "framework-include-path=${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBS}\n") + endif() endif() if (CUTTER_QT6) list(APPEND BINDINGS_INCLUDE_DIRS ${Qt6Core_INCLUDE_DIRS} ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Gui_INCLUDE_DIRS}) @@ -571,9 +550,12 @@ if(CUTTER_ENABLE_PYTHON) endif() list(APPEND BINDINGS_INCLUDE_DIRS ${Rizin_INCLUDE_DIRS}) list(APPEND BINDINGS_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}") - if (NOT WIN32) - string(REPLACE ";" ":" BINDINGS_INCLUDE_DIRS "${BINDINGS_INCLUDE_DIRS}") - endif() + + foreach(_dir ${BINDINGS_INCLUDE_DIRS}) + if (NOT "${_dir}" STREQUAL "") + string(APPEND BINDINGS_INCLUDE_DIR_LINES "include-path = ${_dir}\n") + endif() + endforeach() configure_file("${BINDINGS_SRC_DIR}/bindings.txt.in" "${BINDINGS_BUILD_DIR}/bindings.txt") add_definitions(-DWIN32_LEAN_AND_MEAN) diff --git a/src/bindings/bindings.txt.in b/src/bindings/bindings.txt.in index 5eb103ee..57ee1c4a 100644 --- a/src/bindings/bindings.txt.in +++ b/src/bindings/bindings.txt.in @@ -7,7 +7,7 @@ typesystem-file = ${BINDINGS_BUILD_DIR}/bindings.xml output-directory = ${BINDINGS_BUILD_DIR} -include-path = ${BINDINGS_INCLUDE_DIRS} +${BINDINGS_INCLUDE_DIR_LINES} typesystem-paths = ${PYSIDE_TYPESYSTEMS} diff --git a/src/bindings/bindings.xml.in b/src/bindings/bindings.xml.in index 0fa194a9..c20aea67 100644 --- a/src/bindings/bindings.xml.in +++ b/src/bindings/bindings.xml.in @@ -14,6 +14,7 @@ + diff --git a/src/common/CommandTask.cpp b/src/common/CommandTask.cpp index c027cab1..0366aaf2 100644 --- a/src/common/CommandTask.cpp +++ b/src/common/CommandTask.cpp @@ -2,8 +2,7 @@ #include "CommandTask.h" #include "TempConfig.h" -CommandTask::CommandTask(const QString &cmd, ColorMode colorMode, bool outFormatHtml) - : cmd(cmd), colorMode(colorMode), outFormatHtml(outFormatHtml) +CommandTask::CommandTask(const QString &cmd, ColorMode colorMode) : cmd(cmd), colorMode(colorMode) { } @@ -12,8 +11,5 @@ void CommandTask::runTask() TempConfig tempConfig; tempConfig.set("scr.color", colorMode); auto res = Core()->cmdTask(cmd); - if (outFormatHtml) { - res = CutterCore::ansiEscapeToHtml(res); - } emit finished(res); } diff --git a/src/common/CommandTask.h b/src/common/CommandTask.h index 24a74a5b..15136699 100644 --- a/src/common/CommandTask.h +++ b/src/common/CommandTask.h @@ -17,8 +17,7 @@ public: MODE_16M = COLOR_MODE_16M }; - CommandTask(const QString &cmd, ColorMode colorMode = ColorMode::DISABLED, - bool outFormatHtml = false); + CommandTask(const QString &cmd, ColorMode colorMode = ColorMode::DISABLED); QString getTitle() override { return tr("Running Command"); } @@ -31,7 +30,6 @@ protected: private: QString cmd; ColorMode colorMode; - bool outFormatHtml; }; #endif // COMMANDTASK_H diff --git a/src/common/Decompiler.cpp b/src/common/Decompiler.cpp index 1868e4e4..2d9478e5 100644 --- a/src/common/Decompiler.cpp +++ b/src/common/Decompiler.cpp @@ -16,7 +16,7 @@ static char *jsonToStrdup(const CutterJson &str) if (!j || j->type != RZ_JSON_STRING) { return NULL; } - return rz_str_new(j->str_value); + return rz_str_dup(j->str_value); } static RzAnnotatedCode *parseJsonCode(CutterJson &json) diff --git a/src/common/SelectionHighlight.cpp b/src/common/SelectionHighlight.cpp index e7c2ee72..9906e2d7 100644 --- a/src/common/SelectionHighlight.cpp +++ b/src/common/SelectionHighlight.cpp @@ -7,6 +7,7 @@ #include #include #include +#include QList createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word) @@ -21,6 +22,42 @@ QList createSameWordsSelections(QPlainTextEdit *textE } highlightSelection.cursor = textEdit->textCursor(); + + if (word == "{" || word == "}") { + int val; + if (word == "{") { + val = 0; + } else { + val = 1; + } + selections.append(highlightSelection); + + while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) { + if (word == "{") { + highlightSelection.cursor = + document->find(QRegularExpression("{|}"), highlightSelection.cursor); + } else { + highlightSelection.cursor = + document->find(QRegularExpression("{|}"), highlightSelection.cursor, + QTextDocument::FindBackward); + } + + if (!highlightSelection.cursor.isNull()) { + if (highlightSelection.cursor.selectedText() == word) { + val++; + } else { + val--; + } + if (val == 0) { + highlightSelection.format.setBackground(highlightWordColor); + selections.append(highlightSelection); + break; + } + } + } + return selections; + } + highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd()) { diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index c1ce9d21..2a0db993 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -722,11 +722,10 @@ PRzAnalysisBytes CutterCore::getRzAnalysisBytesSingle(RVA addr) rz_io_read_at(core->io, addr, buf, sizeof(buf)); auto seek = seekTemp(addr); - auto vec = fromOwned(rz_core_analysis_bytes(core, buf, sizeof(buf), 1)); + auto abiter = fromOwned(rz_core_analysis_bytes(core, addr, buf, sizeof(buf), 1)); + auto ab = + abiter ? reinterpret_cast(rz_iterator_next(abiter.get())) : nullptr; - auto ab = vec && rz_pvector_len(vec.get()) > 0 - ? reinterpret_cast(rz_pvector_pop_front(vec.get())) - : nullptr; return { ab, rz_analysis_bytes_free }; } @@ -1027,18 +1026,10 @@ RVA CutterCore::nextOpAddr(RVA startAddr, int count) { CORE_LOCK(); auto seek = seekTemp(startAddr); - auto vec = - fromOwned(rz_core_analysis_bytes(core, core->block, (int)core->blocksize, count + 1)); + auto consumed = + rz_core_analysis_ops_size(core, core->offset, core->block, (int)core->blocksize, count); - RVA addr = startAddr + 1; - if (!vec) { - return addr; - } - auto ab = reinterpret_cast(rz_pvector_tail(vec.get())); - if (!(ab && ab->op)) { - return addr; - } - addr = ab->op->addr; + RVA addr = startAddr + consumed; return addr; } @@ -1666,7 +1657,7 @@ QVector CutterCore::getHeapChunks(RVA arena_addr) rz_list_free(arenas); return chunks_vector; } - m_arena = ((RzArenaListItem *)arenas->head->data)->addr; + m_arena = ((RzArenaListItem *)rz_list_get_head_data(arenas))->addr; rz_list_free(arenas); } else { m_arena = arena_addr; @@ -2372,7 +2363,9 @@ void CutterCore::continueUntilSyscall() } else { if (!asyncTask( [](RzCore *core) { - rz_cons_break_push(reinterpret_cast(rz_debug_stop), core->dbg); + rz_cons_break_push( + [](void *x) { rz_debug_stop(reinterpret_cast(x)); }, + core->dbg); rz_reg_arena_swap(core->dbg->reg, true); rz_debug_continue_syscalls(core->dbg, NULL, 0); rz_cons_break_pop(); @@ -2681,8 +2674,8 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config) moduleNameData = config.positionExpression.toUtf8(); module = moduleNameData.data(); } - breakpoint = rz_debug_bp_add(core->dbg, address, (config.hw && watchpoint_prot == 0), - watchpoint_prot, watchpoint_prot, module, config.moduleDelta); + breakpoint = rz_debug_bp_add(core->dbg, address, config.size, config.hw, (watchpoint_prot != 0), + watchpoint_prot, module, config.moduleDelta); if (!breakpoint) { QMessageBox::critical(nullptr, tr("Breakpoint error"), tr("Failed to create breakpoint")); return; @@ -2791,7 +2784,7 @@ int CutterCore::breakpointIndexAt(RVA addr) BreakpointDescription CutterCore::getBreakpointAt(RVA addr) { CORE_LOCK(); - int index = breakpointIndexAt(addr); + int index = rz_bp_get_index_at(core->dbg->bp, addr); auto bp = rz_bp_get_index(core->dbg->bp, index); if (bp) { return breakpointDescriptionFromRizin(index, bp); @@ -3107,16 +3100,14 @@ QList CutterCore::getAllImports() if (!bf) { return {}; } - const RzList *imports = rz_bin_object_get_imports(bf->o); + const RzPVector *imports = rz_bin_object_get_imports(bf->o); if (!imports) { return {}; } QList qList; - RzBinImport *import; - RzListIter *iter; bool va = core->io->va || core->bin->is_debugger; - CutterRzListForeach (imports, iter, RzBinImport, import) { + for (const auto &import : CutterPVector(imports)) { if (RZ_STR_ISEMPTY(import->name)) { continue; } @@ -3153,7 +3144,8 @@ QList CutterCore::getAllExports() if (!bf) { return {}; } - const RzList *symbols = rz_bin_object_get_symbols(bf->o); + + const RzPVector *symbols = rz_bin_object_get_symbols(bf->o); if (!symbols) { return {}; } @@ -3162,7 +3154,7 @@ QList CutterCore::getAllExports() bool demangle = rz_config_get_b(core->config, "bin.demangle"); QList ret; - for (const auto &symbol : CutterRzList(symbols)) { + for (const auto &symbol : CutterPVector(symbols)) { if (!(symbol->name && rz_core_sym_is_export(symbol))) { continue; } @@ -3187,13 +3179,15 @@ QList CutterCore::getAllExports() QList CutterCore::getAllSymbols() { CORE_LOCK(); - RzListIter *it; + RzBinFile *bf = rz_bin_cur(core->bin); + if (!bf) { + return {}; + } QList ret; - - RzBinSymbol *bs; - if (core && core->bin && core->bin->cur && core->bin->cur->o) { - CutterRzListForeach (core->bin->cur->o->symbols, it, RzBinSymbol, bs) { + const RzPVector *symbols = rz_bin_object_get_symbols(bf->o); + if (symbols) { + for (const auto &bs : CutterPVector(symbols)) { QString type = QString(bs->bind) + " " + QString(bs->type); SymbolDescription symbol; symbol.vaddr = bs->vaddr; @@ -3202,11 +3196,13 @@ QList CutterCore::getAllSymbols() symbol.type = QString(bs->type); ret << symbol; } + } + const RzList *entries = rz_bin_object_get_entries(bf->o); + if (entries) { /* list entrypoints as symbols too */ int n = 0; - RzBinAddr *entry; - CutterRzListForeach (core->bin->cur->o->entries, it, RzBinAddr, entry) { + for (const auto &entry : CutterRzList(entries)) { SymbolDescription symbol; symbol.vaddr = entry->vaddr; symbol.name = QString("entry") + QString::number(n++); @@ -3226,15 +3222,12 @@ QList CutterCore::getAllHeaders() if (!bf) { return {}; } - const RzList *fields = rz_bin_object_get_fields(bf->o); + const RzPVector *fields = rz_bin_object_get_fields(bf->o); if (!fields) { return {}; } - RzListIter *iter; - RzBinField *field; QList ret; - - CutterRzListForeach (fields, iter, RzBinField, field) { + for (auto field : CutterPVector(fields)) { HeaderDescription header; header.vaddr = field->vaddr; header.paddr = field->paddr; @@ -3242,7 +3235,6 @@ QList CutterCore::getAllHeaders() header.name = field->name; ret << header; } - return ret; } @@ -3345,8 +3337,9 @@ QList CutterCore::getAllStrings() if (!obj) { return {}; } - RzList *l = rz_core_bin_whole_strings(core, bf); - if (!l) { + + RzPVector *strings = rz_core_bin_whole_strings(core, bf); + if (!strings) { return {}; } @@ -3357,7 +3350,7 @@ QList CutterCore::getAllStrings() opt.esc_double_quotes = true; QList ret; - for (const auto &str : CutterRzList(l)) { + for (const auto &str : CutterPVector(strings)) { auto section = obj ? rz_bin_get_section_at(obj, str->paddr, 0) : NULL; StringDescription string; @@ -3420,7 +3413,7 @@ QList CutterCore::getAllSections() return sections; } - RzList *sects = rz_bin_object_get_sections(o); + RzPVector *sects = rz_bin_object_get_sections(o); if (!sects) { return sections; } @@ -3428,10 +3421,8 @@ QList CutterCore::getAllSections() if (!hashnames) { return sections; } - rz_list_push(hashnames, rz_str_new("entropy")); - RzListIter *it; - RzBinSection *sect; - CutterRzListForeach (sects, it, RzBinSection, sect) { + rz_list_push(hashnames, rz_str_dup("entropy")); + for (const auto § : CutterPVector(sects)) { if (RZ_STR_ISEMPTY(sect->name)) continue; @@ -3454,7 +3445,7 @@ QList CutterCore::getAllSections() sections << section; } - rz_list_free(sects); + rz_pvector_free(sects); return sections; } @@ -3468,15 +3459,14 @@ QStringList CutterCore::getSectionList() return ret; } - RzList *sects = rz_bin_object_get_sections(o); + RzPVector *sects = rz_bin_object_get_sections(o); if (!sects) { return ret; } - RzListIter *it; - RzBinSection *sect; - CutterRzListForeach (sects, it, RzBinSection, sect) { + for (const auto § : CutterPVector(sects)) { ret << sect->name; } + rz_pvector_free(sects); return ret; } @@ -3492,15 +3482,13 @@ QList CutterCore::getAllSegments() if (!bf) { return {}; } - RzList *segments = rz_bin_object_get_segments(bf->o); + RzPVector *segments = rz_bin_object_get_segments(bf->o); if (!segments) { return {}; } - RzBinSection *segment; - RzListIter *iter; QList ret; - CutterRzListForeach (segments, iter, RzBinSection, segment) { + for (const auto &segment : CutterPVector(segments)) { SegmentDescription segDesc; segDesc.name = segment->name; segDesc.vaddr = segment->vaddr; @@ -3510,7 +3498,7 @@ QList CutterCore::getAllSegments() segDesc.perm = perms_str(segment->perm); ret << segDesc; } - rz_list_free(segments); + rz_pvector_free(segments); return ret; } @@ -3557,17 +3545,16 @@ QList CutterCore::getAllClassesFromBin() return {}; } - const RzList *cs = rz_bin_object_get_classes(bf->o); + const RzPVector *cs = rz_bin_object_get_classes(bf->o); if (!cs) { return {}; } QList qList; - RzListIter *iter, *iter2, *iter3; - RzBinClass *c; + RzListIter *iter2, *iter3; RzBinSymbol *sym; RzBinClassField *f; - CutterRzListForeach (cs, iter, RzBinClass, c) { + for (const auto &c : CutterPVector(cs)) { BinClassDescription classDescription; classDescription.name = c->name; classDescription.addr = c->addr; @@ -3782,8 +3769,8 @@ void CutterCore::setAnalysisMethod(const QString &className, const AnalysisMetho { CORE_LOCK(); RzAnalysisMethod analysisMeth; - analysisMeth.name = rz_str_new(meth.name.toUtf8().constData()); - analysisMeth.real_name = rz_str_new(meth.realName.toUtf8().constData()); + analysisMeth.name = rz_str_dup(meth.name.toUtf8().constData()); + analysisMeth.real_name = rz_str_dup(meth.realName.toUtf8().constData()); analysisMeth.addr = meth.addr; analysisMeth.vtable_offset = meth.vtableOffset; rz_analysis_class_method_set(core->analysis, className.toUtf8().constData(), &analysisMeth); @@ -3806,19 +3793,22 @@ QList CutterCore::getAllResources() if (!bf) { return {}; } - const RzList *resources = rz_bin_object_get_resources(bf->o); + const RzPVector *resources = rz_bin_object_get_resources(bf->o); + if (!resources) { + return {}; + } + QList resourcesDescriptions; - RzBinResource *r; - RzListIter *it; - CutterRzListForeach (resources, it, RzBinResource, r) { + for (const auto &resource : CutterPVector(resources)) { 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; + description.name = resource->name; + description.vaddr = resource->vaddr; + description.index = resource->index; + description.type = resource->type; + description.size = resource->size; + description.lang = resource->language; + resourcesDescriptions << description; } @@ -4449,11 +4439,13 @@ bool CutterCore::setColor(const QString &key, const QString &color) QString CutterCore::ansiEscapeToHtml(const QString &text) { int len; - char *html = rz_cons_html_filter(text.toUtf8().constData(), &len); + QString r = text; + r.replace("\t", " "); + char *html = rz_cons_html_filter(r.toUtf8().constData(), &len); if (!html) { return {}; } - QString r = QString::fromUtf8(html, len); + r = QString::fromUtf8(html, len); rz_mem_free(html); return r; } diff --git a/src/core/RizinCpp.h b/src/core/RizinCpp.h index 85381717..65fd95b6 100644 --- a/src/core/RizinCpp.h +++ b/src/core/RizinCpp.h @@ -51,11 +51,17 @@ static inline auto fromOwned(RZ_OWN RzList *data) -> UniquePtrCP UniquePtrCP +{ + return { data, {} }; +} + // Rizin list iteration macros // deprecated, prefer using CutterPVector and CutterRzList instead #define CutterRzListForeach(list, it, type, x) \ if (list) \ - for (it = list->head; it && ((x = static_cast(it->data))); it = it->n) + for (it = list->head; it && ((x = static_cast(it->elem))); it = it->next) #define CutterRzVectorForeach(vec, it, type) \ if ((vec) && (vec)->a) \ @@ -133,7 +139,7 @@ public: if (!iter) { return *this; } - iter = iter->n; + iter = iter->next; return *this; } iterator operator++(int) @@ -149,7 +155,7 @@ public: if (!iter) { return nullptr; } - return reinterpret_cast(iter->data); + return reinterpret_cast(iter->elem); } }; diff --git a/src/dialogs/preferences/AnalysisOptionsWidget.cpp b/src/dialogs/preferences/AnalysisOptionsWidget.cpp index 53d00f2f..539ea968 100644 --- a/src/dialogs/preferences/AnalysisOptionsWidget.cpp +++ b/src/dialogs/preferences/AnalysisOptionsWidget.cpp @@ -38,7 +38,7 @@ AnalysisOptionsWidget::AnalysisOptionsWidget(PreferencesDialog *dialog) QString val = confCheckbox.config; QCheckBox &cb = *confCheckbox.checkBox; connect(confCheckbox.checkBox, &QCheckBox::stateChanged, this, - [this, val, &cb]() { checkboxEnabler(&cb, val); }); + [val, &cb]() { checkboxEnabler(&cb, val); }); } ui->analyzePushButton->setToolTip("Analyze the program using Rizin's \"aaa\" command"); diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index b2cb760d..9879a16e 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -31,6 +31,7 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main actionEditBytes(this), actionCopy(this), actionCopyAddr(this), + actionCopyInstrBytes(this), actionAddComment(this), actionAnalyzeFunction(this), actionEditFunction(this), @@ -76,6 +77,10 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main getCopyAddressSequence()); addAction(&actionCopyAddr); + initAction(&actionCopyInstrBytes, tr("Copy instruction bytes"), + SLOT(on_actionCopyInstrBytes_triggered()), getCopyInstrBytesSequence()); + addAction(&actionCopyInstrBytes); + initAction(&showInSubmenu, tr("Show in"), nullptr); addAction(&showInSubmenu); @@ -643,6 +648,11 @@ QKeySequence DisassemblyContextMenu::getCopyAddressSequence() const return { Qt::CTRL | Qt::SHIFT | Qt::Key_C }; } +QKeySequence DisassemblyContextMenu::getCopyInstrBytesSequence() const +{ + return { Qt::CTRL | Qt::ALT | Qt::Key_C }; +} + QKeySequence DisassemblyContextMenu::getSetToCodeSequence() const { return { Qt::Key_C }; @@ -793,6 +803,12 @@ void DisassemblyContextMenu::on_actionCopyAddr_triggered() clipboard->setText(RzAddressString(offset)); } +void DisassemblyContextMenu::on_actionCopyInstrBytes_triggered() +{ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(Core()->getInstructionBytes(offset)); +} + void DisassemblyContextMenu::on_actionAddBreakpoint_triggered() { Core()->toggleBreakpoint(offset); diff --git a/src/menus/DisassemblyContextMenu.h b/src/menus/DisassemblyContextMenu.h index e6c0773d..0cf91556 100644 --- a/src/menus/DisassemblyContextMenu.h +++ b/src/menus/DisassemblyContextMenu.h @@ -42,6 +42,7 @@ private slots: void on_actionCopy_triggered(); void on_actionCopyAddr_triggered(); + void on_actionCopyInstrBytes_triggered(); void on_actionAddComment_triggered(); void on_actionAnalyzeFunction_triggered(); void on_actionRename_triggered(); @@ -79,6 +80,7 @@ private: QKeySequence getCopySequence() const; QKeySequence getCommentSequence() const; QKeySequence getCopyAddressSequence() const; + QKeySequence getCopyInstrBytesSequence() const; QKeySequence getGlobalVarSequence() const; QKeySequence getSetToCodeSequence() const; QKeySequence getSetAsStringSequence() const; @@ -111,6 +113,7 @@ private: QAction actionCopy; QAction *copySeparator; QAction actionCopyAddr; + QAction actionCopyInstrBytes; QAction actionAddComment; QAction actionAnalyzeFunction; diff --git a/src/re.rizin.cutter.appdata.xml b/src/re.rizin.cutter.appdata.xml index ab7a6413..9ef364ba 100644 --- a/src/re.rizin.cutter.appdata.xml +++ b/src/re.rizin.cutter.appdata.xml @@ -25,10 +25,6 @@ xarkes - - - - diff --git a/src/translations b/src/translations index 0c92dc93..8358f174 160000 --- a/src/translations +++ b/src/translations @@ -1 +1 @@ -Subproject commit 0c92dc939a0aa74e6b5c8770bf50aa5719e4de2b +Subproject commit 8358f174d519bbf0d6cf4e1ccbe586308c009f85 diff --git a/src/widgets/ColorPicker.cpp b/src/widgets/ColorPicker.cpp index e35f1c5f..1733a74a 100644 --- a/src/widgets/ColorPicker.cpp +++ b/src/widgets/ColorPicker.cpp @@ -286,7 +286,6 @@ void ColorPicker::startPickingFromScreen() { if (!pickingFromScreen) { setMouseTracking(true); - grabMouse(Qt::CursorShape::CrossCursor); pickingFromScreen = true; bufferColor = currColor; } @@ -298,7 +297,6 @@ void ColorPicker::mouseReleaseEvent(QMouseEvent *event) setColor(getColorAtMouse()); pickingFromScreen = false; setMouseTracking(false); - releaseMouse(); } QWidget::mouseReleaseEvent(event); } diff --git a/src/widgets/ColorPicker.ui b/src/widgets/ColorPicker.ui index d4b83a2b..ce8797d2 100644 --- a/src/widgets/ColorPicker.ui +++ b/src/widgets/ColorPicker.ui @@ -11,7 +11,7 @@ - Form + Color Picker diff --git a/src/widgets/ConsoleWidget.cpp b/src/widgets/ConsoleWidget.cpp index de0e6892..cf1b6aaa 100644 --- a/src/widgets/ConsoleWidget.cpp +++ b/src/widgets/ConsoleWidget.cpp @@ -228,11 +228,11 @@ void ConsoleWidget::executeCommand(const QString &command) addOutput(cmd_line); RVA oldOffset = Core()->getOffset(); - commandTask = QSharedPointer( - new CommandTask(command, CommandTask::ColorMode::MODE_256, true)); + commandTask = + QSharedPointer(new CommandTask(command, CommandTask::ColorMode::MODE_16M)); connect(commandTask.data(), &CommandTask::finished, this, [this, cmd_line, command, oldOffset](const QString &result) { - ui->outputTextEdit->appendHtml(result); + ui->outputTextEdit->appendHtml(CutterCore::ansiEscapeToHtml(result)); scrollOutputToEnd(); historyAdd(command); commandTask.clear(); diff --git a/src/widgets/Dashboard.cpp b/src/widgets/Dashboard.cpp index 3636492b..192aab30 100644 --- a/src/widgets/Dashboard.cpp +++ b/src/widgets/Dashboard.cpp @@ -80,7 +80,7 @@ void Dashboard::updateContents() int static_value = rz_bin_is_static(core->bin); setPlainText(ui->staticEdit, tr(setBoolText(static_value))); - RzList *hashes = bf ? rz_bin_file_compute_hashes(core->bin, bf, UT64_MAX) : nullptr; + const RzPVector *hashes = bf ? rz_bin_file_compute_hashes(core->bin, bf, UT64_MAX) : nullptr; // Delete hashesWidget if it isn't null to avoid duplicate components if (hashesWidget) { @@ -94,23 +94,23 @@ void Dashboard::updateContents() ui->hashesVerticalLayout->addWidget(hashesWidget); // Add hashes as a pair of Hash Name : Hash Value. - RzListIter *iter; - RzBinFileHash *hash; - CutterRzListForeach (hashes, iter, RzBinFileHash, hash) { - // Create a bold QString with the hash name uppercased - QString label = QString("%1:").arg(QString(hash->type).toUpper()); + if (hashes != nullptr) { + for (const auto &hash : CutterPVector(hashes)) { + // Create a bold QString with the hash name uppercased + QString label = QString("%1:").arg(QString(hash->type).toUpper()); - // Define a Read-Only line edit to display the hash value - QLineEdit *hashLineEdit = new QLineEdit(); - hashLineEdit->setReadOnly(true); - hashLineEdit->setText(hash->hex); + // Define a Read-Only line edit to display the hash value + QLineEdit *hashLineEdit = new QLineEdit(); + hashLineEdit->setReadOnly(true); + hashLineEdit->setText(hash->hex); - // Set cursor position to begining to avoid long hashes (e.g sha256) - // to look truncated at the begining - hashLineEdit->setCursorPosition(0); + // Set cursor position to begining to avoid long hashes (e.g sha256) + // to look truncated at the begining + hashLineEdit->setCursorPosition(0); - // Add both controls to a form layout in a single row - hashesLayout->addRow(new QLabel(label), hashLineEdit); + // Add both controls to a form layout in a single row + hashesLayout->addRow(new QLabel(label), hashLineEdit); + } } st64 fcns = rz_list_length(core->analysis->fcns); @@ -134,11 +134,11 @@ void Dashboard::updateContents() setPlainText(ui->percentageLineEdit, QString::number(precentage) + "%"); ui->libraryList->setPlainText(""); - const RzList *libs = bf ? rz_bin_object_get_libs(bf->o) : nullptr; + const RzPVector *libs = bf ? rz_bin_object_get_libs(bf->o) : nullptr; if (libs) { QString libText; bool first = true; - for (const auto &lib : CutterRzList(libs)) { + for (const auto &lib : CutterPVector(libs)) { if (!first) { libText.append("\n"); } diff --git a/src/widgets/DecompilerWidget.cpp b/src/widgets/DecompilerWidget.cpp index c54ad6f9..b00c0ccd 100644 --- a/src/widgets/DecompilerWidget.cpp +++ b/src/widgets/DecompilerWidget.cpp @@ -347,8 +347,10 @@ void DecompilerWidget::decompilationFinished(RzAnnotatedCode *codeDecompiled) } } - ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollHistory[historyPos].first); - ui->textEdit->verticalScrollBar()->setSliderPosition(scrollHistory[historyPos].second); + if (!scrollHistory.empty()) { + ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollHistory[historyPos].first); + ui->textEdit->verticalScrollBar()->setSliderPosition(scrollHistory[historyPos].second); + } } void DecompilerWidget::setAnnotationsAtCursor(size_t pos) diff --git a/src/widgets/FunctionsWidget.cpp b/src/widgets/FunctionsWidget.cpp index 24d0d129..10d325fc 100644 --- a/src/widgets/FunctionsWidget.cpp +++ b/src/widgets/FunctionsWidget.cpp @@ -310,7 +310,7 @@ QVariant FunctionModel::headerData(int section, Qt::Orientation orientation, int case SizeColumn: return tr("Size"); case ImportColumn: - return tr("Imp."); + return tr("Import"); case OffsetColumn: return tr("Offset"); case NargsColumn: diff --git a/src/widgets/GraphView.cpp b/src/widgets/GraphView.cpp index 9fcca211..a5e276ed 100644 --- a/src/widgets/GraphView.cpp +++ b/src/widgets/GraphView.cpp @@ -159,7 +159,6 @@ void GraphView::beginMouseDrag(QMouseEvent *event) scrollBase = event->pos(); scroll_mode = true; setCursor(Qt::ClosedHandCursor); - viewport()->grabMouse(); } void GraphView::setViewOffset(QPoint offset) @@ -741,7 +740,6 @@ void GraphView::mouseReleaseEvent(QMouseEvent *event) if (scroll_mode && (event->buttons() & (Qt::LeftButton | Qt::MiddleButton)) == 0) { scroll_mode = false; setCursor(Qt::ArrowCursor); - viewport()->releaseMouse(); } } diff --git a/src/widgets/GraphvizLayout.cpp b/src/widgets/GraphvizLayout.cpp index f2a53b3c..eb1fe4e3 100644 --- a/src/widgets/GraphvizLayout.cpp +++ b/src/widgets/GraphvizLayout.cpp @@ -94,7 +94,7 @@ void GraphvizLayout::CalculateLayout(std::unordered_map &block std::unordered_map nodes; for (const auto &block : blocks) { - nodes[block.first] = agnode(g, nullptr, TRUE); + nodes[block.first] = agnode(g, nullptr, true); } std::vector strc; @@ -143,7 +143,7 @@ void GraphvizLayout::CalculateLayout(std::unordered_map &block if (v == nodes.end()) { continue; } - auto e = agedge(g, u, v->second, nullptr, TRUE); + auto e = agedge(g, u, v->second, nullptr, true); edges[{ blockIt.first, edge.target }] = e; if (loopEdges.find({ blockIt.first, edge.target }) != loopEdges.end()) { agxset(e, constraintAttr, STR("0"));