Skip to content

Commit

Permalink
Merge pull request #42 from doronz88/refactor/bp
Browse files Browse the repository at this point in the history
hilda_client: refactor `bp` to also accept a name instead of an address
  • Loading branch information
doronz88 authored Jan 31, 2024
2 parents 91a2e6b + a0887ba commit 762be56
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 16 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,6 @@ Here is a gist of methods you can access from `p`:
- Get the plist embedded inside the process' __LINKEDIT section.
- `bp`
- Add a breakpoint
- `place_future_breakpoint`
- Place a breakpoint on a function that will resolve in the future of the process lifecycle
- `show_hilda_breakpoints`
- Show existing breakpoints created by Hilda.
- `show_commands`
Expand Down Expand Up @@ -444,6 +442,12 @@ def scripted_breakpoint(hilda, *args):


s.bp(scripted_breakpoint)

# Place a breakpoint at a symbol not yet loaded by it's name
p.bp('symbol_name')

# In case you need to specify a specific library it's loaded from
p.bp('symbol_name', module_name='ModuleName')
```

## Globalized symbols
Expand Down
32 changes: 18 additions & 14 deletions hilda/hilda_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from datetime import datetime, timezone
from functools import cached_property
from pathlib import Path
from typing import Any, List, Optional, Union
from typing import Any, Callable, List, Optional, Union

import hexdump
import IPython
Expand Down Expand Up @@ -556,33 +556,38 @@ def print_proc_entitlements(self):
entitlements = str(linkedit_data[linkedit_data.find(b'<?xml'):].split(b'\xfa', 1)[0], 'utf8')
print(highlight(entitlements, XmlLexer(), TerminalTrueColorFormatter()))

def bp(self, address, callback=None, condition: str = None, forced=False, **options) -> lldb.SBBreakpoint:
def bp(self, address_or_name: Union[int, str], callback: Optional[Callable] = None, condition: str = None,
forced=False, module_name: Optional[str] = None, **options) -> lldb.SBBreakpoint:
"""
Add a breakpoint
:param address:
:param address_or_name:
:param condition: set as a conditional breakpoint using lldb expression
:param callback: callback(hilda, *args) to be called
:param forced: whether the breakpoint should be protected frm usual removal.
:param options:
:return:
:param module_name: Specify module name to place the BP in (used with `address_or_name` when using a name)
:param options: can contain an `override` keyword to specify if to override an existing BP
:return: native LLDB breakpoint
"""
if address in [bp.address for bp in self.breakpoints.values()]:
if address_or_name in [bp.address for bp in self.breakpoints.values()]:
override = True if options.get('override', True) else False
if override or prompts.prompt_for_confirmation('A breakpoint already exist in given location. '
'Would you like to delete the previous one?', True):
breakpoints = list(self.breakpoints.items())
for bp_id, bp in breakpoints:
if address == bp.address:
if address_or_name == bp.address:
self.remove_hilda_breakpoint(bp_id)

bp = self.target.BreakpointCreateByAddress(address)
if isinstance(address_or_name, int):
bp = self.target.BreakpointCreateByAddress(address_or_name)
elif isinstance(address_or_name, str):
bp = self.target.BreakpointCreateByName(address_or_name)

if condition is not None:
bp.SetCondition(condition)

# add into Hilda's internal list of breakpoints
self.breakpoints[bp.id] = HildaClient.Breakpoint(
address=address, options=options, forced=forced, callback=callback
address=address_or_name, options=options, forced=forced, callback=callback
)

if callback is not None:
Expand All @@ -591,10 +596,6 @@ def bp(self, address, callback=None, condition: str = None, forced=False, **opti
self.log_info(f'Breakpoint #{bp.id} has been set')
return bp

def place_future_breakpoint(self, symbol_name: str) -> None:
""" Place a breakpoint on a function that will resolve in the future of the process lifecycle """
self.lldb_handle_command(f'b {symbol_name}')

def bp_callback_router(self, frame, bp_loc, *_):
"""
Route the breakpoint callback the specific breakpoint callback.
Expand All @@ -612,7 +613,10 @@ def show_hilda_breakpoints(self):
""" Show existing breakpoints created by Hilda. """
for bp_id, bp in self.breakpoints.items():
print(f'🚨 Breakpoint #{bp_id}: Forced: {bp.forced}')
print(f'\tAddress: 0x{bp.address:x}')
if isinstance(bp.address, int):
print(f'\tAddress: 0x{bp.address:x}')
elif isinstance(bp.address, str):
print(f'\tName: {bp.address}')
print(f'\tOptions: {bp.options}')

def save(self, filename=None):
Expand Down

0 comments on commit 762be56

Please sign in to comment.