From feb8ced027b7f33bfca6795093b1206df4c2315a Mon Sep 17 00:00:00 2001 From: mothran Date: Fri, 28 Aug 2015 10:39:11 -0700 Subject: [PATCH] fixed the FPIP updates to correctly only work with non-control instructions and make sure the pc addr is correct --- qemu/target-i386/translate.c | 22 +++++++-------- regress/fpu_ip.py | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 11 deletions(-) create mode 100755 regress/fpu_ip.py diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 5b4ccb25..fc8c66ef 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -248,9 +248,9 @@ static void gen_update_cc_op(DisasContext *s) } } -static void fpu_update_ip(CPUX86State *env) +static void fpu_update_ip(CPUX86State *env, target_ulong pc) { - env->fpip = env->eip; + env->fpip = pc; } #ifdef TARGET_X86_64 @@ -6115,7 +6115,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, /* fcomp needs pop */ gen_helper_fpop(tcg_ctx, cpu_env); } - fpu_update_ip(env); + fpu_update_ip(env, pc_start); } break; case 0x08: /* flds */ @@ -6200,7 +6200,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_helper_fpop(tcg_ctx, cpu_env); break; } - fpu_update_ip(env); + fpu_update_ip(env, pc_start); break; case 0x0c: /* fldenv mem */ gen_update_cc_op(s); @@ -6226,14 +6226,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_update_cc_op(s); gen_jmp_im(s, pc_start - s->cs_base); gen_helper_fldt_ST0(tcg_ctx, cpu_env, cpu_A0); - fpu_update_ip(env); + fpu_update_ip(env, pc_start); break; case 0x1f: /* fstpt mem */ gen_update_cc_op(s); gen_jmp_im(s, pc_start - s->cs_base); gen_helper_fstt_ST0(tcg_ctx, cpu_env, cpu_A0); gen_helper_fpop(tcg_ctx, cpu_env); - fpu_update_ip(env); + fpu_update_ip(env, pc_start); break; case 0x2c: /* frstor mem */ gen_update_cc_op(s); @@ -6254,25 +6254,25 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_update_cc_op(s); gen_jmp_im(s, pc_start - s->cs_base); gen_helper_fbld_ST0(tcg_ctx, cpu_env, cpu_A0); - fpu_update_ip(env); + fpu_update_ip(env, pc_start); break; case 0x3e: /* fbstp */ gen_update_cc_op(s); gen_jmp_im(s, pc_start - s->cs_base); gen_helper_fbst_ST0(tcg_ctx, cpu_env, cpu_A0); gen_helper_fpop(tcg_ctx, cpu_env); - fpu_update_ip(env); + fpu_update_ip(env, pc_start); break; case 0x3d: /* fildll */ tcg_gen_qemu_ld_i64(s->uc, cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ); gen_helper_fildll_ST0(tcg_ctx, cpu_env, cpu_tmp1_i64); - fpu_update_ip(env); + fpu_update_ip(env, pc_start); break; case 0x3f: /* fistpll */ gen_helper_fistll_ST0(tcg_ctx, cpu_tmp1_i64, cpu_env); tcg_gen_qemu_st_i64(s->uc, cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ); gen_helper_fpop(tcg_ctx, cpu_env); - fpu_update_ip(env); + fpu_update_ip(env, pc_start); break; default: goto illegal_op; @@ -6587,7 +6587,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, default: goto illegal_op; } - fpu_update_ip(env); + fpu_update_ip(env, pc_start); } break; /************************/ diff --git a/regress/fpu_ip.py b/regress/fpu_ip.py new file mode 100755 index 00000000..ed8fec6b --- /dev/null +++ b/regress/fpu_ip.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +from unicorn import * +from unicorn.x86_const import * +from capstone import * + +ESP = 0x2000 +PAGE_SIZE = 0x8000 + +# mov [esp], DWORD 0x37f +# fldcw [esp] +# fnop +# fnstenv [esp + 8] +# pop ecx +CODE = b'\xc7\x04\x24\x7f\x03\x00\x00\xd9\x2c\x24\xd9\xd0\xd9\x74\x24\x08\x59' + +class SimpleEngine: + def __init__(self): + self.capmd = Cs(CS_ARCH_X86, CS_MODE_32) + + def disas_single(self, data): + for i in self.capmd.disasm(data, 16): + print("\t%s\t%s" % (i.mnemonic, i.op_str)) + break + +disasm = SimpleEngine() + +def hook_code(uc, addr, size, user_data): + mem = uc.mem_read(addr, size) + print(" 0x%X:" % (addr)), + disasm.disas_single(str(mem)) + +def mem_reader(addr, size): + tmp = mu.mem_read(addr, size) + + for i in tmp: + print(" 0x%x" % i), + print("") + + +mu = Uc(UC_ARCH_X86, UC_MODE_32) + +mu.mem_map(0x0, PAGE_SIZE) +mu.mem_map(0x4000, PAGE_SIZE) +mu.mem_write(0x4000, CODE) +mu.reg_write(UC_X86_REG_ESP, ESP) +mu.hook_add(UC_HOOK_CODE, hook_code) + + +mu.emu_start(0x4000, 0, 0, 5) +esp = mu.reg_read(UC_X86_REG_ESP) +print("value at ESP [0x%X - 4]: " % esp) +mem_reader(esp + 14, 4) \ No newline at end of file