为什么非 pic 代码不能使用运行时修复完全实现 ASLR?

2023-12-14

据我了解,PIC 代码使 ASLR 随机化更加高效、更加容易,因为代码可以放置在内存中的任何位置,而无需更改代码。但如果我根据维基百科理解正确的话搬迁动态链接器可以在运行时进行“修复”,以便可以找到符号,尽管代码不是位置无关的。但根据我在这里看到的许多答案,非图片代码不能ASLR除堆栈之外的部分(因此无法随机化程序入口点)。如果这是正确的,那么运行时修复的用途是什么?为什么我们不能在程序开始之前在运行时修复代码中的所有位置,以使程序入口点随机化。


TL:DR:并非所有绝对地址的使用都会在非 PIE 可执行文件(ELF 类型 EXEC,而不是 DYN)中具有重定位信息。因此,内核的程序加载器无法找到所有这些来应用修复。

因此,无法为构建为非 PIE 的可执行文件追溯启用 ASLR。传统的可执行文件无法将自己标记为每次使用绝对地址时都具有重定位元数据,并且添加这样的功能也没有意义,因为如果您想要文本 ASLR,您只需构建一个 PIE。

因为 ELF 类型的 EXEC Linux 可执行文件保证在链接时加载/映射到链接器选择的固定基地址,所以在可执行文件中为内部符号创建符号表条目会浪费空间。所以工具链并没有做到这一点,也没有理由开始。这就是传统 ELF 可执行文件的设计方式; Linux 在 90 年代中期就从 a.out 切换到了 ELF,当时堆栈 ASLR 还没有出现,所以它并没有引起人们的关注。

例如的绝对地址static char buf[100]可能嵌入在使用它的机器代码中的某个位置(如果我们谈论的是 32 位代码,或将地址放入寄存器的 64 位代码),但无法知道在哪里或多少次。

此外,特别是对于 x86-64,非 PIE 可执行文件的默认代码模型保证静态地址(文本/数据/bss)都将位于虚拟地址空间的低 2GiB 中,因此 32 位绝对有符号或无符号地址可以工作,以及rel32位移可以从任何物体到达任何物体。这就是为什么非 PIE 编译器输出使用mov $symbol, %edi(5 个字节)将地址放入寄存器中,而不是lea symbol(%rip), %rdi(7 字节)。https://godbolt.org/z/89PeK1

因此,即使您确实知道每个绝对地址在哪里,您也只能在低 2GiB 中对其进行 ASLR,从而限制了您可以引入的熵位数。 (我认为 Windows 有一个模式:LargeAddressAware = no。但 Linux 没有。x86-64 Linux 中不再允许使用 32 位绝对地址?同样,PIE 是允许文本 ASLR 的更好方法,因此人们(发行版)如果想要它的好处,就应该为此进行编译。)

与 Windows 不同,Linux 不会花费大量精力来处理可以通过从源代码重新编译二进制文件来更好、更高效地处理的事情。

话虽这么说,GNU/Linuxdoes支持修复重定位64-bit即使在 PIC / PIE ELF 共享对象中也是绝对地址。这就是为什么像 NASM 这样的初学者代码mov rdi, BUFFER甚至可以在共享库中工作:使用objdump -drwC -Mintel查看有关在中使用该符号的重定位信息mov reg, imm64操作说明。一个lea rdi, [rel BUFFER]不需要任何重定位条目,如果BUFFER不是一个全球性的符号。 (相当于Cstatic.)


您可能想知道为什么元数据至关重要:

没有可靠的方法来搜索文本/数据以查找可能的绝对地址;误报是可能的. e.g. /usr/bin/ld可能包含0x401000作为 x86-64 可执行文件的默认起始地址。你不想要 ASLRld的代码+数据也可以更改其默认值。或者该整数值可以在许多程序中以多种方式出现,例如作为位图。当然,x86-64 机器代码是可变长度的,因此在最常见的情况下甚至没有可靠的方法来区分操作码和立即操作数。

