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

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

问题描述

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

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