mirror of
https://github.com/rizinorg/cutter.git
synced 2025-02-23 15:04:46 +00:00
Introduce some helpers to deal with rizin C API more cleanly. (#3020)
This commit is contained in:
parent
39bf5c6429
commit
41c4857ed9
@ -5,6 +5,7 @@ set(SOURCES
|
|||||||
Main.cpp
|
Main.cpp
|
||||||
core/Cutter.cpp
|
core/Cutter.cpp
|
||||||
core/CutterJson.cpp
|
core/CutterJson.cpp
|
||||||
|
core/RizinCpp.cpp
|
||||||
dialogs/EditStringDialog.cpp
|
dialogs/EditStringDialog.cpp
|
||||||
dialogs/WriteCommandsDialogs.cpp
|
dialogs/WriteCommandsDialogs.cpp
|
||||||
widgets/DisassemblerGraphView.cpp
|
widgets/DisassemblerGraphView.cpp
|
||||||
@ -154,6 +155,7 @@ set(HEADER_FILES
|
|||||||
core/CutterCommon.h
|
core/CutterCommon.h
|
||||||
core/CutterDescriptions.h
|
core/CutterDescriptions.h
|
||||||
core/CutterJson.h
|
core/CutterJson.h
|
||||||
|
core/RizinCpp.h
|
||||||
dialogs/EditStringDialog.h
|
dialogs/EditStringDialog.h
|
||||||
dialogs/WriteCommandsDialogs.h
|
dialogs/WriteCommandsDialogs.h
|
||||||
widgets/DisassemblerGraphView.h
|
widgets/DisassemblerGraphView.h
|
||||||
|
@ -49,8 +49,7 @@ void DecompilerHighlighter::highlightBlock(const QString &)
|
|||||||
size_t start = block.position();
|
size_t start = block.position();
|
||||||
size_t end = block.position() + block.length();
|
size_t end = block.position() + block.length();
|
||||||
|
|
||||||
std::unique_ptr<RzPVector, decltype(&rz_pvector_free)> annotations(
|
auto annotations = fromOwned(rz_annotated_code_annotations_range(code, start, end));
|
||||||
rz_annotated_code_annotations_range(code, start, end), &rz_pvector_free);
|
|
||||||
void **iter;
|
void **iter;
|
||||||
rz_pvector_foreach(annotations.get(), iter)
|
rz_pvector_foreach(annotations.get(), iter)
|
||||||
{
|
{
|
||||||
|
@ -120,13 +120,6 @@ static void updateOwnedCharPtr(char *&variable, const QString &newValue)
|
|||||||
variable = strdup(data.data());
|
variable = strdup(data.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString fromOwnedCharPtr(char *str)
|
|
||||||
{
|
|
||||||
QString result(str ? str : "");
|
|
||||||
rz_mem_free(str);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool reg_sync(RzCore *core, RzRegisterType type, bool write)
|
static bool reg_sync(RzCore *core, RzRegisterType type, bool write)
|
||||||
{
|
{
|
||||||
if (rz_core_is_debug(core)) {
|
if (rz_core_is_debug(core)) {
|
||||||
@ -782,11 +775,10 @@ PRzAnalysisBytes CutterCore::getRzAnalysisBytesSingle(RVA addr)
|
|||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
ut8 buf[128];
|
ut8 buf[128];
|
||||||
rz_io_read_at(core->io, addr, buf, sizeof(buf));
|
rz_io_read_at(core->io, addr, buf, sizeof(buf));
|
||||||
std::unique_ptr<RzPVector, decltype(rz_pvector_free) *> vec {
|
|
||||||
returnAtSeek<RzPVector *>(
|
auto seek = seekTemp(addr);
|
||||||
[&]() { return rz_core_analysis_bytes(core, buf, sizeof(buf), 1); }, addr),
|
auto vec = fromOwned(rz_core_analysis_bytes(core, buf, sizeof(buf), 1));
|
||||||
rz_pvector_free
|
|
||||||
};
|
|
||||||
auto ab = vec && rz_pvector_len(vec.get()) > 0
|
auto ab = vec && rz_pvector_len(vec.get()) > 0
|
||||||
? reinterpret_cast<RzAnalysisBytes *>(rz_pvector_pop_front(vec.get()))
|
? reinterpret_cast<RzAnalysisBytes *>(rz_pvector_pop_front(vec.get()))
|
||||||
: nullptr;
|
: nullptr;
|
||||||
@ -819,14 +811,20 @@ void CutterCore::editInstruction(RVA addr, const QString &inst, bool fillWithNop
|
|||||||
void CutterCore::nopInstruction(RVA addr)
|
void CutterCore::nopInstruction(RVA addr)
|
||||||
{
|
{
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
applyAtSeek([&]() { rz_core_hack(core, "nop"); }, addr);
|
{
|
||||||
|
auto seek = seekTemp(addr);
|
||||||
|
rz_core_hack(core, "nop");
|
||||||
|
}
|
||||||
emit instructionChanged(addr);
|
emit instructionChanged(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::jmpReverse(RVA addr)
|
void CutterCore::jmpReverse(RVA addr)
|
||||||
{
|
{
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
applyAtSeek([&]() { rz_core_hack(core, "recj"); }, addr);
|
{
|
||||||
|
auto seek = seekTemp(addr);
|
||||||
|
rz_core_hack(core, "recj");
|
||||||
|
}
|
||||||
emit instructionChanged(addr);
|
emit instructionChanged(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,8 +906,8 @@ QString CutterCore::getString(RVA addr, uint64_t len, RzStrEnc encoding, bool es
|
|||||||
opt.length = len;
|
opt.length = len;
|
||||||
opt.encoding = encoding;
|
opt.encoding = encoding;
|
||||||
opt.escape_nl = escape_nl;
|
opt.escape_nl = escape_nl;
|
||||||
char *s = returnAtSeek<char *>([&]() { return rz_str_stringify_raw_buffer(&opt, NULL); }, addr);
|
auto seek = seekTemp(addr);
|
||||||
return fromOwnedCharPtr(s);
|
return fromOwnedCharPtr(rz_str_stringify_raw_buffer(&opt, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CutterCore::getMetaString(RVA addr)
|
QString CutterCore::getMetaString(RVA addr)
|
||||||
@ -993,12 +991,11 @@ void CutterCore::applyStructureOffset(const QString &structureOffset, RVA offset
|
|||||||
offset = getOffset();
|
offset = getOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyAtSeek(
|
{
|
||||||
[&]() {
|
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
|
auto seek = seekTemp(offset);
|
||||||
rz_core_analysis_hint_set_offset(core, structureOffset.toUtf8().constData());
|
rz_core_analysis_hint_set_offset(core, structureOffset.toUtf8().constData());
|
||||||
},
|
}
|
||||||
offset);
|
|
||||||
emit instructionChanged(offset);
|
emit instructionChanged(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,22 +1081,19 @@ RVA CutterCore::prevOpAddr(RVA startAddr, int count)
|
|||||||
RVA CutterCore::nextOpAddr(RVA startAddr, int count)
|
RVA CutterCore::nextOpAddr(RVA startAddr, int count)
|
||||||
{
|
{
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
auto vec = returnAtSeek<RzPVector *>(
|
auto seek = seekTemp(startAddr);
|
||||||
[&]() {
|
auto vec =
|
||||||
return rz_core_analysis_bytes(core, core->block, (int)core->blocksize, count + 1);
|
fromOwned(rz_core_analysis_bytes(core, core->block, (int)core->blocksize, count + 1));
|
||||||
},
|
|
||||||
startAddr);
|
|
||||||
RVA addr = startAddr + 1;
|
RVA addr = startAddr + 1;
|
||||||
if (!vec) {
|
if (!vec) {
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
auto ab = reinterpret_cast<RzAnalysisBytes *>(rz_pvector_tail(vec));
|
auto ab = reinterpret_cast<RzAnalysisBytes *>(rz_pvector_tail(vec.get()));
|
||||||
if (!(ab && ab->op)) {
|
if (!(ab && ab->op)) {
|
||||||
rz_pvector_free(vec);
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
addr = ab->op->addr;
|
addr = ab->op->addr;
|
||||||
rz_pvector_free(vec);
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4193,34 +4187,32 @@ void CutterCore::loadPDB(const QString &file)
|
|||||||
QList<DisassemblyLine> CutterCore::disassembleLines(RVA offset, int lines)
|
QList<DisassemblyLine> CutterCore::disassembleLines(RVA offset, int lines)
|
||||||
{
|
{
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
RzPVector *vec = rz_pvector_new(reinterpret_cast<RzPVectorFree>(rz_analysis_disasm_text_free));
|
auto vec = fromOwned(
|
||||||
|
rz_pvector_new(reinterpret_cast<RzPVectorFree>(rz_analysis_disasm_text_free)));
|
||||||
if (!vec) {
|
if (!vec) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
RzCoreDisasmOptions options = {};
|
RzCoreDisasmOptions options = {};
|
||||||
options.cbytes = 1;
|
options.cbytes = 1;
|
||||||
options.vec = vec;
|
options.vec = vec.get();
|
||||||
applyAtSeek(
|
{
|
||||||
[&]() {
|
auto restoreSeek = seekTemp(offset);
|
||||||
if (rz_cons_singleton()->is_html) {
|
if (rz_cons_singleton()->is_html) {
|
||||||
rz_cons_singleton()->is_html = false;
|
rz_cons_singleton()->is_html = false;
|
||||||
rz_cons_singleton()->was_html = true;
|
rz_cons_singleton()->was_html = true;
|
||||||
}
|
}
|
||||||
rz_core_print_disasm(core, offset, core->block, core->blocksize, lines, NULL,
|
rz_core_print_disasm(core, offset, core->block, core->blocksize, lines, NULL, &options);
|
||||||
&options);
|
}
|
||||||
},
|
|
||||||
offset);
|
|
||||||
|
|
||||||
QList<DisassemblyLine> r;
|
QList<DisassemblyLine> r;
|
||||||
for (const auto &t : CutterPVector<RzAnalysisDisasmText>(vec)) {
|
for (const auto &t : CutterPVector<RzAnalysisDisasmText>(vec.get())) {
|
||||||
DisassemblyLine line;
|
DisassemblyLine line;
|
||||||
line.offset = t->offset;
|
line.offset = t->offset;
|
||||||
line.text = ansiEscapeToHtml(t->text);
|
line.text = ansiEscapeToHtml(t->text);
|
||||||
line.arrow = t->arrow;
|
line.arrow = t->arrow;
|
||||||
r << line;
|
r << line;
|
||||||
}
|
}
|
||||||
rz_pvector_free(vec);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,33 +156,34 @@ public:
|
|||||||
return cmdRawAt(str.toUtf8().constData(), address);
|
return cmdRawAt(str.toUtf8().constData(), address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyAtSeek(const std::function<void()> &fn, RVA address)
|
class SeekReturn
|
||||||
{
|
{
|
||||||
RVA oldOffset = getOffset();
|
RVA returnAddress;
|
||||||
seekSilent(address);
|
bool empty = true;
|
||||||
fn();
|
|
||||||
seekSilent(oldOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
public:
|
||||||
T returnAtSeek(const std::function<T()> &fn, RVA address)
|
SeekReturn(RVA returnAddress) : returnAddress(returnAddress), empty(false) {}
|
||||||
|
~SeekReturn()
|
||||||
{
|
{
|
||||||
RVA oldOffset = getOffset();
|
if (!empty) {
|
||||||
seekSilent(address);
|
Core()->seekSilent(returnAddress);
|
||||||
T ret = fn();
|
|
||||||
seekSilent(oldOffset);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
std::unique_ptr<RVA, std::function<void(const RVA *)>> seekTemp(RVA address)
|
SeekReturn(SeekReturn &&from)
|
||||||
{
|
{
|
||||||
auto seekBack = [&](const RVA *x) {
|
if (this != &from) {
|
||||||
seekSilent(*x);
|
returnAddress = from.returnAddress;
|
||||||
delete x;
|
empty = from.empty;
|
||||||
|
from.empty = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
std::unique_ptr<RVA, decltype(seekBack)> p { new RVA(getOffset()), seekBack };
|
};
|
||||||
|
|
||||||
|
SeekReturn seekTemp(RVA address)
|
||||||
|
{
|
||||||
|
SeekReturn returner(getOffset());
|
||||||
seekSilent(address);
|
seekSilent(address);
|
||||||
return p;
|
return returner;
|
||||||
}
|
}
|
||||||
|
|
||||||
CutterJson cmdj(const char *str);
|
CutterJson cmdj(const char *str);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "rz_core.h"
|
#include "rz_core.h"
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include "RizinCpp.h"
|
||||||
|
|
||||||
// Workaround for compile errors on Windows
|
// Workaround for compile errors on Windows
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
@ -14,103 +15,6 @@
|
|||||||
# undef max
|
# undef max
|
||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
// Rizin list iteration macros
|
|
||||||
#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) \
|
|
||||||
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
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const RzPVector *const vec;
|
|
||||||
|
|
||||||
public:
|
|
||||||
class iterator : public std::iterator<std::input_iterator_tag, T *>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
T **p;
|
|
||||||
|
|
||||||
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; }
|
|
||||||
T *operator*() { return *p; }
|
|
||||||
};
|
|
||||||
|
|
||||||
CutterPVector(const RzPVector *vec) : vec(vec) {}
|
|
||||||
iterator begin() const { return iterator(reinterpret_cast<T **>(vec->v.a)); }
|
|
||||||
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
|
// Global information for Cutter
|
||||||
#define APPNAME "Cutter"
|
#define APPNAME "Cutter"
|
||||||
|
@ -1768,12 +1768,12 @@ void MainWindow::on_actionExport_as_code_triggered()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<char, decltype(free) *> string {
|
|
||||||
|
|
||||||
|
auto string = fromOwned(
|
||||||
dialog.selectedNameFilter() != instructionsInComments
|
dialog.selectedNameFilter() != instructionsInComments
|
||||||
? rz_lang_byte_array(buffer.data(), size, typMap[dialog.selectedNameFilter()])
|
? rz_lang_byte_array(buffer.data(), size, typMap[dialog.selectedNameFilter()])
|
||||||
: rz_core_print_bytes_with_inst(rc, buffer.data(), 0, size),
|
: rz_core_print_bytes_with_inst(rc, buffer.data(), 0, size));
|
||||||
free
|
|
||||||
};
|
|
||||||
fileOut << string.get();
|
fileOut << string.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
src/core/RizinCpp.cpp
Normal file
2
src/core/RizinCpp.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include "RizinCpp.h"
|
||||||
|
|
154
src/core/RizinCpp.h
Normal file
154
src/core/RizinCpp.h
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/** \file RizinCpp.h
|
||||||
|
* Various utilities for easier and safer interactions with Rizin
|
||||||
|
* from C++ code.
|
||||||
|
*/
|
||||||
|
#ifndef RIZINCPP_H
|
||||||
|
#define RIZINCPP_H
|
||||||
|
|
||||||
|
#include "rz_core.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
static inline QString fromOwnedCharPtr(char *str)
|
||||||
|
{
|
||||||
|
QString result(str ? str : "");
|
||||||
|
rz_mem_free(str);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class F>
|
||||||
|
std::unique_ptr<T, F *> fromOwned(T *data, F *freeFunction)
|
||||||
|
{
|
||||||
|
return std::unique_ptr<T, F *> { data, freeFunction };
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::unique_ptr<char, decltype(&rz_mem_free)> fromOwned(char *text)
|
||||||
|
{
|
||||||
|
return { text, rz_mem_free };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, void (*func)(T *)>
|
||||||
|
class FreeBinder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void operator()(T *data) { func(data); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, void (*func)(T *)>
|
||||||
|
using UniquePtrC = std::unique_ptr<T, FreeBinder<T, func>>;
|
||||||
|
|
||||||
|
template<typename T, void (*func)(T)>
|
||||||
|
using UniquePtrCP = UniquePtrC<typename std::remove_pointer<T>::type, func>;
|
||||||
|
|
||||||
|
static inline auto fromOwned(RZ_OWN RzPVector *data)
|
||||||
|
-> UniquePtrCP<decltype(data), &rz_pvector_free>
|
||||||
|
{
|
||||||
|
return { data, {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline auto fromOwned(RZ_OWN RzList *data)
|
||||||
|
-> UniquePtrCP<decltype(data), &rz_list_free>
|
||||||
|
{
|
||||||
|
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<type *>(it->data))); it = it->n)
|
||||||
|
|
||||||
|
#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
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const RzPVector *const vec;
|
||||||
|
|
||||||
|
public:
|
||||||
|
class iterator : public std::iterator<std::input_iterator_tag, T *>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T **p;
|
||||||
|
|
||||||
|
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; }
|
||||||
|
T *operator*() { return *p; }
|
||||||
|
};
|
||||||
|
|
||||||
|
CutterPVector(const RzPVector *vec) : vec(vec) {}
|
||||||
|
iterator begin() const { return iterator(reinterpret_cast<T **>(vec->v.a)); }
|
||||||
|
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); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RIZINCPP_H
|
@ -86,11 +86,7 @@ bool EditMethodDialog::inputValid()
|
|||||||
|
|
||||||
QString EditMethodDialog::convertRealNameToName(const QString &realName)
|
QString EditMethodDialog::convertRealNameToName(const QString &realName)
|
||||||
{
|
{
|
||||||
std::unique_ptr<const char, void (*)(const char *)> sanitizedCString(
|
return fromOwnedCharPtr(rz_str_sanitize_sdb_key(realName.toUtf8().constData()));
|
||||||
rz_str_sanitize_sdb_key(realName.toUtf8().constData()),
|
|
||||||
[](const char *s) { rz_mem_free((void*)s); });
|
|
||||||
|
|
||||||
return QString(sanitizedCString.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditMethodDialog::setClass(const QString &className)
|
void EditMethodDialog::setClass(const QString &className)
|
||||||
|
@ -314,9 +314,8 @@ void DisassemblyContextMenu::addDebugMenu()
|
|||||||
QVector<DisassemblyContextMenu::ThingUsedHere> DisassemblyContextMenu::getThingUsedHere(RVA offset)
|
QVector<DisassemblyContextMenu::ThingUsedHere> DisassemblyContextMenu::getThingUsedHere(RVA offset)
|
||||||
{
|
{
|
||||||
RzCoreLocked core(Core());
|
RzCoreLocked core(Core());
|
||||||
auto p = std::unique_ptr<RzCoreAnalysisName, decltype(rz_core_analysis_name_free) *> {
|
auto p = fromOwned(
|
||||||
rz_core_analysis_name(core, offset), rz_core_analysis_name_free
|
rz_core_analysis_name(core, offset), rz_core_analysis_name_free);
|
||||||
};
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,6 @@ static inline bool isBetween(ut64 a, ut64 x, ut64 b)
|
|||||||
return (a == UT64_MAX || a <= x) && (b == UT64_MAX || x <= b);
|
return (a == UT64_MAX || a <= x) && (b == UT64_MAX || x <= b);
|
||||||
}
|
}
|
||||||
|
|
||||||
using PRzList = std::unique_ptr<RzList, decltype(rz_list_free) *>;
|
|
||||||
|
|
||||||
void CallGraphView::loadCurrentGraph()
|
void CallGraphView::loadCurrentGraph()
|
||||||
{
|
{
|
||||||
@ -90,7 +89,7 @@ void CallGraphView::loadCurrentGraph()
|
|||||||
GraphLayout::GraphBlock block;
|
GraphLayout::GraphBlock block;
|
||||||
block.entry = fcn->addr;
|
block.entry = fcn->addr;
|
||||||
|
|
||||||
auto xrefs = PRzList { rz_analysis_function_get_xrefs_from(fcn), rz_list_free };
|
auto xrefs = fromOwned(rz_analysis_function_get_xrefs_from(fcn));
|
||||||
auto calls = std::unordered_set<ut64>();
|
auto calls = std::unordered_set<ut64>();
|
||||||
for (const auto &xref : CutterRzList<RzAnalysisXRef>(xrefs.get())) {
|
for (const auto &xref : CutterRzList<RzAnalysisXRef>(xrefs.get())) {
|
||||||
const auto x = xref->to;
|
const auto x = xref->to;
|
||||||
|
@ -193,9 +193,7 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
|
|
||||||
windowTitle = tr("Graph");
|
windowTitle = tr("Graph");
|
||||||
if (fcn && RZ_STR_ISNOTEMPTY(fcn->name)) {
|
if (fcn && RZ_STR_ISNOTEMPTY(fcn->name)) {
|
||||||
std::unique_ptr<char, decltype(std::free) *> fcnName {
|
auto fcnName = fromOwned(rz_str_escape_utf8_for_json(fcn->name, -1));
|
||||||
rz_str_escape_utf8_for_json(fcn->name, -1), std::free
|
|
||||||
};
|
|
||||||
windowTitle += QString("(%0)").arg(fcnName.get());
|
windowTitle += QString("(%0)").arg(fcnName.get());
|
||||||
} else {
|
} else {
|
||||||
windowTitle += "(Empty)";
|
windowTitle += "(Empty)";
|
||||||
@ -267,10 +265,8 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
}
|
}
|
||||||
rz_io_read_at(core->io, bbi->addr, buf.get(), (int)bbi->size);
|
rz_io_read_at(core->io, bbi->addr, buf.get(), (int)bbi->size);
|
||||||
|
|
||||||
std::unique_ptr<RzPVector, decltype(rz_pvector_free) *> vec {
|
auto vec = fromOwned(
|
||||||
rz_pvector_new(reinterpret_cast<RzPVectorFree>(rz_analysis_disasm_text_free)),
|
rz_pvector_new(reinterpret_cast<RzPVectorFree>(rz_analysis_disasm_text_free)));
|
||||||
rz_pvector_free
|
|
||||||
};
|
|
||||||
if (!vec) {
|
if (!vec) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -234,12 +234,10 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const
|
|||||||
QStringList summary {};
|
QStringList summary {};
|
||||||
{
|
{
|
||||||
auto seeker = Core()->seekTemp(function.offset);
|
auto seeker = Core()->seekTemp(function.offset);
|
||||||
auto strings = std::unique_ptr<char, decltype(free) *> {
|
auto strings = fromOwnedCharPtr(
|
||||||
rz_core_print_disasm_strings(Core()->core(), RZ_CORE_DISASM_STRINGS_MODE_FUNCTION,
|
rz_core_print_disasm_strings(Core()->core(), RZ_CORE_DISASM_STRINGS_MODE_FUNCTION,
|
||||||
0, NULL),
|
0, NULL));
|
||||||
free
|
summary = strings.split('\n', CUTTER_QT_SKIP_EMPTY_PARTS);
|
||||||
};
|
|
||||||
summary = QString(strings.get()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QFont &fnt = Config()->getFont();
|
const QFont &fnt = Config()->getFont();
|
||||||
|
@ -21,8 +21,7 @@ VisualNavbar::VisualNavbar(MainWindow *main, QWidget *parent)
|
|||||||
graphicsView(new QGraphicsView),
|
graphicsView(new QGraphicsView),
|
||||||
seekGraphicsItem(nullptr),
|
seekGraphicsItem(nullptr),
|
||||||
PCGraphicsItem(nullptr),
|
PCGraphicsItem(nullptr),
|
||||||
main(main),
|
main(main)
|
||||||
stats(nullptr, rz_core_analysis_stats_free)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
|
|
||||||
@ -119,7 +118,7 @@ void VisualNavbar::fetchStats()
|
|||||||
|
|
||||||
RzCoreLocked core(Core());
|
RzCoreLocked core(Core());
|
||||||
stats.reset(nullptr);
|
stats.reset(nullptr);
|
||||||
RzList *list = rz_core_get_boundaries_prot(core, -1, NULL, "search");
|
auto list = fromOwned(rz_core_get_boundaries_prot(core, -1, NULL, "search"));
|
||||||
if (!list) {
|
if (!list) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -127,7 +126,7 @@ void VisualNavbar::fetchStats()
|
|||||||
RzIOMap *map;
|
RzIOMap *map;
|
||||||
ut64 from = UT64_MAX;
|
ut64 from = UT64_MAX;
|
||||||
ut64 to = 0;
|
ut64 to = 0;
|
||||||
CutterRzListForeach (list, iter, RzIOMap, map) {
|
CutterRzListForeach (list.get(), iter, RzIOMap, map) {
|
||||||
ut64 f = rz_itv_begin(map->itv);
|
ut64 f = rz_itv_begin(map->itv);
|
||||||
ut64 t = rz_itv_end(map->itv);
|
ut64 t = rz_itv_end(map->itv);
|
||||||
if (f < from) {
|
if (f < from) {
|
||||||
@ -137,7 +136,6 @@ void VisualNavbar::fetchStats()
|
|||||||
to = t;
|
to = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rz_list_free(list);
|
|
||||||
to--; // rz_core_analysis_get_stats takes inclusive ranges
|
to--; // rz_core_analysis_get_stats takes inclusive ranges
|
||||||
if (to < from) {
|
if (to < from) {
|
||||||
return;
|
return;
|
||||||
|
@ -47,7 +47,7 @@ private:
|
|||||||
QGraphicsRectItem *PCGraphicsItem;
|
QGraphicsRectItem *PCGraphicsItem;
|
||||||
MainWindow *main;
|
MainWindow *main;
|
||||||
|
|
||||||
std::unique_ptr<RzCoreAnalysisStats, decltype(&rz_core_analysis_stats_free)> stats;
|
UniquePtrC<RzCoreAnalysisStats, &rz_core_analysis_stats_free> stats;
|
||||||
unsigned int statsWidth = 0;
|
unsigned int statsWidth = 0;
|
||||||
unsigned int previousWidth = 0;
|
unsigned int previousWidth = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user