【发布时间】:2010-08-21 01:31:17
【问题描述】:
我想知道是否有一个 API,无论它多么晦涩难懂,它允许某人在 Mac OS X 下将数据发送到另一个进程的 stdin 流。在 Linux 下,如果我没记错的话,你可以使用文件系统在/proc 中访问这些流(当然需要正确的权限)。
我不知道。 Mach 端口,有人知道吗?
【问题讨论】:
我想知道是否有一个 API,无论它多么晦涩难懂,它允许某人在 Mac OS X 下将数据发送到另一个进程的 stdin 流。在 Linux 下,如果我没记错的话,你可以使用文件系统在/proc 中访问这些流(当然需要正确的权限)。
我不知道。 Mach 端口,有人知道吗?
【问题讨论】:
只是一个想法,但您不能制作一个管道,并在启动该进程时将该(命名的)管道重定向到该进程的标准输入吗?
大概是这样的
mkfifo MYPIPE
Prog < MYPIPE
echo "test" > MYPIPE
【讨论】:
mkfifo 以代码 1 退出并将“mkfifo: MYPIPE: File exists”写入标准错误。
不幸的是,我不相信你能做到这一点——MacPorts 都是用户空间,你需要的操作需要(或者很多技巧,见下文,或者)内核合作,我相信这不是即将到来。例如,Mac OSX Internals, a System Approach 在文件描述符传递部分中说
描述符是进程本地的 因为它只在 获得的过程 描述符说,通过打开一个文件。在 特别是,进程 A 无法访问 在另一个进程中打开的文件 B 通过简单地使用 表示该文件的描述符 B.
然后继续描述 FD 是如何发送的。
“诡计”部分将要求您获取一些代码以在其他进程中运行(在用户态或作为内核的一部分)。
例如,您可以在用户空间中通过修补可执行文件的二进制文件来做到这一点——在其启动路径的早期找到任何肯定会执行的指令,然后跳转到您自己的代码,该代码会发送FD 到您的监视守护进程,执行修补后的指令,然后跳回到另一个进程的正常顺序流。
要在内核级别执行此操作,需要对内核代码本身或内核加载的代码进行类似的补丁并且以完整的、未经验证的信任运行(这样他们就可以劫持不相关进程的文件描述符表条目)——我当然希望 Mac OS X 中没有这样的代码路径(因为它们的主要用途无疑是病毒、特洛伊木马和其他各种恶意软件)但是,如果有的话,你可以找到它们,这可能是比修补每个感兴趣的二进制可执行文件更通用的解决方案。
回到用户态,另一种相当通用的方法可能是修补所有感兴趣的进程加载的动态加载的库,而不是修补各种进程的几个可执行文件。
【讨论】:
如果你在终端运行目标进程,那么你可以使用writevt,它的源代码是here。
例如,假设您在终端 ttys000 上运行“cat”命令。
在 1 号航站楼:
$ tty
/dev/ttys000
$ cat
在 2 号航站楼:
$ sudo ./writevt /dev/ttys000 'Hello!^M'
上面的^M 是一个控制字符。在我的 Mac 上,您可以通过键入 Ctrl-V 后跟 Ctrl-<enter> 来输入此字符。
这是 1 号航站楼的结果:
$ tty
/dev/ttys000
$ cat
Hello!
Hello!
writevt程序可以用gcc从writevt.c源文件编译:
$ gcc -o writevt writevt.c
【讨论】:
sudo chown root:wheel writevt 和sudo chmod 4755 writevt 结合使用,之后您可以在不使用sudo 命令的情况下使用writevt。如所述here
假设它是在用户许可的情况下(即您想从第三方应用程序捕获信息,以重定向到另一个应用程序,例如 Rogue Amoeba 的音频应用程序或某些视频流捕获应用程序),那么我会说您要么想要查看内核扩展或输入管理器。
(另请参见 fscript anywhere、SIMBL 和 Application Enhancer - 将功能注入第三方应用程序的所有软件示例)。
许多旧的用户驱动代码注入技术在 10.6 中受到限制(例如,输入管理器更难安装)。
如果您对用户输入而不是标准输入感兴趣,那么替代输入法工具包实际上可能“足够好” - 传统上,输入管理器已被用于将各种代码注入应用程序。
另一方面,如果您想在没有用户许可的情况下执行此操作(即密钥记录),那么您就是在进行黑客攻击。可能有一系列尚未修补的漏洞可以组合起来做你想做的事,但知道它的人很可能会从中赚钱。
【讨论】:
stdin。相反,我想将数据注入其中。
stdin 进行通信与通过击键进行通信在很大程度上不同。我很确定我没有输入 Safari 的标准输入来写这个评论;而且我很确定 UNIX CLI 程序本身不会响应击键。
好吧,从技术上讲,您可以将线程注入目标进程,然后让它将标准输入文件描述符的副本发送回给您……但您可能不应该这样做。 :-)
你真正想做什么?
【讨论】:
stdin 流,因此我认为将数据注入 stdin 而不是从我的插件中找到真正可行的解决方案会很“有趣”。
stdin 会失败并返回fwrite,而write(0, ...) 会写入终端,但不会通过进一步的read 调用使该数据可读。只是为了科学,知道我该如何解决这个问题吗?
stdin 对话。我也不怕低级的东西。