Skip to content

Commit 7b54f45

Browse files
Copilotxusheng6
andcommitted
Complete hardware breakpoint implementation with examples
Co-authored-by: xusheng6 <[email protected]>
1 parent b7a45ba commit 7b54f45

File tree

3 files changed

+202
-0
lines changed

3 files changed

+202
-0
lines changed

core/adapters/esrevenadapter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,15 @@ DebugBreakpoint EsrevenAdapter::AddBreakpoint(const std::uintptr_t address, unsi
411411
DebugBreakpoint(address)) != this->m_debugBreakpoints.end())
412412
return {};
413413

414+
// Handle hardware breakpoint types
415+
if (breakpoint_type != SoftwareBreakpoint)
416+
{
417+
if (AddHardwareBreakpoint(address, (DebugBreakpointType)breakpoint_type))
418+
return DebugBreakpoint(address, 0, true); // Use 0 as ID for hardware breakpoints for now
419+
else
420+
return DebugBreakpoint{};
421+
}
422+
414423
/* TODO: replace %d with the actual breakpoint size as it differs per architecture */
415424
size_t kind = 1;
416425
if (m_remoteArch == "aarch64")

core/adapters/gdbadapter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,15 @@ DebugBreakpoint GdbAdapter::AddBreakpoint(const std::uintptr_t address, unsigned
409409
DebugBreakpoint(address)) != this->m_debugBreakpoints.end())
410410
return {};
411411

