Rizin
unix-like reverse engineering framework and cli tools
il_vm_eval.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 heersin <teablearcher@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
9 #include <rz_il/rz_il_vm.h>
10 
11 // Handler for core theory opcodes
15 
37 
44 
47 
57 
62 
63 // TODO: remove me when all the handlers are implemented
66 
102 };
103 
116 };
117 
126  RzILMem *mem = rz_il_vm_get_mem(vm, index);
127  if (!mem) {
128  RZ_LOG_ERROR("Non-existent mem %u referenced\n", (unsigned int)index);
129  return NULL;
130  }
133  return value;
134 }
135 
145  rz_return_if_fail(vm && key && value);
146  RzILMem *mem = rz_il_vm_get_mem(vm, index);
147  if (!mem) {
148  RZ_LOG_ERROR("Non-existent mem %u referenced\n", (unsigned int)index);
149  return;
150  }
151  RzBitVector *old_value = rz_il_mem_load(mem, key);
154  rz_bv_free(old_value);
155 }
156 
165  RzILMem *mem = rz_il_vm_get_mem(vm, index);
166  if (!mem) {
167  RZ_LOG_ERROR("Non-existent mem %u referenced\n", (unsigned int)index);
168  return NULL;
169  }
172  return value;
173 }
174 
184  rz_return_if_fail(vm && key && value);
185  RzILMem *mem = rz_il_vm_get_mem(vm, index);
186  if (!mem) {
187  RZ_LOG_ERROR("Non-existent mem %u referenced\n", (unsigned int)index);
188  return;
189  }
193  rz_bv_free(old_value);
194 }
195 
202  rz_return_if_fail(vm && vm->events && evt);
203  if (!rz_list_append(vm->events, evt)) {
205  rz_il_event_free(evt);
206  }
207 }
208 
213  rz_list_purge(vm->events);
214 }
215 
222 RZ_API bool rz_il_vm_step(RzILVM *vm, RzILOpEffect *op, ut64 fallthrough_addr) {
223  rz_return_val_if_fail(vm && op, false);
224 
226 
227  // Set the successor pc **before** evaluating. Any jmp/goto may then overwrite it again.
228  RzBitVector *next_pc = rz_bv_new_from_ut64(vm->pc->len, fallthrough_addr);
230  rz_bv_free(vm->pc);
231  vm->pc = next_pc;
232 
233  bool succ = rz_il_evaluate_effect(vm, op);
234 
235  // remove any local defined variable (local pure vars are unbound automatically)
237  return succ;
238 }
239 
241  rz_return_val_if_fail(vm && op && type, NULL);
242  RzILOpPureHandler handler = vm->op_handler_pure_table[op->code];
243  rz_return_val_if_fail(handler, NULL);
244  return handler(vm, op, type);
245 }
246 
248  rz_return_val_if_fail(vm && op, NULL);
249  RzILOpEffectHandler handler = vm->op_handler_effect_table[op->code];
250  rz_return_val_if_fail(handler, NULL);
251  return handler(vm, op);
252 }
253 
254 static const char *pure_type_name(RzILTypePure type) {
255  switch (type) {
257  return "bitvector";
259  return "bool";
260  default:
261  return "unknown";
262  }
263 }
264 
270  rz_return_val_if_fail(vm && op, NULL);
271  // check type and auto convertion between bitv/bool/val
272  RzILTypePure type = -1;
273  void *res = eval_pure(vm, op, &type);
274  if (!res) {
275  // propagate error
276  return NULL;
277  }
279  RZ_LOG_ERROR("RzIL: type error: expected bitvector, got %s\n", pure_type_name(type));
280  return NULL;
281  }
282  return res;
283 }
284 
290  rz_return_val_if_fail(vm && op, NULL);
291  // check type and auto convertion between bitv/bool/val
292  RzILTypePure type = -1;
293  void *res = eval_pure(vm, op, &type);
294  if (!res) {
295  // propagate error
296  return NULL;
297  }
298  if (type != RZ_IL_TYPE_PURE_BOOL) {
299  RZ_LOG_ERROR("RzIL: type error: expected bool, got %s\n", pure_type_name(type));
300  return NULL;
301  }
302  return res;
303 }
304 
310  rz_return_val_if_fail(vm && op, NULL);
311  // check type and auto convertion between bitv/bool/val
312  RzILTypePure type = -1;
313  void *res = eval_pure(vm, op, &type);
314  if (!res) {
315  // propagate error
316  return NULL;
317  }
318  switch (type) {
320  return rz_il_value_new_bool(res);
322  return rz_il_value_new_bitv(res);
323  default:
324  RZ_LOG_ERROR("RzIL: type error: got %s\n", pure_type_name(type));
325  return NULL;
326  }
327 }
328 
333  rz_return_val_if_fail(vm && op, NULL);
334  return eval_pure(vm, op, type);
335 }
336 
342  rz_return_val_if_fail(vm && op, false);
343  return eval_effect(vm, op);
344 }
#define RZ_IPI
Definition: analysis_wasm.c:11
static int value
Definition: cmd_api.c:93
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
uint32_t ut32
RZ_API bool rz_il_mem_store(RzILMem *mem, RzBitVector *key, RzBitVector *value)
Definition: mem.c:93
RZ_API bool rz_il_mem_storew(RzILMem *mem, RzBitVector *key, RzBitVector *value, bool big_endian)
Definition: mem.c:169
RZ_API RzBitVector * rz_il_mem_load(RzILMem *mem, RzBitVector *key)
Definition: mem.c:79
RZ_API RzBitVector * rz_il_mem_loadw(RzILMem *mem, RzBitVector *key, ut32 n_bits, bool big_endian)
Definition: mem.c:157
RZ_API RZ_OWN RzILVal * rz_il_value_new_bitv(RZ_NONNULL RzBitVector *bv)
Definition: value.c:28
RZ_API RZ_OWN RzILVal * rz_il_value_new_bool(RZ_NONNULL RzILBool *b)
Definition: value.c:43
RZ_API RZ_OWN RzILEvent * rz_il_event_pc_write_new(RZ_NONNULL const RzBitVector *old_pc, RZ_NONNULL const RzBitVector *new_pc)
Definition: il_events.c:76
RZ_API void rz_il_event_free(RZ_NULLABLE RzILEvent *evt)
Definition: il_events.c:11
RZ_API RZ_OWN RzILEvent * rz_il_event_mem_write_new(RZ_NONNULL const RzBitVector *addr, RZ_NONNULL const RzBitVector *old_v, RZ_NONNULL const RzBitVector *new_v)
Definition: il_events.c:125
RZ_API RZ_OWN RzILEvent * rz_il_event_mem_read_new(RZ_NONNULL const RzBitVector *address, RZ_NULLABLE const RzBitVector *value)
Definition: il_events.c:100
RZ_API RzILMem * rz_il_vm_get_mem(RzILVM *vm, RzILMemIndex index)
Definition: il_vm.c:165
bool rz_il_handler_branch(RzILVM *vm, RzILOpEffect *op)
RZ_API RZ_NULLABLE RZ_OWN void * rz_il_evaluate_pure(RZ_NONNULL RzILVM *vm, RZ_NONNULL RzILOpPure *op, RZ_NONNULL RzILTypePure *type)
Definition: il_vm_eval.c:332
void * rz_il_handler_logical_xor(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:175
void * rz_il_handler_logical_not(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:56
RZ_API void rz_il_vm_clear_events(RzILVM *vm)
Definition: il_vm_eval.c:212
void * rz_il_handler_neg(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:43
void * rz_il_handler_bool_true(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
also known as b1
Definition: theory_bool.c:21
RZ_API void rz_il_vm_mem_storew(RzILVM *vm, RzILMemIndex index, RzBitVector *key, RzBitVector *value)
Definition: il_vm_eval.c:183
RZ_IPI RzILOpEffectHandler rz_il_op_handler_effect_table_default[RZ_IL_OP_EFFECT_MAX]
Definition: il_vm_eval.c:104
void * rz_il_handler_ite(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_init.c:7
void * rz_il_handler_logical_and(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:145
void * rz_il_handler_let(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_init.c:57
void * rz_il_handler_smod(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:276
RZ_API bool rz_il_evaluate_effect(RZ_NONNULL RzILVM *vm, RZ_NONNULL RzILOpEffect *op)
Definition: il_vm_eval.c:341
void * rz_il_handler_bitv(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:336
bool rz_il_handler_nop(RzILVM *vm, RzILOpEffect *op)
Definition: theory_effect.c:34
bool rz_il_handler_jmp(RzILVM *vm, RzILOpEffect *op)
Definition: theory_effect.c:56
RZ_API void rz_il_vm_mem_store(RzILVM *vm, RzILMemIndex index, RzBitVector *key, RzBitVector *value)
Definition: il_vm_eval.c:144
void * rz_il_handler_bool_xor(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bool.c:59
void * rz_il_handler_msb(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:7
void * rz_il_handler_add(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:114
void * rz_il_handler_shiftl(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:291
void * rz_il_handler_bool_false(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
also known as b0
Definition: theory_bool.c:10
void * rz_il_handler_mul(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:205
void * rz_il_handler_logical_or(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:160
RZ_API RZ_NULLABLE RZ_OWN RzBitVector * rz_il_evaluate_bitv(RZ_NONNULL RzILVM *vm, RZ_NONNULL RzILOpBitVector *op)
Definition: il_vm_eval.c:269
bool rz_il_handler_set(RzILVM *vm, RzILOpEffect *op)
Definition: theory_effect.c:39
void * rz_il_handler_loadw(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_mem.c:41
void * rz_il_handler_sdiv(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:246
RZ_API RzBitVector * rz_il_vm_mem_load(RzILVM *vm, RzILMemIndex index, RzBitVector *key)
Definition: il_vm_eval.c:124
bool rz_il_handler_goto(RzILVM *vm, RzILOpEffect *op)
Definition: theory_effect.c:66
void * rz_il_handler_ule(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:99
void * rz_il_handler_lsb(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:19
bool rz_il_handler_empty(RzILVM *vm, RzILOpEffect *op)
Definition: theory_effect.c:28
void * rz_il_handler_bool_and(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bool.c:29
bool rz_il_handler_storew(RzILVM *vm, RzILOpEffect *op)
Definition: theory_mem.c:55
void * rz_il_handler_eq(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:69
RZ_API RzBitVector * rz_il_vm_mem_loadw(RzILVM *vm, RzILMemIndex index, RzBitVector *key, ut32 n_bits)
Definition: il_vm_eval.c:163
bool rz_il_handler_seq(RzILVM *vm, RzILOpEffect *op)
Definition: theory_effect.c:83
void * rz_il_handler_sub(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:190
RZ_API bool rz_il_vm_step(RzILVM *vm, RzILOpEffect *op, ut64 fallthrough_addr)
Definition: il_vm_eval.c:222
void * rz_il_handler_is_zero(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:31
RZ_IPI RzILOpPureHandler rz_il_op_handler_pure_table_default[RZ_IL_OP_PURE_MAX]
Definition: il_vm_eval.c:67
bool rz_il_handler_store(RzILVM *vm, RzILOpEffect *op)
Definition: theory_mem.c:22
void * rz_il_handler_bool_inv(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
also known as boolean not
Definition: theory_bool.c:77
bool rz_il_handler_effect_unimplemented(RzILVM *vm, RzILOpEffect *op)
Definition: theory_init.c:76
void * rz_il_handler_pure_unimplemented(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_init.c:70
RZ_API void rz_il_vm_event_add(RzILVM *vm, RzILEvent *evt)
Definition: il_vm_eval.c:201
void * rz_il_handler_var(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_init.c:26
static void * eval_pure(RZ_NONNULL RzILVM *vm, RZ_NONNULL RzILOpPure *op, RZ_NONNULL RzILTypePure *type)
Definition: il_vm_eval.c:240
void * rz_il_handler_load(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_mem.c:8
void * rz_il_handler_bool_or(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bool.c:44
static bool eval_effect(RZ_NONNULL RzILVM *vm, RZ_NONNULL RzILOpEffect *op)
Definition: il_vm_eval.c:247
bool rz_il_handler_repeat(RzILVM *vm, RzILOpEffect *op)
static const char * pure_type_name(RzILTypePure type)
Definition: il_vm_eval.c:254
void * rz_il_handler_cast(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:346
void * rz_il_handler_sle(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:84
void * rz_il_handler_append(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:130
void * rz_il_handler_mod(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:261
void * rz_il_handler_div(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:221
RZ_API RZ_NULLABLE RZ_OWN RzILBool * rz_il_evaluate_bool(RZ_NONNULL RzILVM *vm, RZ_NONNULL RzILOpBool *op)
Definition: il_vm_eval.c:289
void * rz_il_handler_shiftr(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
Definition: theory_bitv.c:313
RZ_API RZ_NULLABLE RZ_OWN RzILVal * rz_il_evaluate_val(RZ_NONNULL RzILVM *vm, RZ_NONNULL RzILOpPure *op)
Definition: il_vm_eval.c:309
bool rz_il_handler_blk(RzILVM *vm, RzILOpEffect *op)
Definition: theory_effect.c:89
void * mem
Definition: libc.cpp:91
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120
ut32 RzILMemIndex
Definition: mem.h:14
int type
Definition: mipsasm.c:17
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API void rz_bv_free(RZ_NULLABLE RzBitVector *bv)
Definition: bitvector.c:85
RZ_API ut32 rz_bv_len(RZ_NONNULL const RzBitVector *bv)
Definition: bitvector.c:1140
RZ_API RZ_OWN RzBitVector * rz_bv_new_from_ut64(ut32 length, ut64 value)
Definition: bitvector.c:1161
@ RZ_IL_OP_SHIFTR
@ RZ_IL_OP_ULE
@ RZ_IL_OP_SUB
@ RZ_IL_OP_LOGNOT
@ RZ_IL_OP_MSB
@ RZ_IL_OP_ITE
@ RZ_IL_OP_PURE_MAX
@ RZ_IL_OP_SLE
@ RZ_IL_OP_LSB
@ RZ_IL_OP_OR
@ RZ_IL_OP_IS_ZERO
@ RZ_IL_OP_NEG
@ RZ_IL_OP_ADD
@ RZ_IL_OP_B0
@ RZ_IL_OP_LET
@ RZ_IL_OP_CAST
@ RZ_IL_OP_MOD
@ RZ_IL_OP_LOGOR
@ RZ_IL_OP_VAR
@ RZ_IL_OP_INV
@ RZ_IL_OP_APPEND
@ RZ_IL_OP_DIV
@ RZ_IL_OP_SHIFTL
@ RZ_IL_OP_EQ
@ RZ_IL_OP_MUL
@ RZ_IL_OP_BITV
@ RZ_IL_OP_B1
@ RZ_IL_OP_XOR
@ RZ_IL_OP_LOAD
@ RZ_IL_OP_AND
@ RZ_IL_OP_SMOD
@ RZ_IL_OP_LOGXOR
@ RZ_IL_OP_SDIV
@ RZ_IL_OP_LOADW
@ RZ_IL_OP_LOGAND
@ RZ_IL_OP_BLK
@ RZ_IL_OP_GOTO
@ RZ_IL_OP_SEQ
@ RZ_IL_OP_EFFECT_MAX
@ RZ_IL_OP_NOP
@ RZ_IL_OP_JMP
@ RZ_IL_OP_EMPTY
@ RZ_IL_OP_STORE
@ RZ_IL_OP_STOREW
@ RZ_IL_OP_REPEAT
@ RZ_IL_OP_BRANCH
@ RZ_IL_OP_SET
void *(* RzILOpPureHandler)(RzILVM *vm, RzILOpPure *op, RZ_NONNULL RZ_OUT RzILTypePure *type)
Evaluation callback for a single pure opcode.
Definition: rz_il_vm.h:24
bool(* RzILOpEffectHandler)(RzILVM *vm, RzILOpEffect *op)
Evaluation (execution) callback for a single effect opcode.
Definition: rz_il_vm.h:30
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NONNULL
Definition: rz_types.h:64
RzILTypePure
Definition: sort.h:23
@ RZ_IL_TYPE_PURE_BOOL
Definition: sort.h:24
@ RZ_IL_TYPE_PURE_BITVECTOR
Definition: sort.h:25
structure for bitvector
Definition: rz_bitvector.h:19
ut32 len
number of bits – virtual / logical
Definition: rz_bitvector.h:25
A single memory as part of the RzIL VM.
Definition: mem.h:26
An IL op performing a pure computation, 'a pure.
Low-level VM to execute raw IL code.
Definition: rz_il_vm.h:37
RzILVarSet local_vars
All local variables, created by local set ops.
Definition: rz_il_vm.h:39
RzList * events
List of events that has happened in the last step.
Definition: rz_il_vm.h:49
bool big_endian
Sets the endianness of the memory reads/writes operations.
Definition: rz_il_vm.h:50
RzBitVector * pc
Program Counter of VM.
Definition: rz_il_vm.h:46
Definition: dis.c:32
struct op_code code
Definition: dis.c:33
RZ_API void rz_il_var_set_reset(RzILVarSet *vs)
Definition: variable.c:81
ut64(WINAPI *w32_GetEnabledXStateFeatures)()