Search code examples
macosstdin

Is there a way to send data to another process's standard input under Mac OS?


I was wondering if there was an API, however obscure it would be, that would allow someone to send data to another process's stdin stream under Mac OS X. Under Linux, if I remember correctly, you can use the filesystem in /proc to access these streams (with the correct permissions, of course).

I dunno. Mach ports, anyone?


Solution

  • Unfortunately, I don't believe you can do that -- MacPorts are all userland, and the operation you require needs (either a lot of trickery, see below, or) kernel cooperation, which, I believe, isn't forthcoming. For example, Mac OSX Internals, a System Approach in the section on file-descriptor passing, says

    The descriptor is local to the process in that it is meaningful only in the process that acquired the descriptorsay, by opening a file. In particular, a process A cannot access a file that is open in another process B by simply using the value of the descriptor representing that file in B.

    and then goes on to describe how FDs are sent.

    The "trickery" part would require you getting some code of yours to run (either in userland or as part of the kernel) within the other process.

    For example, you could do it in userland by patching the binary file that's their executable -- find any instruction early in its startup path that's sure to be executed, and put in its stead a jump to your own code which sends the FD to your watching daemon process, executes the patched-away instruction, then jumps back to the other process's normal sequential flow.

    To do it at kernel level would require similar patches to either the kernel code itself, or to code which the kernel loads and runs with entire, unverified trust (so they can hijack an unrelated process's file descriptor table entries) -- I sure hope there are no such code paths left in Mac OS X (since their main use would no doubt be by viruses, trojan horses, and other malware of all kinds) but, if there are and you can find them, this might be a more general solution than patching every single binary executable of interest.

    Back to userland, another fairly general approach might be to patch dynamically loaded libraries that all processes of interest load, instead of patching the various processes' several executables.