Uc hook tcg improve (#2011)

* Add handling UC_TCG_OP_FLAG_CMP for ARM

Implementation is not well-tested and complete

* Hook ARM32 CMP and CMN for cmplog
This commit is contained in:
dotcirill
2025-02-10 10:01:21 +03:00
committed by GitHub
parent ada8091ccc
commit dc1f7a88d5
2 changed files with 93 additions and 0 deletions

View File

@@ -861,6 +861,74 @@ static void test_arm_mem_hook_read_write(void)
OK(uc_close(uc));
}
typedef struct {
uint64_t v0;
uint64_t v1;
uint64_t size;
uint64_t pc;
} _last_cmp_info;
static void _uc_hook_sub_cmp(uc_engine *uc, uint64_t address, uint64_t arg1,
uint64_t arg2, uint32_t size,
_last_cmp_info *user_data)
{
user_data->pc = address;
user_data->size = size;
user_data->v0 = arg1;
user_data->v1 = arg2;
}
static void test_arm_tcg_opcode_cmp(void)
{
uc_engine *uc;
const char code[] = "\x04\x00\x9f\xe5" // ldr r0, [pc, #4]
"\x04\x10\x9f\xe5" // ldr r1, [pc, #4]
"\x01\x00\x50\xe1" // cmp r0, r1
"\x05\x00\x00\x00" // (5)
"\x03\x00\x00\x00" // (3)
;
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_ARM, code, sizeof(code) - 1,
UC_CPU_ARM_CORTEX_A15);
uc_hook hook;
_last_cmp_info cmp_info = {0};
OK(uc_hook_add(uc, &hook, UC_HOOK_TCG_OPCODE, (void *)_uc_hook_sub_cmp,
(void *)&cmp_info, 1, 0, UC_TCG_OP_SUB, UC_TCG_OP_FLAG_CMP));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 3));
TEST_CHECK(cmp_info.v0 == 5 && cmp_info.v1 == 3);
TEST_CHECK(cmp_info.pc == code_start);
TEST_CHECK(cmp_info.size == 32);
}
static void test_arm_thumb_tcg_opcode_cmn(void)
{
uc_engine *uc;
const char code[] = "\x01\x48" // ldr r0, [pc, #4]
"\x02\x49" // ldr r1, [pc, #8]
"\x00\xbf" // nop
"\xc8\x42" // cmn r0, r1
"\x05\x00\x00\x00" // (5)
"\x03\x00\x00\x00" // (3)
;
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_THUMB, code, sizeof(code) - 1,
UC_CPU_ARM_CORTEX_A15);
uc_hook hook;
_last_cmp_info cmp_info = {0};
OK(uc_hook_add(uc, &hook, UC_HOOK_TCG_OPCODE, (void *)_uc_hook_sub_cmp,
(void *)&cmp_info, 1, 0, UC_TCG_OP_SUB, UC_TCG_OP_FLAG_CMP));
OK(uc_emu_start(uc, code_start | 1, code_start + sizeof(code) - 1, 0, 4));
TEST_CHECK(cmp_info.v0 == 5 && cmp_info.v1 == 3);
TEST_CHECK(cmp_info.pc == (code_start | 1));
TEST_CHECK(cmp_info.size == 32);
}
TEST_LIST = {{"test_arm_nop", test_arm_nop},
{"test_arm_thumb_sub", test_arm_thumb_sub},
{"test_armeb_sub", test_armeb_sub},
@@ -887,4 +955,6 @@ TEST_LIST = {{"test_arm_nop", test_arm_nop},
{"test_arm_thumb2", test_arm_thumb2},
{"test_armeb_be32_thumb2", test_armeb_be32_thumb2},
{"test_arm_mem_hook_read_write", test_arm_mem_hook_read_write},
{"test_arm_tcg_opcode_cmp", test_arm_tcg_opcode_cmp},
{"test_arm_thumb_tcg_opcode_cmn", test_arm_thumb_tcg_opcode_cmn},
{NULL, NULL}};