Skip to content

Commit

Permalink
Convert de commands to the rzshell (#3083)
Browse files Browse the repository at this point in the history
  • Loading branch information
XVilka authored Oct 10, 2022
1 parent 24503df commit 87e369b
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 137 deletions.
34 changes: 34 additions & 0 deletions librz/core/cesil.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,37 @@ RZ_API bool rz_core_esil_dumpstack(RzAnalysisEsil *esil) {
}
return true;
}

RZ_IPI void rz_core_debug_esil_watch_print(RzDebug *dbg, RzCmdStateOutput *state) {
RzDebugEsilWatchpoint *ew;
RzListIter *iter;
RzList *watchpoints = rz_debug_esil_watch_list(dbg);
rz_cmd_state_output_array_start(state);
rz_cmd_state_output_set_columnsf(state, "sss", "permissions", "kind", "expression");
rz_list_foreach (watchpoints, iter, ew) {
switch (state->mode) {
case RZ_OUTPUT_MODE_JSON:
pj_o(state->d.pj);
pj_ks(state->d.pj, "permissions", rz_str_rwx_i(ew->rwx));
pj_ks(state->d.pj, "kind", ew->dev == 'r' ? "reg" : "mem");
pj_ks(state->d.pj, "expression", ew->expr);
pj_end(state->d.pj);
break;
case RZ_OUTPUT_MODE_TABLE:
rz_table_add_rowf(state->d.t, "sss",
rz_str_rwx_i(ew->rwx), ew->dev == 'r' ? "reg" : "mem",
ew->expr);
break;
case RZ_OUTPUT_MODE_STANDARD:
rz_cons_printf("%s %c %s\n", rz_str_rwx_i(ew->rwx), ew->dev, ew->expr);
break;
case RZ_OUTPUT_MODE_RIZIN:
rz_cons_printf("de %s %c %s\n", rz_str_rwx_i(ew->rwx), ew->dev, ew->expr);
break;
default:
rz_warn_if_reached();
break;
}
}
rz_cmd_state_output_array_end(state);
}
162 changes: 52 additions & 110 deletions librz/core/cmd/cmd_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,24 +68,6 @@ static const char *help_msg_dcu[] = {
NULL
};

static const char *help_msg_de[] = {
"Usage:", "de", "[-sc] [perm] [rm] [expr]",
"de", "", "List esil watchpoints",
"de-*", "", "Delete all esil watchpoints",
"de", " [perm] [rm] [addr|reg|from..to]", "Stop on condition",
"dec", "", "Continue execution until matching expression",
"des", "[?] [N]", "Step-in N instructions with esildebug",
"desu", " [addr]", "Esildebug until specific address",
NULL
};

static const char *help_msg_des[] = {
"Usage:", "des", "[u] [arg]",
"des", " [N]", "step-in N instructions with esildebug",
"desu", " [addr]", "esildebug until specific address",
NULL
};

static const char *help_msg_dk[] = {
"Usage: dk", "", "Signal commands",
"dk", "", "List all signal handlers of child process",
Expand Down Expand Up @@ -1542,95 +1524,6 @@ static void debug_trace_calls(RzCore *core, ut64 from, ut64 to, ut64 final_addr)
rz_cons_break_pop();
}

static void rz_core_debug_esil(RzCore *core, const char *input) {
switch (input[0]) {
case '\0': // "de"
// list
rz_debug_esil_watch_list(core->dbg);
break;
case ' ': // "de "
{
char *line = strdup(input + 1);
char *p, *q;
int done = 0;
int perm = 0, dev = 0;
p = strchr(line, ' ');
if (p) {
*p++ = 0;
if (strchr(line, 'r'))
perm |= RZ_PERM_R;
if (strchr(line, 'w'))
perm |= RZ_PERM_W;
if (strchr(line, 'x'))
perm |= RZ_PERM_X;
q = strchr(p, ' ');
if (q) {
*q++ = 0;
dev = p[0];
if (q) {
rz_debug_esil_watch(core->dbg, perm, dev, q);
done = 1;
}
}
}
if (!done) {
const char *help_de_msg[] = {
"Usage:", "de", " [perm] [reg|mem] [expr]",
NULL
};
rz_core_cmd_help(core, help_de_msg);
}
free(line);
} break;
case '-': // "de-"
rz_debug_esil_watch_reset(core->dbg);
break;
case 'c': // "dec"
if (rz_debug_esil_watch_empty(core->dbg)) {
RZ_LOG_ERROR("core: Error: no esil watchpoints defined\n");
} else {
rz_core_analysis_esil_reinit(core);
rz_debug_esil_prestep(core->dbg, rz_config_get_i(core->config, "esil.prestep"));
rz_debug_esil_continue(core->dbg);
}
break;
case 's': // "des"
if (input[1] == 'u' && input[2] == ' ') { // "desu"
ut64 addr, naddr, fin = rz_num_math(core->num, input + 2);
rz_core_analysis_esil_reinit(core);
addr = rz_debug_reg_get(core->dbg, "PC");
while (addr != fin) {
rz_debug_esil_prestep(core->dbg, rz_config_get_i(core->config, "esil.prestep"));
rz_debug_esil_step(core->dbg, 1);
naddr = rz_debug_reg_get(core->dbg, "PC");
if (naddr == addr) {
RZ_LOG_WARN("core: Detected loophole\n");
break;
}
addr = naddr;
}
} else if (input[1] == '?' || !input[1]) {
rz_core_cmd_help(core, help_msg_des);
} else {
rz_core_analysis_esil_reinit(core);
rz_debug_esil_prestep(core->dbg, rz_config_get_i(core->config, "esil.prestep"));
// continue
rz_debug_esil_step(core->dbg, rz_num_math(core->num, input + 1));
}
break;
case '?': // "de?"
default: {
rz_core_cmd_help(core, help_msg_de);
// TODO #7967 help refactor: move to detail
rz_cons_printf("Examples:\n"
" de r r rip # stop when reads rip\n"
" de rw m ADDR # stop when read or write in ADDR\n"
" de w r rdx # stop when rdx register is modified\n"
" de x m FROM..TO # stop when rip in range\n");
} break;
}
}

