mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 11:26:11 +00:00
Fix multiple crashes related to incorrect rz_iterator usage.
RzAnalysisBytes are owned by the iterator, so returning analysis bytes while destroying iterator owning it is incorrect.
This commit is contained in:
parent
70024929af
commit
6b660e7a48
@ -698,18 +698,16 @@ void CutterCore::delFlag(const QString &name)
|
|||||||
emit flagsChanged();
|
emit flagsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PRzAnalysisBytes CutterCore::getRzAnalysisBytesSingle(RVA addr)
|
CutterRzIter<RzAnalysisBytes> 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));
|
||||||
|
|
||||||
auto seek = seekTemp(addr);
|
// Warning! only safe to use with stack buffer, due to instruction count being 1
|
||||||
auto abiter = fromOwned(rz_core_analysis_bytes(core, addr, buf, sizeof(buf), 1));
|
auto result =
|
||||||
auto ab =
|
CutterRzIter<RzAnalysisBytes>(rz_core_analysis_bytes(core, addr, buf, sizeof(buf), 1));
|
||||||
abiter ? reinterpret_cast<RzAnalysisBytes *>(rz_iterator_next(abiter.get())) : nullptr;
|
return result;
|
||||||
|
|
||||||
return { ab, rz_analysis_bytes_free };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CutterCore::getInstructionBytes(RVA addr)
|
QString CutterCore::getInstructionBytes(RVA addr)
|
||||||
|
@ -62,8 +62,6 @@ struct CUTTER_EXPORT RegisterRef
|
|||||||
QString name;
|
QString name;
|
||||||
};
|
};
|
||||||
|
|
||||||
using PRzAnalysisBytes = std::unique_ptr<RzAnalysisBytes, decltype(rz_analysis_bytes_free) *>;
|
|
||||||
|
|
||||||
class CUTTER_EXPORT CutterCore : public QObject
|
class CUTTER_EXPORT CutterCore : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -248,7 +246,7 @@ public:
|
|||||||
QString getGlobalVariableType(RVA offset);
|
QString getGlobalVariableType(RVA offset);
|
||||||
|
|
||||||
/* Edition functions */
|
/* Edition functions */
|
||||||
PRzAnalysisBytes getRzAnalysisBytesSingle(RVA addr);
|
CutterRzIter<RzAnalysisBytes> getRzAnalysisBytesSingle(RVA addr);
|
||||||
QString getInstructionBytes(RVA addr);
|
QString getInstructionBytes(RVA addr);
|
||||||
QString getInstructionOpcode(RVA addr);
|
QString getInstructionOpcode(RVA addr);
|
||||||
void editInstruction(RVA addr, const QString &inst, bool fillWithNops = false);
|
void editInstruction(RVA addr, const QString &inst, bool fillWithNops = false);
|
||||||
|
@ -51,12 +51,6 @@ static inline auto fromOwned(RZ_OWN RzList *data) -> UniquePtrCP<decltype(data),
|
|||||||
return { data, {} };
|
return { data, {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline auto fromOwned(RZ_OWN RzIterator *data)
|
|
||||||
-> UniquePtrCP<decltype(data), &rz_iterator_free>
|
|
||||||
{
|
|
||||||
return { data, {} };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rizin list iteration macros
|
// Rizin list iteration macros
|
||||||
// deprecated, prefer using CutterPVector and CutterRzList instead
|
// deprecated, prefer using CutterPVector and CutterRzList instead
|
||||||
#define CutterRzListForeach(list, it, type, x) \
|
#define CutterRzListForeach(list, it, type, x) \
|
||||||
@ -170,4 +164,30 @@ public:
|
|||||||
iterator end() const { return iterator(nullptr); }
|
iterator end() const { return iterator(nullptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class CutterRzIter
|
||||||
|
{
|
||||||
|
UniquePtrC<RzIterator, &rz_iterator_free> rzIter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CutterRzIter(RzIterator *rzIter) : rzIter(rzIter)
|
||||||
|
{
|
||||||
|
// immediately attempt advancing by 1, otherwise it's hard to distinguish whether current
|
||||||
|
// element is null due to not having called next, or due to having run out of elements
|
||||||
|
if (rzIter) {
|
||||||
|
++*this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CutterRzIter<T> &operator++()
|
||||||
|
{
|
||||||
|
rz_iterator_next(rzIter.get());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
operator bool() { return rzIter && rzIter->cur; }
|
||||||
|
T &operator*() { return *reinterpret_cast<RzAnalysisBytes *>(rzIter->cur); }
|
||||||
|
T *get() { return reinterpret_cast<RzAnalysisBytes *>(rzIter->cur); }
|
||||||
|
T *operator->() { return reinterpret_cast<RzAnalysisBytes *>(rzIter->cur); }
|
||||||
|
};
|
||||||
|
|
||||||
#endif // RIZINCPP_H
|
#endif // RIZINCPP_H
|
||||||
|
Loading…
Reference in New Issue
Block a user