Exemple #1
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	csh handle = 0;
	cs_insn *insn = NULL;
	int mode = (a->bits==16)? CS_MODE_THUMB: CS_MODE_ARM;
	int n, ret;
	mode |= (a->big_endian)? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN;

	ret = (a->bits==64)?
		cs_open (CS_ARCH_ARM64, mode, &handle):
		cs_open (CS_ARCH_ARM, mode, &handle);
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
	op->type = R_ANAL_OP_TYPE_NULL;
	op->size = (a->bits==16)? 2: 4;
	op->delay = 0;
	op->jump = op->fail = -1;
	op->addr = addr;
	op->ptr = op->val = -1;
	op->refptr = 0;
	r_strbuf_init (&op->esil);
	if (ret == CS_ERR_OK) {
		n = cs_disasm (handle, (ut8*)buf, len, addr, 1, &insn);
		if (n<1) {
			op->type = R_ANAL_OP_TYPE_ILL;
		} else {
			op->size = insn->size;
			if (a->bits == 64) {
				anop64 (op, insn);
			} else {
				anop32 (op, insn);
			}
			if (a->decode) {
				analop_esil (a, op, addr, buf, len, &handle, insn);
			}
			cs_free (insn, n);
		}
		cs_close (&handle);
	}
	return op->size;
}
Exemple #2
0
static int i8051_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	char *tmp =  NULL;
	char buf_asm[64];
	op->delay = 0;
	r_8051_op o = r_8051_decode (buf, len);
	memset(buf_asm, 0, sizeof (buf_asm));
	if (!o.name) return 0; // invalid instruction
	tmp = r_8051_disasm (o, addr, buf_asm, sizeof (buf_asm));
	if (tmp) {
		if (strlen (tmp) < sizeof (buf_asm)) {
			strncpy (buf_asm, tmp, strlen (tmp));
		} else {
			eprintf ("8051 analysis: too big opcode!\n");
			free (tmp);
			op->size = -1;
			return -1;
		}
		free (tmp);
	}
	if (!strncmp (buf_asm, "push", 4)) {
		op->type = R_ANAL_OP_TYPE_UPUSH;
		op->ptr = 0;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = 1;
	} else
	if (!strncmp (buf_asm, "pop", 3)) {
		op->type = R_ANAL_OP_TYPE_POP;
		op->ptr = 0;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -1;
	} else
	if (!strncmp (buf_asm, "ret", 3)) {
		op->type = R_ANAL_OP_TYPE_RET;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -2;
	} else
	if (!strncmp (buf_asm, "nop", 3)) {
		op->type = R_ANAL_OP_TYPE_NOP;
	} else
	if (!strncmp (buf_asm, "inv", 3)) {
		op->type = R_ANAL_OP_TYPE_ILL;
	} else
	if ((!strncmp (buf_asm, "inc", 3)) ||
		(!strncmp (buf_asm, "add", 3))) {
		op->type = R_ANAL_OP_TYPE_ADD;
	} else
	if ((!strncmp (buf_asm, "dec", 3)) ||
		(!strncmp (buf_asm, "sub", 3))) {
		op->type = R_ANAL_OP_TYPE_SUB;
	} else
	if (!strncmp (buf_asm, "mov", 3)) {
		op->type = R_ANAL_OP_TYPE_MOV;
	} else
	if (*buf_asm && !strncmp (buf_asm+1, "call", 4)) {
		op->type = R_ANAL_OP_TYPE_CALL;
		op->jump = o.addr;
		op->fail = addr+o.length;
	} else
		/* CJNE, DJNZ, JC, JNC, JZ, JB, JNB, LJMP, SJMP */
	if (buf_asm[0]=='j' || (buf_asm[0] && buf_asm[1] == 'j'))
	{
		op->type = R_ANAL_OP_TYPE_JMP;
		if (o.operand == OFFSET)
			op->jump = o.addr+addr+o.length;
		else
		op->jump = o.addr;
		op->fail = addr+o.length;
	}
	if (anal->decode) {
		ut8 copy[3] = {0, 0, 0};
		memcpy (copy, buf, len >= 3 ? 3 : len);
		analop_esil (anal, op, addr, copy, buf_asm);
	}
	return op->size = o.length;
}
Exemple #3
0
static int analop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	int n, ret, opsize = -1;
	static csh hndl = 0;
	static csh *handle = &hndl;
	static int omode = -1;
	static int obits = 32;
	cs_insn* insn;
	int mode = anal->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN;

	mode |= (anal->bits==64)? CS_MODE_64: CS_MODE_32;
	if (mode != omode || anal->bits != obits) {
		cs_close (&hndl);
		hndl = 0;
		omode = mode;
		obits = anal->bits;
	}
