From 5bf6d77e4ee258c67c2d7ead94cf266a7b9773e7 Mon Sep 17 00:00:00 2001 From: dmarxn <47157608+dmarxn@users.noreply.github.com> Date: Mon, 25 Feb 2019 15:14:20 +0200 Subject: [PATCH] Fixed the decoding of opcodes after getting vex2 using 0xc5 (#1064) * Fixed the decoding of opcodes after getting vex2 using 0xc5 * Added testcase for vex. Can and should be expanded * Fixed warning of testcase for vex (parentheses for assignment) --- qemu/target-i386/translate.c | 2 +- tests/regress/x86_vex.c | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/regress/x86_vex.c diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 3c94d54d..36fae092 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -5145,7 +5145,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, rex_r = (~vex2 >> 4) & 8; if (b == 0xc5) { vex3 = vex2; - b = cpu_ldub_code(env, s->pc++); + b = cpu_ldub_code(env, s->pc++) | 0x100; } else { #ifdef TARGET_X86_64 s->rex_x = (~vex2 >> 3) & 8; diff --git a/tests/regress/x86_vex.c b/tests/regress/x86_vex.c new file mode 100644 index 00000000..a05f2cf6 --- /dev/null +++ b/tests/regress/x86_vex.c @@ -0,0 +1,58 @@ +#include "unicorn/unicorn.h" +#include +#include + + +#define OK(x) {uc_err __err; if ((__err = x)) { fprintf(stderr, "%s", uc_strerror(__err)); assert(false); } } +static void test_vmovdqu(void) +{ + uc_engine *uc; + + int r_esi = 0x1234; + int r_edi = 0x7890; + + uint64_t r_xmm0[2] = {0x08090a0b0c0d0e0f, 0x0001020304050607}; + + /* 128 bit at address esi (0x1234) this should not be read into xmm0 */ + char mem_esi[] = { '\xE7', '\x1D', '\xA7', '\xE8', '\x88', '\xE4', '\x94', '\x40', '\x54', '\x74', '\x24', '\x97', '\x1F', '\x2E', '\xB6', '\x40' }; + + /* 128 bit at address edi (0x7890) this SHOULD be read into xmm0 */ + char mem_edi[] = { '\xAD', '\xFA', '\x5C', '\x6D', '\x45', '\x4A', '\x93', '\x40', '\xD2', '\x00', '\xDE', '\x02', '\x89', '\xE8', '\x94', '\x40' }; + + /* vmovdqu xmm0, [edi] */ + char code[] = { '\xC5', '\xFA', '\x6F', '\x07' }; + + /* initialize memory and run emulation */ + OK(uc_open(UC_ARCH_X86, UC_MODE_32, &uc)); + OK(uc_mem_map(uc, 0, 2 * 1024 * 1024, UC_PROT_ALL)); + + OK(uc_mem_write(uc, 0, code, sizeof(code) / sizeof(code[0]))); + + // initialize machine registers; + OK(uc_reg_write(uc, UC_X86_REG_XMM0, &r_xmm0)); + + OK(uc_reg_write(uc, UC_X86_REG_ESI, &r_esi)); + OK(uc_reg_write(uc, UC_X86_REG_EDI, &r_edi)); + OK(uc_mem_write(uc, r_esi, mem_esi, sizeof(mem_esi) / sizeof(mem_esi[0]))); + OK(uc_mem_write(uc, r_edi, mem_edi, sizeof(mem_edi) / sizeof(mem_edi[0]))); + + OK(uc_emu_start(uc, 0, sizeof(code) / sizeof(code[0]), 0, 0)); + + /* Read xmm0 after emulation */ + OK(uc_reg_read(uc, UC_X86_REG_XMM0, &r_xmm0)); + + + assert(0x4094e88902de00d2 == r_xmm0[0] && 0x40934a456d5cfaad == r_xmm0[1]); + + OK(uc_close(uc)); +} + + +/* TODO: Add more vex prefixed instructions + Suggestions: vxorpd, vxorps, vandpd, ... */ +int main(int argc, char **argv, char **envp) +{ + test_vmovdqu(); + return 0; +} +