Add tests for UC_HOOK_TCG_OPCODE
This commit is contained in:
@ -307,13 +307,11 @@ typedef enum uc_tcg_op_code {
|
||||
// These are extra flags to be paired with uc_tcg_op_code which is helpful to
|
||||
// instrument in some certain cases.
|
||||
typedef enum uc_tcg_op_flag {
|
||||
// Only instrument opcode if one of the arguments is an immediate value.
|
||||
UC_TCG_OP_FLAG_IMM = 1 << 0,
|
||||
// Only instrument opcode if it would set cc_dst, i.e. cmp instruction.
|
||||
UC_TCG_OP_FLAG_CMP = 1 << 1,
|
||||
// Only instrument opcode which is directly translated. i.e. x86 sub -> tcg
|
||||
// sub_i32/64
|
||||
UC_TCG_OP_FLAG_DIRECT = 1 << 2
|
||||
UC_TCG_OP_FLAG_CMP = 1 << 0,
|
||||
// Only instrument opcode which is directly translated.
|
||||
// i.e. x86 sub/subc -> tcg sub_i32/64
|
||||
UC_TCG_OP_FLAG_DIRECT = 1 << 1
|
||||
} uc_tcg_op_flag;
|
||||
|
||||
// All type of hooks for uc_hook_add() API.
|
||||
|
@ -1552,9 +1552,6 @@ static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
|
||||
continue;
|
||||
if (hook->op == UC_TCG_OP_SUB && (hook->op_flags & UC_TCG_OP_FLAG_DIRECT) ) {
|
||||
// TCGv is just an offset to tcg_ctx so it's safe to do so.
|
||||
if ( (hook->op_flags & UC_TCG_OP_FLAG_IMM) && d != OR_EAX) {
|
||||
continue;
|
||||
}
|
||||
gen_uc_traceopcode(tcg_ctx, hook, (TCGv_i64)s1->T0, (TCGv_i64)s1->T1, uc, s1->pc_start);
|
||||
}
|
||||
}
|
||||
@ -1610,9 +1607,6 @@ static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
|
||||
continue;
|
||||
if (hook->op == UC_TCG_OP_SUB && (hook->op_flags & UC_TCG_OP_FLAG_CMP) ) {
|
||||
// TCGv is just an offset to tcg_ctx so it's safe to do so.
|
||||
if ( (hook->op_flags & UC_TCG_OP_FLAG_IMM) && d != OR_EAX) {
|
||||
continue;
|
||||
}
|
||||
gen_uc_traceopcode(tcg_ctx, hook, (TCGv_i64)s1->T0, (TCGv_i64)s1->T1, uc, s1->pc_start);
|
||||
}
|
||||
}
|
||||
|
@ -1578,10 +1578,6 @@ static bool x86_opcode_hook_invalidate(uint32_t op, uint32_t flags)
|
||||
switch (op) {
|
||||
case UC_TCG_OP_SUB:
|
||||
|
||||
if (flags == UC_TCG_OP_FLAG_IMM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((flags & UC_TCG_OP_FLAG_CMP) && (flags & UC_TCG_OP_FLAG_DIRECT)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -696,6 +696,79 @@ static void test_x86_clear_empty_tb()
|
||||
OK(uc_close(uc));
|
||||
}
|
||||
|
||||
typedef struct _HOOK_TCG_OP_RESULT {
|
||||
uint64_t address;
|
||||
uint64_t arg1;
|
||||
uint64_t arg2;
|
||||
} HOOK_TCG_OP_RESULT;
|
||||
|
||||
typedef struct _HOOK_TCG_OP_RESULTS {
|
||||
HOOK_TCG_OP_RESULT results[128];
|
||||
uint64_t len;
|
||||
} HOOK_TCG_OP_RESULTS;
|
||||
|
||||
static void test_x86_hook_tcg_op_cb(uc_engine *uc, uint64_t address,
|
||||
uint64_t arg1, uint64_t arg2, void *data)
|
||||
{
|
||||
HOOK_TCG_OP_RESULTS *results = (HOOK_TCG_OP_RESULTS *)data;
|
||||
HOOK_TCG_OP_RESULT *result = &results->results[results->len++];
|
||||
|
||||
result->address = address;
|
||||
result->arg1 = arg1;
|
||||
result->arg2 = arg2;
|
||||
}
|
||||
|
||||
static void test_x86_hook_tcg_op()
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_hook h;
|
||||
int flag;
|
||||
HOOK_TCG_OP_RESULTS results;
|
||||
// sub esi, [0x1000];
|
||||
// sub eax, ebx;
|
||||
// sub eax, 1;
|
||||
// cmp eax, 0;
|
||||
// cmp ebx, edx;
|
||||
// cmp esi, [0x1000];
|
||||
char code[] = "\x2b\x35\x00\x10\x00\x00\x29\xd8\x83\xe8\x01\x83\xf8\x00\x39"
|
||||
"\xd3\x3b\x35\x00\x10\x00\x00";
|
||||
int r_eax = 0x1234;
|
||||
int r_ebx = 2;
|
||||
|
||||
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
|
||||
OK(uc_reg_write(uc, UC_X86_REG_EAX, &r_eax));
|
||||
OK(uc_reg_write(uc, UC_X86_REG_EBX, &r_ebx));
|
||||
|
||||
memset(&results, 0, sizeof(HOOK_TCG_OP_RESULTS));
|
||||
flag = 0;
|
||||
OK(uc_hook_add(uc, &h, UC_HOOK_TCG_OPCODE, test_x86_hook_tcg_op_cb,
|
||||
&results, 0, -1, UC_TCG_OP_SUB, flag));
|
||||
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||
OK(uc_hook_del(uc, h));
|
||||
|
||||
TEST_CHECK(results.len == 6);
|
||||
|
||||
memset(&results, 0, sizeof(HOOK_TCG_OP_RESULTS));
|
||||
flag = UC_TCG_OP_FLAG_DIRECT;
|
||||
OK(uc_hook_add(uc, &h, UC_HOOK_TCG_OPCODE, test_x86_hook_tcg_op_cb,
|
||||
&results, 0, -1, UC_TCG_OP_SUB, flag));
|
||||
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||
OK(uc_hook_del(uc, h));
|
||||
|
||||
TEST_CHECK(results.len == 3);
|
||||
|
||||
memset(&results, 0, sizeof(HOOK_TCG_OP_RESULTS));
|
||||
flag = UC_TCG_OP_FLAG_CMP;
|
||||
OK(uc_hook_add(uc, &h, UC_HOOK_TCG_OPCODE, test_x86_hook_tcg_op_cb,
|
||||
&results, 0, -1, UC_TCG_OP_SUB, flag));
|
||||
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||
OK(uc_hook_del(uc, h));
|
||||
|
||||
TEST_CHECK(results.len == 3);
|
||||
|
||||
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},
|
||||
@ -719,4 +792,5 @@ TEST_LIST = {{"test_x86_in", test_x86_in},
|
||||
{"test_x86_hook_cpuid", test_x86_hook_cpuid},
|
||||
{"test_x86_clear_tb_cache", test_x86_clear_tb_cache},
|
||||
{"test_x86_clear_empty_tb", test_x86_clear_empty_tb},
|
||||
{"test_x86_hook_tcg_op", test_x86_hook_tcg_op},
|
||||
{NULL, NULL}};
|
Reference in New Issue
Block a user