void reil_generate_carry_flag(RAnalEsil *esil, ut8 bit) { RAnalReilArg *op1; r_anal_esil_pushnum(esil, bit); r_anal_esil_pushnum(esil, 0x3f); reil_and(esil); // Generate the mask. 2 << bits - 1 reil_generate_mask(esil); op1 = reil_pop_arg(esil); // old & mask r_anal_esil_push(esil, esil->Reil->old); reil_push_arg(esil, op1); reil_and(esil); // cur & mask r_anal_esil_push(esil, esil->Reil->cur); reil_push_arg(esil, op1); reil_and(esil); // Check reil_smaller(esil); free (op1); }
void reil_generate_signature(RAnalEsil *esil) { if (!esil->Reil->lastsz || esil->Reil->lastsz == 0) { r_anal_esil_pushnum(esil, 0); return; } RAnalReilArg *op; r_anal_esil_pushnum(esil, esil->Reil->lastsz - 1); r_anal_esil_pushnum(esil, 1); reil_lsl(esil); r_anal_esil_push(esil, esil->Reil->cur); reil_and(esil); op = reil_pop_arg(esil); if (!op) return; r_anal_esil_pushnum(esil, esil->Reil->lastsz - 1); reil_push_arg(esil, op); reil_lsr(esil); free (op); }
// n = 8, 4, 2, 1 static int reil_poken(RAnalEsil *esil, ut8 n) { char tmp_buf[REGBUFSZ]; RAnalReilInst *ins; RAnalReilArg *op2, *op1; op2 = reil_pop_arg (esil); if (!op2) return false; op1 = reil_pop_arg (esil); if (!op1) { R_FREE (op2); return false; } if (op1->type != ARG_ESIL_INTERNAL) { ins = R_NEW0 (RAnalReilInst); if (!ins) return false; ins->opcode = REIL_LDM; ins->arg[0] = op2; ins->arg[1] = R_NEW0(RAnalReilArg); if (!ins->arg[1]) { R_FREE (op1); reil_free_inst (ins); return false; } ins->arg[2] = R_NEW0(RAnalReilArg); if (!ins->arg[2]) { R_FREE (op1); reil_free_inst (ins); return false; } reil_make_arg (esil, ins->arg[1], " "); get_next_temp_reg (esil, tmp_buf); reil_make_arg (esil, ins->arg[2], tmp_buf); ins->arg[2]->size = ins->arg[0]->size; reil_print_inst (esil, ins); snprintf (esil->Reil->old, sizeof (esil->Reil->old) - 1, "%s:%d", ins->arg[2]->name, ins->arg[2]->size); snprintf (esil->Reil->cur, sizeof (esil->Reil->cur) - 1, "%s:%d", op2->name, op2->size); esil->lastsz = n * 8; reil_push_arg (esil, op1); reil_push_arg (esil, op2); R_FREE (op1); reil_free_inst (ins); } else { reil_flag_spew_inst (esil, op1->name + 1); R_FREE (op1); op1 = reil_pop_arg (esil); reil_push_arg (esil, op2); reil_push_arg (esil, op1); R_FREE (op2); R_FREE (op1); } ins = R_NEW0 (RAnalReilInst); if (!ins) return false; ins->opcode = REIL_STM; ins->arg[2] = reil_pop_arg (esil); ins->arg[0] = reil_pop_arg (esil); ins->arg[1] = R_NEW0 (RAnalReilArg); if (!ins->arg[1]) { reil_free_inst (ins); return false; } reil_make_arg(esil, ins->arg[1], " "); reil_print_inst(esil, ins); reil_free_inst(ins); return true; }
// Here start translation functions! static int reil_eq(RAnalEsil *esil) { RAnalReilInst *ins; char tmp_buf[REGBUFSZ]; RAnalReilArgType src_type, dst_type; RAnalReilArg *dst, *src; dst = reil_pop_arg (esil); if (!dst) return false; src = reil_pop_arg (esil); if (!src) { R_FREE (dst); return false; } src_type = src->type; // Check if the src is an internal var. If it is, we need to resolve it. if (src_type == ARG_ESIL_INTERNAL) { reil_flag_spew_inst (esil, src->name + 1); R_FREE (src); src = reil_pop_arg (esil); } else if (src_type == ARG_REG) { // No direct register to register transfer. ins = R_NEW0 (RAnalReilInst); if (!ins) return false; ins->opcode = REIL_STR; ins->arg[0] = src; ins->arg[1] = R_NEW0 (RAnalReilArg); if (!ins->arg[1]) { reil_free_inst (ins); return false; } ins->arg[2] = R_NEW0(RAnalReilArg); if (!ins->arg[2]) { reil_free_inst (ins); return false; } reil_make_arg (esil, ins->arg[1], " "); get_next_temp_reg (esil, tmp_buf); reil_make_arg (esil, ins->arg[2], tmp_buf); ins->arg[2]->size = ins->arg[0]->size; reil_print_inst (esil, ins); reil_push_arg( esil, ins->arg[2]); reil_free_inst (ins); src = reil_pop_arg (esil); } // First, make a copy of the dst. We will need this to set the flags later on. ins = R_NEW0 (RAnalReilInst); if (!ins) return false; dst_type = dst->type; if (src_type != ARG_ESIL_INTERNAL && dst_type == ARG_REG) { ins->opcode = REIL_STR; ins->arg[0] = dst; ins->arg[1] = R_NEW0 (RAnalReilArg); if (!ins->arg[1]) { reil_free_inst (ins); return false; } ins->arg[2] = R_NEW0 (RAnalReilArg); if (!ins->arg[2]) { reil_free_inst (ins); return false; } reil_make_arg (esil, ins->arg[1], " "); get_next_temp_reg (esil, tmp_buf); reil_make_arg (esil, ins->arg[2], tmp_buf); ins->arg[2]->size = ins->arg[0]->size; reil_print_inst (esil, ins); // Used for setting the flags snprintf (esil->Reil->old, sizeof (esil->Reil->old) - 1, "%s:%d", ins->arg[2]->name, ins->arg[2]->size); snprintf (esil->Reil->cur, sizeof (esil->Reil->cur) - 1, "%s:%d", dst->name, dst->size); esil->Reil->lastsz = dst->size; R_FREE (ins->arg[1]); R_FREE (ins->arg[2]); } // If we are modifying the Instruction Pointer, then we need to emit JCC instead. if (!strcmp(esil->Reil->pc, dst->name)) { ins->opcode = REIL_JCC; r_anal_esil_push (esil, "1:1"); ins->arg[0] = reil_pop_arg (esil); ins->arg[1] = R_NEW0 (RAnalReilArg); reil_make_arg (esil, ins->arg[1], " "); ins->arg[2] = src; reil_print_inst (esil, ins); reil_free_inst (ins); R_FREE (dst); return true; } reil_cast_size (esil, src, dst); ins->opcode = REIL_STR; ins->arg[0] = reil_pop_arg (esil); if (!ins->arg[0]) { R_FREE (dst); reil_free_inst (ins); return false; } ins->arg[2] = dst; ins->arg[1] = R_NEW0 (RAnalReilArg); reil_make_arg (esil, ins->arg[1], " "); reil_print_inst (esil, ins); reil_free_inst (ins); return true; }