+#define MAKE_2OP_8EXT_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, uint_t dst_len) { \
+ if (dst_len == 2) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint16_t *)dst) \
+ : "q"(*(uint8_t *)src), "0"(*(uint16_t *)dst) \
+ ); \
+ } else if (dst_len == 4) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint32_t *)dst) \
+ : "q"(*(uint8_t *)src), "0"(*(uint32_t *)dst) \
+ ); \
+ } else if (dst_len == 8) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint64_t *)dst) \
+ : "q"(*(uint8_t *)src), "0"(*(uint64_t *)dst) \
+ ); \
+ } \
+ }
+
+#define MAKE_2OP_16EXT_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, uint_t dst_len) { \
+ if (dst_len == 4) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint32_t *)dst) \
+ : "q"(*(uint16_t *)src), "0"(*(uint32_t *)dst) \
+ ); \
+ } else if (dst_len == 8) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint64_t *)dst) \
+ : "q"(*(uint16_t *)src), "0"(*(uint64_t *)dst) \
+ ); \
+ } \
+ }
+
+
+
+
+
+
/****************************/
/* 8 Bit instruction forms */
/****************************/
MAKE_1OP_8_INST(not);
MAKE_2OP_8_INST(mov);
+MAKE_2OP_8EXT_INST(movzx);
+MAKE_2OP_8EXT_INST(movsx);
+
MAKE_2OP_8_INST(xchg);
MAKE_2OP_8STR_INST(movs);
MAKE_1OP_16_INST(not);
MAKE_2OP_16_INST(mov);
+MAKE_2OP_16EXT_INST(movzx);
+MAKE_2OP_16EXT_INST(movsx);
MAKE_2OP_16_INST(xchg);
MAKE_2OP_16STR_INST(movs);
MAKE_1OP_32_INST(not);
MAKE_2OP_32_INST(mov);
+
MAKE_2OP_32_INST(xchg);
MAKE_2OP_64_INST(mov);
+
MAKE_2OP_64_INST(xchg);
-static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int op_size);
+static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int src_op_size, int dst_op_size);
// We emulate up to the next 4KB page boundry
static int emulate_string_write_op(struct guest_info * info, struct x86_instr * dec_instr,
uchar_t instr[15];
int ret = 0;
addr_t src_addr = 0;
- int op_len = 0;
+ int src_op_len = 0;
+ int dst_op_len = 0;
PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
PrintDebug("GVA=%p\n", (void *)write_gva);
src_addr = (addr_t)&(dec_instr.src_operand.operand);
}
- op_len = dec_instr.dst_operand.size;
+ dst_op_len = dec_instr.dst_operand.size;
+ src_op_len = dec_instr.src_operand.size;
PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
(void *)dst_addr, (void *)src_addr);
- if (run_op(info, dec_instr.op_type, src_addr, dst_addr, op_len) == -1) {
+ if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
PrintError("Instruction Emulation Failed\n");
return -1;
}
- if (write_fn(write_gpa, (void *)dst_addr, op_len, priv_data) != op_len) {
+ if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
PrintError("Did not fully write hooked data\n");
return -1;
}
info->rip += dec_instr.instr_length;
- return op_len;
+ return dst_op_len;
}
uchar_t instr[15];
int ret = 0;
addr_t dst_addr = 0;
- int op_len = 0;
+ int src_op_len = 0;
+ int dst_op_len = 0;
PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
PrintDebug("GVA=%p\n", (void *)read_gva);
dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
}
- op_len = dec_instr.src_operand.size;
+ src_op_len = dec_instr.src_operand.size;
+ dst_op_len = dec_instr.dst_operand.size;
PrintDebug("Dst_Addr = %p, SRC Addr = %p\n",
(void *)dst_addr, (void *)src_addr);
- if (read_fn(read_gpa, (void *)src_addr,op_len, priv_data) != op_len) {
+ if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
PrintError("Did not fully read hooked data\n");
return -1;
}
- if (run_op(info, dec_instr.op_type, src_addr, dst_addr, op_len) == -1) {
+ if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
PrintError("Instruction Emulation Failed\n");
return -1;
}
info->rip += dec_instr.instr_length;
- return op_len;
+ return src_op_len;
}
-static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int op_size) {
+static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int src_op_size, int dst_op_size) {
- if (op_size == 1) {
+ if (src_op_size == 1) {
switch (op_type) {
case V3_OP_ADC:
case V3_OP_MOV:
mov8((addr_t *)dst_addr, (addr_t *)src_addr);
break;
+
+ case V3_OP_MOVZX:
+ movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
+ break;
+ case V3_OP_MOVSX:
+ movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
+ break;
+
case V3_OP_NOT:
not8((addr_t *)dst_addr);
break;
return -1;
}
- } else if (op_size == 2) {
+ } else if (src_op_size == 2) {
switch (op_type) {
case V3_OP_ADC:
case V3_OP_MOV:
mov16((addr_t *)dst_addr, (addr_t *)src_addr);
break;
+ case V3_OP_MOVZX:
+ movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
+ break;
+ case V3_OP_MOVSX:
+ movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
+ break;
case V3_OP_NOT:
not16((addr_t *)dst_addr);
break;
return -1;
}
- } else if (op_size == 4) {
+ } else if (src_op_size == 4) {
switch (op_type) {
case V3_OP_ADC:
case V3_OP_MOV:
mov32((addr_t *)dst_addr, (addr_t *)src_addr);
break;
+
case V3_OP_NOT:
not32((addr_t *)dst_addr);
break;
}
#ifdef __V3_64BIT__
- } else if (op_size == 8) {
+ } else if (src_op_size == 8) {
switch (op_type) {
case V3_OP_MOV:
mov64((addr_t *)dst_addr, (addr_t *)src_addr);
break;
+
case V3_OP_NOT:
not64((addr_t *)dst_addr);
break;