From e09fb7cf599a5f76b27a7c4f5e4966c3b3e24a91 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 19 Nov 2021 14:35:47 +0100 Subject: [PATCH] Hook cmp on arm and aarch64 --- accel/tcg/translate-all.c | 72 ++++++++++++++++++++++++++++++++++++++ target/arm/translate-a64.c | 36 +++++++++++++++++++ target/arm/translate.c | 42 ++++++++++++++++++++++ 3 files changed, 150 insertions(+) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 6e400e3142..c89e1a0819 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -72,7 +72,9 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block, target_ulong dst_block, target_ulong cs_base, uint32_t flags, int cflags); void libafl_gen_read(TCGv addr, MemOp ot); +void libafl_gen_read_N(TCGv addr, uint32_t size); void libafl_gen_write(TCGv addr, MemOp ot); +void libafl_gen_write_N(TCGv addr, uint32_t size); void libafl_gen_cmp(target_ulong pc, TCGv op0, TCGv op1, MemOp ot); void (*libafl_exec_edge_hook)(uint64_t id); @@ -183,6 +185,41 @@ void libafl_gen_read(TCGv addr, MemOp ot) } } +void libafl_gen_read_N(TCGv addr, uint32_t size) +{ + uint32_t libafl_id = 0; + if (libafl_gen_read_hook) + libafl_id = libafl_gen_read_hook(size); + if (libafl_id != (uint32_t)-1) { + if (!exec_read_hook_added) { + exec_read_hook_added = 1; + libafl_exec_read_hook1_info.func = libafl_exec_read_hook1; + libafl_helper_table_add(&libafl_exec_read_hook1_info); + libafl_exec_read_hook2_info.func = libafl_exec_read_hook2; + libafl_helper_table_add(&libafl_exec_read_hook2_info); + libafl_exec_read_hook4_info.func = libafl_exec_read_hook4; + libafl_helper_table_add(&libafl_exec_read_hook4_info); + libafl_exec_read_hook8_info.func = libafl_exec_read_hook8; + libafl_helper_table_add(&libafl_exec_read_hook8_info); + libafl_exec_read_hookN_info.func = libafl_exec_read_hookN; + libafl_helper_table_add(&libafl_exec_read_hookN_info); + } + TCGv_i64 tmp0 = tcg_const_i64(libafl_id); + TCGv_i32 tmp1 = tcg_const_i32(size); + TCGTemp *tmp2[3] = { tcgv_i64_temp(tmp0), +#if TARGET_LONG_BITS == 32 + tcgv_i32_temp(addr), +#else + tcgv_i64_temp(addr), +#endif + tcgv_i32_temp(tmp1) + }; + tcg_gen_callN(libafl_exec_read_hookN, NULL, 3, tmp2); + tcg_temp_free_i32(tmp1); + tcg_temp_free_i64(tmp0); + } +} + void (*libafl_exec_write_hook1)(uint64_t id, uint64_t addr); void (*libafl_exec_write_hook2)(uint64_t id, uint64_t addr); void (*libafl_exec_write_hook4)(uint64_t id, uint64_t addr); @@ -271,6 +308,41 @@ void libafl_gen_write(TCGv addr, MemOp ot) } } +void libafl_gen_write_N(TCGv addr, uint32_t size) +{ + uint32_t libafl_id = 0; + if (libafl_gen_write_hook) + libafl_id = libafl_gen_write_hook(size); + if (libafl_id != (uint32_t)-1) { + if (!exec_write_hook_added) { + exec_write_hook_added = 1; + libafl_exec_write_hook1_info.func = libafl_exec_write_hook1; + libafl_helper_table_add(&libafl_exec_write_hook1_info); + libafl_exec_write_hook2_info.func = libafl_exec_write_hook2; + libafl_helper_table_add(&libafl_exec_write_hook2_info); + libafl_exec_write_hook4_info.func = libafl_exec_write_hook4; + libafl_helper_table_add(&libafl_exec_write_hook4_info); + libafl_exec_write_hook8_info.func = libafl_exec_write_hook8; + libafl_helper_table_add(&libafl_exec_write_hook8_info); + libafl_exec_write_hookN_info.func = libafl_exec_write_hookN; + libafl_helper_table_add(&libafl_exec_write_hookN_info); + } + TCGv_i64 tmp0 = tcg_const_i64(libafl_id); + TCGv_i32 tmp1 = tcg_const_i32(size); + TCGTemp *tmp2[3] = { tcgv_i64_temp(tmp0), +#if TARGET_LONG_BITS == 32 + tcgv_i32_temp(addr), +#else + tcgv_i64_temp(addr), +#endif + tcgv_i32_temp(tmp1) + }; + tcg_gen_callN(libafl_exec_write_hookN, NULL, 3, tmp2); + tcg_temp_free_i32(tmp1); + tcg_temp_free_i64(tmp0); + } +} + void (*libafl_exec_cmp_hook1)(uint64_t id, uint8_t v0, uint8_t v1); void (*libafl_exec_cmp_hook2)(uint64_t id, uint16_t v0, uint16_t v1); diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index cec672f229..8014f44cc1 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -4184,6 +4184,12 @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn) tcg_gen_movi_i64(cpu_reg(s, rd), base + offset); } +//// --- Begin LibAFL code --- + +void libafl_gen_cmp(target_ulong pc, TCGv op0, TCGv op1, MemOp ot); + +//// --- End LibAFL code --- + /* * Add/subtract (immediate) * @@ -4215,6 +4221,16 @@ static void disas_add_sub_imm(DisasContext *s, uint32_t insn) imm <<= 12; } +//// --- Begin LibAFL code --- + + if (rd == 31 && sub_op) { // cmp xX, imm + TCGv_i64 tcg_imm = tcg_const_i64(imm); + libafl_gen_cmp(s->pc_curr, tcg_rn, tcg_imm, is_64bit ? MO_64 : MO_32); + tcg_temp_free_i64(tcg_imm); + } + +//// --- End LibAFL code --- + tcg_result = tcg_temp_new_i64(); if (!setflags) { if (sub_op) { @@ -4877,6 +4893,13 @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn) tcg_rm = read_cpu_reg(s, rm, sf); ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3); +//// --- Begin LibAFL code --- + + if (rd == 31 && sub_op) // cmp xX, xY + libafl_gen_cmp(s->pc_curr, tcg_rn, tcg_rm, sf ? MO_64 : MO_32); + +//// --- End LibAFL code --- + tcg_result = tcg_temp_new_i64(); if (!setflags) { @@ -4941,6 +4964,13 @@ static void disas_add_sub_reg(DisasContext *s, uint32_t insn) shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6); +//// --- Begin LibAFL code --- + + if (rd == 31 && sub_op) // cmp xX, xY + libafl_gen_cmp(s->pc_curr, tcg_rn, tcg_rm, sf ? MO_64 : MO_32); + +//// --- End LibAFL code --- + tcg_result = tcg_temp_new_i64(); if (!setflags) { @@ -5223,6 +5253,12 @@ static void disas_cc(DisasContext *s, uint32_t insn) } tcg_rn = cpu_reg(s, rn); +//// --- Begin LibAFL code --- + + libafl_gen_cmp(s->pc_curr, tcg_rn, tcg_y, sf ? MO_64 : MO_32); + +//// --- End LibAFL code --- + /* Set the flags for the new comparison. */ tcg_tmp = tcg_temp_new_i64(); if (op) { diff --git a/target/arm/translate.c b/target/arm/translate.c index 98f5925928..9cf7e649e5 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -5429,6 +5429,12 @@ static bool store_reg_kind(DisasContext *s, int rd, g_assert_not_reached(); } +//// --- Begin LibAFL code --- + +void libafl_gen_cmp(target_ulong pc, TCGv op0, TCGv op1, MemOp ot); + +//// --- End LibAFL code --- + /* * Data Processing (register) * @@ -5445,6 +5451,24 @@ static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a, gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc); tmp1 = load_reg(s, a->rn); +//// --- Begin LibAFL code --- + + if (gen == gen_sub_CC || /*gen == gen_add_CC ||*/ gen == gen_rsb_CC) { +#ifdef TARGET_AARCH64 + TCGv tmp1_64 = tcg_temp_new(); + TCGv tmp2_64 = tcg_temp_new(); + tcg_gen_extu_i32_i64(tmp1_64, tmp1); + tcg_gen_extu_i32_i64(tmp2_64, tmp2); + libafl_gen_cmp(s->pc_curr, tmp1_64, tmp2_64, MO_32); + tcg_temp_free(tmp1_64); + tcg_temp_free(tmp2_64); +#else + libafl_gen_cmp(s->pc_curr, tmp1, tmp2, MO_32); +#endif + } + +//// --- End LibAFL code --- + gen(tmp1, tmp1, tmp2); tcg_temp_free_i32(tmp2); @@ -5537,6 +5561,24 @@ static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a, tmp2 = tcg_const_i32(imm); tmp1 = load_reg(s, a->rn); +//// --- Begin LibAFL code --- + + if (gen == gen_sub_CC || /*gen == gen_add_CC ||*/ gen == gen_rsb_CC) { +#ifdef TARGET_AARCH64 + TCGv tmp1_64 = tcg_temp_new(); + TCGv tmp2_64 = tcg_temp_new(); + tcg_gen_extu_i32_i64(tmp1_64, tmp1); + tcg_gen_extu_i32_i64(tmp2_64, tmp2); + libafl_gen_cmp(s->pc_curr, tmp1_64, tmp2_64, MO_32); + tcg_temp_free(tmp1_64); + tcg_temp_free(tmp2_64); +#else + libafl_gen_cmp(s->pc_curr, tmp1, tmp2, MO_32); +#endif + } + +//// --- End LibAFL code --- + gen(tmp1, tmp1, tmp2); tcg_temp_free_i32(tmp2);