Convert ab commands to rzshell (#2395)

This commit is contained in:
Paul I 2022-04-02 16:27:55 +03:00 committed by GitHub
parent 58ef135061
commit 5ea3630c35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 320 additions and 428 deletions

View file

@ -19,7 +19,6 @@ static const char *help_msg_a[] = {
"a8", " [hexpairs]", "analyze bytes",
"ab", "[?] [addr]", "analyze block",
"aC", "[?]", "analyze function call",
"aCe", "[?]", "same as aC, but uses esil with abte to emulate the function",
"ad", "[?]", "analyze data trampoline (wip)",
"ad", " [from] [to]", "analyze data pointers to (from-to)",
"ae", "[?] [expr]", "analyze opcode eval expression (see ao)",
@ -90,34 +89,6 @@ static const char *help_msg_aar[] = {
NULL
};
static const char *help_msg_ab[] = {
"Usage:", "ab", "analyze block",
"ab", " [addr]", "show basic block information at given address",
"aba", " [addr]", "analyze esil accesses in basic block (see aea?)",
"abj", " [addr]", "display basic block information in JSON",
"abl", "[,qj]", "list all basic blocks",
"abx", " [hexpair-bytes]", "analyze N bytes",
"abt", "[?] [addr] [num]", "find num paths from current offset to addr",
NULL
};
static const char *help_msg_abl[] = {
"Usage:", "abl", "analyzed basicblocks listing",
"abl", "", "list all program-wide basic blocks analyzed",
"abl,", " [table-query]", "render the list using a table",
"ablj", "", "in json format",
"ablq", "", "in quiet format",
NULL
};
static const char *help_msg_abt[] = {
"Usage:", "abt", "[addr] [num] # find num paths from current offset to addr",
"abt", " [addr] [num]", "find num paths from current offset to addr",
"abte", " [addr]", "emulate from beginning of function to the given address",
"abtj", " [addr] [num]", "display paths in JSON",
NULL
};
static const char *help_msg_ad[] = {
"Usage:", "ad", "[kt] [...]",
"ad", " [N] [D]", "analyze N data words at D depth",
@ -1335,24 +1306,6 @@ static void core_analysis_bytes_standard(RzCore *core, const ut8 *buf, int len,
#undef printline
#undef printline_noarg
static RzList *get_xrefs(RzAnalysisBlock *block) {
RzListIter *iter;
RzAnalysisXRef *xref;
RzList *list = NULL;
size_t i;
for (i = 0; i < block->ninstr; i++) {
ut64 ia = block->addr + block->op_pos[i];
RzList *xrefs = rz_analysis_xrefs_get_to(block->analysis, ia);
rz_list_foreach (xrefs, iter, xref) {
if (!list) {
list = rz_list_newf(free);
}
rz_list_push(list, ut64_new(xref->from));
}
}
return list;
}
static char *fcnjoin(RzList *list) {
RzAnalysisFunction *n;
RzListIter *iter;
@ -1379,182 +1332,6 @@ static char *ut64join(RzList *list) {
return s;
}
static RzList *get_calls(RzAnalysisBlock *block) {
RzList *list = NULL;
RzAnalysisOp op;
ut8 *data = malloc(block->size);
if (data) {
block->analysis->iob.read_at(block->analysis->iob.io, block->addr, data, block->size);
size_t i;
for (i = 0; i < block->size; i++) {
int ret = rz_analysis_op(block->analysis, &op, block->addr + i, data + i, block->size - i, RZ_ANALYSIS_OP_MASK_HINT);
if (ret < 1) {
continue;
}
if (op.type == RZ_ANALYSIS_OP_TYPE_CALL) {
if (!list) {
list = rz_list_newf(free);
}
rz_list_push(list, ut64_new(op.jump));
}
rz_analysis_op_fini(&op);
if (op.size > 0) {
i += op.size - 1;
}
}
}
return list;
}
static void analysis_bb_list(RzCore *core, const char *input) {
const int mode = *input;
PJ *pj = NULL;
RzTable *table = NULL;
RBIter iter;
RzAnalysisBlock *block;
if (mode == 'j') {
pj = pj_new();
pj_o(pj);
pj_ka(pj, "blocks");
} else if (mode == ',' || mode == 't') {
table = rz_table_new();
RzTableColumnType *s = rz_table_type("string");
RzTableColumnType *n = rz_table_type("number");
rz_table_add_column(table, n, "addr", 0);
rz_table_add_column(table, n, "size", 0);
rz_table_add_column(table, n, "traced", 0);
rz_table_add_column(table, n, "ninstr", 0);
rz_table_add_column(table, s, "jump", 0);
rz_table_add_column(table, s, "fail", 0);
rz_table_add_column(table, s, "fcns", 0);
rz_table_add_column(table, s, "calls", 0);
rz_table_add_column(table, s, "xrefs", 0);
}
rz_rbtree_foreach (core->analysis->bb_tree, iter, block, RzAnalysisBlock, _rb) {
RzList *xrefs = get_xrefs(block);
RzList *calls = get_calls(block);
switch (mode) {
case 'j':
pj_o(pj);
char *addr = rz_str_newf("0x%" PFMT64x, block->addr);
pj_ks(pj, "addr", addr);
free(addr);
pj_kb(pj, "traced", block->traced);
pj_kn(pj, "ninstr", block->ninstr);
pj_kn(pj, "size", block->size);
if (block->jump != UT64_MAX) {
pj_kn(pj, "jump", block->jump);
}
if (block->fail != UT64_MAX) {
pj_kn(pj, "fail", block->fail);
}
if (xrefs) {
pj_ka(pj, "xrefs");
RzListIter *iter2;
ut64 *addr;
rz_list_foreach (xrefs, iter2, addr) {
pj_n(pj, *addr);
}
pj_end(pj);
}
if (calls) {
pj_ka(pj, "calls");
RzListIter *iter2;
ut64 *addr;
rz_list_foreach (calls, iter2, addr) {
pj_n(pj, *addr);
}
pj_end(pj);
}
pj_ka(pj, "fcns");
RzListIter *iter2;
RzAnalysisFunction *fcn;
rz_list_foreach (block->fcns, iter2, fcn) {
pj_n(pj, fcn->addr);
}
pj_end(pj);
pj_end(pj);
break;
case ',':
case 't': {
char *jump = block->jump != UT64_MAX ? rz_str_newf("0x%08" PFMT64x, block->jump) : strdup("");
char *fail = block->fail != UT64_MAX ? rz_str_newf("0x%08" PFMT64x, block->fail) : strdup("");
char *call = ut64join(calls);
char *xref = ut64join(calls);
char *fcns = fcnjoin(block->fcns);
rz_table_add_rowf(table, "xnddsssss",
block->addr,
block->size,
block->traced,
block->ninstr,
jump,
fail,
fcns,
call,
xref);
free(jump);
free(fail);
free(call);
free(xref);
free(fcns);
} break;
case 'q':
rz_cons_printf("0x%08" PFMT64x "\n", block->addr);
break;
default:
rz_cons_printf("0x%08" PFMT64x, block->addr);
if (block->jump != UT64_MAX) {
rz_cons_printf(" .j 0x%08" PFMT64x, block->jump);
}
if (block->fail != UT64_MAX) {
rz_cons_printf(" .f 0x%08" PFMT64x, block->fail);
}
if (xrefs) {
RzListIter *iter2;
rz_cons_printf(" .x");
ut64 *addr;
rz_list_foreach (xrefs, iter2, addr) {
rz_cons_printf(" 0x%08" PFMT64x, *addr);
}
}
if (calls) {
rz_cons_printf(" .c");
RzListIter *iter2;
ut64 *addr;
rz_list_foreach (calls, iter2, addr) {
rz_cons_printf(" 0x%08" PFMT64x, *addr);
}
}
if (block->fcns) {
RzListIter *iter2;
RzAnalysisFunction *fcn;
rz_list_foreach (block->fcns, iter2, fcn) {
rz_cons_printf(" .u 0x%" PFMT64x, fcn->addr);
}
}
rz_cons_printf(" .s %" PFMT64d "\n", block->size);
}
rz_list_free(calls);
}
if (mode == 'j') {
pj_end(pj);
pj_end(pj);
char *j = pj_drain(pj);
rz_cons_println(j);
free(j);
} else if (mode == 't' || mode == ',') {
char *q = strchr(input, ' ');
if (q) {
rz_table_query(table, q + 1);
}
char *s = rz_table_tofancystring(table);
rz_cons_println(s);
free(s);
rz_table_free(table);
}
}
static void rz_core_analysis_nofunclist(RzCore *core, const char *input) {
int minlen = (int)(input[0] == ' ') ? rz_num_math(core->num, input + 1) : 16;
ut64 code_size = rz_num_get(core->num, "$SS");
@ -4964,92 +4741,6 @@ static void cmd_analysis_aad(RzCore *core, const char *input) {
rz_list_free(list);
}
static void cmd_analysis_abt(RzCore *core, const char *input) {
switch (*input) {
case 'e': // "abte"
{
int n = 1;
char *p = strchr(input + 1, ' ');
if (!p) {
eprintf("Usage: abte [addr] # emulate from beginning of function to the given address.\n");
return;
}
ut64 addr = rz_num_math(core->num, p + 1);
RzList *paths = rz_core_analysis_graph_to(core, addr, n);
if (paths) {
RzAnalysisBlock *bb;
RzList *path;
RzListIter *pathi;
RzListIter *bbi;
rz_cons_printf("f+ orip @ `drq PC`\n");
rz_list_foreach (paths, pathi, path) {
rz_list_foreach (path, bbi, bb) {
rz_cons_printf("# 0x%08" PFMT64x "\n", bb->addr);
if (addr >= bb->addr && addr < bb->addr + bb->size) {
rz_cons_printf("aepc 0x%08" PFMT64x "\n", bb->addr);
rz_cons_printf("aesou 0x%08" PFMT64x "\n", addr);
} else {
rz_cons_printf("aepc 0x%08" PFMT64x "\n", bb->addr);
rz_cons_printf("aesou 0x%08" PFMT64x "\n", bb->addr + bb->size);
}
}
rz_cons_newline();
rz_list_purge(path);
free(path);
}
rz_list_purge(paths);
rz_cons_printf("aepc orip\n");
free(paths);
}
} break;
case '?': // "abt?"
rz_core_cmd_help(core, help_msg_abt);
break;
case 'j': { // "abtj"
ut64 addr = rz_num_math(core->num, input + 1);
RzAnalysisBlock *block = rz_analysis_get_block_at(core->analysis, core->offset);
if (!block) {
break;
}
RzList *path = rz_analysis_block_shortest_path(block, addr);
PJ *pj = pj_new();
if (pj) {
pj_a(pj);
if (path) {
RzListIter *it;
rz_list_foreach (path, it, block) {
pj_n(pj, block->addr);
}
}
pj_end(pj);
rz_cons_println(pj_string(pj));
pj_free(pj);
}
rz_list_free(path);
break;
}
case ' ': { // "abt "
ut64 addr = rz_num_math(core->num, input + 1);
RzAnalysisBlock *block = rz_analysis_get_block_at(core->analysis, core->offset);
if (!block) {
break;
}
RzList *path = rz_analysis_block_shortest_path(block, addr);
if (path) {
RzListIter *it;
rz_list_foreach (path, it, block) {
rz_cons_printf("0x%08" PFMT64x "\n", block->addr);
}
rz_list_free(path);
}
break;
}
case '\0': // "abt"
rz_core_cmdf(core, "abl, addr/eq/0x%08" PFMT64x, core->offset);
break;
}
}
static int cmd_analysis_all(RzCore *core, const char *input) {
switch (*input) {
case '?': // "aa?"
@ -5459,30 +5150,20 @@ static void show_reg_args(RzCore *core, int nargs, RzStrBuf *sb) {
// ripped from disasm.c: dupe code from there
// TODO: Implement aC* and aCj
static void cmd_analysis_aC(RzCore *core, const char *input) {
bool is_aCer = false;
const char *cc = rz_analysis_cc_default(core->analysis);
RzAnalysisFuncArg *arg;
RzListIter *iter;
RzListIter *nextele;
const char *iarg = strchr(input, ' ');
if (input[0] == 'e' && input[1] == 'f') { // "aCf"
// hacky :D
rz_core_cmdf(core, ".aCe* $$ @@=`pdr~call`");
return;
}
if (iarg) {
iarg++;
}
if (!iarg) {
eprintf("Usage: aC[e] [addr-of-call] # analyze call args (aCe does esil emulation with abte)\n");
eprintf("Usage: aC [addr-of-call] # analyze call args\n");
return;
}
RzStrBuf *sb = rz_strbuf_new("");
ut64 pcv = rz_num_math(core->num, iarg);
if (input[0] == 'e') { // "aCe"
is_aCer = (input[1] == '*');
rz_core_cmdf(core, ".abte 0x%08" PFMT64x, pcv);
}
RzAnalysisOp *op = rz_core_analysis_op(core, pcv, -1);
if (!op) {
rz_strbuf_free(sb);
@ -5523,13 +5204,8 @@ static void cmd_analysis_aC(RzCore *core, const char *input) {
}
free(fcn_type_str);
} else {
if (is_aCer) {
show_reg_args(core, -1, sb);
go_on = true;
} else {
show_reg_args(core, -1, NULL);
go_on = false;
}
show_reg_args(core, -1, NULL);
go_on = false;
}
}
if (go_on) {
@ -5581,15 +5257,7 @@ static void cmd_analysis_aC(RzCore *core, const char *input) {
rz_list_free(list);
}
char *s = rz_strbuf_drain(sb);
if (is_aCer) {
char *u = rz_base64_encode_dyn((const ut8 *)s, strlen(s));
if (u) {
rz_cons_printf("CCu base64:%s\n", u);
free(u);
}
} else {
rz_cons_printf("%s\n", s);
}
rz_cons_printf("%s\n", s);
free(s);
}
@ -5625,67 +5293,6 @@ RZ_IPI int rz_cmd_analysis(void *data, const char *input) {
}
free(buf);
} break;
case 'b': // "ab"
switch (input[1]) {
case 'a': // "aba"
rz_core_cmdf(core, "aeab%s", input + 1);
break;
case ',': // "ab,"
case 't': // "abt"
cmd_analysis_abt(core, input + 2);
break;
case 'l': // "abl"
if (input[2] == '?') {
rz_core_cmd_help(core, help_msg_abl);
} else {
analysis_bb_list(core, input + 2);
}
break;
case 'j': { // "abj"
ut64 addr = core->offset;
if (input[2] && input[2] != '.') {
addr = rz_num_math(core->num, input + 2);
}
RzAnalysisBlock *bb = rz_analysis_find_most_relevant_block_in(core->analysis, addr);
if (!bb) {
eprintf("No basic block at 0x%" PFMT64x "\n", addr);
break;
}
RzCmdStateOutput state = { 0 };
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON)) {
break;
}
rz_core_analysis_bb_info_print(core, bb, addr, &state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
break;
}
case 0:
case ' ': { // "ab "
// find block
ut64 addr = core->offset;
if (input[1] && input[1] != '.') {
addr = rz_num_math(core->num, input + 1);
}
RzAnalysisBlock *bb = rz_analysis_find_most_relevant_block_in(core->analysis, addr);
if (!bb) {
eprintf("No basic block at 0x%" PFMT64x "\n", addr);
break;
}
RzCmdStateOutput state = { 0 };
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG)) {
break;
}
rz_core_analysis_bb_info_print(core, bb, addr, &state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
break;
}
default:
rz_core_cmd_help(core, help_msg_ab);
break;
}
break;
case 'C': // "aC"
cmd_analysis_aC(core, input + 1);
break;
@ -9144,3 +8751,214 @@ RZ_IPI RzCmdStatus rz_analysis_all_esil_functions_handler(RzCore *core, int argc
}
return RZ_CMD_STATUS_OK;
}
static RzList *get_xrefs(RzAnalysisBlock *block) {
RzListIter *iter;
RzAnalysisXRef *xref;
RzList *list = NULL;
size_t i;
for (i = 0; i < block->ninstr; i++) {
ut64 ia = block->addr + block->op_pos[i];
RzList *xrefs = rz_analysis_xrefs_get_to(block->analysis, ia);
rz_list_foreach (xrefs, iter, xref) {
if (!list) {
list = rz_list_newf(free);
}
rz_list_push(list, ut64_new(xref->from));
}
}
return list;
}
static RzList *get_calls(RzAnalysisBlock *block) {
ut8 *data = malloc(block->size);
if (!data) {
return NULL;
}
RzList *list = NULL;
RzAnalysisOp op;
block->analysis->iob.read_at(block->analysis->iob.io, block->addr, data, block->size);
for (size_t i = 0; i < block->size; i++) {
int ret = rz_analysis_op(block->analysis, &op, block->addr + i, data + i, block->size - i, RZ_ANALYSIS_OP_MASK_HINT);
if (ret < 1) {
continue;
}
if (op.type == RZ_ANALYSIS_OP_TYPE_CALL) {
if (!list) {
list = rz_list_newf(free);
}
rz_list_push(list, ut64_new(op.jump));
}
rz_analysis_op_fini(&op);
if (op.size > 0) {
i += op.size - 1;
}
}
return list;
}
RZ_IPI RzCmdStatus rz_analysis_basic_block_info_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
RzAnalysisBlock *bb = rz_analysis_find_most_relevant_block_in(core->analysis, core->offset);
if (!bb) {
RZ_LOG_ERROR("No basic block at 0x%" PFMT64x "\n", core->offset);
return RZ_CMD_STATUS_ERROR;
}
rz_core_analysis_bb_info_print(core, bb, core->offset, state);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_analysis_basic_block_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
PJ *pj = state->mode == RZ_OUTPUT_MODE_JSON ? state->d.pj : NULL;
RzTable *table = state->mode == RZ_OUTPUT_MODE_TABLE ? state->d.t : NULL;
rz_cmd_state_output_array_start(state);
rz_cmd_state_output_set_columnsf(state, "xnddsssss", "addr", "size",
"traced", "ninstr", "jump", "fail", "fcns", "calls", "xrefs");
RzCmdStatus status = RZ_CMD_STATUS_OK;
RBIter iter;
RzAnalysisBlock *block;
rz_rbtree_foreach (core->analysis->bb_tree, iter, block, RzAnalysisBlock, _rb) {
RzList *xrefs = get_xrefs(block);
RzList *calls = get_calls(block);
switch (state->mode) {
case RZ_OUTPUT_MODE_JSON:
pj_o(pj);
pj_kn(pj, "addr", block->addr);
pj_kb(pj, "traced", block->traced);
pj_kn(pj, "ninstr", block->ninstr);
pj_kn(pj, "size", block->size);
if (block->jump != UT64_MAX) {
pj_kn(pj, "jump", block->jump);
}
if (block->fail != UT64_MAX) {
pj_kn(pj, "fail", block->fail);
}
if (xrefs) {
pj_ka(pj, "xrefs");
RzListIter *iter2;
ut64 *addr;
rz_list_foreach (xrefs, iter2, addr) {
pj_n(pj, *addr);
}
pj_end(pj);
}
if (calls) {
pj_ka(pj, "calls");
RzListIter *iter2;
ut64 *addr;
rz_list_foreach (calls, iter2, addr) {
pj_n(pj, *addr);
}
pj_end(pj);
}
pj_ka(pj, "fcns");
RzListIter *iter2;
RzAnalysisFunction *fcn;
rz_list_foreach (block->fcns, iter2, fcn) {
pj_n(pj, fcn->addr);
}
pj_end(pj);
pj_end(pj);
break;
case RZ_OUTPUT_MODE_TABLE: {
char *jump = block->jump != UT64_MAX ? rz_str_newf("0x%08" PFMT64x, block->jump) : strdup("");
char *fail = block->fail != UT64_MAX ? rz_str_newf("0x%08" PFMT64x, block->fail) : strdup("");
char *call = ut64join(calls);
char *xref = ut64join(calls);
char *fcns = fcnjoin(block->fcns);
rz_table_add_rowf(table, "xnddsssss",
block->addr,
block->size,
block->traced,
block->ninstr,
jump,
fail,
fcns,
call,
xref);
free(jump);
free(fail);
free(call);
free(xref);
free(fcns);
} break;
case RZ_OUTPUT_MODE_QUIET:
rz_cons_printf("0x%08" PFMT64x "\n", block->addr);
break;
case RZ_OUTPUT_MODE_STANDARD:
rz_cons_printf("0x%08" PFMT64x, block->addr);
if (block->jump != UT64_MAX) {
rz_cons_printf(" .j 0x%08" PFMT64x, block->jump);
}
if (block->fail != UT64_MAX) {
rz_cons_printf(" .f 0x%08" PFMT64x, block->fail);
}
if (xrefs) {
RzListIter *iter2;
rz_cons_printf(" .x");
ut64 *addr;
rz_list_foreach (xrefs, iter2, addr) {
rz_cons_printf(" 0x%08" PFMT64x, *addr);
}
}
if (calls) {
rz_cons_printf(" .c");
RzListIter *iter2;
ut64 *addr;
rz_list_foreach (calls, iter2, addr) {
rz_cons_printf(" 0x%08" PFMT64x, *addr);
}
}
if (block->fcns) {
RzListIter *iter2;
RzAnalysisFunction *fcn;
rz_list_foreach (block->fcns, iter2, fcn) {
rz_cons_printf(" .u 0x%" PFMT64x, fcn->addr);
}
}
rz_cons_printf(" .s %" PFMT64d "\n", block->size);
break;
default:
rz_warn_if_reached();
status = RZ_CMD_STATUS_WRONG_ARGS;
iter.len = 0;
}
rz_list_free(xrefs);
rz_list_free(calls);
}
rz_cmd_state_output_array_end(state);
return status;
}
RZ_IPI RzCmdStatus rz_analysis_basic_block_find_paths_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
ut64 addr = rz_num_math(core->num, argv[1]);
RzAnalysisBlock *block = rz_analysis_get_block_at(core->analysis, core->offset);
if (!block) {
RZ_LOG_ERROR("No basic block at 0x%" PFMT64x "\n", core->offset);
return RZ_CMD_STATUS_ERROR;
}
RzList *path = rz_analysis_block_shortest_path(block, addr);
if (!path) {
return RZ_CMD_STATUS_ERROR;
}
RzCmdStatus status = RZ_CMD_STATUS_OK;
rz_cmd_state_output_array_start(state);
RzListIter *it;
rz_list_foreach (path, it, block) {
switch (state->mode) {
case RZ_OUTPUT_MODE_JSON:
pj_n(state->d.pj, block->addr);
break;
case RZ_OUTPUT_MODE_STANDARD:
rz_cons_printf("0x%08" PFMT64x "\n", block->addr);
break;
default:
rz_warn_if_reached();
status = RZ_CMD_STATUS_WRONG_ARGS;
it = NULL;
}
}
rz_cmd_state_output_array_end(state);
rz_list_free(path);
return status;
}

View file

@ -1579,3 +1579,38 @@ commands:
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
- name: ab
summary: Basic blocks
subcommands:
- name: abi
summary: Show basic block information in current seek
cname: analysis_basic_block_info
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_LONG
- RZ_OUTPUT_MODE_JSON
- RZ_OUTPUT_MODE_RIZIN
args: []
- name: abl
summary: List all basic blocks
cname: analysis_basic_block_list
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_LONG
- RZ_OUTPUT_MODE_JSON
- RZ_OUTPUT_MODE_RIZIN
- RZ_OUTPUT_MODE_TABLE
- RZ_OUTPUT_MODE_QUIET
args: []
- name: abt
summary: Find paths from current seek to the given address
cname: analysis_basic_block_find_paths
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
args:
- name: addr
type: RZ_CMD_ARG_TYPE_RZNUM

View file

@ -190,6 +190,7 @@ static const RzCmdDescArg analyze_opcode_args[2];
static const RzCmdDescArg analyze_cycles_args[2];
static const RzCmdDescArg convert_mne_args[2];
static const RzCmdDescArg analyse_name_args[2];
static const RzCmdDescArg analysis_basic_block_find_paths_args[2];
static const RzCmdDescArg block_args[2];
static const RzCmdDescArg block_decrease_args[2];
static const RzCmdDescArg block_increase_args[2];
@ -3806,6 +3807,39 @@ static const RzCmdDescHelp analyse_name_help = {
.args = analyse_name_args,
};
static const RzCmdDescHelp ab_help = {
.summary = "Basic blocks",
};
static const RzCmdDescArg analysis_basic_block_info_args[] = {
{ 0 },
};
static const RzCmdDescHelp analysis_basic_block_info_help = {
.summary = "Show basic block information in current seek",
.args = analysis_basic_block_info_args,
};
static const RzCmdDescArg analysis_basic_block_list_args[] = {
{ 0 },
};
static const RzCmdDescHelp analysis_basic_block_list_help = {
.summary = "List all basic blocks",
.args = analysis_basic_block_list_args,
};
static const RzCmdDescArg analysis_basic_block_find_paths_args[] = {
{
.name = "addr",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp analysis_basic_block_find_paths_help = {
.summary = "Find paths from current seek to the given address",
.args = analysis_basic_block_find_paths_args,
};
static const RzCmdDescHelp b_help = {
.summary = "Display or change the block size",
};
@ -13525,6 +13559,17 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
RzCmdDesc *analyse_name_cd = rz_cmd_desc_argv_state_new(core->rcmd, cmd_analysis_cd, "an", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_analyse_name_handler, &analyse_name_help);
rz_warn_if_fail(analyse_name_cd);
RzCmdDesc *ab_cd = rz_cmd_desc_group_new(core->rcmd, cmd_analysis_cd, "ab", NULL, NULL, &ab_help);
rz_warn_if_fail(ab_cd);
RzCmdDesc *analysis_basic_block_info_cd = rz_cmd_desc_argv_state_new(core->rcmd, ab_cd, "abi", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_LONG | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_RIZIN, rz_analysis_basic_block_info_handler, &analysis_basic_block_info_help);
rz_warn_if_fail(analysis_basic_block_info_cd);
RzCmdDesc *analysis_basic_block_list_cd = rz_cmd_desc_argv_state_new(core->rcmd, ab_cd, "abl", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_LONG | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_RIZIN | RZ_OUTPUT_MODE_TABLE | RZ_OUTPUT_MODE_QUIET, rz_analysis_basic_block_list_handler, &analysis_basic_block_list_help);
rz_warn_if_fail(analysis_basic_block_list_cd);
RzCmdDesc *analysis_basic_block_find_paths_cd = rz_cmd_desc_argv_state_new(core->rcmd, ab_cd, "abt", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_analysis_basic_block_find_paths_handler, &analysis_basic_block_find_paths_help);
rz_warn_if_fail(analysis_basic_block_find_paths_cd);
RzCmdDesc *b_cd = rz_cmd_desc_group_state_new(core->rcmd, root_cd, "b", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_RIZIN, rz_block_handler, &block_help, &b_help);
rz_warn_if_fail(b_cd);
RzCmdDesc *block_decrease_cd = rz_cmd_desc_argv_new(core->rcmd, b_cd, "b-", rz_block_decrease_handler, &block_decrease_help);

View file

@ -235,6 +235,9 @@ RZ_IPI RzCmdStatus rz_analyze_cycles_handler(RzCore *core, int argc, const char
RZ_IPI RzCmdStatus rz_convert_mne_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_list_mne_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_analyse_name_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_analysis_basic_block_info_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_analysis_basic_block_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_analysis_basic_block_find_paths_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI int rz_cmd_analysis(void *data, const char *input);
RZ_IPI RzCmdStatus rz_block_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_block_decrease_handler(RzCore *core, int argc, const char **argv);

View file

@ -849,7 +849,7 @@ static const char *rizin_argv[] = {
"aar?", "aar", "aar*", "aarj", "aas", "aat", "aaT", "aau", "aav",
"a8", "ab",
"acl", "acll", "aclj", "acl*", "ac?", "ac", "ac-", "acn", "acv", "acvf", "acv-", "acb", "acb-", "acm", "acm-", "acmn",
"aC?", "aC", "aCe", "ad", "ad4", "ad8", "adf", "adfg", "adt", "adk",
"aC?", "aC", "ad", "ad4", "ad8", "adf", "adfg", "adt", "adk",
"ae?", "ae??", "ae", "aea", "aeA", "aeaf", "aeAf", "aeC", "aec?", "aec", "aecb", "aecs", "aecc", "aecu", "aecue",
"aef", "aefa",
"aei", "aeim", "aeip", "aek", "aek-", "aeli", "aelir", "aep?", "aep", "aep-", "aepc",

View file

@ -62,17 +62,6 @@ EXPECT=<<EOF
EOF
RUN
NAME=x86_64 getenv this maybe
FILE=bins/mach0/ls-osx-x86_64
CMDS=<<EOF
af
aCe 0x10000143e
EOF
EXPECT=<<EOF
char *getenv("COLUMNS")
EOF
RUN
NAME=x86_64 socket syscall
FILE=bins/elf/socket-syscall
CMDS=<<EOF
@ -3685,7 +3674,7 @@ NAME=Jump table attached to wrong basic block bug
FILE=bins/elf/static-glibc-2.27
CMDS=<<EOF
aF @ 0x00459990
ab @ 0x00459aa7~outputs
abil @ 0x00459aa7~outputs
EOF
EXPECT=<<EOF
outputs: 11

View file

@ -4,8 +4,8 @@ CMDS=<<EOF
e analysis.calls=false
af
echo $(ablq)
abt
ablt fail/str/0x:addr/cols/size/jump/calls
abil
ablt:fail/str/0x:addr/cols/size/jump/calls:fancy
abl~?
aflc
aa
@ -14,12 +14,15 @@ aflc
EOF
EXPECT=<<EOF
0x1000011e8 0x100001211 0x100001216 0x100001232 0x10000124d 0x100001252 0x10000125c 0x100001276 0x10000127e 0x100001284 0x100001290 0x1000012a8 0x1000012b6 0x1000012bf 0x1000012c6 0x1000012dc 0x1000012e3 0x1000012e7 0x100001301 0x10000130a 0x100001321 0x10000132a 0x100001347 0x100001353 0x100001370 0x100001392 0x100001396 0x1000013a2 0x1000013b1 0x1000013bd 0x1000013cc 0x1000013fb 0x10000140a 0x10000141a 0x10000143f 0x10000144b 0x100001466 0x100001473 0x10000147f 0x100001492 0x1000014a9 0x1000014b4 0x1000014ba 0x1000014d0 0x1000014df 0x1000014f0 0x1000014ff 0x100001519 0x100001525 0x10000153e 0x10000155b 0x10000156a 0x100001572 0x100001583 0x1000015a0 0x1000015ac 0x1000015c9 0x1000015e4 0x1000015f7 0x10000160d 0x10000162a 0x100001636 0x100001645 0x100001665 0x100001682 0x10000168b 0x1000016aa 0x1000016b8 0x1000016cd 0x1000016f1 0x100001768 0x10000177f 0x100001789 0x100001795 0x10000179a 0x1000017a6 0x1000017af 0x1000017b4 0x1000017fe 0x100001875 0x10000187e 0x10000188b 0x1000018c2 0x1000018cb 0x1000018d1 0x1000018dd 0x1000018e3 0x1000018ef 0x1000018f8 0x100001901 0x10000190a 0x100001913 0x10000191c 0x100001925 0x10000192e 0x100001937 0x100001940 0x100001949 0x100001952 0x10000195b 0x100001964 0x10000196d 0x100001976 0x10000197f 0x100001988 0x10000198f 0x1000019a2 0x1000019ab 0x1000019b4 0x1000019bd 0x1000019c6 0x1000019cf 0x1000019d6 0x1000019e2 0x1000019f0 0x1000019f7
.----------------------------------------------------------------------------------------------------------.
| addr | size | traced | ninstr | jump | fail | fcns | calls | xrefs |
)----------------------------------------------------------------------------------------------------------(
| 0x1000011e8 | 41 | 0 | 14 | 0x100001216 | 0x100001211 | 0x1000011e8 | | |
`----------------------------------------------------------------------------------------------------------'
jump: 0x100001216
fail: 0x100001211
opaddr: 0x1000011e8
addr: 0x1000011e8
size: 41
inputs: 0
outputs: 2
ninstr: 14
traced: false
.-----------------------------------------------------------------------------------------------------.
| addr | size | jump | calls |
)-----------------------------------------------------------------------------------------------------(
@ -65,7 +68,6 @@ EXPECT=<<EOF
| 0x1000019b4 | 9 | 0x1000019cf | |
| 0x1000019d6 | 12 | 0x1000019f0 | |
`-----------------------------------------------------------------------------------------------------'
116
1
794
@ -77,7 +79,7 @@ NAME=ablt xrefs
FILE=bins/mach0/mac-ls2
CMDS=<<EOF
aa
abl, addr/cols/xrefs:xrefs/str/0x
ablt:addr/cols/xrefs:xrefs/str/0x:fancy
EOF
EXPECT=<<EOF
.------------------------------------------------------------------------------------------------------------------.
@ -262,7 +264,6 @@ EXPECT=<<EOF
| 0x1000043ed | 0x10000443e |
| 0x1000043f2 | 0x1000044d4 0x100004498 |
`------------------------------------------------------------------------------------------------------------------'
EOF
RUN

View file

@ -17,16 +17,16 @@ NAME=ab opaddr
FILE=bins/mach0/mac-ls2
CMDS=<<EOF
af
ab
abil
sd +1
ab~opaddr
abil~opaddr
sd +1
ab~opaddr
abj~{}
abil~opaddr
abij~{}
sd +1
ab~opaddr
abil~opaddr
sd +1
ab~opaddr
abil~opaddr
EOF
EXPECT=<<EOF
jump: 0x100001216

View file

@ -10,7 +10,8 @@
?Vj
aaij
aarj
abj
ablj
abij
abtj
aeafj
aeaj