简体   繁体   中英

Catching output of linux command in background C++ program / bash script

I want to create c++ program or bash script that will run in background and whenever i use chosen command for example

pwd it will catch output of that command which will be let's say ~Desktop/folder1 and it will change that output to You are in ~Desktop/folder1 . So the result would be that user, after using command pwd will see only You are in ~Desktop/folder1 .

Pwd command is just example, i want to modify output of other commands like, ls, ps, and so on.

I want the script to work in all terminals, by that i mean if i open another terminal it would still catch output of chosen commands in that terminal.

QUESTION:

Is it even possible to do c++ program or bash script that would do such thing?

You can put shell function definitions into your bash environment configuration scripts that will have the effect you describe. For example,

~/.bash_profile:

# ...

pwd() {
  echo You are in $(command pwd)
}

export -f pwd

Note the use of the command command to avoid recursion in shell function pwd . Note also the export -f to export the function to child processes. You would need a snippet like that for every command you want to override.

Depending on your system and configuration, it might be more appropriate to put them in ~/.bashrc instead. Or if you want it to apply to every user, then you can put those in one of the system-wide bash configuration scripts. Note, however, that users will be able to override it.

First, missing from your question are two important parameters. The first is which shells need to be affected by this. Is this something that is supposed to be system wide? Just one user? Just a few specific shells of a specific user?

The second missing parameter is what permissions are needed. Is this something that root is supposed to do? A non-privileged user?

Each such command you wish to intercept is a system call. Usually it's execve , but sometimes it's something more specific ( pwd , for example, is, by definition, an internal shell command). Assuming you do not wish to write a kernel module (the only real way to do what you want), you will have to be a little more creative.

One option is to replace all the relevant files on the filesystem with alternative versions that do what you want. This is, of course, not possible if you are not root.

Another option that is more possible using non-privileged user is to use the ptrace interface to take control over the shell processes you wish to control. Be forewarned, however, that this is extremely complicated, slow in performance, and will only work on the same user as the one running the C++ program. In addition, recent kernels have further protection against simply attaching to a random process as a debugger, which means you will need to either disable it (which requires root), or run the affected shells through your program.

One program that already does something similar is <shameless_plug> fakeroot-ng </shameless_plug>. It sets up a debugger, and attaches to a shell in order to give it a different view of what the system is doing than the real system. You can try and hack the code to do what you want. This will probably be easier with the multithreaded_debugger branch, but that one is still not quite stable.

You have asked the wrong question.

If what you're trying to do is to hide a set of processes and files, /etc/ld.so.preload is your friend.

What you need to do is to write a shared object file that re-implements readdir and readdir_r (two functions should, more or less, do it) in a way that makes sure that if someone tries to get the content of the directory where your "hidden" files are, you omit your files from the reply. At the same time, if someone tries to get the content of the /proc/ directory, you omit the directories corresponding to the processes you are trying to hide.

You can easily see whether this is the directory you wish to change the responses to by caching its inode/dev pair, and checking it. This will be resilient to renaming, symlinking etc.

Search the net for how to write an LD_PRELOAD module for instructions on how to daisy chain the functions themselves. This is considerably less work than modifying each and every binary out there. If you know what you are doing, this can be wrapped up in ~200 lines of code.

And now comes the kicker. You do not need to put in the LD_PRELOAD environment variable to each and every process. Simply list your shared object (after testing it with LD_PRELOAD) in /etc/ld.so.preload , and viola! All the processes in your system will have your libary injected to it.

Don't ignore the testing suggestion. Listing the wrong file in /etc/ld.so.preload might render your system completely unusable.

For added bonus, once you're done, install chkrootkit and run it, and watch as it complains that your system has been compromised. This is one of the (many) techniques used by rootkits in order to hide themselves.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM