怪异的行为设定RIP使用ptrace的 [英] weird behavior setting RIP with ptrace
问题描述
基本上我用 ptrace的
来注入壳code来执行远程进程。但我发现关于RIP注册一些怪异的行为。
Basically I am using ptrace
to inject a shell code to a remote process for execution. But I found some weird behavior regarding RIP register.
我做的是我我的shell code复制到程序映射的起始地址。然后,我用设置ptrace的到起始地址的地址RIP。然后,我继续为执行code目标进程。一旦外壳code完成(通过运行 INT3
)我会得到信号并恢复code,我只是修改。
What I do is I copy my shell code to the start address of where the program is mapped. Then I set the RIP using ptrace to the address where the start address is. And then I resume the target process for executing the code. Once the shell code finishes (by running int3
) I will get signal and recover the code that I just modified.
它工作正常,除了当远程过程的阻止的系统调用像睡觉
内部。如果远程进程受阻于附上的过程中时刻系统调用里面,之后我设置的RIP的地方,我要执行我的shell code,然后恢复目标过程中,我会观察到RIP是实际上2比我放在了ptrace调用的地址小。例如,如果我设置RIP是0x4000的,一旦我恢复它RIP变得0x3ffe。通常情况下它崩溃了我的情况,由于该段故障,很明显。但是,如果我抢权后,我将它设置而不恢复过程中的寄存器,RIP是我刚刚设置的值。目前,我解决它通过领先我的壳code,始终插入2 NOP指令加2,当我设定的RIP。我只是想知道有什么,我错过了设置RIP或者我注射code整个方法完全是不稳定的?
It works fine except when the remote process is blocked inside of a system call like sleep
. If the remote process is blocked inside of a system call at the moment I attach the process, after I set the RIP to where I want to execute my shell code and then resume the target process, I will observe that the RIP is actually 2 less than what the address that I put in the ptrace call. For example if I set the RIP to be 0x4000, once I resume it the RIP becomes 0x3ffe. Typically it crashes for my case due to the segment fault, obviously. But if I grab the register right after I set it without resuming the process, the RIP is the value that I just set. Currently I work around it by insert 2 nop instructions ahead of my shell code and always add 2 when I set the RIP. I just want to know is there anything that I miss for setting the RIP or my whole method for injecting code is totally unstable?
我开发框是Ubuntu14.04,内核是3.13.0-45泛型。
My dev box is Ubuntu14.04, kernel is 3.13.0-45-generic.
推荐答案
如果我没有记错,如果中断的过程,而它的挡在系统调用,程序计数器的值,在继续进行,将由sizeof的减去(系统调用指令)由内核。所以一旦你做了PTRACE_DETACH,这个过程会重新做它从中断系统调用。
If I recall correctly, if you interrupt the process while it's blocked in a syscall, the program counter value, upon continuing, will be subtracted by sizeof(syscall instruction) by the kernel. So once you do a PTRACE_DETACH, the process will re-do the syscall it was interrupted from.
我克服这个问题,你做了同样的方式(一直在增加一个微小的NOP-雪橇和增量RIP)。
I overcome the problem the same way you did (always adding a tiny nop-sled and incrementing RIP).
这篇关于怪异的行为设定RIP使用ptrace的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!