📄 platform.c
字号:
return mem_reg(*op_size, opcode, mmio_op, rex); case 0x20: /* and r8, m8 */ mmio_op->instr = INSTR_AND; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return reg_mem(size_reg, opcode, mmio_op, rex); case 0x21: /* and r32/16, m32/16 */ mmio_op->instr = INSTR_AND; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return reg_mem(*op_size, opcode, mmio_op, rex); case 0x22: /* and m8, r8 */ mmio_op->instr = INSTR_AND; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return mem_reg(size_reg, opcode, mmio_op, rex); case 0x23: /* and m32/16, r32/16 */ mmio_op->instr = INSTR_AND; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return mem_reg(*op_size, opcode, mmio_op, rex); case 0x2B: /* sub m32/16, r32/16 */ mmio_op->instr = INSTR_SUB; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return mem_reg(*op_size, opcode, mmio_op, rex); case 0x30: /* xor r8, m8 */ mmio_op->instr = INSTR_XOR; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return reg_mem(size_reg, opcode, mmio_op, rex); case 0x31: /* xor r32/16, m32/16 */ mmio_op->instr = INSTR_XOR; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return reg_mem(*op_size, opcode, mmio_op, rex); case 0x32: /* xor m8, r8 */ mmio_op->instr = INSTR_XOR; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return mem_reg(size_reg, opcode, mmio_op, rex); case 0x38: /* cmp r8, m8 */ mmio_op->instr = INSTR_CMP; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return reg_mem(size_reg, opcode, mmio_op, rex); case 0x39: /* cmp r32/16, m32/16 */ mmio_op->instr = INSTR_CMP; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return reg_mem(*op_size, opcode, mmio_op, rex); case 0x3A: /* cmp m8, r8 */ mmio_op->instr = INSTR_CMP; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return mem_reg(size_reg, opcode, mmio_op, rex); case 0x3B: /* cmp m32/16, r32/16 */ mmio_op->instr = INSTR_CMP; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return mem_reg(*op_size, opcode, mmio_op, rex); case 0x80: case 0x81: case 0x83: { unsigned char ins_subtype = (opcode[1] >> 3) & 7; if ( opcode[0] == 0x80 ) { *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); } else { GET_OP_SIZE_FOR_NONEBYTE(*op_size); size_reg = *op_size; } /* opcode 0x83 always has a single byte operand */ if ( opcode[0] == 0x83 ) mmio_op->immediate = get_immediate_sign_ext(*ad_size, opcode + 1, BYTE); else mmio_op->immediate = get_immediate_sign_ext(*ad_size, opcode + 1, *op_size); mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE); mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY); switch ( ins_subtype ) { case 0: /* add $imm, m32/16 */ mmio_op->instr = INSTR_ADD; return DECODE_success; case 1: /* or $imm, m32/16 */ mmio_op->instr = INSTR_OR; return DECODE_success; case 4: /* and $imm, m32/16 */ mmio_op->instr = INSTR_AND; return DECODE_success; case 5: /* sub $imm, m32/16 */ mmio_op->instr = INSTR_SUB; return DECODE_success; case 6: /* xor $imm, m32/16 */ mmio_op->instr = INSTR_XOR; return DECODE_success; case 7: /* cmp $imm, m32/16 */ mmio_op->instr = INSTR_CMP; return DECODE_success; default: printk("%x/%x, This opcode isn't handled yet!\n", *opcode, ins_subtype); return DECODE_failure; } } case 0x84: /* test r8, m8 */ mmio_op->instr = INSTR_TEST; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return reg_mem(size_reg, opcode, mmio_op, rex); case 0x85: /* test r16/32, m16/32 */ mmio_op->instr = INSTR_TEST; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return reg_mem(*op_size, opcode, mmio_op, rex); case 0x86: /* xchg m8, r8 */ mmio_op->instr = INSTR_XCHG; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return reg_mem(size_reg, opcode, mmio_op, rex); case 0x87: /* xchg m16/32, r16/32 */ mmio_op->instr = INSTR_XCHG; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return reg_mem(*op_size, opcode, mmio_op, rex); case 0x88: /* mov r8, m8 */ mmio_op->instr = INSTR_MOV; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return reg_mem(size_reg, opcode, mmio_op, rex); case 0x89: /* mov r32/16, m32/16 */ mmio_op->instr = INSTR_MOV; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return reg_mem(*op_size, opcode, mmio_op, rex); case 0x8A: /* mov m8, r8 */ mmio_op->instr = INSTR_MOV; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return mem_reg(size_reg, opcode, mmio_op, rex); case 0x8B: /* mov m32/16, r32/16 */ mmio_op->instr = INSTR_MOV; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return mem_reg(*op_size, opcode, mmio_op, rex); case 0xA0: /* mov <addr>, al */ mmio_op->instr = INSTR_MOV; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return mem_acc(size_reg, mmio_op); case 0xA1: /* mov <addr>, ax/eax */ mmio_op->instr = INSTR_MOV; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return mem_acc(*op_size, mmio_op); case 0xA2: /* mov al, <addr> */ mmio_op->instr = INSTR_MOV; *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); return acc_mem(size_reg, mmio_op); case 0xA3: /* mov ax/eax, <addr> */ mmio_op->instr = INSTR_MOV; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return acc_mem(*op_size, mmio_op); case 0xA4: /* movsb */ mmio_op->instr = INSTR_MOVS; *op_size = BYTE; return DECODE_success; case 0xA5: /* movsw/movsl */ mmio_op->instr = INSTR_MOVS; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return DECODE_success; case 0xAA: /* stosb */ mmio_op->instr = INSTR_STOS; *op_size = BYTE; return DECODE_success; case 0xAB: /* stosw/stosl */ mmio_op->instr = INSTR_STOS; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return DECODE_success; case 0xAC: /* lodsb */ mmio_op->instr = INSTR_LODS; *op_size = BYTE; return DECODE_success; case 0xAD: /* lodsw/lodsl */ mmio_op->instr = INSTR_LODS; GET_OP_SIZE_FOR_NONEBYTE(*op_size); return DECODE_success; case 0xC6: if ( ((opcode[1] >> 3) & 7) == 0 ) { /* mov $imm8, m8 */ mmio_op->instr = INSTR_MOV; *op_size = BYTE; mmio_op->operand[0] = mk_operand(*op_size, 0, 0, IMMEDIATE); mmio_op->immediate = get_immediate(*ad_size, opcode + 1, *op_size); mmio_op->operand[1] = mk_operand(*op_size, 0, 0, MEMORY); return DECODE_success; } else return DECODE_failure; case 0xC7: if ( ((opcode[1] >> 3) & 7) == 0 ) { /* mov $imm16/32, m16/32 */ mmio_op->instr = INSTR_MOV; GET_OP_SIZE_FOR_NONEBYTE(*op_size); mmio_op->operand[0] = mk_operand(*op_size, 0, 0, IMMEDIATE); mmio_op->immediate = get_immediate_sign_ext(*ad_size, opcode + 1, *op_size); mmio_op->operand[1] = mk_operand(*op_size, 0, 0, MEMORY); return DECODE_success; } else return DECODE_failure; case 0xF6: case 0xF7: if ( ((opcode[1] >> 3) & 7) == 0 ) { /* test $imm8/16/32, m8/16/32 */ mmio_op->instr = INSTR_TEST; if ( opcode[0] == 0xF6 ) { *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); } else { GET_OP_SIZE_FOR_NONEBYTE(*op_size); size_reg = *op_size; } mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE); mmio_op->immediate = get_immediate_sign_ext(*ad_size, opcode + 1, *op_size); mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY); return DECODE_success; } else return DECODE_failure; case 0xFE: case 0xFF: { unsigned char ins_subtype = (opcode[1] >> 3) & 7; if ( opcode[0] == 0xFE ) { *op_size = BYTE; GET_OP_SIZE_FOR_BYTE(size_reg); } else { GET_OP_SIZE_FOR_NONEBYTE(*op_size); size_reg = *op_size; } mmio_op->immediate = 1; mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE); mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY); switch ( ins_subtype ) { case 0: /* inc */ mmio_op->instr = INSTR_ADD; return DECODE_success; case 1: /* dec */ mmio_op->instr = INSTR_SUB; return DECODE_success; case 6: /* push */ mmio_op->instr = INSTR_PUSH; mmio_op->operand[0] = mmio_op->operand[1]; return DECODE_success; default: printk("%x/%x, This opcode isn't handled yet!\n", *opcode, ins_subtype); return DECODE_failure; } } case 0x0F: break; default: printk("%x, This opcode isn't handled yet!\n", *opcode); return DECODE_failure; } switch ( *++opcode ) { case 0xB6: /* movzx m8, r16/r32/r64 */ mmio_op->instr = INSTR_MOVZX; GET_OP_SIZE_FOR_NONEBYTE(*op_size); index = get_index(opcode + 1, rex); mmio_op->operand[0] = mk_operand(BYTE, 0, 0, MEMORY); mmio_op->operand[1] = mk_operand(*op_size, index, 0, REGISTER); return DECODE_success; case 0xB7: /* movzx m16, r32/r64 */ mmio_op->instr = INSTR_MOVZX; GET_OP_SIZE_FOR_NONEBYTE(*op_size); index = get_index(opcode + 1, rex); mmio_op->operand[0] = mk_operand(WORD, 0, 0, MEMORY); mmio_op->operand[1] = mk_operand(*op_size, index, 0, REGISTER); return DECODE_success; case 0xBE: /* movsx m8, r16/r32/r64 */ mmio_op->instr = INSTR_MOVSX; GET_OP_SIZE_FOR_NONEBYTE(*op_size); index = get_index(opcode + 1, rex); mmio_op->operand[0] = mk_operand(BYTE, 0, 0, MEMORY); mmio_op->operand[1] = mk_operand(*op_size, index, 0, REGISTER); return DECODE_success; case 0xBF: /* movsx m16, r32/r64 */ mmio_op->instr = INSTR_MOVSX; GET_OP_SIZE_FOR_NONEBYTE(*op_size); index = get_index(opcode + 1, rex); mmio_op->operand[0] = mk_operand(WORD, 0, 0, MEMORY); mmio_op->operand[1] = mk_operand(*op_size, index, 0, REGISTER); return DECODE_success; case 0xA3: /* bt r32, m32 */ mmio_op->instr = INSTR_BT; index = get_index(opcode + 1, rex); *op_size = LONG; mmio_op->operand[0] = mk_operand(*op_size, index, 0, REGISTER); mmio_op->operand[1] = mk_operand(*op_size, 0, 0, MEMORY); return DECODE_success; case 0xBA: if ( ((opcode[1] >> 3) & 7) == 4 ) /* BT $imm8, m16/32/64 */ { mmio_op->instr = INSTR_BT; GET_OP_SIZE_FOR_NONEBYTE(*op_size); mmio_op->operand[0] = mk_operand(BYTE, 0, 0, IMMEDIATE); mmio_op->immediate = (signed char)get_immediate(*ad_size, opcode + 1, BYTE); mmio_op->operand[1] = mk_operand(*op_size, 0, 0, MEMORY); return DECODE_success; } else { printk("0f %x, This opcode subtype isn't handled yet\n", *opcode); return DECODE_failure; } default: printk("0f %x, This opcode isn't handled yet\n", *opcode); return DECODE_failure; }}int inst_copy_from_guest( unsigned char *buf, unsigned long guest_eip, int inst_len){ if ( inst_len > MAX_INST_LEN || inst_len <= 0 ) return 0; if ( hvm_fetch_from_guest_virt_nofault(buf, guest_eip, inst_len) ) return 0; return inst_len;}void send_pio_req(unsigned long port, unsigned long count, int size, paddr_t value, int dir, int df, int value_is_ptr){ struct vcpu *v = current; vcpu_iodata_t *vio; ioreq_t *p; if ( size == 0 || count == 0 ) { printk("null pio request? port %lx, count %lx, " "size %d, value %"PRIpaddr", dir %d, value_is_ptr %d.\n", port, count, size, value, dir, value_is_ptr); } vio = get_ioreq(v); if ( vio == NULL ) { printk("bad shared page: %lx\n", (unsigned long) vio); domain_crash_synchronous(); } p = &vio->vp_ioreq; if ( p->state != STATE_IOREQ_NONE ) printk("WARNING: send pio with something already pending (%d)?\n", p->state); p->dir = dir; p->data_is_ptr = value_is_ptr; p->type = IOREQ_TYPE_PIO; p->size = size; p->addr = port; p->count = count; p->df = df; p->io_count++; p->data = value; if ( hvm_portio_intercept(p) ) { p->state = STATE_IORESP_READY; hvm_io_assist(); return; } hvm_send_assist_req(v);}void send_mmio_req(unsigned char type, paddr_t gpa, unsigned long count, int size, paddr_t value, int dir, int df, int value_is_ptr){ struct vcpu *v = current; vcpu_iodata_t *vio; ioreq_t *p; if ( size == 0 || count == 0 ) { printk("null mmio request? type %d, gpa %"PRIpaddr", " "count %lx, size %d, value %"PRIpaddr", dir %d, " "value_is_ptr %d.\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -