如何在执行后立即停止调试器?

逆向工程 调试 linux 数据库 数据库 断点
2021-06-10 00:26:17

/bin/true用作我的示例二进制文件(没有可用的主要方法):

$ lldb /bin/true
(lldb) target create "/bin/true"
Current executable set to '/bin/true' (x86_64).
(lldb) break main
invalid command 'breakpoint main'

有没有什么通用的方法来运行二进制文件并在加载后立即停止调试器,以便可以加载适当的符号?与打破主方法(代码的第一行)等效的东西?或者我需要手动计算入口点?如果是这样,如何?

2个回答

二进制文件通常被剥离对于 ELF 二进制文件,您可以使用file命令进行检查

$ file /bin/true
/bin/true: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0x73796652ea437df8ac7b3ba1864a7ac177e27600, stripped

请注意stripped文件结果末尾的 。这意味着,除其他外,符号已被删除,因此它不会找到main功能。

为了运行的二进制和停止负荷后的调试器吧,有一些种类的通用方法(的一种通用的,不是100%)应该总是工作

您必须找到通过以下命令检索的入口点:

$ readelf -h /bin/true | grep "Entry point"
  Entry point address:               0x401264

然后将二进制文件加载到您最喜欢的调试器(lldb、gdb、...)并在此地址处中断。

数据库:

$ lldb /bin/true
(lldb) target create "/bin/true"
Current executable set to '/bin/true' (x86_64).
(lldb) br s -a 0x401264
Breakpoint 1: address = 0x0000000000401264
(lldb) r
...
(lldb)

数据库:

$ gdb -q /bin/true
Reading symbols from /bin/true...(no debugging symbols found)...done.
gdb$ b *0x401264
Breakpoint 1 at 0x401264
gdb$ r
Breakpoint 1, 0x0000000000401264 in ?? ()
gdb$

加载二进制文件并触发断点后,您可以显示以下将以这种方式执行的指令:

数据库:

(lldb) x -s4 -fi -c11 $pc
-> 0x401264:    xor    ebp,ebp
   0x401266:    mov    r9,rdx
   0x401269:    pop    rsi
   0x40126a:    mov    rdx,rsp
   0x40126d:    and    rsp,0xfffffffffffffff0
   0x401271:    push   rax
   0x401272:    push   rsp
   0x401273:    mov    r8,0x403560
   0x40127a:    mov    rcx,0x403570
   0x401281:    mov    rdi,0x4011c0
   0x401288:    call   0x401060 <__libc_start_main@plt>

数据库:

gdb$ x/11i $pc
=> 0x401264:    xor    ebp,ebp
   0x401266:    mov    r9,rdx
   0x401269:    pop    rsi
   0x40126a:    mov    rdx,rsp
   0x40126d:    and    rsp,0xfffffffffffffff0
   0x401271:    push   rax
   0x401272:    push   rsp
   0x401273:    mov    r8,0x403560
   0x40127a:    mov    rcx,0x403570
   0x401281:    mov    rdi,0x4011c0
   0x401288:    call   0x401060 <__libc_start_main@plt>

i标记的装置nstruction,和$pc装置P rogram Ç ounter(相当于EIP的/ RIP为32/64位architecures)。您可以看到__libc_start_main将在 address 处被调用0x401288它的手册页表明它的第一个参数是一个指向二元main函数的指针第一个参数在此处加载到rdi寄存器中,这意味着该main函数位于 address 0x4011c0

您只需要最终在此地址 ( 0x4011c0)处放置一个断点,您就会位于二进制 main 函数的开头。

进一步阅读:如何使用 GDB 处理剥离的二进制文件?没有来源,没有符号,GDB 只显示地址?

祝好运并玩得开心点 !

来自http://lldb.llvm.org/tutorial.html

(lldb) process launch --stop-at-entry -- -program_arg value

注意你break main是一个gdb命令;lldbs 错误消息不是“没有这样的符号”,而是“无效命令”。要在 中执行相同操作lldb,请使用

(lldb) breakpoint set --name main