Exemple #1
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 #2
0
int _8051_disas (ut64 pc, RAsmOp *op, const ut8 *buf, ut64 len) {
	int i = 0;
	while (_8051_ops[i].string && _8051_ops[i].op != (buf[0] & ~_8051_ops[i].mask)) {
		i++;
	}

	if (_8051_ops[i].string) {
		// valid opcodes
		const char* name = _8051_ops[i].string;
		ut8 mask = _8051_ops[i].mask;
		ut8 arg1 = _8051_ops[i].arg1;
		ut8 arg2 = _8051_ops[i].arg2;
		ut8 arg3 = _8051_ops[i].arg3;
		ut8 oplen = _8051_ops[i].len;
		switch (oplen) {
		case 1:
			if ((arg1 == A_RI) || (arg1 == A_RN)) {
				// op @Ri; op Rn
				sprintf (op->buf_asm, name, buf[0] & mask);
			} else {
				sprintf (op->buf_asm, "%s", name);
			}
			break;
		case 2:
			if (len>1) {
				if (arg1 == A_OFFSET) {
					sprintf (op->buf_asm, name, arg_offset (pc + 2, buf[1]));
				} else if (arg1 == A_ADDR11) {
					sprintf (op->buf_asm, name, arg_addr11 (pc + 2, buf));
				} else if ((arg1 == A_RI) || (arg1 == A_RN)) {
					// op @Ri, arg; op Rn, arg
					if (arg2 == A_OFFSET) {
						sprintf (op->buf_asm, name, buf[0] & mask, arg_offset (pc + 2, buf[1]));
					} else {
						sprintf (op->buf_asm, name, buf[0] & mask, buf[1]);
					}
				} else if ((arg2 == A_RI) || (arg2 == A_RN)) {
					// op arg, @Ri; op arg, Rn
					sprintf (op->buf_asm, name, buf[1], buf[0] & mask);
				} else if (arg1 == A_BIT) {
					// bit addressing mode
					sprintf (op->buf_asm, name, arg_bit (buf[1]), buf[1] & 0x07);
				} else {
					// direct, immediate, bit
					sprintf (op->buf_asm, name, buf[1]);
				}
			} else {
				strcpy (op->buf_asm, "truncated");
				return -1;
			}
			break;
		case 3:
			if (len>2) {
				if ((arg1 == A_ADDR16) || (arg1 == A_IMM16)) {
					sprintf (op->buf_asm, name, 0x100 * buf[1] + buf[2]);
				} else if (arg1 == A_IMM16) {
					sprintf (op->buf_asm, name, 0x100 * buf[1] + buf[2]);
				} else if (arg2 == A_OFFSET) {
					if (mask != A_NONE) {
						// @Ri, immediate, offset; Rn, immediate, offset
						sprintf (op->buf_asm, name, buf[0] & mask, buf[1], arg_offset (pc + 3, buf[1]));
					} else if (arg1 == A_BIT) {
						// bit, offset
						sprintf (op->buf_asm, name, arg_bit (buf[1]), buf[1] & 0x07, arg_offset (pc + 3, buf[2]));
					} else {
						// direct, offset; a, immediate, offset
						sprintf (op->buf_asm, name, buf[1], arg_offset (pc + 3, buf[2]));
					}
				} else if (arg3 == A_OFFSET) {
					// @Ri/Rn, direct, offset
					sprintf (op->buf_asm, name, buf[0] & mask, buf[1], arg_offset (pc + 3, buf[2]));
				} else if (arg1 == A_DIRECT && arg2 == A_DIRECT) {
					// op direct, direct has src and dest swapped
					sprintf (op->buf_asm, name, buf[2], buf[1]);
				} else {
					// direct, immediate
					sprintf (op->buf_asm, name, buf[1], buf[2]);
				}
			} else {
				strcpy (op->buf_asm, "truncated");
				return -1;
			}
			break;
		default:
			// if we get here something is wrong
			return 0;
		}
		return oplen;
	}

	// invalid op-code
	return 0;
}