From 549274f44cadc952ab6223d2f800a1965bee53af Mon Sep 17 00:00:00 2001 From: Quentin DUCASSE Date: Fri, 10 Dec 2021 15:27:54 +0100 Subject: [PATCH] Code patching tests for riscv and arm64 --- tests/unit/test_arm64.c | 62 ++++++++++++++++++++++++++++++++++++++++- tests/unit/test_riscv.c | 56 +++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_arm64.c b/tests/unit/test_arm64.c index 302945db..33c6ca37 100644 --- a/tests/unit/test_arm64.c +++ b/tests/unit/test_arm64.c @@ -50,4 +50,64 @@ static void test_arm64_until() OK(uc_close(uc)); } -TEST_LIST = {{"test_arm64_until", test_arm64_until}, {NULL, NULL}}; + +static void test_arm64_code_patching() { + uc_engine *uc; + char code[] = "\x00\x04\x00\x11"; // add w0, w0, 0x1 + uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1); + // zero out x0 + uint64_t r_x0 = 0x0; + OK(uc_reg_write(uc, UC_ARM64_REG_X0, &r_x0)); + // emulate the instruction + OK(uc_emu_start(uc, code_start, code_start + sizeof(code) -1, 0, 0)); + // check value + OK(uc_reg_read(uc, UC_ARM64_REG_X0, &r_x0)); + TEST_CHECK(r_x0 == 0x1); + // patch instruction + char patch_code[] = "\x00\xfc\x1f\x11"; // add w0, w0, 0x7FF + OK(uc_mem_write(uc, code_start, patch_code, sizeof(patch_code) - 1)); + // zero out x0 + r_x0 = 0x0; + OK(uc_reg_write(uc, UC_ARM64_REG_X0, &r_x0)); + OK(uc_emu_start(uc, code_start, code_start + sizeof(patch_code) -1, 0, 0)); + // check value + OK(uc_reg_read(uc, UC_ARM64_REG_X0, &r_x0)); + TEST_CHECK(r_x0 != 0x1); + TEST_CHECK(r_x0 == 0x7ff); + + OK(uc_close(uc)); +} + +static void test_arm64_code_patching_count() { + uc_engine *uc; + char code[] = "\x00\x04\x00\x11"; // add w0, w0, 0x1 + uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1); + // zero out x0 + uint64_t r_x0 = 0x0; + OK(uc_reg_write(uc, UC_ARM64_REG_X0, &r_x0)); + // emulate the instruction + OK(uc_emu_start(uc, code_start, -1, 0, 1)); + // check value + OK(uc_reg_read(uc, UC_ARM64_REG_X0, &r_x0)); + TEST_CHECK(r_x0 == 0x1); + // patch instruction + char patch_code[] = "\x00\xfc\x1f\x11"; // add w0, w0, 0x7FF + OK(uc_mem_write(uc, code_start, patch_code, sizeof(patch_code) - 1)); + // zero out x0 + r_x0 = 0x0; + OK(uc_reg_write(uc, UC_ARM64_REG_X0, &r_x0)); + OK(uc_emu_start(uc, code_start, -1, 0, 1)); + // check value + OK(uc_reg_read(uc, UC_ARM64_REG_X0, &r_x0)); + TEST_CHECK(r_x0 != 0x1); + TEST_CHECK(r_x0 == 0x7ff); + + OK(uc_close(uc)); +} + +TEST_LIST = { + {"test_arm64_until", test_arm64_until}, + {"test_arm64_code_patching", test_arm64_code_patching}, + {"test_arm64_code_patching_count", test_arm64_code_patching_count}, + {NULL, NULL} +}; diff --git a/tests/unit/test_riscv.c b/tests/unit/test_riscv.c index 2e38392e..076ea347 100644 --- a/tests/unit/test_riscv.c +++ b/tests/unit/test_riscv.c @@ -372,6 +372,60 @@ static void test_riscv64_fp_move_to_int(void) uc_close(uc); } +static void test_riscv64_code_patching() { + uc_engine *uc; + char code[] = "\x93\x82\x12\x00"; // addi t0, t0, 0x1 + uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code, sizeof(code) - 1); + // Zero out t0 and t1 + uint64_t r_t0 = 0x0; + OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0)); + // emulate the instruction + OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); + // check value + OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0)); + TEST_CHECK(r_t0 == 0x1); + // patch instruction + char patch_code[] = "\x93\x82\xf2\x7f"; // addi t0, t0, 0x7FF + OK(uc_mem_write(uc, code_start, patch_code, sizeof(patch_code) - 1)); + // zero out t0 + r_t0 = 0x0; + OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0)); + OK(uc_emu_start(uc, code_start, code_start + sizeof(patch_code) -1, 0, 0)); + // check value + OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0)); + TEST_CHECK(r_t0 != 0x1); + TEST_CHECK(r_t0 == 0x7ff); + + OK(uc_close(uc)); +} + +static void test_riscv64_code_patching_count() { + uc_engine *uc; + char code[] = "\x93\x82\x12\x00"; // addi t0, t0, 0x1 + uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code, sizeof(code) - 1); + // Zero out t0 and t1 + uint64_t r_t0 = 0x0; + OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0)); + // emulate the instruction + OK(uc_emu_start(uc, code_start, -1, 0, 1)); + // check value + OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0)); + TEST_CHECK(r_t0 == 0x1); + // patch instruction + char patch_code[] = "\x93\x82\xf2\x7f"; // addi t0, t0, 0x7FF + OK(uc_mem_write(uc, code_start, patch_code, sizeof(patch_code) - 1)); + // zero out t0 + r_t0 = 0x0; + OK(uc_reg_write(uc, UC_RISCV_REG_T0, &r_t0)); + OK(uc_emu_start(uc, code_start, -1, 0, 1)); + // check value + OK(uc_reg_read(uc, UC_RISCV_REG_T0, &r_t0)); + TEST_CHECK(r_t0 != 0x1); + TEST_CHECK(r_t0 == 0x7ff); + + OK(uc_close(uc)); +} + static void test_riscv64_ecall_cb(uc_engine *uc, uint32_t intno, void *data) { uc_emu_stop(uc); @@ -492,4 +546,6 @@ TEST_LIST = {{"test_riscv32_nop", test_riscv32_nop}, {"test_riscv32_mmio_map", test_riscv32_mmio_map}, {"test_riscv64_mmio_map", test_riscv64_mmio_map}, {"test_riscv32_map", test_riscv32_map}, + {"test_riscv64_code_patching", test_riscv64_code_patching}, + {"test_riscv64_code_patching_count", test_riscv64_code_patching_count}, {NULL, NULL}};