R_API int r_anal_cond_eval(RAnal *anal, RAnalCond *cond) { // XXX: sign issue here? st64 arg0 = (st64) r_anal_value_to_ut64 (anal, cond->arg[0]); if (cond->arg[1]) { st64 arg1 = (st64) r_anal_value_to_ut64 (anal, cond->arg[1]); switch (cond->type) { case R_ANAL_COND_EQ: return arg0 == arg1; case R_ANAL_COND_NE: return arg0 != arg1; case R_ANAL_COND_GE: return arg0 >= arg1; case R_ANAL_COND_GT: return arg0 > arg1; case R_ANAL_COND_LE: return arg0 <= arg1; case R_ANAL_COND_LT: return arg0 < arg1; } } else { switch (cond->type) { case R_ANAL_COND_EQ: return !arg0; case R_ANAL_COND_NE: return arg0; case R_ANAL_COND_GT: return arg0>0; case R_ANAL_COND_GE: return arg0>=0; case R_ANAL_COND_LT: return arg0<0; case R_ANAL_COND_LE: return arg0<=0; } } return R_FALSE; }
R_API int r_anal_value_set_ut64(RAnal *anal, RAnalValue *val, ut64 num) { if (val->memref) { if (anal->iob.io) { ut8 data[8]; ut64 addr = r_anal_value_to_ut64 (anal, val); r_mem_set_num (data, val->memref, num, anal->big_endian); anal->iob.write_at (anal->iob.io, addr, data, val->memref); } else eprintf ("No IO binded to r_anal\n"); } else { if (val->reg) r_reg_set_value (anal->reg, val->reg, num); } return R_FALSE; //is this necessary }
// TODO: return RAnalException * R_API int r_anal_op_execute (RAnal *anal, RAnalOp *op) { while (op) { if (op->delay>0) { anal->queued = r_anal_op_copy (op); return R_FALSE; } switch (op->type) { case R_ANAL_OP_TYPE_JMP: case R_ANAL_OP_TYPE_UJMP: case R_ANAL_OP_TYPE_CALL: break; case R_ANAL_OP_TYPE_ADD: // dst = src[0] + src[1] + src[2] r_anal_value_set_ut64 (anal, op->dst, r_anal_value_to_ut64 (anal, op->src[0])+ r_anal_value_to_ut64 (anal, op->src[1])+ r_anal_value_to_ut64 (anal, op->src[2])); break; case R_ANAL_OP_TYPE_SUB: // dst = src[0] + src[1] + src[2] r_anal_value_set_ut64 (anal, op->dst, r_anal_value_to_ut64 (anal, op->src[0])- r_anal_value_to_ut64 (anal, op->src[1])- r_anal_value_to_ut64 (anal, op->src[2])); break; case R_ANAL_OP_TYPE_DIV: { ut64 div = r_anal_value_to_ut64 (anal, op->src[1]); if (div == 0) { eprintf ("r_anal_op_execute: division by zero\n"); eprintf ("TODO: throw RAnalException\n"); } else r_anal_value_set_ut64 (anal, op->dst, r_anal_value_to_ut64 (anal, op->src[0])/div); } break; case R_ANAL_OP_TYPE_MUL: r_anal_value_set_ut64 (anal, op->dst, r_anal_value_to_ut64 (anal, op->src[0])* r_anal_value_to_ut64 (anal, op->src[1])); break; case R_ANAL_OP_TYPE_MOV: // dst = src[0] r_anal_value_set_ut64 (anal, op->dst, r_anal_value_to_ut64 (anal, op->src[0])); break; case R_ANAL_OP_TYPE_NOP: // do nothing break; } op = op->next; } if (anal->queued) { if (op && op->delay>0) { eprintf ("Exception! two consecutive delayed instructions\n"); return R_FALSE; } anal->queued->delay--; if (anal->queued->delay == 0) { r_anal_op_execute (anal, anal->queued); r_anal_op_free (anal->queued); anal->queued = NULL; } } return R_TRUE; }