/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'
是否有任何通用的方法来运行二进制文件并在加载后立即停止调试器,因此可以加载适当的符号?等同于破坏main方法(代码的第一行)吗?还是我需要手动计算入口点?如果可以,怎么办?
#1 楼
通常会剥离二进制文件。对于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:
$ 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:
$ 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:
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
标志表示指令,而$pc
标志程序计数器(相当于32/64位体系结构的EIP / RIP)。您会看到__libc_start_main将在地址0x401288
处被调用。其手册页指示其第一个参数是指向二进制main
函数的指针。第一个参数在这里加载到rdi
寄存器中,这意味着main
函数位于地址0x4011c0
处。您只需要最终在该地址(
0x4011c0
)处放置一个断点,就可以在您的二进制主函数。进一步阅读:如何使用GDB处理剥离的二进制文件?没有来源,没有符号,GDB只显示地址吗?
祝你好运,玩得开心!
评论
从GDB 8.1开始的最简单方法是starti命令。无需手动寻找入口点地址。
–俄罗斯
19年1月29日在20:52
#2 楼
来自http://lldb.llvm.org/tutorial.html:(lldb) process launch --stop-at-entry -- -program_arg value
请注意,您的
break main
是gdb
命令; lldb
的错误消息不是“没有这样的符号”,它是“无效的命令”。要在lldb
中执行相同操作,请使用(lldb) breakpoint set --name main
评论
对于gdb,请参见:在SO处停止gdb中的第一条机器代码指令