Skip to content

Commit

Permalink
Add new command plf to print the RzIL of the function (#3724)
Browse files Browse the repository at this point in the history
+ expose API rz_core_analysis_bytes_il
+ add new command `plf`
+ add test test/db/cmd/cmd_plf
  • Loading branch information
PeiweiHu authored Aug 5, 2023
1 parent 7febd38 commit d71f4a2
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 4 deletions.
20 changes: 16 additions & 4 deletions librz/core/cmd/cmd_analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
37 changes: 37 additions & 0 deletions librz/core/cmd/cmd_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions librz/core/cmd_descs/cmd_descs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
};
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions librz/core/cmd_descs/cmd_descs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions librz/core/cmd_descs/cmd_print.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions librz/include/rz_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 37 additions & 0 deletions test/db/cmd/cmd_plf
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit d71f4a2

Please sign in to comment.