1 #include "vmm_decoder.h"
3 #include <xed/xed-interface.h>
7 static xed_state_t decoder_state;
10 #define SEGMENT_REGISTER 1
11 #define CTRL_REGISTER 2
12 #define DEBUG_REGISTER 3
16 /* Disgusting mask hack...
17 I can't think right now, so we'll do it this way...
19 static const ullong_t mask_1 = 0x00000000000000ffLL;
20 static const ullong_t mask_2 = 0x000000000000ffffLL;
21 static const ullong_t mask_4 = 0x00000000ffffffffLL;
22 static const ullong_t mask_8 = 0xffffffffffffffffLL;
25 #define MASK(val, length) ({ \
26 ullong_t mask = 0x0LL; \
39 struct memory_operand {
47 uint_t displacement_size;
48 ullong_t displacement;
53 // This returns a pointer to a V3_OPCODE_[*] array defined in vmm_decoder.h
54 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode);
56 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);
57 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
59 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
60 switch (info->cpu_mode) {
62 if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
64 XED_MACHINE_MODE_LEGACY_16,
65 XED_ADDRESS_WIDTH_16b,
66 XED_ADDRESS_WIDTH_16b);
71 if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
73 XED_MACHINE_MODE_LEGACY_32,
74 XED_ADDRESS_WIDTH_32b,
75 XED_ADDRESS_WIDTH_32b);
79 if (state->mmode != XED_MACHINE_MODE_LONG_64) {
80 state->mmode = XED_MACHINE_MODE_LONG_64;
89 int is_flags_reg(xed_reg_enum_t xed_reg) {
104 xed_state_zero(&decoder_state);
109 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
110 xed_decoded_inst_t xed_instr;
111 xed_error_enum_t xed_error;
115 if (set_decoder_mode(info, &decoder_state) == -1) {
116 PrintError("Could not set decoder mode\n");
122 xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
124 xed_error = xed_decode(&xed_instr,
125 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
126 XED_MAX_INSTRUCTION_BYTES);
129 if (xed_error != XED_ERROR_NONE) {
130 PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
134 const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
136 instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
137 instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
139 xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
142 PrintDebug("iform=%s\n", xed_iform_enum_t2str(iform));
145 if (instr->num_operands > 3) {
146 PrintDebug("Special Case Not Handled\n");
149 } else if (instr->num_operands == 3) {
150 const xed_operand_t * op = xed_inst_operand(xi, 2);
151 xed_operand_enum_t op_enum = xed_operand_name(op);
153 if ((!xed_operand_is_register(op_enum)) ||
154 (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
156 PrintDebug("Special Case not handled\n");
165 if (get_opcode(iform, &(instr->opcode)) == -1) {
166 PrintDebug("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
173 //PrintDebug("Number of operands: %d\n", instr->num_operands);
174 //PrintDebug("INSTR length: %d\n", instr->instr_length);
177 if (instr->num_operands >= 1) {
178 const xed_operand_t * op = xed_inst_operand(xi, 0);
179 xed_operand_enum_t op_enum = xed_operand_name(op);
181 if (xed_operand_is_register(op_enum)) {
182 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
183 int v3_reg_type = xed_reg_to_v3_reg(info,
185 &(instr->dst_operand.operand),
186 &(instr->dst_operand.size));
188 if (v3_reg_type == -1) {
189 PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
190 instr->dst_operand.type = INVALID_OPERAND;
192 } else if (v3_reg_type == SEGMENT_REGISTER) {
193 struct v3_segment * seg_reg = (struct v3_segment *)(instr->dst_operand.operand);
194 instr->dst_operand.operand = (addr_t)&(seg_reg->selector);
197 instr->dst_operand.type = REG_OPERAND;
202 case XED_OPERAND_MEM0:
204 struct x86_operand * operand = &(instr->dst_operand);
206 if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
207 operand = &(instr->src_operand);
208 } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
209 operand = &(instr->dst_operand);
212 if (get_memory_operand(info, &xed_instr, 0, operand) == -1) {
213 PrintError("Could not get first memory operand\n");
218 case XED_OPERAND_AGEN:
219 case XED_OPERAND_PTR:
220 case XED_OPERAND_RELBR:
221 case XED_OPERAND_IMM0:
222 PrintError("Unhandled Operand Type\n");
225 case XED_OPERAND_MEM1:
226 case XED_OPERAND_IMM1:
228 PrintError("Illegal Operand Order\n");
235 // set second operand
236 if (instr->num_operands >= 2) {
237 const xed_operand_t * op = xed_inst_operand(xi, 1);
238 xed_operand_type_enum_t op_type = xed_operand_type(op);
239 xed_operand_enum_t op_enum = xed_operand_name(op);
241 if (xed_operand_is_register(op_enum)) {
242 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
243 int v3_reg_type = xed_reg_to_v3_reg(info,
245 &(instr->src_operand.operand),
246 &(instr->src_operand.size));
247 if (v3_reg_type == -1) {
248 PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
249 instr->src_operand.type = INVALID_OPERAND;
251 } else if (v3_reg_type == SEGMENT_REGISTER) {
252 struct v3_segment * seg_reg = (struct v3_segment *)(instr->src_operand.operand);
253 instr->src_operand.operand = (addr_t)&(seg_reg->selector);
256 instr->src_operand.type = REG_OPERAND;
263 case XED_OPERAND_MEM0:
265 struct x86_operand * operand = &(instr->src_operand);
267 if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
268 operand = &(instr->src_operand);
269 } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
270 operand = &(instr->dst_operand);
273 if (get_memory_operand(info, &xed_instr, 0, operand) == -1) {
274 PrintError("Could not get first memory operand\n");
279 case XED_OPERAND_AGEN:
280 case XED_OPERAND_PTR:
281 case XED_OPERAND_RELBR:
282 case XED_OPERAND_IMM0:
283 PrintError("Unhandled Operand Type\n");
286 case XED_OPERAND_MEM1:
287 case XED_OPERAND_IMM1:
289 PrintError("Illegal Operand Order\n");
299 if (instr->num_operands >= 3) {
300 const xed_operand_t * op = xed_inst_operand(xi, 2);
301 xed_operand_type_enum_t op_type = xed_operand_type(op);
302 xed_operand_enum_t op_enum = xed_operand_name(op);
304 if (xed_operand_is_register(op_enum)) {
305 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
306 int v3_reg_type = xed_reg_to_v3_reg(info,
308 &(instr->third_operand.operand),
309 &(instr->third_operand.size));
311 if (v3_reg_type == -1) {
312 PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
313 instr->third_operand.type = INVALID_OPERAND;
315 } else if (v3_reg_type == SEGMENT_REGISTER) {
316 struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
317 instr->third_operand.operand = (addr_t)&(seg_reg->selector);
321 instr->third_operand.type = REG_OPERAND;
325 PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
338 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
347 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
348 struct memory_operand mem_op;
354 ullong_t displacement;
355 struct v3_segment * seg_reg;
360 memset(&mem_op, 0, sizeof(struct memory_operand));
362 xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
363 if (xed_seg != XED_REG_INVALID) {
364 struct v3_segment *tmp_segment;
365 if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
366 PrintError("Unhandled Segment Register\n");
369 mem_op.segment = tmp_segment->base;
372 xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
373 if (xed_base != XED_REG_INVALID) {
375 if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
376 PrintError("Unhandled Base register\n");
379 mem_op.base = *(addr_t *)base_reg;
384 xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
385 if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
388 if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
389 PrintError("Unhandled Index Register\n");
393 mem_op.index= *(addr_t *)index_reg;
395 xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
396 if (xed_scale != 0) {
397 mem_op.scale = xed_scale;
402 xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
404 xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
406 mem_op.displacement_size = disp_bits / 8;
407 mem_op.displacement = xed_disp;
411 operand->type = MEM_OPERAND;
412 operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
416 PrintDebug("Struct: Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n",
417 mem_op.segment, mem_op.base, mem_op.index, mem_op.scale, mem_op.displacement);
420 seg = mem_op.segment;
421 base = MASK(mem_op.base, mem_op.base_size);
422 index = MASK(mem_op.index, mem_op.index_size);
423 scale = mem_op.scale;
424 displacement = MASK(mem_op.displacement, mem_op.displacement_size);
426 PrintDebug("Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", seg, base, index, scale, displacement);
428 operand->operand = seg + base + (scale * index) + displacement;
433 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) {
436 case XED_REG_INVALID:
445 *v3_reg = (addr_t)&(info->vm_regs.rax);
449 *v3_reg = (addr_t)&(info->vm_regs.rax);
453 *v3_reg = (addr_t)&(info->vm_regs.rax);
457 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
461 *v3_reg = (addr_t)&(info->vm_regs.rax);
466 *v3_reg = (addr_t)&(info->vm_regs.rcx);
470 *v3_reg = (addr_t)&(info->vm_regs.rcx);
474 *v3_reg = (addr_t)&(info->vm_regs.rcx);
478 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
482 *v3_reg = (addr_t)&(info->vm_regs.rcx);
487 *v3_reg = (addr_t)&(info->vm_regs.rdx);
491 *v3_reg = (addr_t)&(info->vm_regs.rdx);
495 *v3_reg = (addr_t)&(info->vm_regs.rdx);
499 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
503 *v3_reg = (addr_t)&(info->vm_regs.rdx);
508 *v3_reg = (addr_t)&(info->vm_regs.rbx);
512 *v3_reg = (addr_t)&(info->vm_regs.rbx);
516 *v3_reg = (addr_t)&(info->vm_regs.rbx);
520 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
524 *v3_reg = (addr_t)&(info->vm_regs.rbx);
530 *v3_reg = (addr_t)&(info->vm_regs.rsp);
534 *v3_reg = (addr_t)&(info->vm_regs.rsp);
538 *v3_reg = (addr_t)&(info->vm_regs.rsp);
542 *v3_reg = (addr_t)&(info->vm_regs.rsp);
547 *v3_reg = (addr_t)&(info->vm_regs.rbp);
551 *v3_reg = (addr_t)&(info->vm_regs.rbp);
555 *v3_reg = (addr_t)&(info->vm_regs.rbp);
559 *v3_reg = (addr_t)&(info->vm_regs.rbp);
566 *v3_reg = (addr_t)&(info->vm_regs.rsi);
570 *v3_reg = (addr_t)&(info->vm_regs.rsi);
574 *v3_reg = (addr_t)&(info->vm_regs.rsi);
578 *v3_reg = (addr_t)&(info->vm_regs.rsi);
584 *v3_reg = (addr_t)&(info->vm_regs.rdi);
588 *v3_reg = (addr_t)&(info->vm_regs.rdi);
592 *v3_reg = (addr_t)&(info->vm_regs.rdi);
596 *v3_reg = (addr_t)&(info->vm_regs.rdi);
605 *v3_reg = (addr_t)&(info->rip);
607 return CTRL_REGISTER;
609 *v3_reg = (addr_t)&(info->rip);
611 return CTRL_REGISTER;
613 *v3_reg = (addr_t)&(info->rip);
615 return CTRL_REGISTER;
618 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
620 return CTRL_REGISTER;
622 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
624 return CTRL_REGISTER;
626 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
628 return CTRL_REGISTER;
631 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
633 return CTRL_REGISTER;
635 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
637 return CTRL_REGISTER;
639 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
641 return CTRL_REGISTER;
643 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
645 return CTRL_REGISTER;
647 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
649 return CTRL_REGISTER;
671 *v3_reg = (addr_t)&(info->segments.cs);
672 return SEGMENT_REGISTER;
674 *v3_reg = (addr_t)&(info->segments.ds);
675 return SEGMENT_REGISTER;
677 *v3_reg = (addr_t)&(info->segments.es);
678 return SEGMENT_REGISTER;
680 *v3_reg = (addr_t)&(info->segments.ss);
681 return SEGMENT_REGISTER;
683 *v3_reg = (addr_t)&(info->segments.fs);
684 return SEGMENT_REGISTER;
686 *v3_reg = (addr_t)&(info->segments.gs);
687 return SEGMENT_REGISTER;
694 PrintError("Segment selector operand... Don't know how to handle this...\n");
797 case XED_REG_STACKPUSH:
798 case XED_REG_STACKPOP:
804 case XED_REG_X87CONTROL:
805 case XED_REG_X87STATUS:
808 case XED_REG_X87PUSH:
810 case XED_REG_X87POP2:
845 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
848 case XED_IFORM_MOV_CR_GPR64_CR:
849 case XED_IFORM_MOV_CR_GPR32_CR:
850 *opcode = (addr_t)&V3_OPCODE_MOVCR2;
853 case XED_IFORM_MOV_CR_CR_GPR64:
854 case XED_IFORM_MOV_CR_CR_GPR32:
855 *opcode = (addr_t)&V3_OPCODE_MOV2CR;
859 case XED_IFORM_LMSW_GPR16:
860 *opcode = (addr_t)&V3_OPCODE_LMSW;
864 *opcode = (addr_t)&V3_OPCODE_CLTS;