// XXX no arch->cpu ?!?! CS_MODE_MICRO, N64
	op->delay = 0;
	op->type = R_ANAL_OP_TYPE_ILL;
	if (len<4)
		return -1;
	op->size = 4;
	if (hndl == 0) {
		ret = cs_open (CS_ARCH_MIPS, mode, &hndl);
		if (ret != CS_ERR_OK) goto fin;
		cs_option (hndl, CS_OPT_DETAIL, CS_OPT_ON);
	}
	n = cs_disasm (hndl, (ut8*)buf, len, addr, 1, &insn);
	if (n<1 || insn->size<1)
		goto beach;
	op->type = R_ANAL_OP_TYPE_NULL;
	op->delay = 0;
	op->jump = UT64_MAX;
	op->fail = UT64_MAX;
	opsize = op->size = insn->size;
	switch (insn->id) {
	case MIPS_INS_INVALID:
		op->type = R_ANAL_OP_TYPE_ILL;
		break;
	case MIPS_INS_LB:
	case MIPS_INS_LBU:
	case MIPS_INS_LBUX:
	case MIPS_INS_LW:
	case MIPS_INS_LWC1:
	case MIPS_INS_LWC2:
	case MIPS_INS_LWL:
	case MIPS_INS_LWR:
	case MIPS_INS_LWXC1:
	case MIPS_INS_LD:
	case MIPS_INS_LDC1:
	case MIPS_INS_LDC2:
	case MIPS_INS_LDL:
	case MIPS_INS_LDR:
	case MIPS_INS_LDXC1:
		op->type = R_ANAL_OP_TYPE_LOAD;
		op->refptr = 4;
		switch (OPERAND(1).type) {
		case MIPS_OP_MEM:
			if (OPERAND(1).mem.base == MIPS_REG_GP) {
				op->ptr = anal->gp + OPERAND(1).mem.disp;
				op->refptr = 4;
			}
			break;
		case MIPS_OP_IMM:
			op->ptr = OPERAND(1).imm;
			break;
		case MIPS_OP_REG:
			// wtf?
			break;
		default:
			break;
		}
		// TODO: fill
		break;
	case MIPS_INS_SW:
	case MIPS_INS_SWC1:
	case MIPS_INS_SWC2:
	case MIPS_INS_SWL:
	case MIPS_INS_SWR:
	case MIPS_INS_SWXC1:
		op->type = R_ANAL_OP_TYPE_STORE;
		break;
	case MIPS_INS_NOP:
		op->type = R_ANAL_OP_TYPE_NOP;
		break;
	case MIPS_INS_SYSCALL:
	case MIPS_INS_BREAK:
		op->type = R_ANAL_OP_TYPE_TRAP;
		break;
	case MIPS_INS_JALR:
		op->type = R_ANAL_OP_TYPE_UCALL;
		op->delay = 1;
		break;
	case MIPS_INS_JAL:
	case MIPS_INS_JALS:
	case MIPS_INS_JALX:
	case MIPS_INS_JRADDIUSP:
	case MIPS_INS_BAL:
	// (no blezal/bgtzal or blezall/bgtzall, only blezalc/bgtzalc)
	case MIPS_INS_BLTZAL: // Branch on <0 and link
	case MIPS_INS_BGEZAL: // Branch on >=0 and link
	case MIPS_INS_BLTZALL: // "likely" versions
	case MIPS_INS_BGEZALL:
	case MIPS_INS_BLTZALC: // compact versions
	case MIPS_INS_BLEZALC:
	case MIPS_INS_BGEZALC:
	case MIPS_INS_BGTZALC:
	case MIPS_INS_JIALC:
	case MIPS_INS_JIC:
		op->type = R_ANAL_OP_TYPE_CALL;
		op->jump = IMM(0);

		switch (insn->id) {
		case MIPS_INS_JIALC:
		case MIPS_INS_JIC:
		case MIPS_INS_BLTZALC:
		case MIPS_INS_BLEZALC:
		case MIPS_INS_BGEZALC:
		case MIPS_INS_BGTZALC:
			// compact vesions (no delay)
			op->delay = 0;
			op->fail = addr+4;
			break;
		default:
			op->delay = 1;
			op->fail = addr+8;
			break;
		}
		break;
	case MIPS_INS_LUI:
	case MIPS_INS_MOVE:
		op->type = R_ANAL_OP_TYPE_MOV;
		SET_SRC_DST_2_REGS (op);
		break;
	case MIPS_INS_ADD:
	case MIPS_INS_ADDI:
	case MIPS_INS_ADDU:
	case MIPS_INS_ADDIU:
	case MIPS_INS_DADD:
	case MIPS_INS_DADDI:
	case MIPS_INS_DADDIU:
		SET_VAL (op, 2);
		SET_SRC_DST_3_REG_OR_IMM (op);
		op->type = R_ANAL_OP_TYPE_ADD;
		break;
	case MIPS_INS_SUB:
	case MIPS_INS_SUBV:
	case MIPS_INS_SUBVI:
	case MIPS_INS_DSUBU:
	case MIPS_INS_FSUB:
	case MIPS_INS_FMSUB:
	case MIPS_INS_SUBU:
	case MIPS_INS_DSUB:
	case MIPS_INS_SUBS_S:
	case MIPS_INS_SUBS_U:
	case MIPS_INS_SUBUH:
	case MIPS_INS_SUBUH_R:
		SET_VAL (op,2);
		SET_SRC_DST_3_REG_OR_IMM (op);
		op->type = R_ANAL_OP_TYPE_SUB;
		break;
	case MIPS_INS_MULV:
	case MIPS_INS_MULT:
	case MIPS_INS_MULSA:
	case MIPS_INS_FMUL:
	case MIPS_INS_MUL:
	case MIPS_INS_DMULT:
	case MIPS_INS_DMULTU:
		op->type = R_ANAL_OP_TYPE_MUL;
		break;
	case MIPS_INS_XOR:
	case MIPS_INS_XORI:
		SET_VAL (op,2);
		SET_SRC_DST_3_REG_OR_IMM (op);
		op->type = R_ANAL_OP_TYPE_XOR;
		break;
	case MIPS_INS_AND:
	case MIPS_INS_ANDI:
		SET_VAL (op,2);
		SET_SRC_DST_3_REG_OR_IMM (op);
		op->type = R_ANAL_OP_TYPE_AND;
		break;
	case MIPS_INS_NOT:
		op->type = R_ANAL_OP_TYPE_NOT;
		break;
	case MIPS_INS_OR:
	case MIPS_INS_ORI:
		SET_VAL (op,2);
		SET_SRC_DST_3_REG_OR_IMM (op);
		op->type = R_ANAL_OP_TYPE_OR;
		break;
	case MIPS_INS_DIV:
	case MIPS_INS_DIVU:
	case MIPS_INS_DDIV:
	case MIPS_INS_DDIVU:
	case MIPS_INS_FDIV:
	case MIPS_INS_DIV_S:
	case MIPS_INS_DIV_U:
		SET_SRC_DST_3_REGS (op);
		op->type = R_ANAL_OP_TYPE_DIV;
		break;
	case MIPS_INS_CMPGDU:
	case MIPS_INS_CMPGU:
	case MIPS_INS_CMPU:
	case MIPS_INS_CMPI:
		op->type = R_ANAL_OP_TYPE_CMP;
		break;
	case MIPS_INS_J:
	case MIPS_INS_B:
	case MIPS_INS_BZ:
	case MIPS_INS_BEQ:
	case MIPS_INS_BNZ:
	case MIPS_INS_BNE:
	case MIPS_INS_BEQZ:
	case MIPS_INS_BNEG:
	case MIPS_INS_BNEGI:
	case MIPS_INS_BNEZ:
	case MIPS_INS_BTEQZ:
	case MIPS_INS_BTNEZ:
	case MIPS_INS_BLTZ:
	case MIPS_INS_BLTZL:
	case MIPS_INS_BLEZ:
	case MIPS_INS_BLEZL:
	case MIPS_INS_BGEZ:
	case MIPS_INS_BGEZL:
	case MIPS_INS_BGTZ:
	case MIPS_INS_BGTZL:
	case MIPS_INS_BLEZC:
	case MIPS_INS_BGEZC:
	case MIPS_INS_BLTZC:
	case MIPS_INS_BGTZC:
		if (insn->id == MIPS_INS_J || insn->id == MIPS_INS_B ) {
			op->type = R_ANAL_OP_TYPE_JMP;
		} else {
			op->type = R_ANAL_OP_TYPE_CJMP;
		}
		
		if (OPERAND(0).type == MIPS_OP_IMM) {
			op->jump = IMM(0);
		} else if (OPERAND(1).type == MIPS_OP_IMM) {
			op->jump = IMM(1);
		} else if (OPERAND(2).type == MIPS_OP_IMM) {
			op->jump = IMM(2);
		}

		switch (insn->id) {
		case MIPS_INS_BLEZC:
		case MIPS_INS_BGEZC:
		case MIPS_INS_BLTZC:
		case MIPS_INS_BGTZC:
			// compact vesions (no delay)
			op->delay = 0;
			op->fail = addr+4;
			break;
		default:
			op->delay = 1;
			op->fail = addr+8;
			break;
		}
		
		break;
	case MIPS_INS_JR:
	case MIPS_INS_JRC:
		op->type = R_ANAL_OP_TYPE_JMP;
		op->delay = 1;
        // register is $ra, so jmp is a return
        if (insn->detail->mips.operands[0].reg == MIPS_REG_RA) {
            op->type = R_ANAL_OP_TYPE_RET;
        }
		break;
	case MIPS_INS_SLTI:
	case MIPS_INS_SLTIU:
		SET_SRC_DST_3_IMM (op);
		SET_VAL (op,2);
		break;

	case MIPS_INS_SHRAV:
	case MIPS_INS_SHRAV_R:
	case MIPS_INS_SHRA:
	case MIPS_INS_SHRA_R:
	case MIPS_INS_SRA:
		op->type = R_ANAL_OP_TYPE_SAR;
		SET_SRC_DST_3_REG_OR_IMM (op);
		SET_VAL (op,2);
		break;
	case MIPS_INS_SHRL:
	case MIPS_INS_SRLV:
	case MIPS_INS_SRL:
		op->type = R_ANAL_OP_TYPE_SHR;
		SET_SRC_DST_3_REG_OR_IMM (op);
		SET_VAL (op,2);
		break;
	case MIPS_INS_SLLV:
	case MIPS_INS_SLL:
		op->type = R_ANAL_OP_TYPE_SHL;
		SET_SRC_DST_3_REG_OR_IMM (op);
		SET_VAL (op,2);
		break;
	}
	beach:
	if (anal->decode) {
		if (analop_esil (anal, op, addr, buf, len, &hndl, insn) != 0)
			r_strbuf_fini (&op->esil);
	}
	cs_free (insn, n);
	//cs_close (&handle);
	fin:
	return opsize;
}
Exemple #4
0
static int i8051_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	op->delay = 0;

	int i = 0;
	while (_8051_ops[i].string && _8051_ops[i].op != (buf[0] & ~_8051_ops[i].mask))	{
		i++;
	}

	op->size = _8051_ops[i].len;
	op->jump = op->fail = -1;
	op->ptr = op->val = -1;

	ut8 arg1 = _8051_ops[i].arg1;
	ut8 arg2 = _8051_ops[i].arg2;

	switch (arg1) {
	case A_DIRECT:
		op->ptr = buf[1];
		break;
	case A_BIT:
		op->ptr = arg_bit (buf[1]);
		break;
	case A_IMMEDIATE:
		op->val = buf[1];
		break;
	case A_IMM16:
		op->val = buf[1] * 256 + buf[2];
		break;
	default:
		break;
	}

	switch (arg2) {
	case A_DIRECT:
		op->ptr = (arg1 == A_RI || arg1 == A_RN) ? buf[1] : buf[2];
		break;
	case A_BIT:
		op->ptr = arg_bit ((arg1 == A_RI || arg1 == A_RN) ? buf[1] : buf[2]);
		break;
	case A_IMMEDIATE:
		op->val = (arg1 == A_RI || arg1 == A_RN) ? buf[1] : buf[2];
		break;
	default:
		break;
	}

	switch(_8051_ops[i].instr) {
	case OP_PUSH:
		op->type = R_ANAL_OP_TYPE_PUSH;
		op->ptr = 0;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = 1;
		break;
	case OP_POP:
		op->type = R_ANAL_OP_TYPE_POP;
		op->ptr = 0;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -1;
		break;
	case OP_RET:
		op->type = R_ANAL_OP_TYPE_RET;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -2;
		break;
	case OP_NOP:
		op->type = R_ANAL_OP_TYPE_NOP;
		break;
	case OP_INC:
	case OP_ADD:
	case OP_ADDC:
		op->type = R_ANAL_OP_TYPE_ADD;
		break;
	case OP_DEC:
	case OP_SUBB:
		op->type = R_ANAL_OP_TYPE_SUB;
		break;
	case OP_ANL:
		op->type = R_ANAL_OP_TYPE_AND;
		break;
	case OP_ORL:
		op->type = R_ANAL_OP_TYPE_OR;
		break;
	case OP_XRL:
		op->type = R_ANAL_OP_TYPE_XOR;
		break;
	case OP_CPL:
		op->type = R_ANAL_OP_TYPE_CPL;
		break;
	case OP_XCH:
		op->type = R_ANAL_OP_TYPE_XCHG;
		break;
	case OP_MOV:
		op->type = R_ANAL_OP_TYPE_MOV;
		break;
	case OP_MUL:
		op->type = R_ANAL_OP_TYPE_MUL;
		break;
	case OP_DIV:
		op->type = R_ANAL_OP_TYPE_DIV;
		break;
	case OP_CALL:
		op->type = R_ANAL_OP_TYPE_CALL;
		if (arg1 == A_ADDR11) {
			op->jump = arg_addr11 (addr + op->size, buf);
			op->fail = addr + op->size;
		} else if (arg1 == A_ADDR16) {
			op->jump = 0x100 * buf[1] + buf[2];
			op->fail = addr + op->size;
		}
		break;
	case OP_JMP:
		op->type = R_ANAL_OP_TYPE_JMP;
		if (arg1 == A_ADDR11) {
			op->jump = arg_addr11 (addr + op->size, buf);
			op->fail = addr + op->size;
		} else if (arg1 == A_ADDR16) {
			op->jump = 0x100 * buf[1] + buf[2];
			op->fail = addr + op->size;
		} else if (arg1 == A_OFFSET) {
			op->jump = arg_offset (addr + op->size, buf[1]);
			op->fail = addr + op->size;
		}
		break;
	case OP_CJNE:
	case OP_DJNZ:
	case OP_JC:
	case OP_JNC:
	case OP_JZ:
	case OP_JNZ:
	case OP_JB:
	case OP_JBC:
	case OP_JNB:
		op->type = R_ANAL_OP_TYPE_CJMP;
		if (op->size == 2) {
			op->jump = arg_offset (addr + 2, buf[1]);
			op->fail = addr + 2;
		} else if (op->size == 3) {
			op->jump = arg_offset (addr + 3, buf[2]);
			op->fail = addr + 3;
		}
		break;
	case OP_INVALID:
		op->type = R_ANAL_OP_TYPE_ILL;
		break;
	default:
		op->type = R_ANAL_OP_TYPE_UNK;
		break;
	}

	if (op->ptr != -1 && op->refptr == 0) {
		op->refptr = 1;
	}

	if (anal->decode) {
		ut8 copy[3] = {0, 0, 0};
		memcpy (copy, buf, len >= 3 ? 3 : len);
		analop_esil (anal, op, addr, copy);
	}

	return op->size;
}
Exemple #5
0
static int h8300_op(RAnal *anal, RAnalOp *op, ut64 addr,
		const ut8 *buf, int len, RAnalOpMask mask)
{
	int ret;
	ut8 opcode = buf[0];
	struct h8300_cmd cmd;

	if (!op) {
		return 2;
	}

	memset(op, 0, sizeof (RAnalOp));

	op->addr = addr;
	op->jump = op->fail = -1;
	op->ptr = op->val = -1;
	ret = op->size = h8300_decode_command(buf, &cmd);

	if (ret < 0) {
		return ret;
	}
	switch (opcode >> 4) {
	case H8300_MOV_4BIT_2:
	case H8300_MOV_4BIT_3:
	case H8300_MOV_4BIT:
		op->type = R_ANAL_OP_TYPE_MOV;
		break;
	case H8300_CMP_4BIT:
		op->type = R_ANAL_OP_TYPE_CMP;
		break;
	case H8300_XOR_4BIT:
		op->type = R_ANAL_OP_TYPE_XOR;
		break;
	case H8300_AND_4BIT:
		op->type = R_ANAL_OP_TYPE_AND;
		break;
	case H8300_ADD_4BIT:
	case H8300_ADDX_4BIT:
		op->type = R_ANAL_OP_TYPE_AND;
		break;
	case H8300_SUBX_4BIT:
		op->type = R_ANAL_OP_TYPE_SUB;
		break;
	default:
		op->type = R_ANAL_OP_TYPE_UNK;
		break;
	};

	if (op->type != R_ANAL_OP_TYPE_UNK) {
		analop_esil(anal, op, addr, buf);
		return ret;
	}
	switch (opcode) {
	case H8300_MOV_R82IND16:
	case H8300_MOV_IND162R16:
	case H8300_MOV_R82ABS16:
	case H8300_MOV_ABS162R16:
	case H8300_MOV_R82RDEC16:
	case H8300_MOV_INDINC162R16:
	case H8300_MOV_R82DISPR16:
	case H8300_MOV_DISP162R16:
	case H8300_MOV_IMM162R16:
	case H8300_MOV_1:
	case H8300_MOV_2:
	case H8300_EEPMOV:
		op->type = R_ANAL_OP_TYPE_MOV;
		break;
	case H8300_RTS:
		op->type = R_ANAL_OP_TYPE_RET;
		break;
	case H8300_CMP_1:
	case H8300_CMP_2:
	case H8300_BTST_R2R8:
	case H8300_BTST:
		op->type = R_ANAL_OP_TYPE_CMP;
		break;
	case H8300_SHL:
		op->type = R_ANAL_OP_TYPE_SHL;
		break;
	case H8300_SHR:
		op->type = R_ANAL_OP_TYPE_SHR;
		break;
	case H8300_XOR:
	case H8300_XORC:
		op->type = R_ANAL_OP_TYPE_XOR;
		break;
	case H8300_MULXU:
		op->type = R_ANAL_OP_TYPE_MUL;
		break;
	case H8300_ANDC:
		op->type = R_ANAL_OP_TYPE_AND;
		break;
	case H8300_ADDB_DIRECT:
	case H8300_ADDW_DIRECT:
	case H8300_ADDS:
	case H8300_ADDX:
		op->type = R_ANAL_OP_TYPE_ADD;
		break;
	case H8300_SUB_1:
	case H8300_SUBW:
	case H8300_SUBS:
	case H8300_SUBX:
		op->type = R_ANAL_OP_TYPE_SUB;
		break;
	case H8300_NOP:
		op->type = R_ANAL_OP_TYPE_NOP;
		break;
	case H8300_JSR_1:
	case H8300_JSR_2:
	case H8300_JSR_3:
		h8300_anal_jsr(op, addr, buf);
		break;
	case H8300_JMP_1:
	case H8300_JMP_2:
	case H8300_JMP_3:
		h8300_anal_jmp(op, addr, buf);
		break;
	case H8300_BRA:
	case H8300_BRN:
	case H8300_BHI:
	case H8300_BLS:
	case H8300_BCC:
	case H8300_BCS:
	case H8300_BNE:
	case H8300_BEQ:
	case H8300_BVC:
	case H8300_BVS:
	case H8300_BPL:
	case H8300_BMI:
	case H8300_BGE:
	case H8300_BLT:
	case H8300_BGT:
	case H8300_BLE:
		op->type = R_ANAL_OP_TYPE_CJMP;
		op->jump = addr + 2 + (st8)(buf[1]);
		op->fail = addr + 2;
		break;
	default:
		op->type = R_ANAL_OP_TYPE_UNK;
		break;
	};
	if (mask & R_ANAL_OP_MASK_ESIL) {
		analop_esil(anal, op, addr, buf);
	}
	return ret;
}
Exemple #6
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	csh handle;
	cs_insn *insn;
	int mode = (a->bits==16)? CS_MODE_THUMB: CS_MODE_ARM;
	int i, n, ret = (a->bits==64)?
	cs_open (CS_ARCH_ARM64, mode, &handle):
	cs_open (CS_ARCH_ARM, mode, &handle);
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
	op->type = R_ANAL_OP_TYPE_NULL;
	op->size = (a->bits==16)? 2: 4;
	op->delay = 0;
	r_strbuf_init (&op->esil);
	if (ret == CS_ERR_OK) {
		n = cs_disasm_ex (handle, (ut8*)buf, len, addr, 1, &insn);
		if (n<1) {
			op->type = R_ANAL_OP_TYPE_ILL;
		} else {
			op->size = insn->size;
			switch (insn->id) {
			case ARM_INS_POP:
			case ARM_INS_LDM:
				op->type = R_ANAL_OP_TYPE_POP;

				for (i = 0; i < insn->detail->arm.op_count; i++) {
					if (insn->detail->arm.operands[i].type == ARM_OP_REG &&
							insn->detail->arm.operands[i].reg == ARM_REG_PC) {
						if (insn->detail->arm.cc == ARM_CC_AL)
							op->type = R_ANAL_OP_TYPE_RET;
						else
							op->type = R_ANAL_OP_TYPE_CRET;
						break;
					}
				}
				break;
			case ARM_INS_SUB:
				op->type = R_ANAL_OP_TYPE_SUB;
				break;
			case ARM_INS_ADD:
				op->type = R_ANAL_OP_TYPE_ADD;
				break;
			case ARM_INS_MOV:
			case ARM_INS_MOVS:
			case ARM_INS_MOVT:
			case ARM_INS_MOVW:
			case ARM_INS_VMOVL:
			case ARM_INS_VMOVN:
			case ARM_INS_VQMOVUN:
			case ARM_INS_VQMOVN:
				op->type = R_ANAL_OP_TYPE_MOV;
				break;
			case ARM_INS_CMP:
			case ARM_INS_TST:
				op->type = R_ANAL_OP_TYPE_CMP;
				break;
			case ARM_INS_ROR:
			case ARM_INS_ORN:
			case ARM_INS_LSL:
			case ARM_INS_LSR:
				break;
			case ARM_INS_PUSH:
			case ARM_INS_STR:
				//case ARM_INS_POP:
			case ARM_INS_LDR:
				op->type = R_ANAL_OP_TYPE_LOAD;
				break;
			case ARM_INS_BL:
			case ARM_INS_BLX:
				op->type = R_ANAL_OP_TYPE_CALL;
				op->jump = IMM(0);
				break;
			case ARM_INS_B:
			case ARM_INS_BX:
			case ARM_INS_BXJ:
				if (insn->detail->arm.cc) {
					op->type = R_ANAL_OP_TYPE_CJMP;
					op->jump = IMM(0);
					op->fail = addr+op->size;
				} else {
					op->type = R_ANAL_OP_TYPE_JMP;
					op->jump = IMM(0);
				}
				break;
			}
			if (a->decode) {
				if (!analop_esil (a, op, addr, buf, len, &handle, insn))
					r_strbuf_fini (&op->esil);
			}
			cs_free (insn, n);
		}
	}
	cs_close (&handle);
	return op->size;
}
Exemple #7
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	int n, ret, opsize = -1;
	csh handle;
	cs_insn* insn;
	int mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN;

	mode |= (a->bits==64)? CS_MODE_64: CS_MODE_32;
