break;
case PROTECTED:
case PROTECTED_PAE:
- case LONG_32_COMPAT:
if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
xed_state_init(state,
XED_MACHINE_MODE_LEGACY_32,
XED_ADDRESS_WIDTH_32b);
}
break;
+ case LONG_32_COMPAT:
+ if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
+ xed_state_init(state,
+ XED_MACHINE_MODE_LONG_COMPAT_32,
+ XED_ADDRESS_WIDTH_32b,
+ XED_ADDRESS_WIDTH_32b);
+ }
+ break;
case LONG:
- if (state->mmode != XED_MACHINE_MODE_LONG_64) {
- state->mmode = XED_MACHINE_MODE_LONG_64;
+ if (state->mmode != XED_MACHINE_MODE_LONG_64) {
+ PrintDebug("Setting decoder to long mode\n");
+ // state->mmode = XED_MACHINE_MODE_LONG_64;
+ //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
+ xed_state_init(state,
+ XED_MACHINE_MODE_LONG_64,
+ XED_ADDRESS_WIDTH_64b,
+ XED_ADDRESS_WIDTH_64b);
}
break;
default:
xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
xed_state_zero(decoder_state);
+ xed_state_init(decoder_state,
+ XED_MACHINE_MODE_LEGACY_32,
+ XED_ADDRESS_WIDTH_32b,
+ XED_ADDRESS_WIDTH_32b);
info->decoder_state = decoder_state;
instr->str_op_length = 1;
}
+ } else if (instr->op_type == V3_OP_STOS) {
+ instr->num_operands = 2;
+
+ if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
+ PrintError("Could not get Destination memory operand\n");
+ return -1;
+ }
+
+ // STOS reads from rax
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0),
+ &(instr->src_operand.operand),
+ &(instr->src_operand.size));
+ instr->src_operand.type = REG_OPERAND;
+
+ if (instr->prefixes.rep == 1) {
+ addr_t reg_addr = 0;
+ uint_t reg_length = 0;
+
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), ®_addr, ®_length);
+ instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
+ } else {
+ instr->str_op_length = 1;
+ }
+
+ } else {
+ PrintError("Unhandled String OP\n");
+ return -1;
}
return 0;
ullong_t displacement;
// struct v3_segment * seg_reg;
-
-
+ PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
+ PrintDebug("Address width: %s\n",
+ xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
+ PrintDebug("Stack Address width: %s\n",
+ xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
- PrintDebug("Struct: Seg=%p, base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n",
- (void *)mem_op.segment, (void*)mem_op.base, (void *)mem_op.index,
+ PrintDebug("Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n",
+ (void *)mem_op.segment, mem_op.segment_size, (void*)mem_op.base, (void *)mem_op.index,
(void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
base = MASK(mem_op.base, mem_op.base_size);
index = MASK(mem_op.index, mem_op.index_size);
scale = mem_op.scale;
- displacement = MASK(mem_op.displacement, mem_op.displacement_size);
+
+ // This is a horrendous hack...
+ // XED really screwed the pooch in calculating the displacement
+ if (v3_get_cpu_mode(info) == LONG) {
+ displacement = mem_op.displacement;
+ } else {
+ displacement = MASK(mem_op.displacement, mem_op.displacement_size);
+ }
PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n",
(void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len) {
- PrintError("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
+ PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
switch (xed_reg) {
case XED_REG_INVALID:
*/
case XED_REG_CS:
*v3_reg = (addr_t)&(info->segments.cs);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_DS:
*v3_reg = (addr_t)&(info->segments.ds);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_ES:
*v3_reg = (addr_t)&(info->segments.es);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_SS:
*v3_reg = (addr_t)&(info->segments.ss);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_FS:
*v3_reg = (addr_t)&(info->segments.fs);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_GS:
*v3_reg = (addr_t)&(info->segments.gs);
+ *reg_len = 8;
return SEGMENT_REGISTER;
/* Data Instructions */
+ // Write
case XED_IFORM_ADC_MEMv_GPRv:
case XED_IFORM_ADC_MEMv_IMM:
case XED_IFORM_ADC_MEMb_GPR8:
case XED_IFORM_ADC_MEMb_IMM:
+ // Read
+ case XED_IFORM_ADC_GPRv_MEMv:
+ case XED_IFORM_ADC_GPR8_MEMb:
return V3_OP_ADC;
+ // Write
case XED_IFORM_ADD_MEMv_GPRv:
case XED_IFORM_ADD_MEMb_IMM:
case XED_IFORM_ADD_MEMb_GPR8:
case XED_IFORM_ADD_MEMv_IMM:
+ // Read
+ case XED_IFORM_ADD_GPRv_MEMv:
+ case XED_IFORM_ADD_GPR8_MEMb:
return V3_OP_ADD;
+ // Write
case XED_IFORM_AND_MEMv_IMM:
case XED_IFORM_AND_MEMb_GPR8:
case XED_IFORM_AND_MEMv_GPRv:
case XED_IFORM_AND_MEMb_IMM:
+ // Read
+ case XED_IFORM_AND_GPR8_MEMb:
+ case XED_IFORM_AND_GPRv_MEMv:
return V3_OP_AND;
+ // Write
case XED_IFORM_SUB_MEMv_IMM:
case XED_IFORM_SUB_MEMb_GPR8:
case XED_IFORM_SUB_MEMb_IMM:
case XED_IFORM_SUB_MEMv_GPRv:
+ // Read
+ case XED_IFORM_SUB_GPR8_MEMb:
+ case XED_IFORM_SUB_GPRv_MEMv:
return V3_OP_SUB;
+ // Write
case XED_IFORM_MOV_MEMv_GPRv:
case XED_IFORM_MOV_MEMb_GPR8:
case XED_IFORM_MOV_MEMb_AL:
case XED_IFORM_MOV_MEMv_IMM:
case XED_IFORM_MOV_MEMb_IMM:
+ // Read
+ case XED_IFORM_MOV_GPRv_MEMv:
+ case XED_IFORM_MOV_GPR8_MEMb:
+ case XED_IFORM_MOV_AL_MEMb:
return V3_OP_MOV;
+
+ // Read
+ case XED_IFORM_MOVZX_GPRv_MEMb:
+ case XED_IFORM_MOVZX_GPRv_MEMw:
+ return V3_OP_MOVZX;
+
+ // Read
+ case XED_IFORM_MOVSX_GPRv_MEMb:
+ case XED_IFORM_MOVSX_GPRv_MEMw:
+ return V3_OP_MOVSX;
+
+
+
case XED_IFORM_DEC_MEMv:
case XED_IFORM_DEC_MEMb:
return V3_OP_DEC;
case XED_IFORM_INC_MEMv:
return V3_OP_INC;
+ // Write
case XED_IFORM_OR_MEMv_IMM:
case XED_IFORM_OR_MEMb_IMM:
case XED_IFORM_OR_MEMv_GPRv:
case XED_IFORM_OR_MEMb_GPR8:
+ // Read
+ case XED_IFORM_OR_GPRv_MEMv:
+ case XED_IFORM_OR_GPR8_MEMb:
return V3_OP_OR;
+ // Write
case XED_IFORM_XOR_MEMv_GPRv:
case XED_IFORM_XOR_MEMb_IMM:
case XED_IFORM_XOR_MEMb_GPR8:
case XED_IFORM_XOR_MEMv_IMM:
+ // Read
+ case XED_IFORM_XOR_GPRv_MEMv:
+ case XED_IFORM_XOR_GPR8_MEMb:
return V3_OP_XOR;
case XED_IFORM_NEG_MEMb:
case XED_IFORM_SETZ_MEMb:
return V3_OP_SETZ;
-
case XED_IFORM_MOVSB:
case XED_IFORM_MOVSW:
case XED_IFORM_MOVSD:
case XED_IFORM_MOVSQ:
return V3_OP_MOVS;
+ case XED_IFORM_STOSB:
+ case XED_IFORM_STOSW:
+ case XED_IFORM_STOSD:
+ case XED_IFORM_STOSQ:
+ return V3_OP_STOS;
+
+
default:
return V3_INVALID_OP;
}