无法插入断点.地址值低 [英] Cannot insert breakpoints. Addresses with low values

查看:110
本文介绍了无法插入断点.地址值低的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试调试此简单的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