Skip to content

Commit

Permalink
Add systemmode hw_breakpoint libafl set/remove fns (#93)
Browse files Browse the repository at this point in the history
* Add systemmode hw_breakpoint libafl set/remove fns

* very bad kvm breakpoint hook yolo

* cleanup

* Prevent GDB from using HW breakpoints

* fix: hw breakpoint add/rm no loop over CPUs
  • Loading branch information
Marcondiro authored Jan 24, 2025
1 parent 2b5e4bf commit 30ad91f
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
6 changes: 5 additions & 1 deletion accel/kvm/kvm-accel-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ static void *kvm_vcpu_thread_fn(void *arg)
if (cpu_can_run(cpu)) {
r = kvm_cpu_exec(cpu);
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
//// --- Begin LibAFL code ---
// cpu_handle_guest_debug(cpu);
cpu->stopped = true;
libafl_qemu_trigger_breakpoint(cpu);
//// --- End LibAFL code ---
}
}
qemu_wait_io_event(cpu);
Expand Down
7 changes: 7 additions & 0 deletions gdbstub/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

//// --- Begin LibAFL code ---
#include "libafl/gdb.h"
#include "gdbstub/enums.h"
//// --- End LibAFL code ---

/* System emulation specific state */
Expand Down Expand Up @@ -655,6 +656,12 @@ bool gdb_supports_guest_debug(void)
int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
{
const AccelOpsClass *ops = cpus_get_accel();
//// --- Begin LibAFL code ---
// HW breakpoints are reserved for LibAFL
if (type == GDB_BREAKPOINT_HW) {
return -ENOSYS;
}
//// --- End LibAFL code ---
if (ops->insert_breakpoint) {
return ops->insert_breakpoint(cs, type, addr, len);
}
Expand Down
8 changes: 8 additions & 0 deletions include/libafl/system.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
#pragma once

#include "hw/core/cpu.h"
#include "gdbstub/enums.h"
#include "sysemu/accel-ops.h"
#include "sysemu/cpus.h"

int libafl_qemu_set_hw_breakpoint(vaddr addr);
int libafl_qemu_remove_hw_breakpoint(vaddr addr);

void libafl_qemu_init(int argc, char** argv);
38 changes: 38 additions & 0 deletions libafl/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,42 @@

#include "libafl/system.h"

int libafl_qemu_toggle_hw_breakpoint(vaddr addr, bool set);

void libafl_qemu_init(int argc, char** argv) { qemu_init(argc, argv); }

int libafl_qemu_set_hw_breakpoint(vaddr addr)
{
return libafl_qemu_toggle_hw_breakpoint(addr, true);
}

int libafl_qemu_remove_hw_breakpoint(vaddr addr)
{
return libafl_qemu_toggle_hw_breakpoint(addr, false);
}

int libafl_qemu_toggle_hw_breakpoint(vaddr addr, bool set) {
const int type = GDB_BREAKPOINT_HW;
const vaddr len = 1;
const AccelOpsClass *ops = cpus_get_accel();

CPUState *cs = first_cpu;
int ret = 0;

if (!ops->insert_breakpoint) {
return -ENOSYS;
}

// let's add/remove the breakpoint on the first CPU.
// Both TCG and KVM propagate it to all CPUs internally.
if (set) {
ret = ops->insert_breakpoint(cs, type, addr, len);
} else {
ret = ops->remove_breakpoint(cs, type, addr, len);
}
if (ret != 0) {
return ret;
}

return 0;
}

0 comments on commit 30ad91f

Please sign in to comment.