R_API bool r_anal_op_fini(RAnalOp *op) { if (!op) { return false; } if (((ut64)(size_t)op) == UT64_MAX) { return false; } if (((ut64)(size_t)op->mnemonic) == UT64_MAX) { return false; } r_anal_var_free (op->var); r_anal_value_free (op->src[0]); r_anal_value_free (op->src[1]); r_anal_value_free (op->src[2]); r_anal_value_free (op->dst); r_strbuf_fini (&op->esil); r_anal_switch_op_free (op->switch_op); op->src[0] = NULL; op->src[1] = NULL; op->src[2] = NULL; op->dst = NULL; op->var = NULL; op->switch_op = NULL; R_FREE (op->mnemonic); R_FREE (op->reg); return true; }
R_API void r_anal_op_fini(RAnalOp *op) { r_anal_value_free (op->src[0]); r_anal_value_free (op->src[1]); r_anal_value_free (op->src[2]); r_anal_value_free (op->dst); r_anal_switch_op_free (op->switch_op); free (op->mnemonic); memset (op, 0, sizeof (RAnalOp)); }
R_API void r_anal_op_fini(RAnalOp *op) { if (op->src[0]) r_anal_value_free (op->src[0]); if (op->src[1]) r_anal_value_free (op->src[1]); if (op->src[2]) r_anal_value_free (op->src[2]); if (op->dst) r_anal_value_free (op->dst); free (op->mnemonic); op->mnemonic = NULL; //op->src[0] = op->src[1] = op->src[2] = op->dst = NULL; memset (op, 0, sizeof (RAnalOp)); }
R_API void r_anal_op_fini(RAnalOp *op) { if (!op) // || !op->mnemonic) return; if (((ut64)(size_t)op) == UT64_MAX) { return; } if (((ut64)(size_t)op->mnemonic) == UT64_MAX) { return; } r_anal_value_free (op->src[0]); r_anal_value_free (op->src[1]); r_anal_value_free (op->src[2]); r_anal_value_free (op->dst); r_anal_switch_op_free (op->switch_op); free (op->mnemonic); memset (op, 0, sizeof (RAnalOp)); }
R_API bool r_anal_op_fini(RAnalOp *op) { if (!op) { return false; } r_anal_var_free (op->var); op->var = NULL; r_anal_value_free (op->src[0]); r_anal_value_free (op->src[1]); r_anal_value_free (op->src[2]); op->src[0] = NULL; op->src[1] = NULL; op->src[2] = NULL; r_anal_value_free (op->dst); op->dst = NULL; r_strbuf_fini (&op->opex); r_strbuf_fini (&op->esil); r_anal_switch_op_free (op->switch_op); R_FREE (op->mnemonic); return true; }
R_API void r_anal_cond_fini (RAnalCond *c) { if (!c) return; r_anal_value_free (c->arg[0]); r_anal_value_free (c->arg[1]); c->arg[0] = c->arg[1] = NULL; }
// NOTE: buf should be at least 16 bytes! // XXX addr should be off_t for 64 love static int myop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { if (buf == NULL) return 0; memset (op, 0, sizeof (RAnalOp)); op->type = R_ANAL_OP_TYPE_UNK; op->addr = addr; op->jump = op->fail = -1; op->ptr = op->val = -1; switch (buf[0]) { case 0x8a: case 0x8b: case 0x03: // 034518 add eax, [ebp+0x18] switch (buf[1]) { case 0x45: case 0x46: case 0x55: case 0x5d: case 0x7d: /* mov -0xc(%ebp, %eax */ op->ptr = (st64)((char)buf[2]); op->stackop = R_ANAL_STACK_GET; break; case 0x95: if (buf[2]==0xe0) { // ebp op->ptr = (st64)((int)(buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24))); op->stackop = R_ANAL_STACK_GET; } //op->ptr = -(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)); break; case 0xbd: op->ptr = (st64)((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24))); //op->ptr = -(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)); op->stackop = R_ANAL_STACK_GET; break; } break; case 0x88: case 0x89: // move switch (buf[1]) { case 0x45: case 0x4d: // 894de0 mov [ebp-0x20], ecx case 0x55: op->stackop = R_ANAL_STACK_SET; op->ptr = (st64)((char)buf[2]); break; case 0x85: op->stackop = R_ANAL_STACK_SET; op->ptr = (st64)((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24))); break; case 0x75: op->stackop = R_ANAL_STACK_GET; op->ptr = (st64)((char)buf[2]); //+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)); break; } // XXX: maybe store or mov depending on opcode // 89c3 mov ebx, eax // 897c2408 mov [esp+0x8], edi op->type = R_ANAL_OP_TYPE_STORE; break; case 0xf4: // hlt op->type = R_ANAL_OP_TYPE_RET; op->size = 1; break; case 0xc3: // ret case 0xc2: // ret + 2 bytes case 0xcb: // lret case 0xcf: // iret op->type = R_ANAL_OP_TYPE_RET; op->eob = 1; break; //case 0xea: // far jmp // TODO moar case 0x3b: //cmp op->ptr = (st64)((char)buf[2]); op->stackop = R_ANAL_STACK_GET; case 0x39: case 0x3c: case 0x3d: // 3d 00 40 00 00 cmp eax, 0x4000 op->src[0] = r_anal_value_new (); op->src[0]->reg = r_reg_get (anal->reg, testregs[(buf[0]&7)%8], R_REG_TYPE_GPR); op->src[1] = r_anal_value_new (); op->src[1]->base = buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24); op->type = R_ANAL_OP_TYPE_CMP; break; case 0x80: op->type = R_ANAL_OP_TYPE_CMP; switch (buf[1]) { case 0x3d: // 80 3d b5010608 00 cmp byte [0x80601b5], 0x0 op->src[0] = r_anal_value_new (); op->src[0]->memref = 1; op->src[0]->base = buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24); op->src[1] = r_anal_value_new (); op->src[1]->base = buf[6]; break; } break; case 0x85: op->type = R_ANAL_OP_TYPE_CMP; if (buf[1]>=0xc0) { int src = buf[1]&7; int dst = (buf[1]&0x38)>>3; op->src[0] = r_anal_value_new (); op->src[0]->reg = r_reg_get (anal->reg, testregs[src%8], R_REG_TYPE_GPR); op->src[1] = r_anal_value_new (); op->src[1]->reg = r_reg_get (anal->reg, testregs[dst%8], R_REG_TYPE_GPR); op->src[2] = NULL; //eprintf ("REGZ (%s)\n", anal->reg); //eprintf ("REG IZ: (%s)\n", testregs[src%8]); //eprintf ("REG IZ: %p (%s)\n", op->src[0], op->src[0]->reg->name); if (op->src[0]->reg == op->src[1]->reg) { //eprintf ("fruity\n"); r_anal_value_free (op->src[1]); op->src[1] = NULL; } //eprintf ("0x%"PFMT64x": (%02x) %d %d\n", addr, buf[1], src, dst); } else if (buf[1]<0xc0) { // test [eax+delta], eax