libdebug.debugger package#

Submodules#

libdebug.debugger.debugger module#

class libdebug.debugger.debugger.Debugger[source]#

Bases: object

The Debugger class is the main class of libdebug. It contains all the methods needed to run and interact with the process.

post_init_(internal_debugger: InternalDebugger) None[source]#

Do not use this constructor directly. Use the debugger function instead.

run() None[source]#

Starts the process and waits for it to stop.

attach(pid: int) None[source]#

Attaches to an existing process.

detach() None[source]#

Detaches from the process.

kill() None[source]#

Kills the process.

terminate() None[source]#

Terminates the background thread.

The debugger object cannot be used after this method is called. This method should only be called to free up resources when the debugger object is no longer needed.

cont() None[source]#

Continues the process.

interrupt() None[source]#

Interrupts the process.

wait() None[source]#

Waits for the process to stop.

maps() list[MemoryMap][source]#

Returns the memory maps of the process.

print_maps() None[source]#

Prints the memory maps of the process.

breakpoint(position: int | str, hardware: bool = False, condition: str | None = None, length: int = 1, callback: None | Callable[[ThreadContext, Breakpoint], None] = None, file: str = 'default') Breakpoint[source]#

Sets a breakpoint at the specified location.

Parameters:
  • position (int | bytes) – The location of the breakpoint.

  • hardware (bool, optional) – Whether the breakpoint should be hardware-assisted or purely software.

  • False. (Defaults to)

  • condition (str, optional) – The trigger condition for the breakpoint. Defaults to None.

  • length (int, optional) – The length of the breakpoint. Only for watchpoints. Defaults to 1.

  • callback (Callable[[ThreadContext, Breakpoint], None], optional) – A callback to be called when the

  • None. (breakpoint is hit. Defaults to)

  • file (str, optional) – The user-defined backing file to resolve the address in. Defaults to “default”

  • address ((libdebug will first try to solve the address as an absolute)

  • w.r.t. (then as a relative address)

  • file). (the "binary" map)

watchpoint(position: int | str, condition: str = 'w', length: int = 1, callback: None | Callable[[ThreadContext, Breakpoint], None] = None, file: str = 'default') Breakpoint[source]#

Sets a watchpoint at the specified location. Internally, watchpoints are implemented as breakpoints.

Parameters:
  • position (int | bytes) – The location of the breakpoint.

  • condition (str, optional) – The trigger condition for the watchpoint (either “r”, “rw” or “x”).

  • "w". (Defaults to)

  • length (int, optional) – The size of the word in being watched (1, 2, 4 or 8). Defaults to 1.

  • callback (Callable[[ThreadContext, Breakpoint], None], optional) – A callback to be called when the

  • None. (watchpoint is hit. Defaults to)

  • file (str, optional) – The user-defined backing file to resolve the address in. Defaults to “default”

  • address ((libdebug will first try to solve the address as an absolute)

  • w.r.t. (then as a relative address)

  • file). (the "binary" map)

hook_signal(signal_to_hook: int | str, callback: None | Callable[[ThreadContext, int], None] = None, hook_hijack: bool = True) SignalHook[source]#

Hooks a signal in the target process.

Parameters:
  • signal_to_hook (int | str) – The signal to hook.

  • callback (Callable[[ThreadContext, int], None], optional) – A callback to be called when the signal is received. Defaults to None.

  • hook_hijack (bool, optional) – Whether to execute the hook/hijack of the new signal after an hijack or not. Defaults to False.

unhook_signal(hook: SignalHook) None[source]#

Unhooks a signal in the target process.

Parameters:

hook (SignalHook) – The signal hook to unhook.

hijack_signal(original_signal: int | str, new_signal: int | str, hook_hijack: bool = True) None[source]#

Hijacks a signal in the target process.

Parameters:
  • original_signal (int | str) – The signal to hijack.

  • new_signal (int | str) – The signal to replace the original signal with.

  • hook_hijack (bool, optional) – Whether to execute the hook/hijack of the new signal after the hijack or not. Defaults to True.

