Skip to content

Commit

Permalink
self modifying code clear recursive mem access
Browse files Browse the repository at this point in the history
when self modifying code does unaligned memory accese sometimes
uc->size_recur_mem is changed but for notdirty write not changed back.
This causes mem_hooks to be missed. To fix this uc->size_recur_mem is
set to 0 before each cpu_exec() call.
  • Loading branch information
PhilippTakacs committed Oct 28, 2024
1 parent fb84597 commit f350d8c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
1 change: 1 addition & 0 deletions qemu/softmmu/cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ static int tcg_cpu_exec(struct uc_struct *uc)
// (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
if (cpu_can_run(cpu)) {
uc->quit_request = false;
uc->size_recur_mem = 0;
r = cpu_exec(uc, cpu);

// quit current TB but continue emulating?
Expand Down
42 changes: 42 additions & 0 deletions tests/unit/test_x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,47 @@ static void test_x86_smc_add(void)
OK(uc_emu_start(uc, code_start, -1, 0, 0));
}

static void test_x86_smc_mem_hook_callback(uc_engine *uc, uc_mem_type t,
uint64_t addr, int size,
uint64_t value, void *user_data)
{
uint64_t write_addresses[] = { 0x1030, 0x1010, 0x1010, 0x1018, 0x1018, 0x1029, 0x1029 };
unsigned int *i = user_data;

TEST_CHECK(*i < (sizeof(write_addresses)/sizeof(write_addresses[0])));
TEST_CHECK(write_addresses[*i] == addr);
(*i)++;
}

static void test_x86_smc_mem_hook(void)
{
uc_engine *uc;
uc_hook hook;
uint64_t stack_base = 0x20000;
int r_rsp;
unsigned int i = 0;
/*
* mov qword ptr [rip+0x29], rax
* mov word ptr [rip], 0x0548
* [orig] mov eax, dword ptr [rax + 0x12345678]; [after SMC] 480578563412 add rax, 0x12345678
* nop
* nop
* nop
* mov qword ptr [rip-0x08], rax
* mov word ptr [rip], 0x0548
* [orig] mov eax, dword ptr [rax + 0x12345678]; [after SMC] 480578563412 add rax, 0x12345678
* hlt
*/
char code[] = "\x48\x89\x05\x29\x00\x00\x00\x66\xC7\x05\x00\x00\x00\x00\x48\x05\x8B\x80\x78\x56\x34\x12\x90\x90\x90\x48\x89\x05\xF8\xFF\xFF\xFF\x66\xC7\x05\x00\x00\x00\x00\x48\x05\x8B\x80\x78\x56\x34\x12\xF4";
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1);

OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_WRITE, test_x86_smc_mem_hook_callback, &i, 1, 0));
OK(uc_mem_map(uc, stack_base, 0x2000, UC_PROT_ALL));
r_rsp = stack_base + 0x1800;
OK(uc_reg_write(uc, UC_X86_REG_RSP, &r_rsp));
OK(uc_emu_start(uc, code_start, -1, 0, 0));
}

static uint64_t test_x86_mmio_uc_mem_rw_read_callback(uc_engine *uc,
uint64_t offset,
unsigned size,
Expand Down Expand Up @@ -1870,6 +1911,7 @@ TEST_LIST = {
{"test_x86_missing_code", test_x86_missing_code},
{"test_x86_smc_xor", test_x86_smc_xor},
{"test_x86_smc_add", test_x86_smc_add},
{"test_x86_smc_mem_hook", test_x86_smc_mem_hook},
{"test_x86_mmio_uc_mem_rw", test_x86_mmio_uc_mem_rw},
{"test_x86_sysenter", test_x86_sysenter},
{"test_x86_hook_cpuid", test_x86_hook_cpuid},
Expand Down

0 comments on commit f350d8c

Please sign in to comment.