diff --git a/.gitignore b/.gitignore index 8b24f7b9..86d5d104 100644 --- a/.gitignore +++ b/.gitignore @@ -122,6 +122,7 @@ mem_nofree mips_delay_slot_code_hook test_mem_high +rw_hookstack ################# diff --git a/qemu/memory.c b/qemu/memory.c index a767bf03..5e26d83d 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -78,13 +78,18 @@ void memory_unmap(struct uc_struct *uc, MemoryRegion *mr) int memory_free(struct uc_struct *uc) { + MemoryRegion *mr; int i; get_system_memory(uc)->enabled = false; for (i = 0; i < uc->mapped_block_count; i++) { - uc->mapped_blocks[i]->enabled = false; - memory_region_del_subregion(get_system_memory(uc), uc->mapped_blocks[i]); - g_free(uc->mapped_blocks[i]); + mr = uc->mapped_blocks[i]; + mr->enabled = false; + memory_region_del_subregion(get_system_memory(uc), mr); + mr->destructor(mr); + g_free((char *)mr->name); + g_free(mr->ioeventfds); + g_free(mr); } return 0; diff --git a/tests/regress/Makefile b/tests/regress/Makefile index b7129f09..3221f939 100644 --- a/tests/regress/Makefile +++ b/tests/regress/Makefile @@ -24,6 +24,7 @@ TESTS += invalid_read_in_tb_flush_x86_64 TESTS += sparc_jump_to_zero TESTS += mips_delay_slot_code_hook TESTS += mem_nofree +TESTS += rw_hookstack all: $(TESTS) diff --git a/tests/regress/rw_hookstack.c b/tests/regress/rw_hookstack.c new file mode 100644 index 00000000..65caf1e4 --- /dev/null +++ b/tests/regress/rw_hookstack.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include + +#define ADDRESS 0x1000000 +#define STACK 0x0020D000 +#define STACK2 0x0030D000 +#define STACK_SIZE 16384 +#define SIZE (2 * 1024 * 1024) +#define CODE32 "\x8B\x04\x24\xA3\x40\x00\x00\x01\xA1\x40\x00\x00\x01" + +bool hook_mem_rw(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) +{ + unsigned int EIP; + + uc_reg_read(uc, UC_X86_REG_EIP, &EIP); + switch(type) + { + default: + return false; + break; + case UC_MEM_WRITE: + printf("Hooked write to address 0x%08"PRIX64" with value 0x%08"PRIX64" at EIP %08X\n", address, value, EIP); + + return true; + break; + case UC_MEM_READ: + printf("Hooked read from address 0x%08"PRIX64" with value 0x%08"PRIX64" at EIP %08X\n", address, value, EIP); + + return true; + break; + } +} + +int main(int argc, char *argv[]) +{ + uc_engine *uc; + uc_hook trace; + uc_err err; + unsigned int EAX, ESP, val = 0x0c0c0c0c, stkval = STACK; + + EAX = 0; + ESP = STACK+0x4; + + // Initialize emulator in X86-64bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc); + if(err) { + printf("Failed on uc_open() with error returned: %s\n", uc_strerror(err)); + return; + } + + err = uc_mem_map(uc, ADDRESS, SIZE, UC_PROT_ALL); + if(err != UC_ERR_OK) { + printf("Failed to map memory %s\n", uc_strerror(err)); + return; + } + + err = uc_mem_write(uc, ADDRESS, CODE32, sizeof(CODE32) - 1); + if(err != UC_ERR_OK) { + printf("Failed to write to memory %s\n", uc_strerror(err)); + return; + } + +loop: + err = uc_mem_map(uc, stkval, STACK_SIZE, UC_PROT_ALL); + if(err != UC_ERR_OK) { + printf("Failed to map memory %s\n", uc_strerror(err)); + return; + } + + err = uc_mem_write(uc, ESP, &val, sizeof(val)); + if(err != UC_ERR_OK) { + printf("Failed to write to memory %s\n", uc_strerror(err)); + return; + } + + + uc_hook_add(uc, &trace, UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, (void *)hook_mem_rw, NULL); + + uc_reg_write(uc, UC_X86_REG_EAX, &EAX); + uc_reg_write(uc, UC_X86_REG_ESP, &ESP); + + err = uc_emu_start(uc, ADDRESS, ADDRESS + (sizeof(CODE32) - 1), 0, 0); + if(err) { + printf("Failed on uc_emu_start() with error returned %u: %s\n", err, uc_strerror(err)); + + uc_close(uc); + return; + } + + uc_reg_read(uc, UC_X86_REG_EAX, &EAX); + + printf(">>> EAX = %08X\n", EAX); + + if(stkval != STACK2) + { + printf("=== Beginning test two ===\n"); + ESP = STACK2+0x4; + EAX = 0; + stkval = STACK2; + goto loop; + } + + uc_close(uc); + return 0; +} diff --git a/uc.c b/uc.c index 2c8f9f1d..53bb682d 100644 --- a/uc.c +++ b/uc.c @@ -258,7 +258,6 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) UNICORN_EXPORT uc_err uc_close(uc_engine *uc) { - MemoryRegion *mr; int i; if (uc->release) @@ -274,13 +273,6 @@ uc_err uc_close(uc_engine *uc) g_free(uc->tcg_ctx); - for (i = 0; i < uc->mapped_block_count; i++) { - mr = uc->mapped_blocks[i]; - mr->destructor(mr); - g_free((char *)mr->name); - g_free(mr->ioeventfds); - } - free((void*) uc->system_memory->name); g_free(uc->system_memory); g_hash_table_destroy(uc->type_table);