libdebug adalah pustaka Python sumber terbuka untuk mengotomatiskan proses debug biner yang dapat dieksekusi.
Dengan libdebug Anda memiliki kendali penuh atas aliran executable Anda yang telah di-debug. Dengan itu Anda dapat:
Saat menjalankan executable yang sama beberapa kali, memilih implementasi yang efisien dapat membuat perbedaan. Oleh karena itu, libdebug mengutamakan kinerja.
Beranda: https://libdebug.org
Dokumentasi: https://docs.libdebug.org
Ubuntu:
sudo apt install -y python3 python3-dev libdwarf-dev libelf-dev libiberty-dev linux-headers-generic libc6-dbg
Debian:
sudo apt install -y python3 python3-dev libdwarf-dev libelf-dev libiberty-dev linux-headers-generic libc6-dbg
Lengkungan Linux:
sudo pacman -S python libelf libdwarf gcc make debuginfod
fedora:
sudo dnf install -y python3 python3-devel kernel-devel binutils-devel libdwarf-devel
python3 -m pip install libdebug
PyPy3 didukung tetapi tidak disarankan, karena kinerjanya lebih buruk pada sebagian besar pengujian kami.
Jika Anda ingin tetap mendapatkan fitur-fitur paling mutakhir (dan Anda tidak keberatan berada di cabang yang tidak stabil), Anda dapat menginstal dari cabang lain (misalnya, dev).
python3 -m pip install git+https://github.com/libdebug/libdebug.git@dev
Sekarang setelah Anda menginstal libdebug, Anda dapat mulai menggunakannya di skrip Anda. Berikut ini contoh sederhana cara menggunakan libdebug untuk men-debug biner:
from libdebug import debugger
d = debugger ( "./test" )
# Start debugging from the entry point
d . run ()
my_breakpoint = d . breakpoint ( "function" )
# Continue the execution until the breakpoint is hit
d . cont ()
# Print RAX
print ( f"RAX is { hex ( d . regs . rax ) } " )
# Write to memory
d . memory [ 0x10ad , 8 , "binary" ] = b"Hello! x00 x00 "
# Continue the execution
d . cont ()
Skrip di atas akan menjalankan test
biner di direktori kerja dan berhenti pada fungsi yang sesuai dengan simbol "fungsi". Ini kemudian akan mencetak nilai register RAX dan mematikan prosesnya.
Masih banyak lagi yang bisa dilakukan dengan libdebug. Silakan baca dokumentasi untuk mengetahui lebih lanjut.
libdebug menawarkan banyak fitur lanjutan. Lihatlah skrip ini melakukan keajaiban dengan sinyal:
from libdebug import debugger , libcontext
libcontext . terminal = [ 'tmux' , 'splitw' , '-h' ]
# Define signal catchers
def catcher_SIGUSR1 ( t : ThreadContext , catcher : SignalCatcher ) -> None :
t . signal = 0x0
print ( f"SIGUSR1: Signal number { catcher } " )
def catcher_SIGINT ( t : ThreadContext , catcher : SignalCatcher ) -> None :
print ( f"SIGINT: Signal number { catcher } " )
def catcher_SIGPIPE ( t : ThreadContext , catcher : SignalCatcher ) -> None :
print ( f"SIGPIPE: Signal number { catcher } " )
def handler_geteuid ( t : ThreadContext , handler : SyscallHandler ) -> None :
t . regs . rax = 0x0
# Initialize the debugger
d = debugger ( '/path/to/executable' , continue_to_binary_entrypoint = False , aslr = False )
# Register signal catchers
catcher1 = d . catch_signal ( "SIGUSR1" , callback = catcher_SIGUSR1 )
catcher2 = d . catch_signal ( "SIGINT" , callback = catcher_SIGINT )
catcher3 = d . catch_signal ( "SIGPIPE" , callback = catcher_SIGPIPE )
# Register signal hijackings
d . hijack_signal ( "SIGQUIT" , "SIGTERM" )
d . hijack_signal ( "SIGINT" , "SIGPIPE" , recursive = True )
# Define which signals to block
d . signals_to_block = [ "SIGPOLL" , "SIGIO" , "SIGALRM" ]
d . handle_syscall ( "geteuid" , on_exit = handler_geteuid )
# Continue execution
d . cont ()
# Disable the catchers after execution
catcher1 . disable ()
catcher2 . disable ()
catcher3 . disable ()
bp = d . breakpoint ( 0xdeadc0de , hardware = True )
d . cont ()
d . wait ()
d . gdb ()
libdebug juga memungkinkan Anda membuat semua perintah dijalankan sesegera mungkin, tanpa harus menunggu acara terhenti. Untuk mengaktifkan mode ini, Anda dapat menggunakan auto_interrupt_on_command=True
from libdebug import debugger
d = debugger ( "/path/to/executable" , auto_interrupt_on_command = True )
pipes = d . run ()
bp = d . breakpoint ( "function" )
d . cont ()
# Read shortly after the cont is issued
# The process is forcibly stopped to read the register
value = d . regs . rax
print ( f"RAX is { hex ( value ) } " )
system_offset = d . symbols . filter ( "system" )[ 0 ]. start
libc_base = d . maps . filter ( "libc" )[ 0 ]. base
system_address = libc_base + system_offset
d . memory [ 0x12ebe , 8 , "libc" ] = int . to_bytes ( system_address , 8 , "little" )
d . cont ()
d . wait ()
# Here we should be at the breakpoint
# This value is read while the process is stopped at the breakpoint
ip_value = d . regs . rip
print ( f"RIP is { hex ( ip_value ) } " )
d . kill ()
Jika Anda ingin menggunakan libdebug dalam pekerjaan Anda, harap kutip repositori ini menggunakan biblatex berikut:
@software{libdebug_2024,
title = {libdebug: {Build} {Your} {Own} {Debugger}},
copyright = {MIT Licence},
url = {https://libdebug.org},
publisher = {libdebug.org},
author = {Digregorio, Gabriele and Bertolini, Roberto Alessandro and Panebianco, Francesco and Polino, Mario},
year = {2024},
doi = {10.5281/zenodo.13151549},
}