hook_syscall(syscall: int | str, on_enter: Callable[[ThreadContext, int], None] | None = None, on_exit: Callable[[ThreadContext, int], None] | None = None, hook_hijack: bool = True) SyscallHook[source]#

Hooks a syscall in the target process.

Parameters:
  • syscall (int | str) – The syscall name or number to hook.

  • on_enter (Callable[[ThreadContext, int], None], optional) – The callback to execute when the syscall is entered. Defaults to None.

  • on_exit (Callable[[ThreadContext, int], None], optional) – The callback to execute when the syscall is exited. Defaults to None.

  • hook_hijack (bool, optional) – Whether the syscall after the hijack should be hooked. Defaults to True.

Returns:

The syscall hook object.

Return type:

SyscallHook

unhook_syscall(hook: SyscallHook) None[source]#

Unhooks a syscall in the target process.

Parameters:

hook (SyscallHook) – The syscall hook to unhook.

hijack_syscall(original_syscall: int | str, new_syscall: int | str, hook_hijack: bool = True, **kwargs: int) SyscallHook[source]#

Hijacks a syscall in the target process.

Parameters:
  • original_syscall (int | str) – The syscall name or number to hijack.

  • new_syscall (int | str) – The syscall name or number to replace the original syscall with.

  • hook_hijack (bool, optional) – Whether the syscall after the hijack should be hooked. Defaults to True.

  • **kwargs – (int, optional): The arguments to pass to the new syscall.

Returns:

The syscall hook object.

Return type:

SyscallHook

migrate_to_gdb(open_in_new_process: bool = True) None[source]#

Migrates the current debugging session to GDB.

r() None[source]#

Alias for the run method.

Starts the process and waits for it to stop.

c() None[source]#

Alias for the cont method.

Continues the process.

int() None[source]#

Alias for the interrupt method.

Interrupts the process.

w() None[source]#

Alias for the wait method.

Waits for the process to stop.

bp(position: int | str, hardware: bool = False, condition: str | None = None, length: int = 1, callback: None | Callable[[ThreadContext, Breakpoint], None] = None, file: str = 'default') Breakpoint[source]#

Alias for the breakpoint method.

Parameters:
  • position (int | bytes) – The location of the breakpoint.

  • hardware (bool, optional) – Whether the breakpoint should be hardware-assisted or purely software.

  • False. (Defaults to)

  • condition (str, optional) – The trigger condition for the breakpoint. Defaults to None.

  • length (int, optional) – The length of the breakpoint. Only for watchpoints. Defaults to 1.

  • callback (Callable[[ThreadContext, Breakpoint], None], optional) – A callback to be called when the

  • None. (breakpoint is hit. Defaults to)

  • file (str, optional) – The user-defined backing file to resolve the address in. Defaults to “default”

  • address ((libdebug will first try to solve the address as an absolute)

  • w.r.t. (then as a relative address)

  • file). (the "binary" map)

wp(position: int | str, condition: str = 'w', length: int = 1, callback: None | Callable[[ThreadContext, Breakpoint], None] = None, file: str = 'default') Breakpoint[source]#

Alias for the watchpoint method.

Sets a watchpoint at the specified location. Internally, watchpoints are implemented as breakpoints.

Parameters:
  • position (int | bytes) – The location of the breakpoint.

  • condition (str, optional) – The trigger condition for the watchpoint (either “r”, “rw” or “x”).

  • "w". (Defaults to)

  • length (int, optional) – The size of the word in being watched (1, 2, 4 or 8). Defaults to 1.

  • callback (Callable[[ThreadContext, Breakpoint], None], optional) – A callback to be called when the

  • None. (watchpoint is hit. Defaults to)

  • file (str, optional) – The user-defined backing file to resolve the address in. Defaults to “default”

  • address ((libdebug will first try to solve the address as an absolute)

  • w.r.t. (then as a relative address)

  • file). (the "binary" map)

property threads: list[ThreadContext]#

Get the list of threads in the process.

property memory: MemoryView#

Get the memory view of the process.

property mem: MemoryView#

Alias for the memory property.

Get the memory view of the process.

