static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { short ofst; int imm = 0, d, r, k; ut8 kbuf[4]; ut16 ins = AVR_SOFTCAST (buf[0], buf[1]); char *arg, str[32]; if (op == NULL) { return 2; } memset (op, '\0', sizeof (RAnalOp)); op->type = R_ANAL_OP_TYPE_UNK; op->ptr = UT64_MAX; op->val = UT64_MAX; op->jump = UT64_MAX; op->fail = UT64_MAX; op->refptr = 0; op->nopcode = 1; // Necessary?? op->size = avrdis (str, addr, buf, len); r_strbuf_init (&op->esil); arg = strchr (str, ' '); if (arg) { arg++; imm = (int)r_num_get (NULL, arg); } op->delay = 0; op->type = R_ANAL_OP_TYPE_UNK; if (!strncmp (str, "st", 2)) { op->type = R_ANAL_OP_TYPE_STORE; } else if (str[0] == 'l') { op->type = R_ANAL_OP_TYPE_LOAD; } else if (str[0] == 's') { op->type = R_ANAL_OP_TYPE_SUB; } else if (!strncmp (str, "inv", 3)) { op->type = R_ANAL_OP_TYPE_ILL; } else if (!strncmp (str, "ser ", 4)) { op->type = R_ANAL_OP_TYPE_MOV; } else if (!strncmp (str, "and", 3)) { op->type = R_ANAL_OP_TYPE_AND; } else if (!strncmp (str, "mul", 3)) { op->type = R_ANAL_OP_TYPE_MUL; } else if (!strncmp (str, "out ", 4)) { op->type = R_ANAL_OP_TYPE_IO; op->type2 = 1; op->val = imm; } else if (!strncmp (str, "in ", 3)) { op->type = R_ANAL_OP_TYPE_IO; op->type2 = 0; op->val = imm; } else if (!strncmp (str, "push ", 5)) { op->type = R_ANAL_OP_TYPE_PUSH; } if (ins == 0) { op->type = R_ANAL_OP_TYPE_NOP; op->cycles = 1; } if (buf[1] == 1) { //MOVW d = (buf[0] & 0xf0) >> 3; r = (buf[0] & 0x0f) << 1; op->type = R_ANAL_OP_TYPE_MOV; op->cycles = 1; r_strbuf_setf (&op->esil, "r%d,r%d,=,r%d,r%d,=", r, d, r+1, d+1); }
static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { short ofst; ut8 kbuf[2]; ut16 ins = AVR_SOFTCAST(buf[0],buf[1]); if (op == NULL) return 2; op->size = 2; op->delay = 0; op->type = R_ANAL_OP_TYPE_UNK; if (ins == 0) { op->type = R_ANAL_OP_TYPE_NOP; op->cycles = 1; } if ((buf[1] & 0xec) == 12) { //ADD + ADC op->type = R_ANAL_OP_TYPE_ADD; op->cycles = 1; } if ((buf[1] & 0xec) == 8) { //SUB + SBC op->type = R_ANAL_OP_TYPE_SUB; op->cycles = 1; } if (((buf[0] & 0xf) == 7) && ((buf[1] & 0xfe) == 0x94)) { op->type = R_ANAL_OP_TYPE_ROR; op->cycles = 1; } if (buf[1] == 1) { //MOVW op->type = R_ANAL_OP_TYPE_MOV; op->cycles = 1; } if ((buf[1] & 0xf0) == 0xe0) { //LDI op->type = R_ANAL_OP_TYPE_LOAD; op->cycles = 1; } if ((buf[1] & 0xec) == 4) { //CP + CPC op->type = R_ANAL_OP_TYPE_CMP; op->cycles = 1; } switch (buf[1] & 0xfc) { case 0x10: //CPSE op->type = R_ANAL_OP_TYPE_CMP; op->type2 = R_ANAL_OP_TYPE_CJMP; op->failcycles = 1; //TODO Cycles break; case 0x20: //TST op->type = R_ANAL_OP_TYPE_ACMP; op->cycles = 1; break; case 0x24: //EOR op->type = R_ANAL_OP_TYPE_XOR; op->cycles = 1; break; case 0x28: //OR op->type = R_ANAL_OP_TYPE_OR; op->cycles = 1; break; case 0x2c: //MOV op->type = R_ANAL_OP_TYPE_MOV; op->cycles = 1; break; } switch (buf[1]) { case 0x96: //ADIW op->type = R_ANAL_OP_TYPE_ADD; op->cycles = 2; break; case 0x97: //SBIW op->type = R_ANAL_OP_TYPE_SUB; op->cycles = 2; break; case 0x98: //SBI case 0x9a: //CBI op->type = R_ANAL_OP_TYPE_IO; op->cycles = 2; //1 for atTiny break; case 0x99: //SBIC case 0x9b: //SBIS op->type = R_ANAL_OP_TYPE_CMP; op->type2 = R_ANAL_OP_TYPE_CJMP; op->failcycles = 1; break; } if (!memcmp (buf, "\x0e\x94", 2)) { op->addr = addr; op->type = R_ANAL_OP_TYPE_CALL; // call (absolute) op->fail = (op->addr)+4; // override even if len<4 wtf len = 4; if (len>3) { memcpy (kbuf, buf+2, 2); op->size = 4; //anal->iob.read_at (anal->iob.io, addr+2, kbuf, 2); op->jump = AVR_SOFTCAST(kbuf[0],kbuf[1])*2; } else { op->size = 0; return -1; return op->size; //WTF } //eprintf("addr: %x inst: %x dest: %x fail:%x\n", op->addr, *ins, op->jump, op->fail); } if ((buf[1] & 0xf0) == 0xd0) { op->addr = addr; op->type = R_ANAL_OP_TYPE_CALL; // rcall (relative) op->fail = (op->addr)+2; ofst = ins<<4; ofst>>=4; ofst*=2; op->jump = addr+ofst+2; //eprintf("addr: %x inst: %x ofst: %d dest: %x fail:%x\n", op->addr, *ins, ofst, op->jump, op->fail); }