diff --git a/tests/regress/Makefile b/tests/regress/Makefile index 3de87998..6b8381a9 100644 --- a/tests/regress/Makefile +++ b/tests/regress/Makefile @@ -37,6 +37,7 @@ TESTS += mips_branch_likely_issue TESTS += hook_extrainvoke TESTS += sysenter_hook_x86 TESTS += emu_clear_errors +TESTS += mem_fuzz all: $(TESTS) diff --git a/tests/regress/mem_fuzz.c b/tests/regress/mem_fuzz.c new file mode 100644 index 00000000..a1e080cf --- /dev/null +++ b/tests/regress/mem_fuzz.c @@ -0,0 +1,119 @@ +#define __STDC_FORMAT_MACROS +#include +#include +#include +#include +#include +#include + +#include + + +uint64_t baseranges[] = {0,0,0,0}; +int step =0; + +uint64_t urnd(){ + uint64_t rnd = rand(); + rnd = rnd << 32; + rnd += rand(); + return rnd; +} +uint64_t get_addr(){ + uint64_t base = ((uint64_t)urnd())%4; + uint64_t addr= baseranges[base] + urnd()%(4096*10); + return addr; +} + +uint64_t get_aligned_addr(){ + uint64_t addr = get_addr(); + return addr - (addr % 4096); +} + +uint64_t get_len(){ + uint64_t len = (urnd() % (4096*5))+1; + return len; +} + +uint64_t get_aligned_len(){ + uint64_t len = get_len(); + len = len - (len %4096); + len = ((len == 0) ? 4096 : len); + return len; +} + +void perform_map_step(uc_engine *uc){ + uint64_t addr = get_aligned_addr(); + uint64_t len = get_aligned_len(); + printf("map(0x%lx,0x%lx); //%d\n", addr, len, step); + uc_mem_map(uc, addr, len, UC_PROT_READ | UC_PROT_WRITE); +} + +void perform_unmap_step(uc_engine *uc){ + uint64_t addr = get_aligned_addr(); + uint64_t len = get_aligned_len(); + printf("unmap(0x%lx,0x%lx); //%d\n", addr, len, step); + uc_mem_unmap(uc, addr, len); +} + +void perform_write_step(uc_engine *uc){ + char* buff[4096*4]; + memset(buff, 0, 4096*4); + uint64_t addr = get_addr(); + uint64_t len = get_len()%(4096*3); + printf("write(0x%lx,0x%lx); //%d\n", addr, len, step); + uc_mem_write(uc, addr, buff, len); +} + +void perform_read_step(uc_engine *uc){ + char* buff[4096*4]; + uint64_t addr = get_addr(); + uint64_t len = get_len()%(4096*3); + printf("read(0x%lx,0x%lx); //%d\n", addr, len, step); + uc_mem_read(uc, addr, buff, len); +} + +void perform_fuzz_step(uc_engine *uc){ + switch( ((uint32_t)rand())%2 ){ + case 0: perform_map_step(uc); break; + case 1: perform_unmap_step(uc); break; + //case 2: perform_read_step(uc); break; + //case 3: perform_write_step(uc); break; + } +} + +int main(int argc, char **argv, char **envp) +{ + uc_engine *uc; + uc_hook trace1, trace2; + uc_err err; + if(argc<2){ + printf("usage: mem_fuzz $seed\n"); + return 1; + } + int seed = atoi(argv[1]); + int i = 0; + + //don't really care about quality of randomness + srand(seed); + printf("running with seed %d\n",seed); + + // Initialize emulator in X86-32bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc); + if (err) { + printf("Failed on uc_open() with error returned: %u\n", err); + return 1; + } + + for(i = 0; i < 2048; i++){ + step++; + perform_fuzz_step(uc); + } + // fill in sections that shouldn't get touched + + if (uc_close(uc) != UC_ERR_OK) { + printf("Failed on uc_close\n"); + return 1; + } + + return 0; +} diff --git a/tests/unit/test_mem_map.c b/tests/unit/test_mem_map.c index 210d4790..6b743f0c 100644 --- a/tests/unit/test_mem_map.c +++ b/tests/unit/test_mem_map.c @@ -138,6 +138,29 @@ static void test_unmap_double_map(void **state) uc_assert_fail(uc_mem_map(uc, 0x0000, 0x1000, 0)); /* 0x1000 - 0x1000 */ } +static void test_overlap_unmap_double_map(void **state) +{ + uc_engine *uc = *state; + uc_mem_map( uc, 0x1000, 0x2000, 0); + uc_mem_map( uc, 0x1000, 0x1000, 0); + uc_mem_unmap(uc, 0x2000, 0x1000); +} + +static void test_strange_map(void **state) +{ + uc_engine *uc = *state; + uc_mem_map( uc, 0x0,0x3000,0); + uc_mem_unmap(uc, 0x1000,0x1000); + uc_mem_map( uc, 0x3000,0x1000,0); + uc_mem_map( uc, 0x4000,0x1000,0); + uc_mem_map( uc, 0x1000,0x1000,0); + uc_mem_map( uc, 0x5000,0x1000,0); + uc_mem_unmap(uc, 0x0,0x1000); +} + + + + int main(void) { #define test(x) cmocka_unit_test_setup_teardown(x, setup, teardown) const struct CMUnitTest tests[] = { @@ -147,6 +170,8 @@ int main(void) { test(test_bad_unmap), test(test_rw_across_boundaries), test(test_unmap_double_map), + test(test_overlap_unmap_double_map), + test(test_strange_map), }; #undef test return cmocka_run_group_tests(tests, NULL, NULL);