PTRACE_SINGLESTEP是如何实现的?

2024-01-02

据我所知(我可能是错的),没有办法只执行onex86-64 系统上的指令。也许您可以执行后跟“ud2”操作码的指令来触发信号——但是您必须担心指令会修改控制流并转到其他地方。

然而,如果我理解正确的话,ptrace() 系统调用有一个 SINGLESTEP 选项,该选项将仅执行一条指令。这是如何实施的?我无法想象内核有某种反汇编程序来识别指令并解释它。那么,它是否使用了某种我不知道的架构功能?或者完全不同的东西?


是的,x86 上有一个架构单步标志。从内核返回到用户空间使内核有机会同时设置 RIP/RFLAGS,因此它可以为用户空间设置单步,而无需在内核指令上触发。

由于某种原因,陷阱旗 https://en.wikipedia.org/wiki/Trap_flag有自己的维基百科文章!也可以看看维基百科的 EFLAGS 文章 https://en.wikipedia.org/wiki/FLAGS_register.

See the x86 /questions/tagged/x86tag wiki 以获取英特尔架构手册的链接,该手册记录了所有这些内容。


也许您可以执行后跟“ud2”操作码的指令来触发信号

然后,您需要代码来确定 x86 指令长度,以了解在哪里设置软件断点。而你不会使用ud2,你会用int3为此目的而存在。 https://www.felixcloutier.com/x86/intn:into:int3:int1

x86 还具有调试寄存器 (dr0..7),可以在不修改代码的情况下设置硬件断点,或者可以监视对给定数据地址的访问或写入。 (GDBhbreak使用这些,就像常量地址上的 GDB 观察点一样)

但对于跳转/调用/ret 和其他可能对 RIP 有特殊影响的指令,您需要解码和模拟以找出放置指令的目的地int3在目的地。使用类似寻址模式的内存间接跳转jmp qword [fs: rax]需要调试器知道 FS 段基址,甚至知道将从哪个地址加载指针。 (我假设您可以像实际寄存器值一样轻松地使用 ptrace 获取此值,这与来宾程序本身内部不同rdfsbase是一个新的扩展。)因此,只要您的调试器已停止所有其他线程,就可以避免与另一个线程在读取跳转目标指针和继续执行之间修改跳转目标指针的 TOCTOU 竞争条件。


Fun fact:并非所有 ISA 都有硬件支持PTRACE_SINGLESTEP.

举个例子,Linux 内核曾经为 ARM 模拟它,但这需要内核中的 ARM 反汇编程序在下一条指令处放置断点,即使是分支目标也是如此。它于 2011 年被删除;现在ptrace(PTRACE_SINGLESTEP)回报-ENOSYS on ARM.

