linux - 使用 ptrace 设置 RIP 的奇怪行为

标签 linux assembly ptrace

基本上,我使用 ptrace 将 shell 代码注入(inject)远程进程以供执行。但我发现有关 RIP 寄存器的一些奇怪的行为。

我所做的是将 shell 代码复制到程序映射的起始地址。然后我使用 ptrace 将 RIP 设置为起始地址所在的地址。然后我恢复目标进程来执行代码。一旦 shell 代码完成(通过运行 int3),我将收到信号并恢复我刚刚修改的代码。

除非远程进程在sleep等系统调用中被阻塞,否则它工作正常。如果远程进程在我附加进程时被阻止在系统调用内,则在我将 RIP 设置到我想要执行 shell 代码的位置然后恢复目标进程后,我会观察到 RIP 实际上少了 2比我在 ptrace 调用中输入的地址要多。例如,如果我将 RIP 设置为 0x4000,一旦恢复,RIP 就会变为 0x3ffe。通常,对于我的情况来说,显然是由于段错误而崩溃。但是,如果我在设置后立即获取寄存器而不恢复进程,则 RIP 就是我刚刚设置的值。目前,我通过在 shell 代码之前插入 2 个 nop 指令来解决这个问题,并且在设置 RIP 时始终添加 2 个指令。我只是想知道我在设置 RIP 时是否遗漏了什么,或者我的整个注入(inject)代码方法完全不稳定?

我的开发盒是Ubuntu14.04,内核是3.13.0-45-generic。

最佳答案

如果我没记错的话,如果在系统调用中阻塞进程时中断该进程,则程序计数器值在继续时将被内核减去 sizeof(系统调用指令)。因此,一旦执行 PTRACE_DETACH,该进程将重新执行被中断的系统调用。

我以与您相同的方式解决了这个问题(总是添加一个小 nop-sled 并增加 RIP)。

关于linux - 使用 ptrace 设置 RIP 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38006277/

相关文章:

macos - 为什么使用 jmp 会阻止 Clang 汇编器计算出 .fill 的绝对表达式?

c - Assembly + C - 排序结构

在 ptraced Linux 进程中调用 ptrace

c - ptrace mprotect调试麻烦

c - 如何使用 ptrace 找到 CALL 和 RET 号码?

c - 从丢失的 TCP 连接中恢复传输

c - 我如何在不在 C 中获取 "."和 ".."的情况下获取目录中的所有文件名

linux - pthread 可以自己执行清理吗?

linux - 如何在 bash 中将十进制转换为十六进制?

assembly - NASM 中的增量循环