Add clang-format and format code to qemu code style

This commit is contained in:
lazymio
2021-10-29 12:44:49 +02:00
parent 9e1443013b
commit e62b0ef255
49 changed files with 4967 additions and 4190 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,14 +3,17 @@
const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000;
static void uc_common_setup(uc_engine** uc, uc_arch arch, uc_mode mode, const char* code, uint64_t size) {
static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
const char *code, uint64_t size)
{
OK(uc_open(arch, mode, uc));
OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_arm_nop() {
uc_engine* uc;
static void test_arm_nop()
{
uc_engine *uc;
char code[] = "\x00\xf0\x20\xe3"; // nop
int r_r0 = 0x1234;
int r_r2 = 0x6789;
@ -29,8 +32,9 @@ static void test_arm_nop() {
OK(uc_close(uc));
}
static void test_arm_thumb_sub() {
uc_engine* uc;
static void test_arm_thumb_sub()
{
uc_engine *uc;
char code[] = "\x83\xb0"; // sub sp, #0xc
int r_sp = 0x1234;
@ -45,15 +49,18 @@ static void test_arm_thumb_sub() {
OK(uc_close(uc));
}
static void test_armeb_sub() {
uc_engine* uc;
char code[] = "\xe3\xa0\x00\x37\xe0\x42\x10\x03"; // mov r0, #0x37; sub r1, r2, r3
static void test_armeb_sub()
{
uc_engine *uc;
char code[] =
"\xe3\xa0\x00\x37\xe0\x42\x10\x03"; // mov r0, #0x37; sub r1, r2, r3
int r_r0 = 0x1234;
int r_r2 = 0x6789;
int r_r3 = 0x3333;
int r_r1;
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_ARM | UC_MODE_BIG_ENDIAN, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_ARM | UC_MODE_BIG_ENDIAN, code,
sizeof(code) - 1);
OK(uc_reg_write(uc, UC_ARM_REG_R0, &r_r0));
OK(uc_reg_write(uc, UC_ARM_REG_R2, &r_r2));
OK(uc_reg_write(uc, UC_ARM_REG_R3, &r_r3));
@ -73,12 +80,14 @@ static void test_armeb_sub() {
OK(uc_close(uc));
}
static void test_arm_thumbeb_sub() {
uc_engine* uc;
static void test_arm_thumbeb_sub()
{
uc_engine *uc;
char code[] = "\xb0\x83"; // sub sp, #0xc
int r_sp = 0x1234;
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_BIG_ENDIAN, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_BIG_ENDIAN, code,
sizeof(code) - 1);
OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp));
OK(uc_emu_start(uc, code_start | 1, code_start + sizeof(code) - 1, 0, 0));
@ -89,16 +98,25 @@ static void test_arm_thumbeb_sub() {
OK(uc_close(uc));
}
static void test_arm_thumb_ite_count_callback(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) {
uint64_t* count = (uint64_t*)user_data;
static void test_arm_thumb_ite_count_callback(uc_engine *uc, uint64_t address,
uint32_t size, void *user_data)
{
uint64_t *count = (uint64_t *)user_data;
(*count) += 1;
}
static void test_arm_thumb_ite() {
uc_engine* uc;
static void test_arm_thumb_ite()
{
uc_engine *uc;
uc_hook hook;
char code[] = "\x9a\x42\x15\xbf\x00\x9a\x01\x9a\x78\x23\x15\x23"; // cmp r2, r3; itete ne; ldrne r2, [sp]; ldreq r2, [sp,#4]; movne r3, #0x78; moveq r3, #0x15
char code[] =
"\x9a\x42\x15\xbf\x00\x9a\x01\x9a\x78\x23\x15\x23"; // cmp r2, r3; itete
// ne; ldrne r2,
// [sp]; ldreq r2,
// [sp,#4]; movne
// r3, #0x78; moveq
// r3, #0x15
int r_sp = 0x8000;
int r_r2 = 0;
int r_r3 = 1;
@ -116,7 +134,8 @@ static void test_arm_thumb_ite() {
r_r2 = 0x4d;
OK(uc_mem_write(uc, r_sp + 4, &r_r2, 4));
OK(uc_hook_add(uc, &hook, UC_HOOK_CODE, test_arm_thumb_ite_count_callback, &count, 1, 0));
OK(uc_hook_add(uc, &hook, UC_HOOK_CODE, test_arm_thumb_ite_count_callback,
&count, 1, 0));
// Execute four instructions at a time.
OK(uc_emu_start(uc, code_start | 1, code_start + sizeof(code) - 1, 0, 0));
@ -146,19 +165,22 @@ static void test_arm_thumb_ite() {
OK(uc_close(uc));
}
static void test_arm_m_thumb_mrs() {
uc_engine* uc;
char code[] = "\xef\xf3\x14\x80\xef\xf3\x00\x81"; // mrs r0, control; mrs r1, apsr
static void test_arm_m_thumb_mrs()
{
uc_engine *uc;
char code[] =
"\xef\xf3\x14\x80\xef\xf3\x00\x81"; // mrs r0, control; mrs r1, apsr
uint32_t r_control = 0b10;
uint32_t r_apsr = (0b10101 << 27);
uint32_t r_r0, r_r1;
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_MCLASS, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_MCLASS, code,
sizeof(code) - 1);
OK(uc_reg_write(uc, UC_ARM_REG_CONTROL, &r_control));
OK(uc_reg_write(uc, UC_ARM_REG_APSR_NZCVQ, &r_apsr));
OK(uc_emu_start(uc, code_start | 1, code_start + sizeof(code) - 1, 0, 0));
OK(uc_reg_read(uc, UC_ARM_REG_R0, &r_r0));
OK(uc_reg_read(uc, UC_ARM_REG_R1, &r_r1));
@ -168,8 +190,9 @@ static void test_arm_m_thumb_mrs() {
OK(uc_close(uc));
}
static void test_arm_m_control() {
uc_engine* uc;
static void test_arm_m_control()
{
uc_engine *uc;
int r_control, r_msp, r_psp;
OK(uc_open(UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_MCLASS, &uc));
@ -195,16 +218,19 @@ static void test_arm_m_control() {
OK(uc_reg_read(uc, UC_ARM_REG_R13, &r_msp));
TEST_CHECK(r_psp != r_msp);
TEST_CHECK(r_msp == 0x1000);
OK(uc_close(uc));
}
//
// Some notes:
// Qemu raise a special exception EXCP_EXCEPTION_EXIT to handle the EXC_RETURN. We can't
// help user handle EXC_RETURN since unicorn is designed not to handle any CPU exception.
// Qemu raise a special exception EXCP_EXCEPTION_EXIT to handle the
// EXC_RETURN. We can't help user handle EXC_RETURN since unicorn is designed
// not to handle any CPU exception.
//
static void test_arm_m_exc_return_hook_interrupt(uc_engine* uc, int intno, void* data) {
static void test_arm_m_exc_return_hook_interrupt(uc_engine *uc, int intno,
void *data)
{
int r_pc;
OK(uc_reg_read(uc, UC_ARM_REG_PC, &r_pc));
@ -213,16 +239,19 @@ static void test_arm_m_exc_return_hook_interrupt(uc_engine* uc, int intno, void*
OK(uc_emu_stop(uc));
}
static void test_arm_m_exc_return() {
uc_engine* uc;
static void test_arm_m_exc_return()
{
uc_engine *uc;
char code[] = "\x6f\xf0\x02\x00\x00\x47"; // mov r0, #0xFFFFFFFD; bx r0;
int r_ipsr;
int r_sp = 0x8000;
uc_hook hook;
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_MCLASS, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_MCLASS, code,
sizeof(code) - 1);
OK(uc_mem_map(uc, r_sp - 0x1000, 0x1000, UC_PROT_ALL));
OK(uc_hook_add(uc, &hook, UC_HOOK_INTR, test_arm_m_exc_return_hook_interrupt, NULL, 0, 0));
OK(uc_hook_add(uc, &hook, UC_HOOK_INTR,
test_arm_m_exc_return_hook_interrupt, NULL, 0, 0));
r_sp -= 0x1c;
OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp));
@ -230,20 +259,19 @@ static void test_arm_m_exc_return() {
r_ipsr = 16; // We are in whatever exception.
OK(uc_reg_write(uc, UC_ARM_REG_IPSR, &r_ipsr));
OK(uc_emu_start(uc, code_start | 1, code_start + sizeof(code) - 1, 0, 2)); // Just execute 2 instructions.
OK(uc_emu_start(uc, code_start | 1, code_start + sizeof(code) - 1, 0,
2)); // Just execute 2 instructions.
OK(uc_hook_del(uc, hook));
OK(uc_close(uc));
}
TEST_LIST = {
{ "test_arm_nop", test_arm_nop },
{ "test_arm_thumb_sub", test_arm_thumb_sub },
{ "test_armeb_sub", test_armeb_sub },
{ "test_arm_thumbeb_sub", test_arm_thumbeb_sub },
{ "test_arm_thumb_ite", test_arm_thumb_ite },
{ "test_arm_m_thumb_mrs", test_arm_m_thumb_mrs },
{ "test_arm_m_control", test_arm_m_control },
{ "test_arm_m_exc_return", test_arm_m_exc_return },
{ NULL, NULL }
};
TEST_LIST = {{"test_arm_nop", test_arm_nop},
{"test_arm_thumb_sub", test_arm_thumb_sub},
{"test_armeb_sub", test_armeb_sub},
{"test_arm_thumbeb_sub", test_arm_thumbeb_sub},
{"test_arm_thumb_ite", test_arm_thumb_ite},
{"test_arm_m_thumb_mrs", test_arm_m_thumb_mrs},
{"test_arm_m_control", test_arm_m_control},
{"test_arm_m_exc_return", test_arm_m_exc_return},
{NULL, NULL}};

View File

@ -3,52 +3,51 @@
const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000;
static void uc_common_setup(uc_engine** uc, uc_arch arch, uc_mode mode, const char* code, uint64_t size) {
static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
const char *code, uint64_t size)
{
OK(uc_open(arch, mode, uc));
OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_arm64_until() {
uc_engine *uc;
char code[] = "\x30\x00\x80\xd2\x11\x04\x80\xd2\x9c\x23\x00\x91";
static void test_arm64_until()
{
uc_engine *uc;
char code[] = "\x30\x00\x80\xd2\x11\x04\x80\xd2\x9c\x23\x00\x91";
/*
mov x16, #1
mov x17, #0x20
add x28, x28, 8
*/
/*
mov x16, #1
mov x17, #0x20
add x28, x28, 8
*/
uint64_t r_x16 = 0x12341234;
uint64_t r_x17 = 0x78907890;
uint64_t r_pc = 0x00000000;
uint64_t r_x28 = 0x12341234;
uint64_t r_x16 = 0x12341234;
uint64_t r_x17 = 0x78907890;
uint64_t r_pc = 0x00000000;
uint64_t r_x28 = 0x12341234;
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1);
// initialize machine registers
OK(uc_reg_write(uc, UC_ARM64_REG_X16, &r_x16));
OK(uc_reg_write(uc, UC_ARM64_REG_X17, &r_x17));
OK(uc_reg_write(uc, UC_ARM64_REG_X28, &r_x28));
// initialize machine registers
OK(uc_reg_write(uc, UC_ARM64_REG_X16, &r_x16));
OK(uc_reg_write(uc, UC_ARM64_REG_X17, &r_x17));
OK(uc_reg_write(uc, UC_ARM64_REG_X28, &r_x28));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 3));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 3));
OK(uc_reg_read(uc, UC_ARM64_REG_X16, &r_x16));
OK(uc_reg_read(uc, UC_ARM64_REG_X17, &r_x17));
OK(uc_reg_read(uc, UC_ARM64_REG_X28, &r_x28));
OK(uc_reg_read(uc, UC_ARM64_REG_PC, &r_pc));
OK(uc_reg_read(uc, UC_ARM64_REG_X16, &r_x16));
OK(uc_reg_read(uc, UC_ARM64_REG_X17, &r_x17));
OK(uc_reg_read(uc, UC_ARM64_REG_X28, &r_x28));
OK(uc_reg_read(uc, UC_ARM64_REG_PC, &r_pc));
TEST_CHECK(r_x16 == 0x1);
TEST_CHECK(r_x17 == 0x20);
TEST_CHECK(r_x28 == 0x1234123c);
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
TEST_CHECK(r_x16 == 0x1);
TEST_CHECK(r_x17 == 0x20);
TEST_CHECK(r_x28 == 0x1234123c);
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
OK(uc_close(uc));
OK(uc_close(uc));
}
TEST_LIST = {
{ "test_arm64_until", test_arm64_until },
{ NULL, NULL }
};
TEST_LIST = {{"test_arm64_until", test_arm64_until}, {NULL, NULL}};

View File

@ -3,6 +3,4 @@
const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000;
TEST_LIST = {
{ NULL, NULL }
};
TEST_LIST = {{NULL, NULL}};

View File

@ -1,34 +1,40 @@
#include "unicorn_test.h"
static void test_map_correct() {
uc_engine* uc;
static void test_map_correct()
{
uc_engine *uc;
OK(uc_open (UC_ARCH_X86, UC_MODE_64, &uc));
OK(uc_mem_map (uc, 0x40000, 0x1000 * 16, UC_PROT_ALL)); // [0x40000, 0x50000]
OK(uc_mem_map (uc, 0x60000, 0x1000 * 16, UC_PROT_ALL)); // [0x60000, 0x70000]
OK(uc_mem_map (uc, 0x20000, 0x1000 * 16, UC_PROT_ALL)); // [0x20000, 0x30000]
uc_assert_err(UC_ERR_MAP, uc_mem_map(uc, 0x10000, 0x2000 * 16, UC_PROT_ALL));
uc_assert_err(UC_ERR_MAP, uc_mem_map(uc, 0x25000, 0x1000 * 16, UC_PROT_ALL));
uc_assert_err(UC_ERR_MAP, uc_mem_map(uc, 0x35000, 0x1000 * 16, UC_PROT_ALL));
uc_assert_err(UC_ERR_MAP, uc_mem_map(uc, 0x45000, 0x1000 * 16, UC_PROT_ALL));
uc_assert_err(UC_ERR_MAP, uc_mem_map(uc, 0x55000, 0x2000 * 16, UC_PROT_ALL));
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
OK(uc_mem_map(uc, 0x40000, 0x1000 * 16, UC_PROT_ALL)); // [0x40000, 0x50000]
OK(uc_mem_map(uc, 0x60000, 0x1000 * 16, UC_PROT_ALL)); // [0x60000, 0x70000]
OK(uc_mem_map(uc, 0x20000, 0x1000 * 16, UC_PROT_ALL)); // [0x20000, 0x30000]
uc_assert_err(UC_ERR_MAP,
uc_mem_map(uc, 0x10000, 0x2000 * 16, UC_PROT_ALL));
uc_assert_err(UC_ERR_MAP,
uc_mem_map(uc, 0x25000, 0x1000 * 16, UC_PROT_ALL));
uc_assert_err(UC_ERR_MAP,
uc_mem_map(uc, 0x35000, 0x1000 * 16, UC_PROT_ALL));
uc_assert_err(UC_ERR_MAP,
uc_mem_map(uc, 0x45000, 0x1000 * 16, UC_PROT_ALL));
uc_assert_err(UC_ERR_MAP,
uc_mem_map(uc, 0x55000, 0x2000 * 16, UC_PROT_ALL));
OK(uc_mem_map(uc, 0x35000, 0x5000, UC_PROT_ALL));
OK(uc_mem_map(uc, 0x50000, 0x5000, UC_PROT_ALL));
OK(uc_close(uc));
}
static void test_map_wrapping() {
uc_engine* uc;
static void test_map_wrapping()
{
uc_engine *uc;
OK(uc_open (UC_ARCH_X86, UC_MODE_64, &uc));
uc_assert_err(UC_ERR_ARG, uc_mem_map (uc, (~0ll - 0x4000) & ~0xfff, 0x8000, UC_PROT_ALL));
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
uc_assert_err(UC_ERR_ARG, uc_mem_map(uc, (~0ll - 0x4000) & ~0xfff, 0x8000,
UC_PROT_ALL));
OK(uc_close(uc));
}
TEST_LIST = {
{ "test_map_correct", test_map_correct },
{ "test_map_wrapping", test_map_wrapping },
{ NULL, NULL }
};
TEST_LIST = {{"test_map_correct", test_map_correct},
{"test_map_wrapping", test_map_wrapping},
{NULL, NULL}};

View File

@ -3,18 +3,22 @@
const uint64_t code_start = 0x10000000;
const uint64_t code_len = 0x4000;
static void uc_common_setup(uc_engine** uc, uc_arch arch, uc_mode mode, const char* code, uint64_t size) {
static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
const char *code, uint64_t size)
{
OK(uc_open(arch, mode, uc));
OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_mips_el_ori() {
uc_engine* uc;
static void test_mips_el_ori()
{
uc_engine *uc;
char code[] = "\x56\x34\x21\x34"; // ori $at, $at, 0x3456;
int r_r1 = 0x6789;
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code,
sizeof(code) - 1);
OK(uc_reg_write(uc, UC_MIPS_REG_1, &r_r1));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
@ -26,12 +30,14 @@ static void test_mips_el_ori() {
OK(uc_close(uc));
}
static void test_mips_eb_ori() {
uc_engine* uc;
static void test_mips_eb_ori()
{
uc_engine *uc;
char code[] = "\x34\x21\x34\x56"; // ori $at, $at, 0x3456;
int r_r1 = 0x6789;
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code,
sizeof(code) - 1);
OK(uc_reg_write(uc, UC_MIPS_REG_1, &r_r1));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
@ -43,37 +49,43 @@ static void test_mips_eb_ori() {
OK(uc_close(uc));
}
static void test_mips_stop_at_branch() {
uc_engine* uc;
char code[] = "\x02\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00"; // j 0x8; nop;
static void test_mips_stop_at_branch()
{
uc_engine *uc;
char code[] =
"\x02\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00"; // j 0x8; nop;
int r_pc = 0x0;
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code,
sizeof(code) - 1);
// Execute one instruction with branch delay slot.
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 1));
OK(uc_reg_read(uc, UC_MIPS_REG_PC, &r_pc));
// Even if we just execute one instruction, the instruction in the
// Even if we just execute one instruction, the instruction in the
// delay slot would also be executed.
TEST_CHECK(r_pc == code_start + 0x8);
OK(uc_close(uc));
}
static void test_mips_stop_at_delay_slot() {
uc_engine* uc;
char code[] = "\x02\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00"; // j 0x8; nop;
static void test_mips_stop_at_delay_slot()
{
uc_engine *uc;
char code[] =
"\x02\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00"; // j 0x8; nop;
int r_pc = 0x0;
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code,
sizeof(code) - 1);
// Stop at the delay slot by design.
OK(uc_emu_start(uc, code_start, code_start + 4, 0, 0));
OK(uc_reg_read(uc, UC_MIPS_REG_PC, &r_pc));
// The branch instruction isn't committed and the PC is not updated.
// Users is responsible to restart emulation at the branch instruction.
TEST_CHECK(r_pc == code_start);
@ -81,12 +93,14 @@ static void test_mips_stop_at_delay_slot() {
OK(uc_close(uc));
}
static void test_mips_lwx_exception_issue_1314() {
uc_engine* uc;
static void test_mips_lwx_exception_issue_1314()
{
uc_engine *uc;
char code[] = "\x0a\xc8\x79\x7e"; // lwx $t9, $t9($s3)
int reg;
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code,
sizeof(code) - 1);
OK(uc_mem_map(uc, 0x10000, 0x4000, UC_PROT_ALL));
// Enable DSP
@ -113,10 +127,9 @@ static void test_mips_lwx_exception_issue_1314() {
}
TEST_LIST = {
{ "test_mips_stop_at_branch", test_mips_stop_at_branch },
{ "test_mips_stop_at_delay_slot", test_mips_stop_at_delay_slot},
{ "test_mips_el_ori", test_mips_el_ori},
{ "test_mips_eb_ori", test_mips_eb_ori},
{ "test_mips_lwx_exception_issue_1314", test_mips_lwx_exception_issue_1314},
{ NULL, NULL }
};
{"test_mips_stop_at_branch", test_mips_stop_at_branch},
{"test_mips_stop_at_delay_slot", test_mips_stop_at_delay_slot},
{"test_mips_el_ori", test_mips_el_ori},
{"test_mips_eb_ori", test_mips_eb_ori},
{"test_mips_lwx_exception_issue_1314", test_mips_lwx_exception_issue_1314},
{NULL, NULL}};

View File

@ -3,18 +3,22 @@
const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000;
static void uc_common_setup(uc_engine** uc, uc_arch arch, uc_mode mode, const char* code, uint64_t size) {
static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
const char *code, uint64_t size)
{
OK(uc_open(arch, mode, uc));
OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_ppc32_add() {
uc_engine* uc;
static void test_ppc32_add()
{
uc_engine *uc;
char code[] = "\x7f\x46\x1a\x14"; // ADD 26, 6, 3
int reg;
uc_common_setup(&uc, UC_ARCH_PPC, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_PPC, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code,
sizeof(code) - 1);
reg = 42;
OK(uc_reg_write(uc, UC_PPC_REG_3, &reg));
@ -30,7 +34,4 @@ static void test_ppc32_add() {
OK(uc_close(uc));
}
TEST_LIST = {
{ "test_ppc32_add", test_ppc32_add },
{ NULL, NULL}
};
TEST_LIST = {{"test_ppc32_add", test_ppc32_add}, {NULL, NULL}};

View File

@ -3,19 +3,23 @@
const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000;
static void uc_common_setup(uc_engine** uc, uc_arch arch, uc_mode mode, const char* code, uint64_t size) {
static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
const char *code, uint64_t size)
{
OK(uc_open(arch, mode, uc));
OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_riscv32_nop() {
uc_engine* uc;
static void test_riscv32_nop()
{
uc_engine *uc;
char code[] = "\x13\x00\x00\x00"; // nop
uint32_t r_t0 = 0x1234;
uint32_t r_t1 = 0x5678;
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV32, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV32, code,
sizeof(code) - 1);
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
@ -29,13 +33,15 @@ static void test_riscv32_nop() {
OK(uc_close(uc));
}
static void test_riscv64_nop() {
uc_engine* uc;
static void test_riscv64_nop()
{
uc_engine *uc;
char code[] = "\x13\x00\x00\x00"; // nop
uint64_t r_t0 = 0x1234;
uint64_t r_t1 = 0x5678;
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code,
sizeof(code) - 1);
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
@ -49,167 +55,172 @@ static void test_riscv64_nop() {
OK(uc_close(uc));
}
static void test_riscv32_until_pc_update() {
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
static void test_riscv32_until_pc_update()
{
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
/*
addi t0, zero, 1
addi t1, zero, 0x20
addi sp, sp, 8
*/
/*
addi t0, zero, 1
addi t1, zero, 0x20
addi sp, sp, 8
*/
uint32_t r_t0 = 0x1234;
uint32_t r_t1 = 0x7890;
uint32_t r_pc = 0x0000;
uint32_t r_sp = 0x1234;
uint32_t r_t0 = 0x1234;
uint32_t r_t1 = 0x7890;
uint32_t r_pc = 0x0000;
uint32_t r_sp = 0x1234;
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV32, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV32, code,
sizeof(code) - 1);
// initialize machine registers
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_write(uc, UC_RISCV_REG_SP, &r_sp));
// initialize machine registers
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_write(uc, UC_RISCV_REG_SP, &r_sp));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_read(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_read(uc, UC_RISCV_REG_SP, &r_sp));
OK(uc_reg_read(uc, UC_RISCV_REG_PC, &r_pc));
OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_read(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_read(uc, UC_RISCV_REG_SP, &r_sp));
OK(uc_reg_read(uc, UC_RISCV_REG_PC, &r_pc));
TEST_CHECK(r_t0 == 0x1);
TEST_CHECK(r_t1 == 0x20);
TEST_CHECK(r_sp == 0x123c);
TEST_CHECK(r_t0 == 0x1);
TEST_CHECK(r_t1 == 0x20);
TEST_CHECK(r_sp == 0x123c);
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
OK(uc_close(uc));
OK(uc_close(uc));
}
static void test_riscv64_until_pc_update() {
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
static void test_riscv64_until_pc_update()
{
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
/*
addi t0, zero, 1
addi t1, zero, 0x20
addi sp, sp, 8
*/
/*
addi t0, zero, 1
addi t1, zero, 0x20
addi sp, sp, 8
*/
uint64_t r_t0 = 0x1234;
uint64_t r_t1 = 0x7890;
uint64_t r_pc = 0x0000;
uint64_t r_sp = 0x1234;
uint64_t r_t0 = 0x1234;
uint64_t r_t1 = 0x7890;
uint64_t r_pc = 0x0000;
uint64_t r_sp = 0x1234;
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code,
sizeof(code) - 1);
// initialize machine registers
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_write(uc, UC_RISCV_REG_SP, &r_sp));
// initialize machine registers
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_write(uc, UC_RISCV_REG_SP, &r_sp));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_read(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_read(uc, UC_RISCV_REG_SP, &r_sp));
OK(uc_reg_read(uc, UC_RISCV_REG_PC, &r_pc));
OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_read(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_read(uc, UC_RISCV_REG_SP, &r_sp));
OK(uc_reg_read(uc, UC_RISCV_REG_PC, &r_pc));
TEST_CHECK(r_t0 == 0x1);
TEST_CHECK(r_t1 == 0x20);
TEST_CHECK(r_sp == 0x123c);
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
TEST_CHECK(r_t0 == 0x1);
TEST_CHECK(r_t1 == 0x20);
TEST_CHECK(r_sp == 0x123c);
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
OK(uc_close(uc));
OK(uc_close(uc));
}
static void test_riscv32_3steps_pc_update() {
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
static void test_riscv32_3steps_pc_update()
{
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
/*
addi t0, zero, 1
addi t1, zero, 0x20
addi sp, sp, 8
*/
/*
addi t0, zero, 1
addi t1, zero, 0x20
addi sp, sp, 8
*/
uint32_t r_t0 = 0x1234;
uint32_t r_t1 = 0x7890;
uint32_t r_pc = 0x0000;
uint32_t r_sp = 0x1234;
uint32_t r_t0 = 0x1234;
uint32_t r_t1 = 0x7890;
uint32_t r_pc = 0x0000;
uint32_t r_sp = 0x1234;
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV32, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV32, code,
sizeof(code) - 1);
// initialize machine registers
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_write(uc, UC_RISCV_REG_SP, &r_sp));
// initialize machine registers
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_write(uc, UC_RISCV_REG_SP, &r_sp));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, -1, 0, 3));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, -1, 0, 3));
OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_read(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_read(uc, UC_RISCV_REG_SP, &r_sp));
OK(uc_reg_read(uc, UC_RISCV_REG_PC, &r_pc));
OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_read(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_read(uc, UC_RISCV_REG_SP, &r_sp));
OK(uc_reg_read(uc, UC_RISCV_REG_PC, &r_pc));
TEST_CHECK(r_t0 == 0x1);
TEST_CHECK(r_t1 == 0x20);
TEST_CHECK(r_sp == 0x123c);
TEST_CHECK(r_t0 == 0x1);
TEST_CHECK(r_t1 == 0x20);
TEST_CHECK(r_sp == 0x123c);
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
OK(uc_close(uc));
OK(uc_close(uc));
}
static void test_riscv64_3steps_pc_update() {
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
static void test_riscv64_3steps_pc_update()
{
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
/*
addi t0, zero, 1
addi t1, zero, 0x20
addi sp, sp, 8
*/
/*
addi t0, zero, 1
addi t1, zero, 0x20
addi sp, sp, 8
*/
uint64_t r_t0 = 0x1234;
uint64_t r_t1 = 0x7890;
uint64_t r_pc = 0x0000;
uint64_t r_sp = 0x1234;
uint64_t r_t0 = 0x1234;
uint64_t r_t1 = 0x7890;
uint64_t r_pc = 0x0000;
uint64_t r_sp = 0x1234;
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code, sizeof(code) - 1);
uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code,
sizeof(code) - 1);
// initialize machine registers
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_write(uc, UC_RISCV_REG_SP, &r_sp));
// initialize machine registers
OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_write(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_write(uc, UC_RISCV_REG_SP, &r_sp));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, -1, 0, 3));
// emulate the three instructions
OK(uc_emu_start(uc, code_start, -1, 0, 3));
OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_read(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_read(uc, UC_RISCV_REG_SP, &r_sp));
OK(uc_reg_read(uc, UC_RISCV_REG_PC, &r_pc));
OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0));
OK(uc_reg_read(uc, UC_RISCV_REG_T1, &r_t1));
OK(uc_reg_read(uc, UC_RISCV_REG_SP, &r_sp));
OK(uc_reg_read(uc, UC_RISCV_REG_PC, &r_pc));
TEST_CHECK(r_t0 == 0x1);
TEST_CHECK(r_t1 == 0x20);
TEST_CHECK(r_sp == 0x123c);
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
TEST_CHECK(r_t0 == 0x1);
TEST_CHECK(r_t1 == 0x20);
TEST_CHECK(r_sp == 0x123c);
TEST_CHECK(r_pc == (code_start + sizeof(code) - 1));
OK(uc_close(uc));
OK(uc_close(uc));
}
TEST_LIST = {
{ "test_riscv32_nop", test_riscv32_nop },
{ "test_riscv64_nop", test_riscv64_nop },
{ "test_riscv32_3steps_pc_update", test_riscv32_3steps_pc_update },
{ "test_riscv64_3steps_pc_update", test_riscv64_3steps_pc_update },
{ "test_riscv32_until_pc_update", test_riscv32_until_pc_update },
{ "test_riscv64_until_pc_update", test_riscv64_until_pc_update },
{ NULL, NULL }
};
TEST_LIST = {{"test_riscv32_nop", test_riscv32_nop},
{"test_riscv64_nop", test_riscv64_nop},
{"test_riscv32_3steps_pc_update", test_riscv32_3steps_pc_update},
{"test_riscv64_3steps_pc_update", test_riscv64_3steps_pc_update},
{"test_riscv32_until_pc_update", test_riscv32_until_pc_update},
{"test_riscv64_until_pc_update", test_riscv64_until_pc_update},
{NULL, NULL}};

View File

@ -3,6 +3,4 @@
const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000;
TEST_LIST = {
{ NULL, NULL }
};
TEST_LIST = {{NULL, NULL}};

View File

@ -3,7 +3,9 @@
const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000;
static void uc_common_setup(uc_engine** uc, uc_arch arch, uc_mode mode, const char* code, uint64_t size) {
static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
const char *code, uint64_t size)
{
OK(uc_open(arch, mode, uc));
OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
OK(uc_mem_write(*uc, code_start, code, size));
@ -14,22 +16,26 @@ typedef struct _INSN_IN_RESULT {
int size;
} INSN_IN_RESULT;
static void test_x86_in_callback(uc_engine* uc, uint32_t port, int size, void* user_data) {
INSN_IN_RESULT* result = (INSN_IN_RESULT*)user_data;
static void test_x86_in_callback(uc_engine *uc, uint32_t port, int size,
void *user_data)
{
INSN_IN_RESULT *result = (INSN_IN_RESULT *)user_data;
result->port = port;
result->size = size;
}
static void test_x86_in() {
uc_engine* uc;
static void test_x86_in()
{
uc_engine *uc;
uc_hook hook;
char code[] = "\xe5\x10"; // IN eax, 0x10
INSN_IN_RESULT result;
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
OK(uc_hook_add(uc, &hook, UC_HOOK_INSN, test_x86_in_callback, &result, 1, 0, UC_X86_INS_IN));
OK(uc_hook_add(uc, &hook, UC_HOOK_INSN, test_x86_in_callback, &result, 1, 0,
UC_X86_INS_IN));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
TEST_CHECK(result.port == 0x10);
TEST_CHECK(result.size == 4);
@ -44,23 +50,27 @@ typedef struct _INSN_OUT_RESULT {
uint32_t value;
} INSN_OUT_RESULT;
static void test_x86_out_callback(uc_engine* uc, uint32_t port, int size, uint32_t value, void* user_data) {
INSN_OUT_RESULT* result = (INSN_OUT_RESULT*)user_data;
static void test_x86_out_callback(uc_engine *uc, uint32_t port, int size,
uint32_t value, void *user_data)
{
INSN_OUT_RESULT *result = (INSN_OUT_RESULT *)user_data;
result->port = port;
result->size = size;
result->value = value;
}
static void test_x86_out() {
uc_engine* uc;
static void test_x86_out()
{
uc_engine *uc;
uc_hook hook;
char code[] = "\xb0\x32\xe6\x46"; // MOV al, 0x32; OUT 0x46, al;
INSN_OUT_RESULT result;
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
OK(uc_hook_add(uc, &hook, UC_HOOK_INSN, test_x86_out_callback, &result, 1, 0, UC_X86_INS_OUT));
OK(uc_hook_add(uc, &hook, UC_HOOK_INSN, test_x86_out_callback, &result, 1,
0, UC_X86_INS_OUT));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
TEST_CHECK(result.port == 0x46);
TEST_CHECK(result.size == 1);
@ -82,8 +92,11 @@ typedef struct _MEM_HOOK_RESULTS {
MEM_HOOK_RESULT results[16];
} MEM_HOOK_RESULTS;
static bool test_x86_mem_hook_all_callback(uc_engine* uc, uc_mem_type type, uint64_t address, int size, uint64_t value, void* user_data) {
MEM_HOOK_RESULTS* r = (MEM_HOOK_RESULTS*)user_data;
static bool test_x86_mem_hook_all_callback(uc_engine *uc, uc_mem_type type,
uint64_t address, int size,
uint64_t value, void *user_data)
{
MEM_HOOK_RESULTS *r = (MEM_HOOK_RESULTS *)user_data;
uint64_t count = r->count;
if (count >= 16) {
@ -103,27 +116,28 @@ static bool test_x86_mem_hook_all_callback(uc_engine* uc, uc_mem_type type, uint
return true;
}
static void test_x86_mem_hook_all() {
uc_engine* uc;
static void test_x86_mem_hook_all()
{
uc_engine *uc;
uc_hook hook;
// mov eax, 0xdeadbeef;
// mov [0x8000], eax;
// mov eax, [0x10000];
char code[] = "\xb8\xef\xbe\xad\xde\xa3\x00\x80\x00\x00\xa1\x00\x00\x01\x00";
MEM_HOOK_RESULTS r = { 0 };
MEM_HOOK_RESULT expects[3] = {
{UC_MEM_WRITE, 0x8000, 4, 0xdeadbeef},
{UC_MEM_READ_UNMAPPED, 0x10000, 4, 0},
{UC_MEM_READ, 0x10000, 4, 0}
};
char code[] =
"\xb8\xef\xbe\xad\xde\xa3\x00\x80\x00\x00\xa1\x00\x00\x01\x00";
MEM_HOOK_RESULTS r = {0};
MEM_HOOK_RESULT expects[3] = {{UC_MEM_WRITE, 0x8000, 4, 0xdeadbeef},
{UC_MEM_READ_UNMAPPED, 0x10000, 4, 0},
{UC_MEM_READ, 0x10000, 4, 0}};
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
OK(uc_mem_map(uc, 0x8000, 0x1000, UC_PROT_ALL));
OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_VALID | UC_HOOK_MEM_INVALID, test_x86_mem_hook_all_callback, &r, 1, 0));
OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_VALID | UC_HOOK_MEM_INVALID,
test_x86_mem_hook_all_callback, &r, 1, 0));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
TEST_CHECK(r.count == 3);
for (int i = 0; i < r.count; i ++) {
for (int i = 0; i < r.count; i++) {
TEST_CHECK(expects[i].type == r.results[i].type);
TEST_CHECK(expects[i].address == r.results[i].address);
TEST_CHECK(expects[i].size == r.results[i].size);
@ -134,9 +148,11 @@ static void test_x86_mem_hook_all() {
OK(uc_close(uc));
}
static void test_x86_inc_dec_pxor() {
uc_engine* uc;
char code[] = "\x41\x4a\x66\x0f\xef\xc1"; // INC ecx; DEC edx; PXOR xmm0, xmm1
static void test_x86_inc_dec_pxor()
{
uc_engine *uc;
char code[] =
"\x41\x4a\x66\x0f\xef\xc1"; // INC ecx; DEC edx; PXOR xmm0, xmm1
int r_ecx = 0x1234;
int r_edx = 0x7890;
uint64_t r_xmm0[2] = {0x08090a0b0c0d0e0f, 0x0001020304050607};
@ -162,9 +178,11 @@ static void test_x86_inc_dec_pxor() {
OK(uc_close(uc));
}
static void test_x86_relative_jump() {
uc_engine* uc;
char code[] = "\xeb\x02\x90\x90\x90\x90\x90\x90"; // jmp 4; nop; nop; nop; nop; nop; nop
static void test_x86_relative_jump()
{
uc_engine *uc;
char code[] = "\xeb\x02\x90\x90\x90\x90\x90\x90"; // jmp 4; nop; nop; nop;
// nop; nop; nop
int r_eip;
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
@ -178,8 +196,9 @@ static void test_x86_relative_jump() {
OK(uc_close(uc));
}
static void test_x86_loop() {
uc_engine* uc;
static void test_x86_loop()
{
uc_engine *uc;
char code[] = "\x41\x4a\xeb\xfe"; // inc ecx; dec edx; jmp $;
int r_ecx = 0x1234;
int r_edx = 0x7890;
@ -188,7 +207,8 @@ static void test_x86_loop() {
OK(uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx));
OK(uc_reg_write(uc, UC_X86_REG_EDX, &r_edx));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 1 * 1000000, 0));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 1 * 1000000,
0));
OK(uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx));
OK(uc_reg_read(uc, UC_X86_REG_EDX, &r_edx));
@ -199,40 +219,50 @@ static void test_x86_loop() {
OK(uc_close(uc));
}
static void test_x86_invalid_mem_read() {
uc_engine* uc;
static void test_x86_invalid_mem_read()
{
uc_engine *uc;
char code[] = "\x8b\x0d\xaa\xaa\xaa\xaa"; // mov ecx, [0xAAAAAAAA]
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
uc_assert_err(UC_ERR_READ_UNMAPPED, uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
uc_assert_err(
UC_ERR_READ_UNMAPPED,
uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
OK(uc_close(uc));
}
static void test_x86_invalid_mem_write() {
uc_engine* uc;
static void test_x86_invalid_mem_write()
{
uc_engine *uc;
char code[] = "\x89\x0d\xaa\xaa\xaa\xaa"; // mov ecx, [0xAAAAAAAA]
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
uc_assert_err(UC_ERR_WRITE_UNMAPPED, uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
uc_assert_err(
UC_ERR_WRITE_UNMAPPED,
uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
OK(uc_close(uc));
}
static void test_x86_invalid_jump() {
uc_engine* uc;
static void test_x86_invalid_jump()
{
uc_engine *uc;
char code[] = "\xe9\xe9\xee\xee\xee"; // jmp 0xEEEEEEEE
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
uc_assert_err(UC_ERR_FETCH_UNMAPPED, uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
uc_assert_err(
UC_ERR_FETCH_UNMAPPED,
uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
OK(uc_close(uc));
}
static void test_x86_64_syscall_callback(uc_engine* uc, void* user_data) {
static void test_x86_64_syscall_callback(uc_engine *uc, void *user_data)
{
uint64_t rax;
OK(uc_reg_read(uc, UC_X86_REG_RAX, &rax));
@ -240,15 +270,17 @@ static void test_x86_64_syscall_callback(uc_engine* uc, void* user_data) {
TEST_CHECK(rax == 0x100);
}
static void test_x86_64_syscall() {
uc_engine* uc;
static void test_x86_64_syscall()
{
uc_engine *uc;
uc_hook hook;
char code[] = "\x0f\x05"; // syscall
uint64_t r_rax = 0x100;
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1);
OK(uc_reg_write(uc, UC_X86_REG_RAX, &r_rax));
OK(uc_hook_add(uc, &hook, UC_HOOK_INSN, test_x86_64_syscall_callback, NULL, 1, 0, UC_X86_INS_SYSCALL));
OK(uc_hook_add(uc, &hook, UC_HOOK_INSN, test_x86_64_syscall_callback, NULL,
1, 0, UC_X86_INS_SYSCALL));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
@ -256,8 +288,9 @@ static void test_x86_64_syscall() {
OK(uc_close(uc));
}
static void test_x86_16_add() {
uc_engine* uc;
static void test_x86_16_add()
{
uc_engine *uc;
char code[] = "\x00\x00"; // add byte ptr [bx + si], al
uint16_t r_ax = 7;
uint16_t r_bx = 5;
@ -277,9 +310,10 @@ static void test_x86_16_add() {
OK(uc_close(uc));
}
static void test_x86_reg_save() {
uc_engine* uc;
uc_context* ctx;
static void test_x86_reg_save()
{
uc_engine *uc;
uc_context *ctx;
char code[] = "\x40"; // inc eax
int r_eax = 1;
@ -289,7 +323,7 @@ static void test_x86_reg_save() {
OK(uc_context_alloc(uc, &ctx));
OK(uc_context_save(uc, ctx));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
OK(uc_reg_read(uc, UC_X86_REG_EAX, &r_eax));
TEST_CHECK(r_eax == 2);
@ -302,27 +336,38 @@ static void test_x86_reg_save() {
OK(uc_close(uc));
}
static bool test_x86_invalid_mem_read_stop_in_cb_callback(uc_engine* uc, uc_mem_type type, uint64_t address, int size, uint64_t value, void* user_data) {
// False indicates that we fail to handle this ERROR and let the emulation stop.
static bool
test_x86_invalid_mem_read_stop_in_cb_callback(uc_engine *uc, uc_mem_type type,
uint64_t address, int size,
uint64_t value, void *user_data)
{
// False indicates that we fail to handle this ERROR and let the emulation
// stop.
//
// Note that the memory must be mapped properly if we return true! Check test_x86_mem_hook_all for example.
// Note that the memory must be mapped properly if we return true! Check
// test_x86_mem_hook_all for example.
return false;
}
static void test_x86_invalid_mem_read_stop_in_cb() {
uc_engine* uc;
static void test_x86_invalid_mem_read_stop_in_cb()
{
uc_engine *uc;
uc_hook hook;
char code[] = "\x40\x8b\x1d\x00\x00\x10\x00\x42"; // inc eax; mov ebx, [0x100000]; inc edx
char code[] = "\x40\x8b\x1d\x00\x00\x10\x00\x42"; // inc eax; mov ebx,
// [0x100000]; inc edx
int r_eax = 0x1234;
int r_edx = 0x5678;
int r_eip = 0;
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_READ, test_x86_invalid_mem_read_stop_in_cb_callback, NULL, 1, 0));
OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_READ,
test_x86_invalid_mem_read_stop_in_cb_callback, NULL, 1, 0));
OK(uc_reg_write(uc, UC_X86_REG_EAX, &r_eax));
OK(uc_reg_write(uc, UC_X86_REG_EDX, &r_edx));
uc_assert_err(UC_ERR_READ_UNMAPPED, uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
uc_assert_err(
UC_ERR_READ_UNMAPPED,
uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
// The state of Unicorn should be correct at this time.
OK(uc_reg_read(uc, UC_X86_REG_EIP, &r_eip));
@ -336,8 +381,9 @@ static void test_x86_invalid_mem_read_stop_in_cb() {
OK(uc_close(uc));
}
static void test_x86_x87_fnstenv_callback(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) {
static void test_x86_x87_fnstenv_callback(uc_engine *uc, uint64_t address,
uint32_t size, void *user_data)
{
uint32_t r_eip;
uint32_t r_eax;
uint32_t fnstenv[7];
@ -345,8 +391,8 @@ static void test_x86_x87_fnstenv_callback(uc_engine* uc, uint64_t address, uint3
if (address == code_start + 4) { // The first fnstenv executed
// Save the address of the fld.
OK(uc_reg_read(uc, UC_X86_REG_EIP, &r_eip));
*((uint32_t*)user_data) = r_eip;
*((uint32_t *)user_data) = r_eip;
OK(uc_reg_read(uc, UC_X86_REG_EAX, &r_eax));
OK(uc_mem_read(uc, r_eax, fnstenv, sizeof(fnstenv)));
// Don't update FCS:FIP for fnop.
@ -354,10 +400,13 @@ static void test_x86_x87_fnstenv_callback(uc_engine* uc, uint64_t address, uint3
}
}
static void test_x86_x87_fnstenv() {
uc_engine* uc;
static void test_x86_x87_fnstenv()
{
uc_engine *uc;
uc_hook hook;
char code[] = "\xd9\xd0\xd9\x30\xd9\x00\xd9\x30"; // fnop;fnstenv [eax];fld dword ptr [eax];fnstenv [eax]
char code[] =
"\xd9\xd0\xd9\x30\xd9\x00\xd9\x30"; // fnop;fnstenv [eax];fld dword ptr
// [eax];fnstenv [eax]
uint32_t base = code_start + 3 * code_len;
uint32_t last_eip;
uint32_t fnstenv[7];
@ -366,25 +415,31 @@ static void test_x86_x87_fnstenv() {
OK(uc_mem_map(uc, base, code_len, UC_PROT_ALL));
OK(uc_reg_write(uc, UC_X86_REG_EAX, &base));
OK(uc_hook_add(uc, &hook, UC_HOOK_CODE, test_x86_x87_fnstenv_callback, &last_eip, 1, 0));
OK(uc_hook_add(uc, &hook, UC_HOOK_CODE, test_x86_x87_fnstenv_callback,
&last_eip, 1, 0));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
OK(uc_mem_read(uc, base, fnstenv, sizeof(fnstenv)));
//But update FCS:FIP for fld.
// But update FCS:FIP for fld.
TEST_CHECK(fnstenv[3] == last_eip);
OK(uc_close(uc));
}
static uint64_t test_x86_mmio_read_callback(uc_engine* uc, uint64_t offset, unsigned size, void* user_data) {
static uint64_t test_x86_mmio_read_callback(uc_engine *uc, uint64_t offset,
unsigned size, void *user_data)
{
TEST_CHECK(offset == 4);
TEST_CHECK(size == 4);
return 0x19260817;
}
static void test_x86_mmio_write_callback(uc_engine* uc, uint64_t offset, unsigned size, uint64_t value, void* user_data) {
static void test_x86_mmio_write_callback(uc_engine *uc, uint64_t offset,
unsigned size, uint64_t value,
void *user_data)
{
TEST_CHECK(offset == 4);
TEST_CHECK(size == 4);
TEST_CHECK(value == 0xdeadbeef);
@ -392,14 +447,19 @@ static void test_x86_mmio_write_callback(uc_engine* uc, uint64_t offset, unsigne
return;
}
static void test_x86_mmio() {
uc_engine* uc;
static void test_x86_mmio()
{
uc_engine *uc;
int r_ecx = 0xdeadbeef;
char code[] = "\x89\x0d\x04\x00\x02\x00\x8b\x0d\x04\x00\x02\x00"; // mov [0x20004], ecx; mov ecx, [0x20004]
char code[] =
"\x89\x0d\x04\x00\x02\x00\x8b\x0d\x04\x00\x02\x00"; // mov [0x20004],
// ecx; mov ecx,
// [0x20004]
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
OK(uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx));
OK(uc_mmio_map(uc, 0x20000, 0x1000, test_x86_mmio_read_callback, NULL, test_x86_mmio_write_callback, NULL));
OK(uc_mmio_map(uc, 0x20000, 0x1000, test_x86_mmio_read_callback, NULL,
test_x86_mmio_write_callback, NULL));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
@ -410,7 +470,10 @@ static void test_x86_mmio() {
OK(uc_close(uc));
}
static bool test_x86_missing_code_callback(uc_engine* uc, uc_mem_type type, uint64_t address, int size, uint64_t value, void* user_data) {
static bool test_x86_missing_code_callback(uc_engine *uc, uc_mem_type type,
uint64_t address, int size,
uint64_t value, void *user_data)
{
char code[] = "\x41\x4a"; // inc ecx; dec edx;
uint64_t algined_address = address & 0xFFFFFFFFFFFFF000ULL;
int aligned_size = ((int)(size / 0x1000) + 1) * 0x1000;
@ -422,8 +485,9 @@ static bool test_x86_missing_code_callback(uc_engine* uc, uc_mem_type type, uint
return true;
}
static void test_x86_missing_code() {
uc_engine* uc;
static void test_x86_missing_code()
{
uc_engine *uc;
uc_hook hook;
int r_ecx = 0x1234;
int r_edx = 0x7890;
@ -432,7 +496,8 @@ static void test_x86_missing_code() {
OK(uc_open(UC_ARCH_X86, UC_MODE_32, &uc));
OK(uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx));
OK(uc_reg_write(uc, UC_X86_REG_EDX, &r_edx));
OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_UNMAPPED, test_x86_missing_code_callback, NULL, 1, 0));
OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_UNMAPPED,
test_x86_missing_code_callback, NULL, 1, 0));
OK(uc_emu_start(uc, code_start, code_start + 2, 0, 0));
@ -445,13 +510,14 @@ static void test_x86_missing_code() {
OK(uc_close(uc));
}
static void test_x86_smc_xor() {
uc_engine* uc;
static void test_x86_smc_xor()
{
uc_engine *uc;
/*
* 0x1000 xor dword ptr [edi+0x3], eax ; edi=0x1000, eax=0xbc4177e6
* 0x1003 dw 0x3ea98b13
*/
char code[] = "\x31\x47\x03\x13\x8b\xa9\x3e";
* 0x1000 xor dword ptr [edi+0x3], eax ; edi=0x1000, eax=0xbc4177e6
* 0x1003 dw 0x3ea98b13
*/
char code[] = "\x31\x47\x03\x13\x8b\xa9\x3e";
int r_edi = code_start;
int r_eax = 0xbc4177e6;
uint32_t result;
@ -469,14 +535,23 @@ static void test_x86_smc_xor() {
OK(uc_close(uc));
}
static uint64_t test_x86_mmio_uc_mem_rw_read_callback(uc_engine* uc, uint64_t offset, unsigned size, void* user_data) {
static uint64_t test_x86_mmio_uc_mem_rw_read_callback(uc_engine *uc,
uint64_t offset,
unsigned size,
void *user_data)
{
TEST_CHECK(offset == 8);
TEST_CHECK(size == 4);
return 0x19260817;
}
static void test_x86_mmio_uc_mem_rw_write_callback(uc_engine* uc, uint64_t offset, unsigned size, uint64_t value, void* user_data) {
static void test_x86_mmio_uc_mem_rw_write_callback(uc_engine *uc,
uint64_t offset,
unsigned size,
uint64_t value,
void *user_data)
{
TEST_CHECK(offset == 4);
TEST_CHECK(size == 4);
TEST_CHECK(value == 0xdeadbeef);
@ -484,39 +559,40 @@ static void test_x86_mmio_uc_mem_rw_write_callback(uc_engine* uc, uint64_t offse
return;
}
static void test_x86_mmio_uc_mem_rw() {
uc_engine* uc;
static void test_x86_mmio_uc_mem_rw()
{
uc_engine *uc;
int data = 0xdeadbeef;
OK(uc_open(UC_ARCH_X86, UC_MODE_32, &uc));
OK(uc_mmio_map(uc,
0x20000, 0x1000,
test_x86_mmio_uc_mem_rw_read_callback, NULL,
test_x86_mmio_uc_mem_rw_write_callback, NULL));
OK(uc_mmio_map(uc, 0x20000, 0x1000, test_x86_mmio_uc_mem_rw_read_callback,
NULL, test_x86_mmio_uc_mem_rw_write_callback, NULL));
OK(uc_mem_write(uc, 0x20004, (void*)&data, 4));
OK(uc_mem_read(uc, 0x20008, (void*)&data, 4));
OK(uc_mem_write(uc, 0x20004, (void *)&data, 4));
OK(uc_mem_read(uc, 0x20008, (void *)&data, 4));
TEST_CHECK(data == 0x19260817);
OK(uc_close(uc));
}
static void test_x86_sysenter_hook(uc_engine* uc, void* user) {
*(int*)user = 1;
static void test_x86_sysenter_hook(uc_engine *uc, void *user)
{
*(int *)user = 1;
}
static void test_x86_sysenter() {
uc_engine* uc;
static void test_x86_sysenter()
{
uc_engine *uc;
char code[] = "\x0F\x34"; // sysenter
uc_hook h;
int called = 0;
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
OK(uc_hook_add(uc, &h, UC_HOOK_INSN, test_x86_sysenter_hook, &called, 1, 0, UC_X86_INS_SYSENTER));
OK(uc_hook_add(uc, &h, UC_HOOK_INSN, test_x86_sysenter_hook, &called, 1, 0,
UC_X86_INS_SYSENTER));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
@ -525,21 +601,24 @@ static void test_x86_sysenter() {
OK(uc_close(uc));
}
static void test_x86_hook_cpuid_callback(uc_engine* uc, void* data) {
static void test_x86_hook_cpuid_callback(uc_engine *uc, void *data)
{
int reg = 7;
OK(uc_reg_write(uc, UC_X86_REG_EAX, &reg));
}
static void test_x86_hook_cpuid() {
uc_engine* uc;
static void test_x86_hook_cpuid()
{
uc_engine *uc;
char code[] = "\x40\x0F\xA2"; // INC EAX; CPUID
uc_hook h;
int reg;
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
OK(uc_hook_add(uc, &h, UC_HOOK_INSN, test_x86_hook_cpuid_callback, NULL, 1, 0, UC_X86_INS_CPUID));
OK(uc_hook_add(uc, &h, UC_HOOK_INSN, test_x86_hook_cpuid_callback, NULL, 1,
0, UC_X86_INS_CPUID));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
@ -550,26 +629,25 @@ static void test_x86_hook_cpuid() {
OK(uc_close(uc));
}
TEST_LIST = {
{ "test_x86_in", test_x86_in },
{ "test_x86_out", test_x86_out },
{ "test_x86_mem_hook_all", test_x86_mem_hook_all },
{ "test_x86_inc_dec_pxor", test_x86_inc_dec_pxor },
{ "test_x86_relative_jump", test_x86_relative_jump },
{ "test_x86_loop", test_x86_loop },
{ "test_x86_invalid_mem_read", test_x86_invalid_mem_read },
{ "test_x86_invalid_mem_write", test_x86_invalid_mem_write },
{ "test_x86_invalid_jump", test_x86_invalid_jump},
{ "test_x86_64_syscall", test_x86_64_syscall },
{ "test_x86_16_add", test_x86_16_add },
{ "test_x86_reg_save", test_x86_reg_save },
{ "test_x86_invalid_mem_read_stop_in_cb", test_x86_invalid_mem_read_stop_in_cb },
{ "test_x86_x87_fnstenv", test_x86_x87_fnstenv},
{ "test_x86_mmio", test_x86_mmio},
{ "test_x86_missing_code", test_x86_missing_code},
{ "test_x86_smc_xor", test_x86_smc_xor},
{ "test_x86_mmio_uc_mem_rw", test_x86_mmio_uc_mem_rw},
{ "test_x86_sysenter", test_x86_sysenter},
{ "test_x86_hook_cpuid", test_x86_hook_cpuid},
{ NULL, NULL }
};
TEST_LIST = {{"test_x86_in", test_x86_in},
{"test_x86_out", test_x86_out},
{"test_x86_mem_hook_all", test_x86_mem_hook_all},
{"test_x86_inc_dec_pxor", test_x86_inc_dec_pxor},
{"test_x86_relative_jump", test_x86_relative_jump},
{"test_x86_loop", test_x86_loop},
{"test_x86_invalid_mem_read", test_x86_invalid_mem_read},
{"test_x86_invalid_mem_write", test_x86_invalid_mem_write},
{"test_x86_invalid_jump", test_x86_invalid_jump},
{"test_x86_64_syscall", test_x86_64_syscall},
{"test_x86_16_add", test_x86_16_add},
{"test_x86_reg_save", test_x86_reg_save},
{"test_x86_invalid_mem_read_stop_in_cb",
test_x86_invalid_mem_read_stop_in_cb},
{"test_x86_x87_fnstenv", test_x86_x87_fnstenv},
{"test_x86_mmio", test_x86_mmio},
{"test_x86_missing_code", test_x86_missing_code},
{"test_x86_smc_xor", test_x86_smc_xor},
{"test_x86_mmio_uc_mem_rw", test_x86_mmio_uc_mem_rw},
{"test_x86_sysenter", test_x86_sysenter},
{"test_x86_hook_cpuid", test_x86_hook_cpuid},
{NULL, NULL}};

View File

@ -8,17 +8,17 @@
/**
* Assert that err matches expect
*/
#define uc_assert_err(expect, err) \
do { \
uc_err __err = err; \
if (!TEST_CHECK(__err == expect)) { \
TEST_MSG("%s", uc_strerror(__err)); \
} \
} while (0)
#define uc_assert_err(expect, err) \
do { \
uc_err __err = err; \
if (!TEST_CHECK(__err == expect)) { \
TEST_MSG("%s", uc_strerror(__err)); \
} \
} while (0)
/**
* Assert that err is UC_ERR_OK
*/
#define OK(stat) uc_assert_err(UC_ERR_OK, stat)
#define OK(stat) uc_assert_err(UC_ERR_OK, stat)
#endif /* UNICORN_TEST_H */