libdebug 101
Welcome to libdebug! When writing a script to debug a program, the first step is to create a Debugger object. This object will be your main interface for debugging commands.
argv
can either be a string (the name/path of the executable) or an array corresponding to the argument vector of the execution.
Am I already debugging?
Creating a Debugger object will not start the execution automatically. You can reuse the same debugger to iteratively run multiple instances of the program. This is particularly useful for smart bruteforcing or fuzzing scripts.
Performing debugger initialization each time is not required and can be expensive.
To run the executable, refer to Running an Executable
Environment
Just as you would expect, you can also pass environment variables to the program using the env
parameter. Here, the variables are passed as a string-string dictionary.
Address Space Layout Randomization (ASLR)
Modern operating system kernels implement mitigations against predictable addresses in binary exploitation scenarios. One such feature is ASLR, which randomizes the base address of mapped virtual memory pages (e.g., binary, libraries, stack). When debugging, this feature can become a nuisance for the user.
By default, libdebug keeps ASLR enabled. The debugger aslr
parameter can be used to change this behavior.
Binary Entry Point
When a child process is spawned on the Linux kernel through the ptrace
system call, it is possible to trace it as soon as the loader has set up your executable. Debugging these first instructions inside the loader library is generally uninteresting.
For this reason, the default behavior for libdebug is to continue until the binary entry point (1) is reached. When you need to start debugging from the very beginning, you can simply disable this behavior in the following way:
- In Linux, the binary entry point corresponds to the
_start
/__rt_entry
symbol in your binary executable. This function is the initial stub that calls themain()
function in your executable, through a call to the standard library of your system (e.g.,__libc_start_main
,__rt_lib_init
)
What the hell are you debugging?
Please note that this feature assumes the binary is well-formed. If the ELF header is corrupt, the binary entrypoint will not be resolved correctly. As such, setting this parameter to False
is a good practice when you don't want libdebug to rely on this information.
What else can I do?
The Debugger object has many more parameters it can take.
Function Signature
Parameter | Type | Description |
---|---|---|
argv |
str | list[str] |
Path to the binary or argv list |
aslr |
bool |
Whether to enable ASLR. Defaults to True. |
env |
dict[str, str] |
The environment variables to use. Defaults to the same environment of the parent process. |
escape_antidebug |
bool |
Whether to automatically attempt to patch antidebugger detectors based on ptrace . |
continue_to_binary_entrypoint |
bool |
Whether to automatically continue to the binary entrypoint. |
auto_interrupt_on_command |
bool |
Whether to run libdebug in ASAP Mode. |
fast_memory |
bool |
Whether to use a faster memory reading method. Defaults to False. |
kill_on_exit |
bool |
Whether to kill the debugged process when the debugger exits. Defaults to True. |
Return Value | ||
Debugger | Debugger |
The debugger object |