Use cmdRaw and cmdRawAt in Cutter.cpp

This commit is contained in:
itayc0hen 2020-03-21 15:25:50 +02:00 committed by Itay Cohen
parent 281e75389f
commit 5d02449094
2 changed files with 85 additions and 80 deletions

View File

@ -391,7 +391,6 @@ bool CutterCore::asyncCmd(const char *str, QSharedPointer<R2Task> &task)
return true; return true;
} }
// TODO: Refactor cmdRaw based on this implementation and use it inside cmdRawAt
QString CutterCore::cmdRawAt(const char *cmd, RVA address) QString CutterCore::cmdRawAt(const char *cmd, RVA address)
{ {
QString res; QString res;
@ -411,9 +410,8 @@ QString CutterCore::cmdRaw(const char *cmd)
r_cons_push (); r_cons_push ();
// r_cmd_call does not return the output of the command // r_cmd_call does not return the output of the command
bool success = r_cmd_call(core->rcmd, cmd); r_cmd_call(core->rcmd, cmd);
qInfo() << "---" << success << "----\n";
// we grab the output straight from r_cons // we grab the output straight from r_cons
res = r_cons_get_buffer(); res = r_cons_get_buffer();
@ -618,7 +616,7 @@ void CutterCore::renameFunction(const QString &oldName, const QString &newName)
void CutterCore::delFunction(RVA addr) void CutterCore::delFunction(RVA addr)
{ {
cmd("af- " + RAddressString(addr)); cmdRaw("af- " + RAddressString(addr));
emit functionsChanged(); emit functionsChanged();
} }
@ -630,7 +628,7 @@ void CutterCore::renameFlag(QString old_name, QString new_name)
void CutterCore::delFlag(RVA addr) void CutterCore::delFlag(RVA addr)
{ {
cmd("f-@" + RAddressString(addr)); cmdRawAt("f-", addr);
emit flagsChanged(); emit flagsChanged();
} }
@ -652,37 +650,37 @@ QString CutterCore::getInstructionOpcode(RVA addr)
void CutterCore::editInstruction(RVA addr, const QString &inst) void CutterCore::editInstruction(RVA addr, const QString &inst)
{ {
cmd("\"wa " + inst + "\" @ " + RAddressString(addr)); cmdRawAt(QString("wa %1").arg(inst), addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
void CutterCore::nopInstruction(RVA addr) void CutterCore::nopInstruction(RVA addr)
{ {
cmd("wao nop @ " + RAddressString(addr)); cmdRawAt("wao nop", addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
void CutterCore::jmpReverse(RVA addr) void CutterCore::jmpReverse(RVA addr)
{ {
cmd("wao recj @ " + RAddressString(addr)); cmdRawAt("wao recj", addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
void CutterCore::editBytes(RVA addr, const QString &bytes) void CutterCore::editBytes(RVA addr, const QString &bytes)
{ {
cmd("wx " + bytes + " @ " + RAddressString(addr)); cmdRawAt(QString("wx %1").arg(bytes), addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
void CutterCore::editBytesEndian(RVA addr, const QString &bytes) void CutterCore::editBytesEndian(RVA addr, const QString &bytes)
{ {
cmd("wv " + bytes + " @ " + RAddressString(addr)); cmdRawAt(QString("wv %1").arg(bytes), addr);
emit stackChanged(); emit stackChanged();
} }
void CutterCore::setToCode(RVA addr) void CutterCore::setToCode(RVA addr)
{ {
cmd("Cd- @ " + RAddressString(addr)); cmdRawAt("Cd-", addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
@ -717,26 +715,20 @@ void CutterCore::setAsString(RVA addr, int size, StringTypeFormats type)
} }
seekAndShow(addr); seekAndShow(addr);
QString arg;
if(size > 0) {
arg = QString::asprintf("%d @ %lld", size, addr);
} else {
arg = QString::asprintf("@ %lld", addr);
}
cmd(command + arg); cmdRawAt(QString("%1 %2").arg(command).arg(size), addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
void CutterCore::removeString(RVA addr) void CutterCore::removeString(RVA addr)
{ {
cmd("Cs- @ " + RAddressString(addr)); cmdRawAt("Cs-", addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
QString CutterCore::getString(RVA addr) QString CutterCore::getString(RVA addr)
{ {
return cmd("ps @ " + RAddressString(addr)); return cmdRawAt("ps", addr);
} }
void CutterCore::setToData(RVA addr, int size, int repeat) void CutterCore::setToData(RVA addr, int size, int repeat)
@ -744,27 +736,27 @@ void CutterCore::setToData(RVA addr, int size, int repeat)
if (size <= 0 || repeat <= 0) { if (size <= 0 || repeat <= 0) {
return; return;
} }
cmd("Cd- @ " + RAddressString(addr)); cmdRawAt("Cd-", addr);
cmd(QString::asprintf("Cd %d %d @ %lld", size, repeat, addr)); cmdRawAt(QString("Cd %1 %2").arg(size).arg(repeat), addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
int CutterCore::sizeofDataMeta(RVA addr) int CutterCore::sizeofDataMeta(RVA addr)
{ {
bool ok; bool ok;
int size = cmd("Cd. @ " + RAddressString(addr)).toInt(&ok); int size = cmdRawAt("Cd.", addr).toInt(&ok);
return (ok ? size : 0); return (ok ? size : 0);
} }
void CutterCore::setComment(RVA addr, const QString &cmt) void CutterCore::setComment(RVA addr, const QString &cmt)
{ {
cmd("CCu base64:" + cmt.toLocal8Bit().toBase64() + " @ " + QString::number(addr)); cmdRawAt(QString("CCu base64:%1").arg(QString(cmt.toLocal8Bit().toBase64())), addr);
emit commentsChanged(); emit commentsChanged();
} }
void CutterCore::delComment(RVA addr) void CutterCore::delComment(RVA addr)
{ {
cmd("CC- @ " + QString::number(addr)); cmdRawAt("CC-", addr);
emit commentsChanged(); emit commentsChanged();
} }
@ -774,7 +766,7 @@ void CutterCore::setImmediateBase(const QString &r2BaseName, RVA offset)
offset = getOffset(); offset = getOffset();
} }
this->cmd("ahi " + r2BaseName + " @ " + QString::number(offset)); this->cmdRawAt(QString("ahi %1").arg(r2BaseName), offset);
emit instructionChanged(offset); emit instructionChanged(offset);
} }
@ -784,7 +776,7 @@ void CutterCore::setCurrentBits(int bits, RVA offset)
offset = getOffset(); offset = getOffset();
} }
this->cmd("ahb " + QString::number(bits) + " @ " + QString::number(offset)); this->cmdRawAt(QString("ahb %1").arg(bits), offset);
emit instructionChanged(offset); emit instructionChanged(offset);
} }
@ -794,7 +786,7 @@ void CutterCore::applyStructureOffset(const QString &structureOffset, RVA offset
offset = getOffset(); offset = getOffset();
} }
this->cmdRawAt("aht " + structureOffset, QString::number(offset)); this->cmdRawAt("aht " + structureOffset, offset);
emit instructionChanged(offset); emit instructionChanged(offset);
} }
@ -816,6 +808,8 @@ void CutterCore::seek(ut64 offset)
if (offset == RVA_INVALID) { if (offset == RVA_INVALID) {
return; return;
} }
// use cmd and not cmdRaw to make sure seekChanged is emitted
cmd(QString("s %1").arg(offset)); cmd(QString("s %1").arg(offset));
// cmd already does emit seekChanged(core_->offset); // cmd already does emit seekChanged(core_->offset);
} }
@ -844,11 +838,13 @@ void CutterCore::seek(QString thing)
void CutterCore::seekPrev() void CutterCore::seekPrev()
{ {
// Use cmd because cmdRaw does not work with seek history
cmd("s-"); cmd("s-");
} }
void CutterCore::seekNext() void CutterCore::seekNext()
{ {
// Use cmd because cmdRaw does not work with seek history
cmd("s+"); cmd("s+");
} }
@ -861,8 +857,7 @@ RVA CutterCore::prevOpAddr(RVA startAddr, int count)
{ {
CORE_LOCK(); CORE_LOCK();
bool ok; bool ok;
RVA offset = cmd("/O " + QString::number(count) + " @ " + QString::number(startAddr)).toULongLong( RVA offset = cmdRawAt(QString("/O %1").arg(count), startAddr).toULongLong(&ok, 16);
&ok, 16);
return ok ? offset : startAddr - count; return ok ? offset : startAddr - count;
} }
@ -1045,7 +1040,7 @@ QString CutterCore::disassemble(const QByteArray &data)
QString CutterCore::disassembleSingleInstruction(RVA addr) QString CutterCore::disassembleSingleInstruction(RVA addr)
{ {
return cmd("pi 1@" + QString::number(addr)).simplified(); return cmdRawAt("pi 1", addr).simplified();
} }
RAnalFunction *CutterCore::functionIn(ut64 addr) RAnalFunction *CutterCore::functionIn(ut64 addr)
@ -1106,7 +1101,8 @@ RVA CutterCore::getLastFunctionInstruction(RVA addr)
QString CutterCore::cmdFunctionAt(QString addr) QString CutterCore::cmdFunctionAt(QString addr)
{ {
QString ret; QString ret;
ret = cmd(QString("fd @ ") + addr + "~[0]"); // Use cmd because cmdRaw would not work with grep
ret = cmd(QString("fd @ %1~[0]").arg(addr));
return ret.trimmed(); return ret.trimmed();
} }
@ -1117,6 +1113,7 @@ QString CutterCore::cmdFunctionAt(RVA addr)
void CutterCore::cmdEsil(const char *command) void CutterCore::cmdEsil(const char *command)
{ {
// use cmd and not cmdRaw because of unexpected commands
QString res = cmd(command); QString res = cmd(command);
if (res.contains(QStringLiteral("[ESIL] Stopped execution in an invalid instruction"))) { if (res.contains(QStringLiteral("[ESIL] Stopped execution in an invalid instruction"))) {
msgBox.showMessage("Stopped when attempted to run an invalid instruction. You can disable this in Preferences"); msgBox.showMessage("Stopped when attempted to run an invalid instruction. You can disable this in Preferences");
@ -1125,7 +1122,7 @@ void CutterCore::cmdEsil(const char *command)
QString CutterCore::createFunctionAt(RVA addr) QString CutterCore::createFunctionAt(RVA addr)
{ {
QString ret = cmd("af " + RAddressString(addr)); QString ret = cmdRaw(QString("af %1").arg(addr));
emit functionsChanged(); emit functionsChanged();
return ret; return ret;
} }
@ -1134,8 +1131,7 @@ QString CutterCore::createFunctionAt(RVA addr, QString name)
{ {
static const QRegularExpression regExp("[^a-zA-Z0-9_]"); static const QRegularExpression regExp("[^a-zA-Z0-9_]");
name.remove(regExp); name.remove(regExp);
QString command = "af " + name + " @ " + RAddressString(addr); QString ret = cmdRawAt(QString("af %1").arg(name), addr);
QString ret = cmd(command);
emit functionsChanged(); emit functionsChanged();
return ret; return ret;
} }
@ -1288,7 +1284,7 @@ QList<QJsonObject> CutterCore::getStack(int size, int depth)
CORE_LOCK(); CORE_LOCK();
bool ret; bool ret;
RVA addr = cmd("dr SP").toULongLong(&ret, 16); RVA addr = cmdRaw("dr SP").toULongLong(&ret, 16);
if (!ret) { if (!ret) {
return stack; return stack;
} }
@ -1487,13 +1483,15 @@ QJsonObject CutterCore::getRegisterJson()
QString CutterCore::getRegisterName(QString registerRole) QString CutterCore::getRegisterName(QString registerRole)
{ {
return cmd("drn " + registerRole).trimmed(); return cmdRaw("drn " + registerRole).trimmed();
} }
RVA CutterCore::getProgramCounterValue() RVA CutterCore::getProgramCounterValue()
{ {
bool ok; bool ok;
if (currentlyDebugging) { if (currentlyDebugging) {
// Use cmd because cmdRaw would not work with inner command backticked
// TODO: Risky command due to changes in API, search for something safer
RVA addr = cmd("dr?`drn PC`").toULongLong(&ok, 16); RVA addr = cmd("dr?`drn PC`").toULongLong(&ok, 16);
if (ok) { if (ok) {
return addr; return addr;
@ -1504,7 +1502,7 @@ RVA CutterCore::getProgramCounterValue()
void CutterCore::setRegister(QString regName, QString regValue) void CutterCore::setRegister(QString regName, QString regValue)
{ {
cmd("dr " + regName + "=" + regValue); cmdRaw(QString("dr %1=%2").arg(regName).arg(regValue));
emit registersChanged(); emit registersChanged();
emit refreshCodeViews(); emit refreshCodeViews();
} }
@ -1659,6 +1657,7 @@ void CutterCore::attachRemote(const QString &uri)
connected = true; connected = true;
} }
} }
// Use cmd because cmdRaw would not with inner command backticked
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seekAndShow(programCounterValue); seekAndShow(programCounterValue);
if (!connected) { if (!connected) {
@ -1750,6 +1749,7 @@ void CutterCore::stopDebug()
cmdEsil("aeim-; aei-; wcr; .ar-"); cmdEsil("aeim-; aei-; wcr; .ar-");
currentlyEmulating = false; currentlyEmulating = false;
} else if (currentlyAttachedToPID != -1) { } else if (currentlyAttachedToPID != -1) {
// Use cmd because cmdRaw would not work with command concatenation
cmd(QString("dp- %1; o %2; .ar-").arg( cmd(QString("dp- %1; o %2; .ar-").arg(
QString::number(currentlyAttachedToPID), currentlyOpenFile)); QString::number(currentlyAttachedToPID), currentlyOpenFile));
currentlyAttachedToPID = -1; currentlyAttachedToPID = -1;
@ -1764,6 +1764,7 @@ void CutterCore::stopDebug()
ptraceFiles += "o-" + QString::number(openFile["fd"].toInt()) + ";"; ptraceFiles += "o-" + QString::number(openFile["fd"].toInt()) + ";";
} }
} }
// Use cmd because cmdRaw would not work with command concatenation
cmd("doc" + ptraceFiles); cmd("doc" + ptraceFiles);
} }
@ -1778,6 +1779,7 @@ void CutterCore::stopDebug()
void CutterCore::syncAndSeekProgramCounter() void CutterCore::syncAndSeekProgramCounter()
{ {
// Use cmd because cmdRaw would not work with inner command backticked
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seekAndShow(programCounterValue); seekAndShow(programCounterValue);
emit registersChanged(); emit registersChanged();
@ -1991,7 +1993,7 @@ void CutterCore::setDebugPlugin(QString plugin)
void CutterCore::toggleBreakpoint(RVA addr) void CutterCore::toggleBreakpoint(RVA addr)
{ {
cmd("dbs " + RAddressString(addr)); cmdRaw(QString("dbs %1").arg(addr));
emit instructionChanged(addr); emit instructionChanged(addr);
emit breakpointsChanged(); emit breakpointsChanged();
} }
@ -2080,27 +2082,27 @@ void CutterCore::updateBreakpoint(int index, const BreakpointDescription &config
void CutterCore::delBreakpoint(RVA addr) void CutterCore::delBreakpoint(RVA addr)
{ {
cmd("db- " + RAddressString(addr)); cmdRaw("db- " + RAddressString(addr));
emit instructionChanged(addr); emit instructionChanged(addr);
emit breakpointsChanged(); emit breakpointsChanged();
} }
void CutterCore::delAllBreakpoints() void CutterCore::delAllBreakpoints()
{ {
cmd("db-*"); cmdRaw("db-*");
emit refreshCodeViews(); emit refreshCodeViews();
} }
void CutterCore::enableBreakpoint(RVA addr) void CutterCore::enableBreakpoint(RVA addr)
{ {
cmd("dbe " + RAddressString(addr)); cmdRaw("dbe " + RAddressString(addr));
emit instructionChanged(addr); emit instructionChanged(addr);
emit breakpointsChanged(); emit breakpointsChanged();
} }
void CutterCore::disableBreakpoint(RVA addr) void CutterCore::disableBreakpoint(RVA addr)
{ {
cmd("dbd " + RAddressString(addr)); cmdRaw("dbd " + RAddressString(addr));
emit instructionChanged(addr); emit instructionChanged(addr);
emit breakpointsChanged(); emit breakpointsChanged();
} }
@ -2108,9 +2110,9 @@ void CutterCore::disableBreakpoint(RVA addr)
void CutterCore::setBreakpointTrace(int index, bool enabled) void CutterCore::setBreakpointTrace(int index, bool enabled)
{ {
if (enabled) { if (enabled) {
cmd(QString("dbite %1").arg(index)); cmdRaw(QString("dbite %1").arg(index));
} else { } else {
cmd(QString("dbitd %1").arg(index)); cmdRaw(QString("dbitd %1").arg(index));
} }
} }
@ -2246,21 +2248,24 @@ QList<MemoryMapDescription> CutterCore::getMemoryMap()
QStringList CutterCore::getStats() QStringList CutterCore::getStats()
{ {
QStringList stats; QStringList stats;
cmd("fs functions"); cmdRaw("fs functions");
// The cmd coomand is frequently used in this function because
// cmdRaw would not work with grep
stats << cmd("f~?").trimmed(); stats << cmd("f~?").trimmed();
QString imps = cmd("ii~?").trimmed(); QString imps = cmd("ii~?").trimmed();
stats << imps; stats << imps;
cmd("fs symbols"); cmdRaw("fs symbols");
stats << cmd("f~?").trimmed(); stats << cmd("f~?").trimmed();
cmd("fs strings"); cmdRaw("fs strings");
stats << cmd("f~?").trimmed(); stats << cmd("f~?").trimmed();
cmd("fs relocs"); cmdRaw("fs relocs");
stats << cmd("f~?").trimmed(); stats << cmd("f~?").trimmed();
cmd("fs sections"); cmdRaw("fs sections");
stats << cmd("f~?").trimmed(); stats << cmd("f~?").trimmed();
cmd("fs *"); cmdRaw("fs *");
stats << cmd("f~?").trimmed(); stats << cmd("f~?").trimmed();
return stats; return stats;
@ -2722,9 +2727,9 @@ QList<FlagDescription> CutterCore::getAllFlags(QString flagspace)
QList<FlagDescription> ret; QList<FlagDescription> ret;
if (!flagspace.isEmpty()) if (!flagspace.isEmpty())
cmd("fs " + flagspace); cmdRaw("fs " + flagspace);
else else
cmd("fs *"); cmdRaw("fs *");
QJsonArray flagsArray = cmdj("fj").array(); QJsonArray flagsArray = cmdj("fj").array();
for (const QJsonValue &value : flagsArray) { for (const QJsonValue &value : flagsArray) {
@ -3276,13 +3281,13 @@ QString CutterCore::getTypeAsC(QString name, QString category)
} }
QString typeName = sanitizeStringForCommand(name); QString typeName = sanitizeStringForCommand(name);
if (category == "Struct") { if (category == "Struct") {
output = cmd (QString("tsc %1").arg(typeName)); output = cmdRaw(QString("tsc %1").arg(typeName));
} else if (category == "Union") { } else if (category == "Union") {
output = cmd (QString("tuc %1").arg(typeName)); output = cmdRaw(QString("tuc %1").arg(typeName));
} else if(category == "Enum") { } else if(category == "Enum") {
output = cmd (QString("tec %1").arg(typeName)); output = cmdRaw(QString("tec %1").arg(typeName));
} else if(category == "Typedef") { } else if(category == "Typedef") {
output = cmd (QString("ttc %1").arg(typeName)); output = cmdRaw(QString("ttc %1").arg(typeName));
} }
return output; return output;
} }
@ -3290,7 +3295,7 @@ QString CutterCore::getTypeAsC(QString name, QString category)
bool CutterCore::isAddressMapped(RVA addr) bool CutterCore::isAddressMapped(RVA addr)
{ {
// If value returned by "om. @ addr" is empty means that address is not mapped // If value returned by "om. @ addr" is empty means that address is not mapped
return !Core()->cmd(QString("om. @ %1").arg(addr)).isEmpty(); return !Core()->cmdRawAt(QString("om."), addr).isEmpty();
} }
QList<SearchDescription> CutterCore::getAllSearch(QString search_for, QString space) QList<SearchDescription> CutterCore::getAllSearch(QString search_for, QString space)
@ -3430,7 +3435,7 @@ QList<XrefDescription> CutterCore::getXRefs(RVA addr, bool to, bool whole_functi
} else { } else {
xref.to = xrefObject[RJsonKey::to].toVariant().toULongLong(); xref.to = xrefObject[RJsonKey::to].toVariant().toULongLong();
} }
xref.to_str = Core()->cmd("fd " + QString::number(xref.to)).trimmed(); xref.to_str = Core()->cmdRaw(QString("fd %1").arg(xref.to)).trimmed();
xrefList << xref; xrefList << xref;
} }
@ -3441,7 +3446,7 @@ QList<XrefDescription> CutterCore::getXRefs(RVA addr, bool to, bool whole_functi
void CutterCore::addFlag(RVA offset, QString name, RVA size) void CutterCore::addFlag(RVA offset, QString name, RVA size)
{ {
name = sanitizeStringForCommand(name); name = sanitizeStringForCommand(name);
cmd(QString("f %1 %2 @ %3").arg(name).arg(size).arg(offset)); cmdRawAt(QString("f %1 %2").arg(name).arg(size), offset);
emit flagsChanged(); emit flagsChanged();
} }
@ -3516,27 +3521,27 @@ void CutterCore::triggerFunctionRenamed(const QString &prevName, const QString &
void CutterCore::loadPDB(const QString &file) void CutterCore::loadPDB(const QString &file)
{ {
cmd("idp " + sanitizeStringForCommand(file)); cmdRaw("idp " + sanitizeStringForCommand(file));
} }
void CutterCore::openProject(const QString &name) void CutterCore::openProject(const QString &name)
{ {
cmd("Po " + name); cmdRaw("Po " + name);
QString notes = QString::fromUtf8(QByteArray::fromBase64(cmd("Pnj").toUtf8())); QString notes = QString::fromUtf8(QByteArray::fromBase64(cmdRaw("Pnj").toUtf8()));
} }
void CutterCore::saveProject(const QString &name) void CutterCore::saveProject(const QString &name)
{ {
const QString &rv = cmd("Ps " + name.trimmed()).trimmed(); const QString &rv = cmdRaw("Ps " + name.trimmed()).trimmed();
const bool ok = rv == name.trimmed(); const bool ok = rv == name.trimmed();
cmd(QString("Pnj ") + notes.toUtf8().toBase64()); cmdRaw(QString("Pnj %1").arg(QString(notes.toUtf8().toBase64())));
emit projectSaved(ok, name); emit projectSaved(ok, name);
} }
void CutterCore::deleteProject(const QString &name) void CutterCore::deleteProject(const QString &name)
{ {
cmd("Pd " + name); cmdRaw("Pd " + name);
} }
bool CutterCore::isProjectNameValid(const QString &name) bool CutterCore::isProjectNameValid(const QString &name)
@ -3600,10 +3605,10 @@ QString CutterCore::hexdump(RVA address, int size, HexdumpFormats format)
break; break;
} }
return cmd(QString("%1 %2 @ %3") return cmdRawAt(QString("%1 %2")
.arg(command) .arg(command)
.arg(size) .arg(size),
.arg(address)); address);
} }
QByteArray CutterCore::hexStringToBytes(const QString &hex) QByteArray CutterCore::hexStringToBytes(const QString &hex)
@ -3730,10 +3735,10 @@ void CutterCore::commitWriteCache()
{ {
if (!isWriteModeEnabled()) { if (!isWriteModeEnabled()) {
setWriteMode (true); setWriteMode (true);
cmd("wci"); cmdRaw("wci");
cmd("oo"); cmdRaw("oo");
} else { } else {
cmd("wci"); cmdRaw("wci");
} }
} }
@ -3749,10 +3754,10 @@ void CutterCore::setWriteMode(bool enabled)
// Change from read-only to write-mode // Change from read-only to write-mode
if (enabled && !writeModeState) { if (enabled && !writeModeState) {
cmd("oo+"); cmdRaw("oo+");
// Change from write-mode to read-only // Change from write-mode to read-only
} else { } else {
cmd("oo"); cmdRaw("oo");
} }
writeModeChanged (enabled); writeModeChanged (enabled);
} }

View File

@ -76,8 +76,7 @@ public:
/** /**
* @brief Execute a radare2 command \a cmd. By nature, the API * @brief Execute a radare2 command \a cmd. By nature, the API
* is executing raw commands, and thus ignores multiple commands and overcome command injections. * is executing raw commands, and thus ignores multiple commands and overcome command injections.
* @param cmd - a raw command to execute. If multiple commands will be passed (e.g "px 5; pd 7 && pdf") then * @param cmd - a raw command to execute. Passing multiple commands (e.g "px 5; pd 7 && pdf") will result in them treated as arguments to first command.
* only the first command will be executed.
* @return the output of the command * @return the output of the command
*/ */
QString cmdRaw(const char *cmd); QString cmdRaw(const char *cmd);
@ -90,7 +89,8 @@ public:
/** /**
* @brief Execute a radare2 command \a cmd at \a address. The function will preform a silent seek to the address * @brief Execute a radare2 command \a cmd at \a address. The function will preform a silent seek to the address
* without triggering the seekChanged event nor adding new entries to the seek history. By nature, the * without triggering the seekChanged event nor adding new entries to the seek history. By nature, the
* API is executing raw commands, and thus ignores multiple commands and overcome command injections. * API is executing a single command without going through radare2 shell, and thus ignores multiple commands
* and tries to overcome command injections.
* @param cmd - a raw command to execute. If multiple commands will be passed (e.g "px 5; pd 7 && pdf") then * @param cmd - a raw command to execute. If multiple commands will be passed (e.g "px 5; pd 7 && pdf") then
* only the first command will be executed. * only the first command will be executed.
* @param address - an address to which Cutter will temporarily seek. * @param address - an address to which Cutter will temporarily seek.