无法插入断点.地址值低 [英] 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\n");
}
但是当我分解主要功能时,我得到了:
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.
这已经很奇怪了,因为我认为32位可执行文件的地址以4 ...开头,而64位可执行文件的地址以8 ...开头.
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
推荐答案
您的代码很可能被编译为地址空间布局随机化(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
读取地址,因为您的可执行文件尚未启动 ,因此也未重定位(在PIE中,包括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代码时,start
在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屋!