无法插入断点。低值地址

2024-01-12

我正在尝试调试这个简单的 C 程序:

#include <stdio.h>
int main(int argc, char *argv[]) {
    printf("Hello\n");
}

但是当我反汇编 main 函数时,我得到了这个:

(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... 前缀开头。

但接下来我设置了一个断点:

(gdb) b *0x0000000000000650
Breakpoint 1 at 0x650

我运行它并收到以下错误消息:

Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x650

您的代码很可能被编译为位置无关的可执行文件 (PIE) https://en.wikipedia.org/wiki/Position-independent_code允许地址空间布局随机化 (ASLR) https://en.wikipedia.org/wiki/Address_space_layout_randomization。在某些系统上,gcc 默认配置为创建 PIE(这意味着选项-pie -fPIE被传递给海湾合作委员会)。

当您启动 GDB 来调试 PIE 时,它开始读取地址0,因为您的可执行文件尚未启动yet,因此不会重新定位(在 PIE 中,所有地址,包括.text部分是可重新定位的,它们开始于0,类似于动态共享对象)。这是一个示例输出:

$ 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地址从低值开始。

一旦启动可执行文件,就会发生重定位,因此之后,您的代码将被放置在进程内存中的某个随机地址:

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。然后每次运行都会将您的代码重新定位到随机地址。

所以底线是:调试 PIE 代码时,start首先你的程序在GDB中and then找出地址。

或者,您可以显式禁用 PIE 代码的创建并使用以下命令编译您的应用程序gcc filename.c -o filename -no-pie -fno-PIE。 我的系统默认情况下不强制创建 PIE,因此不幸的是我不知道在这样的系统上禁用 PIE 的影响(很高兴看到对此的评论)。

要更全面地解释位置无关代码 (PIC)(这对于共享库来说至关重要),请查看Ulrich Drepper 的论文“如何编写共享库” https://www.akkadia.org/drepper/dsohowto.pdf.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法插入断点。低值地址 的相关文章

随机推荐

  • 如何执行 Bash 命令并收集 Java 的输出?

    如何执行 Bash 命令并收集 Java 的输出 大家好 基本上我正在编写一个基本的控制台应用程序 并且希望能够从中运行命令 例如 sudo halt ifconfig 等 有什么见解吗 您可以使用流程构建器 http download o
  • 使用 Lazy 是否会降低性能?

    最近 我遇到了一个单例类的问题 该类延迟初始化字典 其中第二个线程会在实际填充字典之前尝试使用它 所以我通过以下方式实现了变量初始化Lazy
  • Gandi.net 和 Heroku 域路由

    我的 io 域适用于 www domain io 但不适用于 domain io 版本 以下是我尝试过的每个版本和修订版 每个版本和修订版之间都有充足的时间 我等 10800 IN A 174 129 212 2 10800 IN A 75
  • subprocess.check_output():失败时显示输出

    的输出subprocess check output 目前看起来像这样 CalledProcessError Command foo returned non zero exit status 1 有没有办法获得更好的错误消息 我想看看st
  • 在哪里可以学习 DirectX 编程? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想学习 C 编程中的 DirectX 我决定学习DirectX 于是在网上找了一些教程 但是都是very复杂且难以理解 我花了3天时间看
  • .cc 和 .cpp 文件后缀有什么区别?

    有什么区别 cc and cpp文件扩展名 从Google 我了解到它们都来自C 语言 但我不确定它们之间的区别 惯例 从历史上看 C 源文件的后缀是 C 这在第一次移植 C 时引起了一些问题 对于文件名中大小写不重要的系统 不同的用户采用
  • 如何在 Substrate 的智能合约平台 ink 上保存字符串值?

    我最初尝试了这个问题中所教授的实现 如何在 Substrate 上保存字符串值 https stackoverflow com questions 63221904 how can i save string value on substr
  • 如何通过 rmarkdown 自动将 networkD3::sankeyNetwork() 保存到静态图像中?

    当我在 rmarkdown 中编写报告时 我的所有数据都会自动保存在该文件夹下graphs 然而 由于桑基图不同 它不会自动保存为图片 png 等 有解决方法吗 无需通过 RStudio Plots 面板手动保存每个图表 I saw 这个问
  • 如何在 Kotlin 中打印 ClosedRange

    我正在学习 Kotlin 并且我正在尝试理解Ranges 我创建了一系列String如下 val alpha A Z 我想打印我写的这个 for item in alpha println item 但它给出了错误 错误 13 18 Kot
  • 什么时候工厂方法比简单工厂更好,反之亦然?

    我正在阅读 Head First Design Patterns 一书 我相信我了解简单工厂和工厂方法 但我很难看出工厂方法相对于简单工厂带来的优势 如果对象 A 使用简单工厂来创建其 B 对象 那么客户端可以这样创建它 A a new A
  • 到 Out-GridView 和 Out-File 的管道有不同的行?

    以下命令仅返回一行 参数 Context 10被忽略 select string path file txt pattern Context 10 Out GridView 但是 以下命令创建一个包含所有行的文件 select string
  • logback 在 Flink 中不起作用

    我有一个单节点 Flink 实例 它在 lib 文件夹中具有 logback 所需的 jar logback classic jar logback core jar log4j over slf4j jar 我已从 lib 文件夹中删除了
  • 如何在 iOS 中用渐变填充由 CGPoints 定义的形状?

    我在代码中设置了自定义形状的箭头 我想做的就是用渐变填充它 问题是 我不知道如何用渐变填充非矩形形状 暗框内的空间 有任何想法吗 Define colours used in drawing CGContextRef context UIG
  • UILabel 默认字偶距与 CATextLayer 不同

    我有一个UILabel与字符串 LA 我也有一个CATextLayer具有相同的字符NSAttributedString分配给其string财产 字距调整UILabel与CATextLayer 这是代码 void viewDidLoad s
  • ExecutorService 与 Swing 计时器

    我一直在读肮脏的有钱客户 http filthyrichclients org 最近注意到 虽然Java的版本是6 但是并没有提到Concurrent Framework 因此 他们谈论 java util Timer 和 javax sw
  • 如何绑定到用户控件的属性?

    在 Windows 应用商店应用中 您创建一个用户控件来封装和重用代码隐藏和布局 XAML 一个简单的用户控件可能如下所示
  • Android 中的文件浏览器[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • PHP 中的 INET_ATON() 和 INET_NTOA()?

    我想将 IP 地址存储在数据库中 但我还需要在整个应用程序中使用它们 我读到关于使用INET ATON and INET NTOA 在我的 MySQL 查询中 从 IP 地址中获取 32 位无符号整数 这正是我想要的 因为它将比使用 cha
  • 每月累计总数和 Postgresql

    我正在尝试计算 dellstore2 数据库的累计用户数 看看这里的答案和其他论坛 我用了这个 select date trunc month orderdate sum count distinct customerid over ord
  • 无法插入断点。低值地址

    我正在尝试调试这个简单的 C 程序 include