} op_form_t;
-static int get_addr_width(struct guest_info * info, struct x86_instr * instr,
- op_form_t form) {
+static int get_addr_width(struct guest_info * info, struct x86_instr * instr) {
switch (v3_get_vm_cpu_mode(info)) {
case REAL:
return (instr->prefixes.addr_size) ? 4 : 2;
+ case LONG:
+ return 8;
case PROTECTED:
case PROTECTED_PAE:
- return (instr->prefixes.addr_size) ? 2 : 4;
case LONG_32_COMPAT:
- case LONG:
+ if (info->segments.cs.db) {
+ return (instr->prefixes.addr_size) ? 2 : 4;
+ } else {
+ return (instr->prefixes.addr_size) ? 4 : 2;
+ }
default:
PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
return -1;
switch (v3_get_vm_cpu_mode(info)) {
case REAL:
return (instr->prefixes.op_size) ? 4 : 2;
+ case LONG:
+ if (instr->prefixes.rex.op_size) {
+ return 8;
+ }
case PROTECTED:
case PROTECTED_PAE:
- return (instr->prefixes.op_size) ? 2 : 4;
case LONG_32_COMPAT:
- case LONG:
+ if (info->segments.cs.db) {
+ // default is 32
+ return (instr->prefixes.op_size) ? 2 : 4;
+ } else {
+ return (instr->prefixes.op_size) ? 4 : 2;
+ }
default:
PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
return -1;
}
-
+
case INVLPG:
switch (v3_get_vm_cpu_mode(info)) {
case REAL:
return 0;
case PROTECTED:
case PROTECTED_PAE:
- return 4;
case LONG_32_COMPAT:
+ return 4;
case LONG:
+ return 8;
default:
PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
return -1;
return 2;
case PROTECTED:
case PROTECTED_PAE:
- return 4;
case LONG_32_COMPAT:
+ return 4;
case LONG:
+ return 8;
default:
PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
return -1;
case REAL:
case PROTECTED:
case PROTECTED_PAE:
- return 4;
case LONG_32_COMPAT:
+
+ return 4;
case LONG:
+ return 8;
default:
PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
return -1;
val; \
})
+
+#define ADDR_MASK(val, length) ({ \
+ ullong_t mask = 0x0LL; \
+ switch (length) { \
+ case 2: \
+ mask = 0x00000000000fffffLL; \
+ break; \
+ case 4: \
+ mask = 0x00000000ffffffffLL; \
+ break; \
+ case 8: \
+ mask = 0xffffffffffffffffLL; \
+ break; \
+ } \
+ val & mask; \
+ })
+
+
+
static int decode_rm_operand16(struct guest_info * core,
uint8_t * modrm_instr,
struct x86_instr * instr,
seg = &(core->segments.ds);
}
- operand->operand = get_addr_linear(core, base_addr, seg);
+ operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg),
+ get_addr_width(core, instr));
}
seg = &(core->segments.ds);
}
- operand->operand = get_addr_linear(core, base_addr, seg);
+ operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg),
+ get_addr_width(core, instr));
}
}
-
+int decode_rm_operand64(struct guest_info * core, uint8_t * instr_ptr,
+ struct x86_instr * instr, struct x86_operand * operand,
+ uint8_t * reg_code) {
+
+
+
+ return 0;
+}
static int decode_rm_operand(struct guest_info * core,
uint8_t * instr_ptr, // input
+ op_form_t form,
struct x86_instr * instr,
struct x86_operand * operand,
uint8_t * reg_code) {
v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
- if (mode == REAL) {
- return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
- } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE)) {
- return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
- } else {
- PrintError("Invalid CPU_MODE (%d)\n", mode);
- return -1;
+ operand->size = get_operand_width(core, instr, form);
+
+ switch (mode) {
+ case REAL:
+ return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
+ case LONG:
+ if (instr->prefixes.rex.op_size) {
+ return decode_rm_operand64(core, instr_ptr, instr, operand, reg_code);
+ }
+ case PROTECTED:
+ case PROTECTED_PAE:
+ case LONG_32_COMPAT:
+ return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
+ default:
+ PrintError("Invalid CPU_MODE (%d)\n", mode);
+ return -1;
}
}