他们只是去掉了所有的复杂性,而不是试图使其成为 SMP 安全并支持每个新指令,如 Thumb-2 等。 (http://lists.infradead.org/pipermail/linux-arm-kernel/2011-February/041324.html http://lists.infradead.org/pipermail/linux-arm-kernel/2011-February/041324.html)

因此调试器必须在此类 ISA 上手动使用断点,而不是让内核为它们执行此操作。如果这意味着其他线程暂时注意到内存中的调试中断操作码,那么这不是内核的问题。 (通常是像 GDB 这样的调试器do单步执行时停止所有线程。)

这意味着调试器必须解码分支指令才能找出断点的位置。包括寄存器间接和/或谓词分支。

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

PTRACE_SINGLESTEP是如何实现的? 的相关文章

  • fopen 不返回

    我在 C 程序中使用 fopen 以只读模式 r 打开文件 但就我而言 我观察到 fopen 调用没有返回 它不返回 NULL 或有效指针 执行在 fopen 调用时被阻止 文件补丁绝对正确 我已经验证过 并且不存在与权限相关的问题 任何人
  • 加载数据infile,Windows和Linux的区别

    我有一个需要导入到 MySQL 表的文件 这是我的命令 LOAD DATA LOCAL INFILE C test csv INTO TABLE logs fields terminated by LINES terminated BY n
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • nslookup 报告“无法解析 '(null)': 名称无法解析”,尽管它成功解析了 DNS 名称

    我在 ubuntu 上 并且正在运行 docker 默认桥接网络 我有 Zookeeper kafka 的容器化版本 以及我编写的与 kafka 对话的应用程序 I do a docker exec it
  • 为什么 printf 使用浮点和整数格式说明符打印随机值

    我在64位机器上写了一个简单的代码 int main printf d 2 443 所以 这就是编译器的行为方式 它将识别第二个参数为双精度型 因此它将在堆栈上压入 8 个字节 或者可能只是在调用之间使用寄存器来访问变量 d需要 4 字节整
  • 为什么X86中没有NAND、NOR和XNOR指令?

    它们是您可以在计算机上执行的最简单的 指令 之一 它们是我亲自实施的第一个指令 执行 NOT AND x y 会使执行时间和依赖链长度和代码大小加倍 BMI1 引入了 andnot 这是一个有意义的补充 是一个独特的操作 为什么不是这个问题
  • Linux 内核标识符中前导和尾随下划线的含义是什么?

    我不断遇到一些小约定 比如 KERNEL Are the 在这种情况下 是内核开发人员使用的命名约定 还是以这种方式命名宏的语法特定原因 整个代码中有很多这样的例子 例如 某些函数和变量以 甚至 这有什么具体原因吗 它似乎被广泛使用 我只需
  • Linux:在文件保存时触发 Shell 命令

    我想在修改文件时自动触发 shell 命令 我认为这可以通过注册 inotify 挂钩并调用来在代码中完成system 但是是否有更高级别的 bash 命令可以完成此任务 尝试 inotify 工具 我在复制链接时遇到问题 抱歉 但 Git
  • Linux:如何从特定端口发送TCP数据包?

    如何打开原始套接字以从特定 TCP 端口发送 我希望所有连接始终来自临时端口以下的一系列端口 如果您正在使用raw套接字 然后只需在数据包标头中填写正确的 TCP 源端口即可 相反 如果您使用 TCP 套接字接口 socket connec
  • 使用 sh 运行 bash 脚本

    我有 bash 脚本 它需要 bash 另一个人尝试运行它 sh script name sh 它失败了 因为 sh 是他的发行版中 dash 的符号链接 ls la bin sh lrwxrwxrwx 1 root root 4 Aug
  • 汇编器8086将32位数字除以16位数字

    我尝试将 32 位数字除以 16 位数字 例如 10000000h 除以 2000h 根据我尝试做的设计除以 右 4 位数字除以除数 然后左 4 位数字除以除数 这是我的代码 DATA num dd 10000000h divisor dw
  • Linux 中什么处理 ping?

    我想覆盖 更改 linux 处理 ping icmp echo 请求数据包的方式 这意味着我想运行自己的服务器来回复传入的 icmp 回显请求或其他 数据包 但为了使其正常工作 我想我需要禁用 Linux 的默认 ping icmp 数据包
  • PHP 无法打开流:是一个目录

    非常简单的 PHP 脚本 我在我亲自设置的 Ubuntu Web 服务器上的 EE 模板中运行 我知道这与权限有关 并且我已经将我尝试写入的目录的所有者更改为 Apache 用户 我得到的错误是 遇到 PHP 错误 严重性 警告 消息 fi
  • SSE:跨页边界的未对齐加载和存储

    我在页面边界旁边执行未对齐加载或存储之前读过某处 例如使用 mm loadu si128 mm storeu si128内在函数 代码应首先检查整个向量 在本例中为 16 个字节 是否属于同一页 如果不属于同一页 则切换到非向量指令 我知道
  • docker容器大小远大于实际大小

    我正在尝试从中构建图像debian latest 构建后 报告的图像虚拟大小来自docker images命令为 1 917 GB 我登录查看尺寸 du sh 大小为 573 MB 我很确定这么大的尺寸通常是不可能的 这里发生了什么 如何获
  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • 我的线程图像生成应用程序如何将其数据传输到 GUI?

    Mandelbrot 生成器的缓慢多精度实现 线程化 使用 POSIX 线程 Gtk 图形用户界面 我有点失落了 这是我第一次尝试编写线程程序 我实际上并没有尝试转换它的单线程版本 只是尝试实现基本框架 到目前为止它是如何工作的简要描述 M
  • 如何通过ssh检查ubuntu服务器上是否存在php和apache

    如何通过ssh检查Ubuntu服务器上apache是 否安装了php和mysql 另外如果安装的话在哪个目录 如果安装了其他软件包 例如 lighttpd 那么它在哪里 确定程序是否已安装的另一种方法是使用which命令 它将显示您正在搜索
  • 在脚本内使用不带密码的 sudo

    由于某种原因 我需要作为用户在没有 sudo 的情况下运行脚本 script sh 该脚本需要 root 权限才能工作 我认为将 sudo 放入 script sh 中是唯一的解决方案 让我们举个例子 script sh bin sh su

随机推荐

  • 如何让 PyDev 编辑器有选择地忽略错误?

    我在 Eclipse 下使用 PyDev 编写一些 Jython 代码 我有很多情况需要做这样的事情 import com work project component client Interface ISubInterface as I
  • 制作自定义tabBar的方法

    创建这样的效果以及导航控制器和视图控制器的处理的最佳方法应该是什么 如果我不想在 viewcontorller 中重新调整每个后续视图的大小并且事情看起来就像是一个 该怎么办标签栏 我建议使用 UIImageView 作为蓝色背景 然后使用
  • 修复警告:[相机]尝试使用不支持的设备更改为肖像模式(BackDual)

    我有一个UICollectionView with a CameraCell作为第一个单元格 它显示相机预览 我想修复 XCode 控制台中的警告iOS 16 iPhone XS Max配备双后置摄像头 Camera Attempted t
  • mysql订单字符串作为数字

    我已经搜索了几天 寻找一种在 mysql 中将字符串排序为数字的方法 我的行看起来像这样 订单列 1 1 2 1 1 100 1 1 1 在 mysql 中按此列升序排序将产生 1 1 1 1 1 100 1 1 2 我有兴趣获得以下结果
  • 如何在给定 ID 的情况下获取未知用户名?

    我有一个 20 个字符的数字 ID 看起来像10527391670258314752 给定这个ID 我怎样才能获得与之关联的用户名 该表如下所示 id name password balance 10527391670258314752 J
  • Safari 中的 SVG 组元素不会触发 Wheel 事件

    我正在尝试绑定一个wheel使用 D3 的 SVG 组元素的事件侦听器 看来wheel当我在 Safari 中滚动组元素时 不会触发事件 组不为空 它在 Firefox 或 Chrome 上运行良好 let svg d3 select sv
  • 使用 Fragment 的 setRetainInstance(true) 确实是处理旋转变化的好习惯吗

    我指的是为什么使用 Fragment setRetainInstance boolean https stackoverflow com questions 11160412 why use fragmentsetretaininstanc
  • 我的模板中获取资源的绝对路径名

    在我的 JSF 2 0 Facelets 应用程序中 我有一个出色的模板 我希望所有页面都使用它 它位于 Web 应用程序的根目录中 名称为 template xhtml 因此它被引用为您所期望的
  • 为什么创建 ASPNETDB.mdf 以及如何摆脱它?

    我的问题已在标题中陈述 以提供一些背景知识 我正在帮助客户在 ASP net 环境中使用 Web 部件 但我不希望它们附加到此数据库 我希望能够在不创建此数据库的情况下使用该网站 我目前正在对此进行更多研究 但是任何有关网站的建议或有关此的
  • 为什么我们需要网络套接字?

    这更像是一个n00b问题 但我从来没有真正知道答案 那么为什么我们需要 websockets 协议呢 与 Comet 式 长轮询 悬挂 GET 式使用 HTTP 相比 有哪些优势 Comet 和 Ajax 都可以提供最终用户体验 提供类似桌
  • VSCode C/C++ IntelliSense 标识符未定义,但可以解析定义

    新安装 VSCode 我安装的唯一扩展是 Microsoft C C Intellisense 插件 版本0 24 1 我正在使用一个代码库 其中包含一些带有 define X foo 宏的头文件 在 cpp 文件中 它用红色下划线表示 标
  • 如何确定 UICollectionView flowLayout 中单元格之间的间距

    我有一个带有流布局的 UICollectionView 每个单元格都是一个正方形 如何确定每行中每个单元格之间的间距 我似乎找不到合适的设置 我看到集合视图的 nib 文件上有一个最小间距属性 但我将其设置为 0 并且单元格甚至不粘在一起
  • 为什么 chrome 中的 height() 值与 safari 中不同?

    我的脚本是这样的 ajax url url type GET dataType json contentType application json charset utf 8 success function result done fun
  • 如何在 vspackage 中获取当前解决方案配置?

    我正在制作 Visual Studio 包 我需要知道打开的解决方案名称和配置 我怎样才能得到这些信息 如果您有 EnvDTE 的参考 您可以使用dte Solution and dte Solution SolutionBuild Act
  • 时间间隔内的Mongo聚合

    我有一些日志数据存储在 mongo 集合中 其中包括 request id 形式的基本信息以及将其添加到集合中的时间 例如 id ObjectId 55ae6ea558a5d3fe018b4568 request id 030ac9f1 a
  • 使用转换时替换 UIWindow 的 rootViewController 似乎存在泄漏

    环境 iOS 9 2Xcode 7 2 我正在寻找更换UIWindow 的 rootViewController https developer apple com library ios documentation UIKit Refer
  • laravel中api中间件的作用是什么

    我在 laravel 8 有一个简单的问题 我测试了两个代码 但没有发现任何差异 它们对我来说看起来一样 即使我点击了很多时间 两者都给了我 太多的请求 Route middleware api gt get user function R
  • R:每两个月休息一次的削减功能

    我从某处了解到Date我们可以使用的向量cut分成垃圾箱 cut dates breaks quarter 现在我想更改它 使其每两个月中断一次 我该怎么做 我尝试通过以下方式查找它 cut 但它甚至不会表明我可以使用 quarter or
  • SQL 中缺少右括号错误是什么原因造成的?

    我已经尝试运行以下 SQL 命令几个小时了 我不断收到错误消息 ORA 00907 缺少右括号错误 我知道这意味着某处存在语法错误 但我已经检查了代码很多次 但仍然无法弄清楚 任何帮助将不胜感激 CREATE TABLE Employees
  • PTRACE_SINGLESTEP是如何实现的?

    据我所知 我可能是错的 没有办法只执行onex86 64 系统上的指令 也许您可以执行后跟 ud2 操作码的指令来触发信号 但是您必须担心指令会修改控制流并转到其他地方 然而 如果我理解正确的话 ptrace 系统调用有一个 SINGLES