mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-07-07 14:20:37 +00:00
Merge branch 'nbsdx-master'
This commit is contained in:
commit
b20f8c5aef
|
@ -1,9 +1,10 @@
|
||||||
|
|
||||||
CFLAGS += -Wall -Werror -Wno-unused-function -g
|
CFLAGS += -Wall -Werror -Wno-unused-function -g
|
||||||
CFLAGS += -L ../../
|
CFLAGS += -L ../../
|
||||||
CFLAGS += -lcmocka -lunicorn
|
|
||||||
CFLAGS += -I ../../include
|
CFLAGS += -I ../../include
|
||||||
|
|
||||||
|
LIBS += -lcmocka -lunicorn
|
||||||
|
|
||||||
ifeq ($(UNICORN_ASAN),yes)
|
ifeq ($(UNICORN_ASAN),yes)
|
||||||
CC = clang -fsanitize=address -fno-omit-frame-pointer
|
CC = clang -fsanitize=address -fno-omit-frame-pointer
|
||||||
CXX = clang++ -fsanitize=address -fno-omit-frame-pointer
|
CXX = clang++ -fsanitize=address -fno-omit-frame-pointer
|
||||||
|
@ -13,7 +14,7 @@ endif
|
||||||
|
|
||||||
ALL_TESTS = test_sanity test_x86 test_mem_map test_mem_high test_mem_map_ptr \
|
ALL_TESTS = test_sanity test_x86 test_mem_map test_mem_high test_mem_map_ptr \
|
||||||
test_tb_x86 test_multihook test_pc_change test_x86_soft_paging \
|
test_tb_x86 test_multihook test_pc_change test_x86_soft_paging \
|
||||||
test_hookcounts test_hang test_x86_shl_enter_leave
|
test_hookcounts test_hang test_x86_shl_enter_leave test_x86_rip_bug
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: ${ALL_TESTS}
|
all: ${ALL_TESTS}
|
||||||
|
@ -37,6 +38,7 @@ test: ${ALL_TESTS}
|
||||||
./test_hookcounts
|
./test_hookcounts
|
||||||
./test_hang
|
./test_hang
|
||||||
./test_x86_shl_enter_leave
|
./test_x86_shl_enter_leave
|
||||||
|
./test_x86_rip_bug
|
||||||
|
|
||||||
test_sanity: test_sanity.c
|
test_sanity: test_sanity.c
|
||||||
test_x86: test_x86.c
|
test_x86: test_x86.c
|
||||||
|
@ -50,6 +52,7 @@ test_x86_soft_paging: test_x86_soft_paging.c
|
||||||
test_hookcounts: test_hookcounts.c
|
test_hookcounts: test_hookcounts.c
|
||||||
test_hang: test_hang.c
|
test_hang: test_hang.c
|
||||||
test_x86_shl_enter_leave: test_x86_shl_enter_leave.c
|
test_x86_shl_enter_leave: test_x86_shl_enter_leave.c
|
||||||
|
test_x86_rip_bug: test_x86_rip_bug.c
|
||||||
|
|
||||||
${ALL_TESTS}:
|
${ALL_TESTS}:
|
||||||
${CC} ${CFLAGS} -o $@ $^
|
${CC} ${CFLAGS} -o $@ $^ ${LIBS}
|
||||||
|
|
173
tests/unit/test_x86_rip_bug.c
Normal file
173
tests/unit/test_x86_rip_bug.c
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <unicorn/unicorn.h>
|
||||||
|
|
||||||
|
#include "unicorn_test.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize i386 Unicorn Instance
|
||||||
|
*/
|
||||||
|
static int setup_i386(void **state)
|
||||||
|
{
|
||||||
|
uc_engine *uc;
|
||||||
|
|
||||||
|
uc_assert_success(uc_open(UC_ARCH_X86, UC_MODE_32, &uc));
|
||||||
|
|
||||||
|
*state = uc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize amd64 Unicorn Instance
|
||||||
|
*/
|
||||||
|
static int setup_amd64(void **state)
|
||||||
|
{
|
||||||
|
uc_engine *uc;
|
||||||
|
|
||||||
|
uc_assert_success(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
|
||||||
|
|
||||||
|
*state = uc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdown a Unicorn Instance
|
||||||
|
*/
|
||||||
|
static int teardown(void **state)
|
||||||
|
{
|
||||||
|
uc_engine *uc = *state;
|
||||||
|
|
||||||
|
uc_assert_success(uc_close(uc));
|
||||||
|
|
||||||
|
*state = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************/
|
||||||
|
|
||||||
|
const uint64_t CodePage = 0x10000;
|
||||||
|
const uint64_t CodeSize = 0x4000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for reading unmapped memory in the i386 Unicorn Instance.
|
||||||
|
*
|
||||||
|
* BUG: EIP from uc_reg_read does not match expected value.
|
||||||
|
*/
|
||||||
|
static bool mem_hook_i386(uc_engine *uc, uc_mem_type type,
|
||||||
|
uint64_t address, int size, int64_t value, void *user_data)
|
||||||
|
{
|
||||||
|
if (type == UC_MEM_READ_UNMAPPED)
|
||||||
|
{
|
||||||
|
uint32_t eip;
|
||||||
|
uint32_t eax;
|
||||||
|
|
||||||
|
uc_reg_read(uc, UC_X86_REG_EIP, &eip);
|
||||||
|
uc_reg_read(uc, UC_X86_REG_EAX, &eax);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code:
|
||||||
|
* 0x10000: mov eax, 0x41414141 ;; <- Returned EIP
|
||||||
|
* 0x10005: mov ecx, [eax] ;; <- Expected EIP
|
||||||
|
*/
|
||||||
|
if ((eax == 0x41414141) && // Proof we're at 0x10005.
|
||||||
|
(eip != (CodePage + 0x5))) // Proof uc_reg_read is wrong
|
||||||
|
{
|
||||||
|
printf("De-synced EIP value. 0x%08X != 0x%08X\n", eip, (uint32_t)CodePage + 0x05);
|
||||||
|
// Failure raised by the uc_emu_start() call.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for reading unmapped memory in the amd64 Unicorn Instance.
|
||||||
|
*
|
||||||
|
* BUG: RIP from uc_reg_read does not match expected value.
|
||||||
|
*/
|
||||||
|
static bool mem_hook_amd64(uc_engine *uc, uc_mem_type type,
|
||||||
|
uint64_t address, int size, int64_t value, void *user_data)
|
||||||
|
{
|
||||||
|
if (type == UC_MEM_READ_UNMAPPED)
|
||||||
|
{
|
||||||
|
uint64_t rip;
|
||||||
|
uint64_t rax;
|
||||||
|
|
||||||
|
uc_reg_read(uc, UC_X86_REG_RIP, &rip);
|
||||||
|
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code:
|
||||||
|
* 0x10000: mov rax, 0x4141414141414141 ;; <- Returned RIP
|
||||||
|
* 0x10005: mov rcx, [rax] ;; <- Expected RIP
|
||||||
|
*/
|
||||||
|
if ((rax == 0x4141414141414141) && // Proof we're at 0x10005
|
||||||
|
(rip != (CodePage + 0x5))) // Proof uc_reg_read is wrong
|
||||||
|
{
|
||||||
|
printf("De-synced RIP value. 0x%"PRIX64" != 0x%"PRIX64"\n", rip, CodePage + 0x05);
|
||||||
|
// Failure raised by the uc_emu_start() call.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the bug for i386.
|
||||||
|
*
|
||||||
|
* 1. Map Code Page
|
||||||
|
* 2. Write Code to page.
|
||||||
|
* 3. Install Unmapped Read hook.
|
||||||
|
* 4. Run the VM.
|
||||||
|
*/
|
||||||
|
static void test_i386(void **state)
|
||||||
|
{
|
||||||
|
uc_engine *uc = *state;
|
||||||
|
uc_hook trace1;
|
||||||
|
|
||||||
|
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, NULL, 1, 0));
|
||||||
|
uc_assert_success(uc_emu_start(uc, CodePage, CodePage + sizeof(i386_bug), 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the bug for amd64..
|
||||||
|
*
|
||||||
|
* 1. Map Code Page
|
||||||
|
* 2. Write Code to page.
|
||||||
|
* 3. Install Unmapped Read hook.
|
||||||
|
* 4. Run the VM.
|
||||||
|
*/
|
||||||
|
static void test_amd64(void **state)
|
||||||
|
{
|
||||||
|
uc_engine *uc = *state;
|
||||||
|
uc_hook trace1;
|
||||||
|
|
||||||
|
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, NULL, 1, 0));
|
||||||
|
uc_assert_success(uc_emu_start(uc, CodePage, CodePage + sizeof(amd64_bug), 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run all tests
|
||||||
|
*/
|
||||||
|
int main(int argc, char **argv, char **envp)
|
||||||
|
{
|
||||||
|
const struct CMUnitTest tests[] = {
|
||||||
|
cmocka_unit_test_setup_teardown(test_i386, setup_i386, teardown),
|
||||||
|
cmocka_unit_test_setup_teardown(test_amd64, setup_amd64, teardown)
|
||||||
|
};
|
||||||
|
|
||||||
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
}
|
Loading…
Reference in a new issue