Skip to content

Commit 30ad91f

Browse files
authored
Add systemmode hw_breakpoint libafl set/remove fns (#93)
* 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
1 parent 2b5e4bf commit 30ad91f

File tree

4 files changed

+58
-1
lines changed

4 files changed

+58
-1
lines changed

accel/kvm/kvm-accel-ops.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ static void *kvm_vcpu_thread_fn(void *arg)
6161
if (cpu_can_run(cpu)) {
6262
r = kvm_cpu_exec(cpu);
6363
if (r == EXCP_DEBUG) {
64-
cpu_handle_guest_debug(cpu);
64+
//// --- Begin LibAFL code ---
65+
// cpu_handle_guest_debug(cpu);
66+
cpu->stopped = true;
67+
libafl_qemu_trigger_breakpoint(cpu);
68+
//// --- End LibAFL code ---
6569
}
6670
}
6771
qemu_wait_io_event(cpu);

gdbstub/system.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
//// --- Begin LibAFL code ---
3535
#include "libafl/gdb.h"
36+
#include "gdbstub/enums.h"
3637
//// --- End LibAFL code ---
3738

3839
/* System emulation specific state */
@@ -655,6 +656,12 @@ bool gdb_supports_guest_debug(void)
655656
int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
656657
{
657658
const AccelOpsClass *ops = cpus_get_accel();
659+
//// --- Begin LibAFL code ---
660+
// HW breakpoints are reserved for LibAFL
661+
if (type == GDB_BREAKPOINT_HW) {
662+
return -ENOSYS;
663+
}
664+
//// --- End LibAFL code ---
658665
if (ops->insert_breakpoint) {
659666
return ops->insert_breakpoint(cs, type, addr, len);
660667
}

include/libafl/system.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
#pragma once
22

3+
#include "hw/core/cpu.h"
4+
#include "gdbstub/enums.h"
5+
#include "sysemu/accel-ops.h"
6+
#include "sysemu/cpus.h"
7+
8+
int libafl_qemu_set_hw_breakpoint(vaddr addr);
9+
int libafl_qemu_remove_hw_breakpoint(vaddr addr);
10+
311
void libafl_qemu_init(int argc, char** argv);

libafl/system.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,42 @@
33

44
#include "libafl/system.h"
55

6+
int libafl_qemu_toggle_hw_breakpoint(vaddr addr, bool set);
7+
68
void libafl_qemu_init(int argc, char** argv) { qemu_init(argc, argv); }
9+
10+
int libafl_qemu_set_hw_breakpoint(vaddr addr)
11+
{
12+
return libafl_qemu_toggle_hw_breakpoint(addr, true);
13+
}
14+
15+
int libafl_qemu_remove_hw_breakpoint(vaddr addr)
16+
{
17+
return libafl_qemu_toggle_hw_breakpoint(addr, false);
18+
}
19+
20+
int libafl_qemu_toggle_hw_breakpoint(vaddr addr, bool set) {
21+
const int type = GDB_BREAKPOINT_HW;
22+
const vaddr len = 1;
23+
const AccelOpsClass *ops = cpus_get_accel();
24+
25+
CPUState *cs = first_cpu;
26+
int ret = 0;
27+
28+
if (!ops->insert_breakpoint) {
29+
return -ENOSYS;
30+
}
31+
32+
// let's add/remove the breakpoint on the first CPU.
33+
// Both TCG and KVM propagate it to all CPUs internally.
34+
if (set) {
35+
ret = ops->insert_breakpoint(cs, type, addr, len);
36+
} else {
37+
ret = ops->remove_breakpoint(cs, type, addr, len);
38+
}
39+
if (ret != 0) {
40+
return ret;
41+
}
42+
43+
return 0;
44+
}

0 commit comments

Comments
 (0)