还有潜在的漏报。 x86 程序不太可能用多条指令在寄存器中构造绝对地址,但这当然是可能的。但在非 x86 代码中,这种情况很常见。

具有固定长度指令的RISC机器无法将32位地址放入32位指令中;就没有空间放其他东西了。因此,要从静态存储加载,绝对地址必须分成多个指令,例如 MIPSlui $t0, %hi(0x612300) / lw $t1, %lo(0x612300)($t0)从绝对地址 0x612300 处的静态变量加载。 (asm 源中通常会有一个符号名称,但它不会出现在最终链接的二进制文件中,除非它是.globl,所以我用数字作为提醒。)这样的指令不必成对出现;地址的相同高半部分可以由后续指令中对同一数组或结构的其他访问重用。

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

为什么非 pic 代码不能使用运行时修复完全实现 ASLR? 的相关文章

  • 如何用X11复制到剪贴板?

    使用 OS X 上的框架 我可以使用以下命令将 PNG 复制到粘贴板 在 C 中 显然我可以将 NSPasteboard 与 Cocoa 一起使用 include
  • 在Linux中断上下文中运行用户线程

    我正在编写一些定制的应用程序 并允许更改 Linux 内核中的中断处理程序代码 我有一个用户线程正在等待中断发生 如果发生中断 那么我要做的第一件事就是执行该用户线程 有什么办法让它发挥作用吗 Thanks 创建一个字符设备 这就是内核所做
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • 如何在特定 systemd 服务重新启动时触发自定义脚本运行

    我想知道如何安排自定义脚本在重新启动服务时运行 我的用例是 每当重新启动 Tomcat 服务时 我都必须运行多个命令 我想知道是否有一种方法可以编写脚本并安排它在重新启动 Tomcat 服务时运行 我已将 tomcat 脚本设置为 syst
  • Docker:处理 tar 文件时出错(退出状态 1):设置枢轴目录时出错:不是目录

    我是 Docker 新手 不知道是什么原因导致此错误或如何诊断它 任何有关此问题的具体帮助或有关首先检查何处以诊断此类问题的提示将不胜感激 我的 Dockerfile FROM java 8 Install maven RUN apt ge
  • 设置 Apache POI 的路径

    我想创建 Excel 文件并使用 java 程序在该文件中写入数据 That is here http www techbrainwave com p 554我在 java 文件所在的位置提取了 Apache POI 并将该路径包含在路径变
  • 让 MongoDB 在 Linux 上监听远程连接

    我已在 Windows 本地计算机上 上成功安装 MongoDB 作为服务 但现在我想将 MongoDb 移动到单独的服务器 所以我将 tarball 解压到网络上的虚拟服务器 运行 Linux 当我从本地计算机使用 PuTTY 连接到服务
  • 归档文件系统或格式

    我正在寻找一种文件类型来存储已退役系统的档案 目前 我们主要使用 tar gz 但从 200GB tar gz 存档中查找并提取几个文件是很麻烦的 因为 tar gz 不支持任何类型的随机访问读取规定 在你明白之前 使用 FUSE 安装 t
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • 并行运行 make 时出错

    考虑以下制作 all a b a echo a exit 1 b echo b start sleep 1 echo b end 当运行它时make j2我收到以下输出 echo a echo b start a exit 1 b star
  • 在 Linux 中禁用历史记录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 要在 Linux 环境中禁用历史记录 我执行了以下命令 export HISTFILESIZE 0 export HISTSIZE 0 u
  • 在Linux上编译C# + WPF以便在Windows上运行

    我有一个 C 应用程序 其中某些部分是使用 WPF 编写的 Mono 不支持 可以在 Linux 上编译这个应用程序吗 最终 该应用程序将在 Windows 上运行 但它是更大框架的一部分 并且我们的整个构建过程在 Linux 上运行 因此
  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • ELF动态符号表

    我有一个关于 ELF 动态符号表的问题 对于 FUNC 类型的符号 我注意到某些二进制文件中的值为 0 但在其他二进制文件中 它具有一些非零值 这两个二进制文件都是由 gcc 生成的 我想知道为什么会出现这种差异 有没有编译器选项来控制这个
  • 何时使用 pthread 条件变量?

    线程问题 看来 只有在其他线程调用 pthread cond notify 之前调用 pthread cond wait 时 条件变量才起作用 如果在等待之前发生通知 那么等待将被卡住 我的问题是 什么时候应该使用条件变量 调度程序可以抢占
  • 修改linux下的路径

    虽然我认为我已经接近 Linux 专业人士 但显然我仍然是一个初学者 当我登录服务器时 我需要使用最新版本的R 统计软件 R 安装在 2 个地方 当我运行以下命令时 which R I get usr bin R 进而 R version
  • 为什么我收到“无法进行二进制日志记录”的信息。在我的 MySQL 服务器上?

    当我今天启动 MySQL 服务器并尝试使用以下命令进行一些更改时用于 MySQL 的 Toad http www quest com toad for mysql 我收到此消息 MySQL 数据库错误 无法进行二进制日志记录 消息 交易级别
  • Elasticsearch 无法写入日志文件

    我想激活 elasticsearch 的日志 当我运行 elasticsearch 二进制文件时 我意识到我在日志记录方面遇到问题 无法加载配置 这是输出 sudo usr share elasticsearch bin elasticse

