Convert disassembly (pd pdj pdJ) to rizin API (#2996)

This commit is contained in:
billow 2022-08-01 23:57:16 +08:00 committed by GitHub
parent db0d4d85a6
commit 44b7a7997a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 40 deletions

2
rizin

@ -1 +1 @@
Subproject commit 0fc9c9682e8a74245e4f24b84508f2bb6b185328
Subproject commit b79201b49a0d687c854b6e2f0c88fc8a7f2afa61

View File

@ -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);

View File

@ -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

View File

@ -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?

View File

@ -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()