不能插入断点.低值地址 [英] Cannot insert breakpoints. Addresses with low values
问题描述
我正在尝试调试这个简单的 C 程序:
I'm trying to debug this simple C program:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello
");
}
但是当我反汇编主函数时,我得到了这个:
But when I disassemble the main function I get this:
(gdb) disas main
Dump of assembler code for function main:
0x000000000000063a <+0>: push rbp
0x000000000000063b <+1>: mov rbp,rsp
0x000000000000063e <+4>: sub rsp,0x10
0x0000000000000642 <+8>: mov DWORD PTR [rbp-0x4],edi
0x0000000000000645 <+11>: mov QWORD PTR [rbp-0x10],rsi
0x0000000000000649 <+15>: lea rdi,[rip+0x94] # 0x6e4
0x0000000000000650 <+22>: call 0x510 <puts@plt>
0x0000000000000655 <+27>: mov eax,0x0
0x000000000000065a <+32>: leave
0x000000000000065b <+33>: ret
End of assembler dump.
这已经很奇怪了,因为地址以前缀 4... 开头,对于 32 位可执行文件,我认为 8... 对于 64 位可执行文件.
And this is already pretty strange because addresses starts with a prefix of 4... for 32 bit executables and 8... for 64 bit executables I think.
但是接下来我设置了一个断点:
But going on I then put a breakpoint:
(gdb) b *0x0000000000000650
Breakpoint 1 at 0x650
我运行它并收到此错误消息:
I run it and I get this error message:
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x650
推荐答案
您的代码很可能被编译为 位置独立的可执行文件 (PIE) 允许 地址空间布局随机化 (ASLR).在某些系统上,gcc 被配置为默认创建 PIE(这意味着选项 -pie -fPIE
被传递给 gcc).
Your code was most probably compiled as Position-Independent Executable (PIE) to allow Address Space Layout Randomization (ASLR). On some systems, gcc is configured to create PIEs by default (that implies the options -pie -fPIE
being passed to gcc).
当您启动 GDB 来调试 PIE 时,它会从 0
开始读取地址,因为您的可执行文件尚未启动yet,因此未重新定位(在 PIE 中,所有包括 .text
部分的地址是可重定位的,它们从 0
开始,类似于动态共享对象).这是一个示例输出:
When you start GDB to debug a PIE, it starts reading addresses from 0
, since your executable was not started yet, and therefore not relocated (in PIEs, all addresses including the .text
section are relocatable and they start at 0
, similar to a dynamic shared object). This is a sample output:
$ gcc -o prog main.c -pie -fPIE
$ gdb -q prog
Reading symbols from prog...(no debugging symbols found)...done.
gdb-peda$ disassemble main
Dump of assembler code for function main:
0x000000000000071a <+0>: push rbp
0x000000000000071b <+1>: mov rbp,rsp
0x000000000000071e <+4>: sub rsp,0x10
0x0000000000000722 <+8>: mov DWORD PTR [rbp-0x4],edi
0x0000000000000725 <+11>: mov QWORD PTR [rbp-0x10],rsi
0x0000000000000729 <+15>: lea rdi,[rip+0x94] # 0x7c4
0x0000000000000730 <+22>: call 0x5d0 <puts@plt>
0x0000000000000735 <+27>: mov eax,0x0
0x000000000000073a <+32>: leave
0x000000000000073b <+33>: ret
End of assembler dump.
如您所见,这显示了与您类似的输出,.text
地址从低值开始.
As you can see, this shows a similar output to yours, with .text
adresses starting at low values.
一旦您启动可执行文件就会发生重定位,因此在那之后,您的代码将被放置在进程内存中的某个随机地址:
Relocation takes place once you start your executable, so after that, your code will be placed at some random address in your process memory:
gdb-peda$ start
...
gdb-peda$ disassemble main
Dump of assembler code for function main:
0x00002b1c8f17271a <+0>: push rbp
0x00002b1c8f17271b <+1>: mov rbp,rsp
=> 0x00002b1c8f17271e <+4>: sub rsp,0x10
0x00002b1c8f172722 <+8>: mov DWORD PTR [rbp-0x4],edi
0x00002b1c8f172725 <+11>: mov QWORD PTR [rbp-0x10],rsi
0x00002b1c8f172729 <+15>: lea rdi,[rip+0x94] # 0x2b1c8f1727c4
0x00002b1c8f172730 <+22>: call 0x2b1c8f1725d0 <puts@plt>
0x00002b1c8f172735 <+27>: mov eax,0x0
0x00002b1c8f17273a <+32>: leave
0x00002b1c8f17273b <+33>: ret
End of assembler dump.
如您所见,地址现在采用您可以设置断点的真实"值.请注意,通常您仍然不会在 GDB 中看到 ASLR 的效果,因为它默认禁用随机化(调试具有随机位置的程序会很麻烦).您可以使用 show disable-randomization
进行检查.如果你真的想在你的 PIE 中看到 ASLR 的效果,set disable-randomization off
.然后每次运行都会将您的代码重新定位到随机地址.
As you can see, the addresses now take "real" values that you can set breakpoints to. Note that usually you will still not see the effect of ASLR in GDB though, since it disables randomization by default (debugging a program with randomized location would be cumbersome). You can check this with show disable-randomization
. If you really want to see the effects of ASLR in your PIE, set disable-randomization off
. Then every run will relocate your code to random addresses.
所以底线是:在调试 PIE 代码时,首先启动
你在 GDB 中的程序然后找出地址.
So the bottom line is: When debugging PIE code, start
your program in GDB first and then figure out the addresses.
或者,您可以明确禁用 PIE 代码的创建并使用 gcc filename.c -o filename -no-pie -fno-PIE
编译您的应用程序.我的系统默认不强制创建 PIE,所以很遗憾我不知道在这样的系统上禁用 PIE 的影响(很高兴看到对此的评论).
Alternatively, you can explicitly disable the creation of PIE code and compile your application using gcc filename.c -o filename -no-pie -fno-PIE
.
My system does not enforce PIE creation by default, so unfortunately I don't know about the implications of disabling PIE on such a system (would be glad to see comments on that).
有关一般位置无关代码 (PIC) 的更全面解释(这对共享库至关重要),请查看 Ulrich Drepper 的论文如何编写共享库".
For a more comprehensive explanation of position-independent code (PIC) in general (which is of utmost importance for shared libraries), have a look at Ulrich Drepper's paper "How to Write Shared Libraries".
这篇关于不能插入断点.低值地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!