mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-23 13:25:27 +00:00
Convert various debug code to C API (#2913)
This commit is contained in:
parent
f8744d12c2
commit
46ea1569d2
@ -79,14 +79,14 @@ void AnalysisTask::runTask()
|
|||||||
|
|
||||||
if (!options.shellcode.isNull() && options.shellcode.size() / 2 > 0) {
|
if (!options.shellcode.isNull() && options.shellcode.size() / 2 > 0) {
|
||||||
log(tr("Loading shellcode..."));
|
log(tr("Loading shellcode..."));
|
||||||
Core()->cmdRaw("wx " + options.shellcode);
|
rz_core_write_hexpair(core, core->offset, options.shellcode.toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.endian != InitialOptions::Endianness::Auto) {
|
if (options.endian != InitialOptions::Endianness::Auto) {
|
||||||
Core()->setEndianness(options.endian == InitialOptions::Endianness::Big);
|
Core()->setEndianness(options.endian == InitialOptions::Endianness::Big);
|
||||||
}
|
}
|
||||||
|
|
||||||
Core()->cmdRaw("fs *");
|
rz_flag_space_set(core->flags, "*");
|
||||||
|
|
||||||
if (!options.script.isNull()) {
|
if (!options.script.isNull()) {
|
||||||
log(tr("Executing script..."));
|
log(tr("Executing script..."));
|
||||||
|
@ -408,7 +408,7 @@ bool CutterCore::isDebugTaskInProgress()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask> &task)
|
bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinTask> &task)
|
||||||
{
|
{
|
||||||
asyncCmd(command, task);
|
asyncCmd(command, task);
|
||||||
|
|
||||||
@ -417,7 +417,7 @@ bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask>
|
|||||||
}
|
}
|
||||||
|
|
||||||
connect(task.data(), &RizinCmdTask::finished, task.data(), [this, task]() {
|
connect(task.data(), &RizinCmdTask::finished, task.data(), [this, task]() {
|
||||||
QString res = task.data()->getResult();
|
QString res = qobject_cast<RizinCmdTask *>(task.data())->getResult();
|
||||||
|
|
||||||
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 "
|
msgBox.showMessage("Stopped when attempted to run an invalid instruction. You can "
|
||||||
@ -428,7 +428,7 @@ bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CutterCore::asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task)
|
bool CutterCore::asyncCmd(const char *str, QSharedPointer<RizinTask> &task)
|
||||||
{
|
{
|
||||||
if (!task.isNull()) {
|
if (!task.isNull()) {
|
||||||
return false;
|
return false;
|
||||||
@ -438,8 +438,28 @@ bool CutterCore::asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task)
|
|||||||
|
|
||||||
RVA offset = core->offset;
|
RVA offset = core->offset;
|
||||||
|
|
||||||
task = QSharedPointer<RizinCmdTask>(new RizinCmdTask(str, true));
|
task = QSharedPointer<RizinTask>(new RizinCmdTask(str, true));
|
||||||
connect(task.data(), &RizinCmdTask::finished, task.data(), [this, offset, task]() {
|
connect(task.data(), &RizinTask::finished, task.data(), [this, offset, task]() {
|
||||||
|
CORE_LOCK();
|
||||||
|
|
||||||
|
if (offset != core->offset) {
|
||||||
|
updateSeek();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CutterCore::asyncTask(std::function<void *(RzCore *)> fcn, QSharedPointer<RizinTask> &task)
|
||||||
|
{
|
||||||
|
if (!task.isNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CORE_LOCK();
|
||||||
|
RVA offset = core->offset;
|
||||||
|
task = QSharedPointer<RizinTask>(new RizinFunctionTask(std::move(fcn), true));
|
||||||
|
connect(task.data(), &RizinTask::finished, task.data(), [this, offset, task]() {
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
|
|
||||||
if (offset != core->offset) {
|
if (offset != core->offset) {
|
||||||
@ -819,12 +839,23 @@ void CutterCore::removeString(RVA addr)
|
|||||||
|
|
||||||
QString CutterCore::getString(RVA addr)
|
QString CutterCore::getString(RVA addr)
|
||||||
{
|
{
|
||||||
return cmdRawAt("ps", addr);
|
CORE_LOCK();
|
||||||
|
char *s = (char *)returnAtSeek(
|
||||||
|
[&]() {
|
||||||
|
RzStrStringifyOpt opt = { 0 };
|
||||||
|
opt.buffer = core->block;
|
||||||
|
opt.length = core->blocksize;
|
||||||
|
opt.encoding = rz_str_guess_encoding_from_buffer(core->block, core->blocksize);
|
||||||
|
return rz_str_stringify_raw_buffer(&opt, NULL);
|
||||||
|
},
|
||||||
|
addr);
|
||||||
|
return fromOwnedCharPtr(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CutterCore::getMetaString(RVA addr)
|
QString CutterCore::getMetaString(RVA addr)
|
||||||
{
|
{
|
||||||
return cmdRawAt("Cs.", addr);
|
CORE_LOCK();
|
||||||
|
return rz_meta_get_string(core->analysis, RZ_META_TYPE_STRING, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::setToData(RVA addr, int size, int repeat)
|
void CutterCore::setToData(RVA addr, int size, int repeat)
|
||||||
@ -1595,16 +1626,6 @@ AddrRefs CutterCore::getAddrRefs(RVA addr, int depth)
|
|||||||
return refs;
|
return refs;
|
||||||
}
|
}
|
||||||
|
|
||||||
CutterJson CutterCore::getProcessThreads(int pid)
|
|
||||||
{
|
|
||||||
if (-1 == pid) {
|
|
||||||
// Return threads list of the currently debugged PID
|
|
||||||
return cmdj("dptj");
|
|
||||||
} else {
|
|
||||||
return cmdj("dptj " + QString::number(pid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<Chunk> CutterCore::getHeapChunks(RVA arena_addr)
|
QVector<Chunk> CutterCore::getHeapChunks(RVA arena_addr)
|
||||||
{
|
{
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
@ -1735,16 +1756,6 @@ bool CutterCore::writeHeapChunk(RzHeapChunkSimple *chunk_simple)
|
|||||||
return rz_heap_write_chunk(core, chunk_simple);
|
return rz_heap_write_chunk(core, chunk_simple);
|
||||||
}
|
}
|
||||||
|
|
||||||
CutterJson CutterCore::getChildProcesses(int pid)
|
|
||||||
{
|
|
||||||
// Return the currently debugged process and it's children
|
|
||||||
if (-1 == pid) {
|
|
||||||
return cmdj("dpj");
|
|
||||||
}
|
|
||||||
// Return the given pid and it's child processes
|
|
||||||
return cmdj("dpj " + QString::number(pid));
|
|
||||||
}
|
|
||||||
|
|
||||||
CutterJson CutterCore::getRegisterValues()
|
CutterJson CutterCore::getRegisterValues()
|
||||||
{
|
{
|
||||||
return cmdj("drj");
|
return cmdj("drj");
|
||||||
@ -1831,7 +1842,12 @@ void CutterCore::setRegister(QString regName, QString regValue)
|
|||||||
|
|
||||||
void CutterCore::setCurrentDebugThread(int tid)
|
void CutterCore::setCurrentDebugThread(int tid)
|
||||||
{
|
{
|
||||||
if (!asyncCmd("dpt=" + QString::number(tid), debugTask)) {
|
if (!asyncTask(
|
||||||
|
[=](RzCore *core) {
|
||||||
|
rz_debug_select(core->dbg, core->dbg->pid, tid);
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1851,7 +1867,14 @@ void CutterCore::setCurrentDebugThread(int tid)
|
|||||||
|
|
||||||
void CutterCore::setCurrentDebugProcess(int pid)
|
void CutterCore::setCurrentDebugProcess(int pid)
|
||||||
{
|
{
|
||||||
if (!currentlyDebugging || !asyncCmd("dp=" + QString::number(pid), debugTask)) {
|
if (!currentlyDebugging
|
||||||
|
|| !asyncTask(
|
||||||
|
[=](RzCore *core) {
|
||||||
|
rz_debug_select(core->dbg, pid, core->dbg->tid);
|
||||||
|
core->dbg->main_pid = pid;
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1877,7 +1900,12 @@ void CutterCore::startDebug()
|
|||||||
}
|
}
|
||||||
currentlyOpenFile = getConfig("file.path");
|
currentlyOpenFile = getConfig("file.path");
|
||||||
|
|
||||||
if (!asyncCmd("ood", debugTask)) {
|
if (!asyncTask(
|
||||||
|
[](RzCore *core) {
|
||||||
|
rz_core_file_reopen_debug(core, "");
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1961,7 +1989,15 @@ void CutterCore::attachRemote(const QString &uri)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// connect to a debugger with the given plugin
|
// connect to a debugger with the given plugin
|
||||||
asyncCmd("e cfg.debug=true; oodf " + uri, debugTask);
|
if (!asyncTask(
|
||||||
|
[&](RzCore *core) {
|
||||||
|
setConfig("cfg.debug", true);
|
||||||
|
rz_core_file_reopen_remote_debug(core, uri.toStdString().c_str(), 0);
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
emit debugTaskStateChanged();
|
emit debugTaskStateChanged();
|
||||||
|
|
||||||
connect(debugTask.data(), &RizinTask::finished, this, [this, uri]() {
|
connect(debugTask.data(), &RizinTask::finished, this, [this, uri]() {
|
||||||
@ -2124,7 +2160,12 @@ void CutterCore::continueDebug()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!asyncCmd("dc", debugTask)) {
|
if (!asyncTask(
|
||||||
|
[](RzCore *core) {
|
||||||
|
rz_debug_continue(core->dbg);
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2151,7 +2192,12 @@ void CutterCore::continueBackDebug()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!asyncCmd("dcb", debugTask)) {
|
if (!asyncTask(
|
||||||
|
[](RzCore *core) {
|
||||||
|
rz_debug_continue_back(core->dbg);
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2167,22 +2213,26 @@ void CutterCore::continueBackDebug()
|
|||||||
debugTask->startTask();
|
debugTask->startTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::continueUntilDebug(QString offset)
|
void CutterCore::continueUntilDebug(ut64 offset)
|
||||||
{
|
{
|
||||||
if (!currentlyDebugging) {
|
if (!currentlyDebugging) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentlyEmulating) {
|
if (currentlyEmulating) {
|
||||||
if (!asyncCmdEsil("aecu " + offset, debugTask)) {
|
if (!asyncCmdEsil("aecu " + QString::number(offset), debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!asyncCmd("dcu " + offset, debugTask)) {
|
if (!asyncTask(
|
||||||
|
[=](RzCore *core) {
|
||||||
|
rz_core_debug_continue_until(core, offset, offset);
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit debugTaskStateChanged();
|
emit debugTaskStateChanged();
|
||||||
connect(debugTask.data(), &RizinTask::finished, this, [this]() {
|
connect(debugTask.data(), &RizinTask::finished, this, [this]() {
|
||||||
debugTask.clear();
|
debugTask.clear();
|
||||||
@ -2190,7 +2240,6 @@ void CutterCore::continueUntilDebug(QString offset)
|
|||||||
emit refreshCodeViews();
|
emit refreshCodeViews();
|
||||||
emit debugTaskStateChanged();
|
emit debugTaskStateChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
debugTask->startTask();
|
debugTask->startTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2205,7 +2254,12 @@ void CutterCore::continueUntilCall()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!asyncCmd("dcc", debugTask)) {
|
if (!asyncTask(
|
||||||
|
[](RzCore *core) {
|
||||||
|
rz_core_debug_step_one(core, 0);
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2259,7 +2313,12 @@ void CutterCore::stepDebug()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!asyncCmd("ds", debugTask)) {
|
if (!asyncTask(
|
||||||
|
[](RzCore *core) {
|
||||||
|
rz_core_debug_step_one(core, 1);
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2383,7 +2442,13 @@ void CutterCore::startTraceSession()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!asyncCmd("dts+", debugTask)) {
|
if (!asyncTask(
|
||||||
|
[](RzCore *core) {
|
||||||
|
core->dbg->session = rz_debug_session_new();
|
||||||
|
rz_debug_add_checkpoint(core->dbg);
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2419,7 +2484,13 @@ void CutterCore::stopTraceSession()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!asyncCmd("dts-", debugTask)) {
|
if (!asyncTask(
|
||||||
|
[](RzCore *core) {
|
||||||
|
rz_debug_session_free(core->dbg->session);
|
||||||
|
core->dbg->session = NULL;
|
||||||
|
return (void *)NULL;
|
||||||
|
},
|
||||||
|
debugTask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2517,25 +2588,29 @@ void CutterCore::updateBreakpoint(int index, const BreakpointDescription &config
|
|||||||
|
|
||||||
void CutterCore::delBreakpoint(RVA addr)
|
void CutterCore::delBreakpoint(RVA addr)
|
||||||
{
|
{
|
||||||
cmdRaw("db- " + RzAddressString(addr));
|
CORE_LOCK();
|
||||||
|
rz_bp_del(core->dbg->bp, addr);
|
||||||
emit breakpointsChanged(addr);
|
emit breakpointsChanged(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::delAllBreakpoints()
|
void CutterCore::delAllBreakpoints()
|
||||||
{
|
{
|
||||||
cmdRaw("db-*");
|
CORE_LOCK();
|
||||||
|
rz_bp_del_all(core->dbg->bp);
|
||||||
emit refreshCodeViews();
|
emit refreshCodeViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::enableBreakpoint(RVA addr)
|
void CutterCore::enableBreakpoint(RVA addr)
|
||||||
{
|
{
|
||||||
cmdRaw("dbe " + RzAddressString(addr));
|
CORE_LOCK();
|
||||||
|
rz_bp_enable(core->dbg->bp, addr, true, 1);
|
||||||
emit breakpointsChanged(addr);
|
emit breakpointsChanged(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::disableBreakpoint(RVA addr)
|
void CutterCore::disableBreakpoint(RVA addr)
|
||||||
{
|
{
|
||||||
cmdRaw("dbd " + RzAddressString(addr));
|
CORE_LOCK();
|
||||||
|
rz_bp_enable(core->dbg->bp, addr, false, 1);
|
||||||
emit breakpointsChanged(addr);
|
emit breakpointsChanged(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2631,37 +2706,53 @@ CutterJson CutterCore::getBacktrace()
|
|||||||
return cmdj("dbtj");
|
return cmdj("dbtj");
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ProcessDescription> CutterCore::getAllProcesses()
|
QList<ProcessDescription> CutterCore::getProcessThreads(int pid = -1)
|
||||||
{
|
{
|
||||||
|
CORE_LOCK();
|
||||||
|
RzList *list = rz_debug_pids(core->dbg, pid != -1 ? pid : core->dbg->pid);
|
||||||
|
RzListIter *iter;
|
||||||
|
RzDebugPid *p;
|
||||||
QList<ProcessDescription> ret;
|
QList<ProcessDescription> ret;
|
||||||
|
|
||||||
for (CutterJson procObject : cmdj("dplj")) {
|
CutterRzListForeach (list, iter, RzDebugPid, p) {
|
||||||
ProcessDescription proc;
|
ProcessDescription proc;
|
||||||
|
|
||||||
proc.pid = procObject[RJsonKey::pid].toSt64();
|
proc.current = core->dbg->pid == p->pid;
|
||||||
proc.uid = procObject[RJsonKey::uid].toSt64();
|
proc.ppid = p->ppid;
|
||||||
proc.status = procObject[RJsonKey::status].toString();
|
proc.pid = p->pid;
|
||||||
proc.path = procObject[RJsonKey::path].toString();
|
proc.uid = p->uid;
|
||||||
|
proc.status = static_cast<RzDebugPidState>(p->status);
|
||||||
|
proc.path = p->path;
|
||||||
|
|
||||||
ret << proc;
|
ret << proc;
|
||||||
}
|
}
|
||||||
|
rz_list_free(list);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<ProcessDescription> CutterCore::getAllProcesses()
|
||||||
|
{
|
||||||
|
return getProcessThreads(0);
|
||||||
|
}
|
||||||
|
|
||||||
QList<MemoryMapDescription> CutterCore::getMemoryMap()
|
QList<MemoryMapDescription> CutterCore::getMemoryMap()
|
||||||
{
|
{
|
||||||
|
CORE_LOCK();
|
||||||
|
RzList *list0 = rz_debug_map_list(core->dbg, false);
|
||||||
|
RzList *list1 = rz_debug_map_list(core->dbg, true);
|
||||||
|
rz_list_join(list0, list1);
|
||||||
QList<MemoryMapDescription> ret;
|
QList<MemoryMapDescription> ret;
|
||||||
|
RzListIter *it;
|
||||||
for (CutterJson memMapObject : cmdj("dmj")) {
|
RzDebugMap *map;
|
||||||
|
CutterRzListForeach (list0, it, RzDebugMap, map) {
|
||||||
MemoryMapDescription memMap;
|
MemoryMapDescription memMap;
|
||||||
|
|
||||||
memMap.name = memMapObject[RJsonKey::name].toString();
|
memMap.name = map->name;
|
||||||
memMap.fileName = memMapObject[RJsonKey::file].toString();
|
memMap.fileName = map->file;
|
||||||
memMap.addrStart = memMapObject[RJsonKey::addr].toRVA();
|
memMap.addrStart = map->addr;
|
||||||
memMap.addrEnd = memMapObject[RJsonKey::addr_end].toRVA();
|
memMap.addrEnd = map->addr_end;
|
||||||
memMap.type = memMapObject[RJsonKey::type].toString();
|
memMap.type = map->user ? "u" : "s";
|
||||||
memMap.permission = memMapObject[RJsonKey::perm].toString();
|
memMap.permission = rz_str_rwx_i(map->perm);
|
||||||
|
|
||||||
ret << memMap;
|
ret << memMap;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ class CutterCore;
|
|||||||
class Decompiler;
|
class Decompiler;
|
||||||
class RizinTask;
|
class RizinTask;
|
||||||
class RizinCmdTask;
|
class RizinCmdTask;
|
||||||
|
class RizinFunctionTask;
|
||||||
class RizinTaskDialog;
|
class RizinTaskDialog;
|
||||||
|
|
||||||
#include "common/BasicBlockHighlighter.h"
|
#include "common/BasicBlockHighlighter.h"
|
||||||
@ -99,12 +100,19 @@ public:
|
|||||||
* Once you have setup connections you can start the task with task->startTask()
|
* Once you have setup connections you can start the task with task->startTask()
|
||||||
* If you want to seek to an address, you should use CutterCore::seek.
|
* If you want to seek to an address, you should use CutterCore::seek.
|
||||||
*/
|
*/
|
||||||
bool asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task);
|
bool asyncCmd(const char *str, QSharedPointer<RizinTask> &task);
|
||||||
bool asyncCmd(const QString &str, QSharedPointer<RizinCmdTask> &task)
|
bool asyncCmd(const QString &str, QSharedPointer<RizinTask> &task)
|
||||||
{
|
{
|
||||||
return asyncCmd(str.toUtf8().constData(), task);
|
return asyncCmd(str.toUtf8().constData(), task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief send a task to Rizin
|
||||||
|
* @param fcn the task you want to execute
|
||||||
|
* @return execute successful?
|
||||||
|
*/
|
||||||
|
bool asyncTask(std::function<void *(RzCore *)> fcn, QSharedPointer<RizinTask> &task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute a Rizin command \a cmd. By nature, the API
|
* @brief Execute a Rizin command \a cmd. By nature, the API
|
||||||
* is executing raw commands, and thus ignores multiple commands and overcome command
|
* is executing raw commands, and thus ignores multiple commands and overcome command
|
||||||
@ -148,6 +156,15 @@ public:
|
|||||||
seekSilent(oldOffset);
|
seekSilent(oldOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *returnAtSeek(std::function<void *()> fn, RVA address)
|
||||||
|
{
|
||||||
|
RVA oldOffset = getOffset();
|
||||||
|
seekSilent(address);
|
||||||
|
void *ret = fn();
|
||||||
|
seekSilent(oldOffset);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
CutterJson cmdj(const char *str);
|
CutterJson cmdj(const char *str);
|
||||||
CutterJson cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
|
CutterJson cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
|
||||||
CutterJson cmdjAt(const char *str, RVA address);
|
CutterJson cmdjAt(const char *str, RVA address);
|
||||||
@ -175,8 +192,8 @@ public:
|
|||||||
* Once you have setup connections you can start the task with task->startTask()
|
* Once you have setup connections you can start the task with task->startTask()
|
||||||
* If you want to seek to an address, you should use CutterCore::seek.
|
* If you want to seek to an address, you should use CutterCore::seek.
|
||||||
*/
|
*/
|
||||||
bool asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask> &task);
|
bool asyncCmdEsil(const char *command, QSharedPointer<RizinTask> &task);
|
||||||
bool asyncCmdEsil(const QString &command, QSharedPointer<RizinCmdTask> &task)
|
bool asyncCmdEsil(const QString &command, QSharedPointer<RizinTask> &task)
|
||||||
{
|
{
|
||||||
return asyncCmdEsil(command.toUtf8().constData(), task);
|
return asyncCmdEsil(command.toUtf8().constData(), task);
|
||||||
}
|
}
|
||||||
@ -431,15 +448,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Get a list of a given process's threads
|
* @brief Get a list of a given process's threads
|
||||||
* @param pid The pid of the process, -1 for the currently debugged process
|
* @param pid The pid of the process, -1 for the currently debugged process
|
||||||
* @return JSON object result of dptj
|
* @return List of ProcessDescription
|
||||||
*/
|
*/
|
||||||
CutterJson getProcessThreads(int pid);
|
QList<ProcessDescription> getProcessThreads(int pid);
|
||||||
/**
|
|
||||||
* @brief Get a list of a given process's child processes
|
|
||||||
* @param pid The pid of the process, -1 for the currently debugged process
|
|
||||||
* @return JSON object result of dptj
|
|
||||||
*/
|
|
||||||
CutterJson getChildProcesses(int pid);
|
|
||||||
CutterJson getBacktrace();
|
CutterJson getBacktrace();
|
||||||
/**
|
/**
|
||||||
* @brief Get a list of heap chunks
|
* @brief Get a list of heap chunks
|
||||||
@ -493,7 +504,7 @@ public:
|
|||||||
void continueBackDebug();
|
void continueBackDebug();
|
||||||
void continueUntilCall();
|
void continueUntilCall();
|
||||||
void continueUntilSyscall();
|
void continueUntilSyscall();
|
||||||
void continueUntilDebug(QString offset);
|
void continueUntilDebug(ut64 offset);
|
||||||
void stepDebug();
|
void stepDebug();
|
||||||
void stepOverDebug();
|
void stepOverDebug();
|
||||||
void stepOutDebug();
|
void stepOutDebug();
|
||||||
@ -814,7 +825,7 @@ private:
|
|||||||
bool iocache = false;
|
bool iocache = false;
|
||||||
BasicInstructionHighlighter biHighlighter;
|
BasicInstructionHighlighter biHighlighter;
|
||||||
|
|
||||||
QSharedPointer<RizinCmdTask> debugTask;
|
QSharedPointer<RizinTask> debugTask;
|
||||||
RizinTaskDialog *debugTaskDialog;
|
RizinTaskDialog *debugTaskDialog;
|
||||||
|
|
||||||
QVector<QString> getCutterRCFilePaths() const;
|
QVector<QString> getCutterRCFilePaths() const;
|
||||||
|
@ -339,9 +339,11 @@ struct BreakpointDescription
|
|||||||
|
|
||||||
struct ProcessDescription
|
struct ProcessDescription
|
||||||
{
|
{
|
||||||
|
bool current;
|
||||||
int pid;
|
int pid;
|
||||||
int uid;
|
int uid;
|
||||||
QString status;
|
int ppid;
|
||||||
|
RzDebugPidState status;
|
||||||
QString path;
|
QString path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,8 @@ EditVariablesDialog::EditVariablesDialog(RVA offset, QString initialVar, QWidget
|
|||||||
connect<void (QComboBox::*)(int)>(ui->dropdownLocalVars, &QComboBox::currentIndexChanged, this,
|
connect<void (QComboBox::*)(int)>(ui->dropdownLocalVars, &QComboBox::currentIndexChanged, this,
|
||||||
&EditVariablesDialog::updateFields);
|
&EditVariablesDialog::updateFields);
|
||||||
|
|
||||||
QString fcnName = Core()->cmdRawAt("afn.", offset).trimmed();
|
RzAnalysisFunction *f = rz_analysis_get_function_at(Core()->core()->analysis, offset);
|
||||||
|
QString fcnName = f->name;
|
||||||
functionAddress = offset;
|
functionAddress = offset;
|
||||||
setWindowTitle(tr("Edit Variables in Function: %1").arg(fcnName));
|
setWindowTitle(tr("Edit Variables in Function: %1").arg(fcnName));
|
||||||
|
|
||||||
|
@ -519,7 +519,7 @@ void DecompilerContextMenu::actionAdvancedBreakpointTriggered()
|
|||||||
|
|
||||||
void DecompilerContextMenu::actionContinueUntilTriggered()
|
void DecompilerContextMenu::actionContinueUntilTriggered()
|
||||||
{
|
{
|
||||||
Core()->continueUntilDebug(RzAddressString(offset));
|
Core()->continueUntilDebug(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecompilerContextMenu::actionSetPCTriggered()
|
void DecompilerContextMenu::actionSetPCTriggered()
|
||||||
|
@ -777,7 +777,7 @@ void DisassemblyContextMenu::on_actionAdvancedBreakpoint_triggered()
|
|||||||
|
|
||||||
void DisassemblyContextMenu::on_actionContinueUntil_triggered()
|
void DisassemblyContextMenu::on_actionContinueUntil_triggered()
|
||||||
{
|
{
|
||||||
Core()->continueUntilDebug(RzAddressString(offset));
|
Core()->continueUntilDebug(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassemblyContextMenu::on_actionSetPC_triggered()
|
void DisassemblyContextMenu::on_actionSetPC_triggered()
|
||||||
|
@ -281,7 +281,7 @@ void DebugActions::continueUntilMain()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Core()->continueUntilDebug(QString::number(main_flag->offset));
|
Core()->continueUntilDebug(main_flag->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugActions::attachRemoteDebugger()
|
void DebugActions::attachRemoteDebugger()
|
||||||
|
@ -84,9 +84,9 @@ void ProcessesWidget::updateContents()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProcessesWidget::translateStatus(QString status)
|
QString ProcessesWidget::translateStatus(const char status)
|
||||||
{
|
{
|
||||||
switch (status.toStdString().c_str()[0]) {
|
switch (status) {
|
||||||
case RZ_DBG_PROC_STOP:
|
case RZ_DBG_PROC_STOP:
|
||||||
return "Stopped";
|
return "Stopped";
|
||||||
case RZ_DBG_PROC_RUN:
|
case RZ_DBG_PROC_RUN:
|
||||||
@ -109,12 +109,12 @@ void ProcessesWidget::setProcessesGrid()
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
QFont font;
|
QFont font;
|
||||||
|
|
||||||
for (CutterJson processesItem : Core()->getChildProcesses(DEBUGGED_PID)) {
|
for (const auto &processesItem : Core()->getProcessThreads(DEBUGGED_PID)) {
|
||||||
st64 pid = processesItem["pid"].toSt64();
|
st64 pid = processesItem.pid;
|
||||||
st64 uid = processesItem["uid"].toSt64();
|
st64 uid = processesItem.uid;
|
||||||
QString status = translateStatus(processesItem["status"].toString());
|
QString status = translateStatus(processesItem.status);
|
||||||
QString path = processesItem["path"].toString();
|
QString path = processesItem.path;
|
||||||
bool current = processesItem["current"].toBool();
|
bool current = processesItem.current;
|
||||||
|
|
||||||
// Use bold font to highlight active thread
|
// Use bold font to highlight active thread
|
||||||
font.setBold(current);
|
font.setBold(current);
|
||||||
@ -143,7 +143,6 @@ void ProcessesWidget::setProcessesGrid()
|
|||||||
|
|
||||||
modelFilter->setSourceModel(modelProcesses);
|
modelFilter->setSourceModel(modelProcesses);
|
||||||
ui->viewProcesses->resizeColumnsToContents();
|
ui->viewProcesses->resizeColumnsToContents();
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessesWidget::fontsUpdatedSlot()
|
void ProcessesWidget::fontsUpdatedSlot()
|
||||||
@ -157,24 +156,23 @@ void ProcessesWidget::onActivated(const QModelIndex &index)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int pid = modelFilter->data(index.sibling(index.row(), COLUMN_PID)).toInt();
|
int pid = modelFilter->data(index.sibling(index.row(), COLUMN_PID)).toInt();
|
||||||
|
|
||||||
// Verify that the selected pid is still in the processes list since dp= will
|
// Verify that the selected pid is still in the processes list since dp= will
|
||||||
// attach to any given id. If it isn't found simply update the UI.
|
// attach to any given id. If it isn't found simply update the UI.
|
||||||
for (CutterJson value : Core()->getChildProcesses(DEBUGGED_PID)) {
|
for (const auto &value : Core()->getAllProcesses()) {
|
||||||
QString status = value["status"].toString();
|
if (pid == value.pid) {
|
||||||
if (pid == value["pid"].toSt64()) {
|
|
||||||
if (QString(QChar(RZ_DBG_PROC_ZOMBIE)) == status
|
|
||||||
|| QString(QChar(RZ_DBG_PROC_DEAD)) == status) {
|
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
|
switch (value.status) {
|
||||||
|
case RZ_DBG_PROC_ZOMBIE:
|
||||||
|
case RZ_DBG_PROC_DEAD:
|
||||||
msgBox.setText(tr("Unable to switch to the requested process."));
|
msgBox.setText(tr("Unable to switch to the requested process."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
Core()->setCurrentDebugProcess(pid);
|
Core()->setCurrentDebugProcess(pid);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
updateContents();
|
updateContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ private slots:
|
|||||||
void onActivated(const QModelIndex &index);
|
void onActivated(const QModelIndex &index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString translateStatus(QString status);
|
QString translateStatus(const char status);
|
||||||
std::unique_ptr<Ui::ProcessesWidget> ui;
|
std::unique_ptr<Ui::ProcessesWidget> ui;
|
||||||
QStandardItemModel *modelProcesses;
|
QStandardItemModel *modelProcesses;
|
||||||
ProcessesFilterModel *modelFilter;
|
ProcessesFilterModel *modelFilter;
|
||||||
|
@ -82,9 +82,9 @@ void ThreadsWidget::updateContents()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ThreadsWidget::translateStatus(QString status)
|
QString ThreadsWidget::translateStatus(const char status)
|
||||||
{
|
{
|
||||||
switch (status.toStdString().c_str()[0]) {
|
switch (status) {
|
||||||
case RZ_DBG_PROC_STOP:
|
case RZ_DBG_PROC_STOP:
|
||||||
return "Stopped";
|
return "Stopped";
|
||||||
case RZ_DBG_PROC_RUN:
|
case RZ_DBG_PROC_RUN:
|
||||||
@ -107,11 +107,11 @@ void ThreadsWidget::setThreadsGrid()
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
QFont font;
|
QFont font;
|
||||||
|
|
||||||
for (CutterJson threadsItem : Core()->getProcessThreads(DEBUGGED_PID)) {
|
for (const auto &threadsItem : Core()->getProcessThreads(DEBUGGED_PID)) {
|
||||||
st64 pid = threadsItem["pid"].toSt64();
|
st64 pid = threadsItem.pid;
|
||||||
QString status = translateStatus(threadsItem["status"].toString());
|
QString status = translateStatus(threadsItem.status);
|
||||||
QString path = threadsItem["path"].toString();
|
QString path = threadsItem.path;
|
||||||
bool current = threadsItem["current"].toBool();
|
bool current = threadsItem.current;
|
||||||
// Use bold font to highlight active thread
|
// Use bold font to highlight active thread
|
||||||
font.setBold(current);
|
font.setBold(current);
|
||||||
QStandardItem *rowPid = new QStandardItem(QString::number(pid));
|
QStandardItem *rowPid = new QStandardItem(QString::number(pid));
|
||||||
@ -150,8 +150,8 @@ void ThreadsWidget::onActivated(const QModelIndex &index)
|
|||||||
|
|
||||||
// Verify that the selected tid is still in the threads list since dpt= will
|
// Verify that the selected tid is still in the threads list since dpt= will
|
||||||
// attach to any given id. If it isn't found simply update the UI.
|
// attach to any given id. If it isn't found simply update the UI.
|
||||||
for (CutterJson value : Core()->getProcessThreads(DEBUGGED_PID)) {
|
for (const auto &value : Core()->getProcessThreads(DEBUGGED_PID)) {
|
||||||
if (tid == value["pid"].toSt64()) {
|
if (tid == value.pid) {
|
||||||
Core()->setCurrentDebugThread(tid);
|
Core()->setCurrentDebugThread(tid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ private slots:
|
|||||||
void onActivated(const QModelIndex &index);
|
void onActivated(const QModelIndex &index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString translateStatus(QString status);
|
QString translateStatus(const char status);
|
||||||
std::unique_ptr<Ui::ThreadsWidget> ui;
|
std::unique_ptr<Ui::ThreadsWidget> ui;
|
||||||
QStandardItemModel *modelThreads;
|
QStandardItemModel *modelThreads;
|
||||||
ThreadsFilterModel *modelFilter;
|
ThreadsFilterModel *modelFilter;
|
||||||
|
Loading…
Reference in New Issue
Block a user