使用ptrace设置RIP的奇怪行为

时间:2016-06-24 05:39:26

标签: linux assembly ptrace

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

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

除非远程进程在sleep之类的系统调用中被阻止,否则它可以正常工作。如果在我附加进程的时候在系统调用内部阻止了远程进程,在我将RIP设置到我想要执行shell代码的位置然后恢复目标进程之后,我将观察到RIP实际上少了2个而不是我在ptrace调用中的地址。例如,如果我将RIP设置为0x4000,则一旦恢复它,RIP将变为0x3ffe。通常情况下,由于段故障,它会因我的情况而崩溃。但是如果我在设置它之后立即抓取寄存器而不恢复进程,那么RIP就是我刚设置的值。目前我通过在shell代码之前插入2个nop指令来解决它,并在设置RIP时总是加2。我只是想知道有什么我想念设置RIP或者我注入代码的整个方法是完全不稳定的吗?

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

1 个答案:

答案 0 :(得分:2)

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

我以同样的方式克服了这个问题(总是添加一个微小的nop-sled并递增RIP)。