Jit edge coverage hook

This commit is contained in:
Andrea Fioraldi 2023-11-24 13:43:26 +01:00
parent 34b0d11943
commit b946fe4618
6 changed files with 80 additions and 4 deletions

View File

@ -362,7 +362,7 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
hook->cur_id = 0; hook->cur_id = 0;
if (hook->gen) if (hook->gen)
hook->cur_id = hook->gen(hook->data, src_block, dst_block); hook->cur_id = hook->gen(hook->data, src_block, dst_block);
if (hook->cur_id != (uint64_t)-1 && hook->helper_info.func) if (hook->cur_id != (uint64_t)-1 && (hook->helper_info.func || hook->jit))
no_exec_hook = 0; no_exec_hook = 0;
hook = hook->next; hook = hook->next;
} }
@ -417,10 +417,11 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
tcg_ctx->cpu = env_cpu(env); tcg_ctx->cpu = env_cpu(env);
hook = libafl_edge_hooks; hook = libafl_edge_hooks;
size_t hcount = 0; size_t hcount = 0, hins = 0;
while (hook) { while (hook) {
if (hook->cur_id != (uint64_t)-1 && hook->helper_info.func) { if (hook->cur_id != (uint64_t)-1 && hook->helper_info.func) {
hcount++; hcount++;
hins++;
TCGv_i64 tmp0 = tcg_constant_i64(hook->data); TCGv_i64 tmp0 = tcg_constant_i64(hook->data);
TCGv_i64 tmp1 = tcg_constant_i64(hook->cur_id); TCGv_i64 tmp1 = tcg_constant_i64(hook->cur_id);
TCGTemp *tmp2[2] = { tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1) }; TCGTemp *tmp2[2] = { tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1) };
@ -428,12 +429,16 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
tcg_temp_free_i64(tmp0); tcg_temp_free_i64(tmp0);
tcg_temp_free_i64(tmp1); tcg_temp_free_i64(tmp1);
} }
if (hook->cur_id != (uint64_t)-1 && hook->jit) {
hcount++;
hins += hook->jit(hook->data, hook->cur_id);
}
hook = hook->next; hook = hook->next;
} }
tcg_gen_goto_tb(0); tcg_gen_goto_tb(0);
tcg_gen_exit_tb(tb, 0); tcg_gen_exit_tb(tb, 0);
tb->size = hcount; tb->size = hcount;
tb->icount = hcount; tb->icount = hins;
assert(tb->size != 0); assert(tb->size != 0);
tcg_ctx->cpu = NULL; tcg_ctx->cpu = NULL;

View File

@ -221,6 +221,18 @@ size_t libafl_add_edge_hook(uint64_t (*gen)(uint64_t data, target_ulong src, tar
GEN_REMOVE_HOOK(edge) GEN_REMOVE_HOOK(edge)
void libafl_qemu_edge_hook_set_jit(size_t num, size_t (*jit)(uint64_t data, uint64_t id)) {
struct libafl_edge_hook* hk = libafl_edge_hooks;
while (hk) {
if (hk->num == num) {
hk->jit = jit;
return;
} else {
hk = hk->next;
}
}
}
static TCGHelperInfo libafl_exec_block_hook_info = { static TCGHelperInfo libafl_exec_block_hook_info = {
.func = NULL, .name = "libafl_exec_block_hook", \ .func = NULL, .name = "libafl_exec_block_hook", \
.flags = dh_callflag(void), \ .flags = dh_callflag(void), \

View File

@ -57,6 +57,7 @@ int libafl_qemu_remove_backdoor_hook(size_t num, int invalidate);
struct libafl_edge_hook { struct libafl_edge_hook {
uint64_t (*gen)(uint64_t data, target_ulong src, target_ulong dst); uint64_t (*gen)(uint64_t data, target_ulong src, target_ulong dst);
// void (*exec)(uint64_t data, uint64_t id); // void (*exec)(uint64_t data, uint64_t id);
size_t (*jit)(uint64_t data, uint64_t id); // optional opt
uint64_t data; uint64_t data;
size_t num; size_t num;
uint64_t cur_id; uint64_t cur_id;
@ -70,6 +71,7 @@ size_t libafl_add_edge_hook(uint64_t (*gen)(uint64_t data, target_ulong src, tar
void (*exec)(uint64_t data, uint64_t id), void (*exec)(uint64_t data, uint64_t id),
uint64_t data); uint64_t data);
int libafl_qemu_remove_edge_hook(size_t num, int invalidate); int libafl_qemu_remove_edge_hook(size_t num, int invalidate);
void libafl_qemu_edge_hook_set_jit(size_t num, size_t (*jit)(uint64_t, uint64_t)); // no param names to avoid to be marked as safe
struct libafl_block_hook { struct libafl_block_hook {
uint64_t (*gen)(uint64_t data, target_ulong pc); uint64_t (*gen)(uint64_t data, target_ulong pc);

45
libafl_extras/jit.c Normal file
View File

@ -0,0 +1,45 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "exec/exec-all.h"
#include "jit.h"
#ifndef TARGET_LONG_BITS
#error "TARGET_LONG_BITS not defined"
#endif
/*
pub extern "C" fn trace_edge_hitcount(id: u64, _data: u64) {
unsafe {
EDGES_MAP[id as usize] = EDGES_MAP[id as usize].wrapping_add(1);
}
}
pub extern "C" fn trace_edge_single(id: u64, _data: u64) {
unsafe {
EDGES_MAP[id as usize] = 1;
}
}
*/
// from libafl_targets coverage.rs
// correct size doesn't matter here
uint8_t __afl_area_ptr_local[65536] __attribute__((weak));
size_t libafl_jit_trace_edge_hitcount(uint64_t data, uint64_t id) {
TCGv_ptr map_ptr = tcg_constant_ptr(__afl_area_ptr_local);
TCGv_i32 counter = tcg_temp_new_i32();
tcg_gen_ld8u_i32(counter, map_ptr, (tcg_target_long)id);
tcg_gen_addi_i32(counter, counter, 1);
tcg_gen_st8_i32(counter, map_ptr, (tcg_target_long)id);
return 3; // # instructions
}
size_t libafl_jit_trace_edge_single(uint64_t data, uint64_t id) {
TCGv_ptr map_ptr = tcg_constant_ptr(__afl_area_ptr_local);
TCGv_i32 counter = tcg_temp_new_i32();
tcg_gen_movi_i32(counter, 1);
tcg_gen_st8_i32(counter, map_ptr, (tcg_target_long)id);
return 2; // # instructions
}

12
libafl_extras/jit.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "tcg/tcg-op.h"
#include "tcg/tcg-internal.h"
#include "tcg/tcg-temp-internal.h"
size_t libafl_jit_trace_edge_hitcount(uint64_t data, uint64_t id);
size_t libafl_jit_trace_edge_single(uint64_t data, uint64_t id);

View File

@ -3,4 +3,4 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files(
'syx-snapshot/syx-snapshot.c', 'syx-snapshot/syx-snapshot.c',
'syx-snapshot/channel-buffer-writeback.c', 'syx-snapshot/channel-buffer-writeback.c',
)]) )])
specific_ss.add(files('exit.c', 'hook.c')) specific_ss.add(files('exit.c', 'hook.c', 'jit.c'))