mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 00:35:05 +00:00
Convert disassembly (pd pdj pdJ) to rizin API (#2996)
This commit is contained in:
parent
db0d4d85a6
commit
44b7a7997a
2
rizin
2
rizin
@ -1 +1 @@
|
||||
Subproject commit 0fc9c9682e8a74245e4f24b84508f2bb6b185328
|
||||
Subproject commit b79201b49a0d687c854b6e2f0c88fc8a7f2afa61
|
@ -377,6 +377,37 @@ QString CutterCore::cmd(const char *str)
|
||||
return o;
|
||||
}
|
||||
|
||||
QString CutterCore::getFunctionExecOut(const std::function<bool(RzCore *)> &fcn, const RVA addr)
|
||||
{
|
||||
CORE_LOCK();
|
||||
|
||||
RVA offset = core->offset;
|
||||
seekSilent(addr);
|
||||
QString o = {};
|
||||
rz_cons_push();
|
||||
bool is_pipe = core->is_pipe;
|
||||
core->is_pipe = true;
|
||||
|
||||
if (!fcn(core)) {
|
||||
core->is_pipe = is_pipe;
|
||||
rz_cons_pop();
|
||||
goto clean_return;
|
||||
}
|
||||
|
||||
core->is_pipe = is_pipe;
|
||||
rz_cons_filter();
|
||||
o = rz_cons_get_buffer();
|
||||
|
||||
rz_cons_pop();
|
||||
rz_cons_echo(NULL);
|
||||
|
||||
clean_return:
|
||||
if (offset != core->offset) {
|
||||
seekSilent(offset);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
bool CutterCore::isRedirectableDebugee()
|
||||
{
|
||||
if (!currentlyDebugging || currentlyAttachedToPID != -1) {
|
||||
@ -1055,24 +1086,23 @@ RVA CutterCore::prevOpAddr(RVA startAddr, int count)
|
||||
RVA CutterCore::nextOpAddr(RVA startAddr, int count)
|
||||
{
|
||||
CORE_LOCK();
|
||||
|
||||
CutterJson array =
|
||||
Core()->cmdj("pdj " + QString::number(count + 1) + " @ " + QString::number(startAddr));
|
||||
if (!array.size()) {
|
||||
return startAddr + 1;
|
||||
auto vec = reinterpret_cast<RzPVector *>(returnAtSeek(
|
||||
[&]() {
|
||||
return rz_core_analysis_bytes(core, core->block, (int)core->blocksize, count + 1);
|
||||
},
|
||||
startAddr));
|
||||
RVA addr = startAddr + 1;
|
||||
if (!vec) {
|
||||
return addr;
|
||||
}
|
||||
|
||||
CutterJson instValue = array.last();
|
||||
if (instValue.type() != RZ_JSON_OBJECT) {
|
||||
return startAddr + 1;
|
||||
auto ab = reinterpret_cast<RzAnalysisBytes *>(rz_pvector_tail(vec));
|
||||
if (!(ab && ab->op)) {
|
||||
rz_pvector_free(vec);
|
||||
return addr;
|
||||
}
|
||||
|
||||
RVA offset = instValue[RJsonKey::offset].toRVA();
|
||||
if (offset == RVA_INVALID) {
|
||||
return startAddr + 1;
|
||||
}
|
||||
|
||||
return offset;
|
||||
addr = ab->op->addr;
|
||||
rz_pvector_free(vec);
|
||||
return addr;
|
||||
}
|
||||
|
||||
RVA CutterCore::getOffset()
|
||||
@ -4176,18 +4206,35 @@ void CutterCore::loadPDB(const QString &file)
|
||||
|
||||
QList<DisassemblyLine> CutterCore::disassembleLines(RVA offset, int lines)
|
||||
{
|
||||
CutterJson array = cmdj(QString("pdJ ") + QString::number(lines) + QString(" @ ")
|
||||
+ QString::number(offset));
|
||||
QList<DisassemblyLine> r;
|
||||
|
||||
for (CutterJson object : array) {
|
||||
DisassemblyLine line;
|
||||
line.offset = object[RJsonKey::offset].toRVA();
|
||||
line.text = ansiEscapeToHtml(object[RJsonKey::text].toString());
|
||||
line.arrow = object[RJsonKey::arrow].toRVA();
|
||||
r << line;
|
||||
CORE_LOCK();
|
||||
RzPVector *vec = rz_pvector_new(reinterpret_cast<RzPVectorFree>(rz_analysis_disasm_text_free));
|
||||
if (!vec) {
|
||||
return {};
|
||||
}
|
||||
|
||||
RzCoreDisasmOptions options = {};
|
||||
options.cbytes = 1;
|
||||
options.vec = vec;
|
||||
applyAtSeek(
|
||||
[&]() {
|
||||
if (rz_cons_singleton()->is_html) {
|
||||
rz_cons_singleton()->is_html = false;
|
||||
rz_cons_singleton()->was_html = true;
|
||||
}
|
||||
rz_core_print_disasm(core, offset, core->block, core->blocksize, lines, NULL,
|
||||
&options);
|
||||
},
|
||||
offset);
|
||||
|
||||
QList<DisassemblyLine> r;
|
||||
for (const auto &t : CutterPVector<RzAnalysisDisasmText>(vec)) {
|
||||
DisassemblyLine line;
|
||||
line.offset = t->offset;
|
||||
line.text = ansiEscapeToHtml(t->text);
|
||||
line.arrow = t->arrow;
|
||||
r << line;
|
||||
}
|
||||
rz_pvector_free(vec);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -4354,7 +4401,7 @@ QString CutterCore::ansiEscapeToHtml(const QString &text)
|
||||
int len;
|
||||
char *html = rz_cons_html_filter(text.toUtf8().constData(), &len);
|
||||
if (!html) {
|
||||
return QString();
|
||||
return {};
|
||||
}
|
||||
QString r = QString::fromUtf8(html, len);
|
||||
rz_mem_free(html);
|
||||
|
@ -81,6 +81,10 @@ public:
|
||||
RVA getOffset() const { return core_->offset; }
|
||||
|
||||
/* Core functions (commands) */
|
||||
/* Almost the same as core_cmd_raw,
|
||||
* only executes std::function<bool(RzCore *)> instead of char* */
|
||||
QString getFunctionExecOut(const std::function<bool(RzCore *)> &fcn,
|
||||
const RVA addr = RVA_INVALID);
|
||||
static QString sanitizeStringForCommand(QString s);
|
||||
/**
|
||||
* @brief send a command to Rizin
|
||||
|
@ -131,8 +131,18 @@ void XrefsDialog::updatePreview(RVA addr)
|
||||
tempConfig.set("asm.lines", false);
|
||||
tempConfig.set("asm.bytes", false);
|
||||
|
||||
// Use cmd because cmRaw cannot handle the output properly. Why?
|
||||
QString disas = Core()->cmd("pd--20 @ " + QString::number(addr));
|
||||
QString disas = Core()->getFunctionExecOut(
|
||||
[](RzCore *core) {
|
||||
ut64 offset = core->offset;
|
||||
if (!rz_core_prevop_addr(core, core->offset, 20, &offset)) {
|
||||
offset = rz_core_prevop_addr_force(core, core->offset, 20);
|
||||
}
|
||||
rz_core_seek(core, offset, true);
|
||||
rz_core_print_disasm(core, core->offset, core->block, (int)core->blocksize, 40,
|
||||
NULL, NULL);
|
||||
return true;
|
||||
},
|
||||
addr);
|
||||
ui->previewTextEdit->document()->setHtml(disas);
|
||||
|
||||
// Does it make any sense?
|
||||
|
@ -726,19 +726,23 @@ void DisassemblyContextMenu::on_actionNopInstruction_triggered()
|
||||
|
||||
void DisassemblyContextMenu::showReverseJmpQuery()
|
||||
{
|
||||
QString type;
|
||||
|
||||
CutterJson array = Core()->cmdj("pdj 1 @ " + RzAddressString(offset));
|
||||
if (!array.size()) {
|
||||
actionJmpReverse.setVisible(false);
|
||||
RzCoreLocked core(Core());
|
||||
auto vec = reinterpret_cast<RzPVector *>(Core()->returnAtSeek(
|
||||
[&]() { return rz_core_analysis_bytes(core, core->block, (int)core->blocksize, 1); },
|
||||
offset));
|
||||
if (!vec) {
|
||||
return;
|
||||
}
|
||||
|
||||
type = array.first()["type"].toString();
|
||||
if (type == "cjmp") {
|
||||
actionJmpReverse.setVisible(true);
|
||||
} else {
|
||||
actionJmpReverse.setVisible(false);
|
||||
auto ab = reinterpret_cast<RzAnalysisBytes *>(rz_pvector_head(vec));
|
||||
if (!(ab && ab->op)) {
|
||||
rz_pvector_free(vec);
|
||||
return;
|
||||
}
|
||||
if (ab->op->type == RZ_ANALYSIS_OP_TYPE_CJMP) {
|
||||
actionJmpReverse.setVisible(true);
|
||||
}
|
||||
rz_pvector_free(vec);
|
||||
}
|
||||
|
||||
void DisassemblyContextMenu::on_actionJmpReverse_triggered()
|
||||
|
Loading…
Reference in New Issue
Block a user