From 2ad9f152f95c984e77dd82e07e004f75bb4a7b94 Mon Sep 17 00:00:00 2001 From: mio Date: Wed, 19 Jan 2022 21:58:46 +0100 Subject: [PATCH] Set emulation_done to true if and only if we exit the outer uc_emu_start Or we may lost uc_emu_stop wrongly --- tests/unit/test_x86.c | 36 ++++++++++++++++++++++++++++++++++++ uc.c | 10 +++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/tests/unit/test_x86.c b/tests/unit/test_x86.c index c057af70..0fae9c69 100644 --- a/tests/unit/test_x86.c +++ b/tests/unit/test_x86.c @@ -873,6 +873,41 @@ static void test_x86_nested_emu_start() OK(uc_close(uc)); } +static void test_x86_nested_emu_stop_cb(uc_engine *uc, uint64_t addr, + size_t size, void *data) +{ + OK(uc_emu_start(uc, code_start + 1, code_start + 2, 0, 0)); + // ecx shouldn't be changed! + OK(uc_emu_stop(uc)); +} + +static void test_x86_nested_emu_stop() +{ + uc_engine *uc; + // INC ecx; DEC edx; DEC edx; + char code[] = "\x41\x4a\x4a"; + int r_ecx = 0x1234; + int r_edx = 0x7890; + uc_hook h; + + uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1); + OK(uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx)); + OK(uc_reg_write(uc, UC_X86_REG_EDX, &r_edx)); + // Emulate DEC in the nested hook. + OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_x86_nested_emu_stop_cb, NULL, + code_start, code_start)); + + OK(uc_emu_start(uc, code_start, code_start + 3, 0, 0)); + + OK(uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx)); + OK(uc_reg_read(uc, UC_X86_REG_EDX, &r_edx)); + + TEST_CHECK(r_ecx == 0x1234); + TEST_CHECK(r_edx == 0x788f); + + OK(uc_close(uc)); +} + TEST_LIST = {{"test_x86_in", test_x86_in}, {"test_x86_out", test_x86_out}, {"test_x86_mem_hook_all", test_x86_mem_hook_all}, @@ -900,4 +935,5 @@ TEST_LIST = {{"test_x86_in", test_x86_in}, {"test_x86_hook_tcg_op", test_x86_hook_tcg_op}, {"test_x86_cmpxchg", test_x86_cmpxchg}, {"test_x86_nested_emu_start", test_x86_nested_emu_start}, + {"test_x86_nested_emu_stop", test_x86_nested_emu_stop}, {NULL, NULL}}; diff --git a/uc.c b/uc.c index b1ed43a9..23c10666 100644 --- a/uc.c +++ b/uc.c @@ -804,8 +804,13 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until, uc->vm_start(uc); - // emulation is done - uc->emulation_done = true; + uc->nested_level--; + + // emulation is done if and only if we exit the outer uc_emu_start + // or we may lost uc_emu_stop + if (uc->nested_level == 0) { + uc->emulation_done = true; + } // remove hooks to delete clear_deleted_hooks(uc); @@ -815,7 +820,6 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until, qemu_thread_join(&uc->timer); } - uc->nested_level--; return uc->invalid_error; }