property breakpoints: dict[int, Breakpoint]#

Get the breakpoints set on the process.

property syscall_hooks: dict[int, SyscallHook]#

Get the syscall hooks dictionary.

Returns:

the syscall hooks dictionary.

Return type:

dict[int, SyscallHook]

property signal_hooks: dict[int, SignalHook]#

Get the signal hooks dictionary.

Returns:

the signal hooks dictionary.

Return type:

dict[int, SignalHook]

property pprint_syscalls: bool#

Get the state of the pprint_syscalls flag.

Returns:

True if the debugger should pretty print syscalls, False otherwise.

Return type:

bool

pprint_syscalls_context(value: bool) ...[source]#

A context manager to temporarily change the state of the pprint_syscalls flag.

Parameters:

value (bool) – the value to set.

Yields:

None

property syscalls_to_pprint: list[str] | None#

Get the syscalls to pretty print.

Returns:

The syscalls to pretty print.

Return type:

list[str]

property syscalls_to_not_pprint: list[str] | None#

Get the syscalls to not pretty print.

Returns:

The syscalls to not pretty print.

Return type:

list[str]

property signals_to_block: list[str]#

Get the signals to not forward to the process.

Returns:

The signals to block.

Return type:

list[str]

libdebug.debugger.internal_debugger module#

class libdebug.debugger.internal_debugger.InternalDebugger[source]#

Bases: object

A class that holds the global debugging state.

auto_interrupt_on_command: bool#

A flag that indicates if the debugger should automatically interrupt the debugged process when a command is issued.

memory: MemoryView#

The memory view of the debugged process.

debugging_interface: DebuggingInterface#

The debugging interface used to communicate with the debugged process.

aslr_enabled: bool#

A flag that indicates if ASLR is enabled or not.

autoreach_entrypoint: bool#

A flag that indicates if the debugger should automatically reach the entry point of the debugged process.

argv: list[str]#

The command line arguments of the debugged process.

env: dict[str, str] | None#

The environment variables of the debugged process.

escape_antidebug: bool#

A flag that indicates if the debugger should escape anti-debugging techniques.

breakpoints: dict[int, Breakpoint]#

A dictionary of all the breakpoints set on the process. Key: the address of the breakpoint.

syscall_hooks: dict[int, SyscallHook]#

A dictionary of all the syscall hooks set on the process. Key: the syscall number.

signal_hooks: dict[int, SignalHook]#

A dictionary of all the signal hooks set on the process. Key: the signal number.

syscalls_to_pprint: list[int] | None#

The syscalls to pretty print.

syscalls_to_not_pprint: list[int] | None#

The syscalls to not pretty print.

signals_to_block: list[int]#

The signals to not forward to the process.

pprint_syscalls: bool#

A flag that indicates if the debugger should pretty print syscalls.

pipe_manager: PipeManager#

The pipe manager used to communicate with the debugged process.

process_id: int#

The PID of the debugged process.

threads: list[ThreadContext]#

A list of all the threads of the debugged process.

instanced: bool = False#

Whether the process was started and has not been killed yet.

resume_context: ResumeContext#

Context that indicates if the debugger should resume the debugged process.

clear() None[source]#

Reinitializes the context, so it is ready for a new run.

start_up() None[source]#

Starts up the context.

start_processing_thread() None[source]#

Starts the thread that will poll the traced process for state change.

run() None[source]#

Starts the process and waits for it to stop.

attach(pid: int) None[source]#

Attaches to an existing process.

detach() None[source]#

Detaches from the process.

kill() None[source]#

Kills the process.

terminate() None[source]#

Terminates the background thread.

The debugger object cannot be used after this method is called. This method should only be called to free up resources when the debugger object is no longer needed.

cont() None[source]#

Continues the process.

Parameters:

auto_wait (bool, optional) – Whether to automatically wait for the process to stop after continuing. Defaults to True.

interrupt() None[source]#

Interrupts the process.

wait() None[source]#

Waits for the process to stop.

maps() list[MemoryMap][source]#

Returns the memory maps of the process.

print_maps() None[source]#

Prints the memory maps of the process.

