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 ("\n Launching 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 ("\n Cleaning 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