libdebug는 바이너리 실행 파일의 디버깅을 자동화하는 오픈 소스 Python 라이브러리입니다.
libdebug를 사용하면 디버깅된 실행 파일의 흐름을 완전히 제어할 수 있습니다. 이를 통해 다음을 수행할 수 있습니다.
동일한 실행 파일을 여러 번 실행할 때 효율적인 구현을 선택하면 차이가 생길 수 있습니다. 이러한 이유로 libdebug는 성능을 우선시합니다.
홈페이지: https://libdebug.org
문서: https://docs.libdebug.org
우분투:
sudo apt install -y python3 python3-dev libdwarf-dev libelf-dev libiberty-dev linux-headers-generic libc6-dbg
데비안:
sudo apt install -y python3 python3-dev libdwarf-dev libelf-dev libiberty-dev linux-headers-generic libc6-dbg
아치 리눅스:
sudo pacman -S python libelf libdwarf gcc make debuginfod
페도라:
sudo dnf install -y python3 python3-devel kernel-devel binutils-devel libdwarf-devel
python3 -m pip install libdebug
PyPy3은 지원되지만 권장되지 않습니다. 대부분의 테스트에서 성능이 떨어지기 때문입니다.
가장 최첨단 기능을 최신 상태로 유지하려면(불안정한 브랜치에 있어도 괜찮음) 다른 브랜치(예: dev)에서 설치할 수 있습니다.
python3 -m pip install git+https://github.com/libdebug/libdebug.git@dev
이제 libdebug가 설치되었으므로 스크립트에서 이를 사용할 수 있습니다. 다음은 libdebug를 사용하여 바이너리를 디버깅하는 방법에 대한 간단한 예입니다.
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 ()
위 스크립트는 작업 디렉터리에서 바이너리 test
실행하고 "function" 기호에 해당하는 함수에서 중지합니다. 그런 다음 RAX 레지스터의 값을 인쇄하고 프로세스를 종료합니다.
libdebug로 할 수 있는 일이 훨씬 더 많습니다. 자세한 내용은 설명서를 읽어보세요.
libdebug는 많은 고급 기능을 제공합니다. 신호로 마술을 부리는 이 스크립트를 살펴보세요:
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를 사용하면 중지 이벤트를 기다리지 않고도 모든 명령이 가능한 한 빨리 실행되도록 할 수 있습니다. 이 모드를 활성화하려면 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 ()
작업에 libdebug를 사용하려는 경우 다음 biblatex를 사용하여 이 저장소를 인용하십시오.
@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},
}