test/unit: add test_basic_blocks

This verifies that the basic block callback is working as expected.
This commit is contained in:
Jonathon Reinhart 2015-09-20 22:45:45 -04:00
parent cc1cfb9141
commit 07122809b5

View File

@ -1,6 +1,97 @@
#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++];
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;
#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_emu_start(uc, address, address+sizeof(code), 0, 0));
}
/******************************************************************************/
// callback for tracing basic blocks
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
@ -654,6 +745,8 @@ int main(void) {
cmocka_unit_test(test_x86_64_syscall),
cmocka_unit_test(test_x86_16),
cmocka_unit_test_setup_teardown(test_basic_blocks, setup32, teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}