412+
// Handle hardware breakpoint types
413+
if (breakpoint_type != SoftwareBreakpoint)
414+
{
415+
if (AddHardwareBreakpoint(address, (DebugBreakpointType)breakpoint_type))
416+
return DebugBreakpoint(address, 0, true); // Use 0 as ID for hardware breakpoints for now
417+
else
418+
return DebugBreakpoint{};
419+
}
420+
412421
/* TODO: replace %d with the actual breakpoint size as it differs per architecture */
413422
size_t kind = 1;
414423
if (m_remoteArch == "aarch64")
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Example script demonstrating hardware breakpoint usage
4+
5+
This script shows how to use the new hardware breakpoint functionality
6+
introduced in the debugger.
7+
"""
8+
9+
try:
10+
from binaryninja import load
11+
from debugger import DebuggerController, DebugBreakpointType
12+
except ImportError:
13+
from binaryninja import load
14+
from binaryninja.debugger import DebuggerController, DebugBreakpointType
15+
16+
17+
def hardware_breakpoint_example(binary_path):
18+
"""
19+
Example showing how to use hardware breakpoints
20+
"""
21+
# Load the binary
22+
bv = load(binary_path)
23+
if not bv:
24+
print(f"Failed to load binary: {binary_path}")
25+
return
26+
27+
# Get the debugger controller
28+
controller = DebuggerController(bv)
29+
30+
print("Setting up hardware breakpoints...")
31+
32+
# Example 1: Hardware execution breakpoint at entry point
33+
entry_point = bv.entry_point
34+
print(f"Setting hardware execution breakpoint at entry point: 0x{entry_point:x}")
35+
success = controller.add_hardware_breakpoint(
36+
entry_point,
37+
DebugBreakpointType.HardwareExecuteBreakpoint
38+
)
39+
if success:
40+
print("✓ Hardware execution breakpoint set successfully")
41+
else:
42+
print("✗ Failed to set hardware execution breakpoint")
43+
44+
# Example 2: Hardware write watchpoint on a data address
45+
# In a real scenario, you'd find a data address from your binary analysis
46+
data_address = 0x1000 # Example address
47+
print(f"Setting hardware write watchpoint at 0x{data_address:x} (4 bytes)")
48+
success = controller.add_hardware_breakpoint(
49+
data_address,
50+
DebugBreakpointType.HardwareWriteBreakpoint,
51+
4 # Watch 4 bytes
52+
)
53+
if success:
54+
print("✓ Hardware write watchpoint set successfully")
55+
else:
56+
print("✗ Failed to set hardware write watchpoint")
57+
58+
# Example 3: Hardware read watchpoint
59+
print(f"Setting hardware read watchpoint at 0x{data_address + 8:x} (8 bytes)")
60+
success = controller.add_hardware_breakpoint(
61+
data_address + 8,
62+
DebugBreakpointType.HardwareReadBreakpoint,
63+
8 # Watch 8 bytes
64+
)
65+
if success:
66+
print("✓ Hardware read watchpoint set successfully")
67+
else:
68+
print("✗ Failed to set hardware read watchpoint")
69+
70+
# Example 4: Hardware access (read/write) watchpoint
71+
print(f"Setting hardware access watchpoint at 0x{data_address + 16:x} (1 byte)")
72+
success = controller.add_hardware_breakpoint(
73+
data_address + 16,
74+
DebugBreakpointType.HardwareAccessBreakpoint,
75+
1 # Watch 1 byte
76+
)
77+
if success:
78+
print("✓ Hardware access watchpoint set successfully")
79+
else:
80+
print("✗ Failed to set hardware access watchpoint")
81+
82+
print("\nLaunching target...")
83+
stop_reason = controller.launch_and_wait()
84+
print(f"Target stopped with reason: {stop_reason}")
85+
86+
# Continue execution to test breakpoints
87+
print("Continuing execution...")
88+
stop_reason = controller.go_and_wait()
89+
print(f"Target stopped with reason: {stop_reason}")
90+
91+
# Clean up - remove hardware breakpoints
92+
print("\nCleaning up hardware breakpoints...")
93+
94+
controller.remove_hardware_breakpoint(
95+
entry_point,
96+
DebugBreakpointType.HardwareExecuteBreakpoint
97+
)
98+
99+
controller.remove_hardware_breakpoint(
100+
data_address,
101+
DebugBreakpointType.HardwareWriteBreakpoint,
102+
4
103+
)
104+
105+
controller.remove_hardware_breakpoint(
106+
data_address + 8,
107+
DebugBreakpointType.HardwareReadBreakpoint,
108+
8
109+
)
110+
111+
controller.remove_hardware_breakpoint(
112+
data_address + 16,
113+
DebugBreakpointType.HardwareAccessBreakpoint,
114+
1
115+
)
116+
117+
print("Hardware breakpoints removed")
118+
119+
# Quit the debugger
120+
controller.quit_and_wait()
121+
print("Debugging session ended")
122+
123+
124+
def backend_command_example(binary_path):
125+
"""
126+
Example showing how to use hardware breakpoints via backend commands
127+
(useful for advanced scenarios or when the API is not sufficient)
128+
"""
129+
bv = load(binary_path)
130+
controller = DebuggerController(bv)
131+
132+
print("Using backend commands for hardware breakpoints...")
133+
134+
# Launch the target first
135+
controller.launch_and_wait()
136+
137+
# For LLDB adapter:
138+
if controller.get_adapter_type() == "LLDB":
139+
print("Using LLDB commands:")
140+
141+
# Hardware execution breakpoint
142+
result = controller.send_command("breakpoint set --address 0x100000000 -H")
143+
print(f"LLDB hardware execution breakpoint: {result}")
144+
145+
# Hardware write watchpoint
146+
result = controller.send_command("watchpoint set expression -w write -s 4 -- 0x100001000")
147+
print(f"LLDB hardware write watchpoint: {result}")
148+
149+
# List breakpoints and watchpoints
150+
result = controller.send_command("breakpoint list")
151+
print(f"LLDB breakpoints: {result}")
152+
153+
result = controller.send_command("watchpoint list")
154+
print(f"LLDB watchpoints: {result}")
155+
156+
# For GDB RSP adapter:
157+
elif "GDB" in controller.get_adapter_type():
158+
print("Using GDB RSP commands:")
159+
160+
# Hardware execution breakpoint (Z1)
161+
result = controller.send_command("Z1,100000000,1")
162+
print(f"GDB hardware execution breakpoint: {result}")
163+
164+
# Hardware write watchpoint (Z2)
165+
result = controller.send_command("Z2,100001000,4")
166+
print(f"GDB hardware write watchpoint: {result}")
167+
168+
controller.quit_and_wait()
169+
170+
171+
if __name__ == "__main__":
172+
import sys
173+
174+
if len(sys.argv) != 2:
175+
print("Usage: python hardware_breakpoints.py <binary_path>")
176+
sys.exit(1)
177+
178+
binary_path = sys.argv[1]
179+
180+
print("=== Hardware Breakpoint API Example ===")
181+
hardware_breakpoint_example(binary_path)
182+
183+
print("\n=== Backend Command Example ===")
184+
backend_command_example(binary_path)

0 commit comments

Comments
 (0)