add test for multiple basic block hooks

This commit is contained in:
Ryan Hileman 2016-01-21 20:58:21 -08:00
parent 93052f6566
commit 33180b5afa
2 changed files with 114 additions and 1 deletions

View file

@ -5,7 +5,7 @@ CFLAGS += -lcmocka -lunicorn
CFLAGS += -I ../../include
ALL_TESTS = test_sanity test_x86 test_mem_map test_mem_high test_mem_map_ptr \
test_tb_x86
test_tb_x86 test_multihook
.PHONY: all
all: ${ALL_TESTS}
@ -23,6 +23,7 @@ test: ${ALL_TESTS}
./test_mem_map_ptr
./test_mem_high
./test_tb_x86
./test_multihook
test_sanity: test_sanity.c
test_x86: test_x86.c
@ -30,6 +31,7 @@ test_mem_map: test_mem_map.c
test_mem_map_ptr: test_mem_map_ptr.c
test_mem_high: test_mem_high.c
test_tb_x86: test_tb_x86.c
test_multihook: test_multihook.c
${ALL_TESTS}:
${CC} ${CFLAGS} -o $@ $^

111
tests/unit/test_multihook.c Normal file
View file

@ -0,0 +1,111 @@
#include "unicorn_test.h"
#include <inttypes.h>
#define OK(x) uc_assert_success(x)
/* Called before every test to set up a new instance */
static int setup32(void **state)
{
uc_engine *uc;
OK(uc_open(UC_ARCH_X86, UC_MODE_32, &uc));
*state = uc;
return 0;
}
/* Called after every test to clean up */
static int teardown(void **state)
{
uc_engine *uc = *state;
OK(uc_close(uc));
*state = NULL;
return 0;
}
/******************************************************************************/
struct bb {
uint64_t addr;
size_t size;
};
struct bbtest {
const struct bb *blocks;
unsigned int blocknum;
};
static void test_basic_blocks_hook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
struct bbtest *bbtest = user_data;
const struct bb *bb = &bbtest->blocks[bbtest->blocknum];
printf("block hook 1: %d == %zu\n", size, bb->size);
assert_int_equal(address, bb->addr);
assert_int_equal((size_t)size, bb->size);
}
static void test_basic_blocks_hook2(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
struct bbtest *bbtest = user_data;
const struct bb *bb = &bbtest->blocks[bbtest->blocknum++];
printf("block hook 2: %d == %zu\n", size, bb->size);
assert_int_equal(address, bb->addr);
assert_int_equal((size_t)size, bb->size);
}
static void test_basic_blocks(void **state)
{
uc_engine *uc = *state;
uc_hook trace1, trace2;
#define BASEADDR 0x1000000
uint64_t address = BASEADDR;
const uint8_t code[] = {
0x33, 0xC0, // xor eax, eax
0x90, // nop
0x90, // nop
0xEB, 0x00, // jmp $+2
0x90, // nop
0x90, // nop
0x90, // nop
};
static const struct bb blocks[] = {
{BASEADDR, 6},
{BASEADDR+ 6, 3},
};
struct bbtest bbtest = {
.blocks = blocks,
.blocknum = 0,
};
#undef BASEADDR
// map 2MB memory for this emulation
OK(uc_mem_map(uc, address, 2 * 1024 * 1024, UC_PROT_ALL));
// write machine code to be emulated to memory
OK(uc_mem_write(uc, address, code, sizeof(code)));
// trace all basic blocks
OK(uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, test_basic_blocks_hook, &bbtest, (uint64_t)1, (uint64_t)0));
OK(uc_hook_add(uc, &trace2, UC_HOOK_BLOCK, test_basic_blocks_hook2, &bbtest, (uint64_t)1, (uint64_t)0));
OK(uc_emu_start(uc, address, address+sizeof(code), 0, 0));
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(test_basic_blocks, setup32, teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}