[core] aezv - modify variables in RzIL VM

This commit is contained in:
wargio 2021-12-13 23:44:00 +01:00 committed by Florian Märkl
parent 869a36d55b
commit 5dafbf7e67
6 changed files with 108 additions and 5 deletions

View file

@ -420,6 +420,67 @@ RZ_IPI void rz_core_analysis_rzil_reinit(RzCore *core) {
}
}
/**
* \brief Set a vm variable from user input
* \return whether the set succeeded
*
* Sets the given var, or "PC" to the given value.
* The type of the variable is handled dynamically.
* This is intended for setting from user input only.
*/
RZ_IPI bool rz_core_analysis_rzil_vm_set(RzCore *core, const char *var_name, ut64 value) {
rz_return_val_if_fail(core && core->analysis && var_name, false);
RzAnalysisRzil *rzil = core->analysis->rzil;
if (!rzil || !rzil->vm) {
RZ_LOG_ERROR("RzIL: Run 'aezi' first to initialize the VM\n");
return false;
}
bool found = false;
RzBitVector *bv = NULL;
if (!strcmp(var_name, "PC")) {
found = true;
bv = rz_bv_new_from_ut64(rzil->vm->pc->len, value);
rz_bv_free(rzil->vm->pc);
rzil->vm->pc = bv;
} else {
RzILVal *oldval = NULL;
RzILVal *newval = NULL;
RzILVar *var = NULL;
void **it = NULL;
rz_pvector_foreach (&rzil->vm->vm_global_variable_list, it) {
var = *it;
if (var_name && strcmp(var_name, var->var_name)) {
continue;
}
found = true;
oldval = rz_il_hash_find_val_by_var(rzil->vm, var);
switch (oldval->type) {
case RZIL_VAR_TYPE_BV:
bv = rz_bv_new_from_ut64(oldval->data.bv->len, value);
newval = rz_il_vm_create_value_bitv(rzil->vm, bv);
break;
case RZIL_VAR_TYPE_BOOL:
newval = rz_il_vm_create_value_bool(rzil->vm, value);
break;
case RZIL_VAR_TYPE_UNK:
RZ_LOG_ERROR("RzIL: cannot set an Unknown type via command line\n");
break;
default:
rz_warn_if_reached();
break;
}
rz_il_hash_cancel_binding(rzil->vm, var);
rz_il_hash_bind(rzil->vm, var, newval);
break;
}
}
return found;
}
typedef struct il_print_t {
RzOutputMode mode;
const char *name;
@ -485,7 +546,7 @@ static void rzil_print_register_unk(ILPrint *p) {
RZ_IPI void rz_core_analysis_rzil_vm_status(RzCore *core, const char *var_name, RzOutputMode mode) {
RzAnalysisRzil *rzil = core->analysis->rzil;
if (!rzil || !rzil->vm) {
RZ_LOG_ERROR("RzIL: the VM is not initialized.\n");
RZ_LOG_ERROR("RzIL: Run 'aezi' first to initialize the VM\n");
return;
}

View file

@ -8932,6 +8932,14 @@ RZ_IPI RzCmdStatus rz_rzil_vm_step_until_addr_handler(RzCore *core, int argc, co
}
RZ_IPI RzCmdStatus rz_rzil_vm_status_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
rz_core_analysis_rzil_vm_status(core, argc > 1 ? argv[1] : NULL, mode);
if (argc == 3) {
ut64 value = rz_num_math(core->num, argv[2]);
if (rz_core_analysis_rzil_vm_set(core, argv[1], value)) {
rz_cons_printf("%s = 0x%" PFMT64x "\n", argv[1], value);
}
} else {
// print variable or all variables
rz_core_analysis_rzil_vm_status(core, argc == 2 ? argv[1] : NULL, mode);
}
return RZ_CMD_STATUS_OK;
}

View file

@ -519,7 +519,7 @@ commands:
- name: address
type: RZ_CMD_ARG_TYPE_RZNUM
- name: aezv
summary: Print the current status of the RzIL Virtual Machine
summary: Print or modify the current status of the RzIL Virtual Machine
cname: rzil_vm_status
type: RZ_CMD_DESC_TYPE_ARGV_MODES
modes:
@ -531,6 +531,9 @@ commands:
- name: var_name
type: RZ_CMD_ARG_TYPE_STRING
optional: true
- name: number
type: RZ_CMD_ARG_TYPE_RZNUM
optional: true
#####################################################
# Keep this in sync with dr in cmd_debug.yaml from here...
- name: ar

View file

@ -104,7 +104,7 @@ static const RzCmdDescArg analysis_function_all_opcode_stat_args[2];
static const RzCmdDescArg rzil_vm_step_args[2];
static const RzCmdDescArg rzil_vm_step_with_events_args[2];
static const RzCmdDescArg rzil_vm_step_until_addr_args[2];
static const RzCmdDescArg rzil_vm_status_args[2];
static const RzCmdDescArg rzil_vm_status_args[3];
static const RzCmdDescArg analysis_regs_args[2];
static const RzCmdDescArg analysis_regs_columns_args[2];
static const RzCmdDescArg analysis_regs_references_args[2];
@ -1860,6 +1860,12 @@ static const RzCmdDescArg rzil_vm_status_args[] = {
{
.name = "var_name",
.type = RZ_CMD_ARG_TYPE_STRING,
.optional = true,
},
{
.name = "number",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
.optional = true,
@ -1867,7 +1873,7 @@ static const RzCmdDescArg rzil_vm_status_args[] = {
{ 0 },
};
static const RzCmdDescHelp rzil_vm_status_help = {
.summary = "Print the current status of the RzIL Virtual Machine",
.summary = "Print or modify the current status of the RzIL Virtual Machine",
.args = rzil_vm_status_args,
};

View file

@ -30,6 +30,7 @@ RZ_IPI void rz_core_analysis_esil_emulate_bb(RzCore *core);
RZ_IPI void rz_core_analysis_esil_default(RzCore *core);
RZ_IPI void rz_core_analysis_rzil_reinit(RzCore *core);
RZ_IPI bool rz_core_analysis_rzil_vm_set(RzCore *core, const char *var_name, ut64 value);
RZ_IPI void rz_core_analysis_rzil_vm_status(RzCore *core, const char *varname, RzOutputMode mode);
RZ_IPI void rz_core_rzil_step(RzCore *core);
RZ_IPI void rz_core_analysis_rzil_step_with_events(RzCore *core, PJ *pj);

View file

@ -10,3 +10,27 @@ EXPECT=<<EOF
PC: 0x0000000000000010 ptr: 0x0000000000000001
EOF
RUN
NAME=aezv: RzIL var set
FILE=bins/bf/hello-ok.bf
CMDS=<<EOF
s 0
aezi
aezv
?e --
aezv PC 0x42
aezv
?e --
aezv ptr 0xc0ffee
aezv
EOF
EXPECT=<<EOF
PC: 0x0000000000000000 ptr: 0x0000000000000000
--
PC = 0x42
PC: 0x0000000000000042 ptr: 0x0000000000000000
--
ptr = 0xc0ffee
PC: 0x0000000000000042 ptr: 0x0000000000c0ffee
EOF
RUN