Add new command plf to print the RzIL of the function (#3724)
+ expose API rz_core_analysis_bytes_il + add new command `plf` + add test test/db/cmd/cmd_plf
This commit is contained in:
parent
7febd38e9d
commit
d71f4a2128
7 changed files with 109 additions and 4 deletions
|
|
@ -5544,14 +5544,26 @@ static void core_colorify_il_statement(RzConsContext *ctx, const char *il_stmt,
|
|||
rz_cons_newline();
|
||||
}
|
||||
|
||||
static void core_analysis_bytes_il(RzCore *core, const ut8 *buf, int len, int nops, bool pretty) {
|
||||
/**
|
||||
* \brief Parse and print \p len bytes and \p num_ops
|
||||
* RzIL instructions of data in \p buf, restricted by
|
||||
* \p len and \p num_ops at the same time
|
||||
*
|
||||
* \param core RzCore
|
||||
* \param buf Buffer holding the instruction bytes.
|
||||
* \param len Maximum length read from \p buf in bytes.
|
||||
* \param num_ops Maximum number of instruction, set to 0 to disable it (only use \p len).
|
||||
* \param pretty Pretty-printing
|
||||
*/
|
||||
RZ_API void rz_core_analysis_bytes_il(RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, int len, ut32 num_ops, bool pretty) {
|
||||
rz_return_if_fail(core && buf);
|
||||
bool colorize = rz_config_get_i(core->config, "scr.color") > 0;
|
||||
const char *il_stmt = NULL;
|
||||
const char delim = pretty ? '\n' : ' ';
|
||||
RzAnalysisOp op;
|
||||
RzStrBuf sb;
|
||||
|
||||
for (size_t i = 0, idx = 0; idx < len && (!nops || (nops && i < nops)); i++) {
|
||||
for (size_t i = 0, idx = 0; idx < len && (!num_ops || (num_ops && i < num_ops)); i++) {
|
||||
ut64 addr = core->offset + idx;
|
||||
|
||||
rz_analysis_op_init(&op);
|
||||
|
|
@ -5591,7 +5603,7 @@ RZ_IPI RzCmdStatus rz_analyze_n_ins_il_handler(RzCore *core, int argc, const cha
|
|||
}
|
||||
}
|
||||
|
||||
core_analysis_bytes_il(core, core->block, core->blocksize, count, false);
|
||||
rz_core_analysis_bytes_il(core, core->block, core->blocksize, count, false);
|
||||
|
||||
if (obs != core->blocksize) {
|
||||
rz_core_block_size(core, obs);
|
||||
|
|
@ -5615,7 +5627,7 @@ RZ_IPI RzCmdStatus rz_analyze_n_ins_il_pretty_handler(RzCore *core, int argc, co
|
|||
}
|
||||
}
|
||||
|
||||
core_analysis_bytes_il(core, core->block, core->blocksize, count, true);
|
||||
rz_core_analysis_bytes_il(core, core->block, core->blocksize, count, true);
|
||||
|
||||
if (obs != core->blocksize) {
|
||||
rz_core_block_size(core, obs);
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ static const char *help_msg_p[] = {
|
|||
"pu", "[?][w] [len]", "print N url encoded bytes (w=wide)",
|
||||
"pv", "[?][jh] [mode]", "show variable/pointer/value in memory",
|
||||
"px", "[?][owq] [len]", "hexdump of N bytes (o=octal, w=32bit, q=64bit)",
|
||||
"plf", "", "print the RzIL output of the function",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -3966,6 +3967,42 @@ RZ_IPI RzCmdStatus rz_cmd_disassembly_function_handler(RzCore *core, int argc, c
|
|||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_print_function_rzil_handler(RzCore *core, int argc, const char **argv) {
|
||||
ut64 oldoff = core->offset;
|
||||
RzList *list = rz_analysis_get_functions_in(core->analysis, core->offset);
|
||||
if (rz_list_empty(list)) {
|
||||
RZ_LOG_ERROR("No function found in 0x%08" PFMT64x ".\n", core->offset);
|
||||
goto exit;
|
||||
}
|
||||
if (rz_list_length(list) > 1) {
|
||||
RZ_LOG_ERROR("Multiple overlapping functions found at 0x%" PFMT64x ". "
|
||||
"Re-run this command at the entrypoint of one of them to disambiguate.\n",
|
||||
core->offset);
|
||||
goto exit;
|
||||
}
|
||||
RzAnalysisFunction *fcn = rz_list_first(list);
|
||||
if (!fcn) {
|
||||
rz_warn_if_reached();
|
||||
}
|
||||
|
||||
ut64 start = fcn->addr;
|
||||
ut64 end = rz_analysis_function_max_addr(fcn);
|
||||
if (end <= start) {
|
||||
RZ_LOG_ERROR("Cannot print function because the end offset is less or equal to the start offset\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ut64 size = end - start;
|
||||
rz_core_seek(core, start, true);
|
||||
rz_core_analysis_bytes_il(core, core->block, size, 0, false);
|
||||
rz_core_seek(core, oldoff, true);
|
||||
rz_list_free(list);
|
||||
return RZ_CMD_STATUS_OK;
|
||||
exit:
|
||||
rz_list_free(list);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_cmd_disassembly_function_summary_handler(RzCore *core, int argc, const char **argv) {
|
||||
ut32 old_blocksize = core->blocksize;
|
||||
RzAnalysisFunction *function = rz_analysis_get_fcn_in(core->analysis, core->offset, RZ_ANALYSIS_FCN_TYPE_FCN | RZ_ANALYSIS_FCN_TYPE_SYM);
|
||||
|
|
|
|||
|
|
@ -13353,6 +13353,14 @@ static const RzCmdDescHelp print_instructions_function_help = {
|
|||
.args = print_instructions_function_args,
|
||||
};
|
||||
|
||||
static const RzCmdDescArg print_function_rzil_args[] = {
|
||||
{ 0 },
|
||||
};
|
||||
static const RzCmdDescHelp print_function_rzil_help = {
|
||||
.summary = "Print the RzIL of the function",
|
||||
.args = print_function_rzil_args,
|
||||
};
|
||||
|
||||
static const RzCmdDescHelp pp_help = {
|
||||
.summary = "Print patterns",
|
||||
};
|
||||
|
|
@ -21208,6 +21216,9 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
|
|||
RzCmdDesc *print_instructions_function_cd = rz_cmd_desc_argv_new(core->rcmd, pI_cd, "pIf", rz_print_instructions_function_handler, &print_instructions_function_help);
|
||||
rz_warn_if_fail(print_instructions_function_cd);
|
||||
|
||||
RzCmdDesc *print_function_rzil_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_print_cd, "plf", rz_print_function_rzil_handler, &print_function_rzil_help);
|
||||
rz_warn_if_fail(print_function_rzil_cd);
|
||||
|
||||
RzCmdDesc *pp_cd = rz_cmd_desc_group_new(core->rcmd, cmd_print_cd, "pp", NULL, NULL, &pp_help);
|
||||
rz_warn_if_fail(pp_cd);
|
||||
RzCmdDesc *print_pattern0_cd = rz_cmd_desc_argv_new(core->rcmd, pp_cd, "pp0", rz_print_pattern0_handler, &print_pattern0_help);
|
||||
|
|
|
|||
|
|
@ -1863,6 +1863,8 @@ RZ_IPI RzCmdStatus rz_assembly_of_hex_alias_handler(RzCore *core, int argc, cons
|
|||
RZ_IPI RzCmdStatus rz_print_instructions_handler(RzCore *core, int argc, const char **argv);
|
||||
// "pIf"
|
||||
RZ_IPI RzCmdStatus rz_print_instructions_function_handler(RzCore *core, int argc, const char **argv);
|
||||
// "plf"
|
||||
RZ_IPI RzCmdStatus rz_print_function_rzil_handler(RzCore *core, int argc, const char **argv);
|
||||
// "pp0"
|
||||
RZ_IPI RzCmdStatus rz_print_pattern0_handler(RzCore *core, int argc, const char **argv);
|
||||
// "pp1"
|
||||
|
|
|
|||
|
|
@ -591,6 +591,10 @@ commands:
|
|||
summary: Print all instructions at the current function
|
||||
cname: print_instructions_function
|
||||
args: []
|
||||
- name: plf
|
||||
summary: Print the RzIL of the function
|
||||
cname: print_function_rzil
|
||||
args: []
|
||||
- name: pp
|
||||
summary: Print patterns
|
||||
subcommands:
|
||||
|
|
|
|||
|
|
@ -1288,6 +1288,8 @@ RZ_API ut64 rz_core_analysis_var_addr(RZ_NONNULL RzCore *core, RZ_NONNULL RzAnal
|
|||
RZ_API void rz_core_sym_name_init(RZ_NONNULL RZ_OUT RzBinSymNames *names, RZ_NONNULL RzBinSymbol *symbol, bool demangle);
|
||||
RZ_API void rz_core_sym_name_fini(RZ_NULLABLE RzBinSymNames *names);
|
||||
|
||||
RZ_API void rz_core_analysis_bytes_il(RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, int len, ut32 num_ops, bool pretty);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
37
test/db/cmd/cmd_plf
Normal file
37
test/db/cmd/cmd_plf
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
NAME=plf
|
||||
FILE=bins/elf/ls
|
||||
CMDS=<<EOF
|
||||
aaa
|
||||
plf
|
||||
echo "---"
|
||||
so 1
|
||||
plf
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
0x5ae0 empty
|
||||
0x5ae4 (seq (set _xor (^ (cast 32 false (var rbp)) (cast 32 false (var rbp)))) (set rbp (cast 64 false (var _xor))) (set of false) (set cf false) (set _result (var _xor)) (set _popcnt (bv 8 0x0)) (set _val (cast 8 false (var _result))) (repeat (! (is_zero (var _val))) (seq (set _popcnt (+ (var _popcnt) (ite (lsb (var _val)) (bv 8 0x1) (bv 8 0x0)))) (set _val (>> (var _val) (bv 8 0x1) false)))) (set pf (is_zero (mod (var _popcnt) (bv 8 0x2)))) (set zf (is_zero (var _result))) (set sf (msb (var _result))))
|
||||
0x5ae6 (set r9 (cast 64 false (var rdx)))
|
||||
0x5ae9 (seq (set rsi (loadw 0 64 (+ (var rsp) (bv 64 0x0)))) (set rsp (+ (var rsp) (bv 64 0x8))))
|
||||
0x5aea (set rdx (var rsp))
|
||||
0x5aed (seq (set and_ (& (var rsp) (bv 64 0xfffffffffffffff0))) (set rsp (var and_)) (set of false) (set cf false) (set _result (var and_)) (set _popcnt (bv 8 0x0)) (set _val (cast 8 false (var _result))) (repeat (! (is_zero (var _val))) (seq (set _popcnt (+ (var _popcnt) (ite (lsb (var _val)) (bv 8 0x1) (bv 8 0x0)))) (set _val (>> (var _val) (bv 8 0x1) false)))) (set pf (is_zero (mod (var _popcnt) (bv 8 0x2)))) (set zf (is_zero (var _result))) (set sf (msb (var _result))))
|
||||
0x5af1 (seq (set final (- (var rsp) (bv 64 0x8))) (storew 0 (var final) (cast 64 false (var rax))) (set rsp (var final)))
|
||||
0x5af2 (seq (set final (- (var rsp) (bv 64 0x8))) (storew 0 (var final) (cast 64 false (var rsp))) (set rsp (var final)))
|
||||
0x5af3 (set r8 (cast 64 false (cast 64 false (+ (bv 64 0x5afa) (bv 64 0x10c66)))))
|
||||
0x5afa (set rcx (cast 64 false (+ (bv 64 0x5b01) (bv 64 0x10bef))))
|
||||
0x5b01 (set rdi (cast 64 false (+ (bv 64 0x5b08) (bv 64 0xffffffffffffe568))))
|
||||
0x5b08 (seq (set final (- (var rsp) (bv 64 0x8))) (storew 0 (var final) (cast 64 false (bv 64 0x5b0e))) (set rsp (var final)) (jmp (loadw 0 64 (+ (bv 64 0x5b0e) (bv 64 0x1c30a)))))
|
||||
---
|
||||
0x5ae0 empty
|
||||
0x5ae4 (seq (set _xor (^ (cast 32 false (var rbp)) (cast 32 false (var rbp)))) (set rbp (cast 64 false (var _xor))) (set of false) (set cf false) (set _result (var _xor)) (set _popcnt (bv 8 0x0)) (set _val (cast 8 false (var _result))) (repeat (! (is_zero (var _val))) (seq (set _popcnt (+ (var _popcnt) (ite (lsb (var _val)) (bv 8 0x1) (bv 8 0x0)))) (set _val (>> (var _val) (bv 8 0x1) false)))) (set pf (is_zero (mod (var _popcnt) (bv 8 0x2)))) (set zf (is_zero (var _result))) (set sf (msb (var _result))))
|
||||
0x5ae6 (set r9 (cast 64 false (var rdx)))
|
||||
0x5ae9 (seq (set rsi (loadw 0 64 (+ (var rsp) (bv 64 0x0)))) (set rsp (+ (var rsp) (bv 64 0x8))))
|
||||
0x5aea (set rdx (var rsp))
|
||||
0x5aed (seq (set and_ (& (var rsp) (bv 64 0xfffffffffffffff0))) (set rsp (var and_)) (set of false) (set cf false) (set _result (var and_)) (set _popcnt (bv 8 0x0)) (set _val (cast 8 false (var _result))) (repeat (! (is_zero (var _val))) (seq (set _popcnt (+ (var _popcnt) (ite (lsb (var _val)) (bv 8 0x1) (bv 8 0x0)))) (set _val (>> (var _val) (bv 8 0x1) false)))) (set pf (is_zero (mod (var _popcnt) (bv 8 0x2)))) (set zf (is_zero (var _result))) (set sf (msb (var _result))))
|
||||
0x5af1 (seq (set final (- (var rsp) (bv 64 0x8))) (storew 0 (var final) (cast 64 false (var rax))) (set rsp (var final)))
|
||||
0x5af2 (seq (set final (- (var rsp) (bv 64 0x8))) (storew 0 (var final) (cast 64 false (var rsp))) (set rsp (var final)))
|
||||
0x5af3 (set r8 (cast 64 false (cast 64 false (+ (bv 64 0x5afa) (bv 64 0x10c66)))))
|
||||
0x5afa (set rcx (cast 64 false (+ (bv 64 0x5b01) (bv 64 0x10bef))))
|
||||
0x5b01 (set rdi (cast 64 false (+ (bv 64 0x5b08) (bv 64 0xffffffffffffe568))))
|
||||
0x5b08 (seq (set final (- (var rsp) (bv 64 0x8))) (storew 0 (var final) (cast 64 false (bv 64 0x5b0e))) (set rsp (var final)) (jmp (loadw 0 64 (+ (bv 64 0x5b0e) (bv 64 0x1c30a)))))
|
||||
EOF
|
||||
RUN
|
||||
Loading…
Reference in a new issue