From d50bbb5d5bb92fae8000a380ed7e11aabb9b6965 Mon Sep 17 00:00:00 2001 From: mio Date: Sat, 4 Jan 2025 15:48:32 +0800 Subject: [PATCH] Add unit test from #2078 --- tests/unit/test_arm64.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/unit/test_arm64.c b/tests/unit/test_arm64.c index e016dc82..e48bbda9 100644 --- a/tests/unit/test_arm64.c +++ b/tests/unit/test_arm64.c @@ -529,6 +529,59 @@ static void test_arm64_pc_wrap(void) OK(uc_close(uc)); } +static void +test_arm64_mem_prot_regress_hook_mem(uc_engine *uc, uc_mem_type type, + uint64_t address, int size, int64_t value, void *user_data) +{ + // fprintf(stderr, "%s %p %d\n", (type == UC_MEM_WRITE) ? "UC_MEM_WRITE" : "UC_MEM_READ", (void *)address, size); +} + +static bool +test_arm64_mem_prot_regress_hook_prot(uc_engine *uc, uc_mem_type type, + uint64_t address, int size, int64_t value, void *user_data) +{ + // fprintf(stderr, "%s %p %d\n", (type == UC_MEM_WRITE_PROT) ? "UC_MEM_WRITE_PROT" : ((type == UC_MEM_FETCH_PROT) ? "UC_MEM_FETCH_PROT" : "UC_MEM_READ_PROT"), (void *)address, size); + return false; +} + +static bool +test_arm64_mem_prot_regress_hook_unm(uc_engine *uc, uc_mem_type type, + uint64_t address, int size, int64_t value, void *user_data) +{ + // fprintf(stderr, "%s %p %d\n", (type == UC_MEM_WRITE_UNMAPPED) ? "UC_MEM_WRITE_UNMAPPED" : ((type == UC_MEM_FETCH_UNMAPPED) ? "UC_MEM_FETCH_UNMAPPED" : "UC_MEM_READ_UNMAPPED"), (void *)address, size); + return false; +} + +// https://github.com/unicorn-engine/unicorn/issues/2078 +static void test_arm64_mem_prot_regress(void) +{ + const uint8_t code[] = { + 0x08, 0x40, 0x5e, 0x78, // ldurh w8, [x0, #-0x1c] + }; + + uc_engine *uc; + OK(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); + + OK(uc_mem_map(uc, 0, 0x4000, UC_PROT_READ|UC_PROT_EXEC)); + OK(uc_mem_map(uc, 0x4000, 0xC000, UC_PROT_READ|UC_PROT_WRITE)); + OK(uc_mem_write(uc, 0, code, sizeof(code))); + uc_hook hh_mem; + OK(uc_hook_add(uc, &hh_mem, UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, test_arm64_mem_prot_regress_hook_mem, NULL, 1, 0)); + + uc_hook hh_prot; + OK(uc_hook_add(uc, &hh_prot, UC_HOOK_MEM_READ_PROT | UC_HOOK_MEM_WRITE_PROT | UC_HOOK_MEM_FETCH_PROT, test_arm64_mem_prot_regress_hook_prot, NULL, 1, 0)); + + uc_hook hh_unm; + OK(uc_hook_add(uc, &hh_unm, UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_UNMAPPED, test_arm64_mem_prot_regress_hook_unm, NULL, 1, 0)); + + const uint64_t value = 0x801b; + OK(uc_reg_write(uc, UC_ARM64_REG_X0, &value)); + + OK(uc_emu_start(uc, 0, sizeof(code), 0, 0)); + + OK(uc_close(uc)); +} + TEST_LIST = {{"test_arm64_until", test_arm64_until}, {"test_arm64_code_patching", test_arm64_code_patching}, {"test_arm64_code_patching_count", test_arm64_code_patching_count}, @@ -544,4 +597,5 @@ TEST_LIST = {{"test_arm64_until", test_arm64_until}, test_arm64_block_invalid_mem_read_write_sync}, {"test_arm64_mmu", test_arm64_mmu}, {"test_arm64_pc_wrap", test_arm64_pc_wrap}, + {"test_arm64_mem_prot_regress", test_arm64_mem_prot_regress}, {NULL, NULL}};