mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-09 01:05:36 +00:00
Fixed multiple bugs in test_x86_rip_bug.c
Fixed format warning in test_hang.c
This commit is contained in:
parent
4a67727f81
commit
d77fd18915
|
@ -87,8 +87,8 @@ void test_hang(void **state)
|
||||||
uc_reg_read(uc, UC_ARM64_REG_X0, &x0);
|
uc_reg_read(uc, UC_ARM64_REG_X0, &x0);
|
||||||
uc_reg_read(uc, UC_ARM64_REG_X1, &x1);
|
uc_reg_read(uc, UC_ARM64_REG_X1, &x1);
|
||||||
|
|
||||||
printf("x0: %#llx\n", x0);
|
printf("x0: %#lx\n", x0);
|
||||||
printf("x1: %#llx\n", x1);
|
printf("x1: %#lx\n", x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char * argv[]) {
|
int main(int argc, const char * argv[]) {
|
||||||
|
|
|
@ -44,7 +44,13 @@ static int teardown(void **state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool good;
|
||||||
|
uint64_t actual;
|
||||||
|
uint64_t expected;
|
||||||
|
} TestData;
|
||||||
|
|
||||||
const uint64_t CodePage = 0x10000;
|
const uint64_t CodePage = 0x10000;
|
||||||
const uint64_t CodeSize = 0x4000;
|
const uint64_t CodeSize = 0x4000;
|
||||||
|
|
||||||
|
@ -56,6 +62,7 @@ const uint64_t CodeSize = 0x4000;
|
||||||
static bool mem_hook_i386(uc_engine *uc, uc_mem_type type,
|
static bool mem_hook_i386(uc_engine *uc, uc_mem_type type,
|
||||||
uint64_t address, int size, int64_t value, void *user_data)
|
uint64_t address, int size, int64_t value, void *user_data)
|
||||||
{
|
{
|
||||||
|
TestData *data = user_data;
|
||||||
if (type == UC_MEM_READ_UNMAPPED)
|
if (type == UC_MEM_READ_UNMAPPED)
|
||||||
{
|
{
|
||||||
uint32_t eip;
|
uint32_t eip;
|
||||||
|
@ -64,6 +71,9 @@ static bool mem_hook_i386(uc_engine *uc, uc_mem_type type,
|
||||||
uc_reg_read(uc, UC_X86_REG_EIP, &eip);
|
uc_reg_read(uc, UC_X86_REG_EIP, &eip);
|
||||||
uc_reg_read(uc, UC_X86_REG_EAX, &eax);
|
uc_reg_read(uc, UC_X86_REG_EAX, &eax);
|
||||||
|
|
||||||
|
data->actual = eip;
|
||||||
|
data->expected = CodePage + 0x05;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code:
|
* Code:
|
||||||
* 0x10000: mov eax, 0x41414141 ;; <- Returned EIP
|
* 0x10000: mov eax, 0x41414141 ;; <- Returned EIP
|
||||||
|
@ -72,9 +82,10 @@ static bool mem_hook_i386(uc_engine *uc, uc_mem_type type,
|
||||||
if ((eax == 0x41414141) && // Proof we're at 0x10005.
|
if ((eax == 0x41414141) && // Proof we're at 0x10005.
|
||||||
(eip != (CodePage + 0x5))) // Proof uc_reg_read is wrong
|
(eip != (CodePage + 0x5))) // Proof uc_reg_read is wrong
|
||||||
{
|
{
|
||||||
printf("De-synced EIP value. 0x%08X != 0x%08X\n", eip, (uint32_t)CodePage + 0x05);
|
data->good = false;
|
||||||
// Failure raised by the uc_emu_start() call.
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
data->good = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +98,7 @@ static bool mem_hook_i386(uc_engine *uc, uc_mem_type type,
|
||||||
static bool mem_hook_amd64(uc_engine *uc, uc_mem_type type,
|
static bool mem_hook_amd64(uc_engine *uc, uc_mem_type type,
|
||||||
uint64_t address, int size, int64_t value, void *user_data)
|
uint64_t address, int size, int64_t value, void *user_data)
|
||||||
{
|
{
|
||||||
|
TestData *data = user_data;
|
||||||
if (type == UC_MEM_READ_UNMAPPED)
|
if (type == UC_MEM_READ_UNMAPPED)
|
||||||
{
|
{
|
||||||
uint64_t rip;
|
uint64_t rip;
|
||||||
|
@ -95,21 +107,36 @@ static bool mem_hook_amd64(uc_engine *uc, uc_mem_type type,
|
||||||
uc_reg_read(uc, UC_X86_REG_RIP, &rip);
|
uc_reg_read(uc, UC_X86_REG_RIP, &rip);
|
||||||
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
|
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
|
||||||
|
|
||||||
|
data->actual = rip;
|
||||||
|
data->expected = CodePage + 0x0A;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code:
|
* Code:
|
||||||
* 0x10000: mov rax, 0x4141414141414141 ;; <- Returned RIP
|
* 0x10000: mov rax, 0x4141414141414141 ;; <- Returned RIP
|
||||||
* 0x10005: mov rcx, [rax] ;; <- Expected RIP
|
* 0x10005: mov rcx, [rax] ;; <- Expected RIP
|
||||||
*/
|
*/
|
||||||
if ((rax == 0x4141414141414141) && // Proof we're at 0x10005
|
if ((rax == 0x4141414141414141) && // Proof we're at 0x10005
|
||||||
(rip != (CodePage + 0x5))) // Proof uc_reg_read is wrong
|
(rip != (CodePage + 0xA))) // Proof uc_reg_read is wrong
|
||||||
{
|
{
|
||||||
printf("De-synced RIP value. 0x%016lX != 0x%016lX\n", rip, CodePage + 0x05);
|
data->good = false;
|
||||||
// Failure raised by the uc_emu_start() call.
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
data->good = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty Code Hook.
|
||||||
|
*/
|
||||||
|
static void code_hook(uc_engine *uc, uint64_t addr, uint32_t size, void *user)
|
||||||
|
{
|
||||||
|
(void) uc;
|
||||||
|
(void) addr;
|
||||||
|
(void) size;
|
||||||
|
(void) user;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the bug for i386.
|
* Test the bug for i386.
|
||||||
*
|
*
|
||||||
|
@ -120,6 +147,7 @@ static bool mem_hook_amd64(uc_engine *uc, uc_mem_type type,
|
||||||
*/
|
*/
|
||||||
static void test_i386(void **state)
|
static void test_i386(void **state)
|
||||||
{
|
{
|
||||||
|
TestData data;
|
||||||
uc_engine *uc = *state;
|
uc_engine *uc = *state;
|
||||||
uc_hook trace1;
|
uc_hook trace1;
|
||||||
|
|
||||||
|
@ -130,8 +158,11 @@ static void test_i386(void **state)
|
||||||
|
|
||||||
uc_assert_success(uc_mem_map(uc, CodePage, CodeSize, UC_PROT_ALL));
|
uc_assert_success(uc_mem_map(uc, CodePage, CodeSize, UC_PROT_ALL));
|
||||||
uc_assert_success(uc_mem_write(uc, CodePage, i386_bug, sizeof(i386_bug)));
|
uc_assert_success(uc_mem_write(uc, CodePage, i386_bug, sizeof(i386_bug)));
|
||||||
uc_assert_success(uc_hook_add(uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED, mem_hook_i386, NULL, 1, 0));
|
uc_assert_success(uc_hook_add(uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED, mem_hook_i386, &data, 1, 0));
|
||||||
uc_assert_success(uc_emu_start(uc, CodePage, CodePage + sizeof(i386_bug), 0, 0));
|
uc_assert_fail(uc_emu_start(uc, CodePage, CodePage + sizeof(i386_bug), 0, 0));
|
||||||
|
|
||||||
|
if (!data.good)
|
||||||
|
fail_msg("De-synced RIP value. 0x%016lX != 0x%016lX\n", data.expected, data.actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,6 +175,7 @@ static void test_i386(void **state)
|
||||||
*/
|
*/
|
||||||
static void test_amd64(void **state)
|
static void test_amd64(void **state)
|
||||||
{
|
{
|
||||||
|
TestData data;
|
||||||
uc_engine *uc = *state;
|
uc_engine *uc = *state;
|
||||||
uc_hook trace1;
|
uc_hook trace1;
|
||||||
|
|
||||||
|
@ -155,8 +187,72 @@ static void test_amd64(void **state)
|
||||||
|
|
||||||
uc_assert_success(uc_mem_map(uc, CodePage, CodeSize, UC_PROT_ALL));
|
uc_assert_success(uc_mem_map(uc, CodePage, CodeSize, UC_PROT_ALL));
|
||||||
uc_assert_success(uc_mem_write(uc, CodePage, amd64_bug, sizeof(amd64_bug)));
|
uc_assert_success(uc_mem_write(uc, CodePage, amd64_bug, sizeof(amd64_bug)));
|
||||||
uc_assert_success(uc_hook_add(uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED, mem_hook_amd64, NULL, 1, 0));
|
uc_assert_success(uc_hook_add(uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED, mem_hook_amd64, &data, 1, 0));
|
||||||
uc_assert_success(uc_emu_start(uc, CodePage, CodePage + sizeof(amd64_bug), 0, 0));
|
uc_assert_fail(uc_emu_start(uc, CodePage, CodePage + sizeof(amd64_bug), 0, 0));
|
||||||
|
|
||||||
|
if (!data.good)
|
||||||
|
fail_msg("De-synced RIP value. 0x%016lX != 0x%016lX\n", data.expected, data.actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test temporary fix for bug for i386.
|
||||||
|
*
|
||||||
|
* 1. Map Code Page
|
||||||
|
* 2. Write Code to page.
|
||||||
|
* 3. Install Unmapped Read hook.
|
||||||
|
* 4. Install Code hook.
|
||||||
|
* 5. Run the VM.
|
||||||
|
*/
|
||||||
|
static void test_i386_fix(void **state)
|
||||||
|
{
|
||||||
|
TestData data;
|
||||||
|
uc_engine *uc = *state;
|
||||||
|
uc_hook trace1, trace2;
|
||||||
|
|
||||||
|
const uint8_t i386_bug[] = {
|
||||||
|
0xb8, 0x41, 0x41, 0x41, 0x41, // mov eax, 0x41414141
|
||||||
|
0x8b, 0x08 // mov ecx, [eax]
|
||||||
|
};
|
||||||
|
|
||||||
|
uc_assert_success(uc_mem_map(uc, CodePage, CodeSize, UC_PROT_ALL));
|
||||||
|
uc_assert_success(uc_mem_write(uc, CodePage, i386_bug, sizeof(i386_bug)));
|
||||||
|
uc_assert_success(uc_hook_add(uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED, mem_hook_i386, &data, 1, 0));
|
||||||
|
uc_assert_success(uc_hook_add(uc, &trace2, UC_HOOK_CODE, code_hook, NULL, 1, 0));
|
||||||
|
uc_assert_fail(uc_emu_start(uc, CodePage, CodePage + sizeof(i386_bug), 0, 0));
|
||||||
|
|
||||||
|
if (!data.good)
|
||||||
|
fail_msg("De-synced RIP value. 0x%016lX != 0x%016lX\n", data.expected, data.actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test temporary fix for bug for amd64..
|
||||||
|
*
|
||||||
|
* 1. Map Code Page
|
||||||
|
* 2. Write Code to page.
|
||||||
|
* 3. Install Unmapped Read hook.
|
||||||
|
* 4. Install Code hook.
|
||||||
|
* 5. Run the VM.
|
||||||
|
*/
|
||||||
|
static void test_amd64_fix(void **state)
|
||||||
|
{
|
||||||
|
TestData data;
|
||||||
|
uc_engine *uc = *state;
|
||||||
|
uc_hook trace1, trace2;
|
||||||
|
|
||||||
|
const uint8_t amd64_bug[] = {
|
||||||
|
0x48, 0xb8, 0x41, 0x41, 0x41, 0x41,
|
||||||
|
0x41, 0x41, 0x41, 0x41,
|
||||||
|
0x48, 0x8b, 0x08
|
||||||
|
};
|
||||||
|
|
||||||
|
uc_assert_success(uc_mem_map(uc, CodePage, CodeSize, UC_PROT_ALL));
|
||||||
|
uc_assert_success(uc_mem_write(uc, CodePage, amd64_bug, sizeof(amd64_bug)));
|
||||||
|
uc_assert_success(uc_hook_add(uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED, mem_hook_amd64, &data, 1, 0));
|
||||||
|
uc_assert_success(uc_hook_add(uc, &trace2, UC_HOOK_CODE, code_hook, NULL, 1, 0));
|
||||||
|
uc_assert_fail(uc_emu_start(uc, CodePage, CodePage + sizeof(amd64_bug), 0, 0));
|
||||||
|
|
||||||
|
if (!data.good)
|
||||||
|
fail_msg("De-synced RIP value. 0x%016lX != 0x%016lX\n", data.expected, data.actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -166,7 +262,9 @@ int main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
const struct CMUnitTest tests[] = {
|
const struct CMUnitTest tests[] = {
|
||||||
cmocka_unit_test_setup_teardown(test_i386, setup_i386, teardown),
|
cmocka_unit_test_setup_teardown(test_i386, setup_i386, teardown),
|
||||||
cmocka_unit_test_setup_teardown(test_amd64, setup_amd64, teardown)
|
cmocka_unit_test_setup_teardown(test_amd64, setup_amd64, teardown),
|
||||||
|
cmocka_unit_test_setup_teardown(test_i386_fix, setup_i386, teardown),
|
||||||
|
cmocka_unit_test_setup_teardown(test_amd64_fix, setup_amd64, teardown)
|
||||||
};
|
};
|
||||||
|
|
||||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
|
Loading…
Reference in a new issue