re-introduce native breakpoints

This commit is contained in:
Alwin Berger 2023-03-13 14:46:09 +01:00
parent a67a70d7f8
commit e144fb9fdf
2 changed files with 145 additions and 1 deletions

View File

@ -62,6 +62,16 @@ int libafl_qemu_read_reg(CPUState* cpu, int reg, uint8_t* val);
int libafl_qemu_num_regs(CPUState* cpu);
//// --- Begin LibAFL code ---
int libafl_qemu_set_breakpoint(target_ulong addr);
int libafl_qemu_remove_breakpoint(target_ulong addr);
void libafl_qemu_set_native_breakpoint( vaddr );
void libafl_qemu_remove_native_breakpoint( vaddr );
size_t libafl_qemu_set_hook(target_ulong pc, void (*callback)(target_ulong, uint64_t),
uint64_t data, int invalidate);
size_t libafl_qemu_remove_hooks_at(target_ulong addr, int invalidate);
int libafl_qemu_remove_hook(size_t num, int invalidate);
struct libafl_hook* libafl_search_hook(target_ulong addr);
void libafl_flush_jit(void);
#ifndef CONFIG_USER_ONLY
hwaddr libafl_qemu_current_paging_id(CPUState* cpu);
@ -175,6 +185,137 @@ hwaddr libafl_qemu_current_paging_id(CPUState* cpu)
}
#endif
int libafl_qemu_remove_breakpoint(target_ulong pc)
{
CPUState *cpu;
int r = 0;
struct libafl_breakpoint** bp = &libafl_qemu_breakpoints;
while (*bp) {
if ((*bp)->addr == pc) {
CPU_FOREACH(cpu) {
libafl_breakpoint_invalidate(cpu, pc);
}
*bp = (*bp)->next;
r = 1;
} else {
bp = &(*bp)->next;
}
}
return r;
}
void libafl_qemu_set_native_breakpoint(vaddr pc)
{
CPUState *cpu;
CPU_FOREACH(cpu) {
cpu_breakpoint_insert(cpu, pc, BP_GDB, NULL);
}
}
void libafl_qemu_remove_native_breakpoint(vaddr pc)
{
CPUState *cpu;
CPU_FOREACH(cpu) {
cpu_breakpoint_remove(cpu, pc, BP_GDB);
}
}
size_t libafl_qemu_set_hook(target_ulong pc, void (*callback)(target_ulong, uint64_t),
uint64_t data, int invalidate)
{
CPUState *cpu;
if (invalidate) {
CPU_FOREACH(cpu) {
libafl_breakpoint_invalidate(cpu, pc);
}
}
size_t idx = LIBAFL_TABLES_HASH(pc);
struct libafl_hook* hk = calloc(sizeof(struct libafl_hook), 1);
hk->addr = pc;
hk->callback = callback;
hk->data = data;
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) | dh_typemask(tl, 1) | dh_typemask(i64, 2);
hk->num = libafl_qemu_hooks_num++;
hk->next = libafl_qemu_hooks[idx];
libafl_qemu_hooks[idx] = hk;
return hk->num;
}
size_t libafl_qemu_remove_hooks_at(target_ulong addr, int invalidate)
{
CPUState *cpu;
size_t r = 0;
size_t idx = LIBAFL_TABLES_HASH(addr);
struct libafl_hook** hk = &libafl_qemu_hooks[idx];
while (*hk) {
if ((*hk)->addr == addr) {
if (invalidate) {
CPU_FOREACH(cpu) {
libafl_breakpoint_invalidate(cpu, addr);
}
}
void *tmp = *hk;
*hk = (*hk)->next;
free(tmp);
r++;
} else {
hk = &(*hk)->next;
}
}
return r;
}
int libafl_qemu_remove_hook(size_t num, int invalidate)
{
CPUState *cpu;
size_t idx;
for (idx = 0; idx < LIBAFL_TABLES_SIZE; ++idx) {
struct libafl_hook** hk = &libafl_qemu_hooks[idx];
while (*hk) {
if ((*hk)->num == num) {
if (invalidate) {
CPU_FOREACH(cpu) {
libafl_breakpoint_invalidate(cpu, (*hk)->addr);
}
}
void *tmp = *hk;
*hk = (*hk)->next;
free(tmp);
return 1;
} else {
hk = &(*hk)->next;
}
}
}
return 0;
}
struct libafl_hook* libafl_search_hook(target_ulong addr)
{
size_t idx = LIBAFL_TABLES_HASH(addr);
struct libafl_hook* hk = libafl_qemu_hooks[idx];
while (hk) {
if (hk->addr == addr) {
return hk;
}
hk = hk->next;
}
return NULL;
}
//// --- End LibAFL code ---
void libafl_flush_jit(void)

View File

@ -313,7 +313,10 @@ void cpu_handle_guest_debug(CPUState *cpu)
cpu_single_step(cpu, 0);
}
} else {
gdb_set_stop_cpu(cpu);
/* Begin LibAFL changes */
// With LibAFL Breakpoints there is no gdb attached.
// gdb_set_stop_cpu(cpu);
/* End LibAFL changes */
qemu_system_debug_request();
cpu->stopped = true;
}