Remove instances of rz_core_cmd_strf from tui/rop.c (#4628)
This commit is contained in:
parent
a29c2c3e7c
commit
ae644fe03e
8 changed files with 249 additions and 116 deletions
|
|
@ -1726,24 +1726,23 @@ static void handle_default_disasm_print_mode(const RzCore *core, const ut64 addr
|
|||
rz_cons_printf("%s0x%08" PFMT64x "" Color_RESET " %10s %s\n",
|
||||
offsetColor, addr, "", m_intr);
|
||||
} else {
|
||||
char *str_buf = rz_str_newf("%s0x%08" PFMT64x "" Color_RESET " %10s %s\n",
|
||||
rz_strbuf_appendf(buf, "%s0x%08" PFMT64x "" Color_RESET " %10s %s\n",
|
||||
offsetColor, addr, "", m_intr);
|
||||
rz_strbuf_append(buf, str_buf);
|
||||
free(str_buf);
|
||||
}
|
||||
} else {
|
||||
if (!ret_val) {
|
||||
rz_cons_printf("0x%08" PFMT64x " %10s %s\n", addr, "", m_intr);
|
||||
} else {
|
||||
char *str_buf = rz_str_newf("0x%08" PFMT64x " %10s %s\n", addr, "", m_intr);
|
||||
rz_strbuf_append(buf, str_buf);
|
||||
free(str_buf);
|
||||
rz_strbuf_appendf(buf, "0x%08" PFMT64x " %10s %s\n", addr, "", m_intr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void disasm_print_ret(const RzCore *core, const RzOutputMode mode, const char *m_intr, const ut64 addr,
|
||||
const bool ret_val, RzStrBuf *buf) {
|
||||
if (!buf && ret_val) {
|
||||
return;
|
||||
}
|
||||
switch (mode) {
|
||||
case RZ_OUTPUT_MODE_QUIET:
|
||||
if (!ret_val) {
|
||||
|
|
@ -1772,8 +1771,11 @@ static void disasm_print_ret(const RzCore *core, const RzOutputMode mode, const
|
|||
* \return True if there are no errors during disassembling and crafting the response. False otherwise.
|
||||
*/
|
||||
RZ_API bool rz_core_disasm_until_ret(RZ_NONNULL RzCore *core, ut64 addr, const int limit,
|
||||
const RzOutputMode mode, const bool ret_val, RZ_NONNULL RZ_OUT RzStrBuf *buf) {
|
||||
rz_return_val_if_fail(core && buf, false);
|
||||
const RzOutputMode mode, const bool ret_val, RZ_NULLABLE RZ_OUT RzStrBuf *buf) {
|
||||
rz_return_val_if_fail(core, false);
|
||||
if (!buf && ret_val) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < limit; i++) {
|
||||
RzAnalysisOp *op = rz_core_analysis_op(core, addr, RZ_ANALYSIS_OP_MASK_BASIC | RZ_ANALYSIS_OP_MASK_DISASM);
|
||||
if (!op) {
|
||||
|
|
|
|||
|
|
@ -226,7 +226,8 @@ RZ_IPI RzCmdStatus rz_cmd_info_gadget_handler(RzCore *core, int argc, const char
|
|||
}
|
||||
|
||||
RzRopSearchContext *context = rz_core_rop_search_context_new(core, argv[1], false, RZ_ROP_GADGET_PRINT, state);
|
||||
return rz_core_rop_gadget_info(core, context);
|
||||
RzCmdStatus status = rz_core_rop_gadget_info(core, context);
|
||||
return status;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_cmd_query_gadget_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
|
|
@ -242,6 +243,7 @@ RZ_IPI RzCmdStatus rz_cmd_query_gadget_handler(RzCore *core, int argc, const cha
|
|||
RzRopSearchContext *context = rz_core_rop_search_context_new(core, argv[1], false, RZ_ROP_GADGET_PRINT, state);
|
||||
const RzCmdStatus cmd_status = rz_core_rop_search(core, context);
|
||||
rz_pvector_fini(constraints);
|
||||
rz_core_rop_search_context_free(context);
|
||||
return cmd_status;
|
||||
}
|
||||
|
||||
|
|
@ -251,13 +253,17 @@ RZ_IPI RzCmdStatus rz_cmd_search_gadget_handler(RzCore *core, int argc, const ch
|
|||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
RzRopSearchContext *context = rz_core_rop_search_context_new(core, input, true, RZ_ROP_GADGET_PRINT, state);
|
||||
return rz_core_rop_search(core, context);
|
||||
RzCmdStatus status = rz_core_rop_search(core, context);
|
||||
rz_core_rop_search_context_free(context);
|
||||
return status;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_cmd_detail_gadget_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
const char *input = argc > 1 ? argv[1] : "";
|
||||
RzRopSearchContext *context = rz_core_rop_search_context_new(core, input, false, RZ_ROP_GADGET_PRINT_DETAIL | RZ_ROP_GADGET_ANALYZE, state);
|
||||
return rz_core_rop_search(core, context);
|
||||
RzCmdStatus status = rz_core_rop_search(core, context);
|
||||
rz_core_rop_search_context_free(context);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void cmd_search_bin(RzCore *core, RzInterval itv) {
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ RZ_API RZ_OWN RzRopSearchContext *rz_core_rop_search_context_new(RZ_NONNULL cons
|
|||
}
|
||||
|
||||
context->greparg = greparg ? strdup(greparg) : NULL;
|
||||
context->mode_str = rz_config_get(core->config, "search.in");
|
||||
context->search_addr = rz_config_get(core->config, "search.in");
|
||||
context->arch = rz_config_get(core->config, "asm.arch");
|
||||
context->regexp = regexp;
|
||||
context->mask = mask;
|
||||
|
|
@ -311,7 +311,8 @@ RZ_API RZ_OWN RzRopSearchContext *rz_core_rop_search_context_new(RZ_NONNULL cons
|
|||
context->crop = rz_config_get_i(core->config, "rop.conditional");
|
||||
context->subchain = rz_config_get_i(core->config, "rop.subchain");
|
||||
context->cache = rz_config_get_i(core->config, "rop.cache");
|
||||
|
||||
context->ret_val = false;
|
||||
context->buf = NULL;
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
@ -328,6 +329,7 @@ RZ_API void rz_core_rop_search_context_free(RZ_NULLABLE RzRopSearchContext *cont
|
|||
}
|
||||
|
||||
free(context->greparg);
|
||||
rz_strbuf_free(context->buf);
|
||||
free(context);
|
||||
}
|
||||
|
||||
|
|
|
|||
203
librz/core/rop.c
203
librz/core/rop.c
|
|
@ -112,7 +112,8 @@ static bool rz_rop_process_asm_op(const RzCore *core, const RzCoreAsmHit *hit, R
|
|||
}
|
||||
|
||||
static bool rz_rop_print_table_mode(const RzCore *core, const RzCoreAsmHit *hit, const RzList /*<RzCoreAsmHit *>*/ *hitlist,
|
||||
unsigned int *size, char **asmop_str, char **asmop_hex_str) {
|
||||
ut32 *size, char **asmop_str, char **asmop_hex_str, RzRopSearchContext *context) {
|
||||
rz_return_val_if_fail(core && hitlist, false);
|
||||
RzAnalysisOp aop = RZ_EMPTY;
|
||||
RzAsmOp *asmop = rz_asm_op_new();
|
||||
if (!asmop) {
|
||||
|
|
@ -132,78 +133,125 @@ static bool rz_rop_print_table_mode(const RzCore *core, const RzCoreAsmHit *hit,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool rz_rop_print_quiet_mode(const RzCore *core, const RzCoreAsmHit *hit, unsigned int *size) {
|
||||
const bool colorize = rz_config_get_i(core->config, "scr.color");
|
||||
RzAnalysisOp aop = RZ_EMPTY;
|
||||
static bool rz_rop_prepare_asm_op(const RzCore *core, const RzCoreAsmHit *hit, RzAsmOp **asmop_out, RzAnalysisOp *aop, ut32 *size) {
|
||||
RzAsmOp *asmop = rz_asm_op_new();
|
||||
if (!asmop) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rz_rop_process_asm_op(core, hit, asmop, &aop, size, NULL, NULL)) {
|
||||
if (!rz_rop_process_asm_op(core, hit, asmop, aop, size, NULL, NULL)) {
|
||||
rz_asm_op_free(asmop);
|
||||
return false;
|
||||
}
|
||||
if (colorize) {
|
||||
RzStrBuf *bw_str = rz_strbuf_new(rz_asm_op_get_asm(asmop));
|
||||
RzAsmParseParam *param = rz_asm_get_parse_param(core->analysis->reg, aop.type);
|
||||
RzStrBuf *colored_asm = rz_asm_colorize_asm_str(bw_str, core->print, param, asmop->asm_toks);
|
||||
rz_asm_parse_param_free(param);
|
||||
rz_cons_printf(" %s%s;", colored_asm ? rz_strbuf_get(colored_asm) : "", Color_RESET);
|
||||
rz_strbuf_free(colored_asm);
|
||||
rz_strbuf_free(bw_str);
|
||||
} else {
|
||||
rz_cons_printf(" %s;", rz_asm_op_get_asm(asmop));
|
||||
}
|
||||
rz_asm_op_free(asmop);
|
||||
rz_analysis_op_fini(&aop);
|
||||
*asmop_out = asmop;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rz_rop_print_standard_mode(const RzCore *core, const RzCoreAsmHit *hit, ut32 *size) {
|
||||
static RzStrBuf *get_colored_asm_str(const RzCore *core, RzAsmOp *asmop, RzAnalysisOp *aop) {
|
||||
RzStrBuf *bw_str = rz_strbuf_new(rz_asm_op_get_asm(asmop));
|
||||
RzAsmParseParam *param = rz_asm_get_parse_param(core->analysis->reg, aop->type);
|
||||
RzStrBuf *colored_asm = rz_asm_colorize_asm_str(bw_str, core->print, param, asmop->asm_toks);
|
||||
rz_asm_parse_param_free(param);
|
||||
rz_strbuf_free(bw_str);
|
||||
return colored_asm;
|
||||
}
|
||||
|
||||
static bool rz_rop_print_quiet_mode(const RzCore *core, const RzCoreAsmHit *hit, ut32 *size, RzRopSearchContext *context) {
|
||||
if (!core || !context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RzAnalysisOp aop = RZ_EMPTY;
|
||||
RzAsmOp *asmop = rz_asm_op_new();
|
||||
if (!asmop) {
|
||||
RzAsmOp *asmop = NULL;
|
||||
if (!rz_rop_prepare_asm_op(core, hit, &asmop, &aop, size)) {
|
||||
return false;
|
||||
}
|
||||
if (!rz_rop_process_asm_op(core, hit, asmop, &aop, size, NULL, NULL)) {
|
||||
rz_asm_op_free(asmop);
|
||||
return false;
|
||||
}
|
||||
const bool rop_comments = rz_config_get_i(core->config, "rop.comments");
|
||||
const char *comment = rop_comments ? rz_meta_get_string(core->analysis, RZ_META_TYPE_COMMENT, hit->addr) : NULL;
|
||||
char *asm_op_hex = rz_asm_op_get_hex(asmop);
|
||||
|
||||
const bool colorize = rz_config_get_i(core->config, "scr.color");
|
||||
|
||||
const char *asm_str = rz_asm_op_get_asm(asmop);
|
||||
RzStrBuf *colored_asm = NULL;
|
||||
if (colorize) {
|
||||
RzStrBuf *bw_str = rz_strbuf_new(rz_asm_op_get_asm(asmop));
|
||||
RzAsmParseParam *param = rz_asm_get_parse_param(core->analysis->reg, aop.type);
|
||||
RzStrBuf *colored_asm = rz_asm_colorize_asm_str(bw_str, core->print, param, asmop->asm_toks);
|
||||
rz_asm_parse_param_free(param);
|
||||
if (comment) {
|
||||
rz_cons_printf(" 0x%08" PFMT64x " %18s %s%s ; %s\n",
|
||||
hit->addr, asm_op_hex, colored_asm ? rz_strbuf_get(colored_asm) : "", Color_RESET, comment);
|
||||
} else {
|
||||
rz_cons_printf(" 0x%08" PFMT64x " %18s %s%s\n",
|
||||
hit->addr, asm_op_hex, colored_asm ? rz_strbuf_get(colored_asm) : "", Color_RESET);
|
||||
}
|
||||
colored_asm = get_colored_asm_str(core, asmop, &aop);
|
||||
asm_str = colored_asm ? rz_strbuf_get(colored_asm) : "";
|
||||
}
|
||||
|
||||
const char *reset_color = colorize ? Color_RESET : "";
|
||||
const char *format = " %s%s;";
|
||||
const char *output_str = asm_str;
|
||||
if (context->ret_val) {
|
||||
rz_strbuf_appendf(context->buf, format, output_str, reset_color);
|
||||
} else {
|
||||
rz_cons_printf(format, output_str, reset_color);
|
||||
}
|
||||
|
||||
if (colored_asm) {
|
||||
rz_strbuf_free(colored_asm);
|
||||
rz_strbuf_free(bw_str);
|
||||
}
|
||||
rz_asm_op_free(asmop);
|
||||
rz_analysis_op_fini(&aop);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rz_rop_print_standard_mode(const RzCore *core, const RzCoreAsmHit *hit, ut32 *size, RzRopSearchContext *context) {
|
||||
if (!core || !context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RzAnalysisOp aop = RZ_EMPTY;
|
||||
RzAsmOp *asmop = NULL;
|
||||
if (!rz_rop_prepare_asm_op(core, hit, &asmop, &aop, size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool rop_comments = rz_config_get_i(core->config, "rop.comments");
|
||||
const bool colorize = rz_config_get_i(core->config, "scr.color");
|
||||
bool ret_val = context->ret_val;
|
||||
|
||||
const char *comment = NULL;
|
||||
if (rop_comments) {
|
||||
comment = rz_meta_get_string(core->analysis, RZ_META_TYPE_COMMENT, hit->addr);
|
||||
}
|
||||
|
||||
char *asm_op_hex = rz_asm_op_get_hex(asmop);
|
||||
const char *asm_str = rz_asm_op_get_asm(asmop);
|
||||
RzStrBuf *colored_asm = NULL;
|
||||
if (colorize) {
|
||||
colored_asm = get_colored_asm_str(core, asmop, &aop);
|
||||
asm_str = colored_asm ? rz_strbuf_get(colored_asm) : "";
|
||||
}
|
||||
|
||||
const char *reset_color = colorize ? Color_RESET : "";
|
||||
const char *format_with_comment = " 0x%08" PFMT64x " %18s %s%s ; %s\n";
|
||||
const char *format_without_comment = " 0x%08" PFMT64x " %18s %s%s\n";
|
||||
const char *format = comment ? format_with_comment : format_without_comment;
|
||||
|
||||
if (ret_val) {
|
||||
if (comment) {
|
||||
rz_strbuf_appendf(context->buf, format, hit->addr, asm_op_hex, asm_str, reset_color, comment);
|
||||
} else {
|
||||
rz_strbuf_appendf(context->buf, format, hit->addr, asm_op_hex, asm_str, reset_color);
|
||||
}
|
||||
} else {
|
||||
if (comment) {
|
||||
rz_cons_printf(" 0x%08" PFMT64x " %18s %s ; %s\n",
|
||||
hit->addr, asm_op_hex, rz_asm_op_get_asm(asmop), comment);
|
||||
rz_cons_printf(format, hit->addr, asm_op_hex, asm_str, reset_color, comment);
|
||||
} else {
|
||||
rz_cons_printf(" 0x%08" PFMT64x " %18s %s\n",
|
||||
hit->addr, asm_op_hex, rz_asm_op_get_asm(asmop));
|
||||
rz_cons_printf(format, hit->addr, asm_op_hex, asm_str, reset_color);
|
||||
}
|
||||
}
|
||||
|
||||
free(asm_op_hex);
|
||||
rz_analysis_op_fini(&aop);
|
||||
if (colored_asm) {
|
||||
rz_strbuf_free(colored_asm);
|
||||
}
|
||||
rz_asm_op_free(asmop);
|
||||
rz_analysis_op_fini(&aop);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rz_rop_print_json_mode(const RzCore *core, const RzCoreAsmHit *hit, unsigned int *size, PJ *pj) {
|
||||
rz_return_val_if_fail(core && hit && pj, false);
|
||||
RzAnalysisOp aop = RZ_EMPTY;
|
||||
RzAsmOp *asmop = rz_asm_op_new();
|
||||
if (!asmop) {
|
||||
|
|
@ -923,35 +971,47 @@ static void print_rop_gadget_info(const RzCore *core, const RzRopGadgetInfo *gad
|
|||
}
|
||||
}
|
||||
|
||||
static bool print_rop(const RzCore *core, const RzList /*<RzCoreAsmHit *>*/ *hitlist, RzCmdStateOutput *state) {
|
||||
rz_return_val_if_fail(core && hitlist && state, false);
|
||||
static bool print_rop(const RzCore *core, RzList /*<RzCoreAsmHit *>*/ *hitlist, RzRopSearchContext *context) {
|
||||
rz_return_val_if_fail(core && hitlist && context && context->state, false);
|
||||
RzCmdStateOutput *state = context->state;
|
||||
rz_cmd_state_output_set_columnsf(state, "XXs", "addr", "bytes", "disasm");
|
||||
RzCoreAsmHit *hit = (RzCoreAsmHit *)rz_list_first(hitlist);
|
||||
if (!hit) {
|
||||
return false;
|
||||
}
|
||||
if (state->mode == RZ_OUTPUT_MODE_JSON) {
|
||||
pj_o(state->d.pj);
|
||||
pj_ka(state->d.pj, "opcodes");
|
||||
} else if (state->mode == RZ_OUTPUT_MODE_QUIET) {
|
||||
rz_cons_printf("0x%08" PFMT64x ":", ((RzCoreAsmHit *)rz_list_first(hitlist))->addr);
|
||||
if (context->ret_val) {
|
||||
rz_strbuf_appendf(context->buf, "0x%08" PFMT64x ":", hit->addr);
|
||||
} else {
|
||||
rz_cons_printf("0x%08" PFMT64x ":", hit->addr);
|
||||
}
|
||||
}
|
||||
const ut64 addr = ((RzCoreAsmHit *)rz_list_first(hitlist))->addr;
|
||||
const ut64 addr = hit->addr;
|
||||
|
||||
bool result = 0;
|
||||
const RzCoreAsmHit *hit = NULL;
|
||||
hit = NULL;
|
||||
RzListIter *iter;
|
||||
ut32 size = 0;
|
||||
char *asmop_str = NULL, *asmop_hex_str = NULL;
|
||||
rz_list_foreach (hitlist, iter, hit) {
|
||||
switch (state->mode) {
|
||||
case RZ_OUTPUT_MODE_JSON:
|
||||
if (!state->d.pj) {
|
||||
break;
|
||||
}
|
||||
result = rz_rop_print_json_mode(core, hit, &size, state->d.pj);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_QUIET:
|
||||
result = rz_rop_print_quiet_mode(core, hit, &size);
|
||||
result = rz_rop_print_quiet_mode(core, hit, &size, context);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_STANDARD:
|
||||
result = rz_rop_print_standard_mode(core, hit, &size);
|
||||
result = rz_rop_print_standard_mode(core, hit, &size, context);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_TABLE:
|
||||
result = rz_rop_print_table_mode(core, hit, hitlist, &size, &asmop_str, &asmop_hex_str);
|
||||
result = rz_rop_print_table_mode(core, hit, hitlist, &size, &asmop_str, &asmop_hex_str, context);
|
||||
break;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
|
|
@ -963,7 +1023,13 @@ static bool print_rop(const RzCore *core, const RzList /*<RzCoreAsmHit *>*/ *hit
|
|||
}
|
||||
switch (state->mode) {
|
||||
case RZ_OUTPUT_MODE_JSON:
|
||||
if (!state->d.pj) {
|
||||
break;
|
||||
}
|
||||
pj_end(state->d.pj);
|
||||
if (context->ret_val) {
|
||||
break;
|
||||
}
|
||||
if (hit) {
|
||||
pj_kn(state->d.pj, "retaddr", hit->addr);
|
||||
pj_ki(state->d.pj, "size", size);
|
||||
|
|
@ -971,17 +1037,26 @@ static bool print_rop(const RzCore *core, const RzList /*<RzCoreAsmHit *>*/ *hit
|
|||
pj_end(state->d.pj);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_QUIET:
|
||||
if (context->ret_val) {
|
||||
rz_strbuf_append(context->buf, "\n");
|
||||
break;
|
||||
}
|
||||
rz_cons_newline();
|
||||
break;
|
||||
// fallthrough
|
||||
case RZ_OUTPUT_MODE_STANDARD:
|
||||
if (context->ret_val) {
|
||||
break;
|
||||
}
|
||||
if (hit) {
|
||||
rz_cons_printf("Gadget size: %d\n", (int)size);
|
||||
}
|
||||
rz_cons_newline();
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_TABLE:
|
||||
rz_table_add_rowf(state->d.t, "Xss", addr, asmop_hex_str, asmop_str);
|
||||
if (!context->ret_val) {
|
||||
rz_table_add_rowf(state->d.t, "Xss", addr, asmop_hex_str, asmop_str);
|
||||
}
|
||||
free(asmop_str);
|
||||
free(asmop_hex_str);
|
||||
break;
|
||||
|
|
@ -1234,18 +1309,18 @@ static RzRopGadgetInfo *perform_gadget_analysis(RzCore *core, const RzRopSearchC
|
|||
return rop_gadget_info;
|
||||
}
|
||||
|
||||
static bool handle_rop_request_type(RzCore *core, const RzRopSearchContext *context, RzList /*<RzCoreAsmHit *>*/ *hitlist) {
|
||||
static bool handle_rop_request_type(RzCore *core, RzRopSearchContext *context, RzList /*<RzCoreAsmHit *>*/ *hitlist) {
|
||||
rz_return_val_if_fail(core && core->analysis && hitlist, false);
|
||||
if (context->mask & RZ_ROP_GADGET_PRINT) {
|
||||
if (context->subchain) {
|
||||
do {
|
||||
if (!print_rop(core, hitlist, context->state)) {
|
||||
if (!print_rop(core, hitlist, context)) {
|
||||
return false;
|
||||
}
|
||||
hitlist->head = hitlist->head->next;
|
||||
} while (hitlist->head->next);
|
||||
} else {
|
||||
if (!print_rop(core, hitlist, context->state)) {
|
||||
if (!print_rop(core, hitlist, context)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1435,7 +1510,7 @@ static bool update_end_gadget(int *i, const int ropdepth, RzRopEndListPair **end
|
|||
* filters results based on the grep argument and request mask. Outputs results to
|
||||
* the provided state object.
|
||||
*/
|
||||
RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_OWN RzRopSearchContext *context) {
|
||||
RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RzRopSearchContext *context) {
|
||||
rz_return_val_if_fail(core && core->search && context, RZ_CMD_STATUS_ERROR);
|
||||
|
||||
RzInterval search_itv = { 0 };
|
||||
|
|
@ -1455,7 +1530,7 @@ RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_OWN
|
|||
RzList /*<char *>*/ *rx_list = handle_grep_args(context->greparg, context->regexp);
|
||||
rz_cmd_state_output_array_start(context->state);
|
||||
rz_cons_break_push(NULL, NULL);
|
||||
RzList *boundaries = rz_core_get_boundaries_prot(core, -1, context->mode_str, "search");
|
||||
RzList *boundaries = rz_core_get_boundaries_prot(core, -1, context->search_addr, "search");
|
||||
if (!boundaries) {
|
||||
rz_cmd_state_output_array_end(context->state);
|
||||
}
|
||||
|
|
@ -1466,6 +1541,9 @@ RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_OWN
|
|||
RzListIter *itermap;
|
||||
RzIOMap *map;
|
||||
RzCmdStatus result = RZ_CMD_STATUS_OK;
|
||||
if (context->ret_val) {
|
||||
context->buf = rz_strbuf_new(NULL);
|
||||
}
|
||||
rz_list_foreach (boundaries, itermap, map) {
|
||||
if (!rz_itv_overlap(search_itv, map->itv)) {
|
||||
continue;
|
||||
|
|
@ -1536,7 +1614,6 @@ RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_OWN
|
|||
rz_cmd_state_output_array_end(context->state);
|
||||
rz_cons_break_pop();
|
||||
rz_list_free(rx_list);
|
||||
rz_core_rop_search_context_free(context);
|
||||
rz_list_free(boundaries);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1556,7 +1633,9 @@ RZ_API RzCmdStatus rz_core_rop_gadget_info(RZ_NONNULL RzCore *core, RZ_NONNULL R
|
|||
if (!core->analysis->ht_rop_semantics) {
|
||||
// TODO: resolve this logic later.
|
||||
}
|
||||
return rz_core_rop_search(core, context);
|
||||
RzCmdStatus status = rz_core_rop_search(core, context);
|
||||
rz_core_rop_search_context_free(context);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <rz_util.h>
|
||||
|
||||
#include "../core_private.h"
|
||||
#include "rz_rop.h"
|
||||
#include <rz_asm.h>
|
||||
#include <rz_util/rz_print.h>
|
||||
#include <rz_util/rz_strbuf.h>
|
||||
|
|
@ -22,6 +23,7 @@ RZ_IPI int rz_core_visual_view_rop(RzCore *core) {
|
|||
const int rows = 7;
|
||||
int cur = 0;
|
||||
RzLine *line = core->cons->line;
|
||||
bool status = true;
|
||||
|
||||
rz_line_set_prompt(line, "rop regexp: ");
|
||||
const char *linestr = rz_line_readline(line);
|
||||
|
|
@ -34,13 +36,32 @@ RZ_IPI int rz_core_visual_view_rop(RzCore *core) {
|
|||
// maybe store in RzCore, so we can save it in project and use it outside visual
|
||||
|
||||
eprintf("Searching ROP gadgets...\n");
|
||||
char *ropstr = rz_core_cmd_strf(core, "\"/Rq %s\" @e:scr.color=0", linestr);
|
||||
RzCmdStateOutput state = { 0 };
|
||||
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET)) {
|
||||
return false;
|
||||
}
|
||||
RzRopSearchContext *context = rz_core_rop_search_context_new(core, linestr, false, RZ_ROP_GADGET_PRINT, &state);
|
||||
context->ret_val = true;
|
||||
if (rz_core_rop_search(core, context) != RZ_CMD_STATUS_OK) {
|
||||
rz_core_rop_search_context_free(context);
|
||||
return false;
|
||||
}
|
||||
char *ropstr = rz_strbuf_get(context->buf);
|
||||
ropstr = strdup(ropstr);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
RzList *rops = rz_str_split_list(ropstr, "\n", 0);
|
||||
if (!rops) {
|
||||
free(ropstr);
|
||||
rz_core_rop_search_context_free(context);
|
||||
return false;
|
||||
}
|
||||
rz_core_rop_search_context_free(context);
|
||||
int delta = 0;
|
||||
bool show_color = core->print->flags & RZ_PRINT_FLAGS_COLOR;
|
||||
bool forceaddr = false;
|
||||
ut64 addr = UT64_MAX;
|
||||
char *cursearch = strdup(linestr);
|
||||
char *curline = NULL, *chainstr = NULL;
|
||||
while (true) {
|
||||
rz_cons_clear00();
|
||||
rz_cons_printf("[0x%08" PFMT64x "]-[visual-rzrop] %s (see pdp command)\n",
|
||||
|
|
@ -60,12 +81,14 @@ RZ_IPI int rz_core_visual_view_rop(RzCore *core) {
|
|||
rz_strbuf_appendf(sb, "%08x", n);
|
||||
}
|
||||
}
|
||||
char *chainstr = rz_strbuf_drain(sb);
|
||||
chainstr = rz_strbuf_drain(sb);
|
||||
|
||||
char *wlist = rz_str_widget_list(core, rops, rows, cur, print_rop);
|
||||
rz_cons_printf("%s", wlist);
|
||||
free(wlist);
|
||||
char *curline = rz_str_dup(rz_str_trim_head_ro(rz_str_widget_list(core, rops, rows, cur, print_rop)));
|
||||
char *widget_str = rz_str_widget_list(core, rops, rows, cur, print_rop);
|
||||
curline = rz_str_dup(rz_str_trim_head_ro(widget_str));
|
||||
free(widget_str);
|
||||
if (curline) {
|
||||
char *sp = strchr(curline, ' ');
|
||||
if (sp) {
|
||||
|
|
@ -78,10 +101,13 @@ RZ_IPI int rz_core_visual_view_rop(RzCore *core) {
|
|||
if (addr != UT64_MAX) {
|
||||
rz_cons_printf("Gadget:");
|
||||
// get comment
|
||||
char *output = rz_core_cmd_strf(core, "piu 10 @ 0x%08" PFMT64x, addr + delta);
|
||||
if (output) {
|
||||
rz_cons_strcat_at(output, 0, 10, scr_w, 10);
|
||||
free(output);
|
||||
RzStrBuf *str_buf = rz_strbuf_new(NULL);
|
||||
if (rz_core_disasm_until_ret(core, addr + delta, 10, RZ_OUTPUT_MODE_QUIET, true, str_buf)) {
|
||||
char *output = rz_strbuf_get(str_buf);
|
||||
if (output) {
|
||||
rz_cons_strcat_at(output, 0, 10, scr_w, 10);
|
||||
}
|
||||
rz_strbuf_free(str_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -103,10 +129,8 @@ RZ_IPI int rz_core_visual_view_rop(RzCore *core) {
|
|||
rz_cons_flush();
|
||||
int ch = rz_cons_readchar();
|
||||
if (ch == -1 || ch == 4) {
|
||||
free(curline);
|
||||
free(cursearch);
|
||||
RZ_FREE(chainstr);
|
||||
return false;
|
||||
status = false;
|
||||
goto exit;
|
||||
}
|
||||
#define NEWTYPE(x, y) rz_mem_dup(&(y), sizeof(x));
|
||||
ch = rz_cons_arrow_to_hjkl(ch); // get ESC+char, return 'hjkl' char
|
||||
|
|
@ -179,8 +203,21 @@ RZ_IPI int rz_core_visual_view_rop(RzCore *core) {
|
|||
addr = UT64_MAX;
|
||||
cur = 0;
|
||||
cursearch = strdup(linestr);
|
||||
free(ropstr);
|
||||
ropstr = rz_core_cmd_strf(core, "\"/Rl %s\" @e:scr.color=0", linestr);
|
||||
RzCmdStateOutput state_detail = { 0 };
|
||||
if (!rz_cmd_state_output_init(&state_detail, RZ_OUTPUT_MODE_STANDARD)) {
|
||||
status = false;
|
||||
goto exit;
|
||||
}
|
||||
RzRopSearchContext *context = rz_core_rop_search_context_new(core, linestr, false, RZ_ROP_GADGET_PRINT, &state);
|
||||
context->ret_val = true;
|
||||
if (rz_core_rop_search(core, context) != RZ_CMD_STATUS_OK) {
|
||||
rz_core_rop_search_context_free(context);
|
||||
status = false;
|
||||
goto exit;
|
||||
}
|
||||
ropstr = rz_strbuf_get(context->buf);
|
||||
rz_cmd_state_output_fini(&state_detail);
|
||||
ropstr = strdup(ropstr);
|
||||
rz_list_free(rops);
|
||||
rops = rz_str_split_list(ropstr, "\n", 0);
|
||||
}
|
||||
|
|
@ -207,21 +244,20 @@ RZ_IPI int rz_core_visual_view_rop(RzCore *core) {
|
|||
case '\n':
|
||||
case '\r':
|
||||
if (curline && *curline) {
|
||||
const ut64 limit = addr + delta > 1 ? addr + delta : 1024;
|
||||
RzStrBuf *line = rz_strbuf_new(NULL);
|
||||
if (!rz_core_disasm_until_ret(core, core->offset, limit, RZ_OUTPUT_MODE_QUIET, true, line)) {
|
||||
rz_strbuf_free(line);
|
||||
RzStrBuf *str_buf = rz_strbuf_new(NULL);
|
||||
if (!rz_core_disasm_until_ret(core, addr + delta, 1024, RZ_OUTPUT_MODE_QUIET, true, str_buf)) {
|
||||
rz_strbuf_free(str_buf);
|
||||
break;
|
||||
}
|
||||
if (show_color) {
|
||||
// XXX parsing fails to read this ansi-offset
|
||||
// const char *offsetColor = rz_cons_singleton ()->context->pal.offset; // TODO etooslow. must cache
|
||||
// rz_list_push (core->ropchain, rz_str_newf ("%s0x%08"PFMT64x""Color_RESET" %s", offsetColor, addr + delta, line));
|
||||
rz_list_push(core->ropchain, rz_str_newf("0x%08" PFMT64x " %s", addr + delta, rz_strbuf_get(line)));
|
||||
rz_list_push(core->ropchain, rz_str_newf("0x%08" PFMT64x " %s", addr + delta, rz_strbuf_get(str_buf)));
|
||||
} else {
|
||||
rz_list_push(core->ropchain, rz_str_newf("0x%08" PFMT64x " %s", addr + delta, rz_strbuf_get(line)));
|
||||
rz_list_push(core->ropchain, rz_str_newf("0x%08" PFMT64x " %s", addr + delta, rz_strbuf_get(str_buf)));
|
||||
}
|
||||
rz_strbuf_free(line);
|
||||
rz_strbuf_free(str_buf);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
|
|
@ -265,12 +301,18 @@ RZ_IPI int rz_core_visual_view_rop(RzCore *core) {
|
|||
case 'q':
|
||||
free(curline);
|
||||
free(cursearch);
|
||||
free(rops);
|
||||
RZ_FREE(chainstr);
|
||||
return true;
|
||||
}
|
||||
RZ_FREE(chainstr);
|
||||
free(curline);
|
||||
}
|
||||
|
||||
exit:
|
||||
free(curline);
|
||||
free(cursearch);
|
||||
return false;
|
||||
free(rops);
|
||||
RZ_FREE(chainstr);
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ RZ_API char *rz_str_widget_list(void *user, RzList /*<void *>*/ *list, int rows,
|
|||
} else {
|
||||
char *line = cb(user, item, cur == count);
|
||||
if (line) {
|
||||
rz_strbuf_appendf(sb, "%s", line);
|
||||
rz_strbuf_append(sb, line);
|
||||
free(line);
|
||||
}
|
||||
rows--;
|
||||
|
|
|
|||
|
|
@ -1308,7 +1308,7 @@ RZ_API void rz_core_sym_name_fini(RZ_NULLABLE RzBinSymNames *names);
|
|||
|
||||
RZ_API void rz_core_analysis_bytes_il(RZ_NONNULL RzCore *core, ut64 len, ut64 num_ops, bool pretty);
|
||||
RZ_API bool rz_core_disasm_until_ret(RZ_NONNULL RzCore *core, ut64 addr, int limit, RzOutputMode mode,
|
||||
bool ret_val, RZ_NONNULL RZ_OUT RzStrBuf *buf);
|
||||
bool ret_val, RZ_NULLABLE RZ_OUT RzStrBuf *buf);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -101,22 +101,24 @@ typedef struct rz_rop_constraint_t {
|
|||
* \brief Structure representing a ROP search context.
|
||||
*/
|
||||
typedef struct rz_rop_search_context_t {
|
||||
ut8 max_instr;
|
||||
ut8 subchain;
|
||||
ut8 crop;
|
||||
char *greparg;
|
||||
const char *mode_str;
|
||||
const char *arch;
|
||||
bool regexp;
|
||||
bool cache;
|
||||
RzRopRequestMask mask;
|
||||
RzCmdStateOutput *state;
|
||||
int increment;
|
||||
int max_count;
|
||||
ut64 from;
|
||||
ut64 to;
|
||||
RzList /*<RzRopEndListPair *>*/ *end_list;
|
||||
HtSU *unique_hitlists;
|
||||
ut8 max_instr; ///< Rop search max length.
|
||||
ut8 subchain; ///< Display every length gadget from rop.len=X to 2 in /Rl.
|
||||
ut8 crop; ///< Include conditional jump, calls and returns in ropsearch.
|
||||
char *greparg; ///< Grep argument string.
|
||||
const char *search_addr; ///< specify where to search stuff.
|
||||
const char *arch; ///< Architecture of the binary.
|
||||
bool regexp; ///< Regular expression argument flag.
|
||||
bool cache; ///< Cache the search results.
|
||||
RzRopRequestMask mask; ///< Mask for kind of rop request operation.
|
||||
RzCmdStateOutput *state; ///< Command state output.
|
||||
int increment; ///< ROP search increment value.
|
||||
ut64 max_count; ///< Maximum number of hits (0: no limit).
|
||||
ut64 from; ///< Start address to start rop search.
|
||||
ut64 to; ///< End address to stop rop search.
|
||||
RzList /*<RzRopEndListPair *>*/ *end_list; ///< List of end gadgets.
|
||||
HtSU *unique_hitlists; ///< Cache unique ROP hitlists.
|
||||
bool ret_val; ///< Flag to indicate return the search results.
|
||||
RzStrBuf *buf; ///< String buffer for storing search results.
|
||||
} RzRopSearchContext;
|
||||
|
||||
/**
|
||||
|
|
@ -142,14 +144,14 @@ typedef bool (*rz_rop_event_check_fn)(const RzRopRegInfo *);
|
|||
extern rz_rop_event_check_fn rz_rop_event_functions[RZ_ROP_EVENT_COUNT];
|
||||
|
||||
// Command APIs
|
||||
RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_OWN RzRopSearchContext *context);
|
||||
RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RzRopSearchContext *context);
|
||||
RZ_API RzCmdStatus rz_core_rop_gadget_info(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_OWN RzRopSearchContext *context);
|
||||
RZ_API bool rz_core_rop_analyze_constraint(const RZ_NONNULL RzCore *core, const RZ_NONNULL char *str,
|
||||
RZ_NONNULL RZ_OUT RzRopConstraint *rop_constraint);
|
||||
|
||||
// ROP Search Context APIs
|
||||
RZ_API RZ_OWN RzRopSearchContext *rz_core_rop_search_context_new(RZ_NONNULL const RzCore *core, RZ_NULLABLE const char *greparg, bool regexp,
|
||||
const RzRopRequestMask mask, RZ_NONNULL RZ_BORROW RzCmdStateOutput *state);
|
||||
RzRopRequestMask mask, RZ_NONNULL RZ_BORROW RzCmdStateOutput *state);
|
||||
RZ_API void rz_core_rop_search_context_free(RZ_NULLABLE RzRopSearchContext *context);
|
||||
|
||||
// ROP Constraint APIs
|
||||
|
|
|
|||
Loading…
Reference in a new issue