二进制文件通常被剥离。对于 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 只显示地址?
祝好运并玩得开心点 !