breakpoint(position: int | str, hardware: bool = False, condition: str | None = None, length: int = 1, callback: None | Callable[[ThreadContext, Breakpoint], None] = None, file: str = 'default') Breakpoint[source]#

Sets a breakpoint at the specified location.

Parameters:
  • position (int | bytes) – The location of the breakpoint.

  • hardware (bool, optional) – Whether the breakpoint should be hardware-assisted or purely software.

  • False. (Defaults to)

  • condition (str, optional) – The trigger condition for the breakpoint. Defaults to None.

  • length (int, optional) – The length of the breakpoint. Only for watchpoints. Defaults to 1.

  • callback (Callable[[ThreadContext, Breakpoint], None], optional) – A callback to be called when the

  • None. (breakpoint is hit. Defaults to)

  • file (str, optional) – The user-defined backing file to resolve the address in. Defaults to “default”

  • address ((libdebug will first try to solve the address as an absolute)

  • w.r.t. (then as a relative address)

  • file). (the "binary" map)

hook_signal(signal_to_hook: int | str, callback: None | Callable[[ThreadContext, int], None] = None, hook_hijack: bool = True) SignalHook[source]#

Hooks a signal in the target process.

Parameters:
  • signal_to_hook (int | str) – The signal to hook.

  • callback (Callable[[ThreadContext, int], None], optional) – A callback to be called when the signal is

  • None. (received. Defaults to)

  • hook_hijack (bool, optional) – Whether to execute the hook/hijack of the new signal after an hijack or not.

  • False. (Defaults to)

unhook_signal(hook: SignalHook) None[source]#

Unhooks a signal in the target process.

Parameters:

hook (SignalHook) – The signal hook to unhook.

hijack_signal(original_signal: int | str, new_signal: int | str, hook_hijack: bool = True) None[source]#

Hijacks a signal in the target process.

Parameters:
  • original_signal (int | str) – The signal to hijack.

  • new_signal (int | str) – The signal to replace the original signal with.

  • hook_hijack (bool, optional) – Whether to execute the hook/hijack of the new signal after the hijack or not.

  • True. (Defaults to)

hook_syscall(syscall: int | str, on_enter: Callable[[ThreadContext, int], None] | None = None, on_exit: Callable[[ThreadContext, int], None] | None = None, hook_hijack: bool = True) SyscallHook[source]#

Hooks a syscall in the target process.

Parameters:
  • syscall (int | str) – The syscall name or number to hook.

  • on_enter (Callable[[ThreadContext, int], None], optional) – The callback to execute when the syscall is entered. Defaults to None.

  • on_exit (Callable[[ThreadContext, int], None], optional) – The callback to execute when the syscall is exited. Defaults to None.

  • hook_hijack (bool, optional) – Whether the syscall after the hijack should be hooked. Defaults to True.

Returns:

The syscall hook object.

Return type:

SyscallHook

unhook_syscall(hook: SyscallHook) None[source]#

Unhooks a syscall in the target process.

Parameters:

hook (SyscallHook) – The syscall hook to unhook.

hijack_syscall(original_syscall: int | str, new_syscall: int | str, hook_hijack: bool = True, **kwargs: int) SyscallHook[source]#

Hijacks a syscall in the target process.

Parameters:
  • original_syscall (int | str) – The syscall name or number to hijack.

  • new_syscall (int | str) – The syscall name or number to replace the original syscall with.

  • hook_hijack (bool, optional) – Whether the syscall after the hijack should be hooked. Defaults to True.

  • **kwargs – (int, optional): The arguments to pass to the new syscall.

Returns:

The syscall hook object.

Return type:

SyscallHook

migrate_to_gdb(open_in_new_process: bool = True) None[source]#

Migrates the current debugging session to GDB.

step(thread: ThreadContext) None[source]#

Executes a single instruction of the process.

Parameters:

thread (ThreadContext) – The thread to step. Defaults to None.

step_until(thread: ThreadContext, position: int | str, max_steps: int = -1, file: str = 'default') None[source]#

Executes instructions of the process until the specified location is reached.