// XXX no arch->cpu ?!?! CS_MODE_MICRO, N64
	ret = cs_open (CS_ARCH_MIPS, mode, &handle);
	op->delay = 0;
	op->type = R_ANAL_OP_TYPE_ILL;
	op->size = 4;
	if (ret != CS_ERR_OK) goto fin;
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
	n = cs_disasm (handle, (ut8*)buf, len, addr, 1, &insn);
	if (n<1 || insn->size<1)
		goto beach;
	op->type = R_ANAL_OP_TYPE_NULL;
	op->delay = 0;
	opsize = op->size = insn->size;
	switch (insn->id) {
	case MIPS_INS_INVALID:
		op->type = R_ANAL_OP_TYPE_ILL;
		break;
	case MIPS_INS_LB:
	case MIPS_INS_LBU:
	case MIPS_INS_LBUX:
	case MIPS_INS_LW:
	case MIPS_INS_LWC1:
	case MIPS_INS_LWC2:
	case MIPS_INS_LWL:
	case MIPS_INS_LWR:
	case MIPS_INS_LWXC1:
	case MIPS_INS_LD:
	case MIPS_INS_LDC1:
	case MIPS_INS_LDC2:
	case MIPS_INS_LDL:
	case MIPS_INS_LDR:
	case MIPS_INS_LDXC1:
		op->type = R_ANAL_OP_TYPE_LOAD;
		op->refptr = 4;
		switch (OPERAND(1).type) {
		case MIPS_OP_MEM:
			if (OPERAND(1).mem.base == MIPS_REG_GP) {
				op->ptr = a->gp + OPERAND(1).mem.disp;
				op->refptr = 4;
			}
			break;
		case MIPS_OP_IMM:
			op->ptr = OPERAND(1).imm;
			break;
		case MIPS_OP_REG:
			// wtf?
			break;
		default:
			break;
		}
		// TODO: fill
		break;
	case MIPS_INS_SW:
	case MIPS_INS_SWC1:
	case MIPS_INS_SWC2:
	case MIPS_INS_SWL:
	case MIPS_INS_SWR:
	case MIPS_INS_SWXC1:
		op->type = R_ANAL_OP_TYPE_STORE;
		break;
	case MIPS_INS_NOP:
		op->type = R_ANAL_OP_TYPE_NOP;
		break;
	case MIPS_INS_SYSCALL:
	case MIPS_INS_BREAK:
		op->type = R_ANAL_OP_TYPE_TRAP;
		break;
	case MIPS_INS_JALR:
		op->type = R_ANAL_OP_TYPE_UCALL;
		op->delay = 1;
		break;
	case MIPS_INS_JAL:
	case MIPS_INS_JALS:
	case MIPS_INS_JALX:
	case MIPS_INS_JIALC:
	case MIPS_INS_JIC:
	case MIPS_INS_JRADDIUSP:
	case MIPS_INS_BAL:
	case MIPS_INS_BGEZAL: // Branch on less than zero and link
		op->type = R_ANAL_OP_TYPE_CALL;
		op->delay = 1;
		op->jump = IMM(0);
		op->fail = addr+4;
		break;
	case MIPS_INS_MOVE:
		op->type = R_ANAL_OP_TYPE_MOV;
		break;
	case MIPS_INS_ADD:
	case MIPS_INS_ADDI:
	case MIPS_INS_ADDIU:
	case MIPS_INS_DADD:
	case MIPS_INS_DADDI:
	case MIPS_INS_DADDIU:
		op->type = R_ANAL_OP_TYPE_ADD;
		break;
	case MIPS_INS_SUB:
	case MIPS_INS_SUBV:
	case MIPS_INS_SUBVI:
	case MIPS_INS_DSUBU:
	case MIPS_INS_FSUB:
	case MIPS_INS_FMSUB:
	case MIPS_INS_SUBU:
	case MIPS_INS_DSUB:
	case MIPS_INS_SUBS_S:
	case MIPS_INS_SUBS_U:
	case MIPS_INS_SUBUH:
	case MIPS_INS_SUBUH_R:
		op->type = R_ANAL_OP_TYPE_SUB;
		break;
	case MIPS_INS_MULV:
	case MIPS_INS_MULT:
	case MIPS_INS_MULSA:
	case MIPS_INS_FMUL:
	case MIPS_INS_MUL:
	case MIPS_INS_DMULT:
	case MIPS_INS_DMULTU:
		op->type = R_ANAL_OP_TYPE_MUL;
		break;
	case MIPS_INS_XOR:
	case MIPS_INS_XORI:
		op->type = R_ANAL_OP_TYPE_XOR;
		break;
	case MIPS_INS_AND:
	case MIPS_INS_ANDI:
		op->type = R_ANAL_OP_TYPE_AND;
		break;
	case MIPS_INS_NOT:
		op->type = R_ANAL_OP_TYPE_NOT;
		break;
	case MIPS_INS_OR:
	case MIPS_INS_ORI:
		op->type = R_ANAL_OP_TYPE_OR;
		break;
	case MIPS_INS_DIV:
	case MIPS_INS_DIVU:
	case MIPS_INS_DDIV:
	case MIPS_INS_DDIVU:
	case MIPS_INS_FDIV:
	case MIPS_INS_DIV_S:
	case MIPS_INS_DIV_U:
		op->type = R_ANAL_OP_TYPE_DIV;
		break;
	case MIPS_INS_CMPGDU:
	case MIPS_INS_CMPGU:
	case MIPS_INS_CMPU:
	case MIPS_INS_CMPI:
		op->type = R_ANAL_OP_TYPE_CMP;
		break;
	case MIPS_INS_J:
	case MIPS_INS_B:
	case MIPS_INS_BZ:
	case MIPS_INS_BEQ:
	case MIPS_INS_BNZ:
	case MIPS_INS_BNE:
	case MIPS_INS_BEQZ:
	case MIPS_INS_BNEG:
	case MIPS_INS_BNEGI:
	case MIPS_INS_BNEZ:
	case MIPS_INS_BTEQZ:
	case MIPS_INS_BTNEZ:
	case MIPS_INS_BLTZ:
	case MIPS_INS_BGEZ:
	case MIPS_INS_BGEZC:
	case MIPS_INS_BGEZALC:
		op->type = R_ANAL_OP_TYPE_JMP;
		op->delay = 1;
		if (OPERAND(0).type == MIPS_OP_IMM) {
			op->jump = IMM(0);
		} else if (OPERAND(1).type == MIPS_OP_IMM) {
			op->jump = IMM(1);
		} else if (OPERAND(2).type == MIPS_OP_IMM) {
			op->jump = IMM(2);
		}
		break;
	case MIPS_INS_JR:
	case MIPS_INS_JRC:
		op->type = R_ANAL_OP_TYPE_JMP;
		op->delay = 1;
        // register 32 is $ra, so jmp is a return
        if (insn->detail->mips.operands[0].reg == 32) {
            op->type = R_ANAL_OP_TYPE_RET;
        }
		break;
	}
	beach:
	if (a->decode) {
		if (!analop_esil (a, op, addr, buf, len, &handle, insn))
			r_strbuf_fini (&op->esil);
	}
	cs_free (insn, n);
	cs_close (&handle);
	fin:
	return opsize;
}