added memory fuzzer and 2 resulting testcases
This commit is contained in:
parent
dad2baa92f
commit
1e13777c91
@ -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)
|
||||
|
||||
|
119
tests/regress/mem_fuzz.c
Normal file
119
tests/regress/mem_fuzz.c
Normal file
@ -0,0 +1,119 @@
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user