Generic hooks

This commit is contained in:
Andrea Fioraldi 2021-10-01 15:47:51 +02:00
parent 6065cb8a84
commit fe9d8cb50d
2 changed files with 82 additions and 2 deletions

View File

@ -20,6 +20,8 @@
//// --- Begin LibAFL code ---
#include "tcg/tcg-internal.h"
struct libafl_breakpoint {
target_ulong addr;
struct libafl_breakpoint* next;
@ -27,6 +29,15 @@ struct libafl_breakpoint {
extern struct libafl_breakpoint* libafl_qemu_breakpoints;
struct libafl_hook {
target_ulong addr;
void (*callback)(void);
TCGHelperInfo helper_info;
struct libafl_hook* next;
};
extern struct libafl_hook* libafl_qemu_hooks;
//// --- End LibAFL code ---
/* Pairs with tcg_clear_temp_count.
@ -110,6 +121,14 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
bp = bp->next;
}
struct libafl_hook* hk = libafl_qemu_hooks;
while (hk) {
if (hk->addr == db->pc_next) {
tcg_gen_callN(hk->callback, NULL, 0, NULL);
}
hk = hk->next;
}
//// --- End LibAFL code ---
/* Disassemble one instruction. The translate_insn hook should

65
cpu.c
View File

@ -42,6 +42,10 @@
//// --- Begin LibAFL code ---
#include "tcg/tcg-op.h"
#include "tcg/tcg-internal.h"
#include "exec/helper-head.h"
struct libafl_breakpoint {
target_ulong addr;
struct libafl_breakpoint* next;
@ -49,6 +53,17 @@ struct libafl_breakpoint {
struct libafl_breakpoint* libafl_qemu_breakpoints = NULL;
struct libafl_hook {
target_ulong addr;
void (*callback)(void);
TCGHelperInfo helper_info;
struct libafl_hook* next;
};
struct libafl_hook* libafl_qemu_hooks = NULL;
void libafl_helper_table_add(TCGHelperInfo* info);
static GByteArray *libafl_qemu_mem_buf = NULL;
int libafl_qemu_write_reg(int reg, uint8_t* val);
@ -56,6 +71,8 @@ int libafl_qemu_read_reg(int reg, uint8_t* val);
int libafl_qemu_num_regs(void);
int libafl_qemu_set_breakpoint(uint64_t addr);
int libafl_qemu_remove_breakpoint(uint64_t addr);
int libafl_qemu_insert_hook(uint64_t addr, void (*callback)(void));
int libafl_qemu_remove_hook(uint64_t addr);
int libafl_qemu_write_reg(int reg, uint8_t* val)
{
@ -126,6 +143,7 @@ int libafl_qemu_set_breakpoint(uint64_t addr)
int libafl_qemu_remove_breakpoint(uint64_t addr)
{
CPUState *cpu;
int r = 0;
target_ulong pc = (target_ulong) addr;
struct libafl_breakpoint** bp = &libafl_qemu_breakpoints;
@ -136,11 +154,54 @@ int libafl_qemu_remove_breakpoint(uint64_t addr)
}
*bp = (*bp)->next;
return 1;
r = 1;
}
bp = &(*bp)->next;
}
return 0;
return r;
}
int libafl_qemu_insert_hook(uint64_t addr, void (*callback)(void))
{
CPUState *cpu;
target_ulong pc = (target_ulong) addr;
CPU_FOREACH(cpu) {
libafl_breakpoint_invalidate(cpu, pc);
}
struct libafl_hook* hk = malloc(sizeof(struct libafl_hook));
hk->addr = pc;
hk->callback = callback;
hk->helper_info.func = callback;
hk->helper_info.name = "libafl_hook";
hk->helper_info.flags = dh_callflag(void);
hk->helper_info.typemask = dh_typemask(void, 0);
hk->next = libafl_qemu_hooks;
libafl_qemu_hooks = hk;
libafl_helper_table_add(&hk->helper_info);
return 1;
}
int libafl_qemu_remove_hook(uint64_t addr)
{
CPUState *cpu;
int r = 0;
target_ulong pc = (target_ulong) addr;
struct libafl_hook** hk = &libafl_qemu_hooks;
while (*hk) {
if ((*hk)->addr == pc) {
CPU_FOREACH(cpu) {
libafl_breakpoint_invalidate(cpu, pc);
}
*hk = (*hk)->next;
r = 1;
}
hk = &(*hk)->next;
}
return r;
}
//// --- End LibAFL code ---