Parameters:
  • thread (ThreadContext) – The thread to step. Defaults to None.

  • position (int | bytes) – The location to reach.

  • max_steps (int, optional) – The maximum number of steps to execute. Defaults to -1.

  • file (str, optional) – The user-defined backing file to resolve the address in. Defaults to “default”

  • address ((libdebug will first try to solve the address as an absolute)

  • w.r.t. (then as a relative address)

  • file). (the "binary" map)

finish(thread: ThreadContext, heuristic: str = 'backtrace') None[source]#

Continues execution until the current function returns or the process stops.

The command requires a heuristic to determine the end of the function. The available heuristics are: - backtrace: The debugger will place a breakpoint on the saved return address found on the stack and continue execution on all threads. - step-mode: The debugger will step on the specified thread until the current function returns. This will be slower.

Parameters:
  • thread (ThreadContext) – The thread to finish.

  • heuristic (str, optional) – The heuristic to use. Defaults to “backtrace”.

enable_pretty_print() SyscallHook[source]#

Hooks a syscall in the target process to pretty prints its arguments and return value.

disable_pretty_print() None[source]#

Unhooks all syscalls that are pretty printed.

insert_new_thread(thread: ThreadContext) None[source]#

Insert a new thread in the context.

Parameters:

thread (ThreadContext) – the thread to insert.

set_thread_as_dead(thread_id: int, exit_code: int | None, exit_signal: int | None) None[source]#

Set a thread as dead and update its exit code and exit signal.

Parameters:
  • thread_id (int) – the ID of the thread to set as dead.

  • exit_code (int, optional) – the exit code of the thread.

  • exit_signal (int, optional) – the exit signal of the thread.

get_thread_by_id(thread_id: int) ThreadContext[source]#

Get a thread by its ID.

Parameters:

thread_id (int) – the ID of the thread to get.

Returns:

the thread with the specified ID.

Return type:

ThreadContext

resolve_address(address: int, backing_file: str) int[source]#

Normalizes and validates the specified address.

Parameters:
  • address (int) – The address to normalize and validate.

  • backing_file (str) – The backing file to resolve the address in.

Returns:

The normalized and validated address.

Return type:

int

Raises:

ValueError – If the substring backing_file is present in multiple backing files.

resolve_symbol(symbol: str, backing_file: str) int[source]#

Resolves the address of the specified symbol.

Parameters:
  • symbol (str) – The symbol to resolve.

  • backing_file (str) – The backing file to resolve the symbol in.

Returns:

The address of the symbol.

Return type:

int

property running: bool#

Get the state of the process.

Returns:

True if the process is running, False otherwise.

Return type:

bool

set_running() None[source]#

Set the state of the process to running.

set_stopped() None[source]#

Set the state of the process to stopped.

libdebug.debugger.internal_debugger_holder module#

class libdebug.debugger.internal_debugger_holder.InternalDebuggerHolder(internal_debuggers: ~weakref.WeakKeyDictionary = <factory>)[source]#

Bases: object

A holder for internal debuggers.

internal_debuggers: WeakKeyDictionary#
global_internal_debugger = None#
internal_debugger_lock = <unlocked _thread.lock object>#

libdebug.debugger.internal_debugger_instance_manager module#

libdebug.debugger.internal_debugger_instance_manager.get_global_internal_debugger() InternalDebugger[source]#

Can be used to retrieve a temporarily-global internal debugger.

libdebug.debugger.internal_debugger_instance_manager.provide_internal_debugger(reference: object) InternalDebugger[source]#

Provide a internal debugger.

Parameters:

reference (object) – the object that needs the internal debugger.

Returns:

the internal debugger.

Return type:

InternalDebugger

Link a reference to a InternalDebugger.

Parameters:
  • reference (object) – the object that needs the internal debugger.

  • internal_debugger (InternalDebugger) – the internal debugger.

libdebug.debugger.internal_debugger_instance_manager.extend_internal_debugger(referrer: object) ...[source]#

Extend the internal debugger.

Parameters:

referrer (object) – the referrer object.

Yields:

InternalDebugger – the internal debugger.

Module contents#