Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions tests/unit/test_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,37 @@ static void test_noexec(void)
OK(uc_close(uc));
}

static void test_add_block_hook_syscall_cb(uc_engine *uc, void *userdata)
{
OK(uc_emu_stop(uc));
}

static void test_add_block_hook_block_cb(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
uint64_t *block_counter = user_data;
*block_counter += 1;
}

static void test_add_block_hook(void)
{
uc_engine *uc;
uint64_t block_counter = 0;
uc_hook syscall_hook;
uc_hook block_hook;
/* nop
* syscall
*/
char code[] = "\x90\x0F\x05";

uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1);
OK(uc_hook_add(uc, &syscall_hook, UC_HOOK_INSN, &test_add_block_hook_syscall_cb, NULL, 1, 0, UC_X86_INS_SYSCALL));
OK(uc_emu_start(uc, code_start, 0, 0, 0));
OK(uc_hook_add(uc, &block_hook, UC_HOOK_BLOCK, &test_add_block_hook_block_cb, &block_counter, code_start, code_start+0x1000));
OK(uc_emu_start(uc, code_start, 0, 0, 0));
TEST_CHECK(block_counter == 1);
OK(uc_close(uc));
}

TEST_LIST = {
{"test_uc_ctl_mode", test_uc_ctl_mode},
{"test_uc_ctl_page_size", test_uc_ctl_page_size},
Expand All @@ -416,4 +447,5 @@ TEST_LIST = {
{"test_uc_emu_stop_set_ip", test_uc_emu_stop_set_ip},
{"test_tlb_clear", test_tlb_clear},
{"test_noexec", test_noexec},
{"test_add_block_hook", test_add_block_hook},
{NULL, NULL}};
2 changes: 1 addition & 1 deletion tests/unit/test_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ static void test_virtual_write(void)
OK(uc_vmem_write(uc, 0x1000, UC_PROT_EXEC, code, sizeof(code)));
OK(uc_vmem_write(uc, 0x2000, UC_PROT_READ, &rax, sizeof(rax)));

OK(uc_emu_start(uc, 0x1000, 0x1000 + sizeof(code) - 1, 0, 1));
OK(uc_emu_start(uc, 0x1000, 0x1000 + sizeof(code), 0, 1));
OK(uc_reg_read(uc, UC_X86_REG_RAX, &res));
TEST_CHECK(rax == res);

Expand Down
18 changes: 16 additions & 2 deletions uc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1999,6 +1999,18 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
return UC_ERR_OK;
}

if (type & UC_HOOK_CODE || type & UC_HOOK_BLOCK) {
if (end <= begin) {
uc->tb_flush(uc);
} else {
uc->uc_invalidate_tb(uc, begin, end-begin);
}
if (uc->nested_level) {
uc->quit_request = true;
break_translation_loop(uc);
}
}

while ((type >> i) > 0) {
if ((type >> i) & 1) {
// TODO: invalid hook error?
Expand Down Expand Up @@ -2047,8 +2059,10 @@ uc_err uc_hook_del(uc_engine *uc, uc_hook hh)
// and store the type mask in the hook pointer.
for (i = 0; i < UC_HOOK_MAX; i++) {
if (list_exists(&uc->hook[i], (void *)hook)) {
g_hash_table_foreach(hook->hooked_regions, hook_invalidate_region,
uc);
if (hook->type & UC_HOOK_CODE || hook->type & UC_HOOK_BLOCK) {
g_hash_table_foreach(hook->hooked_regions,
hook_invalidate_region, uc);
}
g_hash_table_remove_all(hook->hooked_regions);
hook->to_delete = true;
uc->hooks_count[i]--;
Expand Down
Loading