开发一个Linux调试器(三):寄存器和内存

  • 时间:
  • 浏览:0
  • 来源:幸运飞艇APP下载_幸运飞艇APP官网

给 continue_execution 打补丁

在亲戚朋友真正读取任何寄存器然后,亲戚朋友时需告诉调试器其他关于亲戚朋友的目标平台的信息,这里是 x8664 平台。除了多组通用和专用目的寄存器,x8664 还提供浮点和向量寄存器。为了比较复杂,我将跳然后四种 寄存器,但有你有然后喜欢语录也还可不可以挑选支持它们。x86_64 也允许你像访问 32、16 有然后 8 位寄存器那样访问其他 64 位寄存器,但我只会介绍 64 位寄存器。有然后那些比较复杂,对于每个寄存器亲戚朋友只时需它的名称、它的 DWARF 寄存器编号以及 ptrace 返回价值形式体中的存储地址。我使用范围枚举引用那些寄存器,有然后我列出了有另有兩个 全局寄存器描述符数组,其中元素顺序和 ptrace 中寄存器价值形式体相同。

现在亲戚朋友会给亲戚朋友的用户界面加在命令:

现在亲戚朋友还可不可以读取和修改寄存器了,亲戚朋友还可不可以对亲戚朋友的 hello world 进程做其他有意思的更改。什儿 第一次测试,再次尝试在 call 指令处设置断点有然后从那里继续执行。让我看了输出了 Hello world。现在是有趣的次责,在输出调用后设有另有兩个 断点、继续、将 call 参数设置代码的地址写入进程计数器(rip)并继续。有然后进程计数器操纵,你应该再次看了输出了 Hello world。为了以防你不挑选在哪里设置断点,下面是我上一篇博文中的 objdump 输出:

系列文章索引

在下一篇博客中,亲戚朋友会第一次接触到 DWARF 信息并给亲戚朋友的调试器加在一系列逐步调试的功能。然后,亲戚朋友会有有另有兩个 功能工具,它能逐步执行代码、在我你要的地方设置断点、修改数据以及其它。一如以往,让我有任何问題请留下你的评论!

来源:51CTO

最后亲戚朋友像下面另有另有兩个 重写 continue_execution:

到 uint64_t 的转换是安全的,有然后 user_regs_struct 是有另有兩个 标准布局类型,但我认为指针算术技术上是未定义的行为undefined behavior。当前那末编译器会对此产生警告,我也懒得修改,有然后让我想保持最严格的正确性,那就写有另有兩个 大的 switch 语录。

下一步是通过 DWARF 寄存器编号查找。这次我会真正检查有另有兩个 错误条件以防亲戚朋友得到其他奇怪的 DWARF 信息。

这里亲戚朋友要做的要是给 handle_command 函数加在有另有兩个 命令。通过下面的代码,用户还可不可以输入 register read rax、 register write rax 0x42 以及什儿 的语录。

为了清晰和简洁起见,首先亲戚朋友要加在其他帮助函数:

接下来做那些?

让我想自己看看语录,你通常还可不可以在 /usr/include/sys/user.h 找到寄存器数据价值形式,另外 DWARF 寄存器编号取自 System V x86_64 ABI。

就快完成啦,现在亲戚朋友有然后有了寄存器名称查找:

现在根据要请求的寄存器,亲戚朋友要读取 regs。亲戚朋友还可不可以写有另有兩个 很大的 switch 语录,但有然后亲戚朋友 g_register_descriptors 表的布局顺序和 user_regs_struct 相同,亲戚朋友只时需搜索寄存器描述符的索引,有然后作为 uint64_t 数组访问 user_regs_struct 就行。(你也还可不可以重新排序 reg 枚举变量,有然后使用索引把它们转换为底层类型,但第一次让我使用其他方法编写,它能正常工作,我也就懒得改它了。)

在亲戚朋友测试亲戚朋友的更改然后,亲戚朋友现在还可不可以实现有另有兩个 更健全的 continue_execution 版本。有然后亲戚朋友还可不可以获取进程计数器,亲戚朋友还可不可以检查亲戚朋友的断点映射来判断亲戚朋友否是指在有另有兩个 断点。有然后是语录,亲戚朋友还可不可以停用断点并在继续然后跳过它。

随着上方文章的发布,那些链接会逐渐生效。

有然后亲戚朋友还可不可以编写函数来跳过断点:

显示亲戚朋友的寄存器

现在亲戚朋友还可不可以编写一堆函数来和寄存器交互。亲戚朋友希望还可不可以读取寄存器、写入数据、根据 DWARF 寄存器编号获取值,以及通过名称查找寄存器,反什儿 似。让亲戚朋友先从实现 get_register_value 刚结束:

那些有然后足够支持亲戚朋友在调试器接下来的次责轻松指在理寄存器,好多好多 亲戚朋友现在还可不可以把那些加在到亲戚朋友的用户界面。

上一篇博文中亲戚朋友给调试器加在了有另有兩个 简单的地址断点。这次,亲戚朋友将加在读写寄存器和内存的功能,这将使亲戚朋友还可不可以使用亲戚朋友的进程计数器、观察具体情况和改变进程的行为。

正如你看了的,iostreams 有非常精确的接口用于美观地输出十六进制数据(啊哈哈哈哈哈哈)。让我喜欢你也还可不可以通过 I/O 操纵器来摆脱其他混乱。

首先亲戚朋友检查当前进程计算器的值否是设置了有另有兩个 断点。有然后有,首先亲戚朋友把执行返回到断点然后,停用它,跳过另有另有兩个 的指令,再重新启用断点。

set_register_value 非常什儿 ,亲戚朋友要是写入该位置并在最后写回寄存器:

最后亲戚朋友会加在有另有兩个 简单的帮助函数用于导出所有寄存器的内容:

wait_for_signal 封装了亲戚朋友常用的 waitpid 模式:

测试效果

设置断点的然后亲戚朋友有然后读取和写入内存,有然后亲戚朋友只时需加在其他函数用于隐藏 ptrace 调用。

我要将进程计数器移回 0x30093a 以便正确设置 esi 和 edi 寄存器。

让我在这里找到这篇博文的代码。

你有然后我你要加在支持一次读取有然后写入多个字节,让我在每次希望读取另有另有兩个 字节时通过递增地址来实现。让我时需语录,你也还可不可以使用 process_vm_readv 和 process_vm_writev 或 /proc/<pid>/mem 代替 ptrace。

ptrace 使得亲戚朋友还可不可以轻易获得亲戚朋友我你要的数据。亲戚朋友只时需构造有另有兩个 user_regs_struct 实例并把它和 PTRACE_GETREGS 请求传递给 ptrace。

注册亲戚朋友的寄存器

作者:Simon Brand