Memory Access
In libdebug, memory access is performed via the memory
attribute of the Debugger object or the Thread Context. When reading from memory, a bytes-like object is returned. The following methods are available:
Access a range of bytes by providing the start and end addresses as integers.
Access a range of bytes by providing the base address and length as integers.
Access memory using a symbol name.
When specifying a symbol, you can also provide an offset. Contrary to what happens in GDB, the offset is always interpreted as hexadecimal.
Accessing memory with symbols
Please note that, unless otherwise specified, symbols are resolved in the debugged binary only. To resolve symbols in shared libraries, you need to indicate it in the third parameter of the function.
Writing to memory works similarly. You can write a bytes-like object to memory using the same addressing methods:
Length/Slice when writing
When writing to memory, slices and length are ignored in favor of the length of the specified bytes-like object.
In the following example, only 4 bytes are written:
Absolute and Relative Addressing
Just like with symbols, memory addresses can also be accessed relative to a certain file base. libdebug uses "hybrid"
addressing by default. This means it first attempts to resolve addresses as absolute. If the address does not correspond to an absolute one, it considers it relative to the base of the binary.
You can use the third parameter of the memory access method to select the file you want to use as base (e.g., libc, ld, binary). If you want to force libdebug to use absolute addressing, you can specify "absolute"
instead.
Examples of relative and absolute addressing
Searching inside Memory
The memory
attribute of the Debugger object also allows you to search for specific values in the memory of the process. You can search for integers, strings, or bytes-like objects.
Function Signature
Parameters:
Argument | Type | Description |
---|---|---|
value |
int | bytes | str |
The value to search for. |
file |
str |
The backing file to search in (e.g, binary, libc, stack). |
start |
int (optional) |
The start address of the search (works with both relative and absolute). |
end |
int (optional) |
The end address of the search (works with both relative and absolute). |
Returns:
Return | Type | Description |
---|---|---|
Addresses |
list[int] |
List of memory addresses where the value was found. |
Usage Example
Faster Memory Access
Warning: This feature is Experimental!
This feature is experimental and may not work as expected. Please report any issues you encounter here.
By default, libdebug reads and writes memory using the ptrace
system call interface. However, this is not the most efficient way to access memory and will likely be changed in future versions.
To speed up memory access, you can already enable a faster system that relies on Linux's procfs. To use it, simply set the fast_memory
parameter to True
when creating the Debugger object. You can also enable and disable this feature at runtime by accessing the debugger's attribute.