Convert Rizin commands to the API calls (#2948)

Including wx wr wd ws ww wz ahi ahb aec aecu aecc aecs aes aesb aets+
aets- afc afcl omfg+w oo+ oo p8 aei aeim aeip aecb aeso dbs avj
This commit is contained in:
billow 2022-05-28 16:09:00 +08:00 committed by GitHub
parent 147af53565
commit 150769cd6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 247 additions and 139 deletions

2
rizin

@ -1 +1 @@
Subproject commit f2a1e5e09087550e70122c3a2bedd4e2a02f77f1
Subproject commit 24524f26b5e4db58a736f702a77e79245148c559

View File

@ -656,7 +656,10 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int
}
if (perms & RZ_PERM_W) {
rz_core_cmd0(core, "omfg+w");
RzPVector *maps = rz_io_maps(core->io);
for (auto map : CutterPVector<RzIOMap>(maps)) {
map->perm |= RZ_PERM_W;
}
}
fflush(stdout);
@ -802,7 +805,8 @@ void CutterCore::jmpReverse(RVA addr)
void CutterCore::editBytes(RVA addr, const QString &bytes)
{
cmdRawAt(QString("wx %1").arg(bytes), addr);
CORE_LOCK();
rz_core_write_hexpair(core, addr, bytes.toUtf8().constData());
emit instructionChanged(addr);
}
@ -935,8 +939,9 @@ void CutterCore::setImmediateBase(const QString &rzBaseName, RVA offset)
if (offset == RVA_INVALID) {
offset = getOffset();
}
this->cmdRawAt(QString("ahi %1").arg(rzBaseName), offset);
CORE_LOCK();
int base = (int)rz_num_base_of_string(core->num, rzBaseName.toUtf8().constData());
rz_analysis_hint_set_immbase(core->analysis, offset, base);
emit instructionChanged(offset);
}
@ -946,7 +951,8 @@ void CutterCore::setCurrentBits(int bits, RVA offset)
offset = getOffset();
}
this->cmdRawAt(QString("ahb %1").arg(bits), offset);
CORE_LOCK();
rz_analysis_hint_set_bits(core->analysis, offset, bits);
emit instructionChanged(offset);
}
@ -1950,7 +1956,7 @@ void CutterCore::startDebug()
if (!asyncTask(
[](RzCore *core) {
rz_core_file_reopen_debug(core, "");
return (void *)nullptr;
return nullptr;
},
debugTask)) {
return;
@ -1991,14 +1997,19 @@ void CutterCore::startEmulation()
}
// clear registers, init esil state, stack, progcounter at current seek
asyncCmd("aei; aeim; aeip", debugTask);
asyncTask(
[&](RzCore *core) {
rz_core_analysis_esil_reinit(core);
rz_core_analysis_esil_init_mem(core, NULL, UT64_MAX, UT32_MAX);
rz_core_analysis_esil_init_regs(core);
return nullptr;
},
debugTask);
emit debugTaskStateChanged();
connect(debugTask.data(), &RizinTask::finished, this, [this]() {
if (debugTaskDialog) {
delete debugTaskDialog;
}
delete debugTaskDialog;
debugTask.clear();
if (!currentlyDebugging || !currentlyEmulating) {
@ -2105,9 +2116,7 @@ void CutterCore::attachDebug(int pid)
emit debugTaskStateChanged();
connect(debugTask.data(), &RizinTask::finished, this, [this, pid]() {
if (debugTaskDialog) {
delete debugTaskDialog;
}
delete debugTaskDialog;
debugTask.clear();
syncAndSeekProgramCounter();
@ -2184,14 +2193,20 @@ void CutterCore::continueDebug()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aec", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_core_esil_step(core, UT64_MAX, "0", NULL, false);
rz_core_reg_update_flags(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
if (!asyncTask(
[](RzCore *core) {
rz_debug_continue(core->dbg);
return (void *)NULL;
return nullptr;
},
debugTask)) {
return;
@ -2216,14 +2231,20 @@ void CutterCore::continueBackDebug()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aecb", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_core_esil_continue_back(core);
rz_core_reg_update_flags(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
if (!asyncTask(
[](RzCore *core) {
rz_debug_continue_back(core->dbg);
return (void *)NULL;
return nullptr;
},
debugTask)) {
return;
@ -2248,14 +2269,20 @@ void CutterCore::continueUntilDebug(ut64 offset)
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aecu " + QString::number(offset), debugTask)) {
if (!asyncTask(
[=](RzCore *core) {
rz_core_esil_step(core, offset, NULL, NULL, false);
rz_core_reg_update_flags(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
if (!asyncTask(
[=](RzCore *core) {
rz_core_debug_continue_until(core, offset, offset);
return (void *)NULL;
return nullptr;
},
debugTask)) {
return;
@ -2278,14 +2305,19 @@ void CutterCore::continueUntilCall()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aecc", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_core_analysis_continue_until_call(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
if (!asyncTask(
[](RzCore *core) {
rz_core_debug_step_one(core, 0);
return (void *)NULL;
return nullptr;
},
debugTask)) {
return;
@ -2310,7 +2342,12 @@ void CutterCore::continueUntilSyscall()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aecs", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_core_analysis_continue_until_syscall(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
@ -2346,14 +2383,20 @@ void CutterCore::stepDebug()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aes", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_core_esil_step(core, UT64_MAX, NULL, NULL, false);
rz_core_reg_update_flags(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
if (!asyncTask(
[](RzCore *core) {
rz_core_debug_step_one(core, 1);
return (void *)NULL;
return nullptr;
},
debugTask)) {
return;
@ -2378,7 +2421,12 @@ void CutterCore::stepOverDebug()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aeso", debugTask)) {
if (!asyncTask(
[&](RzCore *core) {
rz_core_analysis_esil_step_over(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
@ -2442,7 +2490,13 @@ void CutterCore::stepBackDebug()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aesb", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_core_esil_step_back(core);
rz_core_reg_update_flags(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
@ -2499,7 +2553,12 @@ void CutterCore::startTraceSession()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aets+", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_core_analysis_esil_trace_start(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
@ -2507,7 +2566,7 @@ void CutterCore::startTraceSession()
[](RzCore *core) {
core->dbg->session = rz_debug_session_new();
rz_debug_add_checkpoint(core->dbg);
return (void *)NULL;
return nullptr;
},
debugTask)) {
return;
@ -2516,9 +2575,7 @@ void CutterCore::startTraceSession()
emit debugTaskStateChanged();
connect(debugTask.data(), &RizinTask::finished, this, [this]() {
if (debugTaskDialog) {
delete debugTaskDialog;
}
delete debugTaskDialog;
debugTask.clear();
currentlyTracing = true;
@ -2541,7 +2598,12 @@ void CutterCore::stopTraceSession()
}
if (currentlyEmulating) {
if (!asyncCmdEsil("aets-", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_core_analysis_esil_trace_stop(core);
return nullptr;
},
debugTask)) {
return;
}
} else {
@ -2549,7 +2611,7 @@ void CutterCore::stopTraceSession()
[](RzCore *core) {
rz_debug_session_free(core->dbg->session);
core->dbg->session = NULL;
return (void *)NULL;
return nullptr;
},
debugTask)) {
return;
@ -2558,9 +2620,7 @@ void CutterCore::stopTraceSession()
emit debugTaskStateChanged();
connect(debugTask.data(), &RizinTask::finished, this, [this]() {
if (debugTaskDialog) {
delete debugTaskDialog;
}
delete debugTaskDialog;
debugTask.clear();
currentlyTracing = false;
@ -2578,7 +2638,8 @@ void CutterCore::stopTraceSession()
void CutterCore::toggleBreakpoint(RVA addr)
{
cmdRaw(QString("dbs %1").arg(addr));
CORE_LOCK();
rz_core_debug_breakpoint_toggle(core, addr);
emit breakpointsChanged(addr);
}
@ -3649,25 +3710,29 @@ QList<ResourcesDescription> CutterCore::getAllResources()
QList<VTableDescription> CutterCore::getAllVTables()
{
CORE_LOCK();
QList<VTableDescription> vtables;
for (CutterJson vTableObject : cmdj("avj")) {
VTableDescription res;
res.addr = vTableObject[RJsonKey::offset].toRVA();
for (CutterJson methodObject : vTableObject[RJsonKey::methods]) {
BinClassMethodDescription method;
method.addr = methodObject[RJsonKey::offset].toRVA();
method.name = methodObject[RJsonKey::name].toString();
res.methods << method;
QList<VTableDescription> vtableDescs;
RVTableContext context;
rz_analysis_vtable_begin(core->analysis, &context);
RzList *vtables = rz_analysis_vtable_search(&context);
RzListIter *iter;
RVTableInfo *table;
RVTableMethodInfo *method;
CutterRzListForeach (vtables, iter, RVTableInfo, table) {
VTableDescription tableDesc;
tableDesc.addr = table->saddr;
CutterRzVectorForeach(&table->methods, method, RVTableMethodInfo)
{
BinClassMethodDescription methodDesc;
RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, method->addr, 0);
const char *fname = fcn ? fcn->name : nullptr;
methodDesc.addr = method->addr;
methodDesc.name = fname ? fname : "No Name found";
tableDesc.methods << methodDesc;
}
vtables << res;
vtableDescs << tableDesc;
}
return vtables;
rz_list_free(vtables);
return vtableDescs;
}
QList<TypeDescription> CutterCore::getAllTypes()
@ -4226,10 +4291,10 @@ void CutterCore::commitWriteCache()
TempConfig tempConfig;
tempConfig.set("io.cache", false);
if (!isWriteModeEnabled()) {
cmdRaw("oo+");
rz_core_io_file_reopen(core, core->io->desc->fd, RZ_PERM_RW);
rz_io_cache_commit(core->io, 0, UT64_MAX);
rz_core_block_read(core);
cmdRaw("oo");
rz_core_io_file_open(core, core->io->desc->fd);
} else {
rz_io_cache_commit(core->io, 0, UT64_MAX);
rz_core_block_read(core);
@ -4252,17 +4317,22 @@ void CutterCore::setWriteMode(bool enabled)
return;
}
CORE_LOCK();
// Change from read-only to write-mode
if (enabled && !writeModeState) {
cmdRaw("oo+");
// Change from write-mode to read-only
if (enabled) {
if (!writeModeState) {
rz_core_io_file_reopen(core, core->io->desc->fd, RZ_PERM_RW);
}
} else {
cmdRaw("oo");
// Change from write-mode to read-only
rz_core_io_file_open(core, core->io->desc->fd);
}
// Disable cache mode because we specifically set write or
// read-only modes.
setIOCache(false);
writeModeChanged(enabled);
if (this->iocache) {
setIOCache(false);
}
emit writeModeChanged(enabled);
emit ioModeChanged();
}

View File

@ -77,14 +77,12 @@ size_t DuplicateFromOffsetDialog::getNBytes() const
void DuplicateFromOffsetDialog::refresh()
{
RVA offestFrom = getOffset();
QSignalBlocker sb(Core());
RzCoreLocked core(Core());
auto buf = Core()->ioRead(getOffset(), (int)getNBytes());
// Add space every two characters for word wrap in hex sequence
QRegularExpression re { "(.{2})" };
QString bytes = Core()->cmdRawAt(QString("p8 %1").arg(QString::number(getNBytes())), offestFrom)
.replace(re, "\\1 ");
ui->bytesLabel->setText(bytes.trimmed());
auto bytes = QString(buf).replace(re, "\\1 ").trimmed();
ui->bytesLabel->setText(bytes);
}

View File

@ -1014,8 +1014,18 @@ void DisassemblyContextMenu::on_actionEditFunction_triggered()
dialog.setStackSizeText(QString::number(fcn->stack));
QStringList callConList = Core()->cmdRaw("afcl").split("\n");
callConList.removeLast();
QStringList callConList;
RzList *list = rz_analysis_calling_conventions(core->analysis);
if (!list) {
return;
}
RzListIter *iter;
const char *cc;
CutterRzListForeach (list, iter, const char, cc) {
callConList << cc;
}
rz_list_free(list);
dialog.setCallConList(callConList);
dialog.setCallConSelected(fcn->cc);
@ -1026,7 +1036,15 @@ void DisassemblyContextMenu::on_actionEditFunction_triggered()
fcn->addr = Core()->math(new_start_addr);
QString new_stack_size = dialog.getStackSizeText();
fcn->stack = int(Core()->math(new_stack_size));
Core()->cmdRaw("afc " + dialog.getCallConSelected());
const char *ccSelected = dialog.getCallConSelected().toUtf8().constData();
if (RZ_STR_ISEMPTY(ccSelected)) {
return;
}
if (rz_analysis_cc_exist(core->analysis, ccSelected)) {
fcn->cc = rz_str_constpool_get(&core->analysis->constpool, ccSelected);
}
emit Core()->functionsChanged();
}
}

View File

@ -131,7 +131,8 @@ HexWidget::HexWidget(QWidget *parent)
// delete comment option
actionDeleteComment = new QAction(tr("Delete Comment"), this);
actionDeleteComment->setShortcutContext(Qt::ShortcutContext::WidgetWithChildrenShortcut);
connect(actionDeleteComment, &QAction::triggered, this, &HexWidget::on_actionDeleteComment_triggered);
connect(actionDeleteComment, &QAction::triggered, this,
&HexWidget::on_actionDeleteComment_triggered);
addAction(actionDeleteComment);
actionSelectRange = new QAction(tr("Select range"), this);
@ -713,14 +714,14 @@ void HexWidget::copyAddress()
clipboard->setText(RzAddressString(addr));
}
//slot for add comment action
// slot for add comment action
void HexWidget::on_actionAddComment_triggered()
{
uint64_t addr = cursor.address;
CommentsDialog::addOrEditComment(addr, this);
}
//slot for deleting comment action
// slot for deleting comment action
void HexWidget::on_actionDeleteComment_triggered()
{
uint64_t addr = cursor.address;
@ -742,14 +743,16 @@ void HexWidget::w_writeString()
return;
}
bool ok = false;
QInputDialog d;
d.setInputMode(QInputDialog::InputMode::TextInput);
QString str = d.getText(this, tr("Write string"), tr("String:"), QLineEdit::Normal, "", &ok);
if (ok && !str.isEmpty()) {
QString str = QInputDialog::getText(this, tr("Write string"), tr("String:"), QLineEdit::Normal,
"", &ok);
if (!ok || str.isEmpty()) {
return;
}
{
RzCoreLocked core(Core());
rz_core_write_string_at(core, getLocationAddress(), str.toUtf8().constData());
refresh();
}
refresh();
}
void HexWidget::w_increaseDecrease()
@ -767,8 +770,10 @@ void HexWidget::w_increaseDecrease()
if (d.getMode() == IncrementDecrementDialog::Decrease) {
value *= -1;
}
RzCoreLocked core(Core());
rz_core_write_value_inc_at(core, getLocationAddress(), value, sz);
{
RzCoreLocked core(Core());
rz_core_write_value_inc_at(core, getLocationAddress(), value, sz);
}
refresh();
}
@ -784,10 +789,8 @@ void HexWidget::w_writeBytes()
size = static_cast<int>(selection.size());
}
QInputDialog d;
d.setInputMode(QInputDialog::InputMode::TextInput);
QByteArray bytes = d.getText(this, tr("Write hex bytes"), tr("Hex byte string:"),
QLineEdit::Normal, "", &ok)
QByteArray bytes = QInputDialog::getText(this, tr("Write hex bytes"), tr("Hex byte string:"),
QLineEdit::Normal, "", &ok)
.toUtf8();
const int offset = bytes.startsWith("\\x") ? 2 : 0;
const int incr = offset + 2;
@ -795,16 +798,18 @@ void HexWidget::w_writeBytes()
if (!ok || !bytes_size) {
return;
}
uint8_t *buf = (uint8_t *)malloc(static_cast<size_t>(bytes_size));
if (!buf) {
return;
{
auto *buf = (uint8_t *)malloc(static_cast<size_t>(bytes_size));
if (!buf) {
return;
}
for (int i = 0, j = 0, sz = bytes.size(); i < sz; i += incr, j++) {
buf[j] = static_cast<uint8_t>(bytes.mid(i + offset, 2).toInt(nullptr, 16));
}
RzCoreLocked core(Core());
rz_core_write_at(core, getLocationAddress(), buf, bytes_size);
free(buf);
}
for (int i = 0, j = 0, sz = bytes.size(); i < sz; i += incr, j++) {
buf[j] = static_cast<uint8_t>(bytes.mid(i + offset, 2).toInt(nullptr, 16));
}
RzCoreLocked core(Core());
rz_core_write_at(core, getLocationAddress(), buf, bytes_size);
free(buf);
refresh();
}
@ -813,24 +818,25 @@ void HexWidget::w_writeZeros()
if (!ioModesController.prepareForWriting()) {
return;
}
bool ok = false;
QInputDialog d;
int size = 1;
if (!selection.isEmpty() && selection.size() <= INT_MAX) {
size = static_cast<int>(selection.size());
}
int len =
d.getInt(this, tr("Write zeros"), tr("Number of zeros:"), size, 1, 0x7FFFFFFF, 1, &ok);
if (ok) {
bool ok = false;
int len = QInputDialog::getInt(this, tr("Write zeros"), tr("Number of zeros:"), size, 1,
0x7FFFFFFF, 1, &ok);
if (!ok) {
return;
}
{
RzCoreLocked core(Core());
uint8_t *buf = (uint8_t *)calloc(len, sizeof(uint8_t));
auto *buf = (uint8_t *)calloc(len, sizeof(uint8_t));
rz_core_write_at(core, getLocationAddress(), buf, len);
free(buf);
refresh();
}
refresh();
}
void HexWidget::w_write64()
@ -855,11 +861,13 @@ void HexWidget::w_write64()
return;
}
RzCoreLocked core(Core());
if (d.getMode() == Base64EnDecodedWriteDialog::Encode) {
rz_core_write_base64_at(core, getLocationAddress(), str.toHex().constData());
} else {
rz_core_write_base64d_at(core, getLocationAddress(), str.constData());
{
RzCoreLocked core(Core());
if (d.getMode() == Base64EnDecodedWriteDialog::Encode) {
rz_core_write_base64_at(core, getLocationAddress(), str.toHex().constData());
} else {
rz_core_write_base64d_at(core, getLocationAddress(), str.constData());
}
}
refresh();
}
@ -869,19 +877,24 @@ void HexWidget::w_writeRandom()
if (!ioModesController.prepareForWriting()) {
return;
}
bool ok = false;
QInputDialog d;
int size = 1;
if (!selection.isEmpty() && selection.size() <= INT_MAX) {
size = static_cast<int>(selection.size());
}
QString nbytes = QString::number(d.getInt(this, tr("Write random"), tr("Number of bytes:"),
size, 1, 0x7FFFFFFF, 1, &ok));
if (ok && !nbytes.isEmpty()) {
Core()->cmdRawAt(QString("wr %1").arg(nbytes), getLocationAddress());
refresh();
bool ok = false;
int nbytes = QInputDialog::getInt(this, tr("Write random"), tr("Number of bytes:"), size, 1,
0x7FFFFFFF, 1, &ok);
if (!ok) {
return;
}
{
RzCoreLocked core(Core());
rz_core_write_random_at(core, getLocationAddress(), nbytes);
}
refresh();
}
void HexWidget::w_duplFromOffset()
@ -894,9 +907,12 @@ void HexWidget::w_duplFromOffset()
if (ret == QDialog::Rejected) {
return;
}
RVA copyFrom = d.getOffset();
QString nBytes = QString::number(d.getNBytes());
Core()->cmdRawAt(QString("wd %1 %2").arg(copyFrom).arg(nBytes), getLocationAddress());
RVA src = d.getOffset();
int len = (int)d.getNBytes();
{
RzCoreLocked core(Core());
rz_core_write_duplicate_at(core, getLocationAddress(), src, len);
}
refresh();
}
@ -906,14 +922,16 @@ void HexWidget::w_writePascalString()
return;
}
bool ok = false;
QInputDialog d;
d.setInputMode(QInputDialog::InputMode::TextInput);
QString str =
d.getText(this, tr("Write Pascal string"), tr("String:"), QLineEdit::Normal, "", &ok);
if (ok && !str.isEmpty()) {
Core()->cmdRawAt(QString("ws %1").arg(str), getLocationAddress());
refresh();
QString str = QInputDialog::getText(this, tr("Write Pascal string"), tr("String:"),
QLineEdit::Normal, "", &ok);
if (!ok || str.isEmpty()) {
return;
}
{
RzCoreLocked core(Core());
rz_core_write_length_string_at(core, getLocationAddress(), str.toUtf8().constData());
}
refresh();
}
void HexWidget::w_writeWideString()
@ -922,14 +940,16 @@ void HexWidget::w_writeWideString()
return;
}
bool ok = false;
QInputDialog d;
d.setInputMode(QInputDialog::InputMode::TextInput);
QString str =
d.getText(this, tr("Write wide string"), tr("String:"), QLineEdit::Normal, "", &ok);
if (ok && !str.isEmpty()) {
Core()->cmdRawAt(QString("ww %1").arg(str), getLocationAddress());
refresh();
QString str = QInputDialog::getText(this, tr("Write wide string"), tr("String:"),
QLineEdit::Normal, "", &ok);
if (!ok || str.isEmpty()) {
return;
}
{
RzCoreLocked core(Core());
rz_core_write_string_wide_at(core, getLocationAddress(), str.toUtf8().constData());
}
refresh();
}
void HexWidget::w_writeCString()
@ -938,14 +958,16 @@ void HexWidget::w_writeCString()
return;
}
bool ok = false;
QInputDialog d;
d.setInputMode(QInputDialog::InputMode::TextInput);
QString str = d.getText(this, tr("Write zero-terminated string"), tr("String:"),
QLineEdit::Normal, "", &ok);
if (ok && !str.isEmpty()) {
Core()->cmdRawAt(QString("wz %1").arg(str), getLocationAddress());
refresh();
QString str = QInputDialog::getText(this, tr("Write zero-terminated string"), tr("String:"),
QLineEdit::Normal, "", &ok);
if (!ok || str.isEmpty()) {
return;
}
{
RzCoreLocked core(Core());
rz_core_write_string_zero_at(core, getLocationAddress(), str.toUtf8().constData());
}
refresh();
}
void HexWidget::updateItemLength()