static void rz_core_debug_kill(RzCore *core, const char *input) {
if (!input || *input == '?') {
if (input && input[1]) {
Expand Down Expand Up @@ -2044,9 +1937,6 @@ RZ_IPI int rz_cmd_debug(void *data, const char *input) {
int follow = 0;

switch (input[0]) {
case 'e': // "de"
rz_core_debug_esil(core, input + 1);
break;
case 'k': // "dk"
rz_core_debug_kill(core, input + 1);
break;
Expand Down Expand Up @@ -3415,3 +3305,55 @@ RZ_IPI RzCmdStatus rz_cmd_debug_window_identify_handler(RzCore *core, int argc,
return RZ_CMD_STATUS_ERROR;
#endif
}

RZ_IPI RzCmdStatus rz_cmd_debug_esil_add_handler(RzCore *core, int argc, const char **argv) {
int perm = rz_str_rwx(argv[1]);
int kind = (int)argv[2][0];
rz_debug_esil_watch(core->dbg, perm, kind, argv[3]);
return RZ_CMD_STATUS_OK;
}

RZ_IPI RzCmdStatus rz_cmd_debug_esil_remove_handler(RzCore *core, int argc, const char **argv) {
rz_debug_esil_watch_reset(core->dbg);
return RZ_CMD_STATUS_OK;
}

RZ_IPI RzCmdStatus rz_cmd_debug_esil_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
rz_core_debug_esil_watch_print(core->dbg, state);
return RZ_CMD_STATUS_OK;
}

RZ_IPI RzCmdStatus rz_cmd_debug_esil_continue_handler(RzCore *core, int argc, const char **argv) {
if (rz_debug_esil_watch_empty(core->dbg)) {
RZ_LOG_ERROR("core: Error: no esil watchpoints defined\n");
return RZ_CMD_STATUS_ERROR;
}
rz_core_analysis_esil_reinit(core);
rz_debug_esil_prestep(core->dbg, rz_config_get_b(core->config, "esil.prestep"));
rz_debug_esil_continue(core->dbg);
return RZ_CMD_STATUS_OK;
}

RZ_IPI RzCmdStatus rz_cmd_debug_esil_step_handler(RzCore *core, int argc, const char **argv) {
rz_core_analysis_esil_reinit(core);
rz_debug_esil_prestep(core->dbg, rz_config_get_b(core->config, "esil.prestep"));
rz_debug_esil_step(core->dbg, rz_num_math(core->num, argv[1]));
return RZ_CMD_STATUS_OK;
}

RZ_IPI RzCmdStatus rz_cmd_debug_esil_step_until_handler(RzCore *core, int argc, const char **argv) {
ut64 fin = rz_num_math(core->num, argv[1]);
rz_core_analysis_esil_reinit(core);
ut64 addr = rz_debug_reg_get(core->dbg, "PC");
while (addr != fin) {
rz_debug_esil_prestep(core->dbg, rz_config_get_b(core->config, "esil.prestep"));
rz_debug_esil_step(core->dbg, 1);
ut64 naddr = rz_debug_reg_get(core->dbg, "PC");
if (naddr == addr) {
RZ_LOG_WARN("core: Detected loophole\n");
break;
}
addr = naddr;
}
return RZ_CMD_STATUS_OK;
}
61 changes: 61 additions & 0 deletions librz/core/cmd_descs/cmd_debug.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,67 @@ commands:
type: RZ_CMD_ARG_TYPE_NUM
- name: len
type: RZ_CMD_ARG_TYPE_NUM
- name: de
summary: Manage ESIL watchpoints
subcommands:
- name: de
summary: Add ESIL watchpoint
cname: cmd_debug_esil_add
args:
- name: perm
type: RZ_CMD_ARG_TYPE_STRING
- name: kind
type: RZ_CMD_ARG_TYPE_CHOICES
choices:
- reg
- mem
- name: expression
type: RZ_CMD_ARG_TYPE_STRING
details:
- name: Examples
entries:
- text: de
arg_str: "r reg rip"
comment: Stop when reads RIP register
- text: de
arg_str: "rw mem ADDR"
comment: Stop when read or write in ADDR
- text: de
arg_str: "w r rdx"
comment: Stop when rdx register is modified
- text: de
arg_str: "x m FROM..TO"
comment: Stop when rip in range
- name: de-*
summary: Remove all ESIL watchpoints
cname: cmd_debug_esil_remove
args: []
- name: del
summary: List all ESIL watchpoints
cname: cmd_debug_esil_list
args: []
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_JSON
- RZ_OUTPUT_MODE_TABLE
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_RIZIN
- name: dec
summary: Continue execution until matching expression
cname: cmd_debug_esil_continue
args: []
- name: des
summary: Step-in <N> instructions with ESIL
cname: cmd_debug_esil_step
args:
- name: N
type: RZ_CMD_ARG_TYPE_NUM
- name: desu
summary: Step until specified <address>
cname: cmd_debug_esil_step_until
args:
- name: <address>
type: RZ_CMD_ARG_TYPE_RZNUM
- name: dg
summary: Generate core dump file
cname: cmd_debug_core_dump_generate
Expand Down
Loading

0 comments on commit 87e369b

Please sign in to comment.