随机推荐

  • 使用 openpyxl 复制整个工作表

    请有人给我一个例子 如何复制带有样式的整个工作表 从行和列 到同一工作簿中的第二个工作表 也可以在新的工作簿中 谢谢 P S 我尝试进行深度复制 但未能保存更改的数据单元格 目的是 我尝试用我的数据填充一些工作表 第一个工作表是我的模板 我
  • 如何在 Lisp 中将函数存储在变量中并使用它

    我想存储一个像这样的函数print在一个变量中 这样我就可以输入一些简短的内容 例如p e g In Scheme define print display print Hello world n alternate way define
  • 通过 RewriteCond 和 .htaccess 对 RewriteRule 进行分组

    我有一个网页模板 用于运行多个登陆页面 htaccess 用于将友好 URL 定向到 PHP 代码中的 pageid 这一切都有效 但目前我必须在每个规则或重定向冲突之前添加重写条件行 您可以在下面的伪代码中看到这一点 RewriteEng
  • DynamoDB 中的复合键具有超过 2 列?

    我正在探索在我所处理的应用程序中使用 DynamoDB 该应用程序目前只有一个数据库组件 在 RDS 上运行的 MySQL 数据库 我们大量使用 AWS 并为我们的数据库使用分片方案 但如果没有人工干预 它只能让我们到目前为止 在使用 Au
  • 在 Visual Studio 中显示构建时间

    我们的构建服务器构建 C 项目之一花费的时间太长 它用视觉工作室2008 跑步devenv com MyApp sln Build see devenv 命令行开关 尽管这是针对较新版本的 VS 有没有办法让 devenv com 记录在解
  • 如何根据表单状态隐藏普通按钮

    我试图隐藏我的保存vanilla根据表单状态按钮 当表单状态 创建时 不应显示普通按钮 我尝试了不同的方法 但没有任何作用 我在 js 中创建一个函数 如果表单处于创建状态 则返回 true function isHideState for
  • 以编程方式安装 APK - 返回值

    在我的应用程序中 我从我的活动中调用 javascript 接口 在与此界面关联的 web 视图中 我要求用户下载并安装 APK 我正在使用 startActivityForResult 来启动安装过程 下载文件后 这是代码 Intent
  • 游戏在快速从后台恢复后退出暂停状态

    我正在使用 SpriteKit 开发一个游戏 可以在执行期间暂停并可以恢复 但我有一个问题applicationDidEnterBackground当游戏暂停时按下主页按钮时 因为当我恢复游戏时 即使游戏之前已暂停 实体也会立即开始移动 我
  • android studio 禁用日期选择器中的天数

    我想禁用日期选择器中的某一天 我有一个数组存储我想要禁用的日期 我有这个代码来禁用日历中的日期 for Calendar loopdate min date c min date c before max date c min date c
  • 如何将原始电子邮件 (MIME) 从 AWS SES 转换为 Gmail?

    我有一个 Gmail 帐户链接到我的域帐户 AWS SES 会将消息发送到我的 S3 存储桶 从那里 SNS 将以原始格式将消息转发到我的 Gmail 地址 如何自动将原始消息转换为标准电子邮件格式 原始消息采用标准电子邮件格式 我认为您想
  • python 中的运算符重载,对象位于运算符右侧

    我最近了解了 python 中的运算符重载 我想知道以下内容是否可行 考虑以下假设 人为的类 class My Num object def init self val self val val def add self other num
  • C++ getline 方法不起作用

    抱歉 我对 C 很陌生 但一般不熟悉编程 所以我尝试做一个简单的加密 解密 然而 当我对以前的代码添加修改时 因此没有两个用于加密和解密的程序 我发现代码 getline 方法不再起作用 相反 它只是在运行代码时忽略它 这是代码 int m
  • 在 Google 自定义搜索中使用 TBS(或等效参数)

    使用时谷歌自定义搜索用于选择特定类型搜索引擎的 TBM 参数 例如 专利的 tbm pts 或博客的 tbm blg 似乎受到支持 尽管参数列表中没有正确记录这一点 然而 当使用这种 特殊 搜索时 通常会使用 TBS 参数来扩展查询 不幸的
  • 敏感的 ASP.NET Session 数据是否需要加密?

    ASP NET Session string key 数据是否需要加密才能安全 如果此类数据始终保留在服务器上 那么只要数据是通过 SSL 从客户端发送的 那么在那里存储信用卡信息 密码等是否就可以安全了 鉴于所有的反对票都投在这里 我将添
  • 在android中显示后台服务的弹出窗口

    您好 android 中可以显示后台运行服务的弹出对话框吗 答案是肯定的 我该怎么做 有几种选择 您可以使用主题并使活动的外观和行为类似于对话框 如这个问题 通过设置android theme你的属性
  • img 标签显示方向错误

    我在这个链接中有一张图片 http d38daqc8ucuvuv cloudfront net avatars 216 2014 02 19 2017 13 48 jpg 正如您所看到的 这是一个方向正确的正常图像 但是 当我将此链接设置为
  • 如何使用seaborn实现Lineplot,x轴为“日期”

    我尝试实现seaborn lineplot 数据框具有日期值列表作为索引 试图将其作为 x 轴 Dataframe info 将 日期 字段显示为对象 我需要以日期为 x 轴的 4 种类型的列值的线图 当我尝试执行下面的代码时 它显示错误消
  • 为什么从 java 9 PhantomReference java doc 开始,它就专门用于 POST-mortem 清理操作,尽管它之前是 PRE-mortem

    PhantomReference java 8 的 java 文档更少看起来像这样 幻像引用对象 在收集器之后排队 确定它们的引用对象可以以其他方式被回收 幻影 参考最常用于调度事前清理 行动以比 Java 更灵活的方式 最终确定机制 如果
  • Android - XPath 评估速度非常慢

    我在用着XPath查询我的XML file目前大约有100KB 我正在迭代一个数组并查询列表中的每个值 不幸的是单个查询大约需要 3 4 秒在调试器下 在禁用调试器的情况下稍微少一些 有什么想法为什么这么慢吗 我用一个Galaxy S2供测
  • 为什么非 pic 代码不能使用运行时修复完全实现 ASLR?

    据我了解 PIC 代码使 ASLR 随机化更加高效 更加容易 因为代码可以放置在内存中的任何位置 而无需更改代码 但如果我根据维基百科理解正确的话搬迁动态链接器可以在运行时进行 修复 以便可以找到符号 尽管代码不是位置无关的 但根据我在这里