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:
Peiwei Hu 2023-08-05 22:27:54 +08:00 committed by GitHub
parent 7febd38e9d
commit d71f4a2128
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 109 additions and 4 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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"

View file

@ -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:

View file

@ -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
View 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