linux - 是否有 Linux 系统调用可以让我在另一个进程的上下文中进行系统调用?

标签 linux linux-kernel kernel system-calls

我想做的是进行系统调用,让内核表现得好像是另一个进程在进行调用。您可以将其视为模拟另一个进程。我知道我可能会使用 ptrace 弄乱程序的代码,但这不是很优雅,可能需要进行调整才能与我正在做的任何过程一起工作。另外,我所要求的对于内核应该是可能的,而不必触及其他进程的内存或执行进程,当然除非我正在执行的系统调用的影响会导致这种情况。

我认为它的工作方式是有一个(特权)系统调用(我们称它为 setepid,表示“设置有效的 PID”),它接受 PID 作为参数。在 setepid 之后,该进程(或可能仅该线程)进行的任何 future 系统调用都将表现得好像是指定的进程进行系统调用一样。异常(exception)是 setepid 调用本身,它可用于恢复原始上下文或以其他方式定位不同的进程。

例如,以下代码可用于将已运行进程(本例中的 PID 1234)的标准输出重定向到文件 output.txt,该文件位于进程 1234 的当前工作中目录:

setepid(1234); /* perform following system calls on process 1234 */

int fd = open("output.txt", O_WRONLY|O_CREAT|O_TRUNC);
if (fd > 0) {
    dup2(fd, 1);
    close(fd);
}

setepid(0); /* done acting as 1234, restore original context */

这可能存在的一个问题是 "output.txt" 字符串常量,它作为指针传递。根据 setepid 的实现方式,也许出于必要,它可能将该指针视为进程 1234 内存中的地址。由于在编译时在另一个进程中静态分配内存(包括常量)甚至没有意义,因此绕过它需要像这样丑陋的东西:

setepid(1234);
char *buf = mmap(NULL, 12, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
setepid(0);

const char *str = "output.txt\0"; /* extra byte to make it a multiple of 4 */
/* Disclaimer: I'm not sure if I'm using ptrace correctly, but you get the idea. */
ptrace(PTRACE_ATTACH, 1234, NULL, NULL);
ptrace(PTRACE_POKEDATA, 1234, buf, *(void**)str);
ptrace(PTRACE_POKEDATA, 1234, buf+4, *(void**)(str+4));
ptrace(PTRACE_POKEDATA, 1234, buf+8, *(void**)(str+8));
ptrace(PTRACE_DETACH, 1234, NULL, NULL);

setepid(1234);

int fd = open(buf, O_WRONLY|O_CREAT|O_TRUNC);
if (fd > 0) {
    dup2(fd, 1);
    close(fd);
}

setepid(0);

我假设这样的机制不存在,但我希望我是错的。如果我的假设是正确的,是否有任何问题会阻止将其添加到 future 版本的 Linux 中?在内核模块中实现它会很简单(甚至可能)吗?这听起来像是一个危险但功能强大且可能有用的工具。

最佳答案

如果不有效地将代码注入(inject)目标线程,您所提议的内容将无法工作,而您已经可以使用 ptrace 完成这些工作。

其中一个问题是存在仅由当前线程修改的数据。由于没有其他人修改它,因此可以在没有锁的情况下轻松读取它。但是用你的方法,不变量会被打破。一个简单的例子是凭据。

这也不适用于提供的玩具 fd 更换盒。当以 fd 作为参数进行任何系统调用时,必须找到目标文件指针。如果 fd 表是共享的,则必须引用该文件,因为其他人可以同时关闭(fd)。内核对单线程进程进行了微优化——因为表不是共享的,所以没有人关闭 fd,所以以后不需要引用(和取消引用)它。再一次,当您关闭线程使用的 fd 时,fd 表的突然修改很容易导致释放后使用。

等等。

简而言之,这是不可能飞起来的。您可以做的最接近的事情是使用 ptrace 注入(inject)系统调用。

关于linux - 是否有 Linux 系统调用可以让我在另一个进程的上下文中进行系统调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41253216/

相关文章:

linux - 在没有源代码的情况下在 linux 中分发程序

linux - 提交后忽略 Git 中的文件

iphone - 将邮件从 postfix 推送到 iPhone

c - C中struct封装指针的目的

编译器错误 : implicit declaration of function 'find_task_by_vpid'

c++ - 如何循环 Blowfish Crypto++

c - 无法从用户空间 C 调用 ioctl

c - 并发用户访问

Linux 3.x 内核书籍

linux - Linux内核如何产生方波